diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index e2282654fc9..ef6dd3a834a 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -47,8 +47,8 @@ Long description (Can span accross multiple lines). Where KEYWORD is one of: -- "FIXED:" for bug fixes (May be followed by the bug number i.e: #456) -- "NEW:" for new features (May be followed by the task number i.e: #123) +- "FIXED:" for bug fixes. In upper case to appear into ChangeLog. (May be followed by the bug number i.e: #456) +- "NEW:" for new features. In upper case to appear into ChangeLog. (May be followed by the task number i.e: #123) - void, don't put a keyword if the commit is not introducing feature or closing a bug. ### Resources diff --git a/ChangeLog b/ChangeLog index ebf41dd0516..7a5e1c7c5da 100644 --- a/ChangeLog +++ b/ChangeLog @@ -14,8 +14,10 @@ For users: MARGIN_PMP_AS_DEFAULT_BUY_PRICE to replace with first supplier price. - Introduce option MAIN_HTML_TITLE to start to control format of html title content. - Add extrafields on bank account cards. -- Added delay between mails in Newsletter module -- [ task #1793 ] Create new permission to restrict commercial agent margin to logged user +- Added delay between mails in Newsletter module. +- [ task #1793 ] Create new permission to restrict commercial agent margin to logged user. +- Add experimental module ask supplier price to request supplier quotation. +- Add experimental module batch management. For translators: - Update language files. @@ -25,6 +27,12 @@ For developers: - New: Function yn can show a visual checkbox. - New: Introduced select2 jquery plugin. +WARNING: Following changes may create regression for some external modules, but was necessary to make +Dolibarr better: +- Removed hoo supplierorderdao into supplier order creation. This is a business event, so we must use the + trigger ORDER_SUPPLIER_CREATE instead. + + ***** ChangeLog for 3.7 compared to 3.6.* ***** For users: @@ -223,6 +231,7 @@ Dolibarr better: - Fix: [ bug #1825 ] External agenda: hide/show checkbox doesn't work - Fix: [ bug #1790 ] Email form behaves in an unexpected way when pressing Enter key - Fix: Bad SEPA xml file creation +- Fix: [ bug #1892 ] PHP Fatal error when using USER_UPDATE_SESSION trigger and adding a supplier invoice payment ***** ChangeLog for 3.6.2 compared to 3.6.1 ***** - Fix: fix ErrorBadValueForParamNotAString error message in price customer multiprice. diff --git a/build/debian/changelog b/build/debian/changelog index db3f1dc887b..50d2b158e29 100644 --- a/build/debian/changelog +++ b/build/debian/changelog @@ -1,6 +1,6 @@ -dolibarr (3.7.0-3) UNRELEASED; urgency=low +dolibarr (3.8.0-3) UNRELEASED; urgency=low [ Laurent Destailleur (eldy) ] * New upstream release. - -- Laurent Destailleur (eldy) Tue, 21 Oct 2014 12:00:00 +0100 + -- Laurent Destailleur (eldy) Tue, 3 Mar 2015 12:00:00 +0100 diff --git a/build/makepack-dolibarr.pl b/build/makepack-dolibarr.pl index ecdf371dc6f..d96b84ab822 100755 --- a/build/makepack-dolibarr.pl +++ b/build/makepack-dolibarr.pl @@ -451,15 +451,18 @@ if ($nboftargetok) { $ret=`rm -fr $BUILDROOT/$PROJECT/documents`; $ret=`rm -fr $BUILDROOT/$PROJECT/htdocs/document`; $ret=`rm -fr $BUILDROOT/$PROJECT/htdocs/documents`; + # Removed known external modules to avoir any error when packaging on test env $ret=`rm -fr $BUILDROOT/$PROJECT/htdocs/ancotec*`; $ret=`rm -fr $BUILDROOT/$PROJECT/htdocs/bootstrap*`; $ret=`rm -fr $BUILDROOT/$PROJECT/htdocs/custom*`; $ret=`rm -fr $BUILDROOT/$PROJECT/htdocs/factory*`; + $ret=`rm -fr $BUILDROOT/$PROJECT/htdocs/management*`; $ret=`rm -fr $BUILDROOT/$PROJECT/htdocs/multicompany*`; $ret=`rm -fr $BUILDROOT/$PROJECT/htdocs/nltechno*`; $ret=`rm -fr $BUILDROOT/$PROJECT/htdocs/pos*`; $ret=`rm -fr $BUILDROOT/$PROJECT/htdocs/public/test`; $ret=`rm -fr $BUILDROOT/$PROJECT/htdocs/teclib*`; + $ret=`rm -fr $BUILDROOT/$PROJECT/htdocs/timesheet*`; $ret=`rm -fr $BUILDROOT/$PROJECT/htdocs/themes/oblyon*`; $ret=`rm -fr $BUILDROOT/$PROJECT/htdocs/themes/eldy/*.new`; $ret=`rm -fr $BUILDROOT/$PROJECT/test`; diff --git a/build/rpm/dolibarr_fedora.spec b/build/rpm/dolibarr_fedora.spec index 5312ea52bf7..0682f400b98 100755 --- a/build/rpm/dolibarr_fedora.spec +++ b/build/rpm/dolibarr_fedora.spec @@ -174,6 +174,7 @@ done >>%{name}.lang %_datadir/dolibarr/htdocs/cron %_datadir/dolibarr/htdocs/ecm %_datadir/dolibarr/htdocs/expedition +%_datadir/dolibarr/htdocs/expensereport %_datadir/dolibarr/htdocs/exports %_datadir/dolibarr/htdocs/externalsite %_datadir/dolibarr/htdocs/fichinter diff --git a/build/rpm/dolibarr_generic.spec b/build/rpm/dolibarr_generic.spec index 7d02cd24c16..884e883d86c 100755 --- a/build/rpm/dolibarr_generic.spec +++ b/build/rpm/dolibarr_generic.spec @@ -254,6 +254,7 @@ done >>%{name}.lang %_datadir/dolibarr/htdocs/cron %_datadir/dolibarr/htdocs/ecm %_datadir/dolibarr/htdocs/expedition +%_datadir/dolibarr/htdocs/expensereport %_datadir/dolibarr/htdocs/exports %_datadir/dolibarr/htdocs/externalsite %_datadir/dolibarr/htdocs/fichinter diff --git a/build/rpm/dolibarr_mandriva.spec b/build/rpm/dolibarr_mandriva.spec index e10e5028a0b..e2b5309b572 100755 --- a/build/rpm/dolibarr_mandriva.spec +++ b/build/rpm/dolibarr_mandriva.spec @@ -171,6 +171,7 @@ done >>%{name}.lang %_datadir/dolibarr/htdocs/cron %_datadir/dolibarr/htdocs/ecm %_datadir/dolibarr/htdocs/expedition +%_datadir/dolibarr/htdocs/expensereport %_datadir/dolibarr/htdocs/exports %_datadir/dolibarr/htdocs/externalsite %_datadir/dolibarr/htdocs/fichinter diff --git a/build/rpm/dolibarr_opensuse.spec b/build/rpm/dolibarr_opensuse.spec index 126ca639bbc..3cf98a83375 100755 --- a/build/rpm/dolibarr_opensuse.spec +++ b/build/rpm/dolibarr_opensuse.spec @@ -182,6 +182,7 @@ done >>%{name}.lang %_datadir/dolibarr/htdocs/cron %_datadir/dolibarr/htdocs/ecm %_datadir/dolibarr/htdocs/expedition +%_datadir/dolibarr/htdocs/expensereport %_datadir/dolibarr/htdocs/exports %_datadir/dolibarr/htdocs/externalsite %_datadir/dolibarr/htdocs/fichinter diff --git a/dev/fixdosfiles.sh b/dev/fixdosfiles.sh index 30d47e7b0c4..5efd4b58543 100755 --- a/dev/fixdosfiles.sh +++ b/dev/fixdosfiles.sh @@ -10,6 +10,7 @@ # Syntax if [ "x$1" != "xlist" -a "x$1" != "xfix" ] then + echo "This script clean files with CR+LF into files with LF only. All source files are included, also files into includes." echo "Usage: fixdosfiles.sh [list|fix]" fi diff --git a/htdocs/admin/askpricesupplier.php b/htdocs/admin/askpricesupplier.php new file mode 100644 index 00000000000..6307e81042c --- /dev/null +++ b/htdocs/admin/askpricesupplier.php @@ -0,0 +1,599 @@ + + * Copyright (C) 2004-2011 Laurent Destailleur + * Copyright (C) 2004 Sebastien Di Cintio + * Copyright (C) 2004 Benoit Mortier + * Copyright (C) 2004 Eric Seigne + * Copyright (C) 2005-2012 Regis Houssin + * Copyright (C) 2008 Raphael Bertrand (Resultic) + * Copyright (C) 2011-2013 Juanjo Menent + * + * 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 . + */ + +require '../main.inc.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/admin.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/comm/askpricesupplier/class/askpricesupplier.class.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/askpricesupplier.lib.php'; +$langs->load("admin"); +$langs->load("errors"); +$langs->load('other'); +$langs->load('askpricesupplier'); + +if (! $user->admin) accessforbidden(); + +$action = GETPOST('action','alpha'); +$value = GETPOST('value','alpha'); +$label = GETPOST('label','alpha'); +$scandir = GETPOST('scandir','alpha'); +$type='askpricesupplier'; + +/* + * Actions + */ +$error=0; +if ($action == 'updateMask') +{ + $maskconstaskpricesupplier=GETPOST('maskconstaskpricesupplier','alpha'); + $maskaskpricesupplier=GETPOST('maskaskpricesupplier','alpha'); + if ($maskconstaskpricesupplier) $res = dolibarr_set_const($db,$maskconstaskpricesupplier,$maskaskpricesupplier,'chaine',0,'',$conf->entity); + + if (! $res > 0) $error++; + + if (! $error) + { + setEventMessage($langs->trans("SetupSaved")); + } + else + { + setEventMessage($langs->trans("Error"),'errors'); + } +} + +if ($action == 'specimen') +{ + $modele=GETPOST('module','alpha'); + + $askpricesupplier = new AskPriceSupplier($db); + $askpricesupplier->initAsSpecimen(); + + // Search template files + $file=''; $classname=''; $filefound=0; + $dirmodels=array_merge(array('/'),(array) $conf->modules_parts['models']); + foreach($dirmodels as $reldir) + { + $file=dol_buildpath($reldir."core/modules/askpricesupplier/doc/pdf_".$modele.".modules.php"); + if (file_exists($file)) + { + $filefound=1; + $classname = "pdf_".$modele; + break; + } + } + + if ($filefound) + { + require_once $file; + + $module = new $classname($db); + + if ($module->write_file($askpricesupplier,$langs) > 0) + { + header("Location: ".DOL_URL_ROOT."/document.php?modulepart=askpricesupplier&file=SPECIMEN.pdf"); + return; + } + else + { + setEventMessage($module->error,'errors'); + dol_syslog($module->error, LOG_ERR); + } + } + else + { + setEventMessage($langs->trans("ErrorModuleNotFound"),'errors'); + dol_syslog($langs->trans("ErrorModuleNotFound"), LOG_ERR); + } +} + +if ($action == 'set_ASKPRICESUPPLIER_DRAFT_WATERMARK') +{ + $draft = GETPOST('ASKPRICESUPPLIER_DRAFT_WATERMARK','alpha'); + + $res = dolibarr_set_const($db, "ASKPRICESUPPLIER_DRAFT_WATERMARK",trim($draft),'chaine',0,'',$conf->entity); + if (! $res > 0) $error++; + + if (! $error) + { + setEventMessage($langs->trans("SetupSaved")); + } + else + { + setEventMessage($langs->trans("Error"),'errors'); + } +} + +if ($action == 'set_ASKPRICESUPPLIER_FREE_TEXT') +{ + $freetext = GETPOST('ASKPRICESUPPLIER_FREE_TEXT'); // No alpha here, we want exact string + + $res = dolibarr_set_const($db, "ASKPRICESUPPLIER_FREE_TEXT",$freetext,'chaine',0,'',$conf->entity); + + if (! $res > 0) $error++; + + if (! $error) + { + setEventMessage($langs->trans("SetupSaved")); + } + else + { + setEventMessage($langs->trans("Error"),'errors'); + } +} + +if ($action == 'set_BANK_ASK_PAYMENT_BANK_DURING_ASKPRICESUPPLIER') +{ + $res = dolibarr_set_const($db, "BANK_ASK_PAYMENT_BANK_DURING_ASKPRICESUPPLIER",$value,'chaine',0,'',$conf->entity); + + if (! $res > 0) $error++; + + if (! $error) + { + setEventMessage($langs->trans("SetupSaved")); + } + else + { + setEventMessage($langs->trans("Error"),'errors'); + } +} + +// Define constants for submodules that contains parameters (forms with param1, param2, ... and value1, value2, ...) +if ($action == 'setModuleOptions') +{ + $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(); + setEventMessage($langs->trans("SetupSaved")); + } + else + { + $db->rollback(); + setEventMessage($langs->trans("Error"),'errors'); + } +} + +// Activate a model +if ($action == 'set') +{ + $ret = addDocumentModel($value, $type, $label, $scandir); +} + +else if ($action == 'del') +{ + $ret = delDocumentModel($value, $type); + if ($ret > 0) + { + if ($conf->global->ASKPRICESUPPLIER_ADDON_PDF == "$value") dolibarr_del_const($db, 'ASKPRICESUPPLIER_ADDON_PDF',$conf->entity); + } +} + +else if ($action == 'setdoc') +{ + if (dolibarr_set_const($db, "ASKPRICESUPPLIER_ADDON_PDF",$value,'chaine',0,'',$conf->entity)) + { + $conf->global->ASKPRICESUPPLIER_ADDON_PDF = $value; + } + + // On active le modele + $ret = delDocumentModel($value, $type); + if ($ret > 0) + { + $ret = addDocumentModel($value, $type, $label, $scandir); + } +} + +else if ($action == 'setmod') +{ + // TODO Verifier si module numerotation choisi peut etre active + // par appel methode canBeActivated + + dolibarr_set_const($db, "ASKPRICESUPPLIER_ADDON",$value,'chaine',0,'',$conf->entity); +} + + +/* + * Affiche page + */ + +$dirmodels=array_merge(array('/'),(array) $conf->modules_parts['models']); + + +llxHeader('',$langs->trans("AskPriceSupplierSetup")); + +$form=new Form($db); + +//if ($mesg) print $mesg; + +$linkback=''.$langs->trans("BackToModuleList").''; +print_fiche_titre($langs->trans("AskPriceSupplierSetup"),$linkback,'setup'); + +$head = askpricesupplier_admin_prepare_head(); + +dol_fiche_head($head, 'general', $langs->trans("CommRequests"), 0, 'askpricesupplier'); + +/* + * Module numerotation + */ +print_titre($langs->trans("AskPriceSupplierNumberingModules")); + +print ''; +print ''; +print '\n"; +print '\n"; +print '\n"; +print ''; +print ''; +print ''."\n"; + +clearstatcache(); +foreach ($dirmodels as $reldir) +{ + $dir = dol_buildpath($reldir."core/modules/askpricesupplier/"); + + if (is_dir($dir)) + { + $handle = opendir($dir); + if (is_resource($handle)) + { + $var=true; + + while (($file = readdir($handle))!==false) + { + if (substr($file, 0, 21) == 'mod_askpricesupplier_' && substr($file, dol_strlen($file)-3, 3) == 'php') + { + $file = substr($file, 0, dol_strlen($file)-4); + + require_once $dir.$file.'.php'; + + $module = new $file; + + // Show modules according to features level + if ($module->version == 'development' && $conf->global->MAIN_FEATURES_LEVEL < 2) continue; + if ($module->version == 'experimental' && $conf->global->MAIN_FEATURES_LEVEL < 1) continue; + + if ($module->isEnabled()) + { + $var=!$var; + print ''; + + // Show example of numbering module + print ''."\n"; + + print ''; + + $askpricesupplier=new AskPriceSupplier($db); + $askpricesupplier->initAsSpecimen(); + + // Info + $htmltooltip=''; + $htmltooltip.=''.$langs->trans("Version").': '.$module->getVersion().'
'; + $askpricesupplier->type=0; + $nextval=$module->getNextValue($mysoc,$askpricesupplier); + if ("$nextval" != $langs->trans("NotAvailable")) { // Keep " on nextval + $htmltooltip.=''.$langs->trans("NextValue").': '; + if ($nextval) { + if (preg_match('/^Error/',$nextval) || $nextval=='NotConfigured') + $nextval = $langs->trans($nextval); + $htmltooltip.=$nextval.'
'; + } else { + $htmltooltip.=$langs->trans($module->error).'
'; + } + } + + print ''; + + print "\n"; + } + } + } + closedir($handle); + } + } +} +print "
'.$langs->trans("Name")."'.$langs->trans("Description")."'.$langs->trans("Example")."'.$langs->trans("Status").''.$langs->trans("ShortInfo").'
'.$module->nom."\n"; + print $module->info(); + print ''; + $tmp=$module->getExample(); + if (preg_match('/^Error/',$tmp)) print '
'.$langs->trans($tmp).'
'; + elseif ($tmp=='NotConfigured') print $langs->trans($tmp); + else print $tmp; + print '
'; + if ($conf->global->ASKPRICESUPPLIER_ADDON == "$file") + { + print img_picto($langs->trans("Activated"),'switch_on'); + } + else + { + print ''; + print img_picto($langs->trans("Disabled"),'switch_off'); + print ''; + } + print ''; + print $form->textwithpicto('',$htmltooltip,1,0); + print '

\n"; + + +/* + * Document templates generators + */ + +print_titre($langs->trans("AskPriceSupplierPDFModules")); + +// Load array def with activated templates +$def = array(); +$sql = "SELECT nom"; +$sql.= " FROM ".MAIN_DB_PREFIX."document_model"; +$sql.= " WHERE type = '".$type."'"; +$sql.= " AND entity = ".$conf->entity; +$resql=$db->query($sql); +if ($resql) +{ + $i = 0; + $num_rows=$db->num_rows($resql); + while ($i < $num_rows) + { + $array = $db->fetch_array($resql); + array_push($def, $array[0]); + $i++; + } +} +else +{ + dol_print_error($db); +} + + +print "\n"; +print "\n"; +print " \n"; +print " \n"; +print '\n"; +print '\n"; +print ''; +print ''; +print "\n"; + +clearstatcache(); + +$var=true; +foreach ($dirmodels as $reldir) +{ + foreach (array('','/doc') as $valdir) + { + $dir = dol_buildpath($reldir."core/modules/askpricesupplier".$valdir); + + if (is_dir($dir)) + { + $handle=opendir($dir); + if (is_resource($handle)) + { + while (($file = readdir($handle))!==false) + { + $filelist[]=$file; + } + closedir($handle); + arsort($filelist); + + foreach($filelist as $file) + { + if (preg_match('/\.modules\.php$/i',$file) && preg_match('/^(pdf_|doc_)/',$file)) + { + if (file_exists($dir.'/'.$file)) + { + $name = substr($file, 4, dol_strlen($file) -16); + $classname = substr($file, 0, dol_strlen($file) -12); + + require_once $dir.'/'.$file; + $module = new $classname($db); + + $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; + + if ($modulequalified) + { + $var = !$var; + print ''; + + // Active + if (in_array($name, $def)) + { + print ''; + } + else + { + print ""; + } + + // Defaut + print "'; + + // Info + $htmltooltip = ''.$langs->trans("Name").': '.$module->name; + $htmltooltip.='
'.$langs->trans("Type").': '.($module->type?$module->type:$langs->trans("Unknown")); + if ($module->type == 'pdf') + { + $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); + $htmltooltip.='
'.$langs->trans("PaymentMode").': '.yn($module->option_modereg,1,1); + $htmltooltip.='
'.$langs->trans("PaymentConditions").': '.yn($module->option_condreg,1,1); + $htmltooltip.='
'.$langs->trans("MultiLanguage").': '.yn($module->option_multilang,1,1); + //$htmltooltip.='
'.$langs->trans("Discounts").': '.yn($module->option_escompte,1,1); + //$htmltooltip.='
'.$langs->trans("CreditNote").': '.yn($module->option_credit_note,1,1); + $htmltooltip.='
'.$langs->trans("WatermarkOnDraftProposal").': '.yn($module->option_draft_watermark,1,1); + + + print ''; + + // Preview + print ''; + + print "\n"; + } + } + } + } + } + } + } +} + +print '
".$langs->trans("Name")."".$langs->trans("Description")."'.$langs->trans("Status")."'.$langs->trans("Default")."'.$langs->trans("ShortInfo").''.$langs->trans("Preview").'
'; + print (empty($module->name)?$name:$module->name); + print "\n"; + if (method_exists($module,'info')) print $module->info($langs); + else print $module->description; + print ''."\n"; + print ''; + print img_picto($langs->trans("Enabled"),'switch_on'); + print ''; + print '\n"; + print 'scandir.'&label='.urlencode($module->name).'">'.img_picto($langs->trans("Disabled"),'switch_off').''; + print ""; + if ($conf->global->ASKPRICESUPPLIER_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 ''; + print $form->textwithpicto('',$htmltooltip,1,0); + print ''; + if ($module->type == 'pdf') + { + print ''.img_object($langs->trans("Preview"),'bill').''; + } + else + { + print img_object($langs->trans("PreviewNotAvailable"),'generic'); + } + print '
'; +print '
'; + + +/* + * Other options + * + */ +print_titre($langs->trans("OtherOptions")); + +$var=true; +print ""; +print ""; +print "\n"; +print '\n"; +print "\n"; +print ""; + +$var=! $var; +print ''; +print ''; +print ''; +print '\n"; +print ''; + +$var=!$var; +print ""; +print ''; +print ""; +print '\n"; +print ''; + +if ($conf->banque->enabled) +{ + $var=!$var; + print ''; +} +else +{ + $var=!$var; + print ''; +} + +print '
".$langs->trans("Parameter")."'.$langs->trans("Value")." 
'; +print $langs->trans("FreeLegalTextOnAskPriceSupplier").' ('.$langs->trans("AddCRIfTooLong").')
'; +print ''; +print '
'; +print ''; +print "
'; +print $langs->trans("WatermarkOnDraftAskPriceSupplier").'
'; +print ''; +print '
'; +print ''; +print "
'; + print $langs->trans("BANK_ASK_PAYMENT_BANK_DURING_ASKPRICESUPPLIER").' '; + if (! empty($conf->use_javascript_ajax)) + { + print ajax_constantonoff('BANK_ASK_PAYMENT_BANK_DURING_ASKPRICESUPPLIER'); + } + else + { + if (empty($conf->global->BANK_ASK_PAYMENT_BANK_DURING_ASKPRICESUPPLIER)) + { + print ''.img_picto($langs->trans("Disabled"),'switch_off').''; + } + else + { + print ''.img_picto($langs->trans("Enabled"),'switch_on').''; + } + } + print '
'; + print $langs->trans("BANK_ASK_PAYMENT_BANK_DURING_ASKPRICESUPPLIER").' '.$langs->trans('NotAvailable').'
'; + + + +/* + * Directory + */ +print '
'; +print_titre($langs->trans("PathToDocuments")); + +print "\n"; +print "\n"; +print " \n"; +print " \n"; +print "\n"; +print "\n \n \n\n"; +print "
".$langs->trans("Name")."".$langs->trans("Value")."
".$langs->trans("PathDirectory")."".$conf->askpricesupplier->dir_output."
\n
"; + +$db->close(); + +llxFooter(); diff --git a/htdocs/admin/fichinter.php b/htdocs/admin/fichinter.php index 8965b225cfb..8e06e946dee 100644 --- a/htdocs/admin/fichinter.php +++ b/htdocs/admin/fichinter.php @@ -221,7 +221,7 @@ else if ($action == 'set_FICHINTER_DRAFT_WATERMARK') elseif ($action == 'set_FICHINTER_PRINT_PRODUCTS') { $val = GETPOST('FICHINTER_PRINT_PRODUCTS','alpha'); - $res = dolibarr_set_const($db, "FICHINTER_PRINT_PRODUCTS",($val == 'on'),'bool',0,'',$conf->entity); + $res = dolibarr_set_const($db, "FICHINTER_PRINT_PRODUCTS",($val == 'on' ? 1 : 0),'bool',0,'',$conf->entity); if (! $res > 0) $error++; diff --git a/htdocs/admin/security_file.php b/htdocs/admin/security_file.php index 4c0dd435634..d99db6ed638 100644 --- a/htdocs/admin/security_file.php +++ b/htdocs/admin/security_file.php @@ -208,7 +208,7 @@ $formfile->form_attach_new_file($_SERVER['PHP_SELF'], $langs->trans("FormToTestF // List of document $filearray=dol_dir_list($upload_dir, "files", 0, '', '', 'name', SORT_ASC, 1); -$formfile->list_of_documents($filearray, '', 'admin_temp', ''); +$formfile->list_of_documents($filearray, null, 'admin_temp', ''); llxFooter(); $db->close(); diff --git a/htdocs/admin/system/filecheck.php b/htdocs/admin/system/filecheck.php index 278aae8ea5b..8eff6821224 100644 --- a/htdocs/admin/system/filecheck.php +++ b/htdocs/admin/system/filecheck.php @@ -108,7 +108,7 @@ $db->close(); /** * Function to get list of updated or modified files * - * @param object $dir SimpleXMLElement of files to test + * @param SimpleXMLElement $dir SimpleXMLElement of files to test * @param string $path Path of file * @return array Array of filenames */ diff --git a/htdocs/categories/class/categorie.class.php b/htdocs/categories/class/categorie.class.php index 1d51ea6f7fb..e4ff0e4e0d1 100644 --- a/htdocs/categories/class/categorie.class.php +++ b/htdocs/categories/class/categorie.class.php @@ -1330,17 +1330,23 @@ class Categorie extends CommonObject * Build thumb * * @param string $file Chemin du fichier d'origine - * @param int $maxWidth Largeur maximum que dois faire la miniature (160 par defaut) - * @param int $maxHeight Hauteur maximum que dois faire la miniature (120 par defaut) * @return void */ - function add_thumb($file, $maxWidth = 160, $maxHeight = 120) + function add_thumb($file) { - require_once DOL_DOCUMENT_ROOT .'/core/lib/images.lib.php'; + global $maxwidthsmall, $maxheightsmall, $maxwidthmini, $maxheightmini, $quality; + + require_once DOL_DOCUMENT_ROOT .'/core/lib/images.lib.php'; // This define also $maxwidthsmall, $quality, ... if (file_exists($file)) { - vignette($file,$maxWidth,$maxHeight); + // Create small thumbs for company (Ratio is near 16/9) + // Used on logon for example + $imgThumbSmall = vignette($file, $maxwidthsmall, $maxheightsmall, '_small', $quality); + + // Create mini thumbs for company (Ratio is near 16/9) + // Used on menu or for setup page for example + $imgThumbMini = vignette($file, $maxwidthmini, $maxheightmini, '_mini', $quality); } } diff --git a/htdocs/comm/action/index.php b/htdocs/comm/action/index.php index a0ab00b9db6..71c45be9eff 100644 --- a/htdocs/comm/action/index.php +++ b/htdocs/comm/action/index.php @@ -363,17 +363,16 @@ if (! empty($conf->use_javascript_ajax)) { foreach ($showextcals as $val) { - $htmlname = dol_string_nospecial($val['name']); - $htmlname = dol_string_nospecial($htmlname,'_',array("\.","#")); + $htmlname = md5($val['name']); $s.='' . "\n"; - $s.='
' . $val ['name'] . '  
'; + $s.='
' . $val ['name'] . '  
'; } } $s.='
'.$langs->trans("AgendaShowBirthdayEvents").'  
'; @@ -1174,7 +1173,7 @@ function show_day_events($db, $day, $month, $year, $monthshown, $style, &$eventa $numicals[dol_string_nospecial($event->icalname)]++; } $color=$event->icalcolor; - $cssclass=(! empty($event->icalname)?'family_'.dol_string_nospecial($event->icalname):'family_other unmovable'); + $cssclass=(! empty($event->icalname)?'family_ext'.md5($event->icalname):'family_other unmovable'); } else if ($event->type_code == 'BIRTHDAY') { diff --git a/htdocs/comm/action/peruser.php b/htdocs/comm/action/peruser.php index 335fc491224..cb2aa9fa99f 100644 --- a/htdocs/comm/action/peruser.php +++ b/htdocs/comm/action/peruser.php @@ -305,16 +305,16 @@ if ($conf->use_javascript_ajax) { foreach ($showextcals as $val) { - $htmlname = dol_string_nospecial($val['name']); + $htmlname = md5($val['name']); $s.='' . "\n"; - $s.='
' . $val ['name'] . '  
'; + $s.='
' . $val ['name'] . '  
'; } } } @@ -869,7 +869,7 @@ function show_day_events2($username, $day, $month, $year, $monthshown, $style, & } $color=$event->icalcolor; - $cssclass=(! empty($event->icalname)?'family_'.dol_string_nospecial($event->icalname):'family_other unsortable'); + $cssclass=(! empty($event->icalname)?'family_ext'.md5($event->icalname):'family_other unsortable'); } else if ($event->type_code == 'BIRTHDAY') { diff --git a/htdocs/comm/admin/askpricesupplier_extrafields.php b/htdocs/comm/admin/askpricesupplier_extrafields.php new file mode 100644 index 00000000000..0e74ca265e9 --- /dev/null +++ b/htdocs/comm/admin/askpricesupplier_extrafields.php @@ -0,0 +1,151 @@ + + * Copyright (C) 2003 Jean-Louis Bergamo + * Copyright (C) 2004-2011 Laurent Destailleur + * Copyright (C) 2012 Regis Houssin + * + * 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 . + */ + +require '../../main.inc.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/askpricesupplier.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/core/class/extrafields.class.php'; + +$langs->load("companies"); +$langs->load("admin"); +$langs->load('askpricesupplier'); + +$extrafields = new ExtraFields($db); +$form = new Form($db); + +// List of supported format +$tmptype2label=ExtraFields::$type2label; +$type2label=array(''); +foreach ($tmptype2label as $key => $val) $type2label[$key]=$langs->trans($val); + +$action=GETPOST('action', 'alpha'); +$attrname=GETPOST('attrname', 'alpha'); +$elementtype='askpricesupplier'; //Must be the $table_element of the class that manage extrafield + +if (!$user->admin) accessforbidden(); + + +/* + * Actions + */ + +require DOL_DOCUMENT_ROOT.'/core/actions_extrafields.inc.php'; + + + +/* + * View + */ + +$textobject=$langs->transnoentitiesnoconv("CommRequests"); + + +llxHeader('',$langs->trans("AskPriceSupplierSetup")); + + +$linkback=''.$langs->trans("BackToModuleList").''; +print_fiche_titre($langs->trans("AskPriceSupplierSetup"),$linkback,'setup'); + + +$head = askpricesupplier_admin_prepare_head(); + +dol_fiche_head($head, 'attributes', $langs->trans("CommRequests"), 0, 'askpricesupplier'); + + +print $langs->trans("DefineHereComplementaryAttributes",$textobject).'
'."\n"; +print '
'; + +// Load attribute_label +$extrafields->fetch_name_optionals_label($elementtype); + +print ""; + +print ''; +print ''; +print ''; +print ''; +print ''; +print ''; +print ''; +print ''; +print ''; +print "\n"; + +$var=True; +foreach($extrafields->attribute_type as $key => $value) +{ + $var=!$var; + print ""; + print "\n"; + print "\n"; + print "\n"; + print "\n"; + print '\n"; + print '\n"; + print '\n"; + print '\n"; + print ""; + // $i++; +} + +print "
'.$langs->trans("Position").''.$langs->trans("Label").''.$langs->trans("AttributeCode").''.$langs->trans("Type").''.$langs->trans("Size").''.$langs->trans("Unique").''.$langs->trans("Required").' 
".$extrafields->attribute_pos[$key]."".$extrafields->attribute_label[$key]."".$key."".$type2label[$extrafields->attribute_type[$key]]."'.$extrafields->attribute_size[$key]."'.yn($extrafields->attribute_unique[$key])."'.yn($extrafields->attribute_required[$key])."'.img_edit().''; + print "  ".img_delete()."
"; + +dol_fiche_end(); + + +// Buttons +if ($action != 'create' && $action != 'edit') +{ + print '
'; + print ''; + print "
"; +} + + +/* ************************************************************************** */ +/* */ +/* Creation d'un champ optionnel + /* */ +/* ************************************************************************** */ + +if ($action == 'create') +{ + print "
"; + print_titre($langs->trans('NewAttribute')); + + require DOL_DOCUMENT_ROOT.'/core/tpl/admin_extrafields_add.tpl.php'; +} + +/* ************************************************************************** */ +/* */ +/* Edition d'un champ optionnel */ +/* */ +/* ************************************************************************** */ +if ($action == 'edit' && ! empty($attrname)) +{ + print "
"; + print_titre($langs->trans("FieldEdition", $attrname)); + + require DOL_DOCUMENT_ROOT.'/core/tpl/admin_extrafields_edit.tpl.php'; +} + +llxFooter(); + +$db->close(); diff --git a/htdocs/comm/admin/askpricesupplierdet_extrafields.php b/htdocs/comm/admin/askpricesupplierdet_extrafields.php new file mode 100644 index 00000000000..a58164b63dd --- /dev/null +++ b/htdocs/comm/admin/askpricesupplierdet_extrafields.php @@ -0,0 +1,153 @@ + + * Copyright (C) 2003 Jean-Louis Bergamo + * Copyright (C) 2004-2013 Laurent Destailleur + * Copyright (C) 2012 Regis Houssin + * Copyright (C) 2012 Florian Henry + * Copyright (C) 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 + * 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 . + */ + +require '../../main.inc.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/askpricesupplier.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/core/class/extrafields.class.php'; + + +if (!$user->admin) + accessforbidden(); + +$langs->load("admin"); +$langs->load("other"); +$langs->load("askpricesupplier"); + +$extrafields = new ExtraFields($db); +$form = new Form($db); + +// List of supported format +$tmptype2label=ExtraFields::$type2label; +$type2label=array(''); +foreach ($tmptype2label as $key => $val) $type2label[$key]=$langs->trans($val); + +$action=GETPOST('action', 'alpha'); +$attrname=GETPOST('attrname', 'alpha'); + +$elementtype='askpricesupplierdet'; //Must be the $table_element of the class that manage extrafield + +if (!$user->admin) accessforbidden(); + + +/* + * Actions + */ + +require DOL_DOCUMENT_ROOT.'/core/actions_extrafields.inc.php'; + + + +/* + * View + */ + +$textobject=$langs->transnoentitiesnoconv("CommRequests"); + +llxHeader('',$langs->trans("AskPriceSupplierSetup")); + +$linkback=''.$langs->trans("BackToModuleList").''; +print_fiche_titre($langs->trans("AskPriceSupplierSetup"),$linkback,'setup'); + +$head = askpricesupplier_admin_prepare_head(); + +dol_fiche_head($head, 'attributeslines', $langs->trans("CommRequests"), 0, 'askpricesupplier'); + + +print $langs->trans("DefineHereComplementaryAttributes",$textobject).'
'."\n"; +print '
'; + +// Load attribute_label +$extrafields->fetch_name_optionals_label($elementtype); + +print ""; + +print ''; +print ''; +print ''; +print ''; +print ''; +print ''; +print ''; +print ''; +print "\n"; + +$var=True; +foreach($extrafields->attribute_type as $key => $value) +{ + $var=!$var; + print ""; + print "\n"; + print "\n"; + print "\n"; + print '\n"; + print '\n"; + print '\n"; + print '\n"; + print ""; +} + +print "
'.$langs->trans("Label").''.$langs->trans("AttributeCode").''.$langs->trans("Type").''.$langs->trans("Size").''.$langs->trans("Unique").''.$langs->trans("Required").' 
".$extrafields->attribute_label[$key]."".$key."".$type2label[$extrafields->attribute_type[$key]]."'.$extrafields->attribute_size[$key]."'.yn($extrafields->attribute_unique[$key])."'.yn($extrafields->attribute_required[$key])."'.img_edit().''; + print "  ".img_delete()."
"; + +dol_fiche_end(); + + +// Buttons +if ($action != 'create' && $action != 'edit') +{ + print '
'; + print "".$langs->trans("NewAttribute").""; + print "
"; +} + + +/* ************************************************************************** */ +/* */ +/* Creation d'un champ optionnel */ +/* */ +/* ************************************************************************** */ + +if ($action == 'create') +{ + print "
"; + print_titre($langs->trans('NewAttribute')); + + require DOL_DOCUMENT_ROOT.'/core/tpl/admin_extrafields_add.tpl.php'; +} + +/* ************************************************************************** */ +/* */ +/* Edition d'un champ optionnel */ +/* */ +/* ************************************************************************** */ +if ($action == 'edit' && ! empty($attrname)) +{ + print "
"; + print_titre($langs->trans("FieldEdition", $attrname)); + + require DOL_DOCUMENT_ROOT.'/core/tpl/admin_extrafields_edit.tpl.php'; +} + +llxFooter(); + +$db->close(); diff --git a/htdocs/comm/askpricesupplier/card.php b/htdocs/comm/askpricesupplier/card.php new file mode 100644 index 00000000000..f2ca52f1f89 --- /dev/null +++ b/htdocs/comm/askpricesupplier/card.php @@ -0,0 +1,1821 @@ + + * Copyright (C) 2004-2014 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-2014 Juanjo Menent + * Copyright (C) 2010-2011 Philippe Grand + * Copyright (C) 2012-2013 Christophe Battarel + * Copyright (C) 2013-2014 Florian Henry + * Copyright (C) 2014 Ferran Marcet + * + * 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 . + */ + +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.formaskpricesupplier.class.php'; +require_once DOL_DOCUMENT_ROOT . '/comm/askpricesupplier/class/askpricesupplier.class.php'; +require_once DOL_DOCUMENT_ROOT . '/comm/action/class/actioncomm.class.php'; +require_once DOL_DOCUMENT_ROOT . '/core/modules/askpricesupplier/modules_askpricesupplier.php'; +require_once DOL_DOCUMENT_ROOT . '/core/lib/askpricesupplier.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/class/html.formprojet.class.php'; +} + +$langs->load('companies'); +$langs->load('askpricesupplier'); +$langs->load('compta'); +$langs->load('bills'); +$langs->load('orders'); +$langs->load('products'); +$langs->load("deliveries"); +$langs->load('sendings'); +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'); +$contactid = GETPOST('contactid','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, 'askpricesupplier', $id); + +$object = new AskPriceSupplier($db); +$extrafields = new ExtraFields($db); + +// fetch optionals attributes and labels +$extralabels = $extrafields->fetch_name_optionals_label($object->table_element); + +// 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('askpricesuppliercard','globalcard')); + +$permissionnote = $user->rights->askpricesupplier->creer; // Used by the include of actions_setnotes.inc.php + + +/* + * Actions + */ + +$parameters = array('socid' => $socid); +$reshook = $hookmanager->executeHooks('doActions', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks +if ($reshook < 0) setEventMessages($hookmanager->error, $hookmanager->errors, 'errors'); + +if (empty($reshook)) +{ + include DOL_DOCUMENT_ROOT . '/core/actions_setnotes.inc.php'; // Must be include, not includ_once + + // 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 = ''; + } + } + } + } + + // Delete askprice + else if ($action == 'confirm_delete' && $confirm == 'yes' && $user->rights->askpricesupplier->supprimer) + { + $result = $object->delete($user); + if ($result > 0) { + header('Location: ' . DOL_URL_ROOT . '/comm/askpricesupplier/list.php'); + exit(); + } else { + $langs->load("errors"); + setEventMessage($langs->trans($object->error), 'errors'); + } + } + + // Remove line + else if ($action == 'confirm_deleteline' && $confirm == 'yes' && $user->rights->askpricesupplier->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->thirdparty->default_lang); + $outputlangs->setDefaultLang($newlang); + } + $ret = $object->fetch($id); // Reload to get new records + $object->generateDocument($object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref); + } + + header('Location: ' . $_SERVER["PHP_SELF"] . '?id=' . $object->id); + exit(); + } + + // Validation + else if ($action == 'confirm_validate' && $confirm == 'yes' && + ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->askpricesupplier->creer)) + || (! empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->askpricesupplier->validate))) + ) + { + $result = $object->valid($user); + if ($result >= 0) + { + if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) + { + // Define output language + if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) + { + $outputlangs = $langs; + $newlang = ''; + if ($conf->global->MAIN_MULTILANGS && empty($newlang) && GETPOST('lang_id')) $newlang = GETPOST('lang_id','alpha'); + if ($conf->global->MAIN_MULTILANGS && empty($newlang)) $newlang = $object->thirdparty->default_lang; + if (! empty($newlang)) { + $outputlangs = new Translate("", $conf); + $outputlangs->setDefaultLang($newlang); + } + $model=$object->modelpdf; + $ret = $object->fetch($id); // Reload to get new records + + $object->generateDocument($model, $outputlangs, $hidedetails, $hidedesc, $hideref); + } + } + } else { + $langs->load("errors"); + if (count($object->errors) > 0) setEventMessage($object->errors, 'errors'); + else setEventMessage($langs->trans($object->error), 'errors'); + } + } + + else if ($action == 'setdate_livraison' && $user->rights->askpricesupplier->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); + } + + // Create askprice + else if ($action == 'add' && $user->rights->askpricesupplier->creer) + { + $object->socid = $socid; + $object->fetch_thirdparty(); + + $date_delivery = dol_mktime(12, 0, 0, GETPOST('liv_month'), GETPOST('liv_day'), GETPOST('liv_year')); + + if ($socid < 1) { + setEventMessage($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Customer")), 'errors'); + $action = 'create'; + $error ++; + } + + if (! $error) + { + $db->begin(); + + // Si on a selectionne une demande a copier, on realise la copie + if (GETPOST('createmode') == 'copy' && GETPOST('copie_askpricesupplier')) + { + if ($object->fetch(GETPOST('copie_askpricesupplier')) > 0) { + $object->ref = GETPOST('ref'); + $object->date_livraison = $date_delivery; + $object->shipping_method_id = GETPOST('shipping_method_id', 'int'); + $object->cond_reglement_id = GETPOST('cond_reglement_id'); + $object->mode_reglement_id = GETPOST('mode_reglement_id'); + $object->fk_account = GETPOST('fk_account', 'int'); + $object->remise_percent = GETPOST('remise_percent'); + $object->remise_absolue = GETPOST('remise_absolue'); + $object->socid = GETPOST('socid'); + $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_askpricesupplier')), 'errors'); + } + } else { + $object->ref = GETPOST('ref'); + $object->date_livraison = $date_delivery; + $object->demand_reason_id = GETPOST('demand_reason_id'); + $object->shipping_method_id = GETPOST('shipping_method_id', 'int'); + $object->cond_reglement_id = GETPOST('cond_reglement_id'); + $object->mode_reglement_id = GETPOST('mode_reglement_id'); + $object->fk_account = GETPOST('fk_account', 'int'); + $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]); + } + } + + // Fill array 'array_options' with data from add form + $ret = $extrafields->setOptionalsFromPost($extralabels, $object); + if ($ret < 0) { + $error ++; + $action = 'create'; + } + } + + if (! $error) + { + if ($origin && $originid) + { + $element = 'comm/askpricesupplier'; + $subelement = 'askpricesupplier'; + + $object->origin = $origin; + $object->origin_id = $originid; + + // Possibility to add external linked objects with hooks + $object->linked_objects [$object->origin] = $object->origin_id; + if (is_array($_POST['other_linked_objects']) && ! empty($_POST['other_linked_objects'])) { + $object->linked_objects = array_merge($object->linked_objects, $_POST['other_linked_objects']); + } + + $id = $object->create($user); + if ($id > 0) + { + dol_include_once('/' . $element . '/class/' . $subelement . '.class.php'); + + $classname = ucfirst($subelement); + $srcobject = new $classname($db); + + dol_syslog("Try to find source object origin=" . $object->origin . " originid=" . $object->origin_id . " to add lines"); + $result = $srcobject->fetch($object->origin_id); + + if ($result > 0) + { + $lines = $srcobject->lines; + if (empty($lines) && method_exists($srcobject, 'fetch_lines')) + { + $srcobject->fetch_lines(); + $lines = $srcobject->lines; + } + + $fk_parent_line=0; + $num=count($lines); + for ($i=0;$i<$num;$i++) + { + $label=(! empty($lines[$i]->label)?$lines[$i]->label:''); + $desc=(! empty($lines[$i]->desc)?$lines[$i]->desc:$lines[$i]->libelle); + + // Positive line + $product_type = ($lines[$i]->product_type ? $lines[$i]->product_type : 0); + + // Reset fk_parent_line for no child products and special product + if (($lines[$i]->product_type != 9 && empty($lines[$i]->fk_parent_line)) || $lines[$i]->product_type == 9) { + $fk_parent_line = 0; + } + + // Extrafields + if (empty($conf->global->MAIN_EXTRAFIELDS_DISABLED) && method_exists($lines[$i], 'fetch_optionals')) { + $lines[$i]->fetch_optionals($lines[$i]->rowid); + $array_option = $lines[$i]->array_options; + } + + $tva_tx=get_default_tva($mysoc, $object->thirdparty); + + $result = $object->addline($desc, $lines[$i]->subprice, $lines[$i]->qty, $tva_tx, $lines[$i]->localtax1_tx, $lines[$i]->localtax2_tx, $lines[$i]->fk_product, $lines[$i]->remise_percent, 'HT', 0, $lines[$i]->info_bits, $product_type, $lines[$i]->rang, $lines[$i]->special_code, $fk_parent_line, $lines[$i]->fk_fournprice, $lines[$i]->pa_ht, $label, $array_option); + + if ($result > 0) { + $lineid = $result; + } else { + $lineid = 0; + $error ++; + break; + } + + // Defined the new fk_parent_line + if ($result > 0 && $lines[$i]->product_type == 9) { + $fk_parent_line = $result; + } + } + + // Hooks + $parameters = array('objFrom' => $srcobject); + $reshook = $hookmanager->executeHooks('createFrom', $parameters, $object, $action); // Note that $action and $object may have been + // modified by hook + if ($reshook < 0) + $error ++; + } else { + setEventMessages($srcobject->error, $srcobject->errors, 'errors'); + $error ++; + } + } else { + setEventMessages($object->error, $object->errors, 'errors'); + $error ++; + } + } // Standard creation + else + { + $id = $object->create($user); + } + + if ($id > 0) + { + if (! $error) + { + $db->commit(); + + // Define output language + if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) + { + $outputlangs = $langs; + $newlang = ''; + if ($conf->global->MAIN_MULTILANGS && empty($newlang) && GETPOST('lang_id')) $newlang = GETPOST('lang_id','alpha'); + if ($conf->global->MAIN_MULTILANGS && empty($newlang)) $newlang = $object->thirdparty->default_lang; + if (! empty($newlang)) { + $outputlangs = new Translate("", $conf); + $outputlangs->setDefaultLang($newlang); + } + $model=$object->modelpdf; + + $ret = $object->fetch($id); // Reload to get new records + $result=$object->generateDocument($model, $outputlangs, $hidedetails, $hidedesc, $hideref); + if ($result < 0) dol_print_error($db,$result); + } + + header('Location: ' . $_SERVER["PHP_SELF"] . '?id=' . $id); + exit(); + } + else + { + $db->rollback(); + $action='create'; + } + } + else + { + setEventMessages($object->error, $object->errors, 'errors'); + $db->rollback(); + $action='create'; + } + } + } + } + + // Reopen proposal + else if ($action == 'confirm_reopen' && $user->rights->askpricesupplier->cloturer && ! GETPOST('cancel')) { + // prevent browser refresh from reopening proposal several times + if ($object->statut == 2 || $object->statut == 3 || $object->statut == 4) { + $object->reopen($user, 1); + } + } + + // Close proposal + else if ($action == 'setstatut' && $user->rights->askpricesupplier->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')); + } + } + } + + include DOL_DOCUMENT_ROOT.'/core/actions_printing.inc.php'; + + + /* + * Send mail + */ + + // Actions to send emails + $actiontypecode='AC_ASKPRICE'; + $trigger_name='ASKPRICESUPPLIER_SENTBYMAIL'; + $paramname='id'; + $mode='emailfromaskpricesupplier'; + include DOL_DOCUMENT_ROOT.'/core/actions_sendmails.inc.php'; + + + + // Go back to draft + if ($action == 'modif' && $user->rights->askpricesupplier->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->thirdparty->default_lang); + $outputlangs->setDefaultLang($newlang); + } + $ret = $object->fetch($id); // Reload to get new records + $object->generateDocument($object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref); + } + } + + else if ($action == "setabsolutediscount" && $user->rights->askpricesupplier->creer) { + if ($_POST["remise_id"]) { + if ($object->id > 0) { + $result = $object->insert_discount($_POST["remise_id"]); + if ($result < 0) { + setEventMessage($object->error, 'errors'); + } + } + } + } + + // Add line + else if ($action == 'addline' && $user->rights->askpricesupplier->creer) { + + // Set if we used free entry or predefined product + $predef=''; + $product_desc=(GETPOST('dp_desc')?GETPOST('dp_desc'):''); + $price_ht = GETPOST('price_ht'); + + if (GETPOST('prod_entry_mode') == 'free') + { + $idprod=0; + $tva_tx = (GETPOST('tva_tx') ? GETPOST('tva_tx') : 0); + } + else + { + $idprod=GETPOST('idprod', 'int'); + $tva_tx = ''; + } + + $qty = GETPOST('qty' . $predef); + $remise_percent = GETPOST('remise_percent' . $predef); + + // Extrafields + $extrafieldsline = new ExtraFields($db); + $extralabelsline = $extrafieldsline->fetch_name_optionals_label($object->table_element_line); + $array_option = $extrafieldsline->getOptionalsFromPost($extralabelsline, $predef); + // Unset extrafield + if (is_array($extralabelsline)) { + // Get extra fields + foreach ($extralabelsline as $key => $value) { + unset($_POST["options_" . $key]); + } + } + + if (GETPOST('prod_entry_mode') == 'free' && empty($idprod) && GETPOST('type') < 0) { + setEventMessage($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Type")), 'errors'); + $error ++; + } + + if (GETPOST('prod_entry_mode') == 'free' && empty($idprod) && $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 (GETPOST('prod_entry_mode') == 'free' && empty($idprod) && empty($product_desc)) { + setEventMessage($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Description")), 'errors'); + $error ++; + } + + if (! $error && ($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'); + + $db->begin(); + + // 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 + $tva_tx = get_default_tva($mysoc, $object->thirdparty, $prod->id); + $tva_npr = get_default_npr($mysoc, $object->thirdparty, $prod->id); + + //On garde le prix indiqué dans l'input pour la demande de prix fournisseur + //$pu_ht = $prod->price; + $pu_ht = price2num($price_ht, 'MU'); + //$pu_ttc = $prod->price_ttc; + $pu_ttc = price2num($pu_ht * (1 + ($tva_tx / 100)), 'MU'); + + $price_min = $prod->price_min; + $price_base_type = $prod->price_base_type; + + // On defini prix unitaire + if (! empty($conf->global->PRODUIT_MULTIPRICES) && $object->thirdparty->price_level) + { + $pu_ht = $prod->multiprices[$object->thirdparty->price_level]; + $pu_ttc = $prod->multiprices_ttc[$object->thirdparty->price_level]; + $price_min = $prod->multiprices_min[$object->thirdparty->price_level]; + $price_base_type = $prod->multiprices_base_type[$object->thirdparty->price_level]; + if (isset($prod->multiprices_tva_tx[$object->thirdparty->price_level])) $tva_tx=$prod->multiprices_tva_tx[$object->thirdparty->price_level]; + if (isset($prod->multiprices_recuperableonly[$object->thirdparty->price_level])) $tva_npr=$prod->multiprices_recuperableonly[$object->thirdparty->price_level]; + } + elseif (! empty($conf->global->PRODUIT_CUSTOMER_PRICES)) + { + require_once DOL_DOCUMENT_ROOT . '/product/class/productcustomerprice.class.php'; + + $prodcustprice = new Productcustomerprice($db); + + $filter = array('t.fk_product' => $prod->id,'t.fk_soc' => $object->thirdparty->id); + + $result = $prodcustprice->fetch_all('', '', 0, 0, $filter); + if ($result) { + if (count($prodcustprice->lines) > 0) { + $pu_ht = price($prodcustprice->lines [0]->price); + $pu_ttc = price($prodcustprice->lines [0]->price_ttc); + $price_base_type = $prodcustprice->lines [0]->price_base_type; + $prod->tva_tx = $prodcustprice->lines [0]->tva_tx; + } + } + } + + // if price ht is forced (ie: calculated by margin rate and cost price) + if (! empty($price_ht)) { + $pu_ht = price2num($price_ht, 'MU'); + $pu_ttc = price2num($pu_ht * (1 + ($tva_tx / 100)), 'MU'); + } + + // 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). + elseif ($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->thirdparty->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' . $predef) ? GETPOST('fournprice' . $predef) : ''); + $buyingprice = (GETPOST('buying_price' . $predef) ? GETPOST('buying_price' . $predef) : ''); + + // Local Taxes + $localtax1_tx = get_localtax($tva_tx, 1, $object->thirdparty); + $localtax2_tx = get_localtax($tva_tx, 2, $object->thirdparty); + + $info_bits = 0; + if ($tva_npr) + $info_bits |= 0x01; + + if (! empty($price_min) && (price2num($pu_ht) * (1 - price2num($remise_percent) / 100) < price2num($price_min))) { + $mesg = $langs->trans("CantBeLessThanMinPrice", price(price2num($price_min, 'MU'), 0, $langs, 0, 0, - 1, $conf->currency)); + setEventMessage($mesg, 'errors'); + } else { + // Insert line + $ref_fourn = GETPOST('fourn_ref'); + $result = $object->addline($desc, $pu_ht, $qty, $tva_tx, $localtax1_tx, $localtax2_tx, $idprod, $remise_percent, $price_base_type, $pu_ttc, $info_bits, $type, - 1, 0, GETPOST('fk_parent_line'), $fournprice, $buyingprice, $label, $array_option, $ref_fourn); + + if ($result > 0) { + $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->thirdparty->default_lang); + $outputlangs->setDefaultLang($newlang); + } + $ret = $object->fetch($id); // Reload to get new records + $object->generateDocument($object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref); + } + + unset($_POST['prod_entry_mode']); + + unset($_POST['qty']); + unset($_POST['type']); + 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']); + unset($_POST['np_marginRate']); + unset($_POST['np_markRate']); + unset($_POST['dp_desc']); + unset($_POST['idprod']); + + } else { + $db->rollback(); + + setEventMessage($object->error, 'errors'); + } + } + } + } + + // Mise a jour d'une ligne dans la demande de prix + else if ($action == 'updateligne' && $user->rights->askpricesupplier->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->thirdparty); + $localtax2_rate = get_localtax($vat_rate, 2, $object->thirdparty); + $pu_ht = GETPOST('price_ht') ? GETPOST('price_ht') : 0; + + // Add buying price + $fournprice = (GETPOST('fournprice') ? GETPOST('fournprice') : ''); + $buyingprice = (GETPOST('buying_price') ? GETPOST('buying_price') : ''); + + // Extrafields + $extrafieldsline = new ExtraFields($db); + $extralabelsline = $extrafieldsline->fetch_name_optionals_label($object->table_element_line); + $array_option = $extrafieldsline->getOptionalsFromPost($extralabelsline); + // Unset extrafield + if (is_array($extralabelsline)) { + // Get extra fields + foreach ($extralabelsline as $key => $value) { + unset($_POST["options_" . $key]); + } + } + + // Define special_code for special lines + $special_code=GETPOST('special_code'); + 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->thirdparty->price_level)) + $price_min = $product->multiprices_min [$object->thirdparty->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", price(price2num($price_min, 'MU'), 0, $langs, 0, 0, - 1, $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) { + $db->begin(); + $ref_fourn = GETPOST('fourn_ref'); + $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, $array_option, $ref_fourn); + + if ($result >= 0) { + $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->thirdparty->default_lang); + $outputlangs->setDefaultLang($newlang); + } + $ret = $object->fetch($id); // Reload to get new records + $object->generateDocument($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 { + $db->rollback(); + + setEventMessage($object->error, 'errors'); + } + } + } + + else if ($action == 'updateligne' && $user->rights->askpricesupplier->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->askpricesupplier->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->thirdparty->default_lang); + $outputlangs->setDefaultLang($newlang); + } + $ret = $object->fetch($id); // Reload to get new records + $result = $object->generateDocument($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->askpricesupplier->creer) { + if ($object->id > 0) { + require_once DOL_DOCUMENT_ROOT . '/core/lib/files.lib.php'; + + $langs->load("other"); + $upload_dir = $conf->askpricesupplier->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->askpricesupplier->creer) { + $object->setProject($_POST['projectid']); + } + + // Delai de livraison + else if ($action == 'setavailability' && $user->rights->askpricesupplier->creer) { + $result = $object->availability($_POST['availability_id']); + } + + // Conditions de reglement + else if ($action == 'setconditions' && $user->rights->askpricesupplier->creer) { + $result = $object->setPaymentTerms(GETPOST('cond_reglement_id', 'int')); + } + + else if ($action == 'setremisepercent' && $user->rights->askpricesupplier->creer) { + $result = $object->set_remise_percent($user, $_POST['remise_percent']); + } + + else if ($action == 'setremiseabsolue' && $user->rights->askpricesupplier->creer) { + $result = $object->set_remise_absolue($user, $_POST['remise_absolue']); + } + + // Mode de reglement + else if ($action == 'setmode' && $user->rights->askpricesupplier->creer) { + $result = $object->setPaymentMethods(GETPOST('mode_reglement_id', 'int')); + } + + /* + * Ordonnancement des lignes + */ + + else if ($action == 'up' && $user->rights->askpricesupplier->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->thirdparty->default_lang); + $outputlangs->setDefaultLang($newlang); + } + $ret = $object->fetch($id); // Reload to get new records + $object->generateDocument($object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref); + } + + header('Location: ' . $_SERVER["PHP_SELF"] . '?id=' . $id . '#' . GETPOST('rowid')); + exit(); + } + + else if ($action == 'down' && $user->rights->askpricesupplier->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->thirdparty->default_lang); + $outputlangs->setDefaultLang($newlang); + } + $ret = $object->fetch($id); // Reload to get new records + $object->generateDocument($object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref); + } + + header('Location: ' . $_SERVER["PHP_SELF"] . '?id=' . $id . '#' . GETPOST('rowid')); + exit(); + } else if ($action == 'update_extras') { + // Fill array 'array_options' with data from update form + $extralabels = $extrafields->fetch_name_optionals_label($object->table_element); + $ret = $extrafields->setOptionalsFromPost($extralabels, $object, GETPOST('attribute')); + if ($ret < 0) + $error ++; + + if (! $error) { + // Actions on extra fields (by external module or standard code) + $hookmanager->initHooks(array('askpricesupplierdao')); + $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)) { + $result = $object->insertExtraFields(); + if ($result < 0) { + $error ++; + } + } else if ($reshook < 0) + $error ++; + } + + if ($error) + $action = 'edit_extras'; + } +} + + +/* + * View + */ + +llxHeader('', $langs->trans('CommRequests'), 'EN:Ask_Price_Supplier|FR:Demande_de_prix_fournisseur'); + +$form = new Form($db); +$formother = new FormOther($db); +$formfile = new FormFile($db); +$formaskpricesupplier = new FormAskPriceSupplier($db); +$companystatic = new Societe($db); + +$now = dol_now(); + +// Add new askprice +if ($action == 'create') +{ + print_fiche_titre($langs->trans("NewAskPrice")); + + $soc = new Societe($db); + if ($socid > 0) + $res = $soc->fetch($socid); + + // Load objectsrc + if (! empty($origin) && ! empty($originid)) + { + $element = 'comm/askpricesupplier'; + $subelement = 'askpricesupplier'; + + dol_include_once('/' . $element . '/class/' . $subelement . '.class.php'); + + $classname = ucfirst($subelement); + $objectsrc = new $classname($db); + $objectsrc->fetch($originid); + if (empty($objectsrc->lines) && method_exists($objectsrc, 'fetch_lines')) + { + $objectsrc->fetch_lines(); + } + $objectsrc->fetch_thirdparty(); + + $projectid = (! empty($objectsrc->fk_project) ? $objectsrc->fk_project : ''); + $soc = $objectsrc->thirdparty; + + $cond_reglement_id = (! empty($objectsrc->cond_reglement_id)?$objectsrc->cond_reglement_id:(! empty($soc->cond_reglement_id)?$soc->cond_reglement_id:1)); + $mode_reglement_id = (! empty($objectsrc->mode_reglement_id)?$objectsrc->mode_reglement_id:(! empty($soc->mode_reglement_id)?$soc->mode_reglement_id:0)); + $remise_percent = (! empty($objectsrc->remise_percent)?$objectsrc->remise_percent:(! empty($soc->remise_percent)?$soc->remise_percent:0)); + $remise_absolue = (! empty($objectsrc->remise_absolue)?$objectsrc->remise_absolue:(! empty($soc->remise_absolue)?$soc->remise_absolue:0)); + + // Replicate extrafields + $objectsrc->fetch_optionals($originid); + $object->array_options = $objectsrc->array_options; + + } + + $object = new AskPriceSupplier($db); + + print '
'; + print ''; + print ''; + if ($origin != 'project' && $originid) { + print ''; + print ''; + } + + dol_fiche_head(); + + print ''; + + // Reference + print ''; + + // Third party + print ''; + print ''; + if ($socid > 0) { + print ''; + } else { + print ''; + } + print '' . "\n"; + + // Terms of payment + print ''; + + // Mode of payment + print ''; + + // Bank Account + if (! empty($conf->global->BANK_ASK_PAYMENT_BANK_DURING_PROPOSAL) && $conf->banque->enabled) { + print ''; + } + + // Shipping Method + if (! empty($conf->expedition->enabled)) { + print ''; + } + + // Delivery date (or manufacturing) + print ''; + print ''; + + + // Model + print ''; + print ''; + print '"; + + // Project + if (! empty($conf->projet->enabled) && $socid > 0) { + + $formproject = new FormProjets($db); + + $projectid = 0; + if ($origin == 'project') + $projectid = ($originid ? $originid : 0); + + print ''; + print ''; + print ''; + } + + + // Other attributes + $parameters = array('colspan' => ' colspan="3"'); + $reshook = $hookmanager->executeHooks('formObjectOptions', $parameters, $object, $action); // Note that $action and $object may have been modified + // by + // hook + if (empty($reshook) && ! empty($extrafields->attribute_label)) { + print $object->showOptionals($extrafields, 'edit'); + } + + + // Lines from source + if (! empty($origin) && ! empty($originid) && is_object($objectsrc)) + { + // TODO for compatibility + if ($origin == 'contrat') { + // Calcul contrat->price (HT), contrat->total (TTC), contrat->tva + $objectsrc->remise_absolue = $remise_absolue; + $objectsrc->remise_percent = $remise_percent; + $objectsrc->update_price(1, - 1, 1); + } + + print "\n"; + print "\n"; + print '' . "\n"; + print '' . "\n"; + print '' . "\n"; + print ''; + print ''; + + print ''; + print ''; + print '"; + if ($mysoc->localtax1_assuj == "1" || $objectsrc->total_localtax1 != 0 ) // Localtax1 + { + print '"; + } + + if ($mysoc->localtax2_assuj == "1" || $objectsrc->total_localtax2 != 0) // Localtax2 + { + print '"; + } + print '"; + } + + print "
' . $langs->trans('Ref') . '' . $langs->trans("Draft") . '
' . $langs->trans('Supplier') . ''; + print $soc->getNomUrl(1); + print ''; + print ''; + print $form->select_company('', 'socid', 's.fournisseur = 1', 1); + print '
' . $langs->trans('PaymentConditionsShort') . ''; + $form->select_conditions_paiements($soc->cond_reglement_id, 'cond_reglement_id', -1, 1); + print '
' . $langs->trans('PaymentMode') . ''; + $form->select_types_paiements($soc->mode_reglement_id, 'mode_reglement_id'); + print '
' . $langs->trans('BankAccount') . ''; + $form->select_comptes($fk_account, 'fk_account', 0, '', 1); + print '
' . $langs->trans('SendingMethod') . ''; + print $form->selectShippingMethod($shipping_method_id, 'shipping_method_id', '', 1); + print '
' . $langs->trans("DeliveryDate") . ''; + if ($conf->global->DATE_LIVRAISON_WEEK_DELAY != "") { + $tmpdte = time() + ((7 * $conf->global->DATE_LIVRAISON_WEEK_DELAY) * 24 * 60 * 60); + $syear = date("Y", $tmpdte); + $smonth = date("m", $tmpdte); + $sday = date("d", $tmpdte); + $form->select_date($syear."-".$smonth."-".$sday, 'liv_', '', '', '', "addask"); + } else { + $form->select_date(-1, 'liv_', '', '', '', "addask", 1, 1); + } + print '
' . $langs->trans("DefaultModel") . ''; + $liste = ModelePDFAskPriceSupplier::liste_modeles($db); + print $form->selectarray('model', $liste, ($conf->global->ASKPRICESUPPLIER_ADDON_PDF_ODT_DEFAULT ? $conf->global->ASKPRICESUPPLIER_ADDON_PDF_ODT_DEFAULT : $conf->global->ASKPRICESUPPLIER_ADDON_PDF)); + print "
' . $langs->trans("Project") . ''; + + $numprojet = $formproject->select_projects($soc->id, $projectid); + if ($numprojet == 0) { + $langs->load("projects"); + print '   ' . $langs->trans("AddProject") . ''; + } + print '
' . $langs->trans('CommRequest') . '' . $objectsrc->getNomUrl(1) . '
' . $langs->trans('TotalHT') . '' . price($objectsrc->total_ht) . '
' . $langs->trans('TotalVAT') . '' . price($objectsrc->total_tva) . "
' . $langs->transcountry("AmountLT1", $mysoc->country_code) . '' . price($objectsrc->total_localtax1) . "
' . $langs->transcountry("AmountLT2", $mysoc->country_code) . '' . price($objectsrc->total_localtax2) . "
' . $langs->trans('TotalTTC') . '' . price($objectsrc->total_ttc) . "
\n"; + + + /* + * Combobox pour la fonction de copie + */ + + if (empty($conf->global->ASKPRICESUPPLIER_CLONE_ON_CREATE_PAGE)) print ''; + + if (! empty($conf->global->ASKPRICESUPPLIER_CLONE_ON_CREATE_PAGE) || ! empty($conf->global->PRODUCT_SHOW_WHEN_CREATE)) print '
'; + if (! empty($conf->global->ASKPRICESUPPLIER_CLONE_ON_CREATE_PAGE)) + { + // For backward compatibility + print ''; + print ''; + print ''; + print ''; + + if (! empty($conf->global->PRODUCT_SHOW_WHEN_CREATE)) + print ''; + + print ''; + print ''; + } + + if (! empty($conf->global->PRODUCT_SHOW_WHEN_CREATE)) + { + print ''; + } + if (! empty($conf->global->ASKPRICESUPPLIER_CLONE_ON_CREATE_PAGE) || ! empty($conf->global->PRODUCT_SHOW_WHEN_CREATE)) print '
' . $langs->trans("CopyAskFrom") . ' '; + $liste_ask = array(); + $liste_ask [0] = ''; + + $sql = "SELECT p.rowid as id, p.ref, s.nom"; + $sql .= " FROM " . MAIN_DB_PREFIX . "askpricesupplier p"; + $sql .= ", " . MAIN_DB_PREFIX . "societe s"; + $sql .= " WHERE s.rowid = p.fk_soc"; + $sql .= " AND p.entity = " . $conf->entity; + $sql .= " AND p.fk_statut <> 0"; + $sql .= " ORDER BY Id"; + + $resql = $db->query($sql); + if ($resql) { + $num = $db->num_rows($resql); + $i = 0; + while ($i < $num) { + $row = $db->fetch_row($resql); + $askPriceSupplierRefAndSocName = $row [1] . " - " . $row [2]; + $liste_ask [$row [0]] = $askPriceSupplierRefAndSocName; + $i ++; + } + print $form->selectarray("copie_askpricesupplier", $liste_ask, 0); + } else { + dol_print_error($db); + } + print '
 
' . $langs->trans("CreateEmptyAsk") . '
'; + if (! empty($conf->product->enabled) || ! empty($conf->service->enabled)) { + $lib = $langs->trans("ProductsAndServices"); + + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + for($i = 1; $i <= $conf->global->PRODUCT_SHOW_WHEN_CREATE; $i ++) { + print ''; + print ''; + print ''; + print ''; + } + print "
' . $lib . '' . $langs->trans("Qty") . '' . $langs->trans("ReductionShort") . '
'; + // multiprix + if ($conf->global->PRODUIT_MULTIPRICES && $soc->price_level) + $form->select_produits('', "idprod" . $i, '', $conf->product->limit_size, $soc->price_level); + else + $form->select_produits('', "idprod" . $i, '', $conf->product->limit_size); + print '%
"; + } + print '
'; + + dol_fiche_end(); + + print '
'; + print ''; + print '     '; + print ''; + print '
'; + + print "
"; + + + // Show origin lines + if (! empty($origin) && ! empty($originid) && is_object($objectsrc)) { + print '
'; + + $title = $langs->trans('ProductsAndServices'); + print_titre($title); + + print ''; + + $objectsrc->printOriginLinesList(); + + print '
'; + } + +} else { + /* + * Show object in view mode + */ + + $soc = new Societe($db); + $soc->fetch($object->socid); + + $head = askpricesupplier_prepare_head($object); + dol_fiche_head($head, 'comm', $langs->trans('CommRequest'), 0, 'askpricesupplier'); + + $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.fournisseur=1'))); + // Paiement incomplet. On demande si motif = escompte ou autre + $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"] . '?id=' . $object->id, $langs->trans('CloneAsk'), $langs->trans('ConfirmCloneAsk', $object->ref), 'confirm_clone', $formquestion, 'yes', 1); + } + + // Confirm delete + else if ($action == 'delete') { + $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"] . '?id=' . $object->id, $langs->trans('DeleteAsk'), $langs->trans('ConfirmDeleteAsk', $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('ConfirmReOpenAsk', $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 askprice + 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 ++; + setEventMessage($object->error, 'errors'); + } + } else { + $numref = $object->ref; + } + + $text = $langs->trans('ConfirmValidateAsk', $numref); + if (! empty($conf->notification->enabled)) { + require_once DOL_DOCUMENT_ROOT . '/core/class/notify.class.php'; + $notify = new Notify($db); + $text .= '
'; + $text .= $notify->confirmMessage('ASKPRICESUPPLIER_VALIDATE', $object->socid); + } + + if (! $error) + $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"] . '?id=' . $object->id, $langs->trans('ValidateAsk'), $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 ''; + + // Company + print ''; + print ''; + + // Payment term + print ''; + print ''; + + // Delivery date + $langs->load('deliveries'); + print ''; + print ''; + + // Payment mode + print ''; + print ''; + + // Project + if (! empty($conf->projet->enabled)) { + $langs->load("projects"); + print ''; + } else { + print '
' . $langs->trans('Ref') . ''; + print $form->showrefnav($object, 'ref', $linkback, 1, 'ref', 'ref', ''); + print '
' . $langs->trans('Supplier') . '' . $soc->getNomUrl(1) . '
'; + print ''; + if ($action != 'editconditions' && ! empty($object->brouillon)) + print ''; + print '
'; + print $langs->trans('PaymentConditionsShort'); + print 'id . '">' . img_edit($langs->transnoentitiesnoconv('SetConditions'), 1) . '
'; + print '
'; + if ($action == 'editconditions') { + $form->form_conditions_reglement($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->cond_reglement_id, 'cond_reglement_id', 1); + } else { + $form->form_conditions_reglement($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->cond_reglement_id, 'none', 1); + } + print '
'; + print ''; + if ($action != 'editdate_livraison' && ! empty($object->brouillon)) + print ''; + print '
'; + print $langs->trans('DeliveryDate'); + print 'id . '">' . img_edit($langs->transnoentitiesnoconv('SetDeliveryDate'), 1) . '
'; + print '
'; + if ($action == 'editdate_livraison') { + print '
'; + print ''; + print ''; + $form->select_date($object->date_livraison, 'liv_', '', '', '', "editdate_livraison"); + print ''; + print '
'; + } else { + print dol_print_date($object->date_livraison, 'daytext'); + } + print '
'; + print ''; + if ($action != 'editmode' && ! empty($object->brouillon)) + print ''; + print '
'; + print $langs->trans('PaymentMode'); + print 'id . '">' . img_edit($langs->transnoentitiesnoconv('SetMode'), 1) . '
'; + print '
'; + if ($action == 'editmode') { + $form->form_modes_reglement($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->mode_reglement_id, 'mode_reglement_id'); + } else { + $form->form_modes_reglement($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->mode_reglement_id, 'none'); + } + print '
'; + print ''; + if ($user->rights->askpricesupplier->creer) { + if ($action != 'classify') + print ''; + print '
'; + print $langs->trans('Project') . '' . img_edit($langs->transnoentitiesnoconv('SetProject')) . '
'; + print '
'; + if ($action == 'classify') { + $form->form_project($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->socid, $object->fk_project, 'projectid'); + } else { + $form->form_project($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->socid, $object->fk_project, 'none'); + } + print '
'; + if (! empty($object->fk_project)) { + print ''; + $proj = new Project($db); + $proj->fetch($object->fk_project); + print ''; + print $proj->ref; + print ''; + print ''; + } else { + print ' '; + } + } + print ''; + } + + + if ($soc->outstanding_limit) + { + // Outstanding Bill + print ''; + print $langs->trans('OutstandingBill'); + print ''; + print price($soc->get_OutstandingBill()) . ' / '; + print price($soc->outstanding_limit, 0, '', 1, - 1, - 1, $conf->currency); + print ''; + print ''; + } + + if (! empty($conf->global->BANK_ASK_PAYMENT_BANK_DURING_PROPOSAL) && $conf->banque->enabled) + { + // Bank Account + print ''; + print ''; + if ($action != 'editbankaccount' && $user->rights->askpricesupplier->creer) + print ''; + print '
'; + print $langs->trans('BankAccount'); + print 'id.'">'.img_edit($langs->trans('SetBankAccount'),1).'
'; + print ''; + if ($action == 'editbankaccount') { + $form->formSelectAccount($_SERVER['PHP_SELF'].'?id='.$object->id, $object->fk_account, 'fk_account', 1); + } else { + $form->formSelectAccount($_SERVER['PHP_SELF'].'?id='.$object->id, $object->fk_account, 'none'); + } + print ''; + print ''; + } + + // Other attributes + $cols = 3; + include DOL_DOCUMENT_ROOT . '/core/tpl/extrafields_view.tpl.php'; + + // Amount HT + print '' . $langs->trans('AmountHT') . ''; + print '' . price($object->total_ht, '', $langs, 0, - 1, - 1, $conf->currency) . ''; + print ''; + + // Margin Infos + if (! empty($conf->margin->enabled)) { + print ''; + $object->displayMarginInfos(); + print ''; + } + print ''; + + // Amount VAT + print '' . $langs->trans('AmountVAT') . ''; + print '' . price($object->total_tva, '', $langs, 0, - 1, - 1, $conf->currency) . ''; + print ''; + + // Amount Local Taxes + if ($mysoc->localtax1_assuj == "1" || $object->total_localtax1 != 0) // Localtax1 + { + print '' . $langs->transcountry("AmountLT1", $mysoc->country_code) . ''; + print '' . price($object->total_localtax1, '', $langs, 0, - 1, - 1, $conf->currency) . ''; + print ''; + } + if ($mysoc->localtax2_assuj == "1" || $object->total_localtax2 != 0) // Localtax2 + { + print '' . $langs->transcountry("AmountLT2", $mysoc->country_code) . ''; + print '' . price($object->total_localtax2, '', $langs, 0, - 1, - 1, $conf->currency) . ''; + print ''; + } + + // Amount TTC + print '' . $langs->trans('AmountTTC') . ''; + print '' . price($object->total_ttc, '', $langs, 0, - 1, - 1, $conf->currency) . ''; + print ''; + + // Statut + print '' . $langs->trans('Status') . '' . $object->getLibStatut(4) . ''; + + print '
'; + + if (! empty($conf->global->MAIN_DISABLE_CONTACTS_TAB)) { + $blocname = 'contacts'; + $title = $langs->trans('ContactsAddresses'); + include DOL_DOCUMENT_ROOT . '/core/tpl/bloc_showhide.tpl.php'; + } + + if (! empty($conf->global->MAIN_DISABLE_NOTES_TAB)) { + $blocname = 'notes'; + $title = $langs->trans('Notes'); + include DOL_DOCUMENT_ROOT . '/core/tpl/bloc_showhide.tpl.php'; + } + + /* + * Lines + */ + + // Show object lines + $result = $object->getLinesArray(); + + print '
+ + + + + '; + + if (! empty($conf->use_javascript_ajax) && $object->statut == 0) { + include DOL_DOCUMENT_ROOT . '/core/tpl/ajaxrow.tpl.php'; + } + + print ''; + + if (! empty($object->lines)) + $ret = $object->printObjectLines($action, $mysoc, $soc, $lineid, 1); + + // Form to add new line + if ($object->statut == 0 && $user->rights->askpricesupplier->creer) + { + if ($action != 'editline') + { + $var = true; + + // Add products/services form + $object->formAddObjectLine(1, $mysoc, $soc); + + $parameters = array(); + $reshook = $hookmanager->executeHooks('formAddObjectLine', $parameters, $object, $action); // Note that $action and $object may have been modified by hook + } + } + + print '
'; + + print "
\n"; + + dol_fiche_end(); + + if ($action == 'statut') + { + /* + * Form to close proposal (signed or not) + */ + $form_close = '
'; + $form_close .= '

'.$langs->trans('AskPriceSupplierRefFournNotice').'

'; + $form_close .= ''; + $form_close .= ''; + $form_close .= ''; + $form_close .= ''; + $form_close .= ''; + $form_close .= '
' . $langs->trans("CloseAs") . ''; + $form_close .= ''; + $form_close .= ''; + $form_close .= '
' . $langs->trans('Note') . '
'; + $form_close .= ''; + $form_close .= '   '; + $form_close .= ' '; + $form_close .= '
'; + + print $form_close; + } + + /* + * Boutons Actions + */ + if ($action != 'presend') { + print '
'; + + $parameters = array(); + $reshook = $hookmanager->executeHooks('addMoreActionsButtons', $parameters, $object, $action); // Note that $action and $object may have been + // modified by hook + if (empty($reshook)) + { + if ($action != 'statut' && $action != 'editline') + { + // Validate + if ($object->statut == 0 && $object->total_ttc >= 0 && count($object->lines) > 0 && + ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->askpricesupplier->creer)) + || (! empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->askpricesupplier->validate))) + ) { + if (count($object->lines) > 0) + print ''; + // else print ''.$langs->trans('Validate').''; + } + + // Edit + if ($object->statut == 1 && $user->rights->askpricesupplier->creer) { + print ''; + } + + // ReOpen + if (($object->statut == 2 || $object->statut == 3 || $object->statut == 4) && $user->rights->askpricesupplier->cloturer) { + print ''; + } + + // Send + if ($object->statut == 1 || $object->statut == 2) { + if (empty($conf->global->MAIN_USE_ADVANCED_PERMS) || $user->rights->askpricesupplier->send) { + print ''; + } else + print ''; + } + + // Create an order + if (! empty($conf->commande->enabled) && $object->statut == 2) { + if ($user->rights->commande->creer) { + print ''; + } + } + + // Close + if ($object->statut == 1 && $user->rights->askpricesupplier->cloturer) { + print ''; + } + + // Clone + if ($user->rights->askpricesupplier->creer) { + print ''; + } + + // Delete + if ($user->rights->askpricesupplier->supprimer) { + print ''; + } + } + } + + print '
'; + } + print "
\n"; + + if ($action != 'presend') + { + print '
'; + + /* + * Documents generes + */ + $filename = dol_sanitizeFileName($object->ref); + $filedir = $conf->askpricesupplier->dir_output . "/" . dol_sanitizeFileName($object->ref); + $urlsource = $_SERVER["PHP_SELF"] . "?id=" . $object->id; + $genallowed = $user->rights->askpricesupplier->creer; + $delallowed = $user->rights->askpricesupplier->supprimer; + + $var = true; + + $somethingshown = $formfile->show_documents('askpricesupplier', $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, 'askpricesupplier', $socid); + + print '
'; + } + + /* + * Action presend + */ + if ($action == 'presend') + { + $object->fetch_projet(); + + $ref = dol_sanitizeFileName($object->ref); + include_once DOL_DOCUMENT_ROOT . '/core/lib/files.lib.php'; + $fileparams = dol_most_recent_file($conf->askpricesupplier->dir_output . '/' . $ref, preg_quote($ref, '/')); + $file = $fileparams ['fullname']; + + // 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->thirdparty->default_lang; + + if (!empty($newlang)) + { + $outputlangs = new Translate('', $conf); + $outputlangs->setDefaultLang($newlang); + $outputlangs->load('commercial'); + } + + // Build document if it not exists + if (! $file || ! is_readable($file)) { + $result = $object->generateDocument(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->askpricesupplier->dir_output . '/' . $ref, preg_quote($ref, '/')); + $file = $fileparams ['fullname']; + } + + print '
'; + print_titre($langs->trans('SendAskByMail')); + + // Create form object + include_once DOL_DOCUMENT_ROOT . '/core/class/html.formmail.class.php'; + $formmail = new FormMail($db); + $formmail->param['langsmodels']=(empty($newlang)?$langs->defaultlang:$newlang); + $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 = $outputlangs->trans('SendAskRef', '__ASKREF__'); + + $formmail->withfile = 2; + $formmail->withbody = 1; + $formmail->withdeliveryreceipt = 1; + $formmail->withcancel = 1; + + // Tableau des substitutions + $formmail->substit['__ASKREF__'] = $object->ref; + $formmail->substit['__SIGNATURE__'] = $user->signature; + $formmail->substit['__THIRPARTY_NAME__'] = $object->thirdparty->name; + $formmail->substit['__PROJECT_REF__'] = (is_object($object->projet)?$object->projet->ref:''); + $formmail->substit['__CONTACTCIVNAME__'] = ''; + $formmail->substit['__PERSONALIZED__'] = ''; + + // Tableau des parametres complementaires + $formmail->param['action'] = 'send'; + $formmail->param['models'] = 'askpricesupplier_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)); + } + + print $formmail->get_form(); + + print '
'; + } +} + +// End of page +llxFooter(); +$db->close(); diff --git a/htdocs/comm/askpricesupplier/class/askpricesupplier.class.php b/htdocs/comm/askpricesupplier/class/askpricesupplier.class.php new file mode 100644 index 00000000000..8740e139235 --- /dev/null +++ b/htdocs/comm/askpricesupplier/class/askpricesupplier.class.php @@ -0,0 +1,2872 @@ + + * Copyright (C) 2004 Eric Seigne + * Copyright (C) 2004-2011 Laurent Destailleur + * Copyright (C) 2005 Marc Barilley + * Copyright (C) 2005-2013 Regis Houssin + * Copyright (C) 2006 Andre Cianfarani + * Copyright (C) 2008 Raphael Bertrand + * Copyright (C) 2010-2014 Juanjo Menent + * Copyright (C) 2010-2011 Philippe Grand + * Copyright (C) 2012-2014 Christophe Battarel + * Copyright (C) 2013 Florian Henry + * Copyright (C) 2014 Marcos García + * + * 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/class/propal.class.php + * \brief File of class to manage proposals + */ + +require_once DOL_DOCUMENT_ROOT .'/fourn/class/fournisseur.product.class.php'; +require_once DOL_DOCUMENT_ROOT .'/core/class/commonobject.class.php'; +require_once DOL_DOCUMENT_ROOT .'/product/class/product.class.php'; +require_once DOL_DOCUMENT_ROOT .'/contact/class/contact.class.php'; +require_once DOL_DOCUMENT_ROOT .'/margin/lib/margins.lib.php'; + +/** + * Class to manage price ask supplier + */ +class AskPriceSupplier extends CommonObject +{ + public $element='askpricesupplier'; + public $table_element='askpricesupplier'; + public $table_element_line='askpricesupplierdet'; + public $fk_element='fk_askpricesupplier'; + protected $ismultientitymanaged = 1; // 0=No test on entity, 1=Test with field entity, 2=Test with link by societe + + /** + * {@inheritdoc} + */ + protected $table_ref_field = 'ref'; + + var $id; + + var $socid; // Id client + var $client; // Objet societe client (a charger par fetch_client) + + var $fk_project; + var $author; + var $ref; + var $ref_fourn; //Reference saisie lors de l'ajout d'une ligne à la demande + var $statut; // 0 (draft), 1 (validated), 2 (signed), 3 (not signed), 4 (billed) + var $datec; // Date of creation + var $date; // Date of proposal + var $date_livraison; + + var $user_author_id; + var $user_valid_id; + var $user_close_id; + + var $total_ht; // Total net of tax + var $total_tva; // Total VAT + var $total_localtax1; // Total Local Taxes 1 + var $total_localtax2; // Total Local Taxes 2 + var $total_ttc; // Total with tax + var $price; // deprecated (for compatibility) + var $tva; // deprecated (for compatibility) + var $total; // deprecated (for compatibility) + + var $cond_reglement_id; + var $cond_reglement_code; + var $fk_account; // Id of bank account + var $mode_reglement_id; + var $mode_reglement_code; + var $remise; + var $remise_percent; + var $remise_absolue; + var $note; // deprecated (for compatibility) + var $note_private; + var $note_public; + var $shipping_method_id; + + var $products=array(); + var $extraparams=array(); + + var $lines = array(); + var $line; + + var $origin; + var $origin_id; + + var $labelstatut=array(); + var $labelstatut_short=array(); + + var $nbtodo; + var $nbtodolate; + + var $specimen; + + + /** + * Constructor + * + * @param DoliDB $db Database handler + * @param int $socid Id third party + * @param int $askpricesupplierid Id askpricesupplier + */ + function __construct($db, $socid="", $askpricesupplierid=0) + { + global $conf,$langs; + + $this->db = $db; + $this->socid = $socid; + $this->id = $askpricesupplierid; + $this->products = array(); + $this->remise = 0; + $this->remise_percent = 0; + $this->remise_absolue = 0; + + $langs->load("askpricesupplier"); + $this->labelstatut[0]=(! empty($conf->global->ASKPRICESUPPLIER_STATUS_DRAFT_LABEL) ? $conf->global->ASKPRICESUPPLIER_STATUS_DRAFT_LABEL : $langs->trans("AskpricesupplierStatusDraft")); + $this->labelstatut[1]=(! empty($conf->global->ASKPRICESUPPLIER_STATUS_VALIDATED_LABEL) ? $conf->global->ASKPRICESUPPLIER_STATUS_VALIDATED_LABEL : $langs->trans("AskpricesupplierStatusValidated")); + $this->labelstatut[2]=(! empty($conf->global->ASKPRICESUPPLIER_STATUS_SIGNED_LABEL) ? $conf->global->ASKPRICESUPPLIER_STATUS_SIGNED_LABEL : $langs->trans("AskpricesupplierStatusSigned")); + $this->labelstatut[3]=(! empty($conf->global->ASKPRICESUPPLIER_STATUS_NOTSIGNED_LABEL) ? $conf->global->ASKPRICESUPPLIER_STATUS_NOTSIGNED_LABEL : $langs->trans("AskpricesupplierStatusNotSigned")); + $this->labelstatut[4]=(! empty($conf->global->ASKPRICESUPPLIER_STATUS_BILLED_LABEL) ? $conf->global->ASKPRICESUPPLIER_STATUS_BILLED_LABEL : $langs->trans("AskpricesupplierStatusBilled")); + $this->labelstatut_short[0]=(! empty($conf->global->ASKPRICESUPPLIER_STATUS_DRAFTSHORT_LABEL) ? $conf->global->ASKPRICESUPPLIER_STATUS_DRAFTSHORT_LABEL : $langs->trans("AskpricesupplierStatusDraftShort")); + $this->labelstatut_short[1]=(! empty($conf->global->ASKPRICESUPPLIER_STATUS_VALIDATEDSHORT_LABEL) ? $conf->global->ASKPRICESUPPLIER_STATUS_VALIDATEDSHORT_LABEL : $langs->trans("Opened")); + $this->labelstatut_short[2]=(! empty($conf->global->ASKPRICESUPPLIER_STATUS_SIGNEDSHORT_LABEL) ? $conf->global->ASKPRICESUPPLIER_STATUS_SIGNEDSHORT_LABEL : $langs->trans("AskpricesupplierStatusSignedShort")); + $this->labelstatut_short[3]=(! empty($conf->global->ASKPRICESUPPLIER_STATUS_NOTSIGNEDSHORT_LABEL) ? $conf->global->ASKPRICESUPPLIER_STATUS_NOTSIGNEDSHORT_LABEL : $langs->trans("AskpricesupplierStatusNotSignedShort")); + $this->labelstatut_short[4]=(! empty($conf->global->ASKPRICESUPPLIER_STATUS_BILLEDSHORT_LABEL) ? $conf->global->ASKPRICESUPPLIER_STATUS_BILLEDSHORT_LABEL : $langs->trans("AskpricesupplierStatusBilledShort")); + } + + + /** + * Add line into array products + * $this->client doit etre charge + * + * @param int $idproduct Product Id to add + * @param int $qty Quantity + * @param int $remise_percent Discount effected on Product + * @return int <0 if KO, >0 if OK + * + * TODO Remplacer les appels a cette fonction par generation objet Ligne + * insere dans tableau $this->products + */ + function add_product($idproduct, $qty, $remise_percent=0) + { + global $conf, $mysoc; + + if (! $qty) $qty = 1; + + dol_syslog(get_class($this)."::add_product $idproduct, $qty, $remise_percent"); + if ($idproduct > 0) + { + $prod=new Product($this->db); + $prod->fetch($idproduct); + + $productdesc = $prod->description; + + $tva_tx = get_default_tva($mysoc,$this->client,$prod->id); + // local taxes + $localtax1_tx = get_default_localtax($mysoc,$this->client,1,$prod->tva_tx); + $localtax2_tx = get_default_localtax($mysoc,$this->client,2,$prod->tva_tx); + + // multiprix + if($conf->global->PRODUIT_MULTIPRICES && $this->client->price_level) + { + $price = $prod->multiprices[$this->client->price_level]; + } + else + { + $price = $prod->price; + } + + $line = new AskPriceSupplierLigne($this->db); + + $line->fk_product=$idproduct; + $line->desc=$productdesc; + $line->qty=$qty; + $line->subprice=$price; + $line->remise_percent=$remise_percent; + $line->tva_tx=$tva_tx; + + $this->lines[]=$line; + } + } + + /** + * Adding line of fixed discount in the proposal in DB + * + * @param int $idremise Id of fixed discount + * @return int >0 if OK, <0 if KO + */ + function insert_discount($idremise) + { + global $langs; + + include_once DOL_DOCUMENT_ROOT.'/core/lib/price.lib.php'; + include_once DOL_DOCUMENT_ROOT.'/core/class/discount.class.php'; + + $this->db->begin(); + + $remise=new DiscountAbsolute($this->db); + $result=$remise->fetch($idremise); + + if ($result > 0) + { + if ($remise->fk_facture) // Protection against multiple submission + { + $this->error=$langs->trans("ErrorDiscountAlreadyUsed"); + $this->db->rollback(); + return -5; + } + + $askpricesupplierligne=new AskPriceSupplierLigne($this->db); + $askpricesupplierligne->fk_askpricesupplier=$this->id; + $askpricesupplierligne->fk_remise_except=$remise->id; + $askpricesupplierligne->desc=$remise->description; // Description ligne + $askpricesupplierligne->tva_tx=$remise->tva_tx; + $askpricesupplierligne->subprice=-$remise->amount_ht; + $askpricesupplierligne->fk_product=0; // Id produit predefini + $askpricesupplierligne->qty=1; + $askpricesupplierligne->remise=0; + $askpricesupplierligne->remise_percent=0; + $askpricesupplierligne->rang=-1; + $askpricesupplierligne->info_bits=2; + + // TODO deprecated + $askpricesupplierligne->price=-$remise->amount_ht; + + $askpricesupplierligne->total_ht = -$remise->amount_ht; + $askpricesupplierligne->total_tva = -$remise->amount_tva; + $askpricesupplierligne->total_ttc = -$remise->amount_ttc; + + $result=$askpricesupplierligne->insert(); + if ($result > 0) + { + $result=$this->update_price(1); + if ($result > 0) + { + $this->db->commit(); + return 1; + } + else + { + $this->db->rollback(); + return -1; + } + } + else + { + $this->error=$askpricesupplierligne->error; + $this->db->rollback(); + return -2; + } + } + else + { + $this->db->rollback(); + return -2; + } + } + + /** + * Add a proposal line into database (linked to product/service or not) + * Les parametres sont deja cense etre juste et avec valeurs finales a l'appel + * de cette methode. Aussi, pour le taux tva, il doit deja avoir ete defini + * par l'appelant par la methode get_default_tva(societe_vendeuse,societe_acheteuse,'',produit) + * et le desc doit deja avoir la bonne valeur (a l'appelant de gerer le multilangue) + * + * @param string $desc Description de la ligne + * @param double $pu_ht Prix unitaire + * @param double $qty Quantite + * @param double $txtva Taux de tva + * @param double $txlocaltax1 Local tax 1 rate + * @param double $txlocaltax2 Local tax 2 rate + * @param int $fk_product Id du produit/service predefini + * @param double $remise_percent Pourcentage de remise de la ligne + * @param string $price_base_type HT or TTC + * @param double $pu_ttc Prix unitaire TTC + * @param int $info_bits Bits de type de lignes + * @param int $type Type of line (product, service) + * @param int $rang Position of line + * @param int $special_code Special code (also used by externals modules!) + * @param int $fk_parent_line Id of parent line + * @param int $fk_fournprice Id supplier price + * @param int $pa_ht Buying price without tax + * @param string $label ??? + * @param array $array_option extrafields array + * @param string $ref_fourn Supplier price reference + * @return int >0 if OK, <0 if KO + * + * @see add_product + */ + function addline($desc, $pu_ht, $qty, $txtva, $txlocaltax1=0, $txlocaltax2=0, $fk_product=0, $remise_percent=0, $price_base_type='HT', $pu_ttc=0, $info_bits=0, $type=0, $rang=-1, $special_code=0, $fk_parent_line=0, $fk_fournprice=0, $pa_ht=0, $label='',$array_option=0, $ref_fourn='') + { + global $mysoc; + + dol_syslog(get_class($this)."::addline askpricesupplierid=$this->id, desc=$desc, pu_ht=$pu_ht, qty=$qty, txtva=$txtva, fk_product=$fk_product, remise_except=$remise_percent, price_base_type=$price_base_type, pu_ttc=$pu_ttc, info_bits=$info_bits, type=$type"); + include_once DOL_DOCUMENT_ROOT.'/core/lib/price.lib.php'; + + // Clean parameters + if (empty($remise_percent)) $remise_percent=0; + if (empty($qty)) $qty=0; + if (empty($info_bits)) $info_bits=0; + if (empty($rang)) $rang=0; + if (empty($fk_parent_line) || $fk_parent_line < 0) $fk_parent_line=0; + + $remise_percent=price2num($remise_percent); + $qty=price2num($qty); + $pu_ht=price2num($pu_ht); + $pu_ttc=price2num($pu_ttc); + $txtva=price2num($txtva); + $txlocaltax1=price2num($txlocaltax1); + $txlocaltax2=price2num($txlocaltax2); + $pa_ht=price2num($pa_ht); + if ($price_base_type=='HT') + { + $pu=$pu_ht; + } + else + { + $pu=$pu_ttc; + } + + // Check parameters + if ($type < 0) return -1; + + if ($this->statut == 0) + { + $this->db->begin(); + + // Calcul du total TTC et de la TVA pour la ligne a partir de + // qty, pu, remise_percent et txtva + // TRES IMPORTANT: C'est au moment de l'insertion ligne qu'on doit stocker + // la part ht, tva et ttc, et ce au niveau de la ligne qui a son propre taux tva. + + $localtaxes_type=getLocalTaxesFromRate($txtva,0,$this->thirdparty,$mysoc); + + $tabprice=calcul_price_total($qty, $pu, $remise_percent, $txtva, $txlocaltax1, $txlocaltax2, 0, $price_base_type, $info_bits, $type, '', $localtaxes_type); + $total_ht = $tabprice[0]; + $total_tva = $tabprice[1]; + $total_ttc = $tabprice[2]; + $total_localtax1 = $tabprice[9]; + $total_localtax2 = $tabprice[10]; + + // Rang to use + $rangtouse = $rang; + if ($rangtouse == -1) + { + $rangmax = $this->line_max($fk_parent_line); + $rangtouse = $rangmax + 1; + } + + // TODO A virer + // Anciens indicateurs: $price, $remise (a ne plus utiliser) + $price = $pu; + $remise = 0; + if ($remise_percent > 0) + { + $remise = round(($pu * $remise_percent / 100), 2); + $price = $pu - $remise; + } + + // Insert line + $this->line=new AskPriceSupplierLigne($this->db); + + $this->line->fk_askpricesupplier=$this->id; + $this->line->label=$label; + $this->line->desc=$desc; + $this->line->qty=$qty; + $this->line->tva_tx=$txtva; + $this->line->localtax1_tx=$txlocaltax1; + $this->line->localtax2_tx=$txlocaltax2; + $this->line->localtax1_type = $localtaxes_type[0]; + $this->line->localtax2_type = $localtaxes_type[2]; + $this->line->fk_product=$fk_product; + $this->line->remise_percent=$remise_percent; + $this->line->subprice=$pu_ht; + $this->line->rang=$rangtouse; + $this->line->info_bits=$info_bits; + $this->line->total_ht=$total_ht; + $this->line->total_tva=$total_tva; + $this->line->total_localtax1=$total_localtax1; + $this->line->total_localtax2=$total_localtax2; + $this->line->total_ttc=$total_ttc; + $this->line->product_type=$type; + $this->line->special_code=$special_code; + $this->line->fk_parent_line=$fk_parent_line; + + $this->line->ref_fourn = $this->db->escape($ref_fourn); + + // infos marge + if (!empty($fk_product) && empty($fk_fournprice) && empty($pa_ht)) { + // by external module, take lowest buying price + include_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.product.class.php'; + $productFournisseur = new ProductFournisseur($this->db); + $productFournisseur->find_min_price_product_fournisseur($fk_product); + $this->line->fk_fournprice = $productFournisseur->product_fourn_price_id; + } else { + $this->line->fk_fournprice = $fk_fournprice; + } + $this->line->pa_ht = $pa_ht; + + // Mise en option de la ligne + if (empty($qty) && empty($special_code)) $this->line->special_code=3; + + // TODO deprecated + $this->line->price=$price; + $this->line->remise=$remise; + + if (is_array($array_option) && count($array_option)>0) { + $this->line->array_options=$array_option; + } + + $result=$this->line->insert(); + if ($result > 0) + { + // Reorder if child line + if (! empty($fk_parent_line)) $this->line_order(true,'DESC'); + + // Mise a jour informations denormalisees au niveau de la propale meme + $result=$this->update_price(1,'auto'); // This method is designed to add line from user input so total calculation must be done using 'auto' mode. + if ($result > 0) + { + $this->db->commit(); + return $this->line->rowid; + } + else + { + $this->error=$this->db->error(); + $this->db->rollback(); + return -1; + } + } + else + { + $this->error=$this->line->error; + $this->db->rollback(); + return -2; + } + } + } + + + /** + * Update a proposal line + * + * @param int $rowid Id de la ligne + * @param double $pu Prix unitaire (HT ou TTC selon price_base_type) + * @param double $qty Quantity + * @param double $remise_percent Remise effectuee sur le produit + * @param double $txtva Taux de TVA + * @param double $txlocaltax1 Local tax 1 rate + * @param double $txlocaltax2 Local tax 2 rate + * @param string $desc Description + * @param double $price_base_type HT ou TTC + * @param int $info_bits Miscellaneous informations + * @param int $special_code Special code (also used by externals modules!) + * @param int $fk_parent_line Id of parent line (0 in most cases, used by modules adding sublevels into lines). + * @param int $skip_update_total Keep fields total_xxx to 0 (used for special lines by some modules) + * @param int $fk_fournprice Id of origin supplier price + * @param int $pa_ht Price (without tax) of product when it was bought + * @param string $label ??? + * @param int $type 0/1=Product/service + * @param array $array_option extrafields array + * @param string $ref_fourn Supplier price reference + * @return int 0 if OK, <0 if KO + */ + function updateline($rowid, $pu, $qty, $remise_percent, $txtva, $txlocaltax1=0, $txlocaltax2=0, $desc='', $price_base_type='HT', $info_bits=0, $special_code=0, $fk_parent_line=0, $skip_update_total=0, $fk_fournprice=0, $pa_ht=0, $label='', $type=0, $array_option=0, $ref_fourn='') + { + global $conf,$user,$langs, $mysoc; + + dol_syslog(get_class($this)."::updateLine $rowid, $pu, $qty, $remise_percent, $txtva, $desc, $price_base_type, $info_bits"); + include_once DOL_DOCUMENT_ROOT.'/core/lib/price.lib.php'; + + // Clean parameters + $remise_percent=price2num($remise_percent); + $qty=price2num($qty); + $pu = price2num($pu); + $txtva = price2num($txtva); + $txlocaltax1=price2num($txlocaltax1); + $txlocaltax2=price2num($txlocaltax2); + $pa_ht=price2num($pa_ht); + if (empty($qty) && empty($special_code)) $special_code=3; // Set option tag + if (! empty($qty) && $special_code == 3) $special_code=0; // Remove option tag + + if ($this->statut == 0) + { + $this->db->begin(); + + // Calcul du total TTC et de la TVA pour la ligne a partir de + // qty, pu, remise_percent et txtva + // TRES IMPORTANT: C'est au moment de l'insertion ligne qu'on doit stocker + // la part ht, tva et ttc, et ce au niveau de la ligne qui a son propre taux tva. + + $localtaxes_type=getLocalTaxesFromRate($txtva,0,$this->thirdparty,$mysoc); + + $tabprice=calcul_price_total($qty, $pu, $remise_percent, $txtva, $txlocaltax1, $txlocaltax2, 0, $price_base_type, $info_bits, $type,'', $localtaxes_type); + $total_ht = $tabprice[0]; + $total_tva = $tabprice[1]; + $total_ttc = $tabprice[2]; + $total_localtax1 = $tabprice[9]; + $total_localtax2 = $tabprice[10]; + + // Anciens indicateurs: $price, $remise (a ne plus utiliser) + $price = $pu; + if ($remise_percent > 0) + { + $remise = round(($pu * $remise_percent / 100), 2); + $price = $pu - $remise; + } + + // Update line + $this->line=new AskPriceSupplierLigne($this->db); + + // Stock previous line records + $staticline=new AskPriceSupplierLigne($this->db); + $staticline->fetch($rowid); + $this->line->oldline = $staticline; + + // Reorder if fk_parent_line change + if (! empty($fk_parent_line) && ! empty($staticline->fk_parent_line) && $fk_parent_line != $staticline->fk_parent_line) + { + $rangmax = $this->line_max($fk_parent_line); + $this->line->rang = $rangmax + 1; + } + + $this->line->rowid = $rowid; + $this->line->label = $label; + $this->line->desc = $desc; + $this->line->qty = $qty; + $this->line->product_type = $type; + $this->line->tva_tx = $txtva; + $this->line->localtax1_tx = $txlocaltax1; + $this->line->localtax2_tx = $txlocaltax2; + $this->line->localtax1_type = $localtaxes_type[0]; + $this->line->localtax2_type = $localtaxes_type[2]; + $this->line->remise_percent = $remise_percent; + $this->line->subprice = $pu; + $this->line->info_bits = $info_bits; + $this->line->total_ht = $total_ht; + $this->line->total_tva = $total_tva; + $this->line->total_localtax1 = $total_localtax1; + $this->line->total_localtax2 = $total_localtax2; + $this->line->total_ttc = $total_ttc; + $this->line->special_code = $special_code; + $this->line->fk_parent_line = $fk_parent_line; + $this->line->skip_update_total = $skip_update_total; + $this->line->ref_fourn = $ref_fourn; + + // infos marge + if (!empty($fk_product) && empty($fk_fournprice) && empty($pa_ht)) { + // by external module, take lowest buying price + include_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.product.class.php'; + $productFournisseur = new ProductFournisseur($this->db); + $productFournisseur->find_min_price_product_fournisseur($fk_product); + $this->line->fk_fournprice = $productFournisseur->product_fourn_price_id; + } else { + $this->line->fk_fournprice = $fk_fournprice; + } + $this->line->pa_ht = $pa_ht; + + // TODO deprecated + $this->line->price=$price; + $this->line->remise=$remise; + + if (is_array($array_option) && count($array_option)>0) { + $this->line->array_options=$array_option; + } + + $result=$this->line->update(); + if ($result > 0) + { + // Reorder if child line + if (! empty($fk_parent_line)) $this->line_order(true,'DESC'); + + $this->update_price(1); + + $this->fk_askpricesupplier = $this->id; + $this->rowid = $rowid; + + $this->db->commit(); + return $result; + } + else + { + $this->error=$this->db->error(); + $this->db->rollback(); + return -1; + } + } + else + { + dol_syslog(get_class($this)."::updateline Erreur -2 Askpricesupplier en mode incompatible pour cette action"); + return -2; + } + } + + + /** + * Delete detail line + * + * @param int $lineid Id of line to delete + * @return int >0 if OK, <0 if KO + */ + function deleteline($lineid) + { + if ($this->statut == 0) + { + $line=new AskPriceSupplierLigne($this->db); + + // For triggers + $line->fetch($lineid); + + if ($line->delete() > 0) + { + $this->update_price(1); + + return 1; + } + else + { + return -1; + } + } + else + { + return -2; + } + } + + + /** + * Create commercial proposal into database + * this->ref can be set or empty. If empty, we will use "(PROVid)" + * + * @param User $user User that create + * @param int $notrigger 1=Does not execute triggers, 0= execuete triggers + * @return int <0 if KO, >=0 if OK + */ + function create($user, $notrigger=0) + { + global $langs,$conf,$mysoc,$hookmanager; + $error=0; + + $now=dol_now(); + + dol_syslog(get_class($this)."::create"); + + // Check parameters + $result=$this->fetch_thirdparty(); + if ($result < 0) + { + $this->error="Failed to fetch company"; + dol_syslog(get_class($this)."::create ".$this->error, LOG_ERR); + return -3; + } + + // Check parameters + if (! empty($this->ref)) // We check that ref is not already used + { + $result=self::isExistingObject($this->element, 0, $this->ref); // Check ref is not yet used + if ($result > 0) + { + $this->error='ErrorRefAlreadyExists'; + dol_syslog(get_class($this)."::create ".$this->error,LOG_WARNING); + $this->db->rollback(); + return -1; + } + } + + $this->db->begin(); + + // Insert into database + $sql = "INSERT INTO ".MAIN_DB_PREFIX."askpricesupplier ("; + $sql.= "fk_soc"; + $sql.= ", price"; + $sql.= ", remise"; + $sql.= ", remise_percent"; + $sql.= ", remise_absolue"; + $sql.= ", tva"; + $sql.= ", total"; + $sql.= ", datec"; + $sql.= ", ref"; + $sql.= ", fk_user_author"; + $sql.= ", note_private"; + $sql.= ", note_public"; + $sql.= ", model_pdf"; + $sql.= ", fk_cond_reglement"; + $sql.= ", fk_mode_reglement"; + $sql.= ", fk_account"; + $sql.= ", date_livraison"; + $sql.= ", fk_shipping_method"; + $sql.= ", fk_projet"; + $sql.= ", entity"; + $sql.= ") "; + $sql.= " VALUES ("; + $sql.= $this->socid; + $sql.= ", 0"; + $sql.= ", ".$this->remise; + $sql.= ", ".($this->remise_percent?$this->remise_percent:'null'); + $sql.= ", ".($this->remise_absolue?$this->remise_absolue:'null'); + $sql.= ", 0"; + $sql.= ", 0"; + $sql.= ", '".$this->db->idate($now)."'"; + $sql.= ", '(PROV)'"; + $sql.= ", ".($user->id > 0 ? "'".$user->id."'":"null"); + $sql.= ", '".$this->db->escape($this->note_private)."'"; + $sql.= ", '".$this->db->escape($this->note_public)."'"; + $sql.= ", '".$this->modelpdf."'"; + $sql.= ", ".$this->cond_reglement_id; + $sql.= ", ".$this->mode_reglement_id; + $sql.= ", ".($this->fk_account>0?$this->fk_account:'NULL'); + $sql.= ", ".($this->date_livraison!=''?"'".$this->db->idate($this->date_livraison)."'":"null"); + $sql.= ", ".($this->shipping_method_id>0?$this->shipping_method_id:'NULL'); + $sql.= ", ".($this->fk_project?$this->fk_project:"null"); + $sql.= ", ".$conf->entity; + $sql.= ")"; + + dol_syslog(get_class($this)."::create", LOG_DEBUG); + $resql=$this->db->query($sql); + if ($resql) + { + $this->id = $this->db->last_insert_id(MAIN_DB_PREFIX."askpricesupplier"); + + if ($this->id) + { + $this->ref='(PROV'.$this->id.')'; + $sql = 'UPDATE '.MAIN_DB_PREFIX."askpricesupplier SET ref='".$this->ref."' WHERE rowid=".$this->id; + + dol_syslog(get_class($this)."::create", LOG_DEBUG); + $resql=$this->db->query($sql); + if (! $resql) $error++; + + /* + * Insertion du detail des produits dans la base + */ + if (! $error) + { + $fk_parent_line=0; + $num=count($this->lines); + + for ($i=0;$i<$num;$i++) + { + // Reset fk_parent_line for no child products and special product + if (($this->lines[$i]->product_type != 9 && empty($this->lines[$i]->fk_parent_line)) || $this->lines[$i]->product_type == 9) { + $fk_parent_line = 0; + } + + $result = $this->addline( + $this->lines[$i]->desc, + $this->lines[$i]->subprice, + $this->lines[$i]->qty, + $this->lines[$i]->tva_tx, + $this->lines[$i]->localtax1_tx, + $this->lines[$i]->localtax2_tx, + $this->lines[$i]->fk_product, + $this->lines[$i]->remise_percent, + 'HT', + 0, + 0, + $this->lines[$i]->product_type, + $this->lines[$i]->rang, + $this->lines[$i]->special_code, + $fk_parent_line, + $this->lines[$i]->fk_fournprice, + $this->lines[$i]->pa_ht, + $this->lines[$i]->label, + $this->lines[$i]->array_options, + $this->lines[$i]->ref_fourn + ); + + if ($result < 0) + { + $error++; + $this->error=$this->db->error; + dol_print_error($this->db); + break; + } + // Defined the new fk_parent_line + if ($result > 0 && $this->lines[$i]->product_type == 9) { + $fk_parent_line = $result; + } + } + } + + // Add linked object + if (! $error && $this->origin && $this->origin_id) + { + $ret = $this->add_object_linked(); + if (! $ret) dol_print_error($this->db); + } + + if (! $error) + { + // Mise a jour infos denormalisees + $resql=$this->update_price(1); + if ($resql) + { + $action='update'; + + // Actions on extra fields (by external module or standard code) + $hookmanager->initHooks(array('askpricesupplierdao')); + $parameters=array('socid'=>$this->id); + $reshook=$hookmanager->executeHooks('insertExtraFields',$parameters,$this,$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=$this->insertExtraFields(); + if ($result < 0) + { + $error++; + } + } + } + else if ($reshook < 0) $error++; + + if (! $notrigger) + { + // Call trigger + $result=$this->call_trigger('ASKPRICESUPPLIER_CREATE',$user); + if ($result < 0) { $error++; } + // End call triggers + } + } + else + { + $this->error=$this->db->lasterror(); + $error++; + } + } + } + else + { + $this->error=$this->db->lasterror(); + $error++; + } + + if (! $error) + { + $this->db->commit(); + dol_syslog(get_class($this)."::create done id=".$this->id); + return $this->id; + } + else + { + $this->db->rollback(); + return -2; + } + } + else + { + $this->error=$this->db->lasterror(); + $this->db->rollback(); + return -1; + } + } + + + /** + * Insert into DB a askpricesupplier object completely defined by its data members (ex, results from copy). + * + * @param User $user User that create + * @return int Id of the new object if ok, <0 if ko + * @see create + */ + function create_from($user) + { + $this->products=$this->lines; + + return $this->create($user); + } + + /** + * Load an object from its id and create a new one in database + * + * @param int $socid Id of thirdparty + * @return int New id of clone + */ + function createFromClone($socid=0) + { + global $user,$langs,$conf,$hookmanager; + + $error=0; + $now=dol_now(); + + $this->db->begin(); + + // get extrafields so they will be clone + foreach($this->lines as $line) + $line->fetch_optionals($line->rowid); + + // Load source object + $objFrom = dol_clone($this); + + $objsoc=new Societe($this->db); + + // Change socid if needed + if (! empty($socid) && $socid != $this->socid) + { + if ($objsoc->fetch($socid) > 0) + { + $this->socid = $objsoc->id; + $this->cond_reglement_id = (! empty($objsoc->cond_reglement_id) ? $objsoc->cond_reglement_id : 0); + $this->mode_reglement_id = (! empty($objsoc->mode_reglement_id) ? $objsoc->mode_reglement_id : 0); + $this->fk_project = ''; + } + + // TODO Change product price if multi-prices + } + else + { + $objsoc->fetch($this->socid); + } + + $this->id=0; + $this->statut=0; + + if (empty($conf->global->ASKPRICESUPPLIER_ADDON) || ! is_readable(DOL_DOCUMENT_ROOT ."/core/modules/askpricesupplier/".$conf->global->ASKPRICESUPPLIER_ADDON.".php")) + { + $this->error='ErrorSetupNotComplete'; + return -1; + } + + // Clear fields + $this->user_author = $user->id; + $this->user_valid = ''; + $this->date = $now; + + // Set ref + require_once DOL_DOCUMENT_ROOT ."/core/modules/askpricesupplier/".$conf->global->ASKPRICESUPPLIER_ADDON.'.php'; + $obj = $conf->global->ASKPRICESUPPLIER_ADDON; + $modAskPriceSupplier = new $obj; + $this->ref = $modAskPriceSupplier->getNextValue($objsoc,$this); + + // Create clone + $result=$this->create($user); + if ($result < 0) $error++; + + if (! $error) + { + // Hook of thirdparty module + if (is_object($hookmanager)) + { + $parameters=array('objFrom'=>$objFrom); + $action=''; + $reshook=$hookmanager->executeHooks('createFrom',$parameters,$this,$action); // Note that $action and $object may have been modified by some hooks + if ($reshook < 0) $error++; + } + + // Call trigger + $result=$this->call_trigger('ASKPRICESUPPLIER_CLONE',$user); + if ($result < 0) { $error++; } + // End call triggers + } + + // End + if (! $error) + { + $this->db->commit(); + return $this->id; + } + else + { + $this->db->rollback(); + return -1; + } + } + + /** + * Load a proposal from database and its ligne array + * + * @param int $rowid id of object to load + * @param string $ref Ref of proposal + * @return int >0 if OK, <0 if KO + */ + function fetch($rowid,$ref='') + { + global $conf; + + $sql = "SELECT p.rowid, p.ref, p.remise, p.remise_percent, p.remise_absolue, p.fk_soc"; + $sql.= ", p.total, p.tva, p.localtax1, p.localtax2, p.total_ht"; + $sql.= ", p.datec"; + $sql.= ", p.date_valid as datev"; + $sql.= ", p.date_livraison as date_livraison"; + $sql.= ", p.model_pdf, p.extraparams"; + $sql.= ", p.note_private, p.note_public"; + $sql.= ", p.fk_projet, p.fk_statut"; + $sql.= ", p.fk_user_author, p.fk_user_valid, p.fk_user_cloture"; + $sql.= ", p.fk_cond_reglement"; + $sql.= ", p.fk_mode_reglement"; + $sql.= ', p.fk_account'; + $sql.= ", p.fk_shipping_method"; + $sql.= ", c.label as statut_label"; + $sql.= ", cr.code as cond_reglement_code, cr.libelle as cond_reglement, cr.libelle_facture as cond_reglement_libelle_doc"; + $sql.= ", cp.code as mode_reglement_code, cp.libelle as mode_reglement"; + $sql.= " FROM ".MAIN_DB_PREFIX."c_propalst as c, ".MAIN_DB_PREFIX."askpricesupplier as p"; + $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_paiement as cp ON p.fk_mode_reglement = cp.id'; + $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_payment_term as cr ON p.fk_cond_reglement = cr.rowid'; + $sql.= " WHERE p.fk_statut = c.id"; + $sql.= " AND p.entity = ".$conf->entity; + if ($ref) $sql.= " AND p.ref='".$ref."'"; + else $sql.= " AND p.rowid=".$rowid; + + dol_syslog(get_class($this)."::fetch", LOG_DEBUG); + $resql=$this->db->query($sql); + if ($resql) + { + if ($this->db->num_rows($resql)) + { + $obj = $this->db->fetch_object($resql); + + $this->id = $obj->rowid; + + $this->ref = $obj->ref; + $this->remise = $obj->remise; + $this->remise_percent = $obj->remise_percent; + $this->remise_absolue = $obj->remise_absolue; + $this->total = $obj->total; // TODO obsolete + $this->total_ht = $obj->total_ht; + $this->total_tva = $obj->tva; + $this->total_localtax1 = $obj->localtax1; + $this->total_localtax2 = $obj->localtax2; + $this->total_ttc = $obj->total; + $this->socid = $obj->fk_soc; + $this->fk_project = $obj->fk_projet; + $this->modelpdf = $obj->model_pdf; + $this->note = $obj->note_private; // TODO obsolete + $this->note_private = $obj->note_private; + $this->note_public = $obj->note_public; + $this->statut = $obj->fk_statut; + $this->statut_libelle = $obj->statut_label; + + $this->datec = $this->db->jdate($obj->datec); // TODO obsolete + $this->datev = $this->db->jdate($obj->datev); // TODO obsolete + $this->date_creation = $this->db->jdate($obj->datec); //Creation date + $this->date_validation = $this->db->jdate($obj->datev); //Validation date + $this->date_livraison = $this->db->jdate($obj->date_livraison); + $this->shipping_method_id = ($obj->fk_shipping_method>0)?$obj->fk_shipping_method:null; + + $this->mode_reglement_id = $obj->fk_mode_reglement; + $this->mode_reglement_code = $obj->mode_reglement_code; + $this->mode_reglement = $obj->mode_reglement; + $this->fk_account = ($obj->fk_account>0)?$obj->fk_account:null; + $this->cond_reglement_id = $obj->fk_cond_reglement; + $this->cond_reglement_code = $obj->cond_reglement_code; + $this->cond_reglement = $obj->cond_reglement; + $this->cond_reglement_doc = $obj->cond_reglement_libelle_doc; + + $this->extraparams = (array) json_decode($obj->extraparams, true); + + $this->user_author_id = $obj->fk_user_author; + $this->user_valid_id = $obj->fk_user_valid; + $this->user_close_id = $obj->fk_user_cloture; + + if ($obj->fk_statut == 0) + { + $this->brouillon = 1; + } + + // Retreive all extrafield for invoice + // fetch optionals attributes and labels + require_once DOL_DOCUMENT_ROOT.'/core/class/extrafields.class.php'; + $extrafields=new ExtraFields($this->db); + $extralabels=$extrafields->fetch_name_optionals_label($this->table_element,true); + $this->fetch_optionals($this->id,$extralabels); + + $this->db->free($resql); + + $this->lines = array(); + + /* + * Lignes askprice liees a un produit ou non + */ + $sql = "SELECT d.rowid, d.fk_askpricesupplier, d.fk_parent_line, d.label as custom_label, d.description, d.price, d.tva_tx, d.localtax1_tx, d.localtax2_tx, d.qty, d.fk_remise_except, d.remise_percent, d.subprice, d.fk_product,"; + $sql.= " d.info_bits, d.total_ht, d.total_tva, d.total_localtax1, d.total_localtax2, d.total_ttc, d.fk_product_fournisseur_price as fk_fournprice, d.buy_price_ht as pa_ht, d.special_code, d.rang, d.product_type,"; + $sql.= ' p.ref as product_ref, p.description as product_desc, p.fk_product_type, p.label as product_label,'; + $sql.= ' d.ref_fourn as ref_produit_fourn'; + $sql.= " FROM ".MAIN_DB_PREFIX."askpricesupplierdet as d"; + $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."product as p ON d.fk_product = p.rowid"; + $sql.= " WHERE d.fk_askpricesupplier = ".$this->id; + $sql.= " ORDER by d.rang"; + + $result = $this->db->query($sql); + if ($result) + { + $num = $this->db->num_rows($result); + $i = 0; + + while ($i < $num) + { + $objp = $this->db->fetch_object($result); + + $line = new AskPriceSupplierLigne($this->db); + + $line->rowid = $objp->rowid; + $line->fk_askpricesupplier = $objp->fk_askpricesupplier; + $line->fk_parent_line = $objp->fk_parent_line; + $line->product_type = $objp->product_type; + $line->label = $objp->custom_label; + $line->desc = $objp->description; // Description ligne + $line->qty = $objp->qty; + $line->tva_tx = $objp->tva_tx; + $line->localtax1_tx = $objp->localtax1_tx; + $line->localtax2_tx = $objp->localtax2_tx; + $line->subprice = $objp->subprice; + $line->fk_remise_except = $objp->fk_remise_except; + $line->remise_percent = $objp->remise_percent; + $line->price = $objp->price; // TODO deprecated + + $line->info_bits = $objp->info_bits; + $line->total_ht = $objp->total_ht; + $line->total_tva = $objp->total_tva; + $line->total_localtax1 = $objp->total_localtax1; + $line->total_localtax2 = $objp->total_localtax2; + $line->total_ttc = $objp->total_ttc; + $line->fk_fournprice = $objp->fk_fournprice; + $marginInfos = getMarginInfos($objp->subprice, $objp->remise_percent, $objp->tva_tx, $objp->localtax1_tx, $objp->localtax2_tx, $line->fk_fournprice, $objp->pa_ht); + $line->pa_ht = $marginInfos[0]; + $line->marge_tx = $marginInfos[1]; + $line->marque_tx = $marginInfos[2]; + $line->special_code = $objp->special_code; + $line->rang = $objp->rang; + + $line->fk_product = $objp->fk_product; + + $line->ref = $objp->product_ref; // TODO deprecated + $line->product_ref = $objp->product_ref; + $line->libelle = $objp->product_label; // TODO deprecated + $line->product_label = $objp->product_label; + $line->product_desc = $objp->product_desc; // Description produit + $line->fk_product_type = $objp->fk_product_type; + + $line->ref_fourn = $objp->ref_produit_fourn; + + $this->lines[$i] = $line; + + $i++; + } + $this->db->free($result); + } + else + { + $this->error=$this->db->error(); + return -1; + } + + // Retreive all extrafield for askprice + // fetch optionals attributes and labels + require_once DOL_DOCUMENT_ROOT.'/core/class/extrafields.class.php'; + $extrafields=new ExtraFields($this->db); + $extralabels=$extrafields->fetch_name_optionals_label($this->table_element,true); + $this->fetch_optionals($this->id,$extralabels); + + return 1; + } + + $this->error="Record Not Found"; + return 0; + } + else + { + $this->error=$this->db->error(); + return -1; + } + } + + /** + * Update value of extrafields on the proposal + * + * @param User $user Object user that modify + * @return int <0 if ko, >0 if ok + */ + function update_extrafields($user) + { + $action='update'; + + // Actions on extra fields (by external module or standard code) + $hookmanager->initHooks(array('askpricesupplierdao')); + $parameters=array('id'=>$this->id); + $reshook=$hookmanager->executeHooks('insertExtraFields',$parameters,$this,$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=$this->insertExtraFields(); + if ($result < 0) + { + $error++; + } + } + } + else if ($reshook < 0) $error++; + + if (!$error) + { + return 1; + } + else + { + return -1; + } + + } + + /** + * Set status to validated + * + * @param User $user Object user that validate + * @param int $notrigger 1=Does not execute triggers, 0= execuete triggers + * @return int <0 if KO, >=0 if OK + */ + function valid($user, $notrigger=0) + { + require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; + + global $conf,$langs; + + $error=0; + $now=dol_now(); + + if ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->askpricesupplier->creer)) + || (! empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->askpricesupplier->validate))) + { + $this->db->begin(); + + // Numbering module definition + $soc = new Societe($this->db); + $soc->fetch($this->socid); + + // Define new ref + if (! $error && (preg_match('/^[\(]?PROV/i', $this->ref))) + { + $num = $this->getNextNumRef($soc); + } + else + { + $num = $this->ref; + } + $this->newref = $num; + + $sql = "UPDATE ".MAIN_DB_PREFIX."askpricesupplier"; + $sql.= " SET ref = '".$num."',"; + $sql.= " fk_statut = 1, date_valid='".$this->db->idate($now)."', fk_user_valid=".$user->id; + $sql.= " WHERE rowid = ".$this->id." AND fk_statut = 0"; + + dol_syslog(get_class($this)."::valid", LOG_DEBUG); + $resql=$this->db->query($sql); + if (! $resql) + { + dol_print_error($this->db); + $error++; + } + + // Trigger calls + if (! $error && ! $notrigger) + { + // Call trigger + $result=$this->call_trigger('ASKPRICESUPPLIER_VALIDATE',$user); + if ($result < 0) { $error++; } + // End call triggers + } + + if (! $error) + { + $this->oldref = $this->ref; + + // Rename directory if dir was a temporary ref + if (preg_match('/^[\(]?PROV/i', $this->ref)) + { + // Rename of propal directory ($this->ref = old ref, $num = new ref) + // to not lose the linked files + $oldref = dol_sanitizeFileName($this->ref); + $newref = dol_sanitizeFileName($num); + $dirsource = $conf->askpricesupplier->dir_output.'/'.$oldref; + $dirdest = $conf->askpricesupplier->dir_output.'/'.$newref; + + if (file_exists($dirsource)) + { + dol_syslog(get_class($this)."::validate rename dir ".$dirsource." into ".$dirdest); + if (@rename($dirsource, $dirdest)) + { + dol_syslog("Rename ok"); + // Rename docs starting with $oldref with $newref + $listoffiles=dol_dir_list($conf->askpricesupplier->dir_output.'/'.$newref, 'files', 1, '^'.preg_quote($oldref,'/')); + foreach($listoffiles as $fileentry) + { + $dirsource=$fileentry['name']; + $dirdest=preg_replace('/^'.preg_quote($oldref,'/').'/',$newref, $dirsource); + $dirsource=$fileentry['path'].'/'.$dirsource; + $dirdest=$fileentry['path'].'/'.$dirdest; + @rename($dirsource, $dirdest); + } + } + } + } + + $this->ref=$num; + $this->brouillon=0; + $this->statut = 1; + $this->user_valid_id=$user->id; + $this->datev=$now; + + $this->db->commit(); + return 1; + } + else + { + $this->db->rollback(); + return -1; + } + } + } + + /** + * Set delivery date + * + * @param User $user Object user that modify + * @param int $date_livraison Delivery date + * @return int <0 if ko, >0 if ok + */ + function set_date_livraison($user, $date_livraison) + { + if (! empty($user->rights->askpricesupplier->creer)) + { + $sql = "UPDATE ".MAIN_DB_PREFIX."askpricesupplier "; + $sql.= " SET date_livraison = ".($date_livraison!=''?"'".$this->db->idate($date_livraison)."'":'null'); + $sql.= " WHERE rowid = ".$this->id; + + if ($this->db->query($sql)) + { + $this->date_livraison = $date_livraison; + return 1; + } + else + { + $this->error=$this->db->error(); + dol_syslog(get_class($this)."::set_date_livraison Erreur SQL"); + return -1; + } + } + } + + /** + * Set an overall discount on the proposal + * + * @param User $user Object user that modify + * @param double $remise Amount discount + * @return int <0 if ko, >0 if ok + */ + function set_remise_percent($user, $remise) + { + $remise=trim($remise)?trim($remise):0; + + if (! empty($user->rights->askpricesupplier->creer)) + { + $remise = price2num($remise); + + $sql = "UPDATE ".MAIN_DB_PREFIX."askpricesupplier SET remise_percent = ".$remise; + $sql.= " WHERE rowid = ".$this->id." AND fk_statut = 0"; + + if ($this->db->query($sql) ) + { + $this->remise_percent = $remise; + $this->update_price(1); + return 1; + } + else + { + $this->error=$this->db->error(); + return -1; + } + } + } + + + /** + * Set an absolute overall discount on the proposal + * + * @param User $user Object user that modify + * @param double $remise Amount discount + * @return int <0 if ko, >0 if ok + */ + function set_remise_absolue($user, $remise) + { + $remise=trim($remise)?trim($remise):0; + + if (! empty($user->rights->askpricesupplier->creer)) + { + $remise = price2num($remise); + + $sql = "UPDATE ".MAIN_DB_PREFIX."askpricesupplier "; + $sql.= " SET remise_absolue = ".$remise; + $sql.= " WHERE rowid = ".$this->id." AND fk_statut = 0"; + + if ($this->db->query($sql) ) + { + $this->remise_absolue = $remise; + $this->update_price(1); + return 1; + } + else + { + $this->error=$this->db->error(); + return -1; + } + } + } + + + + /** + * Reopen the commercial proposal + * + * @param User $user Object user that close + * @param int $statut Statut + * @param string $note Comment + * @param int $notrigger 1=Does not execute triggers, 0= execuete triggers + * @return int <0 if KO, >0 if OK + */ + function reopen($user, $statut, $note='', $notrigger=0) + { + global $langs,$conf; + + $this->statut = $statut; + $error=0; + + $sql = "UPDATE ".MAIN_DB_PREFIX."askpricesupplier"; + $sql.= " SET fk_statut = ".$this->statut.","; + if (! empty($note)) $sql.= " note_private = '".$this->db->escape($note)."',"; + $sql.= " date_cloture=NULL, fk_user_cloture=NULL"; + $sql.= " WHERE rowid = ".$this->id; + + $this->db->begin(); + + dol_syslog(get_class($this)."::reopen", LOG_DEBUG); + $resql = $this->db->query($sql); + if (! $resql) { + $error++; $this->errors[]="Error ".$this->db->lasterror(); + } + if (! $error) + { + if (! $notrigger) + { + // Call trigger + $result=$this->call_trigger('ASKPRICESUPPLIER_REOPEN',$user); + if ($result < 0) { $error++; } + // End call triggers + } + } + + // Commit or rollback + if ($error) + { + if (!empty($this->errors)) + { + foreach($this->errors as $errmsg) + { + dol_syslog(get_class($this)."::update ".$errmsg, LOG_ERR); + $this->error.=($this->error?', '.$errmsg:$errmsg); + } + } + $this->db->rollback(); + return -1*$error; + } + else + { + $this->db->commit(); + return 1; + } + } + + + /** + * Close the askprice + * + * @param User $user Object user that close + * @param int $statut Statut + * @param string $note Comment + * @return int <0 if KO, >0 if OK + */ + function cloture($user, $statut, $note) + { + global $langs,$conf; + + $this->statut = $statut; + $error=0; + $now=dol_now(); + + $this->db->begin(); + + $sql = "UPDATE ".MAIN_DB_PREFIX."askpricesupplier"; + $sql.= " SET fk_statut = ".$statut.", note_private = '".$this->db->escape($note)."', date_cloture='".$this->db->idate($now)."', fk_user_cloture=".$user->id; + $sql.= " WHERE rowid = ".$this->id; + + $resql=$this->db->query($sql); + if ($resql) + { + $modelpdf=$conf->global->ASKPRICESUPPLIER_ADDON_PDF_ODT_CLOSED?$conf->global->ASKPRICESUPPLIER_ADDON_PDF_ODT_CLOSED:$this->modelpdf; + $trigger_name='ASKPRICESUPPLIER_CLOSE_REFUSED'; + + if ($statut == 2) + { + $trigger_name='ASKPRICESUPPLIER_CLOSE_SIGNED'; + $modelpdf=$conf->global->ASKPRICESUPPLIER_ADDON_PDF_ODT_TOBILL?$conf->global->ASKPRICESUPPLIER_ADDON_PDF_ODT_TOBILL:$this->modelpdf; + + // The connected company is classified as a client + $soc=new Societe($this->db); + $soc->id = $this->socid; + $result=$soc->set_as_client(); + + if ($result < 0) + { + $this->error=$this->db->error(); + $this->db->rollback(); + return -2; + } + else + { + $this->updateOrCreatePriceFournisseur($user); + } + } + if ($statut == 4) + { + $trigger_name='ASKPRICESUPPLIER_CLASSIFY_BILLED'; + } + + 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 + $this->generateDocument($modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref); + } + + // Call trigger + $result=$this->call_trigger($trigger_name,$user); + if ($result < 0) { $error++; } + // End call triggers + + if ( ! $error ) + { + $this->db->commit(); + return 1; + } + else + { + $this->db->rollback(); + return -1; + } + } + else + { + $this->error=$this->db->error(); + $this->db->rollback(); + return -1; + } + } + + /** + * Choose between update or create ProductFournisseur + * + * @param User $user Object user + */ + function updateOrCreatePriceFournisseur($user) + { + $productsupplier = new ProductFournisseur($this->db); + + dol_syslog(get_class($this)."::updateOrCreatePriceFournisseur", LOG_DEBUG); + foreach ($this->lines as $product) { + if ($product->subprice <= 0) + continue; + + $idProductFourn = $productsupplier->find_min_price_product_fournisseur($product->fk_product, $product->qty); + $res = $productsupplier->fetch($idProductFourn); + + if ($productsupplier->id) { + if ($productsupplier->fourn_qty == $product->qty) { + $this->updatePriceFournisseur($productsupplier->product_fourn_price_id, $product, $user); + } else { + $this->createPriceFournisseur($product, $user); + } + } else { + $this->createPriceFournisseur($product, $user); + } + } + } + + /** + * Upate ProductFournisseur + * + * @param int $idProductFournPrice id of llx_product_fournisseur_price + * @param int $product contain informations to update + * @param User $user Object user + * @return int <0 if KO, >0 if OK + */ + function updatePriceFournisseur($idProductFournPrice, $product, $user) { + $price=price2num($product->subprice*$product->qty,'MU'); + $unitPrice = price2num($product->subprice,'MU'); + + $sql = 'UPDATE '.MAIN_DB_PREFIX.'product_fournisseur_price SET '.(!empty($product->ref_fourn) ? 'ref_fourn = "'.$product->ref_fourn.'", ' : '').' price ='.$price.', unitprice ='.$unitPrice.' WHERE rowid = '.$idProductFournPrice; + + $resql = $this->db->query($sql); + if (!resql) { + $this->error=$this->db->error(); + $this->db->rollback(); + return -1; + } + } + + /** + * Create ProductFournisseur + * + * @param Product $product Object Product + * @param User $user Object user + * @return int <0 if KO, >0 if OK + */ + function createPriceFournisseur($product, $user) { + $price=price2num($product->subprice*$product->qty,'MU'); + $qty=price2num($product->qty); + $unitPrice = price2num($product->subprice,'MU'); + $now=dol_now(); + + $values = array( + "'".$this->db->idate($now)."'", + $product->fk_product, + $this->client->id, + "'".$product->ref_fourn."'", + $price, + $qty, + $unitPrice, + $product->tva_tx, + $user->id + ); + + $sql = 'INSERT INTO '.MAIN_DB_PREFIX.'product_fournisseur_price '; + $sql .= '(datec, fk_product, fk_soc, ref_fourn, price, quantity, unitprice, tva_tx, fk_user) VALUES ('.implode(',', $values).')'; + + $resql = $this->db->query($sql); + if (!resql) { + $this->error=$this->db->error(); + $this->db->rollback(); + return -1; + } + } + + /** + * Set draft status + * + * @param User $user Object user that modify + * @return int <0 if KO, >0 if OK + */ + function set_draft($user) + { + global $conf,$langs; + + $sql = "UPDATE ".MAIN_DB_PREFIX."askpricesupplier SET fk_statut = 0"; + $sql.= " WHERE rowid = ".$this->id; + + if ($this->db->query($sql)) + { + $this->statut = 0; + $this->brouillon = 1; + return 1; + } + else + { + return -1; + } + } + + + /** + * Return list of askprice (eventually filtered on user) into an array + * + * @param int $shortlist 0=Return array[id]=ref, 1=Return array[](id=>id,ref=>ref,name=>name) + * @param int $draft 0=not draft, 1=draft + * @param int $notcurrentuser 0=all user, 1=not current user + * @param int $socid Id third pary + * @param int $limit For pagination + * @param int $offset For pagination + * @param string $sortfield Sort criteria + * @param string $sortorder Sort order + * @return int -1 if KO, array with result if OK + */ + function liste_array($shortlist=0, $draft=0, $notcurrentuser=0, $socid=0, $limit=0, $offset=0, $sortfield='p.datec', $sortorder='DESC') + { + global $conf,$user; + + $ga = array(); + + $sql = "SELECT s.rowid, s.nom as name, s.client,"; + $sql.= " p.rowid as askpricesupplierid, p.fk_statut, p.total_ht, p.ref, p.remise, "; + $sql.= " p.datep as dp, p.fin_validite as datelimite"; + if (! $user->rights->societe->client->voir && ! $socid) $sql .= ", sc.fk_soc, sc.fk_user"; + $sql.= " FROM ".MAIN_DB_PREFIX."societe as s, ".MAIN_DB_PREFIX."askpricesupplier as p, ".MAIN_DB_PREFIX."c_propalst as c"; + if (! $user->rights->societe->client->voir && ! $socid) $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; + $sql.= " WHERE p.entity = ".$conf->entity; + $sql.= " AND p.fk_soc = s.rowid"; + $sql.= " AND p.fk_statut = c.id"; + if (! $user->rights->societe->client->voir && ! $socid) //restriction + { + $sql.= " AND s.rowid = sc.fk_soc AND sc.fk_user = " .$user->id; + } + if ($socid) $sql.= " AND s.rowid = ".$socid; + if ($draft) $sql.= " AND p.fk_statut = 0"; + if ($notcurrentuser > 0) $sql.= " AND p.fk_user_author <> ".$user->id; + $sql.= $this->db->order($sortfield,$sortorder); + $sql.= $this->db->plimit($limit,$offset); + + $result=$this->db->query($sql); + if ($result) + { + $num = $this->db->num_rows($result); + if ($num) + { + $i = 0; + while ($i < $num) + { + $obj = $this->db->fetch_object($result); + + if ($shortlist == 1) + { + $ga[$obj->askpricesupplierid] = $obj->ref; + } + else if ($shortlist == 2) + { + $ga[$obj->askpricesupplierid] = $obj->ref.' ('.$obj->name.')'; + } + else + { + $ga[$i]['id'] = $obj->askpricesupplierid; + $ga[$i]['ref'] = $obj->ref; + $ga[$i]['name'] = $obj->name; + } + + $i++; + } + } + return $ga; + } + else + { + dol_print_error($this->db); + return -1; + } + } + + /** + * Delete askprice + * + * @param User $user Object user that delete + * @param int $notrigger 1=Does not execute triggers, 0= execuete triggers + * @return int 1 if ok, otherwise if error + */ + function delete($user, $notrigger=0) + { + global $conf,$langs; + require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; + + $error=0; + + $this->db->begin(); + + if (! $notrigger) + { + // Call trigger + $result=$this->call_trigger('ASKPRICESUPPLIER_DELETE',$user); + if ($result < 0) { $error++; } + // End call triggers + } + + if (! $error) + { + $sql = "DELETE FROM ".MAIN_DB_PREFIX."askpricesupplierdet WHERE fk_askpricesupplier = ".$this->id; + if ($this->db->query($sql)) + { + $sql = "DELETE FROM ".MAIN_DB_PREFIX."askpricesupplier WHERE rowid = ".$this->id; + if ($this->db->query($sql)) + { + // Delete linked object + $res = $this->deleteObjectLinked(); + if ($res < 0) $error++; + + if (! $error) + { + // We remove directory + $ref = dol_sanitizeFileName($this->ref); + if ($conf->askpricesupplier->dir_output && !empty($this->ref)) + { + $dir = $conf->askpricesupplier->dir_output . "/" . $ref ; + $file = $dir . "/" . $ref . ".pdf"; + if (file_exists($file)) + { + dol_delete_preview($this); + + if (! dol_delete_file($file,0,0,0,$this)) // For triggers + { + $this->error='ErrorFailToDeleteFile'; + $this->errors=array('ErrorFailToDeleteFile'); + $this->db->rollback(); + return 0; + } + } + if (file_exists($dir)) + { + $res=@dol_delete_dir_recursive($dir); + if (! $res) + { + $this->error='ErrorFailToDeleteDir'; + $this->errors=array('ErrorFailToDeleteDir'); + $this->db->rollback(); + return 0; + } + } + } + } + + // Removed extrafields + if (! $error) + { + if (empty($conf->global->MAIN_EXTRAFIELDS_DISABLED)) // For avoid conflicts if trigger used + { + $result=$this->deleteExtraFields(); + if ($result < 0) + { + $error++; + $errorflag=-4; + dol_syslog(get_class($this)."::delete erreur ".$errorflag." ".$this->error, LOG_ERR); + } + } + } + + if (! $error) + { + dol_syslog(get_class($this)."::delete ".$this->id." by ".$user->id, LOG_DEBUG); + $this->db->commit(); + return 1; + } + else + { + $this->error=$this->db->lasterror(); + $this->db->rollback(); + return 0; + } + } + else + { + $this->error=$this->db->lasterror(); + $this->db->rollback(); + return -3; + } + } + else + { + $this->error=$this->db->lasterror(); + $this->db->rollback(); + return -2; + } + } + else + { + $this->db->rollback(); + return -1; + } + } + + /** + * Object AskPriceSupplier Information + * + * @param int $id Proposal id + * @return void + */ + function info($id) + { + $sql = "SELECT c.rowid, "; + $sql.= " c.datec, c.date_valid as datev, c.date_cloture as dateo,"; + $sql.= " c.fk_user_author, c.fk_user_valid, c.fk_user_cloture"; + $sql.= " FROM ".MAIN_DB_PREFIX."askpricesupplier as c"; + $sql.= " WHERE c.rowid = ".$id; + + $result = $this->db->query($sql); + + if ($result) + { + if ($this->db->num_rows($result)) + { + $obj = $this->db->fetch_object($result); + + $this->id = $obj->rowid; + + $this->date_creation = $this->db->jdate($obj->datec); + $this->date_validation = $this->db->jdate($obj->datev); + $this->date_cloture = $this->db->jdate($obj->dateo); + + $cuser = new User($this->db); + $cuser->fetch($obj->fk_user_author); + $this->user_creation = $cuser; + + if ($obj->fk_user_valid) + { + $vuser = new User($this->db); + $vuser->fetch($obj->fk_user_valid); + $this->user_validation = $vuser; + } + + if ($obj->fk_user_cloture) + { + $cluser = new User($this->db); + $cluser->fetch($obj->fk_user_cloture); + $this->user_cloture = $cluser; + } + + + } + $this->db->free($result); + + } + else + { + dol_print_error($this->db); + } + } + + + /** + * Return label of status of proposal (draft, validated, ...) + * + * @param int $mode 0=long label, 1=short label, 2=Picto + short label, 3=Picto, 4=Picto + long label, 5=Short label + Picto + * @return string Label + */ + function getLibStatut($mode=0) + { + return $this->LibStatut($this->statut,$mode); + } + + /** + * Return label of a status (draft, validated, ...) + * + * @param int $statut id statut + * @param int $mode 0=long label, 1=short label, 2=Picto + short label, 3=Picto, 4=Picto + long label, 5=Short label + Picto + * @return string Label + */ + function LibStatut($statut,$mode=1) + { + global $langs; + $langs->load("askpricesupplier"); + + if ($statut==0) $statuttrans='statut0'; + if ($statut==1) $statuttrans='statut1'; + if ($statut==2) $statuttrans='statut3'; + if ($statut==3) $statuttrans='statut5'; + if ($statut==4) $statuttrans='statut6'; + + if ($mode == 0) return $this->labelstatut[$statut]; + if ($mode == 1) return $this->labelstatut_short[$statut]; + if ($mode == 2) return img_picto($this->labelstatut_short[$statut], $statuttrans).' '.$this->labelstatut_short[$statut]; + if ($mode == 3) return img_picto($this->labelstatut[$statut], $statuttrans); + if ($mode == 4) return img_picto($this->labelstatut[$statut],$statuttrans).' '.$this->labelstatut[$statut]; + if ($mode == 5) return ''.$this->labelstatut_short[$statut].' '.img_picto($this->labelstatut_short[$statut],$statuttrans); + } + + + /** + * Load indicators for dashboard (this->nbtodo and this->nbtodolate) + * + * @param User $user Object user + * @param int $mode "opened" for askprice to close, "signed" for proposal to invoice + * @return int <0 if KO, >0 if OK + */ + function load_board($user,$mode) + { + global $conf, $user; + + $now=dol_now(); + + $this->nbtodo=$this->nbtodolate=0; + $clause = " WHERE"; + + $sql = "SELECT p.rowid, p.ref, p.datec as datec"; + $sql.= " FROM ".MAIN_DB_PREFIX."askpricesupplier as p"; + if (!$user->rights->societe->client->voir && !$user->societe_id) + { + $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."societe_commerciaux as sc ON p.fk_soc = sc.fk_soc"; + $sql.= " WHERE sc.fk_user = " .$user->id; + $clause = " AND"; + } + $sql.= $clause." p.entity = ".$conf->entity; + if ($mode == 'opened') $sql.= " AND p.fk_statut = 1"; + if ($mode == 'signed') $sql.= " AND p.fk_statut = 2"; + if ($user->societe_id) $sql.= " AND p.fk_soc = ".$user->societe_id; + + $resql=$this->db->query($sql); + if ($resql) + { + if ($mode == 'opened') $delay_warning=$conf->askpricesupplier->cloture->warning_delay; + if ($mode == 'signed') $delay_warning=$conf->askpricesupplier->facturation->warning_delay; + + // This assignment in condition is not a bug. It allows walking the results. + while ($obj=$this->db->fetch_object($resql)) + { + $this->nbtodo++; + if ($mode == 'opened') + { + $datelimit = $this->db->jdate($obj->datefin); + if ($datelimit < ($now - $delay_warning)) + { + $this->nbtodolate++; + } + } + // TODO Definir regle des propales a facturer en retard + // if ($mode == 'signed' && ! count($this->FactureListeArray($obj->rowid))) $this->nbtodolate++; + } + return 1; + } + else + { + $this->error=$this->db->error(); + return -1; + } + } + + + /** + * Initialise an instance with random values. + * Used to build previews or test instances. + * id must be 0 if object instance is a specimen. + * + * @return void + */ + function initAsSpecimen() + { + global $user,$langs,$conf; + + // Charge tableau des produits prodids + $prodids = array(); + $sql = "SELECT rowid"; + $sql.= " FROM ".MAIN_DB_PREFIX."product"; + $sql.= " WHERE entity IN (".getEntity('product', 1).")"; + $resql = $this->db->query($sql); + if ($resql) + { + $num_prods = $this->db->num_rows($resql); + $i = 0; + while ($i < $num_prods) + { + $i++; + $row = $this->db->fetch_row($resql); + $prodids[$i] = $row[0]; + } + } + + // Initialise parametres + $this->id=0; + $this->ref = 'SPECIMEN'; + $this->specimen=1; + $this->socid = 1; + $this->date = time(); + $this->cond_reglement_id = 1; + $this->cond_reglement_code = 'RECEP'; + $this->mode_reglement_id = 7; + $this->mode_reglement_code = 'CHQ'; + $this->note_public='This is a comment (public)'; + $this->note_private='This is a comment (private)'; + // Lines + $nbp = 5; + $xnbp = 0; + while ($xnbp < $nbp) + { + $line=new AskPriceSupplierLigne($this->db); + $line->desc=$langs->trans("Description")." ".$xnbp; + $line->qty=1; + $line->subprice=100; + $line->price=100; + $line->tva_tx=19.6; + $line->localtax1_tx=0; + $line->localtax2_tx=0; + if ($xnbp == 2) + { + $line->total_ht=50; + $line->total_ttc=59.8; + $line->total_tva=9.8; + $line->remise_percent=50; + } + else + { + $line->total_ht=100; + $line->total_ttc=119.6; + $line->total_tva=19.6; + $line->remise_percent=00; + } + + $prodid = rand(1, $num_prods); + $line->fk_product=$prodids[$prodid]; + + $this->lines[$xnbp]=$line; + + $this->total_ht += $line->total_ht; + $this->total_tva += $line->total_tva; + $this->total_ttc += $line->total_ttc; + + $xnbp++; + } + } + + /** + * Charge indicateurs this->nb de tableau de bord + * + * @return int <0 if ko, >0 if ok + */ + function load_state_board() + { + global $conf, $user; + + $this->nb=array(); + $clause = "WHERE"; + + $sql = "SELECT count(p.rowid) as nb"; + $sql.= " FROM ".MAIN_DB_PREFIX."askpricesupplier as p"; + $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."societe as s ON p.fk_soc = s.rowid"; + if (!$user->rights->societe->client->voir && !$user->societe_id) + { + $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."societe_commerciaux as sc ON s.rowid = sc.fk_soc"; + $sql.= " WHERE sc.fk_user = " .$user->id; + $clause = "AND"; + } + $sql.= " ".$clause." p.entity = ".$conf->entity; + + $resql=$this->db->query($sql); + if ($resql) + { + // This assignment in condition is not a bug. It allows walking the results. + while ($obj=$this->db->fetch_object($resql)) + { + $this->nb["askprice"]=$obj->nb; + } + $this->db->free($resql); + return 1; + } + else + { + dol_print_error($this->db); + $this->error=$this->db->error(); + return -1; + } + } + + + /** + * Returns the reference to the following non used Proposal used depending on the active numbering module + * defined into ASKPRICESUPPLIER_ADDON + * + * @param Societe $soc Object thirdparty + * @return string Reference libre pour la propale + */ + function getNextNumRef($soc) + { + global $conf, $db, $langs; + $langs->load("askpricesupplier"); + + if (! empty($conf->global->ASKPRICESUPPLIER_ADDON)) + { + $mybool=false; + + $file = $conf->global->ASKPRICESUPPLIER_ADDON.".php"; + $classname = $conf->global->ASKPRICESUPPLIER_ADDON; + + // Include file with class + $dirmodels = array_merge(array('/'), (array) $conf->modules_parts['models']); + foreach ($dirmodels as $reldir) { + + $dir = dol_buildpath($reldir."core/modules/askpricesupplier/"); + + // Load file with numbering class (if found) + $mybool|=@include_once $dir.$file; + } + + if (! $mybool) + { + dol_print_error('',"Failed to include file ".$file); + return ''; + } + + $obj = new $classname(); + $numref = ""; + $numref = $obj->getNextValue($soc,$this); + + if ($numref != "") + { + return $numref; + } + else + { + $this->error=$obj->error; + return ""; + } + } + else + { + $langs->load("errors"); + print $langs->trans("Error")." ".$langs->trans("ErrorModuleSetupNotComplete"); + return ""; + } + } + + /** + * Return clicable link of object (with eventually picto) + * + * @param int $withpicto Add picto into link + * @param string $option Where point the link ('compta', 'expedition', 'document', ...) + * @param string $get_params Parametres added to url + * @return string String with URL + */ + function getNomUrl($withpicto=0,$option='', $get_params='') + { + global $langs; + + $result=''; + $label=$langs->trans("ShowAskpricesupplier").': '.$this->ref; + $linkclose = '" title="'.dol_escape_htmltag($label, 1).'" class="classfortooltip">'; + if ($option == '') { + $lien = ''; + + $picto='askpricesupplier'; + + + if ($withpicto) + $result.=($lien.img_object($label, $picto, 'class="classfortooltip"').$lienfin); + if ($withpicto && $withpicto != 2) + $result.=' '; + $result.=$lien.$this->ref.$lienfin; + return $result; + } + + /** + * Retrieve an array of askprice lines + * + * @return int <0 if ko, >0 if ok + */ + function getLinesArray() + { + $sql = 'SELECT pt.rowid, pt.label as custom_label, pt.description, pt.fk_product, pt.fk_remise_except,'; + $sql.= ' pt.qty, pt.tva_tx, pt.remise_percent, pt.subprice, pt.info_bits,'; + $sql.= ' pt.total_ht, pt.total_tva, pt.total_ttc, pt.fk_product_fournisseur_price as fk_fournprice, pt.buy_price_ht as pa_ht, pt.special_code, pt.localtax1_tx, pt.localtax2_tx,'; + $sql.= ' pt.product_type, pt.rang, pt.fk_parent_line,'; + $sql.= ' p.label as product_label, p.ref, p.fk_product_type, p.rowid as prodid,'; + $sql.= ' p.description as product_desc, pt.ref_fourn as ref_produit_fourn'; + $sql.= ' FROM '.MAIN_DB_PREFIX.'askpricesupplierdet as pt'; + $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'product as p ON pt.fk_product=p.rowid'; + $sql.= ' WHERE pt.fk_askpricesupplier = '.$this->id; + $sql.= ' ORDER BY pt.rang ASC, pt.rowid'; + + dol_syslog(get_class($this).'::getLinesArray', LOG_DEBUG); + $resql = $this->db->query($sql); + if ($resql) + { + $num = $this->db->num_rows($resql); + $i = 0; + + while ($i < $num) + { + $obj = $this->db->fetch_object($resql); + + $this->lines[$i] = new AskPriceSupplierLigne($this->db); + $this->lines[$i]->id = $obj->rowid; // for backward compatibility + $this->lines[$i]->rowid = $obj->rowid; + $this->lines[$i]->label = $obj->custom_label; + $this->lines[$i]->description = $obj->description; + $this->lines[$i]->fk_product = $obj->fk_product; + $this->lines[$i]->ref = $obj->ref; + $this->lines[$i]->product_label = $obj->product_label; + $this->lines[$i]->product_desc = $obj->product_desc; + $this->lines[$i]->fk_product_type = $obj->fk_product_type; // deprecated + $this->lines[$i]->product_type = $obj->product_type; + $this->lines[$i]->qty = $obj->qty; + $this->lines[$i]->subprice = $obj->subprice; + $this->lines[$i]->fk_remise_except = $obj->fk_remise_except; + $this->lines[$i]->remise_percent = $obj->remise_percent; + $this->lines[$i]->tva_tx = $obj->tva_tx; + $this->lines[$i]->info_bits = $obj->info_bits; + $this->lines[$i]->total_ht = $obj->total_ht; + $this->lines[$i]->total_tva = $obj->total_tva; + $this->lines[$i]->total_ttc = $obj->total_ttc; + $this->lines[$i]->fk_fournprice = $obj->fk_fournprice; + $marginInfos = getMarginInfos($obj->subprice, $obj->remise_percent, $obj->tva_tx, $obj->localtax1_tx, $obj->localtax2_tx, $this->lines[$i]->fk_fournprice, $obj->pa_ht); + $this->lines[$i]->pa_ht = $marginInfos[0]; + $this->lines[$i]->marge_tx = $marginInfos[1]; + $this->lines[$i]->marque_tx = $marginInfos[2]; + $this->lines[$i]->fk_parent_line = $obj->fk_parent_line; + $this->lines[$i]->special_code = $obj->special_code; + $this->lines[$i]->rang = $obj->rang; + + $this->lines[$i]->ref_fourn = $obj->ref_produit_fourn; + + $i++; + } + $this->db->free($resql); + + return 1; + } + else + { + $this->error=$this->db->error(); + return -1; + } + } + + /** + * Create a document onto disk according to template module. + * + * @param string $modele Force model to use ('' to not force) + * @param Translate $outputlangs Object langs to use for output + * @param int $hidedetails Hide details of lines + * @param int $hidedesc Hide description + * @param int $hideref Hide ref + * @return int 0 if KO, 1 if OK + */ + public function generateDocument($modele, $outputlangs, $hidedetails=0, $hidedesc=0, $hideref=0) + { + global $conf,$user,$langs; + + $langs->load("askpricesupplier"); + + // Positionne le modele sur le nom du modele a utiliser + if (! dol_strlen($modele)) + { + if (! empty($conf->global->ASKPRICESUPPLIER_ADDON_PDF)) + { + $modele = $conf->global->ASKPRICESUPPLIER_ADDON_PDF; + } + else + { + $modele = 'aurore'; + } + } + + $modelpath = "core/modules/askpricesupplier/doc/"; + + return $this->commonGenerateDocument($modelpath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref); + } + + + function printOriginLinesList() + { + global $langs, $hookmanager; + + print ''; + print ''.$langs->trans('Ref').''; + print ''.$langs->trans('Description').''; + print ''.$langs->trans('VAT').''; + print ''.$langs->trans('PriceUHT').''; + print ''.$langs->trans('Qty').''; + print ''.$langs->trans('ReductionShort').''; + + $num = count($this->lines); + $var = true; + $i = 0; + + foreach ($this->lines as $line) + { + if (empty($line->subprice) || $line->qty <= 0) + continue; + + $var=!$var; + + if (is_object($hookmanager) && (($line->product_type == 9 && ! empty($line->special_code)) || ! empty($line->fk_parent_line))) + { + if (empty($line->fk_parent_line)) + { + $parameters=array('line'=>$line,'var'=>$var,'i'=>$i); + $action=''; + $reshook=$hookmanager->executeHooks('printOriginObjectLine',$parameters,$this,$action); // Note that $action and $object may have been modified by some hooks + } + } + else + { + $this->printOriginLine($line,$var); + } + + $i++; + } + } + + +} + + +/** + * \class AskPriceSupplierLigne + * \brief Class to manage askpricesupplier lines + */ +class AskPriceSupplierLigne extends CommonObject +{ + var $db; + var $error; + + public $element='askpricesupplierdet'; + public $table_element='askpricesupplierdet'; + + var $oldline; + + // From llx_askpricesupplierdet + var $rowid; + var $fk_askpricesupplier; + var $fk_parent_line; + var $desc; // Description ligne + var $fk_product; // Id produit predefini + var $product_type = 0; // Type 0 = product, 1 = Service + + var $qty; + var $tva_tx; + var $subprice; + var $remise_percent; + var $fk_remise_except; + + var $rang = 0; + + var $fk_fournprice; + var $pa_ht; + var $marge_tx; + var $marque_tx; + + var $special_code; // Tag for special lines (exlusive tags) + // 1: frais de port + // 2: ecotaxe + // 3: option line (when qty = 0) + + var $info_bits = 0; // Liste d'options cumulables: + // Bit 0: 0 si TVA normal - 1 si TVA NPR + // Bit 1: 0 ligne normale - 1 si ligne de remise fixe + + var $total_ht; // Total HT de la ligne toute quantite et incluant la remise ligne + var $total_tva; // Total TVA de la ligne toute quantite et incluant la remise ligne + var $total_ttc; // Total TTC de la ligne toute quantite et incluant la remise ligne + + // Ne plus utiliser + var $remise; + var $price; + + // From llx_product + var $ref; // Reference produit + var $libelle; // Label produit + var $product_desc; // Description produit + + var $localtax1_tx; // Local tax 1 + var $localtax2_tx; // Local tax 2 + var $localtax1_type; // Local tax 1 type + var $localtax2_type; // Local tax 2 type + var $total_localtax1; // Line total local tax 1 + var $total_localtax2; // Line total local tax 2 + + var $skip_update_total; // Skip update price total for special lines + + var $ref_fourn; + + /** + * Class line Contructor + * + * @param DoliDB $db Database handler + */ + function __construct($db) + { + $this->db= $db; + } + + /** + * Retrieve the propal line object + * + * @param int $rowid Propal line id + * @return int <0 if KO, >0 if OK + */ + function fetch($rowid) + { + $sql = 'SELECT pd.rowid, pd.fk_askpricesupplier, pd.fk_parent_line, pd.fk_product, pd.label as custom_label, pd.description, pd.price, pd.qty, pd.tva_tx,'; + $sql.= ' pd.remise, pd.remise_percent, pd.fk_remise_except, pd.subprice,'; + $sql.= ' pd.info_bits, pd.total_ht, pd.total_tva, pd.total_ttc, pd.fk_product_fournisseur_price as fk_fournprice, pd.buy_price_ht as pa_ht, pd.special_code, pd.rang,'; + $sql.= ' pd.localtax1_tx, pd.localtax2_tx, pd.total_localtax1, pd.total_localtax2,'; + $sql.= ' p.ref as product_ref, p.label as product_label, p.description as product_desc,'; + $sql.= ' pd.product_type, pd.ref_fourn as ref_produit_fourn'; + $sql.= ' FROM '.MAIN_DB_PREFIX.'askpricesupplierdet as pd'; + $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'product as p ON pd.fk_product = p.rowid'; + $sql.= ' WHERE pd.rowid = '.$rowid; + + $result = $this->db->query($sql); + if ($result) + { + $objp = $this->db->fetch_object($result); + + $this->rowid = $objp->rowid; + $this->fk_askpricesupplier = $objp->fk_askpricesupplier; + $this->fk_parent_line = $objp->fk_parent_line; + $this->label = $objp->custom_label; + $this->desc = $objp->description; + $this->qty = $objp->qty; + $this->price = $objp->price; // deprecated + $this->subprice = $objp->subprice; + $this->tva_tx = $objp->tva_tx; + $this->remise = $objp->remise; + $this->remise_percent = $objp->remise_percent; + $this->fk_remise_except = $objp->fk_remise_except; + $this->fk_product = $objp->fk_product; + $this->info_bits = $objp->info_bits; + + $this->total_ht = $objp->total_ht; + $this->total_tva = $objp->total_tva; + $this->total_ttc = $objp->total_ttc; + + $this->fk_fournprice = $objp->fk_fournprice; + + $marginInfos = getMarginInfos($objp->subprice, $objp->remise_percent, $objp->tva_tx, $objp->localtax1_tx, $objp->localtax2_tx, $this->fk_fournprice, $objp->pa_ht); + $this->pa_ht = $marginInfos[0]; + $this->marge_tx = $marginInfos[1]; + $this->marque_tx = $marginInfos[2]; + + $this->special_code = $objp->special_code; + $this->product_type = $objp->product_type; + $this->rang = $objp->rang; + + $this->ref = $objp->product_ref; // deprecated + $this->product_ref = $objp->product_ref; + $this->libelle = $objp->product_label; // deprecated + $this->product_label = $objp->product_label; + $this->product_desc = $objp->product_desc; + + $this->ref_fourn = $objp->ref_produit_forun; + + $this->db->free($result); + } + else + { + dol_print_error($this->db); + } + } + + /** + * Insert object line propal in database + * + * @param int $notrigger 1=Does not execute triggers, 0= execuete triggers + * @return int <0 if KO, >0 if OK + */ + function insert($notrigger=0) + { + global $conf,$langs,$user; + + $error=0; + + dol_syslog(get_class($this)."::insert rang=".$this->rang); + + // Clean parameters + if (empty($this->tva_tx)) $this->tva_tx=0; + if (empty($this->localtax1_tx)) $this->localtax1_tx=0; + if (empty($this->localtax2_tx)) $this->localtax2_tx=0; + if (empty($this->localtax1_type)) $this->localtax1_type=0; + if (empty($this->localtax2_type)) $this->localtax2_type=0; + if (empty($this->total_localtax1)) $this->total_localtax1=0; + if (empty($this->total_localtax2)) $this->total_localtax2=0; + if (empty($this->rang)) $this->rang=0; + if (empty($this->remise)) $this->remise=0; + if (empty($this->remise_percent)) $this->remise_percent=0; + if (empty($this->info_bits)) $this->info_bits=0; + if (empty($this->special_code)) $this->special_code=0; + if (empty($this->fk_parent_line)) $this->fk_parent_line=0; + if (empty($this->fk_fournprice)) $this->fk_fournprice=0; + + if (empty($this->pa_ht)) $this->pa_ht=0; + + // si prix d'achat non renseigne et utilise pour calcul des marges alors prix achat = prix vente + if ($this->pa_ht == 0) { + if ($this->subprice > 0 && (isset($conf->global->ForceBuyingPriceIfNull) && $conf->global->ForceBuyingPriceIfNull == 1)) + $this->pa_ht = $this->subprice * (1 - $this->remise_percent / 100); + } + + // Check parameters + if ($this->product_type < 0) return -1; + + $this->db->begin(); + + // Insert line into database + $sql = 'INSERT INTO '.MAIN_DB_PREFIX.'askpricesupplierdet'; + $sql.= ' (fk_askpricesupplier, fk_parent_line, label, description, fk_product, product_type,'; + $sql.= ' fk_remise_except, qty, tva_tx, localtax1_tx, localtax2_tx, localtax1_type, localtax2_type,'; + $sql.= ' subprice, remise_percent, '; + $sql.= ' info_bits, '; + $sql.= ' total_ht, total_tva, total_localtax1, total_localtax2, total_ttc, fk_product_fournisseur_price, buy_price_ht, special_code, rang,'; + $sql.= ' ref_fourn)'; + $sql.= " VALUES (".$this->fk_askpricesupplier.","; + $sql.= " ".($this->fk_parent_line>0?"'".$this->fk_parent_line."'":"null").","; + $sql.= " ".(! empty($this->label)?"'".$this->db->escape($this->label)."'":"null").","; + $sql.= " '".$this->db->escape($this->desc)."',"; + $sql.= " ".($this->fk_product?"'".$this->fk_product."'":"null").","; + $sql.= " '".$this->product_type."',"; + $sql.= " ".($this->fk_remise_except?"'".$this->fk_remise_except."'":"null").","; + $sql.= " ".price2num($this->qty).","; + $sql.= " ".price2num($this->tva_tx).","; + $sql.= " ".price2num($this->localtax1_tx).","; + $sql.= " ".price2num($this->localtax2_tx).","; + $sql.= " '".$this->localtax1_type."',"; + $sql.= " '".$this->localtax2_type."',"; + $sql.= " ".($this->subprice?price2num($this->subprice):"null").","; + $sql.= " ".price2num($this->remise_percent).","; + $sql.= " ".(isset($this->info_bits)?"'".$this->info_bits."'":"null").","; + $sql.= " ".price2num($this->total_ht).","; + $sql.= " ".price2num($this->total_tva).","; + $sql.= " ".price2num($this->total_localtax1).","; + $sql.= " ".price2num($this->total_localtax2).","; + $sql.= " ".price2num($this->total_ttc).","; + $sql.= " ".(!empty($this->fk_fournprice)?"'".$this->fk_fournprice."'":"null").","; + $sql.= " ".(isset($this->pa_ht)?"'".price2num($this->pa_ht)."'":"null").","; + $sql.= ' '.$this->special_code.','; + $sql.= ' '.$this->rang.','; + $sql.= " '".$this->db->escape($this->ref_fourn)."'"; + $sql.= ')'; + + dol_syslog(get_class($this).'::insert', LOG_DEBUG); + $resql=$this->db->query($sql); + if ($resql) + { + $this->rowid=$this->db->last_insert_id(MAIN_DB_PREFIX.'askpricesupplierdet'); + + if (empty($conf->global->MAIN_EXTRAFIELDS_DISABLED)) // For avoid conflicts if trigger used + { + $this->id=$this->rowid; + $result=$this->insertExtraFields(); + if ($result < 0) + { + $error++; + } + } + + if (! $notrigger) + { + // Call trigger + $result=$this->call_trigger('LINEASKPRICESUPPLIER_INSERT',$user); + if ($result < 0) + { + $this->db->rollback(); + return -1; + } + // End call triggers + } + + $this->db->commit(); + return 1; + } + else + { + $this->error=$this->db->error()." sql=".$sql; + $this->db->rollback(); + return -1; + } + } + + /** + * Delete line in database + * + * @return int <0 if ko, >0 if ok + */ + function delete() + { + global $conf,$langs,$user; + + $error=0; + $this->db->begin(); + + $sql = "DELETE FROM ".MAIN_DB_PREFIX."askpricesupplierdet WHERE rowid = ".$this->rowid; + dol_syslog("AskPriceSupplierLigne::delete", LOG_DEBUG); + if ($this->db->query($sql) ) + { + + // Remove extrafields + if ((! $error) && (empty($conf->global->MAIN_EXTRAFIELDS_DISABLED))) // For avoid conflicts if trigger used + { + $this->id=$this->rowid; + $result=$this->deleteExtraFields(); + if ($result < 0) + { + $error++; + dol_syslog(get_class($this)."::delete error -4 ".$this->error, LOG_ERR); + } + } + + // Call trigger + $result=$this->call_trigger('LINEASKPRICESUPLLIER_DELETE',$user); + if ($result < 0) + { + $this->db->rollback(); + return -1; + } + // End call triggers + + $this->db->commit(); + + return 1; + } + else + { + $this->error=$this->db->error()." sql=".$sql; + $this->db->rollback(); + return -1; + } + } + + /** + * Update propal line object into DB + * + * @param int $notrigger 1=Does not execute triggers, 0= execuete triggers + * @return int <0 if ko, >0 if ok + */ + function update($notrigger=0) + { + global $conf,$langs,$user; + + $error=0; + + // Clean parameters + if (empty($this->tva_tx)) $this->tva_tx=0; + if (empty($this->localtax1_tx)) $this->localtax1_tx=0; + if (empty($this->localtax2_tx)) $this->localtax2_tx=0; + if (empty($this->total_localtax1)) $this->total_localtax1=0; + if (empty($this->total_localtax2)) $this->total_localtax2=0; + if (empty($this->localtax1_type)) $this->localtax1_type=0; + if (empty($this->localtax2_type)) $this->localtax2_type=0; + if (empty($this->marque_tx)) $this->marque_tx=0; + if (empty($this->marge_tx)) $this->marge_tx=0; + if (empty($this->price)) $this->price=0; // TODO A virer + if (empty($this->remise)) $this->remise=0; // TODO A virer + if (empty($this->remise_percent)) $this->remise_percent=0; + if (empty($this->info_bits)) $this->info_bits=0; + if (empty($this->special_code)) $this->special_code=0; + if (empty($this->fk_parent_line)) $this->fk_parent_line=0; + if (empty($this->fk_fournprice)) $this->fk_fournprice=0; + + if (empty($this->pa_ht)) $this->pa_ht=0; + + // si prix d'achat non renseigne et utilise pour calcul des marges alors prix achat = prix vente + if ($this->pa_ht == 0) { + if ($this->subprice > 0 && (isset($conf->global->ForceBuyingPriceIfNull) && $conf->global->ForceBuyingPriceIfNull == 1)) + $this->pa_ht = $this->subprice * (1 - $this->remise_percent / 100); + } + + $this->db->begin(); + + // Mise a jour ligne en base + $sql = "UPDATE ".MAIN_DB_PREFIX."askpricesupplierdet SET"; + $sql.= " description='".$this->db->escape($this->desc)."'"; + $sql.= " , label=".(! empty($this->label)?"'".$this->db->escape($this->label)."'":"null"); + $sql.= " , product_type=".$this->product_type; + $sql.= " , tva_tx='".price2num($this->tva_tx)."'"; + $sql.= " , localtax1_tx=".price2num($this->localtax1_tx); + $sql.= " , localtax2_tx=".price2num($this->localtax2_tx); + $sql.= " , localtax1_type='".$this->localtax1_type."'"; + $sql.= " , localtax2_type='".$this->localtax2_type."'"; + $sql.= " , qty='".price2num($this->qty)."'"; + $sql.= " , subprice=".price2num($this->subprice).""; + $sql.= " , remise_percent=".price2num($this->remise_percent).""; + $sql.= " , price=".price2num($this->price).""; // TODO A virer + $sql.= " , remise=".price2num($this->remise).""; // TODO A virer + $sql.= " , info_bits='".$this->info_bits."'"; + if (empty($this->skip_update_total)) + { + $sql.= " , total_ht=".price2num($this->total_ht).""; + $sql.= " , total_tva=".price2num($this->total_tva).""; + $sql.= " , total_ttc=".price2num($this->total_ttc).""; + $sql.= " , total_localtax1=".price2num($this->total_localtax1).""; + $sql.= " , total_localtax2=".price2num($this->total_localtax2).""; + } + $sql.= " , fk_product_fournisseur_price=".(! empty($this->fk_fournprice)?"'".$this->fk_fournprice."'":"null"); + $sql.= " , buy_price_ht=".price2num($this->pa_ht); + if (strlen($this->special_code)) $sql.= " , special_code=".$this->special_code; + $sql.= " , fk_parent_line=".($this->fk_parent_line>0?$this->fk_parent_line:"null"); + if (! empty($this->rang)) $sql.= ", rang=".$this->rang; + $sql.= " , ref_fourn=".(! empty($this->ref_fourn)?"'".$this->db->escape($this->ref_fourn)."'":"null"); + $sql.= " WHERE rowid = ".$this->rowid; + + dol_syslog(get_class($this)."::update", LOG_DEBUG); + $resql=$this->db->query($sql); + if ($resql) + { + if (empty($conf->global->MAIN_EXTRAFIELDS_DISABLED)) // For avoid conflicts if trigger used + { + $this->id=$this->rowid; + $result=$this->insertExtraFields(); + if ($result < 0) + { + $error++; + } + } + + if (! $notrigger) + { + // Call trigger + $result=$this->call_trigger('LINEASKPRICESUPPLIER_UPDATE',$user); + if ($result < 0) + { + $this->db->rollback(); + return -1; + } + // End call triggers + } + + $this->db->commit(); + return 1; + } + else + { + $this->error=$this->db->error(); + $this->db->rollback(); + return -2; + } + } + + /** + * Update DB line fields total_xxx + * Used by migration + * + * @return int <0 if ko, >0 if ok + */ + function update_total() + { + $this->db->begin(); + + // Mise a jour ligne en base + $sql = "UPDATE ".MAIN_DB_PREFIX."askpricesupplierdet SET"; + $sql.= " total_ht=".price2num($this->total_ht,'MT').""; + $sql.= ",total_tva=".price2num($this->total_tva,'MT').""; + $sql.= ",total_ttc=".price2num($this->total_ttc,'MT').""; + $sql.= " WHERE rowid = ".$this->rowid; + + dol_syslog("AskPriceSupplierLigne::update_total", LOG_DEBUG); + + $resql=$this->db->query($sql); + if ($resql) + { + $this->db->commit(); + return 1; + } + else + { + $this->error=$this->db->error(); + $this->db->rollback(); + return -2; + } + } + +} + diff --git a/htdocs/comm/askpricesupplier/class/index.html b/htdocs/comm/askpricesupplier/class/index.html new file mode 100644 index 00000000000..e69de29bb2d diff --git a/htdocs/comm/askpricesupplier/document.php b/htdocs/comm/askpricesupplier/document.php new file mode 100644 index 00000000000..f2558e826dc --- /dev/null +++ b/htdocs/comm/askpricesupplier/document.php @@ -0,0 +1,127 @@ + + * Copyright (C) 2004-2009 Laurent Destailleur + * Copyright (C) 2005 Marc Barilley / Ocebo + * Copyright (C) 2005-2012 Regis Houssin + * Copyright (C) 2013 Cédric Salvador + * + * 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/document.php + * \ingroup propal + * \brief Management page of documents attached to a business proposal + */ + +require '../../main.inc.php'; +require_once DOL_DOCUMENT_ROOT.'/comm/askpricesupplier/class/askpricesupplier.class.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/askpricesupplier.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/images.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php'; + +$langs->load('compta'); +$langs->load('other'); + +$action = GETPOST('action','alpha'); +$confirm = GETPOST('confirm','alpha'); +$id = GETPOST('id','int'); +$ref = GETPOST('ref','alpha'); + +// Security check +$socid=''; +if (! empty($user->societe_id)) +{ + $action=''; + $socid = $user->societe_id; +} +$result = restrictedArea($user, 'askpricesupplier', $id); + +// Get parameters +$sortfield = GETPOST("sortfield",'alpha'); +$sortorder = GETPOST("sortorder",'alpha'); +$page = GETPOST("page",'int'); +if ($page == -1) { $page = 0; } +$offset = $conf->liste_limit * $page; +$pageprev = $page - 1; +$pagenext = $page + 1; +if (! $sortorder) $sortorder="ASC"; +if (! $sortfield) $sortfield="name"; + +$object = new AskPriceSupplier($db); +$object->fetch($id,$ref); +if ($object->id > 0) +{ + $object->fetch_thirdparty(); + $upload_dir = $conf->askpricesupplier->dir_output.'/'.dol_sanitizeFileName($object->ref); + include_once DOL_DOCUMENT_ROOT . '/core/tpl/document_actions_pre_headers.tpl.php'; +} + + +/* + * View + */ + +llxHeader('',$langs->trans('CommRequest'),'EN:Ask_Price_Supplier|FR:Demande_de_prix_fournisseur'); + +$form = new Form($db); + +if ($object->id > 0) +{ + $upload_dir = $conf->askpricesupplier->dir_output.'/'.dol_sanitizeFileName($object->ref); + + $head = askpricesupplier_prepare_head($object); + dol_fiche_head($head, 'document', $langs->trans('CommRequest'), 0, 'askpricesupplier'); + + // Construit liste des fichiers + $filearray=dol_dir_list($upload_dir,"files",0,'','(\.meta|_preview\.png)$',$sortfield,(strtolower($sortorder)=='desc'?SORT_DESC:SORT_ASC),1); + $totalsize=0; + foreach($filearray as $key => $file) + { + $totalsize+=$file['size']; + } + + print ''; + + $linkback=''.$langs->trans("BackToList").''; + + // Ref + print ''; + + // Supplier + print ""; + print ''; + + print ''; + print ''; + + print '
'.$langs->trans('Ref').''; + print $form->showrefnav($object,'ref',$linkback,1,'ref','ref',''); + print '
".$langs->trans("Supplier")."'.$object->thirdparty->getNomUrl(1).'
'.$langs->trans("NbOfAttachedFiles").''.count($filearray).'
'.$langs->trans("TotalSizeOfAttachedFiles").''.$totalsize.' '.$langs->trans("bytes").'
'; + + print ''; + + $modulepart = 'askpricesupplier'; + $permission = $user->rights->askpricesupplier->creer; + $param = '&id=' . $object->id; + include_once DOL_DOCUMENT_ROOT . '/core/tpl/document_actions_post_headers.tpl.php'; +} +else +{ + print $langs->trans("ErrorUnknown"); +} + +llxFooter(); +$db->close(); diff --git a/htdocs/comm/askpricesupplier/index.php b/htdocs/comm/askpricesupplier/index.php new file mode 100644 index 00000000000..2f943cef083 --- /dev/null +++ b/htdocs/comm/askpricesupplier/index.php @@ -0,0 +1,377 @@ + + * Copyright (C) 2004-2011 Laurent Destailleur + * Copyright (C) 2005-2012 Regis Houssin + * + * 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/index.php + * \ingroup propal + * \brief Home page of proposal area + */ + +require '../../main.inc.php'; +require_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php'; +require_once DOL_DOCUMENT_ROOT .'/comm/askpricesupplier/class/askpricesupplier.class.php'; + +$langs->load("askpricesupplier"); +$langs->load("companies"); + +// Security check +$socid=GETPOST('socid','int'); +if (isset($user->societe_id) && $user->societe_id > 0) +{ + $action = ''; + $socid = $user->societe_id; +} +$result = restrictedArea($user, 'askpricesupplier'); + + +/* + * View + */ +$now=dol_now(); +$askpricesupplierstatic=new AskPriceSupplier($db); +$companystatic=new Societe($db); +$form = new Form($db); +$formfile = new FormFile($db); +$help_url="EN:Module_Ask_Price_Supplier|FR:Module_Demande_de_prix_fournisseur"; + +llxHeader("",$langs->trans("AskPriceSupplierArea"),$help_url); + +print_fiche_titre($langs->trans("AskPriceSupplierArea")); + +print '
'; + + +/* + * Search form + */ +$var=false; +print ''; +print ''; +print ''; +print ''; +print ''; +print ''; +print ''; +print "
'.$langs->trans("SearchRequest").'
'; +print $langs->trans("Ref").':
'.$langs->trans("Other").':

\n"; + + +/* + * Statistics + */ + +$sql = "SELECT count(p.rowid), p.fk_statut"; +$sql.= " FROM ".MAIN_DB_PREFIX."societe as s"; +$sql.= ", ".MAIN_DB_PREFIX."askpricesupplier as p"; +if (!$user->rights->societe->client->voir && !$socid) $sql.= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; +$sql.= " WHERE p.fk_soc = s.rowid"; +$sql.= " AND p.entity = ".$conf->entity; +if ($user->societe_id) $sql.=' AND p.fk_soc = '.$user->societe_id; +if (!$user->rights->societe->client->voir && !$socid) $sql.= " AND s.rowid = sc.fk_soc AND sc.fk_user = " .$user->id; +$sql.= " AND p.fk_statut IN (0,1,2,3,4)"; +$sql.= " GROUP BY p.fk_statut"; +$resql = $db->query($sql); +if ($resql) +{ + $num = $db->num_rows($resql); + $i = 0; + + $total=0; + $totalinprocess=0; + $dataseries=array(); + $vals=array(); + // -1=Canceled, 0=Draft, 1=Validated, (2=Accepted/On process not managed for customer orders), 3=Closed (Sent/Received, billed or not) + while ($i < $num) + { + $row = $db->fetch_row($resql); + if ($row) + { + //if ($row[1]!=-1 && ($row[1]!=3 || $row[2]!=1)) + { + $vals[$row[1]]=$row[0]; + $totalinprocess+=$row[0]; + } + $total+=$row[0]; + } + $i++; + } + $db->free($resql); + + print ''; + print ''."\n"; + $var=true; + $listofstatus=array(0,1,2,3,4); + foreach ($listofstatus as $status) + { + $dataseries[]=array('label'=>$askpricesupplierstatic->LibStatut($status,1),'data'=>(isset($vals[$status])?(int) $vals[$status]:0)); + if (! $conf->use_javascript_ajax) + { + $var=!$var; + print ""; + print ''; + print ''; + print "\n"; + } + } + if ($conf->use_javascript_ajax) + { + print ''; + } + + print ''; + print "
'.$langs->trans("Statistics").' - '.$langs->trans("CommRequests").'
'.$askpricesupplierstatic->LibStatut($status,0).''.(isset($vals[$status])?$vals[$status]:0).'
'; + $data=array('series'=>$dataseries); + dol_print_graph('stats',300,180,$data,1,'pie',1); + print '
'.$langs->trans("Total").''.$total.'

"; +} +else +{ + dol_print_error($db); +} + + +/* + * Draft askprice + */ +if (! empty($conf->askpricesupplier->enabled)) +{ + $sql = "SELECT c.rowid, c.ref, s.nom as socname, s.rowid as socid, s.canvas, s.client"; + $sql.= " FROM ".MAIN_DB_PREFIX."askpricesupplier as c"; + $sql.= ", ".MAIN_DB_PREFIX."societe as s"; + if (!$user->rights->societe->client->voir && !$socid) $sql.= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; + $sql.= " WHERE c.fk_soc = s.rowid"; + $sql.= " AND c.entity = ".$conf->entity; + $sql.= " AND c.fk_statut = 0"; + if ($socid) $sql.= " AND c.fk_soc = ".$socid; + if (!$user->rights->societe->client->voir && !$socid) $sql.= " AND s.rowid = sc.fk_soc AND sc.fk_user = " .$user->id; + + $resql=$db->query($sql); + if ($resql) + { + print ''; + print ''; + print ''; + $langs->load("askpricesupplier"); + $num = $db->num_rows($resql); + if ($num) + { + $i = 0; + $var = True; + while ($i < $num) + { + $var=!$var; + $obj = $db->fetch_object($resql); + print ""; + + $askpricesupplierstatic->id=$obj->rowid; + $askpricesupplierstatic->ref=$obj->ref; + print ''; + + $companystatic->id=$obj->socid; + $companystatic->name=$obj->socname; + $companystatic->client=$obj->client; + $companystatic->canvas=$obj->canvas; + print ''; + + print ''; + $i++; + } + } + print "
'.$langs->trans("DraftRequests").'
'.$askpricesupplierstatic->getNomUrl(1).''.$companystatic->getNomUrl(1,'customer',24).'

"; + } +} + +print '
'; + + +$max=5; + +/* + * Last modified askprice + */ + +$sql = "SELECT c.rowid, c.ref, c.fk_statut, s.nom as socname, s.rowid as socid, s.canvas, s.client,"; +$sql.= " date_cloture as datec"; +$sql.= " FROM ".MAIN_DB_PREFIX."askpricesupplier as c"; +$sql.= ", ".MAIN_DB_PREFIX."societe as s"; +if (!$user->rights->societe->client->voir && !$socid) $sql.= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; +$sql.= " WHERE c.fk_soc = s.rowid"; +$sql.= " AND c.entity = ".$conf->entity; +//$sql.= " AND c.fk_statut > 2"; +if ($socid) $sql .= " AND c.fk_soc = ".$socid; +if (!$user->rights->societe->client->voir && !$socid) $sql.= " AND s.rowid = sc.fk_soc AND sc.fk_user = " .$user->id; +$sql.= " ORDER BY c.tms DESC"; +$sql.= $db->plimit($max, 0); + +$resql=$db->query($sql); +if ($resql) +{ + print ''; + print ''; + print ''; + + $num = $db->num_rows($resql); + if ($num) + { + $i = 0; + $var = True; + while ($i < $num) + { + $var=!$var; + $obj = $db->fetch_object($resql); + + print ""; + print ''; + + $companystatic->id=$obj->socid; + $companystatic->name=$obj->socname; + $companystatic->client=$obj->client; + $companystatic->canvas=$obj->canvas; + print ''; + + print ''; + print ''; + print ''; + $i++; + } + } + print "
'.$langs->trans("LastModifiedRequests",$max).'
'; + + $askpricesupplierstatic->id=$obj->rowid; + $askpricesupplierstatic->ref=$obj->ref; + + print ''; + print ''; + + print ''; + + print '
'; + print $askpricesupplierstatic->getNomUrl(1); + print ''; + print ' '; + print ''; + $filename=dol_sanitizeFileName($obj->ref); + $filedir=$conf->askpricesupplier->dir_output . '/' . dol_sanitizeFileName($obj->ref); + $urlsource=$_SERVER['PHP_SELF'].'?id='.$obj->rowid; + print $formfile->getDocumentsLink($askpricesupplierstatic->element, $filename, $filedir); + print '
'; + + print '
'.$companystatic->getNomUrl(1,'customer').''.dol_print_date($db->jdate($obj->datec),'day').''.$askpricesupplierstatic->LibStatut($obj->fk_statut,5).'

"; +} +else dol_print_error($db); + + +/* + * Opened askprice + */ +if (! empty($conf->askpricesupplier->enabled) && $user->rights->askpricesupplier->lire) +{ + $langs->load("askpricesupplier"); + + $now=dol_now(); + + $sql = "SELECT s.nom as socname, s.rowid as socid, s.canvas, s.client, p.rowid as askpricesupplierid, p.total as total_ttc, p.total_ht, p.ref, p.fk_statut, p.datec as dp"; + $sql.= " FROM ".MAIN_DB_PREFIX."societe as s"; + $sql.= ", ".MAIN_DB_PREFIX."askpricesupplier as p"; + if (!$user->rights->societe->client->voir && !$socid) $sql.= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; + $sql.= " WHERE p.fk_soc = s.rowid"; + $sql.= " AND p.entity = ".$conf->entity; + $sql.= " AND p.fk_statut = 1"; + if (!$user->rights->societe->client->voir && !$socid) $sql.= " AND s.rowid = sc.fk_soc AND sc.fk_user = " .$user->id; + if ($socid) $sql.= " AND s.rowid = ".$socid; + $sql.= " ORDER BY p.rowid DESC"; + + $result=$db->query($sql); + if ($result) + { + $total = 0; + $num = $db->num_rows($result); + $i = 0; + if ($num > 0) + { + $var=true; + + print ''; + print ''; + + $nbofloop=min($num, (empty($conf->global->MAIN_MAXLIST_OVERLOAD)?500:$conf->global->MAIN_MAXLIST_OVERLOAD)); + while ($i < $nbofloop) + { + $obj = $db->fetch_object($result); + $var=!$var; + print ''; + + // Ref + print '"; + + $companystatic->id=$obj->socid; + $companystatic->name=$obj->socname; + $companystatic->client=$obj->client; + $companystatic->canvas=$obj->canvas; + print ''."\n"; + + print ''."\n"; + print ''; + print ''."\n"; + print ''."\n"; + $i++; + $total += $obj->total_ttc; + } + if ($num > $nbofloop) + { + print '"; + } + else if ($total>0) + { + print '"; + } + print "
'.$langs->trans("RequestsOpened").' '.$num.'
'; + + $askpricesupplierstatic->id=$obj->askpricesupplierid; + $askpricesupplierstatic->ref=$obj->ref; + + print ''; + print ''; + print ''; + print '
'; + print $askpricesupplierstatic->getNomUrl(1); + print ''; + if ($db->jdate($obj->dfv) < ($now - $conf->askpricesupplier->cloture->warning_delay)) print img_warning($langs->trans("Late")); + print ''; + $filename=dol_sanitizeFileName($obj->ref); + $filedir=$conf->askpricesupplier->dir_output . '/' . dol_sanitizeFileName($obj->ref); + $urlsource=$_SERVER['PHP_SELF'].'?id='.$obj->askpricesupplierid; + print $formfile->getDocumentsLink($askpricesupplierstatic->element, $filename, $filedir); + print '
'; + + print "
'.$companystatic->getNomUrl(1,'customer',44).''; + print dol_print_date($db->jdate($obj->dp),'day').''.price($obj->total_ttc).''.$askpricesupplierstatic->LibStatut($obj->fk_statut,3).'
'.$langs->trans("XMoreLines", ($num - $nbofloop))."
'.$langs->trans("Total")."".price($total)." 

"; + } + } + else + { + dol_print_error($db); + } +} + +print '
'; + +llxFooter(); + +$db->close(); diff --git a/htdocs/comm/askpricesupplier/info.php b/htdocs/comm/askpricesupplier/info.php new file mode 100644 index 00000000000..3b8f95d45fa --- /dev/null +++ b/htdocs/comm/askpricesupplier/info.php @@ -0,0 +1,65 @@ + + * Copyright (C) 2004-2006 Laurent Destailleur + * Copyright (C) 2005-2012 Regis Houssin + * + * 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/info.php + * \ingroup propal + * \brief Page d'affichage des infos d'une proposition commerciale + */ + +require '../../main.inc.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/comm/askpricesupplier/class/askpricesupplier.class.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/askpricesupplier.lib.php'; + +$langs->load('askpricesupplier'); +$langs->load('compta'); + +$id=GETPOST('id','int'); +$socid=GETPOST('socid','int'); + +// Security check +if (! empty($user->societe_id)) $socid=$user->societe_id; +$result = restrictedArea($user, 'askpricesupplier', $id); + + +/* + * View + */ + +llxHeader('',$langs->trans('CommRequest'),'EN:Ask_Price_Supplier|FR:Demande_de_prix_fournisseur'); + +$object = new AskPriceSupplier($db); +$object->fetch($id); +$object->fetch_thirdparty(); + +$head = askpricesupplier_prepare_head($object); +dol_fiche_head($head, 'info', $langs->trans('CommRequest'), 0, 'askpricesupplier'); + +$object->info($object->id); + +print '
'; +dol_print_object_info($object); +print '
'; + +print ''; + + +llxFooter(); +$db->close(); diff --git a/htdocs/comm/askpricesupplier/list.php b/htdocs/comm/askpricesupplier/list.php new file mode 100644 index 00000000000..bce521489e0 --- /dev/null +++ b/htdocs/comm/askpricesupplier/list.php @@ -0,0 +1,425 @@ + + * Copyright (C) 2004-2011 Laurent Destailleur + * Copyright (C) 2004 Eric Seigne + * Copyright (C) 2005 Marc Barilley / Ocebo + * Copyright (C) 2005-2013 Regis Houssin + * Copyright (C) 2006 Andre Cianfarani + * Copyright (C) 2010-2011 Juanjo Menent + * Copyright (C) 2010-2011 Philippe Grand + * Copyright (C) 2012 Christophe Battarel + * Copyright (C) 2013 Cédric Salvador +* + * 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/list.php + * \ingroup propal + * \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.formaskpricesupplier.class.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/comm/askpricesupplier/class/askpricesupplier.class.php'; +if (! empty($conf->projet->enabled)) + require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php'; + +$langs->load('companies'); +$langs->load('askpricesupplier'); +$langs->load('compta'); +$langs->load('bills'); +$langs->load('orders'); +$langs->load('products'); + +$socid=GETPOST('socid','int'); + +$search_user=GETPOST('search_user','int'); +$search_sale=GETPOST('search_sale','int'); +$search_ref=GETPOST('sf_ref')?GETPOST('sf_ref','alpha'):GETPOST('search_ref','alpha'); +$search_societe=GETPOST('search_societe','alpha'); +$search_montant_ht=GETPOST('search_montant_ht','alpha'); +$search_author=GETPOST('search_author','alpha'); +$viewstatut=$db->escape(GETPOST('viewstatut')); +$object_statut=$db->escape(GETPOST('askpricesupplier_statut')); + +$sall=GETPOST("sall"); +$mesg=(GETPOST("msg") ? GETPOST("msg") : GETPOST("mesg")); +$year=GETPOST("year"); +$month=GETPOST("month"); + +// Nombre de ligne pour choix de produit/service predefinis +$NBLINES=4; + +// Security check +$module='askpricesupplier'; +$dbtable=''; +$objectid=''; +if (! empty($user->societe_id)) $socid=$user->societe_id; +if (! empty($socid)) +{ + $objectid=$socid; + $module='societe'; + $dbtable='&societe'; +} +$result = restrictedArea($user, $module, $objectid, $dbtable); + +if (GETPOST("button_removefilter") || GETPOST("button_removefilter_x")) // Both tests are required to be compatible with all browsers +{ + $search_categ=''; + $search_user=''; + $search_sale=''; + $search_ref=''; + $search_societe=''; + $search_montant_ht=''; + $search_author=''; + $year=''; + $month=''; + $viewstatut=''; + $object_statut=''; +} + +if($object_statut != '') +$viewstatut=$object_statut; + + +// Initialize technical object to manage hooks of thirdparties. Note that conf->hooks_modules contains array array +$hookmanager->initHooks(array('askpricesupplierlist')); + + + +/* + * Actions + */ + + +$parameters=array('socid'=>$socid); +$reshook=$hookmanager->executeHooks('doActions',$parameters,$object,$action); // Note that $action and $object may have been modified by some hooks +if ($reshook < 0) setEventMessages($hookmanager->error, $hookmanager->errors, 'errors'); + + + +/* + * View + */ + +llxHeader('',$langs->trans('CommRequest'),'EN:Ask_Price_Supplier|FR:Demande_de_prix_fournisseur'); + +$form = new Form($db); +$formother = new FormOther($db); +$formfile = new FormFile($db); +$formaskpricesupplier = new FormAskPriceSupplier($db); +$companystatic=new Societe($db); + +$now=dol_now(); + +$sortfield = GETPOST("sortfield",'alpha'); +$sortorder = GETPOST("sortorder",'alpha'); +$page = GETPOST("page",'int'); +if ($page == -1) { $page = 0; } +$offset = $conf->liste_limit * $page; +$pageprev = $page - 1; +$pagenext = $page + 1; + +if (! $sortfield) $sortfield='p.date_livraison'; +if (! $sortorder) $sortorder='DESC'; +$limit = $conf->liste_limit; + + +$sql = 'SELECT s.rowid, s.nom as name, s.town, s.client, s.code_client,'; +$sql.= ' p.rowid as askpricesupplierid, p.note_private, p.total_ht, p.ref, p.fk_statut, p.fk_user_author, p.date_livraison as dp,'; +if (! $user->rights->societe->client->voir && ! $socid) $sql .= " sc.fk_soc, sc.fk_user,"; +$sql.= ' u.login'; +$sql.= ' FROM '.MAIN_DB_PREFIX.'societe as s, '.MAIN_DB_PREFIX.'askpricesupplier as p'; +if ($sall) $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'askpricesupplierdet as pd ON p.rowid=pd.fk_askpricesupplier'; +$sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'user as u ON p.fk_user_author = u.rowid'; +// We'll need this table joined to the select in order to filter by sale +if ($search_sale > 0 || (! $user->rights->societe->client->voir && ! $socid)) $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; +if ($search_user > 0) +{ + $sql.=", ".MAIN_DB_PREFIX."element_contact as c"; + $sql.=", ".MAIN_DB_PREFIX."c_type_contact as tc"; +} +$sql.= ' WHERE p.fk_soc = s.rowid'; +$sql.= ' AND p.entity = '.$conf->entity; +if (! $user->rights->societe->client->voir && ! $socid) //restriction +{ + $sql.= " AND s.rowid = sc.fk_soc AND sc.fk_user = " .$user->id; +} +if ($search_ref) { + $sql .= natural_search('p.ref', $search_ref); +} +if ($search_societe) { + $sql .= natural_search('s.nom', $search_societe); +} +if ($search_author) +{ + $sql.= " AND u.login LIKE '%".$db->escape(trim($search_author))."%'"; +} +if ($search_montant_ht) +{ + $sql.= " AND p.total_ht='".$db->escape(price2num(trim($search_montant_ht)))."'"; +} +if ($sall) { + $sql .= natural_search(array('s.nom', 'p.note_private', 'p.note_public', 'pd.description'), $sall); +} +if ($socid) $sql.= ' AND s.rowid = '.$socid; +if ($viewstatut <> '') +{ + $sql.= ' AND p.fk_statut IN ('.$viewstatut.')'; +} +if ($month > 0) +{ + if ($year > 0 && empty($day)) + $sql.= " AND p.date_livraison BETWEEN '".$db->idate(dol_get_first_day($year,$month,false))."' AND '".$db->idate(dol_get_last_day($year,$month,false))."'"; + else if ($year > 0 && ! empty($day)) + $sql.= " AND p.date_livraison BETWEEN '".$db->idate(dol_mktime(0, 0, 0, $month, $day, $year))."' AND '".$db->idate(dol_mktime(23, 59, 59, $month, $day, $year))."'"; + else + $sql.= " AND date_format(p.date_livraison, '%m') = '".$month."'"; +} +else if ($year > 0) +{ + $sql.= " AND p.date_livraison BETWEEN '".$db->idate(dol_get_first_day($year,1,false))."' AND '".$db->idate(dol_get_last_day($year,12,false))."'"; +} +if ($search_sale > 0) $sql.= " AND s.rowid = sc.fk_soc AND sc.fk_user = " .$search_sale; +if ($search_user > 0) +{ + $sql.= " AND c.fk_c_type_contact = tc.rowid AND tc.element='askpricesupplier' AND tc.source='internal' AND c.element_id = p.rowid AND c.fk_socpeople = ".$search_user; +} + + +$sql.= ' ORDER BY '.$sortfield.' '.$sortorder.', p.ref DESC'; + +$nbtotalofrecords = 0; +if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST)) +{ + $result = $db->query($sql); + $nbtotalofrecords = $db->num_rows($result); +} + + +$sql.= $db->plimit($limit + 1,$offset); +$result=$db->query($sql); + +if ($result) +{ + $objectstatic=new AskPriceSupplier($db); + $userstatic=new User($db); + $num = $db->num_rows($result); + + if ($socid) + { + $soc = new Societe($db); + $soc->fetch($socid); + } + + $param='&socid='.$socid.'&viewstatut='.$viewstatut; + if ($month) $param.='&month='.$month; + if ($year) $param.='&year='.$year; + if ($search_ref) $param.='&search_ref=' .$search_ref; + if ($search_societe) $param.='&search_societe=' .$search_societe; + if ($search_user > 0) $param.='&search_user='.$search_user; + if ($search_sale > 0) $param.='&search_sale='.$search_sale; + if ($search_montant_ht) $param.='&search_montant_ht='.$search_montant_ht; + if ($search_author) $param.='&search_author='.$search_author; + print_barre_liste($langs->trans('ListOfAskPriceSupplier').' '.($socid?'- '.$soc->name:''), $page, $_SERVER["PHP_SELF"],$param,$sortfield,$sortorder,'',$num,$nbtotalofrecords); + + // Lignes des champs de filtre + print '
'; + + $i = 0; + print ''; + + $moreforfilter=''; + + // If the user can view prospects other than his' + if ($user->rights->societe->client->voir || $socid) + { + $langs->load("commercial"); + $moreforfilter.=$langs->trans('ThirdPartiesOfSaleRepresentative'). ': '; + $moreforfilter.=$formother->select_salesrepresentatives($search_sale,'search_sale',$user); + $moreforfilter.='       '; + } + // If the user can view prospects other than his' + if ($user->rights->societe->client->voir || $socid) + { + $moreforfilter.=$langs->trans('LinkedToSpecificUsers'). ': '; + $moreforfilter.=$form->select_dolusers($search_user,'search_user',1); + } + if (! empty($moreforfilter)) + { + print ''; + print ''; + } + + print ''; + print_liste_field_titre($langs->trans('Ref'),$_SERVER["PHP_SELF"],'p.ref','',$param,'',$sortfield,$sortorder); + print_liste_field_titre($langs->trans('Company'),$_SERVER["PHP_SELF"],'s.nom','',$param,'',$sortfield,$sortorder); + print_liste_field_titre($langs->trans('AskPriceSupplierDate'),$_SERVER["PHP_SELF"],'p.date_livraison','',$param, 'align="center"',$sortfield,$sortorder); + print_liste_field_titre($langs->trans('AmountHT'),$_SERVER["PHP_SELF"],'p.total_ht','',$param, 'align="right"',$sortfield,$sortorder); + print_liste_field_titre($langs->trans('Author'),$_SERVER["PHP_SELF"],'u.login','',$param,'align="center"',$sortfield,$sortorder); + print_liste_field_titre($langs->trans('Status'),$_SERVER["PHP_SELF"],'p.fk_statut','',$param,'align="right"',$sortfield,$sortorder); + print_liste_field_titre(''); + print "\n"; + + print ''; + print ''; + print ''; + + // Date + print ''; + + // Amount + print ''; + // Author + print ''; + print ''; + + print ''; + + print "\n"; + + $var=true; + $total=0; + $subtotal=0; + + while ($i < min($num,$limit)) + { + $objp = $db->fetch_object($result); + $now = dol_now(); + $var=!$var; + print ''; + print '\n"; + + $url = DOL_URL_ROOT.'/comm/card.php?socid='.$objp->rowid; + + // Company + $companystatic->id=$objp->rowid; + $companystatic->name=$objp->name; + $companystatic->client=$objp->client; + $companystatic->code_client=$objp->code_client; + print ''; + + // Date askprice + print '\n"; + + print '\n"; + + $userstatic->id=$objp->fk_user_author; + $userstatic->login=$objp->login; + print '\n"; + + print '\n"; + + print ''; + + print "\n"; + + $total += $objp->total_ht; + $subtotal += $objp->total_ht; + + $i++; + } + + if ($total>0) + { + if($num<$limit){ + $var=!$var; + print ''; + print ''; + print ''; + } + else + { + $var=!$var; + print ''; + print ''; + print ''; + } + + } + + print '
'; + print $moreforfilter; + print '
'; + print ''; + print ''; + print ''; + print ''; + //print $langs->trans('Month').': '; + print ''; + //print ' '.$langs->trans('Year').': '; + $syear = $year; + $formother->select_year($syear,'year',1, 20, 5); + print ''; + print ''; + print ''; + print ''; + print ''; + $formaskpricesupplier->selectAskPriceSupplierStatus($viewstatut,1); + print ''; + print ''; + print ''; + print '
'; + + $objectstatic->id=$objp->askpricesupplierid; + $objectstatic->ref=$objp->ref; + + print ''; + print ''; + + print ''; + + // Ref + print '
'; + print $objectstatic->getNomUrl(1); + print ''; + if ($objp->fk_statut == 1 && $db->jdate($objp->dfv) < ($now - $conf->askpricesupplier->cloture->warning_delay)) print img_warning($langs->trans("Late")); + if (! empty($objp->note_private)) + { + print ' '; + print ''.img_picto($langs->trans("ViewPrivateNote"),'object_generic').''; + print ''; + } + print ''; + $filename=dol_sanitizeFileName($objp->ref); + $filedir=$conf->askpricesupplier->dir_output . '/' . dol_sanitizeFileName($objp->ref); + $urlsource=$_SERVER['PHP_SELF'].'?id='.$objp->askpricesupplierid; + print $formfile->getDocumentsLink($objectstatic->element, $filename, $filedir); + print '
'; + + print "
'; + print $companystatic->getNomUrl(1,'customer'); + print ''; + print dol_print_date($db->jdate($objp->dp), 'day'); + print "'.price($objp->total_ht)."'; + if ($userstatic->id) print $userstatic->getLoginUrl(1); + else print ' '; + print "'.$objectstatic->LibStatut($objp->fk_statut,5)." 
'.$langs->trans("TotalHT").''.price($total).'
'.$langs->trans("TotalHTforthispage").''.price($total).'
'; + + print '
'; + + $db->free($result); +} +else +{ + dol_print_error($db); +} + +// End of page +llxFooter(); +$db->close(); diff --git a/htdocs/comm/askpricesupplier/note.php b/htdocs/comm/askpricesupplier/note.php new file mode 100644 index 00000000000..0ce89fe5e8b --- /dev/null +++ b/htdocs/comm/askpricesupplier/note.php @@ -0,0 +1,113 @@ + + * Copyright (C) 2004-2012 Laurent Destailleur + * Copyright (C) 2004 Eric Seigne + * Copyright (C) 2005-2012 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 + * 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/note.php + * \ingroup propal + * \brief Fiche d'information sur une proposition commerciale + */ + +require '../../main.inc.php'; +require_once DOL_DOCUMENT_ROOT.'/comm/askpricesupplier/class/askpricesupplier.class.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/askpricesupplier.lib.php'; + +$langs->load('askpricesupplier'); +$langs->load('compta'); +$langs->load('bills'); + +$id = GETPOST('id','int'); +$ref=GETPOST('ref','alpha'); +$action=GETPOST('action','alpha'); + +// Security check +if ($user->societe_id) $socid=$user->societe_id; +$result = restrictedArea($user, 'askpricesupplier', $id, 'askpricesupplier'); + +$object = new AskPriceSupplier($db); + + + +/******************************************************************************/ +/* Actions */ +/******************************************************************************/ + +$permissionnote=$user->rights->askpricesupplier->creer; // Used by the include of actions_setnotes.inc.php + +include DOL_DOCUMENT_ROOT.'/core/actions_setnotes.inc.php'; // Must be include, not includ_once + + + +/******************************************************************************/ +/* Affichage fiche */ +/******************************************************************************/ + +llxHeader('',$langs->trans('CommRequest'),'EN:Ask_Price_Supplier|FR:Demande_de_prix_fournisseur'); + +$form = new Form($db); + +if ($id > 0 || ! empty($ref)) +{ + if ($mesg) print $mesg; + + $now=dol_now(); + + if ($object->fetch($id, $ref)) + { + $societe = new Societe($db); + if ( $societe->fetch($object->socid) ) + { + $head = askpricesupplier_prepare_head($object); + dol_fiche_head($head, 'note', $langs->trans('CommRequest'), 0, 'askpricesupplier'); + + print ''; + + $linkback = ''.$langs->trans('BackToList').''; + + // Ref + print ''; + + // Customer + if ( is_null($object->client) ) + $object->fetch_thirdparty(); + print ""; + print ''; + + print ''; + print ''; + + print "
'.$langs->trans('Ref').''; + print $form->showrefnav($object,'ref',$linkback,1,'ref','ref',''); + print '
".$langs->trans("Supplier")."'.$object->client->getNomUrl(1).'
'.$langs->trans('AskPriceSupplierDate').''; + print dol_print_date($object->date_livraison,'daytext'); + print '
"; + + print '
'; + + include DOL_DOCUMENT_ROOT.'/core/tpl/notes.tpl.php'; + + dol_fiche_end(); + } + } +} + + +llxFooter(); +$db->close(); diff --git a/htdocs/comm/askpricesupplier/tpl/index.html b/htdocs/comm/askpricesupplier/tpl/index.html new file mode 100644 index 00000000000..e69de29bb2d diff --git a/htdocs/comm/askpricesupplier/tpl/linkedobjectblock.tpl.php b/htdocs/comm/askpricesupplier/tpl/linkedobjectblock.tpl.php new file mode 100644 index 00000000000..a45fac8b3c9 --- /dev/null +++ b/htdocs/comm/askpricesupplier/tpl/linkedobjectblock.tpl.php @@ -0,0 +1,74 @@ + + * Copyright (C) 2013 Juanjo Menent + * Copyright (C) 2014 Marcos García + * + * 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 . + */ + +?> + + + +'; +print_titre($langs->trans('RelatedAskPriceSupplier')); +?> + + + + + + + + + + > + + + + + + + + + + + +
trans("Ref"); ?>trans("Date"); ?>trans("AmountHTShort"); ?>trans("Status"); ?>
+ trans("ShowAskPriceSupplier"),"askpricesupplier").' '.$object->ref; ?>datec,'day'); ?>rights->askpricesupplier->lire) { + $total = $total + $object->total_ht; + echo price($object->total_ht); + } ?>getLibStatut(3); ?>
trans('TotalHT'); ?>rights->askpricesupplier->lire) { + echo price($total); + } ?> 
+ + diff --git a/htdocs/comm/card.php b/htdocs/comm/card.php index ffc01a998d5..78b786d2366 100644 --- a/htdocs/comm/card.php +++ b/htdocs/comm/card.php @@ -400,7 +400,7 @@ if ($id > 0) // display amount and link to unpaid bill $outstandigBills = $object->get_OutstandingBill(); if ($outstandigBills != 0) - print " / ".price($outstandigBills).''; + print " (".$langs->trans("CurrentOutstandingBill")." ".price($outstandigBills, '', $langs, 0, 0, -1, $conf->currency).')'; print ''; print ''; } diff --git a/htdocs/comm/propal.php b/htdocs/comm/propal.php index 0fe47b9d837..98f662e3d5d 100644 --- a/htdocs/comm/propal.php +++ b/htdocs/comm/propal.php @@ -53,6 +53,7 @@ $langs->load('orders'); $langs->load('products'); $langs->load("deliveries"); $langs->load('sendings'); +if (!empty($conf->incoterm->enabled)) $langs->load('incoterm'); if (! empty($conf->margin->enabled)) $langs->load('margins'); @@ -241,6 +242,12 @@ if (empty($reshook)) $object->set_ref_client($user, $_POST['ref_client']); } + // Set incoterm + elseif ($action == 'set_incoterms' && !empty($conf->incoterm->enabled)) + { + $result = $object->setIncoterms(GETPOST('incoterm_id', 'int'), GETPOST('location_incoterms', 'alpha')); + } + // Create proposal else if ($action == 'add' && $user->rights->propal->creer) { @@ -296,6 +303,8 @@ if (empty($reshook)) $object->author = $user->id; // deprecated $object->note = GETPOST('note'); $object->statut = 0; + $object->fk_incoterms = GETPOST('incoterm_id', 'int'); + $object->location_incoterms = GETPOST('location_incoterms', 'alpha'); $id = $object->create_from($user); } else { @@ -319,6 +328,8 @@ if (empty($reshook)) $object->modelpdf = GETPOST('model'); $object->author = $user->id; // deprecated $object->note = GETPOST('note'); + $object->fk_incoterms = GETPOST('incoterm_id', 'int'); + $object->location_incoterms = GETPOST('location_incoterms', 'alpha'); $object->origin = GETPOST('origin'); $object->origin_id = GETPOST('originid'); @@ -1393,6 +1404,16 @@ if ($action == 'create') print $form->selectarray('model', $liste, ($conf->global->PROPALE_ADDON_PDF_ODT_DEFAULT ? $conf->global->PROPALE_ADDON_PDF_ODT_DEFAULT : $conf->global->PROPALE_ADDON_PDF)); print ""; + // Incoterms + if (!empty($conf->incoterm->enabled)) + { + print ''; + print ''; + print ''; + print $form->select_incoterms((!empty($soc->fk_incoterms) ? $soc->fk_incoterms : ''), (!empty($soc->location_incoterms)?$soc->location_incoterms:'')); + print ''; + } + // Project if (! empty($conf->projet->enabled) && $socid > 0) { @@ -1953,6 +1974,29 @@ if ($action == 'create') print ''; } + // Incoterms + if (!empty($conf->incoterm->enabled)) + { + print ''; + print '
'; + print $langs->trans('IncotermLabel'); + print ''; + if ($user->rights->propal->creer) print ''.img_edit().''; + else print ' '; + print '
'; + print ''; + print ''; + if ($action != 'editincoterm') + { + print $form->textwithpicto($object->display_incoterms(), $object->libelle_incoterms, 1); + } + else + { + print $form->select_incoterms((!empty($object->fk_incoterms) ? $object->fk_incoterms : ''), (!empty($object->location_incoterms)?$object->location_incoterms:''), $_SERVER['PHP_SELF'].'?id='.$object->id); + } + print ''; + } + // Other attributes $cols = 3; include DOL_DOCUMENT_ROOT . '/core/tpl/extrafields_view.tpl.php'; diff --git a/htdocs/comm/propal/class/propal.class.php b/htdocs/comm/propal/class/propal.class.php index 189c6101594..b0997cb9943 100644 --- a/htdocs/comm/propal/class/propal.class.php +++ b/htdocs/comm/propal/class/propal.class.php @@ -117,6 +117,11 @@ class Propal extends CommonObject var $labelstatut_short=array(); var $specimen; + + //Incorterms + var $fk_incoterms; + var $location_incoterms; + var $libelle_incoterms; //Used into tooltip /** @@ -748,6 +753,8 @@ class Propal extends CommonObject $sql.= ", fk_availability"; $sql.= ", fk_input_reason"; $sql.= ", fk_projet"; + $sql.= ", fk_incoterms"; + $sql.= ", location_incoterms"; $sql.= ", entity"; $sql.= ") "; $sql.= " VALUES ("; @@ -775,6 +782,8 @@ class Propal extends CommonObject $sql.= ", ".$this->availability_id; $sql.= ", ".$this->demand_reason_id; $sql.= ", ".($this->fk_project?$this->fk_project:"null"); + $sql.= ", ".(int) $this->fk_incoterms; + $sql.= ", '".$this->db->escape($this->location_incoterms)."'"; $sql.= ", ".$conf->entity; $sql.= ")"; @@ -1095,6 +1104,8 @@ class Propal extends CommonObject $sql.= ", p.fk_mode_reglement"; $sql.= ', p.fk_account'; $sql.= ", p.fk_shipping_method"; + $sql.= ", p.fk_incoterms, p.location_incoterms"; + $sql.= ", i.libelle as libelle_incoterms"; $sql.= ", c.label as statut_label"; $sql.= ", ca.code as availability_code, ca.label as availability"; $sql.= ", dr.code as demand_reason_code, dr.label as demand_reason"; @@ -1105,6 +1116,7 @@ class Propal extends CommonObject $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_payment_term as cr ON p.fk_cond_reglement = cr.rowid'; $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_availability as ca ON p.fk_availability = ca.rowid'; $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_input_reason as dr ON p.fk_input_reason = dr.rowid'; + $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_incoterms as i ON p.fk_incoterms = i.rowid'; $sql.= " WHERE p.fk_statut = c.id"; $sql.= " AND p.entity = ".$conf->entity; if ($ref) $sql.= " AND p.ref='".$ref."'"; @@ -1172,6 +1184,11 @@ class Propal extends CommonObject $this->user_valid_id = $obj->fk_user_valid; $this->user_close_id = $obj->fk_user_cloture; + //Incoterms + $this->fk_incoterms = $obj->fk_incoterms; + $this->location_incoterms = $obj->location_incoterms; + $this->libelle_incoterms = $obj->libelle_incoterms; + if ($obj->fk_statut == 0) { $this->brouillon = 1; @@ -1203,6 +1220,11 @@ class Propal extends CommonObject $result = $this->db->query($sql); if ($result) { + require_once DOL_DOCUMENT_ROOT.'/core/class/extrafields.class.php'; + $extrafieldsline=new ExtraFields($this->db); + $line = new PropaleLigne($this->db); + $extralabelsline=$extrafieldsline->fetch_name_optionals_label($line->table_element,true); + $num = $this->db->num_rows($result); $i = 0; @@ -1212,7 +1234,8 @@ class Propal extends CommonObject $line = new PropaleLigne($this->db); - $line->rowid = $objp->rowid; + $line->rowid = $objp->rowid; //Deprecated + $line->id = $objp->rowid; $line->fk_propal = $objp->fk_propal; $line->fk_parent_line = $objp->fk_parent_line; $line->product_type = $objp->product_type; @@ -1253,6 +1276,8 @@ class Propal extends CommonObject $line->date_start = $objp->date_start; $line->date_end = $objp->date_end; + $line->fetch_optionals($line->id,$extralabelsline); + $this->lines[$i] = $line; //dol_syslog("1 ".$line->fk_product); //print "xx $i ".$this->lines[$i]->fk_product; @@ -1266,12 +1291,6 @@ class Propal extends CommonObject return -1; } - // Retreive all extrafield for propal - // fetch optionals attributes and labels - require_once DOL_DOCUMENT_ROOT.'/core/class/extrafields.class.php'; - $extrafields=new ExtraFields($this->db); - $extralabels=$extrafields->fetch_name_optionals_label($this->table_element,true); - $this->fetch_optionals($this->id,$extralabels); return 1; } diff --git a/htdocs/comm/propal/list.php b/htdocs/comm/propal/list.php index a3ef72bb6ca..da6e56c9460 100644 --- a/htdocs/comm/propal/list.php +++ b/htdocs/comm/propal/list.php @@ -182,9 +182,9 @@ if ($search_author) { $sql.= " AND u.login LIKE '%".$db->escape(trim($search_author))."%'"; } -if ($search_montant_ht) +if ($search_montant_ht != '') { - $sql.= " AND p.total_ht='".$db->escape(price2num(trim($search_montant_ht)))."'"; + $sql.= natural_search("p.total_ht", $search_montant_ht, 1); } if ($sall) { $sql .= natural_search(array('s.nom', 'p.note_private', 'p.note_public', 'pd.description'), $sall); @@ -316,12 +316,12 @@ if ($result) print ''; print ' '; // Amount - print ''; - print ''; + print ''; + print ''; print ''; // Author print ''; - print ''; + print ''; print ''; print ''; $formpropal->selectProposalStatus($viewstatut,1); diff --git a/htdocs/commande/card.php b/htdocs/commande/card.php index 9d17d65910d..5f6c085831f 100644 --- a/htdocs/commande/card.php +++ b/htdocs/commande/card.php @@ -55,6 +55,7 @@ $langs->load('propal'); $langs->load('deliveries'); $langs->load('sendings'); $langs->load('products'); +if (!empty($conf->incoterm->enabled)) $langs->load('incoterm'); if (! empty($conf->margin->enabled)) $langs->load('margins'); @@ -84,10 +85,7 @@ $extrafields = new ExtraFields($db); $extralabels = $extrafields->fetch_name_optionals_label($object->table_element); // Load object -if ($id > 0 || ! empty($ref)) { - $ret = $object->fetch($id, $ref); - $ret = $object->fetch_thirdparty(); -} +include DOL_DOCUMENT_ROOT.'/core/actions_fetchobject.inc.php'; // Must be include, not includ_once // Initialize technical object to manage hooks of thirdparties. Note that conf->hooks_modules contains array array $hookmanager->initHooks(array('ordercard','globalcard')); @@ -222,13 +220,13 @@ if (empty($reshook)) if ($datecommande == '') { setEventMessage($langs->trans('ErrorFieldRequired', $langs->transnoentities('Date')), 'errors'); $action = 'create'; - $error ++; + $error++; } if ($socid < 1) { setEventMessage($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Customer")), 'errors'); $action = 'create'; - $error ++; + $error++; } if (! $error) { @@ -253,7 +251,9 @@ if (empty($reshook)) $object->shipping_method_id = GETPOST('shipping_method_id', 'int'); $object->fk_delivery_address = GETPOST('fk_address'); $object->contactid = GETPOST('contactid'); - + $object->fk_incoterms = GETPOST('incoterm_id', 'int'); + $object->location_incoterms = GETPOST('location_incoterms', 'alpha'); + // If creation from another object of another module (Example: origin=propal, originid=1) if (! empty($origin) && ! empty($originid)) { @@ -350,7 +350,7 @@ if (empty($reshook)) $result = $object->addline($desc, $lines[$i]->subprice, $lines[$i]->qty, $lines[$i]->tva_tx, $lines[$i]->localtax1_tx, $lines[$i]->localtax2_tx, $lines[$i]->fk_product, $lines[$i]->remise_percent, $lines[$i]->info_bits, $lines[$i]->fk_remise_except, 'HT', 0, $date_start, $date_end, $product_type, $lines[$i]->rang, $lines[$i]->special_code, $fk_parent_line, $lines[$i]->fk_fournprice, $lines[$i]->pa_ht, $label, $array_options); if ($result < 0) { - $error ++; + $error++; break; } @@ -365,14 +365,14 @@ if (empty($reshook)) $reshook = $hookmanager->executeHooks('createFrom', $parameters, $object, $action); // Note that $action and $object may have been // modified by hook if ($reshook < 0) - $error ++; + $error++; } else { setEventMessage($srcobject->error, 'errors'); - $error ++; + $error++; } } else { setEventMessage($object->error, 'errors'); - $error ++; + $error++; } } else { // Required extrafield left blank, error message already defined by setOptionalsFromPost() @@ -408,7 +408,7 @@ if (empty($reshook)) $result = $object->add_contact(GETPOST('contactid'), 'CUSTOMER', 'external'); if ($result < 0) { setEventMessage($langs->trans("ErrorFailedToAddContact"), 'errors'); - $error ++; + $error++; } } @@ -518,6 +518,12 @@ if (empty($reshook)) } } + // Set incoterm + elseif ($action == 'set_incoterms' && !empty($conf->incoterm->enabled)) + { + $result = $object->setIncoterms(GETPOST('incoterm_id', 'int'), GETPOST('location_incoterms', 'alpha')); + } + // bank account else if ($action == 'setbankaccount' && $user->rights->commande->creer) { $result=$object->setBankAccount(GETPOST('fk_account', 'int')); @@ -573,24 +579,24 @@ if (empty($reshook)) if (empty($idprod) && ($price_ht < 0) && ($qty < 0)) { setEventMessage($langs->trans('ErrorBothFieldCantBeNegative', $langs->transnoentitiesnoconv('UnitPriceHT'), $langs->transnoentitiesnoconv('Qty')), 'errors'); - $error ++; + $error++; } if (GETPOST('prod_entry_mode') == 'free' && empty($idprod) && GETPOST('type') < 0) { setEventMessage($langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv('Type')), 'errors'); - $error ++; + $error++; } if (GETPOST('prod_entry_mode') == 'free' && empty($idprod) && (! ($price_ht >= 0) || $price_ht == '')) // Unit price can be 0 but not '' { setEventMessage($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("UnitPriceHT")), 'errors'); - $error ++; + $error++; } if ($qty == '') { setEventMessage($langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv('Qty')), 'errors'); - $error ++; + $error++; } if (GETPOST('prod_entry_mode') == 'free' && empty($idprod) && empty($product_desc)) { setEventMessage($langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv('Description')), 'errors'); - $error ++; + $error++; } if (! $error && ($qty >= 0) && (! empty($product_desc) || ! empty($idprod))) { @@ -846,7 +852,7 @@ if (empty($reshook)) if ($price_min && (price2num($pu_ht) * (1 - price2num(GETPOST('remise_percent')) / 100) < price2num($price_min))) { setEventMessage($langs->trans("CantBeLessThanMinPrice", price(price2num($price_min, 'MU'), 0, $langs, 0, 0, - 1, $conf->currency)), 'errors'); - $error ++; + $error++; } } else { $type = GETPOST('type'); @@ -855,7 +861,7 @@ if (empty($reshook)) // Check parameters if (GETPOST('type') < 0) { setEventMessage($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Type")), 'errors'); - $error ++; + $error++; } } @@ -1119,10 +1125,10 @@ if (empty($reshook)) if (empty($reshook)) { $result = $object->insertExtraFields(); if ($result < 0) { - $error ++; + $error++; } } else if ($reshook < 0) - $error ++; + $error++; } if ($error) @@ -1413,6 +1419,16 @@ if ($action == 'create' && $user->rights->commande->creer) print ''; } + // Incoterms + if (!empty($conf->incoterm->enabled)) + { + print ''; + print ''; + print ''; + print $form->select_incoterms((!empty($objectsrc->fk_incoterms) ? $objectsrc->fk_incoterms : ''), (!empty($objectsrc->location_incoterms)?$objectsrc->location_incoterms:'')); + print ''; + } + // Other attributes $parameters = array('objectsrc' => $objectsrc, 'colspan' => ' colspan="3"', 'socid'=>$socid); $reshook = $hookmanager->executeHooks('formObjectOptions', $parameters, $object, $action); // Note that $action and $object may have been modified by @@ -1972,7 +1988,30 @@ if ($action == 'create' && $user->rights->commande->creer) print ''; print ''; } - + + // Incoterms + if (!empty($conf->incoterm->enabled)) + { + print ''; + print '
'; + print $langs->trans('IncotermLabel'); + print ''; + if ($user->rights->commande->creer) print ''.img_edit().''; + else print ' '; + print '
'; + print ''; + print ''; + if ($action != 'editincoterm') + { + print $form->textwithpicto($object->display_incoterms(), $object->libelle_incoterms, 1); + } + else + { + print $form->select_incoterms((!empty($object->fk_incoterms) ? $object->fk_incoterms : ''), (!empty($object->location_incoterms)?$object->location_incoterms:''), $_SERVER['PHP_SELF'].'?id='.$object->id); + } + print ''; + } + // Other attributes $cols = 3; include DOL_DOCUMENT_ROOT . '/core/tpl/extrafields_view.tpl.php'; diff --git a/htdocs/commande/class/commande.class.php b/htdocs/commande/class/commande.class.php index c1c0fa9ec4e..3402999b350 100644 --- a/htdocs/commande/class/commande.class.php +++ b/htdocs/commande/class/commande.class.php @@ -106,6 +106,11 @@ class Commande extends CommonOrder var $lines = array(); + //Incorterms + var $fk_incoterms; + var $location_incoterms; + var $libelle_incoterms; //Used into tooltip + /** * Constructor @@ -672,6 +677,7 @@ class Commande extends CommonOrder $sql.= ", model_pdf, fk_cond_reglement, fk_mode_reglement, fk_account, fk_availability, fk_input_reason, date_livraison, fk_delivery_address"; $sql.= ", fk_shipping_method"; $sql.= ", remise_absolue, remise_percent"; + $sql.= ", fk_incoterms, location_incoterms"; $sql.= ", entity"; $sql.= ")"; $sql.= " VALUES ('(PROV)',".$this->socid.", '".$this->db->idate($now)."', ".$user->id; @@ -694,6 +700,8 @@ class Commande extends CommonOrder $sql.= ", ".($this->shipping_method_id>0?$this->shipping_method_id:'NULL'); $sql.= ", ".($this->remise_absolue>0?$this->remise_absolue:'NULL'); $sql.= ", ".($this->remise_percent>0?$this->remise_percent:0); + $sql.= ", ".(int) $this->fk_incoterms; + $sql.= ", '".$this->db->escape($this->location_incoterms)."'"; $sql.= ", ".$conf->entity; $sql.= ")"; @@ -1389,6 +1397,8 @@ class Commande extends CommonOrder $sql.= ', c.fk_shipping_method'; $sql.= ', c.fk_projet, c.remise_percent, c.remise, c.remise_absolue, c.source, c.facture as billed'; $sql.= ', c.note_private, c.note_public, c.ref_client, c.ref_ext, c.ref_int, c.model_pdf, c.fk_delivery_address, c.extraparams'; + $sql.= ', c.fk_incoterms, c.location_incoterms'; + $sql.= ", i.libelle as libelle_incoterms"; $sql.= ', p.code as mode_reglement_code, p.libelle as mode_reglement_libelle'; $sql.= ', cr.code as cond_reglement_code, cr.libelle as cond_reglement_libelle, cr.libelle_facture as cond_reglement_libelle_doc'; $sql.= ', ca.code as availability_code'; @@ -1398,6 +1408,7 @@ class Commande extends CommonOrder $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_paiement as p ON (c.fk_mode_reglement = p.id)'; $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_availability as ca ON (c.fk_availability = ca.rowid)'; $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_input_reason as dr ON (c.fk_input_reason = ca.rowid)'; + $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_incoterms as i ON c.fk_incoterms = i.rowid'; $sql.= " WHERE c.entity = ".$conf->entity; if ($id) $sql.= " AND c.rowid=".$id; if ($ref) $sql.= " AND c.ref='".$this->db->escape($ref)."'"; @@ -1453,6 +1464,11 @@ class Commande extends CommonOrder $this->shipping_method_id = ($obj->fk_shipping_method>0)?$obj->fk_shipping_method:null; $this->fk_delivery_address = $obj->fk_delivery_address; + //Incoterms + $this->fk_incoterms = $obj->fk_incoterms; + $this->location_incoterms = $obj->location_incoterms; + $this->libelle_incoterms = $obj->libelle_incoterms; + $this->extraparams = (array) json_decode($obj->extraparams, true); $this->lines = array(); diff --git a/htdocs/commande/list.php b/htdocs/commande/list.php index 9d143d87eb2..c38b1a8e34f 100644 --- a/htdocs/commande/list.php +++ b/htdocs/commande/list.php @@ -51,6 +51,7 @@ $sall=GETPOST('sall'); $socid=GETPOST('socid','int'); $search_user=GETPOST('search_user','int'); $search_sale=GETPOST('search_sale','int'); +$search_total_ht=GETPOST('search_total_ht','alpha'); // Security check $id = (GETPOST('orderid')?GETPOST('orderid'):GETPOST('id','int')); @@ -79,6 +80,7 @@ if (GETPOST("button_removefilter_x") || GETPOST("button_removefilter")) // Both $search_ref=''; $search_ref_customer=''; $search_company=''; + $search_total_ht=''; $orderyear=''; $ordermonth=''; $deliverymonth=''; @@ -96,6 +98,7 @@ $parameters=array('socid'=>$socid); $reshook=$hookmanager->executeHooks('doActions',$parameters,$object,$action); // Note that $action and $object may have been modified by some hook if ($reshook < 0) setEventMessages($hookmanager->error, $hookmanager->errors, 'errors'); + /* * View */ @@ -198,7 +201,10 @@ if ($search_user > 0) { $sql.= " AND ec.fk_c_type_contact = tc.rowid AND tc.element='commande' AND tc.source='internal' AND ec.element_id = c.rowid AND ec.fk_socpeople = ".$search_user; } - +if ($search_total_ht != '') +{ + $sql.= natural_search('c.total_ht', $search_total_ht, 1); +} $sql.= ' ORDER BY '.$sortfield.' '.$sortorder; $nbtotalofrecords = 0; @@ -252,7 +258,8 @@ if ($resql) if ($search_ref_customer) $param.='&search_ref_customer='.$search_ref_customer; if ($search_user > 0) $param.='&search_user='.$search_user; if ($search_sale > 0) $param.='&search_sale='.$search_sale; - + if ($search_total_ht != '') $param.='&search_total_ht='.$search_total_ht; + $num = $db->num_rows($resql); print_barre_liste($title, $page,$_SERVER["PHP_SELF"],$param,$sortfield,$sortorder,'',$num,$nbtotalofrecords); $i = 0; @@ -316,7 +323,9 @@ if ($resql) print ''; $formother->select_year($deliveryyear?$deliveryyear:-1,'deliveryyear',1, 20, 5); print ''; - print ' '; + print ''; + print ''; + print ''; print ''; print ''; print "\n"; @@ -328,7 +337,8 @@ if ($resql) $generic_commande = new Commande($db); $generic_product = new Product($db); - while ($i < min($num,$limit)) { + while ($i < min($num,$limit)) + { $objp = $db->fetch_object($resql); $var=!$var; print ''; diff --git a/htdocs/compta/bank/bankid_fr.php b/htdocs/compta/bank/bankid_fr.php deleted file mode 100644 index f20d70ef14f..00000000000 --- a/htdocs/compta/bank/bankid_fr.php +++ /dev/null @@ -1,477 +0,0 @@ - - * Copyright (C) 2003 Jean-Louis Bergamo - * Copyright (C) 2004-2008 Laurent Destailleur - * Copytight (C) 2005-2009 Regis Houssin - * - * 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/compta/bank/bankid_fr.php - * \ingroup banque - * \brief Fiche creation compte bancaire - */ - -require('../../main.inc.php'); -require_once DOL_DOCUMENT_ROOT.'/core/lib/bank.lib.php'; -require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php'; -require_once DOL_DOCUMENT_ROOT.'/compta/bank/class/account.class.php'; - -$langs->load("banks"); -$langs->load("categories"); -$langs->load("bills"); - -$action=GETPOST('action'); -$id=GETPOST('id','int'); -$ref=GETPOST('ref'); - -// Security check -if (isset($_GET["id"]) || isset($_GET["ref"])) -{ - $id = isset($_GET["id"])?$_GET["id"]:(isset($_GET["ref"])?$_GET["ref"]:''); -} -$fieldid = isset($_GET["ref"])?'ref':'rowid'; -if ($user->societe_id) $socid=$user->societe_id; -$result=restrictedArea($user,'banque',$id,'bank_account&bank_account','','',$fieldid); - - -/* - * Actions - */ - -if ($action == 'update' && ! $_POST["cancel"]) -{ - // Modification - $account = new Account($db); - $account->fetch($id); - - $account->bank = trim($_POST["bank"]); - $account->code_banque = trim($_POST["code_banque"]); - $account->code_guichet = trim($_POST["code_guichet"]); - $account->number = trim($_POST["number"]); - $account->cle_rib = trim($_POST["cle_rib"]); - $account->bic = trim($_POST["bic"]); - $account->iban = trim($_POST["iban"]); - $account->domiciliation = trim($_POST["domiciliation"]); - $account->proprio = trim($_POST["proprio"]); - $account->owner_address = trim($_POST["owner_address"]); - $account->state_id = trim($_POST["state_id"]); - //$account->country_id = trim($_POST["country_id"]); // We do not change this. - - if ($account->id) - { - $result = $account->update_bban($user); - if ($result >= 0) - { - $_GET["id"]=$_POST["id"]; // Force chargement page en mode visu - } - else - { - setEventMessage($account->error, 'errors'); - $action='edit'; // Force chargement page edition - } - } -} - -if ($action == 'confirm_delete' && $_POST["confirm"] == "yes" && $user->rights->banque->configurer) -{ - // Modification - $account = new Account($db); - $account->fetch($id); - $account->delete(); - - header("Location: ".DOL_URL_ROOT."/compta/bank/index.php"); - exit; -} - - -/* - * View - */ - -llxHeader(); - -$form = new Form($db); - -/* ************************************************************************** */ -/* */ -/* Affichage page en mode creation */ -/* */ -/* ************************************************************************** */ - -if (($_GET["id"] || $_GET["ref"]) && $action != 'edit') -{ - $account = new Account($db); - if ($_GET["id"]) - { - $result=$account->fetch($id); - } - if ($_GET["ref"]) - { - $result=$account->fetch(0,$_GET["ref"]); - $_GET["id"]=$account->id; - } - - // Onglets - $head=bank_prepare_head($account); - dol_fiche_head($head, 'bankid', $langs->trans("FinancialAccount"),0,'account'); - - // Confirmation de la suppression - if ($action == 'delete') - { - print $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$account->id,$langs->trans("DeleteAccount"),$langs->trans("ConfirmDeleteAccount"),"confirm_delete"); - - } - - - print ''; - - $linkback = ''.$langs->trans("BackToList").''; - - // Ref - print ''; - print ''; - - // Label - print ''; - print ''; - - // Type - print ''; - print ''; - - // Currency - print ''; - print ''; - - // Status - print ''; - print ''; - - if ($account->type == 0 || $account->type == 1) - { - // Country - print '\n"; - - print ''; - print ''; - - // Show fields of bank account - $fieldlists='BankCode DeskCode AccountNumber BankAccountNumberKey'; - if (! empty($conf->global->BANK_SHOW_ORDER_OPTION)) - { - if (is_numeric($conf->global->BANK_SHOW_ORDER_OPTION)) - { - if ($conf->global->BANK_SHOW_ORDER_OPTION == '1') $fieldlists='BankCode DeskCode BankAccountNumberKey AccountNumber'; - } - else $fieldlists=$conf->global->BANK_SHOW_ORDER_OPTION; - } - $fieldlistsarray=explode(' ',$fieldlists); - - foreach($fieldlistsarray as $val) - { - if ($val == 'BankCode') - { - if ($account->useDetailedBBAN() == 1) - { - print ''; - print ''; - print ''; - } - } - if ($val == 'DeskCode') - { - if ($account->useDetailedBBAN() == 1) - { - print ''; - print ''; - print ''; - } - } - - if ($val == 'BankCode') - { - if ($account->useDetailedBBAN() == 2) - { - print ''; - print ''; - print ''; - } - } - - if ($val == 'AccountNumber') - { - print ''; - print ''; - print ''; - } - - if ($val == 'BankAccountNumberKey') - { - if ($account->useDetailedBBAN() == 1) - { - print ''; - print ''; - print ''; - } - } - } - - $ibankey="IBANNumber"; - $bickey="BICNumber"; - if ($account->getCountryCode() == 'IN') $ibankey="IFSC"; - if ($account->getCountryCode() == 'IN') $bickey="SWIFT"; - - print ''; - print ''; - - print ''; - print ''; - - print '\n"; - - print '\n"; - - print '\n"; - - } - - print '
'.$langs->trans("Ref").''; - print $form->showrefnav($account, 'ref', $linkback, 1, 'ref'); - print '
'.$langs->trans("Label").''.$account->label.'
'.$langs->trans("AccountType").''.$account->type_lib[$account->type].'
'.$langs->trans("Currency").''; - $selectedcode=$account->account_currency_code; - if (! $selectedcode) $selectedcode=$conf->currency; - print $langs->trans("Currency".$selectedcode); - print '
'.$langs->trans("Status").''.$account->getLibStatut(4).'
'.$langs->trans("BankAccountCountry").''; - $img=picto_from_langcode($account->country_code); - print $img?$img.' ':''; - print getCountry($account->getCountryCode(), 0, $db); - print "
'.$langs->trans("BankName").''.$account->bank.'
'.$langs->trans("BankCode").''.$account->code_banque.'
'.$langs->trans("DeskCode").''.$account->code_guichet.'
'.$langs->trans("BankCode").''.$account->code_banque.'
'.$langs->trans("BankAccountNumber").''.$account->number.'
'.$langs->trans("BankAccountNumberKey").''.$account->cle_rib.'
'.$langs->trans($ibankey).''.$account->iban.' '; - if (! empty($account->iban)) { - if (! checkIbanForAccount($account)) { - print img_picto($langs->trans("IbanNotValid"),'warning'); - } else { - print img_picto($langs->trans("IbanValid"),'info'); - } - } - print '
'.$langs->trans($bickey).''.$account->bic.' '; - if (! empty($account->bic)) { - if (! checkSwiftForAccount($account)) { - print img_picto($langs->trans("SwiftNotValid"),'warning'); - } else { - print img_picto($langs->trans("SwiftValid"),'info'); - } - } - print '
'.$langs->trans("BankAccountDomiciliation").''; - print nl2br($account->domiciliation); - print "
'.$langs->trans("BankAccountOwner").''; - print $account->proprio; - print "
'.$langs->trans("BankAccountOwnerAddress").''; - print nl2br($account->owner_address); - print "
'; - - - // Check BBAN - if (! checkBanForAccount($account)) - { - print '
'.$langs->trans("RIBControlError").'
'; - } - - print "\n\n"; - - - /* - * Barre d'actions - */ - - print '
'; - - if ($user->rights->banque->configurer) - { - print 'id.'">'.$langs->trans("Modify").''; - } - - print '
'; - -} - -/* ************************************************************************** */ -/* */ -/* Edition */ -/* */ -/* ************************************************************************** */ - -if ($_GET["id"] && $action == 'edit' && $user->rights->banque->configurer) -{ - $account = new Account($db); - $account->fetch($id); - - print_fiche_titre($langs->trans("EditFinancialAccount")); - print "
"; - - print '
'; - print ''; - print ''; - print ''."\n\n"; - - print ''; - - // Ref - print ''; - print ''; - - // Label - print ''; - print ''; - - // Type - print ''; - print ''; - - // Currency - print ''; - print ''; - - // Status - print ''; - print ''; - - if ($account->type == 0 || $account->type == 1) - { - print '\n"; - - // If bank account - print ''; - print ''; - print ''; - - // Show fields of bank account - $fieldlists='BankCode DeskCode AccountNumber BankAccountNumberKey'; - if (! empty($conf->global->BANK_SHOW_ORDER_OPTION)) - { - if (is_numeric($conf->global->BANK_SHOW_ORDER_OPTION)) - { - if ($conf->global->BANK_SHOW_ORDER_OPTION == '1') $fieldlists='BankCode DeskCode BankAccountNumberKey AccountNumber'; - } - else $fieldlists=$conf->global->BANK_SHOW_ORDER_OPTION; - } - $fieldlistsarray=explode(' ',$fieldlists); - - foreach($fieldlistsarray as $val) - { - if ($val == 'BankCode') - { - if ($account->useDetailedBBAN() == 1) - { - print ''; - print ''; - print ''; - } - } - - if ($val == 'DeskCode') - { - if ($account->useDetailedBBAN() == 1) - { - print ''; - print ''; - print ''; - } - } - - if ($val == 'BankCode') - { - if ($account->useDetailedBBAN() == 2) - { - print ''; - print ''; - print ''; - } - } - - if ($val == 'AccountNumber') - { - print ''; - print ''; - print ''; - } - - if ($val == 'BankAccountNumberKey') - { - if ($account->useDetailedBBAN() == 1) - { - print ''; - print ''; - print ''; - } - } - } - - $ibankey="IBANNumber"; - $bickey="BICNumber"; - if ($account->getCountryCode() == 'IN') $ibankey="IFSC"; - if ($account->getCountryCode() == 'IN') $bickey="SWIFT"; - - // IBAN - print ''; - print ''; - - print ''; - print ''; - - print '"; - - print ''; - print ''; - - print '"; - - } - - print '
'.$langs->trans("Ref").''.$account->ref; - print '
'.$langs->trans("Label").''.$account->label; - print '
'.$langs->trans("AccountType").''.$account->type_lib[$account->type]; - print '
'.$langs->trans("Currency").''; - $selectedcode=$account->account_currency_code; - if (! $selectedcode) $selectedcode=$conf->currency; - print $langs->trans("Currency".$selectedcode); - print '
'.$langs->trans("Status").''.$account->getLibStatut(4); - print '
'.$langs->trans("BankAccountCountry").''; - $img=picto_from_langcode($account->country_code); - print $img?$img.' ':''; - print getCountry($account->getCountryCode(), 0, $db); - print "
'.$langs->trans("BankName").'
'.$langs->trans("BankCode").'
'.$langs->trans("DeskCode").'
'.$langs->trans("BankCode").'
'.$langs->trans("BankAccountNumber").'
'.$langs->trans("BankAccountNumberKey").'
'.$langs->trans($ibankey).'
'.$langs->trans($bickey).'
'.$langs->trans("BankAccountDomiciliation").''; - print "
'.$langs->trans("BankAccountOwner").''; - print '
'.$langs->trans("BankAccountOwnerAddress").''; - print "
'; - - print '
'; - - print '
'; - print ''; - print '   '; - print '
'; - - print '
'; -} - - -llxFooter(); - -$db->close(); diff --git a/htdocs/compta/bank/budget.php b/htdocs/compta/bank/budget.php index 04697909eac..5c9d5bdd934 100644 --- a/htdocs/compta/bank/budget.php +++ b/htdocs/compta/bank/budget.php @@ -1,7 +1,7 @@ * Copyright (C) 2004-2010 Laurent Destailleur - * Copytight (C) 2005-2009 Regis Houssin + * Copyright (C) 2005-2009 Regis Houssin * * 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 diff --git a/htdocs/compta/bank/card.php b/htdocs/compta/bank/card.php index c44dd2058b7..c84e7f47482 100644 --- a/htdocs/compta/bank/card.php +++ b/htdocs/compta/bank/card.php @@ -2,8 +2,8 @@ /* Copyright (C) 2002-2003 Rodolphe Quiedeville * Copyright (C) 2003 Jean-Louis Bergamo * Copyright (C) 2004-2012 Laurent Destailleur - * Copytight (C) 2005-2009 Regis Houssin - * Copytight (C) 2014 Alexandre Spangaro + * Copyright (C) 2005-2009 Regis Houssin + * Copyright (C) 2014-2015 Alexandre Spangaro * * 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 @@ -21,19 +21,20 @@ /** * \file htdocs/compta/bank/card.php - * \ingroup banque + * \ingroup bank * \brief Page to create/view a bank account */ require('../../main.inc.php'); -require_once DOL_DOCUMENT_ROOT.'/core/lib/bank.lib.php'; -require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php'; -require_once DOL_DOCUMENT_ROOT.'/core/class/html.formcompany.class.php'; -require_once DOL_DOCUMENT_ROOT.'/core/class/html.formbank.class.php'; -require_once DOL_DOCUMENT_ROOT.'/compta/bank/class/account.class.php'; +require_once DOL_DOCUMENT_ROOT . '/core/lib/bank.lib.php'; +require_once DOL_DOCUMENT_ROOT . '/core/lib/company.lib.php'; +require_once DOL_DOCUMENT_ROOT . '/core/class/html.formcompany.class.php'; +require_once DOL_DOCUMENT_ROOT . '/core/class/html.formbank.class.php'; +require_once DOL_DOCUMENT_ROOT . '/compta/bank/class/account.class.php'; require_once DOL_DOCUMENT_ROOT . '/core/class/extrafields.class.php'; $langs->load("banks"); +$langs->load("bills"); $langs->load("categories"); $langs->load("companies"); $langs->load("compta"); @@ -71,6 +72,18 @@ if ($_POST["action"] == 'add') $account->rappro = (isset($_POST["norappro"]) && $_POST["norappro"])?0:1; $account->url = $_POST["url"]; + $account->bank = trim($_POST["bank"]); + $account->code_banque = trim($_POST["code_banque"]); + $account->code_guichet = trim($_POST["code_guichet"]); + $account->number = trim($_POST["number"]); + $account->cle_rib = trim($_POST["cle_rib"]); + $account->bic = trim($_POST["bic"]); + $account->iban = trim($_POST["iban"]); + $account->domiciliation = trim($_POST["domiciliation"]); + + $account->proprio = trim($_POST["proprio"]); + $account->owner_address = trim($_POST["owner_address"]); + $account->account_number = trim($_POST["account_number"]); $account->accountancy_journal = trim($_POST["accountancy_journal"]); @@ -82,8 +95,8 @@ if ($_POST["action"] == 'add') $account->state_id = $_POST["account_state_id"]; $account->country_id = $_POST["account_country_id"]; - $account->min_allowed = $_POST["account_min_allowed"]; - $account->min_desired = $_POST["account_min_desired"]; + $account->min_allowed = GETPOST("account_min_allowed",'int'); + $account->min_desired = GETPOST("account_min_desired",'int'); $account->comment = trim($_POST["account_comment"]); if ($conf->global->MAIN_BANK_ACCOUNTANCY_CODE_ALWAYS_REQUIRED && empty($account->account_number)) @@ -157,8 +170,8 @@ if ($_POST["action"] == 'update' && ! $_POST["cancel"]) $account->state_id = $_POST["account_state_id"]; $account->country_id = $_POST["account_country_id"]; - $account->min_allowed = $_POST["account_min_allowed"]; - $account->min_desired = $_POST["account_min_desired"]; + $account->min_allowed = GETPOST("account_min_allowed",'int'); + $account->min_desired = GETPOST("account_min_desired",'int'); $account->comment = trim($_POST["account_comment"]); if ($conf->global->MAIN_BANK_ACCOUNTANCY_CODE_ALWAYS_REQUIRED && empty($account->account_number)) @@ -233,8 +246,12 @@ if ($action == 'create') if ($conf->use_javascript_ajax) { - print "\n".''; } diff --git a/htdocs/product/class/product.class.php b/htdocs/product/class/product.class.php index e5a8afc274b..56e721b67ac 100755 --- a/htdocs/product/class/product.class.php +++ b/htdocs/product/class/product.class.php @@ -43,7 +43,7 @@ class Product extends CommonObject public $element='product'; public $table_element='product'; public $fk_element='fk_product'; - protected $childtables=array('propaldet','commandedet','facturedet','contratdet','facture_fourn_det','commande_fournisseurdet'); // To test if we can delete object + protected $childtables=array('askpricesupplierdet', 'propaldet','commandedet','facturedet','contratdet','facture_fourn_det','commande_fournisseurdet'); // To test if we can delete object protected $isnolinkedbythird = 1; // No field fk_soc protected $ismultientitymanaged = 1; // 0=No test on entity, 1=Test with field entity, 2=Test with link by societe @@ -1250,14 +1250,14 @@ class Product extends CommonObject } else { - $this->error=$this->db->error(); + $this->error=$this->db->lasterror(); return -3; } } } else { - $this->error=$this->db->error(); + $this->error=$this->db->lasterror(); return -2; } } @@ -3262,11 +3262,9 @@ class Product extends CommonObject * * @param string $sdir Target directory * @param string $file Array of file info of file to upload: array('name'=>..., 'tmp_name'=>...) - * @param int $maxWidth Largeur maximum que dois faire la miniature (160 by defaut) - * @param int $maxHeight Hauteur maximum que dois faire la miniature (120 by defaut) * @return int <0 if KO, >0 if OK */ - function add_photo($sdir, $file, $maxWidth = 160, $maxHeight = 120) + function add_photo($sdir, $file) { global $conf; @@ -3276,10 +3274,12 @@ class Product extends CommonObject $dir = $sdir; if (! empty($conf->global->PRODUCT_USE_OLD_PATH_FOR_PHOTO)) $dir .= '/'. get_exdir($this->id,2) . $this->id ."/photos"; + else $dir .= '/'.dol_sanitizeFileName($this->ref); dol_mkdir($dir); $dir_osencoded=$dir; + if (is_dir($dir_osencoded)) { $originImage = $dir . '/' . $file['name']; @@ -3290,7 +3290,7 @@ class Product extends CommonObject if (file_exists(dol_osencode($originImage))) { // Cree fichier en taille vignette - $this->add_thumb($originImage,$maxWidth,$maxHeight); + $this->add_thumb($originImage); } } @@ -3302,18 +3302,24 @@ class Product extends CommonObject * Build thumb * * @param string $file Chemin du fichier d'origine - * @param int $maxWidth Largeur maximum que dois faire la miniature (160 par defaut) - * @param int $maxHeight Hauteur maximum que dois faire la miniature (120 par defaut) * @return void */ - function add_thumb($file, $maxWidth = 160, $maxHeight = 120) + function add_thumb($file) { - require_once DOL_DOCUMENT_ROOT .'/core/lib/images.lib.php'; + global $maxwidthsmall, $maxheightsmall, $maxwidthmini, $maxheightmini, $quality; + + require_once DOL_DOCUMENT_ROOT .'/core/lib/images.lib.php'; // This define also $maxwidthsmall, $quality, ... $file_osencoded=dol_osencode($file); if (file_exists($file_osencoded)) { - vignette($file,$maxWidth,$maxHeight); + // Create small thumbs for company (Ratio is near 16/9) + // Used on logon for example + $imgThumbSmall = vignette($file, $maxwidthsmall, $maxheightsmall, '_small', $quality); + + // Create mini thumbs for company (Ratio is near 16/9) + // Used on menu or for setup page for example + $imgThumbMini = vignette($file, $maxwidthmini, $maxheightmini, '_mini', $quality); } } diff --git a/htdocs/product/stats/commande.php b/htdocs/product/stats/commande.php index 2ae1dcd1582..49a443938ab 100644 --- a/htdocs/product/stats/commande.php +++ b/htdocs/product/stats/commande.php @@ -141,9 +141,9 @@ if ($id > 0 || ! empty($ref)) $sql.= " AND d.fk_commande = c.rowid"; $sql.= " AND d.fk_product =".$product->id; if (! empty($search_month)) - $sql.= ' AND MONTH(f.datef) IN (' . $search_month . ')'; + $sql.= ' AND MONTH(c.date_commande) IN (' . $search_month . ')'; if (! empty($search_year)) - $sql.= ' AND YEAR(f.datef) IN (' . $search_year . ')'; + $sql.= ' AND YEAR(c.date_commande) IN (' . $search_year . ')'; if (!$user->rights->societe->client->voir && !$socid) $sql.= " AND s.rowid = sc.fk_soc AND sc.fk_user = " .$user->id; if ($socid) $sql.= " AND c.fk_soc = ".$socid; $sql.= " ORDER BY $sortfield $sortorder "; @@ -189,12 +189,14 @@ if ($id > 0 || ! empty($ref)) print_barre_liste($langs->trans("CustomersOrders"),$page,$_SERVER["PHP_SELF"],"&id=$product->id",$sortfield,$sortorder,'',$num,$totalrecords,''); print '
'; - print $langs->trans('Period').'('.$langs->trans("DateInvoice") .') '; + print $langs->trans('Period').' ('.$langs->trans("OrderDate") .') - '; print $langs->trans('Month') . ': '; print $langs->trans('Year') . ':' . $formother->selectyear($search_year ? $search_year : - 1, 'search_year', 1, 20, 5); + print '
'; print ''; print ''; print '
'; + print '
'; $i = 0; print ''; diff --git a/htdocs/product/stats/commande_fournisseur.php b/htdocs/product/stats/commande_fournisseur.php index 3141b3266e9..8cbdea41495 100644 --- a/htdocs/product/stats/commande_fournisseur.php +++ b/htdocs/product/stats/commande_fournisseur.php @@ -150,9 +150,9 @@ if ($id > 0 || ! empty($ref)) { $sql .= " AND d.fk_commande = c.rowid"; $sql .= " AND d.fk_product =" . $product->id; if (! empty($search_month)) - $sql .= ' AND MONTH(f.datef) IN (' . $search_month . ')'; + $sql .= ' AND MONTH(c.date_commande) IN (' . $search_month . ')'; if (! empty($search_year)) - $sql .= ' AND YEAR(f.datef) IN (' . $search_year . ')'; + $sql .= ' AND YEAR(c.date_commande) IN (' . $search_year . ')'; if (! $user->rights->societe->client->voir && ! $socid) $sql .= " AND s.rowid = sc.fk_soc AND sc.fk_user = " . $user->id; if ($socid) @@ -199,12 +199,14 @@ if ($id > 0 || ! empty($ref)) { print_barre_liste($langs->trans("SuppliersOrders"), $page, $_SERVER["PHP_SELF"], "&id=$product->id", $sortfield, $sortorder, '', $num, $totalrecords, ''); print '
'; - print $langs->trans('Period') . '(' . $langs->trans("DateInvoice") . ') '; + print $langs->trans('Period') . ' (' . $langs->trans("OrderDate") . ') - '; print $langs->trans('Month') . ': '; print $langs->trans('Year') . ':' . $formother->selectyear($search_year ? $search_year : - 1, 'search_year', 1, 20, 5); + print '
'; print ''; print ''; print '
'; + print '
'; $i = 0; print '
'; diff --git a/htdocs/product/stats/facture.php b/htdocs/product/stats/facture.php index b59bc008f17..2ae8164b0f9 100644 --- a/htdocs/product/stats/facture.php +++ b/htdocs/product/stats/facture.php @@ -190,12 +190,14 @@ if ($id > 0 || ! empty($ref)) print_barre_liste($langs->trans("CustomersInvoices"),$page,$_SERVER["PHP_SELF"],"&id=".$product->id,$sortfield,$sortorder,'',$num,$totalrecords,''); print '
'; - print $langs->trans('Period').'('.$langs->trans("DateInvoice") .') '; + print $langs->trans('Period').' ('.$langs->trans("DateInvoice") .') - '; print $langs->trans('Month') . ': '; print $langs->trans('Year') . ':' . $formother->selectyear($search_year ? $search_year : - 1, 'search_year', 1, 20, 5); + print '
'; print ''; print ''; print '
'; + print '
'; $i = 0; print '
'; diff --git a/htdocs/product/stats/facture_fournisseur.php b/htdocs/product/stats/facture_fournisseur.php index 0feb415cc43..2e8e84621ba 100644 --- a/htdocs/product/stats/facture_fournisseur.php +++ b/htdocs/product/stats/facture_fournisseur.php @@ -191,12 +191,14 @@ if ($id > 0 || ! empty($ref)) print_barre_liste($langs->trans("SuppliersInvoices"), $page, $_SERVER["PHP_SELF"], "&id=$product->id", $sortfield, $sortorder, '', $num, $totalrecords, ''); print '
'; - print $langs->trans('Period') . '(' . $langs->trans("DateInvoice") . ') '; + print $langs->trans('Period') . ' (' . $langs->trans("DateInvoice") . ') - '; print $langs->trans('Month') . ': '; print $langs->trans('Year') . ':' . $formother->selectyear($search_year ? $search_year : - 1, 'search_year', 1, 20, 5); + print '
'; print ''; print ''; print '
'; + print '
'; $i = 0; print '
'; diff --git a/htdocs/product/stats/propal.php b/htdocs/product/stats/propal.php index 50d7c952b6d..10fd8247204 100644 --- a/htdocs/product/stats/propal.php +++ b/htdocs/product/stats/propal.php @@ -192,12 +192,14 @@ if ($id > 0 || ! empty($ref)) print_barre_liste($langs->trans("Proposals"), $page, $_SERVER["PHP_SELF"], "&id=$product->id", $sortfield, $sortorder, '', $num, $totalrecords, ''); print '
'; - print $langs->trans('Period') . '(' . $langs->trans("DateInvoice") . ') '; + print $langs->trans('Period') . ' (' . $langs->trans("DatePropal") . ') - '; print $langs->trans('Month') . ': '; print $langs->trans('Year') . ':' . $formother->selectyear($search_year ? $search_year : - 1, 'search_year', 1, 20, 5); + print '
'; print ''; print ''; print '
'; + print '
'; $i = 0; print '
'; diff --git a/htdocs/projet/activity/perday.php b/htdocs/projet/activity/perday.php index f7b37ca1ca0..abec2e8cf7c 100644 --- a/htdocs/projet/activity/perday.php +++ b/htdocs/projet/activity/perday.php @@ -50,6 +50,11 @@ $result = restrictedArea($user, 'projet', $projectid); $now=dol_now(); +$year=GETPOST("year","int")?GETPOST("year","int"):date("Y"); +$month=GETPOST("month","int")?GETPOST("month","int"):date("m"); +$week=GETPOST("week","int")?GETPOST("week","int"):date("W"); +$day=GETPOST("day","int")?GETPOST("day","int"):date("d"); + /* * Actions @@ -78,8 +83,10 @@ $taskstatic = new Task($db); $title=$langs->trans("TimeSpent"); if ($mine) $title=$langs->trans("MyTimeSpent"); +$usertoprocess=$user; + //$projectsListId = $projectstatic->getProjectsAuthorizedForUser($user,$mine,1); -$projectsListId = $projectstatic->getProjectsAuthorizedForUser($user,0,1); // Return all project i have permission on. I want my tasks and some of my task may be on a public projet that is not my project +$projectsListId = $projectstatic->getProjectsAuthorizedForUser($usertoprocess,0,1); // Return all project i have permission on. I want my tasks and some of my task may be on a public projet that is not my project if ($id) { @@ -89,8 +96,8 @@ if ($id) $onlyopened=1; // or -1 $tasksarray=$taskstatic->getTasksArray(0,0,($project->id?$project->id:$projectsListId),$socid,0,'',$onlyopened); // We want to see all task of opened project i am allowed to see, not only mine. Later only mine will be editable later. -$projectsrole=$taskstatic->getUserRolesForProjectsOrTasks($user,0,($project->id?$project->id:$projectsListId),0); -$tasksrole=$taskstatic->getUserRolesForProjectsOrTasks(0,$user,($project->id?$project->id:$projectsListId),0); +$projectsrole=$taskstatic->getUserRolesForProjectsOrTasks($usertoprocess,0,($project->id?$project->id:$projectsListId),0); +$tasksrole=$taskstatic->getUserRolesForProjectsOrTasks(0,$usertoprocess,($project->id?$project->id:$projectsListId),0); //var_dump($tasksarray); //var_dump($projectsrole); //var_dump($taskrole); @@ -101,10 +108,45 @@ llxHeader("",$title,"",'','','',array('/core/js/timesheet.js')); print_barre_liste($title, $page, $_SERVER["PHP_SELF"], "", $sortfield, $sortorder, "", $num); -print ''; +$startdayarray=dol_get_first_day_week($day, $month, $year); + +$prev = $startdayarray; +$prev_year = $prev['prev_year']; +$prev_month = $prev['prev_month']; +$prev_day = $prev['prev_day']; +$first_day = $prev['first_day']; +$first_month= $prev['first_month']; +$first_year = $prev['first_year']; +$week = $prev['week']; + +$day = (int) $day; +$next = dol_get_next_week($first_day, $week, $first_month, $first_year); +$next_year = $next['year']; +$next_month = $next['month']; +$next_day = $next['day']; + +// Define firstdaytoshow and lastdaytoshow (warning: lastdaytoshow is last second to show + 1) +$firstdaytoshow=dol_mktime(0,0,0,$first_month,$first_day,$first_year); +$lastdaytoshow=dol_time_plus_duree($firstdaytoshow, 7, 'd'); + +$tmpday = $first_day; + +// Show navigation bar +$nav ="".img_previous($langs->trans("Previous"))."\n"; +$nav.=" ".dol_print_date(dol_mktime(0,0,0,$first_month,$first_day,$first_year),"%Y").", ".$langs->trans("Week")." ".$week; +$nav.=" \n"; +$nav.="".img_next($langs->trans("Next"))."\n"; +$nav.="   (".$langs->trans("Today").")"; +$picto='calendarweek'; + + +print ''; print ''; print ''; print ''; +print ''; +print ''; +print ''; $head=project_timesheet_prepare_head($mode); dol_fiche_head($head, 'inputperday', '', 0, 'task'); @@ -138,6 +180,10 @@ print "\n"; dol_fiche_end(); */ + +print '
'.$nav.'
'; + + print '
'; print ''; print ''; @@ -145,10 +191,10 @@ print ''; print ''; print ''; print ''; -//print ''; +print ''; +if ($usertoprocess->id == $user->id) print ''; +else print ''; -$tmp=dol_getdate($now); -$startdayarray=dol_get_first_day_week($tmp['mday'], $tmp['mon'], $tmp['year']); $startday=dol_mktime(12, 0, 0, $startdayarray['first_month'], $startdayarray['first_day'], $startdayarray['first_year']); for($i=0;$i<7;$i++) @@ -167,7 +213,7 @@ if (count($tasksarray) > 0) projectLinesPerDay($j, 0, $tasksarray, $level, $projectsrole, $tasksrole, $mine, $restricteditformytask); print ' - + @@ -189,10 +235,17 @@ print ''; -print ''; +print ''; print ''; -print ''; +print ''."\n\n"; + + +print ''; llxFooter(); diff --git a/htdocs/projet/activity/pertime.php b/htdocs/projet/activity/pertime.php index 9d277251772..9f2dc3e99ca 100644 --- a/htdocs/projet/activity/pertime.php +++ b/htdocs/projet/activity/pertime.php @@ -62,8 +62,8 @@ if ($action == 'addtime' && $user->rights->projet->creer) { if (intval($time) > 0) { - // Hours or minutes - if (preg_match("/([0-9]+)(hour|min)/",$key,$matches)) + // Hours or minutes of duration + if (preg_match("/([0-9]+)duration(hour|min)/",$key,$matches)) { $id = $matches[1]; if ($id > 0) @@ -86,15 +86,33 @@ if ($action == 'addtime' && $user->rights->projet->creer) $task->progress = GETPOST($key . 'progress', 'int'); $task->timespent_duration = $val; $task->timespent_fk_user = $user->id; - $task->timespent_date = dol_mktime(12,0,0,$_POST["{$key}month"],$_POST["{$key}day"],$_POST["{$key}year"]); - $task->addTimeSpent($user); + if (GETPOST($key."hour") != '' && GETPOST($key."hour") >= 0) // If hour was entered + { + $task->timespent_date = dol_mktime(GETPOST($key."hour"),GETPOST($key."min"),0,GETPOST($key."month"),GETPOST($key."day"),GETPOST($key."year")); + $task->timespent_withhour = 1; + } + else + { + $task->timespent_date = dol_mktime(12,0,0,GETPOST($key."month"),GETPOST($key."day"),GETPOST($key."year")); + } + + $result=$task->addTimeSpent($user); + if ($result < 0) + { + setEventMessages($task->error, $task->errors, 'errors'); + $error++; + break; + } } - setEventMessage($langs->trans("RecordSaved")); + if (! $error) + { + setEventMessage($langs->trans("RecordSaved")); - // Redirect to avoid submit twice on back - header('Location: '.$_SERVER["PHP_SELF"].'?id='.$projectid.($mode?'&mode='.$mode:'')); - exit; + // Redirect to avoid submit twice on back + header('Location: '.$_SERVER["PHP_SELF"].($projectid?'?id='.$projectid:'?').($mode?'&mode='.$mode:'')); + exit; + } } else { @@ -116,8 +134,9 @@ $taskstatic = new Task($db); $title=$langs->trans("TimeSpent"); if ($mine) $title=$langs->trans("MyTimeSpent"); -//$projectsListId = $projectstatic->getProjectsAuthorizedForUser($user,$mine,1); -$projectsListId = $projectstatic->getProjectsAuthorizedForUser($user,0,1); // Return all project i have permission on. I want my tasks and some of my task may be on a public projet that is not my project +$usertoprocess = $user; + +$projectsListId = $projectstatic->getProjectsAuthorizedForUser($usertoprocess,0,1); // Return all project i have permission on. I want my tasks and some of my task may be on a public projet that is not my project if ($id) { @@ -127,8 +146,8 @@ if ($id) $onlyopened=1; // or -1 $tasksarray=$taskstatic->getTasksArray(0,0,($project->id?$project->id:$projectsListId),$socid,0,'',$onlyopened); // We want to see all task of opened project i am allowed to see, not only mine. Later only mine will be editable later. -$projectsrole=$taskstatic->getUserRolesForProjectsOrTasks($user,0,($project->id?$project->id:$projectsListId),0); -$tasksrole=$taskstatic->getUserRolesForProjectsOrTasks(0,$user,($project->id?$project->id:$projectsListId),0); +$projectsrole=$taskstatic->getUserRolesForProjectsOrTasks($usertoprocess,0,($project->id?$project->id:$projectsListId),0); +$tasksrole=$taskstatic->getUserRolesForProjectsOrTasks(0,$usertoprocess,($project->id?$project->id:$projectsListId),0); //var_dump($tasksarray); //var_dump($projectsrole); //var_dump($taskrole); @@ -184,7 +203,10 @@ print ''; print ''; print ''; print ''; -print ''; +if ($usertoprocess->id == $user->id) print ''; +else print ''; +print ''; +print ''; print "\n"; // By default, we can edit only tasks we are assigned to diff --git a/htdocs/projet/card.php b/htdocs/projet/card.php index 541d9271ade..990640f0fee 100644 --- a/htdocs/projet/card.php +++ b/htdocs/projet/card.php @@ -38,6 +38,7 @@ $id=GETPOST('id','int'); $ref=GETPOST('ref','alpha'); $action=GETPOST('action','alpha'); $backtopage=GETPOST('backtopage','alpha'); +$cancel=GETPOST('cancel','alpha'); if ($id == '' && $ref == '' && ($action != "create" && $action != "add" && $action != "update" && ! $_POST["cancel"])) accessforbidden(); @@ -49,15 +50,15 @@ $hookmanager->initHooks(array('projectcard','globalcard')); $object = new Project($db); $extrafields = new ExtraFields($db); + +// Load object +//include DOL_DOCUMENT_ROOT.'/core/actions_fetchobject.inc.php'; // Can use generic include because when creating a project, ref is defined and we dont want error if fetch fails from ref. if ($id > 0 || ! empty($ref)) { - $ret = $object->fetch($id,$ref); + $ret = $object->fetch($id,$ref); // If we create project, ref may be defined into POST but record does not yet exists into database if ($ret > 0) { $object->fetch_thirdparty(); $id=$object->id; - } else { - setEventMessage($object->error, 'errors'); - $action=''; } } @@ -83,9 +84,8 @@ if ($reshook < 0) setEventMessages($hookmanager->error, $hookmanager->errors, 'e if (empty($reshook)) { - // Cancel - if (GETPOST("cancel") && ! empty($backtopage)) + if ($cancel) { if (GETPOST("comefromclone")==1) { @@ -101,24 +101,13 @@ if (empty($reshook)) setEventMessage($langs->trans("CantRemoveProject"), 'errors'); } } - header("Location: ".$backtopage); - exit; - } + if ($backtopage) + { + header("Location: ".$backtopage); + exit; + } - //if cancel and come from clone then delete the cloned project - if (GETPOST("cancel") && (GETPOST("comefromclone")==1)) - { - $result=$object->delete($user); - if ($result > 0) - { - header("Location: index.php"); - exit; - } - else - { - dol_syslog($object->error,LOG_DEBUG); - setEventMessage($langs->trans("CantRemoveProject"), 'errors'); - } + $action = ''; } if ($action == 'add' && $user->rights->projet->creer) @@ -156,7 +145,7 @@ if (empty($reshook)) if ($ret < 0) $error++; $result = $object->create($user); - if ($result > 0) + if (! $error && $result > 0) { // Add myself as project leader $result = $object->add_contact($user->id, 'PROJECTLEADER', 'internal'); diff --git a/htdocs/projet/class/project.class.php b/htdocs/projet/class/project.class.php index 1d5daf2110a..bc9e6bd37b5 100644 --- a/htdocs/projet/class/project.class.php +++ b/htdocs/projet/class/project.class.php @@ -49,8 +49,10 @@ class Project extends CommonObject var $title; var $date_start; var $date_end; + var $date_close; var $socid; var $user_author_id; //!< Id of project creator. Not defined if shared project. + var $user_close_id; var $public; //!< Tell if this is a public or private project var $note_private; var $note_public; @@ -212,6 +214,8 @@ class Project extends CommonObject $sql.= ", datec=" . ($this->date_c != '' ? "'".$this->db->idate($this->date_c)."'" : 'null'); $sql.= ", dateo=" . ($this->date_start != '' ? "'".$this->db->idate($this->date_start)."'" : 'null'); $sql.= ", datee=" . ($this->date_end != '' ? "'".$this->db->idate($this->date_end)."'" : 'null'); + $sql.= ", date_close=" . ($this->date_close != '' ? "'".$this->db->idate($this->date_close)."'" : 'null'); + $sql.= ", fk_user_close=" . ($this->fk_user_close > 0 ? $this->fk_user_close : "null"); $sql.= ", budget_amount = " . ($this->budget_amount > 0 ? $this->budget_amount : "null"); $sql.= " WHERE rowid = " . $this->id; @@ -299,7 +303,7 @@ class Project extends CommonObject if (empty($id) && empty($ref)) return -1; $sql = "SELECT rowid, ref, title, description, public, datec, budget_amount,"; - $sql.= " tms, dateo, datee, fk_soc, fk_user_creat, fk_statut, note_private, note_public,model_pdf"; + $sql.= " tms, dateo, datee, date_close, fk_soc, fk_user_creat, fk_user_close, fk_statut, note_private, note_public, model_pdf"; $sql.= " FROM " . MAIN_DB_PREFIX . "projet"; if (! empty($id)) { @@ -330,10 +334,12 @@ class Project extends CommonObject $this->datem = $this->db->jdate($obj->tms); // TODO deprecated $this->date_start = $this->db->jdate($obj->dateo); $this->date_end = $this->db->jdate($obj->datee); + $this->date_close = $this->db->jdate($obj->date_close); $this->note_private = $obj->note_private; $this->note_public = $obj->note_public; $this->socid = $obj->fk_soc; $this->user_author_id = $obj->fk_user_creat; + $this->user_close_id = $obj->fk_user_close; $this->public = $obj->public; $this->statut = $obj->fk_statut; $this->budget_amount = $obj->budget_amount; @@ -682,13 +688,15 @@ class Project extends CommonObject /** * Close a project * - * @param User $user User that validate + * @param User $user User that close project * @return int <0 if KO, >0 if OK */ function setClose($user) { global $langs, $conf; + $now = dol_now(); + $error=0; if ($this->statut != 2) @@ -696,7 +704,7 @@ class Project extends CommonObject $this->db->begin(); $sql = "UPDATE " . MAIN_DB_PREFIX . "projet"; - $sql.= " SET fk_statut = 2"; + $sql.= " SET fk_statut = 2, fk_user_close = ".$user->id.", date_close = '".$this->db->idate($now)."'"; $sql.= " WHERE rowid = " . $this->id; $sql.= " AND entity = " . $conf->entity; $sql.= " AND fk_statut = 1"; diff --git a/htdocs/projet/class/task.class.php b/htdocs/projet/class/task.class.php index a9ecdd7bbc6..c322e0be3cc 100644 --- a/htdocs/projet/class/task.class.php +++ b/htdocs/projet/class/task.class.php @@ -61,6 +61,7 @@ class Task extends CommonObject var $timespent_old_duration; var $timespent_date; var $timespent_datehour; // More accurate start date (same than timespent_date but includes hours, minutes and seconds) + var $timespent_withhour; // 1 = we entered also start hours for timesheet line var $timespent_fk_user; var $timespent_note; @@ -505,9 +506,18 @@ class Task extends CommonObject global $langs; $result=''; - $label=$langs->trans("ShowTask").': '.$this->ref.($this->label?' - '.$this->label:''); + $label = '' . $langs->trans("ShowTask") . ''; + if (! empty($this->ref)) + $label .= '
' . $langs->trans('Ref') . ': ' . $this->ref; + if (! empty($this->title)) + $label .= '
' . $langs->trans('LabelTask') . ': ' . $this->label; + if ($this->date_start || $this->date_end) + { + $label .= "
".get_date_range($this->date_start,$this->date_end,'',$langs,0); + } + $linkclose = '" title="'.dol_escape_htmltag($label, 1).'" class="classfortooltip">'; - $lien = ''; + $lien = 'db->query($sql); if ($resql) @@ -759,6 +769,8 @@ class Task extends CommonObject { global $conf,$langs; + dol_syslog(get_class($this)."::addTimeSpent", LOG_DEBUG); + $ret = 0; // Check parameters @@ -778,6 +790,7 @@ class Task extends CommonObject $sql.= "fk_task"; $sql.= ", task_date"; $sql.= ", task_datehour"; + $sql.= ", task_date_withhour"; $sql.= ", task_duration"; $sql.= ", fk_user"; $sql.= ", note"; @@ -785,13 +798,14 @@ class Task extends CommonObject $sql.= $this->id; $sql.= ", '".$this->db->idate($this->timespent_date)."'"; $sql.= ", '".$this->db->idate($this->timespent_datehour)."'"; + $sql.= ", ".(empty($this->timespent_withhour)?0:1); $sql.= ", ".$this->timespent_duration; $sql.= ", ".$this->timespent_fk_user; $sql.= ", ".(isset($this->timespent_note)?"'".$this->db->escape($this->timespent_note)."'":"null"); $sql.= ")"; - dol_syslog(get_class($this)."::addTimeSpent", LOG_DEBUG); - if ($this->db->query($sql) ) + $resql=$this->db->query($sql); + if ($resql) { $tasktime_id = $this->db->last_insert_id(MAIN_DB_PREFIX."projet_task_time"); $ret = $tasktime_id; @@ -800,21 +814,21 @@ class Task extends CommonObject { // Call trigger $result=$this->call_trigger('TASK_TIMESPENT_CREATE',$user); - if ($result < 0) { $this->db->rollback(); $ret=-1; } + if ($result < 0) { $ret=-1; } // End call triggers } } else { $this->error=$this->db->lasterror(); - $this->db->rollback(); $ret = -1; } if ($ret >= 0) { + // Recalculate amount of time spent for task and update denormalized field $sql = "UPDATE ".MAIN_DB_PREFIX."projet_task"; - $sql.= " SET duration_effective = duration_effective + '".price2num($this->timespent_duration)."'"; + $sql.= " SET duration_effective = (SELECT SUM(task_duration) FROM ".MAIN_DB_PREFIX."projet_task_time as ptt where ptt.fk_task = ".$this->id.")"; if (isset($this->progress)) $sql.= ", progress = " . $this->progress; // Do not overwrite value if not provided $sql.= " WHERE rowid = ".$this->id; @@ -822,7 +836,6 @@ class Task extends CommonObject if (! $this->db->query($sql) ) { $this->error=$this->db->lasterror(); - $this->db->rollback(); $ret = -2; } @@ -834,12 +847,18 @@ class Task extends CommonObject if (! $this->db->query($sql) ) { $this->error=$this->db->lasterror(); - $this->db->rollback(); $ret = -2; } } - if ($ret >=0) $this->db->commit(); + if ($ret >=0) + { + $this->db->commit(); + } + else + { + $this->db->rollback(); + } return $ret; } @@ -898,6 +917,8 @@ class Task extends CommonObject $sql.= " t.rowid,"; $sql.= " t.fk_task,"; $sql.= " t.task_date,"; + $sql.= " t.task_datehour,"; + $sql.= " t.task_date_withhour,"; $sql.= " t.task_duration,"; $sql.= " t.fk_user,"; $sql.= " t.note"; @@ -914,7 +935,9 @@ class Task extends CommonObject $this->timespent_id = $obj->rowid; $this->id = $obj->fk_task; - $this->timespent_date = $obj->task_date; + $this->timespent_date = $this->db->jdate($obj->task_date); + $this->timespent_datehour = $this->db->jdate($obj->task_datehour); + $this->timespent_withhour = $obj->task_date_withhour; $this->timespent_duration = $obj->task_duration; $this->timespent_fk_user = $obj->fk_user; $this->timespent_note = $obj->note; @@ -953,6 +976,7 @@ class Task extends CommonObject $sql = "UPDATE ".MAIN_DB_PREFIX."projet_task_time SET"; $sql.= " task_date = '".$this->db->idate($this->timespent_date)."',"; $sql.= " task_datehour = '".$this->db->idate($this->timespent_datehour)."',"; + $sql.= " task_date_withhour = ".(empty($this->timespent_withhour)?0:1); $sql.= " task_duration = ".$this->timespent_duration.","; $sql.= " fk_user = ".$this->timespent_fk_user.","; $sql.= " note = ".(isset($this->timespent_note)?"'".$this->db->escape($this->timespent_note)."'":"null"); @@ -987,7 +1011,7 @@ class Task extends CommonObject $newDuration = $this->timespent_duration - $this->timespent_old_duration; $sql = "UPDATE ".MAIN_DB_PREFIX."projet_task"; - $sql.= " SET duration_effective = duration_effective + '".$newDuration."'"; + $sql.= " SET duration_effective = (SELECT SUM(task_duration) FROM ".MAIN_DB_PREFIX."projet_task_time as ptt where ptt.fk_task = ".$this->id.")"; $sql.= " WHERE rowid = ".$this->id; dol_syslog(get_class($this)."::updateTimeSpent", LOG_DEBUG); diff --git a/htdocs/projet/contact.php b/htdocs/projet/contact.php index bc8f5b3098c..594ed1feffe 100644 --- a/htdocs/projet/contact.php +++ b/htdocs/projet/contact.php @@ -41,12 +41,8 @@ $mine = GETPOST('mode')=='mine' ? 1 : 0; //if (! $user->rights->projet->all->lire) $mine=1; // Special for projects $object = new Project($db); -if ($id > 0 || ! empty($ref)) -{ - $object->fetch($id,$ref); - $object->fetch_thirdparty(); - $id=$object->id; -} + +include DOL_DOCUMENT_ROOT.'/core/actions_fetchobject.inc.php'; // Must be include, not includ_once // Security check $socid=0; diff --git a/htdocs/projet/document.php b/htdocs/projet/document.php index cb9742e40cc..bb381ae8b38 100644 --- a/htdocs/projet/document.php +++ b/htdocs/projet/document.php @@ -46,11 +46,11 @@ if ($user->societe_id > 0) $socid=$user->societe_id; $result=restrictedArea($user,'projet',$id,''); $object = new Project($db); -if ($id > 0 || ! empty($ref)) -{ - $object->fetch($id,$ref); - $object->fetch_thirdparty(); - $upload_dir = $conf->projet->dir_output . "/" . dol_sanitizeFileName($object->ref); + +include DOL_DOCUMENT_ROOT.'/core/actions_fetchobject.inc.php'; // Must be include, not includ_once + +if ($id > 0 || ! empty($ref)) { + $upload_dir = $conf->projet->dir_output . "/" . dol_sanitizeFileName($object->ref); } // Get parameters diff --git a/htdocs/projet/element.php b/htdocs/projet/element.php index 540ceff1bfa..85e8406d708 100644 --- a/htdocs/projet/element.php +++ b/htdocs/projet/element.php @@ -80,21 +80,9 @@ $mine = $_REQUEST['mode']=='mine' ? 1 : 0; $projectid=$id; // For backward compatibility -$project = new Project($db); -if ($id > 0 || ! empty($ref)) -{ - $ret=$project->fetch($id,$ref); - if ($ret > 0) - { - $projectid=$project->id; - $project->fetch_thirdparty(); - } - else - { - setEventMessages($project->error, $project->errors, 'errors'); - $action=''; - } -} +$object = new Project($db); + +include DOL_DOCUMENT_ROOT.'/core/actions_fetchobject.inc.php'; // Must be include, not includ_once // Security check $socid=0; @@ -116,10 +104,10 @@ $formfile = new FormFile($db); $userstatic=new User($db); // To verify role of users -$userAccess = $project->restrictedProjectArea($user); +$userAccess = $object->restrictedProjectArea($user); -$head=project_prepare_head($project); -dol_fiche_head($head, 'element', $langs->trans("Project"),0,($project->public?'projectpub':'project')); +$head=project_prepare_head($object); +dol_fiche_head($head, 'element', $langs->trans("Project"),0,($object->public?'projectpub':'project')); print '
'.$langs->trans("Project").''.$langs->trans("RefTask").''.$langs->trans("LabelTask").''.$langs->trans("PlannedWorkload").''.$langs->trans("ProgressDeclared").''.$langs->trans("TimeSpent").''.$langs->trans("TimeSpent").''.$langs->trans("TimeSpentByYou").''.$langs->trans("TimeSpentByUser").'
'.$langs->trans("Total").''.$langs->trans("Total").'
 
 
 
'.$langs->trans("LabelTask").''.$langs->trans("PlannedWorkload").''.$langs->trans("ProgressDeclared").''.$langs->trans("TimeSpent").''.$langs->trans("NewTimeSpent").''.$langs->trans("TimeSpentByYou").''.$langs->trans("TimeSpentByUser").''.$langs->trans("DateAndHour").''.$langs->trans("Duration").'
'; @@ -130,36 +118,36 @@ print ''; -print ''; +print ''; print ''; // Visibility print ''; // Statut -print ''; +print ''; // Date start print ''; // Date end print ''; print '
'.$langs->trans("Ref").''; // Define a complementary filter for search of next/prev ref. if (! $user->rights->projet->all->lire) { - $projectsListId = $project->getProjectsAuthorizedForUser($user,$mine,0); - $project->next_prev_filter=" rowid in (".(count($projectsListId)?join(',',array_keys($projectsListId)):'0').")"; + $projectsListId = $object->getProjectsAuthorizedForUser($user,$mine,0); + $object->next_prev_filter=" rowid in (".(count($projectsListId)?join(',',array_keys($projectsListId)):'0').")"; } -print $form->showrefnav($project, 'ref', $linkback, 1, 'ref', 'ref'); +print $form->showrefnav($object, 'ref', $linkback, 1, 'ref', 'ref'); print '
'.$langs->trans("Label").''.$project->title.'
'.$langs->trans("Label").''.$object->title.'
'.$langs->trans("ThirdParty").''; -if (! empty($project->thirdparty->id)) print $project->thirdparty->getNomUrl(1); +if (! empty($object->thirdparty->id)) print $object->thirdparty->getNomUrl(1); else print ' '; print '
'.$langs->trans("Visibility").''; -if ($project->public) print $langs->trans('SharedProject'); +if ($object->public) print $langs->trans('SharedProject'); else print $langs->trans('PrivateProject'); print '
'.$langs->trans("Status").''.$project->getLibStatut(4).'
'.$langs->trans("Status").''.$object->getLibStatut(4).'
'.$langs->trans("DateStart").''; -print dol_print_date($project->date_start,'day'); +print dol_print_date($object->date_start,'day'); print '
'.$langs->trans("DateEnd").''; -print dol_print_date($project->date_end,'day'); +print dol_print_date($object->date_end,'day'); print '
'; @@ -263,18 +251,18 @@ if ($action=="addelement") { $tablename = GETPOST("tablename"); $elementselectid = GETPOST("elementselect"); - $result=$project->update_element($tablename, $elementselectid); + $result=$object->update_element($tablename, $elementselectid); if ($result<0) { - setEventMessage($project->error,'errors'); + setEventMessage($object->error,'errors'); } }elseif ($action == "unlink") { $tablename = GETPOST("tablename"); $elementselectid = GETPOST("elementselect"); - $result = $project->remove_element($tablename, $elementselectid); + $result = $object->remove_element($tablename, $elementselectid); if ($result < 0) { - setEventMessage($project->error, 'errors'); + setEventMessage($object->error, 'errors'); } } @@ -317,7 +305,7 @@ foreach ($listofreferent as $key => $value) print_titre($langs->trans($title)); - $selectList=$formproject->select_element($tablename,$project->thirdparty->id); + $selectList=$formproject->select_element($tablename,$object->thirdparty->id); if (! $selectList || ($selectList<0)) { setEventMessages($formproject->error,$formproject->errors,'errors'); @@ -352,7 +340,7 @@ foreach ($listofreferent as $key => $value) else print ''; print ''.$langs->trans("Status").''; print ''; - $elementarray = $project->get_element_list($key, $tablename, $datefieldname, $dates, $datee); + $elementarray = $object->get_element_list($key, $tablename, $datefieldname, $dates, $datee); if (is_array($elementarray) && count($elementarray)>0) { $var=true; @@ -544,32 +532,32 @@ foreach ($listofreferent as $key => $value) */ print '
'; - if ($project->statut > 0) + if ($object->statut > 0) { - if ($project->thirdparty->prospect || $project->thirdparty->client) + if ($object->thirdparty->prospect || $object->thirdparty->client) { if ($key == 'propal' && ! empty($conf->propal->enabled) && $user->rights->propale->creer) { - print ''.$langs->trans("AddProp").''; + print ''.$langs->trans("AddProp").''; } if ($key == 'order' && ! empty($conf->commande->enabled) && $user->rights->commande->creer) { - print ''.$langs->trans("AddCustomerOrder").''; + print ''.$langs->trans("AddCustomerOrder").''; } if ($key == 'invoice' && ! empty($conf->facture->enabled) && $user->rights->facture->creer) { - print ''.$langs->trans("AddCustomerInvoice").''; + print ''.$langs->trans("AddCustomerInvoice").''; } } - if ($project->thirdparty->fournisseur) + if ($object->thirdparty->fournisseur) { if ($key == 'order_supplier' && ! empty($conf->fournisseur->enabled) && $user->rights->fournisseur->commande->creer) { - print ''.$langs->trans("AddSupplierInvoice").''; + print ''.$langs->trans("AddSupplierInvoice").''; } if ($key == 'invoice_supplier' && ! empty($conf->fournisseur->enabled) && $user->rights->fournisseur->facture->creer) { - print ''.$langs->trans("AddSupplierOrder").''; + print ''.$langs->trans("AddSupplierOrder").''; } } } @@ -607,7 +595,7 @@ foreach ($listofreferent as $key => $value) { $element = new $classname($db); - $elementarray = $project->get_element_list($key, $tablename); + $elementarray = $object->get_element_list($key, $tablename); if (count($elementarray)>0 && is_array($elementarray)) { $var=true; diff --git a/htdocs/projet/ganttview.php b/htdocs/projet/ganttview.php index 81acd18e301..181aeca032a 100644 --- a/htdocs/projet/ganttview.php +++ b/htdocs/projet/ganttview.php @@ -38,12 +38,8 @@ $mine = ($mode == 'mine' ? 1 : 0); //if (! $user->rights->projet->all->lire) $mine=1; // Special for projects $object = new Project($db); -if ($id > 0 || ! empty($ref)) -{ - $object->fetch($id,$ref); - $object->fetch_thirdparty(); - $id=$object->id; -} + +include DOL_DOCUMENT_ROOT.'/core/actions_fetchobject.inc.php'; // Must be include, not includ_once // Security check $socid=0; diff --git a/htdocs/projet/index.php b/htdocs/projet/index.php index 65351b70638..a7f0f957f06 100644 --- a/htdocs/projet/index.php +++ b/htdocs/projet/index.php @@ -175,7 +175,7 @@ if (empty($conf->global->PROJECT_HIDE_TASKS)) if ($socid) $sql.= " AND (p.fk_soc IS NULL OR p.fk_soc = 0 OR p.fk_soc = ".$socid.")"; $sql.= " AND p.fk_statut=1"; $sql.= " GROUP BY p.ref, p.title, p.rowid, t.label, t.rowid, t.planned_workload, t.duration_effective, t.progress, t.dateo, t.datee"; - $sql.= " ORDER BY t.rowid, t.dateo, t.datee"; + $sql.= " ORDER BY t.dateo desc, t.rowid desc, t.datee"; $sql.= $db->plimit($max+1); // We want more to know if we have more than limit $var=true; diff --git a/htdocs/projet/note.php b/htdocs/projet/note.php index b581ca01be9..6e7b0e28595 100644 --- a/htdocs/projet/note.php +++ b/htdocs/projet/note.php @@ -36,12 +36,8 @@ $mine = $_REQUEST['mode']=='mine' ? 1 : 0; //if (! $user->rights->projet->all->lire) $mine=1; // Special for projects $object = new Project($db); -if ($id > 0 || ! empty($ref)) -{ - $object->fetch($id,$ref); - $object->fetch_thirdparty(); - $id=$object->id; -} + +include DOL_DOCUMENT_ROOT.'/core/actions_fetchobject.inc.php'; // Must be include, not includ_once // Security check $socid=0; diff --git a/htdocs/projet/tasks.php b/htdocs/projet/tasks.php index 1b69fd5757e..96618fc83d4 100644 --- a/htdocs/projet/tasks.php +++ b/htdocs/projet/tasks.php @@ -47,12 +47,11 @@ $object = new Project($db); $taskstatic = new Task($db); $extrafields_project = new ExtraFields($db); $extrafields_task = new ExtraFields($db); + +include DOL_DOCUMENT_ROOT.'/core/actions_fetchobject.inc.php'; // Must be include, not includ_once + if ($id > 0 || ! empty($ref)) { - $object->fetch($id,$ref); - $id=$object->id; - $ref=$object->ref; - // fetch optionals attributes and labels $extralabels_projet=$extrafields_project->fetch_name_optionals_label($object->table_element); $extralabels_task=$extrafields_task->fetch_name_optionals_label($taskstatic->table_element); diff --git a/htdocs/projet/tasks/time.php b/htdocs/projet/tasks/time.php index 9951902ec5b..20ef1714164 100644 --- a/htdocs/projet/tasks/time.php +++ b/htdocs/projet/tasks/time.php @@ -87,7 +87,15 @@ if ($action == 'addtimespent' && $user->rights->projet->creer) $object->progress = GETPOST('progress', 'int'); $object->timespent_duration = $_POST["timespent_durationhour"]*60*60; // We store duration in seconds $object->timespent_duration+= $_POST["timespent_durationmin"]*60; // We store duration in seconds - $object->timespent_date = dol_mktime(12,0,0,$_POST["timemonth"],$_POST["timeday"],$_POST["timeyear"]); + if (GETPOST("timehour") != '' && GETPOST("timehour") >= 0) // If hour was entered + { + $object->timespent_date = dol_mktime(GETPOST("timehour"),GETPOST("timemin"),0,GETPOST("timemonth"),GETPOST("timeday"),GETPOST("timeyear")); + $object->timespent_withhour = 1; + } + else + { + $object->timespent_date = dol_mktime(12,0,0,GETPOST("timemonth"),GETPOST("timeday"),GETPOST("timeyear")); + } $object->timespent_fk_user = $_POST["userid"]; $result=$object->addTimeSpent($user); if ($result >= 0) @@ -126,7 +134,15 @@ if ($action == 'updateline' && ! $_POST["cancel"] && $user->rights->projet->cree $object->timespent_old_duration = $_POST["old_duration"]; $object->timespent_duration = $_POST["new_durationhour"]*60*60; // We store duration in seconds $object->timespent_duration+= $_POST["new_durationmin"]*60; // We store duration in seconds - $object->timespent_date = dol_mktime(12,0,0,$_POST["timelinemonth"],$_POST["timelineday"],$_POST["timelineyear"]); + if (GETPOST("timelinehour") != '' && GETPOST("timelinehour") >= 0) // If hour was entered + { + $object->timespent_date = dol_mktime(GETPOST("timelinehour"),GETPOST("timelinemin"),0,GETPOST("timelinemonth"),GETPOST("timelineday"),GETPOST("timelineyear")); + $object->timespent_withhour = 1; + } + else + { + $object->timespent_date = dol_mktime(12,0,0,GETPOST("timelinemonth"),GETPOST("timelineday"),GETPOST("timelineyear")); + } $object->timespent_fk_user = $_POST["userid_line"]; $result=$object->updateTimeSpent($user); @@ -341,7 +357,7 @@ if ($id > 0 || ! empty($ref)) /* - * Add time spent + * Form to add time spent */ if ($user->rights->projet->creer) { @@ -367,8 +383,9 @@ if ($id > 0 || ! empty($ref)) // Date print ''; - $newdate=dol_mktime(12,0,0,$_POST["timemonth"],$_POST["timeday"],$_POST["timeyear"]); - print $form->select_date($newdate,'time','','','',"timespent_date"); + //$newdate=dol_mktime(12,0,0,$_POST["timemonth"],$_POST["timeday"],$_POST["timeyear"]); + $newdate=''; + print $form->select_date($newdate,'time',1,1,2,"timespent_date"); print ''; // Contributor @@ -410,13 +427,13 @@ if ($id > 0 || ! empty($ref)) /* * List of time spent */ - $sql = "SELECT t.rowid, t.task_date, t.task_duration, t.fk_user, t.note"; + $sql = "SELECT t.rowid, t.task_date, t.task_datehour, t.task_date_withhour, t.task_duration, t.fk_user, t.note"; $sql.= ", u.lastname, u.firstname"; $sql .= " FROM ".MAIN_DB_PREFIX."projet_task_time as t"; $sql .= " , ".MAIN_DB_PREFIX."user as u"; $sql .= " WHERE t.fk_task =".$object->id; $sql .= " AND t.fk_user = u.rowid"; - $sql .= " ORDER BY t.task_date DESC"; + $sql .= " ORDER BY t.task_date DESC, t.task_datehour DESC, t.rowid DESC"; $var=true; $resql = $db->query($sql); @@ -459,15 +476,18 @@ if ($id > 0 || ! empty($ref)) $var=!$var; print ""; + $date1=$db->jdate($task_time->task_date); + $date2=$db->jdate($task_time->task_datehour); + // Date - print ''; + print ''; if ($_GET['action'] == 'editline' && $_GET['lineid'] == $task_time->rowid) { - print $form->select_date($db->jdate($task_time->task_date),'timeline','','','',"timespent_date"); + print $form->select_date($db->jdate($date2?$date2:$date1),'timeline',1,1,2,"timespent_date"); } else { - print dol_print_date($db->jdate($task_time->task_date),'day'); + print dol_print_date($date2?$date2:$date1,($task_time->task_date_withhour?'dayhour':'day')); } print ''; @@ -480,6 +500,7 @@ if ($id > 0 || ! empty($ref)) $contactsoftask[]=$task_time->fk_user; } if (count($contactsoftask)>0) { + print img_object('','user','class="hideonsmartphone"'); print $form->select_dolusers($task_time->fk_user,'userid_line',0,'',0,'',$contactsoftask); }else { print img_error($langs->trans('FirstAddRessourceToAllocateTime')).$langs->trans('FirstAddRessourceToAllocateTime'); diff --git a/htdocs/societe/class/societe.class.php b/htdocs/societe/class/societe.class.php index 77673b82ed3..ea08019853e 100644 --- a/htdocs/societe/class/societe.class.php +++ b/htdocs/societe/class/societe.class.php @@ -1,6 +1,6 @@ - * Copyright (C) 2004-2014 Laurent Destailleur + * Copyright (C) 2004-2015 Laurent Destailleur * Copyright (C) 2004 Eric Seigne * Copyright (C) 2003 Brian Fraval * Copyright (C) 2006 Andre Cianfarani @@ -42,7 +42,7 @@ class Societe extends CommonObject public $element='societe'; public $table_element = 'societe'; public $fk_element='fk_soc'; - protected $childtables=array("propal","commande","facture","contrat","facture_fourn","commande_fournisseur"); // To test if we can delete object + protected $childtables=array("askpricesupplier","propal","commande","facture","contrat","facture_fourn","commande_fournisseur","projet"); // To test if we can delete object /** * 0=No test on entity, 1=Test with field entity, 2=Test with link by societe @@ -352,6 +352,11 @@ class Societe extends CommonObject var $array_options; + // Incoterms + var $fk_incoterms; + var $location_incoterms; + var $libelle_incoterms; //Used into tooltip + /** * To contains a clone of this when we need to save old properties of object */ @@ -424,7 +429,7 @@ class Societe extends CommonObject if ($result >= 0) { - $sql = "INSERT INTO ".MAIN_DB_PREFIX."societe (nom, entity, datec, fk_user_creat, canvas, status, ref_int, ref_ext, fk_stcomm, import_key)"; + $sql = "INSERT INTO ".MAIN_DB_PREFIX."societe (nom, entity, datec, fk_user_creat, canvas, status, ref_int, ref_ext, fk_stcomm, fk_incoterms, location_incoterms ,import_key)"; $sql.= " VALUES ('".$this->db->escape($this->name)."', ".$conf->entity.", '".$this->db->idate($now)."'"; $sql.= ", ".(! empty($user->id) ? "'".$user->id."'":"null"); $sql.= ", ".(! empty($this->canvas) ? "'".$this->canvas."'":"null"); @@ -432,6 +437,8 @@ class Societe extends CommonObject $sql.= ", ".(! empty($this->ref_int) ? "'".$this->ref_int."'":"null"); $sql.= ", ".(! empty($this->ref_ext) ? "'".$this->ref_ext."'":"null"); $sql.= ", 0"; + $sql.= ", ".(int) $this->fk_incoterms; + $sql.= ", '".$this->db->escape($this->location_incoterms)."'"; $sql.= ", ".(! empty($this->import_key) ? "'".$this->import_key."'":"null").")"; dol_syslog(get_class($this)."::create", LOG_DEBUG); @@ -731,6 +738,10 @@ class Societe extends CommonObject $this->webservices_url = $this->webservices_url?clean_url($this->webservices_url,0):''; $this->webservices_key = trim($this->webservices_key); + //Incoterms + $this->fk_incoterms = (int) $this->fk_incoterms; + $this->location_incoterms = trim($this->location_incoterms); + $this->db->begin(); // Check name is required and codes are ok or unique. @@ -814,6 +825,10 @@ class Societe extends CommonObject $sql .= ",webservices_url = ".(! empty($this->webservices_url)?"'".$this->db->escape($this->webservices_url)."'":"null"); $sql .= ",webservices_key = ".(! empty($this->webservices_key)?"'".$this->db->escape($this->webservices_key)."'":"null"); + //Incoterms + $sql.= ", fk_incoterms = ".$this->fk_incoterms; + $sql.= ", location_incoterms = ".(! empty($this->location_incoterms)?"'".$this->db->escape($this->location_incoterms)."'":"null"); + if ($customer) { $sql .= ", code_client = ".(! empty($this->code_client)?"'".$this->db->escape($this->code_client)."'":"null"); @@ -976,13 +991,14 @@ class Societe extends CommonObject $sql .= ', s.code_client, s.code_fournisseur, s.code_compta, s.code_compta_fournisseur, s.parent, s.barcode'; $sql .= ', s.fk_departement, s.fk_pays as country_id, s.fk_stcomm, s.remise_client, s.mode_reglement, s.cond_reglement, s.tva_assuj'; $sql .= ', s.mode_reglement_supplier, s.cond_reglement_supplier, s.localtax1_assuj, s.localtax1_value, s.localtax2_assuj, s.localtax2_value, s.fk_prospectlevel, s.default_lang, s.logo'; - $sql .= ', s.outstanding_limit, s.import_key, s.canvas'; + $sql .= ', s.outstanding_limit, s.import_key, s.canvas, s.fk_incoterms, s.location_incoterms'; $sql .= ', fj.libelle as forme_juridique'; $sql .= ', e.libelle as effectif'; $sql .= ', c.code as country_code, c.label as country'; $sql .= ', d.code_departement as state_code, d.nom as state'; $sql .= ', st.libelle as stcomm'; $sql .= ', te.code as typent_code'; + $sql .= ', i.libelle as libelle_incoterms'; $sql .= ' FROM '.MAIN_DB_PREFIX.'societe as s'; $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_effectif as e ON s.fk_effectif = e.id'; $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_country as c ON s.fk_pays = c.rowid'; @@ -990,6 +1006,7 @@ class Societe extends CommonObject $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_forme_juridique as fj ON s.fk_forme_juridique = fj.code'; $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_departements as d ON s.fk_departement = d.rowid'; $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_typent as te ON s.fk_typent = te.id'; + $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_incoterms as i ON s.fk_incoterms = i.rowid'; if ($rowid) $sql .= ' WHERE s.rowid = '.$rowid; if ($ref) $sql .= " WHERE s.nom = '".$this->db->escape($ref)."' AND s.entity IN (".getEntity($this->element, 1).")"; if ($ref_ext) $sql .= " WHERE s.ref_ext = '".$this->db->escape($ref_ext)."' AND s.entity IN (".getEntity($this->element, 1).")"; @@ -1118,6 +1135,11 @@ class Societe extends CommonObject $this->import_key = $obj->import_key; + //Incoterms + $this->fk_incoterms = $obj->fk_incoterms; + $this->location_incoterms = $obj->location_incoterms; + $this->libelle_incoterms = $obj->libelle_incoterms; + $result = 1; // Retreive all extrafield for thirdparty @@ -2068,6 +2090,7 @@ class Societe extends CommonObject return $bac->getRibLabel(true); } + /** * Return Array of RIB * diff --git a/htdocs/societe/soc.php b/htdocs/societe/soc.php index 72dfc8931b8..0f17851b89e 100644 --- a/htdocs/societe/soc.php +++ b/htdocs/societe/soc.php @@ -45,6 +45,7 @@ $langs->load("commercial"); $langs->load("bills"); $langs->load("banks"); $langs->load("users"); +if (!empty($conf->incoterm->enabled)) $langs->load("incoterm"); if (! empty($conf->notification->enabled)) $langs->load("mails"); $mesg=''; $error=0; $errors=array(); @@ -191,6 +192,12 @@ if (empty($reshook)) $object->webservices_url = GETPOST('webservices_url', 'custom', 0, FILTER_SANITIZE_URL); $object->webservices_key = GETPOST('webservices_key', 'san_alpha'); + // Incoterms + if (!empty($conf->incoterm->enabled)) + { + $object->fk_incoterms = GETPOST('incoterm_id', 'int'); + $object->location_incoterms = GETPOST('location_incoterms', 'alpha'); + } // Fill array 'array_options' with data from add form $ret = $extrafields->setOptionalsFromPost($extralabels,$object); if ($ret < 0) $error++; @@ -518,6 +525,12 @@ if (empty($reshook)) $result = $object->set_parent(GETPOST('editparentcompany','int')); } + // Set incoterm + if ($action == 'set_incoterms' && !empty($conf->incoterm->enabled)) + { + $object->fetch($socid); + $result = $object->setIncoterms(GETPOST('incoterm_id', 'int'), GETPOST('location_incoterms', 'alpha')); + } // Actions to send emails $id=$socid; @@ -1078,7 +1091,17 @@ else $form->select_users((! empty($object->commercial_id)?$object->commercial_id:$user->id),'commercial_id',1); // Add current user by default print ''; } - + + // Incoterms + if (!empty($conf->incoterm->enabled)) + { + print ''; + print ''; + print ''; + print $form->select_incoterms((!empty($object->fk_incoterms) ? $object->fk_incoterms : ''), (!empty($object->location_incoterms)?$object->location_incoterms:'')); + print ''; + } + // Other attributes $parameters=array('colspan' => ' colspan="3"', 'colspanvalue' => '3'); $reshook=$hookmanager->executeHooks('formObjectOptions',$parameters,$object,$action); // Note that $action and $object may have been modified by hook @@ -1201,6 +1224,13 @@ else $object->webservices_url = GETPOST('webservices_url', 'custom', 0, FILTER_SANITIZE_URL); $object->webservices_key = GETPOST('webservices_key', 'san_alpha'); + //Incoterms + if (!empty($conf->incoterm->enabled)) + { + $object->fk_incoterms = GETPOST('incoterm_id', 'int'); + $object->location_incoterms = GETPOST('lcoation_incoterms', 'alpha'); + } + //Local Taxes $object->localtax1_assuj = GETPOST('localtax1assuj_value'); $object->localtax2_assuj = GETPOST('localtax2assuj_value'); @@ -1588,6 +1618,16 @@ else print ''; } + // Incoterms + if (!empty($conf->incoterm->enabled)) + { + print ''; + print ''; + print ''; + print $form->select_incoterms((!empty($object->fk_incoterms) ? $object->fk_incoterms : ''), (!empty($object->location_incoterms)?$object->location_incoterms:'')); + print ''; + } + // Logo print ''; print ''; @@ -1974,6 +2014,29 @@ else print ''; } + // Incoterms + if (!empty($conf->incoterm->enabled)) + { + print ''; + print '
'; + print $langs->trans('IncotermLabel'); + print ''; + if ($user->rights->societe->creer) print ''.img_edit().''; + else print ' '; + print '
'; + print ''; + print ''; + if ($action != 'editincoterm') + { + print $form->textwithpicto($object->display_incoterms(), $object->libelle_incoterms, 1); + } + else + { + print $form->select_incoterms((!empty($object->fk_incoterms) ? $object->fk_incoterms : ''), (!empty($object->location_incoterms)?$object->location_incoterms:''), $_SERVER['PHP_SELF'].'?socid='.$object->id); + } + print ''; + } + // Other attributes $parameters=array('socid'=>$socid, 'colspan' => ' colspan="3"', 'colspanvalue' => '3'); $reshook=$hookmanager->executeHooks('formObjectOptions',$parameters,$object,$action); // Note that $action and $object may have been modified by hook diff --git a/htdocs/theme/amarok/style.css.php b/htdocs/theme/amarok/style.css.php index bd41d0735a5..c7f3d27dcfb 100644 --- a/htdocs/theme/amarok/style.css.php +++ b/htdocs/theme/amarok/style.css.php @@ -1125,6 +1125,24 @@ td.formdocbutton {padding-top:6px;} ); color:white; } +.button:disabled { + opacity: 0.4; + filter: alpha(opacity=40); /* For IE8 and earlier */ + box-shadow: none; + -webkit-box-shadow: none; + -moz-box-shadow: none; + cursor: auto; +} +.buttonRefused { + pointer-events: none; + cursor: default; + opacity: 0.4; + filter: alpha(opacity=40); /* For IE8 and earlier */ + box-shadow: none; + -webkit-box-shadow: none; + -moz-box-shadow: none; +} + /* ============================================================================== */ /* Tables */ diff --git a/htdocs/theme/auguria/style.css.php b/htdocs/theme/auguria/style.css.php index 35e0cdd36c9..7278521e092 100644 --- a/htdocs/theme/auguria/style.css.php +++ b/htdocs/theme/auguria/style.css.php @@ -184,6 +184,23 @@ legend { margin-bottom: 8px; } padding: 0px 2px 0px 2px; margin: 0px 0px 0px 0px; } +.button:disabled { + opacity: 0.4; + filter: alpha(opacity=40); /* For IE8 and earlier */ + box-shadow: none; + -webkit-box-shadow: none; + -moz-box-shadow: none; + cursor: auto; +} +.buttonRefused { + pointer-events: none; + cursor: default; + opacity: 0.4; + filter: alpha(opacity=40); /* For IE8 and earlier */ + box-shadow: none; + -webkit-box-shadow: none; + -moz-box-shadow: none; +} form { padding: 0em 0em 0em 0em; margin: 0em 0em 0em 0em; diff --git a/htdocs/theme/bureau2crea/style.css.php b/htdocs/theme/bureau2crea/style.css.php index b720bd4a802..31071f0b10c 100644 --- a/htdocs/theme/bureau2crea/style.css.php +++ b/htdocs/theme/bureau2crea/style.css.php @@ -209,6 +209,23 @@ legend { margin-bottom: 8px; } padding: 0px 2px 0px 2px; margin: 0px 0px 0px 0px; } +.button:disabled { + opacity: 0.4; + filter: alpha(opacity=40); /* For IE8 and earlier */ + box-shadow: none; + -webkit-box-shadow: none; + -moz-box-shadow: none; + cursor: auto; +} +.buttonRefused { + pointer-events: none; + cursor: default; + opacity: 0.4; + filter: alpha(opacity=40); /* For IE8 and earlier */ + box-shadow: none; + -webkit-box-shadow: none; + -moz-box-shadow: none; +} form { padding: 0em 0em 0em 0em; margin: 0em 0em 0em 0em; diff --git a/htdocs/theme/cameleo/style.css.php b/htdocs/theme/cameleo/style.css.php index a49ad6daaec..d09cb844b88 100644 --- a/htdocs/theme/cameleo/style.css.php +++ b/htdocs/theme/cameleo/style.css.php @@ -185,6 +185,23 @@ legend { margin-bottom: 8px; } padding: 0px 2px 0px 2px; margin: 0px 0px 0px 0px; } +.button:disabled { + opacity: 0.4; + filter: alpha(opacity=40); /* For IE8 and earlier */ + box-shadow: none; + -webkit-box-shadow: none; + -moz-box-shadow: none; + cursor: auto; +} +.buttonRefused { + pointer-events: none; + cursor: default; + opacity: 0.4; + filter: alpha(opacity=40); /* For IE8 and earlier */ + box-shadow: none; + -webkit-box-shadow: none; + -moz-box-shadow: none; +} form { padding: 0em 0em 0em 0em; margin: 0em 0em 0em 0em; diff --git a/htdocs/theme/eldy/img/object_askpricesupplier.png b/htdocs/theme/eldy/img/object_askpricesupplier.png new file mode 100644 index 00000000000..2dc60e66b3e Binary files /dev/null and b/htdocs/theme/eldy/img/object_askpricesupplier.png differ diff --git a/htdocs/theme/eldy/style.css.php b/htdocs/theme/eldy/style.css.php index ccf54a6f9b5..206b1df019e 100644 --- a/htdocs/theme/eldy/style.css.php +++ b/htdocs/theme/eldy/style.css.php @@ -361,6 +361,15 @@ fieldset { border: 1px solid #AAAAAA !important; box-shadow: 2px 2px 3px #DDD; } -moz-box-shadow: none; cursor: auto; } +.buttonRefused { + pointer-events: none; + cursor: default; + opacity: 0.4; + filter: alpha(opacity=40); /* For IE8 and earlier */ + box-shadow: none; + -webkit-box-shadow: none; + -moz-box-shadow: none; +} form { padding:0px; margin:0px; diff --git a/htdocs/user/card.php b/htdocs/user/card.php index f709b02f043..cc880878671 100644 --- a/htdocs/user/card.php +++ b/htdocs/user/card.php @@ -8,7 +8,7 @@ * Copyright (C) 2011 Herve Prot * Copyright (C) 2012 Juanjo Menent * Copyright (C) 2013 Florian Henry - * Copyright (C) 2013-2014 Alexandre Spangaro + * Copyright (C) 2013-2015 Alexandre Spangaro * * 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 @@ -987,6 +987,15 @@ if (($action == 'create') || ($action == 'adduserldap')) print ''; print ''; print "\n"; + + // Accountancy code + if ($conf->salaries->enabled) + { + print ''.$langs->trans("AccountancyCode").''; + print ''; + print ''; + print ''; + } // User color if (! empty($conf->agenda->enabled)) @@ -1130,7 +1139,7 @@ else */ if ($action != 'edit') { - $rowspan=17; + $rowspan=19; print ''; @@ -1326,13 +1335,12 @@ else print "\n"; // Accountancy code - if (! empty($conf->global->USER_ENABLE_ACCOUNTANCY_CODE)) // For the moment field is not used so must not appeared. + if ($conf->salaries->enabled) { - $rowspan++; - print ''; - print ''; + print ''; + print ''; } - + // Color user if (! empty($conf->agenda->enabled)) { @@ -1661,7 +1669,7 @@ else */ if ($action == 'edit' && ($canedituser || $caneditfield || $caneditpassword || ($user->id == $object->id))) { - $rowspan=15; + $rowspan=16; if (isset($conf->file->main_authentication) && preg_match('/openid/',$conf->file->main_authentication) && ! empty($conf->global->MAIN_OPENIDURL_PERUSER)) $rowspan++; if (! empty($conf->societe->enabled)) $rowspan++; if (! empty($conf->adherent->enabled)) $rowspan++; @@ -2028,23 +2036,23 @@ else print "\n"; // Accountancy code - if (! empty($conf->global->USER_ENABLE_ACCOUNTANCY_CODE)) // For the moment field is not used so must not appeared. - { - print ""; - print ''; - print ''; - print ""; - } + if ($conf->salaries->enabled) + { + print ""; + print ''; + print ''; + print ""; + } // User color if (! empty($conf->agenda->enabled)) diff --git a/htdocs/webservices/server_contact.php b/htdocs/webservices/server_contact.php index ec652e80074..066c9f38b6c 100644 --- a/htdocs/webservices/server_contact.php +++ b/htdocs/webservices/server_contact.php @@ -114,8 +114,7 @@ $contact_fields = array( 'user_id' => array('name'=>'user_id','type'=>'xsd:string'), 'user_login' => array('name'=>'user_login','type'=>'xsd:string'), 'civility_id' => array('name'=>'civility_id','type'=>'xsd:string'), - 'poste' => array('name'=>'poste','type'=>'xsd:string'), - 'statut' => array('name'=>'statut','type'=>'xsd:string') + 'poste' => array('name'=>'poste','type'=>'xsd:string') //... ); //Retreive all extrafield for contact @@ -286,7 +285,7 @@ function getContact($authentication,$id,$ref_ext) 'country_code' => $contact->country_code, 'country' => $contact->country, 'socid' => $contact->socid, - 'status' => $contact->status, + 'status' => $contact->statut, 'phone_pro' => $contact->phone_pro, 'fax' => $contact->fax, 'phone_perso' => $contact->phone_perso, @@ -304,8 +303,7 @@ function getContact($authentication,$id,$ref_ext) 'user_id' => $contact->user_id, 'user_login' => $contact->user_login, 'civility_id' => $contact->civility_id, - 'poste' => $contact->poste, - 'statut' => $contact->statut + 'poste' => $contact->poste ); //Retreive all extrafield for thirdsparty @@ -353,7 +351,7 @@ function getContact($authentication,$id,$ref_ext) * Create Contact * * @param array $authentication Array of authentication information - * @param Contact $contact $contact + * @param Contact $contact $contact * @return array Array result */ function createContact($authentication,$contact) @@ -398,7 +396,7 @@ function createContact($authentication,$contact) $newobject->country_code=$contact['country_code']; $newobject->country=$contact['country']; $newobject->socid=$contact['socid']; - $newobject->status=$contact['status']; + $newobject->statut=$contact['status']; $newobject->phone_pro=$contact['phone_pro']; $newobject->fax=$contact['fax']; $newobject->phone_perso=$contact['phone_perso']; @@ -416,7 +414,6 @@ function createContact($authentication,$contact) $newobject->user_id=$contact['user_id']; $newobject->user_login=$contact['user_login']; $newobject->poste=$contact['poste']; - $newobject->statut=$contact['statut']; //Retreive all extrafield for thirdsparty // fetch optionals attributes and labels @@ -493,7 +490,7 @@ function getContactsForThirdParty($authentication,$idthirdparty) { $linesinvoice=array(); - $sql = "SELECT c.rowid, c.fk_soc, c.civility as civility_id, c.lastname, c.firstname, c.statut,"; + $sql = "SELECT c.rowid, c.fk_soc, c.civility as civility_id, c.lastname, c.firstname, c.statut as status,"; $sql.= " c.address, c.zip, c.town,"; $sql.= " c.fk_pays as country_id,"; $sql.= " c.fk_departement,"; @@ -511,7 +508,6 @@ function getContactsForThirdParty($authentication,$idthirdparty) $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."societe as s ON c.fk_soc = s.rowid"; $sql.= " WHERE c.fk_soc=$idthirdparty"; - $resql=$db->query($sql); if ($resql) { @@ -525,58 +521,50 @@ function getContactsForThirdParty($authentication,$idthirdparty) $contact=new Contact($db); $contact->fetch($obj->rowid); - // Now define invoice $linescontact[]=array( - 'id' => $contact->id, - 'ref' => $contact->ref, - 'civility_id' => $contact->civility_id?$contact->civility_id:'', - 'lastname' => $contact->lastname?$contact->lastname:'', - 'firstname' => $contact->firstname?$contact->firstname:'', - 'address' => $contact->address?$contact->address:'', - 'zip' => $contact->zip?$contact->zip:'', - 'town' => $contact->town?$contact->town:'', + 'id' => $contact->id, + 'ref' => $contact->ref, + 'civility_id' => $contact->civility_id?$contact->civility_id:'', + 'lastname' => $contact->lastname?$contact->lastname:'', + 'firstname' => $contact->firstname?$contact->firstname:'', + 'address' => $contact->address?$contact->address:'', + 'zip' => $contact->zip?$contact->zip:'', + 'town' => $contact->town?$contact->town:'', - 'state_id' => $contact->state_id?$contact->state_id:'', - 'state_code' => $contact->state_code?$contact->state_code:'', - 'state' => $contact->state?$contact->state:'', - - 'country_id' => $contact->country_id?$contact->country_id:'', - 'country_code' => $contact->country_code?$contact->country_code:'', - 'country' => $contact->country?$contact->country:'', - - 'socid' => $contact->socid?$contact->socid:'', - 'socname' => $contact->socname?$contact->socname:'', - 'poste' => $contact->poste?$contact->poste:'', - - - - 'phone_pro' => $contact->phone_pro?$contact->phone_pro:'', - 'fax' => $contact->fax?$contact->fax:'', - 'phone_perso' => $contact->phone_perso?$contact->phone_perso:'', - 'phone_mobile' => $contact->phone_mobile?$contact->phone_mobile:'', - - 'email' => $contact->email?$contact->email:'', - 'jabberid' => $contact->jabberid?$contact->jabberid:'', - 'priv' => $contact->priv?$contact->priv:'', - 'mail' => $contact->mail?$contact->mail:'', - - 'birthday' => $contact->birthday?$contact->birthday:'', - 'default_lang' => $contact->default_lang?$contact->default_lang:'', - 'note' => $contact->note?$contact->note:'', - 'no_email' => $contact->no_email?$contact->no_email:'', - 'ref_facturation' => $contact->ref_facturation?$contact->ref_facturation:'', - 'ref_contrat' => $contact->ref_contrat?$contact->ref_contrat:'', - 'ref_commande' => $contact->ref_commande?$contact->ref_commande:'', - 'ref_propal' => $contact->ref_propal?$contact->ref_propal:'', - 'user_id' => $contact->user_id?$contact->user_id:'', - 'user_login' => $contact->user_login?$contact->user_login:'', - 'statut' => $contact->statut?$contact->statut:'' + 'state_id' => $contact->state_id?$contact->state_id:'', + 'state_code' => $contact->state_code?$contact->state_code:'', + 'state' => $contact->state?$contact->state:'', + 'country_id' => $contact->country_id?$contact->country_id:'', + 'country_code' => $contact->country_code?$contact->country_code:'', + 'country' => $contact->country?$contact->country:'', + 'socid' => $contact->socid?$contact->socid:'', + 'socname' => $contact->socname?$contact->socname:'', + 'poste' => $contact->poste?$contact->poste:'', + 'phone_pro' => $contact->phone_pro?$contact->phone_pro:'', + 'fax' => $contact->fax?$contact->fax:'', + 'phone_perso' => $contact->phone_perso?$contact->phone_perso:'', + 'phone_mobile' => $contact->phone_mobile?$contact->phone_mobile:'', + 'email' => $contact->email?$contact->email:'', + 'jabberid' => $contact->jabberid?$contact->jabberid:'', + 'priv' => $contact->priv?$contact->priv:'', + 'mail' => $contact->mail?$contact->mail:'', + 'birthday' => $contact->birthday?$contact->birthday:'', + 'default_lang' => $contact->default_lang?$contact->default_lang:'', + 'note' => $contact->note?$contact->note:'', + 'no_email' => $contact->no_email?$contact->no_email:'', + 'ref_facturation' => $contact->ref_facturation?$contact->ref_facturation:'', + 'ref_contrat' => $contact->ref_contrat?$contact->ref_contrat:'', + 'ref_commande' => $contact->ref_commande?$contact->ref_commande:'', + 'ref_propal' => $contact->ref_propal?$contact->ref_propal:'', + 'user_id' => $contact->user_id?$contact->user_id:'', + 'user_login' => $contact->user_login?$contact->user_login:'', + 'status' => $contact->statut?$contact->statut:'' ); $i++; diff --git a/test/phpunit/ProjectTest.php b/test/phpunit/ProjectTest.php index e27cd1e0223..c2f5d5b8161 100644 --- a/test/phpunit/ProjectTest.php +++ b/test/phpunit/ProjectTest.php @@ -189,7 +189,7 @@ class ProjectTest extends PHPUnit_Framework_TestCase } /** - * testProjectOther + * testProjectClose * * @param Project $localobject Project * @return int @@ -205,6 +205,10 @@ class ProjectTest extends PHPUnit_Framework_TestCase $langs=$this->savlangs; $db=$this->savdb; + $result=$localobject->setClose($user); + + print __METHOD__." id=".$localobject->id." result=".$result."\n"; + $this->assertLessThan($result, 0); return $localobject->id; } @@ -214,7 +218,7 @@ class ProjectTest extends PHPUnit_Framework_TestCase * @param int $id Id of project * @return void * - * @depends testProjectOther + * @depends testProjectClose * The depends says test is run only if previous is ok */ public function testProjectDelete($id)
'.$langs->trans("AccountancyCode").''.$object->accountancy_code.'
'.$langs->trans("AccountancyCode").''.$object->accountancy_code.'
'.$langs->trans("AccountancyCode").''; - if ($caneditfield) - { - print ''; - } - else - { - print ''; - print $object->accountancy_code; - } - print '
'.$langs->trans("AccountancyCode").''; + if ($caneditfield) + { + print ''; + } + else + { + print ''; + print $object->accountancy_code; + } + print '