diff --git a/ChangeLog b/ChangeLog index c0eb78120b0..a70c0f58da2 100644 --- a/ChangeLog +++ b/ChangeLog @@ -4,6 +4,7 @@ English Dolibarr ChangeLog ***** ChangeLog for 3.4 compared to 3.3.2 ***** For users: +- New: Can use ODS templates as document templates. - New: Add link to autofill/reset with quantity to ship when creating a delivery receipt. - New: Event into calendar use different colors for different users. @@ -11,44 +12,48 @@ For users: - New: Add a tab "consumption" on thirdparties to list products bought/sells. - New: Some performance enhancements. - New: Can attach files onto trip and expenses modules. -- New: Add option MAIN_PDF_TITLE_BACKGROUND_COLOR. +- New: Add hidden option MAIN_PDF_TITLE_BACKGROUND_COLOR. - New: Merge tab customer and prospect. - New: Add ES formated address country rule. -- New: Can define a hierarchical responsible on user. -- New: Add a hierarchical view for users. +- New: Can define a hierarchical responsible on user and add a tree view to + see hierarchy of users. - New: Can expand/collapse menus, categories and users list. -- New: extra parameters are supported into ODT templates. -- New: total per vat rate are available as tags for ODT templates. -- New: Add more types for extra parameters (lists, phone, emails, checkbox, prices). +- New: extra parameters are supported into ODT/ODS templates. +- New: total per vat rate are available as tags for ODT/ODS templates. - New: Some part of interface use more CSS3 (ie: agenda) -- New: [ task #707 ] Create option ProfIdx are mandatory to validate a invoice. +- New: [ task #707 ] Create option "ProfIdx is mandatory to validate a invoice". - New: Can define if we want to use VAT or not for subscriptions (foundation module). -- New: Can define a default choice for choice "More action when recording - a subscription" (foundation module). -- New: Add link to check professional id for india. +- New: Can define a default choice for "More action when recording a + subscription" (foundation module). +- New: Add link to check professional id for India. - New: [ task #731 ] Uniformize ref generation - New: [ task #748 ] Add a link "Dolibarr" into left menu -- New: Script email_unpaid_invoices_to_representative accepts now a parameter test - and a delay. -- New: Can define a different clicktodial setup per user. -- New: Add option INVOICE_CAN_NEVER_BE_REMOVED. -- New: Enhance agenda module to reach RFC2445 (add busy information). +- New: Script email_unpaid_invoices_to_representative accepts now a parameter "test" + and a "late delay". +- New: Can define different clicktodial setups for each user. +- New: Add hidden option INVOICE_CAN_NEVER_BE_REMOVED. +- New: Enhance agenda module to reach RFC2445 ("type" not enabled by default and add + "busy" information). - New: Add module Opensurvey. -- New: Default aprrover for holidays i sby default hierchical parent. +- New: Default approver for holidays is set by default to hierchical parent. - First change to prepare feature "click to print" (IPP) for PDF. -- New: [ task #350 ] Merge tab customer and prospect -- New: [ task #710 ] Add substitution into mailing send (and HTML is now valid) -- New: [ task #711 ] Add combobox for contact as done for product/thirdparty -- New: [ task #714 ] In Emailing module admin autogenerate security key of READRECIEPT -- New: [ task #743 ] GED : Add aministration option to disabled autotree to display -- New: [ task #767 ] Customer Address fallback when a contact doesn't have an address -- New: [ task #768 ] WYSIWYG for all mail -- New: [ task #773 ] Add Project document in GED(ECM) modules -- New: [ task #783 ] Add checkbox and radio into extrafield feature -- New: [ task #798 ] Add range limit date on product/services as it is done on order and invoice -- New: [ task #814 ] Add extrafield feature into Project/project tasks module -- New: [ task #770 ] Add ODT document generation for Projects module -- New: [ task #741 ] Add intervention box +- New: [ task #350 ] Merge tab customer and prospect. +- New: [ task #710 ] Add substitution into mailing send (and HTML is now valid). +- New: [ task #711 ] Add combobox for contact, as done for product/thirdparty. +- New: [ task #714 ] In Emailing module admin autogenerate security key of READRECEIPT. +- New: [ task #743 ] GED : Add aministration option to disable autotree display. +- New: [ task #767 ] Customer Address fallback when a contact doesn't have an address. +- New: [ task #768 ] WYSIWYG for all mails. +- New: [ task #773 ] Add Project document in GED(ECM) modules. +- New: [ task #783 ] Add more types for extra parameters (lists, phone, emails, checkbox, + prices, radio). +- New: [ task #798 ] Add range limit date on product/services as it is done on order + and invoice. +- New: [ task #814 ] Add extrafield feature for projects ands tasks. +- New: [ task #770 ] Add ODT document generation for Projects module. +- New: [ task #741 ] Add intervention box. +- New: [ task #826 ] Optionnal increase stock when deleting an invoice already validated. +- New: [ task #823 ] Shipping_validate email notification. For translators: - Update language files. @@ -58,8 +63,8 @@ For developers: - An external module can force its theme. - Add function dol_set_focus('#xxx'). - A mymodule can bring its own core/modules/mymodule/modules_mymodule.php file. -- Removed not used libraries. -- More web services. +- Removed some not used libraries. +- More web services. - Renamed some database fields, code variables and parameters from french to english. - First change to manage margins on contracts. - Add hook getFormMail. @@ -86,7 +91,7 @@ WARNING: If you used external modules, some of them may need to be upgraded due ***** ChangeLog for 3.3.2 compared to 3.3.1 ***** -- Fix: Ducth (nl_NL) translation +- Fix: Dutch (nl_NL) translation - Fix: [ bug #790 ] Spanish localtax RE not being correctly calculated - Generalize fix: file with a specific mask not found, again - Fix: translations and BILL_SUPPLIER_BUILDDOC trigger @@ -99,11 +104,12 @@ WARNING: If you used external modules, some of them may need to be upgraded due - Fix: [ bug #806 ] Margins module with orders2invoice does not respect cost price - Fix: Orderstoinvoice didn't act as expected when no order was checked - Fix: Bad link to all proposals into Third party card if customer is prospect +- Fix: [ bug #774 ] Bug on creating event with box "all day" crossed - Fix: [ bug #789 ] VAT not being calculated in POS - Fix: [ bug #794 ] Lost filter on zipcode in prospect list -- Fix: [ bug #774 ] Bug on creating event with box "all day" crossed - Fix: [ bug #810 ] Cannot update ODT template path - Fix: [ bug #824 ] MAIN_DB_PREFIX not use into dictionnary +- Fix: [ bug #828 ] Error when code_region is not a number in llx_c_regions (with postgres) ***** ChangeLog for 3.3.1 compared to 3.3 ***** diff --git a/dev/skeletons/modMyModule.class.php b/dev/skeletons/modMyModule.class.php index 2f203cbfeb2..5711b61c4ac 100644 --- a/dev/skeletons/modMyModule.class.php +++ b/dev/skeletons/modMyModule.class.php @@ -133,7 +133,11 @@ class modMyModule extends DolibarrModules $this->tabs = array(); // Dictionnaries - if (! isset($conf->mymodule->enabled)) $conf->mymodule->enabled=0; + if (! isset($conf->mymodule->enabled)) + { + $conf->mymodule=new stdClass(); + $conf->mymodule->enabled=0; + } $this->dictionnaries=array(); /* Example: if (! isset($conf->mymodule->enabled)) $conf->mymodule->enabled=0; // This is to avoid warnings diff --git a/htdocs/adherents/class/adherent.class.php b/htdocs/adherents/class/adherent.class.php index 87a9b14877e..13a6bdea810 100644 --- a/htdocs/adherents/class/adherent.class.php +++ b/htdocs/adherents/class/adherent.class.php @@ -1520,7 +1520,12 @@ class Adherent extends CommonObject $lien = ''; $lienfin=''; } - + if ($option == 'category') + { + $lien = ''; + $lienfin=''; + } + $picto='user'; $label=$langs->trans("ShowMember"); diff --git a/htdocs/admin/agenda.php b/htdocs/admin/agenda.php index 7eb659bde97..4e53a709d20 100644 --- a/htdocs/admin/agenda.php +++ b/htdocs/admin/agenda.php @@ -65,8 +65,8 @@ else /* -* Actions -*/ + * Actions + */ if ($action == "save" && empty($cancel)) { $i=0; @@ -125,7 +125,7 @@ if (preg_match('/del_(.*)/',$action,$reg)) /** - * Affichage du formulaire de saisie + * View */ llxHeader(); @@ -184,48 +184,7 @@ print ""; print "\n"; -print ''; - -/* - * Other options -*/ - -print_titre($langs->trans("OtherOptions")); - -$var=true; - -print ''."\n"; -print ''."\n"; -print ''."\n"; -print ''."\n"; -print ''."\n"; -print ''."\n"; - -// Manual or automatic -$var=!$var; -print ''."\n"; -print ''."\n"; -print ''."\n"; - -print ''."\n"; - -print '
'.$langs->trans("Parameters").' '.$langs->trans("Value").'
'.$langs->trans("AGENDA_USE_EVENT_TYPE").' '."\n"; -if ($conf->use_javascript_ajax) -{ - print ajax_constantonoff('AGENDA_USE_EVENT_TYPE'); -} -else -{ - if($conf->global->AGENDA_USE_EVENT_TYPE == 0) - { - print ''.img_picto($langs->trans("Disabled"),'off').''; - } - else if($conf->global->BUSINESS_VISIBLE_TO_ALL_BY_DEFAULT == 1) - { - print ''.img_picto($langs->trans("Enabled"),'on').''; - } -} -print '
'; +dol_fiche_end(); print "
"; diff --git a/htdocs/admin/agenda_other.php b/htdocs/admin/agenda_other.php new file mode 100644 index 00000000000..cffbed706ce --- /dev/null +++ b/htdocs/admin/agenda_other.php @@ -0,0 +1,135 @@ + + * Copyright (C) 2011 Regis Houssin + * Copyright (C) 2011-2012 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 . + */ + +/** + * \file htdocs/admin/agenda.php + * \ingroup agenda + * \brief Autocreate actions for agenda module setup page + */ + +require '../main.inc.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/admin.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/agenda.lib.php'; + +if (!$user->admin) + accessforbidden(); + +$langs->load("admin"); +$langs->load("other"); + +$action = GETPOST('action','alpha'); +$cancel = GETPOST('cancel','alpha'); + + +/* + * Actions + */ + +if (preg_match('/set_(.*)/',$action,$reg)) +{ + $code=$reg[1]; + $value=(GETPOST($code) ? GETPOST($code) : 1); + if (dolibarr_set_const($db, $code, $value, 'chaine', 0, '', $conf->entity) > 0) + { + Header("Location: ".$_SERVER["PHP_SELF"]); + exit; + } + else + { + dol_print_error($db); + } +} + +if (preg_match('/del_(.*)/',$action,$reg)) +{ + $code=$reg[1]; + if (dolibarr_del_const($db, $code, $conf->entity) > 0) + { + Header("Location: ".$_SERVER["PHP_SELF"]); + exit; + } + else + { + dol_print_error($db); + } +} + + +/** + * View + */ + +llxHeader(); + +$linkback=''.$langs->trans("BackToModuleList").''; +print_fiche_titre($langs->trans("AgendaSetup"),$linkback,'setup'); +print "
\n"; + + +$head=agenda_prepare_head(); + +dol_fiche_head($head, 'other', $langs->trans("Agenda")); + +print_titre($langs->trans("OtherOptions")); + +$var=true; + +print ''."\n"; +print ''."\n"; +print ''."\n"; +print ''."\n"; +print ''."\n"; +print ''."\n"; + +// Manual or automatic +$var=!$var; +print ''."\n"; +print ''."\n"; +print ''."\n"; + +print ''."\n"; + +print '
'.$langs->trans("Parameters").' '.$langs->trans("Value").'
'.$langs->trans("AGENDA_USE_EVENT_TYPE").' '."\n"; +if ($conf->use_javascript_ajax) +{ + print ajax_constantonoff('AGENDA_USE_EVENT_TYPE'); +} +else +{ + if($conf->global->AGENDA_USE_EVENT_TYPE == 0) + { + print ''.img_picto($langs->trans("Disabled"),'off').''; + } + else if($conf->global->BUSINESS_VISIBLE_TO_ALL_BY_DEFAULT == 1) + { + print ''.img_picto($langs->trans("Enabled"),'on').''; + } +} +print '
'; + +dol_fiche_end(); + +print "
"; + +dol_htmloutput_mesg($mesg); + +llxFooter(); + +$db->close(); +?> diff --git a/htdocs/admin/carrier.php b/htdocs/admin/carrier.php deleted file mode 100644 index edb995d3fe7..00000000000 --- a/htdocs/admin/carrier.php +++ /dev/null @@ -1,222 +0,0 @@ - - * - * 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/admin/carrier.php - * \ingroup expedition - * \brief Page to setup carriers. TODO Delete this page. We mut use dictionnary instead. - */ - -require '../main.inc.php'; -require_once DOL_DOCUMENT_ROOT.'/core/lib/admin.lib.php'; -require_once DOL_DOCUMENT_ROOT.'/expedition/class/expedition.class.php'; - -$langs->load("admin"); -$langs->load("sendings"); -$langs->load("deliveries"); -$langs->load('other'); - -if (! $user->admin) - accessforbidden(); - -$action=GETPOST('action','alpha'); -$carrier=GETPOST('carrier','int'); - -$object = new Expedition($db); - - -/* - * Actions - */ -//if ($action==setvalue AND $carrier) -if ($action=='setvalue') -{ - // need to add check on values - $object->update['code']=GETPOST('code','alpha'); - $object->update['libelle']=GETPOST('libelle','alpha'); - $object->update['description']=GETPOST('description','alpha'); - $object->update['tracking']=GETPOST('tracking','alpha'); - $object->update_delivery_method($carrier); - header("Location: carrier.php"); - exit; -} - -if ($action=='activate_carrier' && $carrier!='') -{ - $object->activ_delivery_method($carrier); -} - -if ($action=='disable_carrier' && $carrier!='') -{ - $object->disable_delivery_method($carrier); -} - -/* - * View - */ - -$form=new Form($db); - -llxHeader("",""); - -$linkback=''.$langs->trans("BackToModuleList").''; -print_fiche_titre($langs->trans("SendingsSetup"),$linkback,'setup'); -print '
'; - - -//if ($mesg) print $mesg.'
'; - - -$h = 0; - -$head[$h][0] = DOL_URL_ROOT."/admin/confexped.php"; -$head[$h][1] = $langs->trans("Setup"); -$h++; - -$head[$h][0] = DOL_URL_ROOT."/admin/carrier.php"; -$head[$h][1] = $langs->trans("Carriers"); -$hselected=$h; -$h++; - -if (! empty($conf->global->MAIN_SUBMODULE_EXPEDITION)) -{ - $head[$h][0] = DOL_URL_ROOT."/admin/expedition.php"; - $head[$h][1] = $langs->trans("Sending"); - $h++; -} - -if (! empty($conf->global->MAIN_SUBMODULE_LIVRAISON)) -{ - $head[$h][0] = DOL_URL_ROOT."/admin/livraison.php"; - $head[$h][1] = $langs->trans("Receivings"); - $h++; -} - -dol_fiche_head($head, $hselected, $langs->trans("ModuleSetup")); - -/* - * Carrier List - */ -if ($action=='edit_carrier' || $action=='setvalue') -{ - // Carrier Edit - if ($carrier!='') $object->list_delivery_methods($carrier); - print_titre($langs->trans("CarrierEdit")); - - print '
'; - print ''; - print ''; - - - print ''; - - $var=true; - print ''; - print ''; - print ''; - print "\n"; - - $var=!$var; - print ''; - - $var=!$var; - print ''; - - $var=!$var; - print ''; - - $var=!$var; - print ''; - - if ($carrier) - { - print ''; - } - else - { - print ''; - } - - print '
'.$langs->trans("CarrierParameter").''.$langs->trans("Value").'
'; - print $langs->trans("Code").''; - print ''; - print '   '.$langs->trans("Example").': CODE'; - print '
'; - print $langs->trans("Name").''; - print ''; - print '
'; - print $langs->trans("Description").''; - print ''; - print '
'; - print $langs->trans("Tracking").''; - print ''; - print '   '.$langs->trans("Example").': http://www.website.com/dir/{TRACKID}'; - print '


'; - print '
'; - -} -else -{ - // Display List - $object->list_delivery_methods(); - $var=true; - print_titre($langs->trans("CarrierList")); - - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print "\n"; - $numlistmeths=count($object->listmeths); - for ($i=0; $i<$numlistmeths; $i++) - { - $var=!$var; - print ""; - print ''; - print ''; - print ''; - print ''; - print ''; - print "\n"; - } - print ''; - - print '
'.$langs->trans("Code").''.$langs->trans("Name").''.$langs->trans("Description").''.$langs->trans("TrackingUrl").''.$langs->trans("Status").''.$langs->trans("Edit").'
'.$object->listmeths[$i]['code'].''.$object->listmeths[$i]['libelle'].''.$object->listmeths[$i]['description'].''.dol_trunc($object->listmeths[$i]['tracking'],92,'middle').''; - if($object->listmeths[$i]['active'] == 0) - { - print ''.img_picto($langs->trans("Disabled"),'switch_off').''; - } - else - { - print ''.img_picto($langs->trans("Enabled"),'switch_on').''; - } - print ''; - print ''.img_picto($langs->trans("Edit"),'edit').''; - print '

'.$langs->trans("Add").'

'; - - print ''; -} - -llxFooter(); - -$db->close(); -?> diff --git a/htdocs/admin/compta.php b/htdocs/admin/compta.php index a5213413d54..c30af26f1c0 100644 --- a/htdocs/admin/compta.php +++ b/htdocs/admin/compta.php @@ -107,7 +107,7 @@ print '
'; $h = 0; $head[$h][0] = DOL_URL_ROOT."/admin/compta.php"; -$head[$h][1] = $langs->trans("Compta"); +$head[$h][1] = $langs->trans("Accountancy"); $head[$h][2] = 'Compta'; $hselected=$h; $h++; diff --git a/htdocs/admin/confexped.php b/htdocs/admin/confexped.php index 6653badfb36..d9be768461f 100644 --- a/htdocs/admin/confexped.php +++ b/htdocs/admin/confexped.php @@ -84,10 +84,6 @@ $head[$h][1] = $langs->trans("Setup"); $hselected=$h; $h++; -$head[$h][0] = DOL_URL_ROOT."/admin/carrier.php"; -$head[$h][1] = $langs->trans("Carriers"); -$h++; - if (! empty($conf->global->MAIN_SUBMODULE_EXPEDITION)) { $head[$h][0] = DOL_URL_ROOT."/admin/expedition.php"; diff --git a/htdocs/admin/dict.php b/htdocs/admin/dict.php index cf93f472019..41178e36012 100644 --- a/htdocs/admin/dict.php +++ b/htdocs/admin/dict.php @@ -6,9 +6,9 @@ * Copyright (C) 2010-2011 Juanjo Menent * Copyright (C) 2011 Philippe Grand * Copyright (C) 2011 Remy Younes - * Copyright (C) 2012 Marcos García + * Copyright (C) 2012-2013 Marcos García * Copyright (C) 2012 Christophe Battarel - * Copyright (C) 2011-2012 Alexandre Spangaro + * Copyright (C) 2011-2012 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 @@ -147,7 +147,7 @@ $tabsql[14]= "SELECT e.rowid as rowid, e.code as code, e.libelle, e.price, e.org $tabsql[15]= "SELECT rowid as rowid, code, label as libelle, width, height, unit, active FROM ".MAIN_DB_PREFIX."c_paper_format"; $tabsql[16]= "SELECT code, label as libelle, active FROM ".MAIN_DB_PREFIX."c_prospectlevel"; $tabsql[17]= "SELECT id as rowid, code, libelle, active FROM ".MAIN_DB_PREFIX."c_type_fees"; -$tabsql[18]= "SELECT rowid as rowid, code, libelle, active FROM ".MAIN_DB_PREFIX."c_shipment_mode"; +$tabsql[18]= "SELECT rowid as rowid, code, libelle, tracking, active FROM ".MAIN_DB_PREFIX."c_shipment_mode"; $tabsql[19]= "SELECT id as rowid, code, libelle, active FROM ".MAIN_DB_PREFIX."c_effectif"; $tabsql[20]= "SELECT rowid as rowid, code, libelle, active FROM ".MAIN_DB_PREFIX."c_input_method"; $tabsql[21]= "SELECT c.rowid as rowid, code, label, active FROM ".MAIN_DB_PREFIX."c_availability AS c"; @@ -203,7 +203,7 @@ $tabfield[14]= "code,libelle,price,organization,country_id,country"; $tabfield[15]= "code,libelle,width,height,unit"; $tabfield[16]= "code,libelle"; $tabfield[17]= "code,libelle"; -$tabfield[18]= "code,libelle"; +$tabfield[18]= "code,libelle,tracking"; $tabfield[19]= "code,libelle"; $tabfield[20]= "code,libelle"; $tabfield[21]= "code,label"; @@ -231,7 +231,7 @@ $tabfieldvalue[14]= "code,libelle,price,organization,country"; $tabfieldvalue[15]= "code,libelle,width,height,unit"; $tabfieldvalue[16]= "code,libelle"; $tabfieldvalue[17]= "code,libelle"; -$tabfieldvalue[18]= "code,libelle"; +$tabfieldvalue[18]= "code,libelle,tracking"; $tabfieldvalue[19]= "code,libelle"; $tabfieldvalue[20]= "code,libelle"; $tabfieldvalue[21]= "code,label"; @@ -259,7 +259,7 @@ $tabfieldinsert[14]= "code,libelle,price,organization,fk_pays"; $tabfieldinsert[15]= "code,label,width,height,unit"; $tabfieldinsert[16]= "code,label"; $tabfieldinsert[17]= "code,libelle"; -$tabfieldinsert[18]= "code,libelle"; +$tabfieldinsert[18]= "code,libelle,tracking"; $tabfieldinsert[19]= "code,libelle"; $tabfieldinsert[20]= "code,libelle"; $tabfieldinsert[21]= "code,label"; @@ -391,7 +391,7 @@ if ($id == 11) // Define localtax_typeList (used for dictionnary "c_tva") $localtax_typeList = array(); -if (GETPOST("id") == 10) +if ($id == 10) { $localtax_typeList = array( "0" => $langs->trans("No"), @@ -441,22 +441,32 @@ if (GETPOST('actionadd') || GETPOST('actionmodify')) if ($fieldnamekey == 'position') $fieldnamekey = 'Position'; if ($fieldnamekey == 'unicode') $fieldnamekey = 'Unicode'; - $msg.=$langs->trans("ErrorFieldRequired",$langs->transnoentities($fieldnamekey)).'
'; + $msg.=$langs->transnoentities("ErrorFieldRequired", $langs->transnoentities($fieldnamekey)).'
'; } } // Other checks if ($tabname[$id] == MAIN_DB_PREFIX."c_actioncomm" && isset($_POST["type"]) && in_array($_POST["type"],array('system','systemauto'))) { $ok=0; - $msg.="Value 'system' and 'systemauto' for type is reserved. You can use 'user' as value to add your own record.
"; + $msg.= $langs->transnoentities('ErrorReservedTypeSystemSystemAuto').'
'; } - if (isset($_POST["code"]) && $_POST["code"]=='0') { - $ok=0; - $msg.="Code can't contains value 0
"; + if (isset($_POST["code"])) + { + if ($_POST["code"]=='0') + { + $ok=0; + $msg.= $langs->transnoentities('ErrorCodeCantContainZero').'
'; + } + if (!is_numeric($_POST['code'])) + { + $ok = 0; + $msg .= $langs->transnoentities('ErrorFieldFormat', $langs->transnoentities('Code')).'
'; + } } if (isset($_POST["country"]) && $_POST["country"]=='0') { $ok=0; - $msg.=$langs->trans("ErrorFieldRequired",$langs->trans("Country")).'
'; + $msg.=$langs->transnoentities("ErrorFieldRequired",$langs->transnoentities("Country")).'
'; } + // Clean some parameters if (isset($_POST["localtax1"]) && empty($_POST["localtax1"])) $_POST["localtax1"]='0'; // If empty, we force to 0 if (isset($_POST["localtax2"]) && empty($_POST["localtax2"])) $_POST["localtax2"]='0'; // If empty, we force to 0 @@ -518,7 +528,7 @@ if (GETPOST('actionadd') || GETPOST('actionmodify')) else { if ($db->errno() == 'DB_ERROR_RECORD_ALREADY_EXISTS') { - $msg=$langs->trans("ErrorRecordAlreadyExists").'
'; + $msg=$langs->transnoentities("ErrorRecordAlreadyExists").'
'; } else { dol_print_error($db); @@ -588,7 +598,7 @@ if ($action == 'confirm_delete' && $confirm == 'yes') // delete { if ($db->errno() == 'DB_ERROR_CHILD_EXISTS') { - $msg='
'.$langs->trans("ErrorRecordIsUsedByChild").'
'; + $msg='
'.$langs->transnoentities("ErrorRecordIsUsedByChild").'
'; } else { @@ -994,6 +1004,7 @@ if ($id) $valuetoshow=($obj->code && $key != "Civility".strtoupper($obj->code)?$key:$obj->$fieldlist[$field]); } else if ($fieldlist[$field]=='libelle' && $tabname[$id]==MAIN_DB_PREFIX.'c_type_contact') { + $langs->load('agenda'); $key=$langs->trans("TypeContact_".$obj->element."_".$obj->source."_".strtoupper($obj->code)); $valuetoshow=($obj->code && $key != "TypeContact_".$obj->element."_".$obj->source."_".strtoupper($obj->code)?$key:$obj->$fieldlist[$field]); } @@ -1084,15 +1095,23 @@ if ($id) } // Est-ce une entree du dictionnaire qui peut etre desactivee ? - $iserasable=1; // Oui par defaut - if (isset($obj->code) && ($obj->code == '0' || $obj->code == '' || preg_match('/unknown/i',$obj->code))) $iserasable=0; - if (isset($obj->code) && $obj->code == 'RECEP') $iserasable=0; - if (isset($obj->code) && $obj->code == 'EF0') $iserasable=0; + // True by default + $iserasable=1; + + if (isset($obj->code)) + { + if (($obj->code == '0' || $obj->code == '' || preg_match('/unknown/i',$obj->code))) $iserasable = 0; + else if ($obj->code == 'RECEP') $iserasable = 0; + else if ($obj->code == 'EF0') $iserasable = 0; + } + if (isset($obj->type) && in_array($obj->type, array('system', 'systemauto'))) $iserasable=0; + $url = $_SERVER["PHP_SELF"].'?'.($page?'page='.$page.'&':'').'sortfield='.$sortfield.'&sortorder='.$sortorder.'&rowid='.(! empty($obj->rowid)?$obj->rowid:(! empty($obj->code)?$obj->code:'')).'&code='.(! empty($obj->code)?$obj->code:'').'&id='.$id.'&'; + // Active print ''; - if ($iserasable) print ''.$actl[$obj->active].''; + if ($iserasable) print ''.$actl[$obj->active].''; else { if (isset($obj->type) && in_array($obj->type, array('system', 'systemauto')) && empty($obj->active)) print $langs->trans("Deprecated"); @@ -1101,11 +1120,11 @@ if ($id) print ""; // Modify link - if ($iserasable) print 'rowid)?$obj->rowid:(! empty($obj->code)?$obj->code:'')).'">'.img_edit().''; + if ($iserasable) print ''.img_edit().''; else print ' '; // Delete link - if ($iserasable) print ''.img_delete().''; + if ($iserasable) print ''.img_delete().''; else print ' '; print "\n"; @@ -1153,7 +1172,7 @@ else $var=!$var; $value=$tabname[$i]; - print ''; + print ''; if (! empty($tabcond[$i])) { print ''.$langs->trans($tablib[$i]).''; @@ -1299,6 +1318,7 @@ function fieldList($fieldlist,$obj='',$tabname='') print ''; $size=''; if ($fieldlist[$field]=='libelle') $size='size="32" '; + if ($fieldlist[$field]=='tracking') $size='size="92" '; if ($fieldlist[$field]=='accountancy_code') $size='size="15" '; if ($fieldlist[$field]=='accountancy_code_sell') $size='size="15" '; if ($fieldlist[$field]=='accountancy_code_buy') $size='size="15" '; diff --git a/htdocs/admin/expedition.php b/htdocs/admin/expedition.php index 34535b1d321..28e5b912de2 100644 --- a/htdocs/admin/expedition.php +++ b/htdocs/admin/expedition.php @@ -201,10 +201,6 @@ $head[$h][0] = DOL_URL_ROOT."/admin/confexped.php"; $head[$h][1] = $langs->trans("Setup"); $h++; -$head[$h][0] = DOL_URL_ROOT."/admin/carrier.php"; -$head[$h][1] = $langs->trans("Carriers"); -$h++; - $head[$h][0] = DOL_URL_ROOT."/admin/expedition.php"; $head[$h][1] = $langs->trans("Sending"); $hselected=$h; diff --git a/htdocs/admin/livraison.php b/htdocs/admin/livraison.php index 49cbeee9026..677e2b3773b 100644 --- a/htdocs/admin/livraison.php +++ b/htdocs/admin/livraison.php @@ -189,10 +189,6 @@ $head[$h][0] = DOL_URL_ROOT."/admin/confexped.php"; $head[$h][1] = $langs->trans("Setup"); $h++; -$head[$h][0] = DOL_URL_ROOT."/admin/carrier.php"; -$head[$h][1] = $langs->trans("Carriers"); -$h++; - if (! empty($conf->global->MAIN_SUBMODULE_EXPEDITION)) { $head[$h][0] = DOL_URL_ROOT."/admin/expedition.php"; diff --git a/htdocs/admin/menus/edit.php b/htdocs/admin/menus/edit.php index 569200f35e4..f7bd7ad95d7 100644 --- a/htdocs/admin/menus/edit.php +++ b/htdocs/admin/menus/edit.php @@ -29,6 +29,7 @@ require_once DOL_DOCUMENT_ROOT.'/core/class/menubase.class.php'; $langs->load("admin"); +$langs->load('other'); if (! $user->admin) accessforbidden(); diff --git a/htdocs/admin/modules.php b/htdocs/admin/modules.php index 4440d632b2e..acdf756eb86 100644 --- a/htdocs/admin/modules.php +++ b/htdocs/admin/modules.php @@ -194,7 +194,7 @@ asort($orders); $nbofactivatedmodules=count($conf->modules); $moreinfo=$langs->trans("TotalNumberOfActivatedModules",($nbofactivatedmodules-1)); - +if ($nbofactivatedmodules <= 1) $moreinfo .= ' '.img_warning($langs->trans("YouMustEnableOneModule")); print load_fiche_titre($langs->trans("ModulesSetup"),$moreinfo,'setup'); // Start to show page @@ -206,7 +206,7 @@ if ($mode==='functional') print $langs->trans("ModulesJobDesc")."
\n"; if ($mode==='marketplace') print $langs->trans("ModulesMarketPlaceDesc")."
\n"; if ($mode==='expdev') print $langs->trans("ModuleFamilyExperimental")."
\n"; -if ($nbofactivatedmodules <= 1) print ' '.img_warning($langs->trans("YouMustEnableOneModule")); + //print '
'."\n"; diff --git a/htdocs/admin/stock.php b/htdocs/admin/stock.php index bbdbf3276db..0390efcdda4 100644 --- a/htdocs/admin/stock.php +++ b/htdocs/admin/stock.php @@ -4,6 +4,7 @@ * Copyright (C) 2005-2009 Regis Houssin * Copyright (C) 2012 Juanjo Menent * 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 @@ -67,6 +68,7 @@ if ($action == 'STOCK_CALCULATE_ON_SUPPLIER_BILL' $res=dolibarr_set_const($db, "STOCK_CALCULATE_ON_SUPPLIER_BILL", '','chaine',0,'',$conf->entity); $res=dolibarr_set_const($db, "STOCK_CALCULATE_ON_SUPPLIER_VALIDATE_ORDER", '','chaine',0,'',$conf->entity); $res=dolibarr_set_const($db, "STOCK_CALCULATE_ON_SUPPLIER_DISPATCH_ORDER", '','chaine',0,'',$conf->entity); + $res=dolibarr_set_const($db, "STOCK_CALCULATE_ON_DELETE_INVOICE", '','chaine',0,'',$conf->entity); if ($action == 'STOCK_CALCULATE_ON_SUPPLIER_BILL') $res=dolibarr_set_const($db, "STOCK_CALCULATE_ON_SUPPLIER_BILL", GETPOST('STOCK_CALCULATE_ON_SUPPLIER_BILL','alpha'),'chaine',0,'',$conf->entity); if ($action == 'STOCK_CALCULATE_ON_SUPPLIER_VALIDATE_ORDER') $res=dolibarr_set_const($db, "STOCK_CALCULATE_ON_SUPPLIER_VALIDATE_ORDER", GETPOST('STOCK_CALCULATE_ON_SUPPLIER_VALIDATE_ORDER','alpha'),'chaine',0,'',$conf->entity); if ($action == 'STOCK_CALCULATE_ON_SUPPLIER_DISPATCH_ORDER') $res=dolibarr_set_const($db, "STOCK_CALCULATE_ON_SUPPLIER_DISPATCH_ORDER", GETPOST('STOCK_CALCULATE_ON_SUPPLIER_DISPATCH_ORDER','alpha'),'chaine',0,'',$conf->entity); @@ -239,6 +241,19 @@ if (! empty($conf->fournisseur->enabled)) print ''; print "\n\n\n"; } +if (! empty($conf->facture->enabled)) +{ + $var=!$var; + print ""; + print ''.$langs->trans("ReStockOnDeleteInvoice").''; + print ''; + print "
"; + print ''; + print ""; + print $form->selectyesno("STOCK_CALCULATE_ON_DELETE_INVOICE",$conf->global->STOCK_CALCULATE_ON_DELETE_INVOICE,1); + print ''; + print "
\n\n\n"; +} print ''; diff --git a/htdocs/categories/categorie.php b/htdocs/categories/categorie.php index ddc7079c786..ec2a2b49d63 100644 --- a/htdocs/categories/categorie.php +++ b/htdocs/categories/categorie.php @@ -99,7 +99,7 @@ $error=$hookmanager->error; $errors=array_merge($errors, (array) $hookmanager->e if (empty($reshook)) { - //Suppression d'un objet d'une categorie + // Remove element from category if ($removecat > 0) { if ($type==0 && ($user->rights->produit->creer || $user->rights->service->creer)) @@ -113,17 +113,20 @@ if (empty($reshook)) { $object = new Societe($db); $result = $object->fetch($objectid); + $elementtype = 'fournisseur'; } if ($type==2 && $user->rights->societe->creer) { $object = new Societe($db); $result = $object->fetch($objectid); + $elementtype = 'societe'; } if ($type == 3 && $user->rights->adherent->creer) { require_once DOL_DOCUMENT_ROOT.'/adherents/class/adherent.class.php'; $object = new Adherent($db); $result = $object->fetch($objectid); + $elementtype = 'member'; } $cat = new Categorie($db); $result=$cat->fetch($removecat); @@ -507,7 +510,7 @@ function formCategory($db,$object,$typeid,$socid=0) //print $c->getNomUrl(1); print img_object('','category').' '.$way.""; - // Lien supprimer + // Link to delete from category print ''; $permission=0; if ($typeid == 0) $permission=($user->rights->produit->creer || $user->rights->service->creer); diff --git a/htdocs/categories/class/categorie.class.php b/htdocs/categories/class/categorie.class.php index 96c111f2dc0..377c06fd8d8 100644 --- a/htdocs/categories/class/categorie.class.php +++ b/htdocs/categories/class/categorie.class.php @@ -420,6 +420,7 @@ class Categorie $sql .= " WHERE fk_categorie = ".$this->id; $sql .= " AND fk_".($type=='fournisseur'?'societe':$type)." = ".$obj->id; + dol_syslog(get_class($this).'::del_type sql='.$sql); if ($this->db->query($sql)) { return 1; diff --git a/htdocs/categories/viewcat.php b/htdocs/categories/viewcat.php index f174f5f4a60..57cffd387de 100644 --- a/htdocs/categories/viewcat.php +++ b/htdocs/categories/viewcat.php @@ -36,6 +36,7 @@ $ref=GETPOST('ref'); $type=GETPOST('type'); $action=GETPOST('action'); $confirm=GETPOST('confirm'); +$removeelem = GETPOST('removeelem','int'); if ($id == "") { @@ -61,6 +62,40 @@ $type=$object->type; * Actions */ +// Remove element from category +if ($id > 0 && $removeelem > 0) +{ + if ($type==0 && ($user->rights->produit->creer || $user->rights->service->creer)) + { + require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php'; + $tmpobject = new Product($db); + $result = $tmpobject->fetch($removeelem); + $elementtype = 'product'; + } + if ($type==1 && $user->rights->societe->creer) + { + $tmpobject = new Societe($db); + $result = $tmpobject->fetch($removeelem); + $elementtype = 'fournisseur'; + } + if ($type==2 && $user->rights->societe->creer) + { + $tmpobject = new Societe($db); + $result = $tmpobject->fetch($removeelem); + $elementtype = 'societe'; + } + if ($type == 3 && $user->rights->adherent->creer) + { + require_once DOL_DOCUMENT_ROOT.'/adherents/class/adherent.class.php'; + $tmpobject = new Adherent($db); + $result = $tmpobject->fetch($removeelem); + $elementtype = 'member'; + } + + $result=$object->del_type($tmpobject,$elementtype); + if ($result < 0) dol_print_error('',$object->error); +} + if ($user->rights->categorie->supprimer && $action == 'confirm_delete' && $confirm == 'yes') { if ($object->delete($user) >= 0) @@ -214,7 +249,7 @@ if ($object->type == 0) { print "
"; print "\n"; - print '\n"; + print '\n"; if (count($prods) > 0) { @@ -224,10 +259,24 @@ if ($object->type == 0) $var=!$var; print "\t\n"; print '\n"; + print $prod->getNomUrl(1,'category'); + print "\n"; print '\n"; + // Link to delete from category + print ''; print "\n"; } } @@ -249,8 +298,8 @@ if ($object->type == 1) else { print "
"; - print "
'.$langs->trans("ProductsAndServices")."
'.$langs->trans("ProductsAndServices")."
'; - if ($prod->type == 1) print img_object($langs->trans("ShowService"),"service"); - else print img_object($langs->trans("ShowProduct"),"product"); - print " ".$prod->ref."'.$prod->libelle."'; + $typeid=$object->type; + $permission=0; + if ($typeid == 0) $permission=($user->rights->produit->creer || $user->rights->service->creer); + if ($typeid == 1) $permission=$user->rights->societe->creer; + if ($typeid == 2) $permission=$user->rights->societe->creer; + if ($typeid == 3) $permission=$user->rights->adherent->creer; + if ($permission) + { + print ""; + print img_delete($langs->trans("DeleteFromCat")).' '; + print $langs->trans("DeleteFromCat").""; + } + print '
\n"; - print "\n"; + print '
".$langs->trans("Suppliers")."
'."\n"; + print '\n"; if (count($socs) > 0) { @@ -261,9 +310,24 @@ if ($object->type == 1) print "\t\n"; print '\n"; - + // Link to delete from category + print ''; + print "\n"; } } @@ -285,8 +349,8 @@ if($object->type == 2) else { print "
"; - print "
'.$langs->trans("Suppliers")."
'; - print $soc->getNomUrl(1); + print $soc->getNomUrl(1,'category_supplier'); print "'; + $typeid=$object->type; + $permission=0; + if ($typeid == 0) $permission=($user->rights->produit->creer || $user->rights->service->creer); + if ($typeid == 1) $permission=$user->rights->societe->creer; + if ($typeid == 2) $permission=$user->rights->societe->creer; + if ($typeid == 3) $permission=$user->rights->adherent->creer; + if ($permission) + { + print ""; + print img_delete($langs->trans("DeleteFromCat")).' '; + print $langs->trans("DeleteFromCat").""; + } + print '
\n"; - print "\n"; + print '
".$langs->trans("Customers")."
'."\n"; + print '\n"; if (count($socs) > 0) { @@ -298,9 +362,23 @@ if($object->type == 2) $var=!$var; print "\t\n"; print '\n"; - + // Link to delete from category + print ''; print "\n"; } } @@ -326,7 +404,7 @@ if ($object->type == 3) { print "
"; print "
'.$langs->trans("Customers")."
'; - print $soc->getNomUrl(1); + print $soc->getNomUrl(1,'category'); print "'; + $typeid=$object->type; + $permission=0; + if ($typeid == 0) $permission=($user->rights->produit->creer || $user->rights->service->creer); + if ($typeid == 1) $permission=$user->rights->societe->creer; + if ($typeid == 2) $permission=$user->rights->societe->creer; + if ($typeid == 3) $permission=$user->rights->adherent->creer; + if ($permission) + { + print ""; + print img_delete($langs->trans("DeleteFromCat")).' '; + print $langs->trans("DeleteFromCat").""; + } + print '
\n"; - print '\n"; + print '\n"; if (count($prods) > 0) { @@ -336,10 +414,25 @@ if ($object->type == 3) $var=!$var; print "\t\n"; print '\n"; print '\n"; print '\n"; + // Link to delete from category + print '\n"; } } diff --git a/htdocs/comm/action/class/cactioncomm.class.php b/htdocs/comm/action/class/cactioncomm.class.php index c686db153c4..e9fe439e75c 100644 --- a/htdocs/comm/action/class/cactioncomm.class.php +++ b/htdocs/comm/action/class/cactioncomm.class.php @@ -132,7 +132,7 @@ class CActionComm $qualified=1; // $obj->type can be system, systemauto, module, moduleauto, xxx, xxxauto - if ($qualified && $onlyautoornot && preg_match('/^system/',$obj->type) && ! preg_match('/^AC_OTH/',$obj->code)) $qualified=0; // We discard detailed system events. We keep only the 2 generic lines (AC_OTH and AC_OTHER) + if ($qualified && $onlyautoornot && preg_match('/^system/',$obj->type) && ! preg_match('/^AC_OTH/',$obj->code)) $qualified=0; // We discard detailed system events. We keep only the 2 generic lines (AC_OTH and AC_OTH_AUTO) if ($qualified && $obj->module) { diff --git a/htdocs/comm/action/fiche.php b/htdocs/comm/action/fiche.php index 37c5aaba693..4b4917715b5 100644 --- a/htdocs/comm/action/fiche.php +++ b/htdocs/comm/action/fiche.php @@ -1,6 +1,6 @@ - * Copyright (C) 2004-2012 Laurent Destailleur + * Copyright (C) 2004-2013 Laurent Destailleur * Copyright (C) 2005 Simon TOSSER * Copyright (C) 2005-2012 Regis Houssin * Copyright (C) 2010 Juanjo Menent @@ -592,7 +592,7 @@ if ($action == 'create') // Description print ''; @@ -663,7 +663,6 @@ if ($id > 0) */ $head=actions_prepare_head($act); - dol_fiche_head($head, 'card', $langs->trans("Action"),0,'action'); $now=dol_now(); $delay_warning=$conf->global->MAIN_DELAY_ACTIONS_TODO*24*60*60; @@ -711,6 +710,8 @@ if ($id > 0) print ''; if ($backtopage) print ''; + dol_fiche_head($head, 'card', $langs->trans("Action"),0,'action'); + print '
'.$langs->trans("Member")."
'.$langs->trans("Member")."
'; - print $member->getNomUrl(1); + $member->ref=$member->login; + print $member->getNomUrl(1,0,'category'); print "'.$member->lastname."'.$member->firstname."'; + $typeid=$object->type; + $permission=0; + if ($typeid == 0) $permission=($user->rights->produit->creer || $user->rights->service->creer); + if ($typeid == 1) $permission=$user->rights->societe->creer; + if ($typeid == 2) $permission=$user->rights->societe->creer; + if ($typeid == 3) $permission=$user->rights->adherent->creer; + if ($permission) + { + print ""; + print img_delete($langs->trans("DeleteFromCat")).' '; + print $langs->trans("DeleteFromCat").""; + } print "
'.$langs->trans("Description").''; require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php'; - $doleditor=new DolEditor('note',(GETPOST('note')?GETPOST('note'):$actioncomm->note),'',280,'dolibarr_notes','In',true,true,$conf->fckeditor->enabled,ROWS_7,90); + $doleditor=new DolEditor('note',(GETPOST('note')?GETPOST('note'):$actioncomm->note),'',240,'dolibarr_notes','In',true,true,$conf->fckeditor->enabled,ROWS_7,90); $doleditor->Create(); print '
'; // Ref @@ -836,7 +837,9 @@ if ($id > 0) print '
'; - print '

'; + dol_fiche_end(); + + print '
'; print '     '; print '
'; @@ -844,6 +847,8 @@ if ($id > 0) } else { + dol_fiche_head($head, 'card', $langs->trans("Action"),0,'action'); + // Affichage fiche action en mode visu print ''; @@ -1021,14 +1026,13 @@ if ($id > 0) } print '


'; } - } - print "\n"; + dol_fiche_end(); + } /* * Barre d'actions - * */ print '
'; diff --git a/htdocs/comm/action/index.php b/htdocs/comm/action/index.php index 49a84a28d22..813c2578374 100644 --- a/htdocs/comm/action/index.php +++ b/htdocs/comm/action/index.php @@ -1,7 +1,7 @@ * Copyright (C) 2003 Eric Seigne - * Copyright (C) 2004-2012 Laurent Destailleur + * Copyright (C) 2004-2013 Laurent Destailleur * Copyright (C) 2005-2012 Regis Houssin * Copyright (C) 2011 Juanjo Menent * @@ -72,11 +72,11 @@ $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"):0; -$actioncode=GETPOST("actioncode","alpha",3); $pid=GETPOST("projectid","int",3); $status=GETPOST("status"); $type=GETPOST("type"); $maxprint=(isset($_GET["maxprint"])?GETPOST("maxprint"):$conf->global->AGENDA_MAX_EVENTS_DAY_VIEW); +$actioncode=GETPOST("actioncode","alpha",3)?GETPOST("actioncode","alpha",3):(GETPOST("actioncode")=="0"?'':(empty($conf->global->AGENDA_USE_EVENT_TYPE)?'AC_OTH':'')); if (GETPOST('viewcal')) { $action='show_month'; $day=''; @@ -271,7 +271,7 @@ $param.='&year='.$year.'&month='.$month.($day?'&day='.$day:''); $head = calendars_prepare_head(''); dol_fiche_head($head, 'card', $langs->trans('Events'), 0, $picto); -print_actions_filter($form,$canedit,$status,$year,$month,$day,$showbirthday,$filtera,$filtert,$filterd,$pid,$socid,$listofextcals); +print_actions_filter($form,$canedit,$status,$year,$month,$day,$showbirthday,$filtera,$filtert,$filterd,$pid,$socid,$listofextcals,$actioncode); dol_fiche_end(); $link=''; diff --git a/htdocs/comm/action/listactions.php b/htdocs/comm/action/listactions.php index b603792b957..9e7a7a959bb 100644 --- a/htdocs/comm/action/listactions.php +++ b/htdocs/comm/action/listactions.php @@ -238,7 +238,7 @@ if ($resql) $i = 0; print ''; print ''; - print_liste_field_titre($langs->trans("Action"),$_SERVER["PHP_SELF"],"acode",$param,"","",$sortfield,$sortorder); + print_liste_field_titre($langs->trans("Action"),$_SERVER["PHP_SELF"],"a.label",$param,"","",$sortfield,$sortorder); //print_liste_field_titre($langs->trans("Title"),$_SERVER["PHP_SELF"],"a.label",$param,"","",$sortfield,$sortorder); print_liste_field_titre($langs->trans("DateStart"),$_SERVER["PHP_SELF"],"a.datep",$param,'','align="center"',$sortfield,$sortorder); print_liste_field_titre($langs->trans("DateEnd"),$_SERVER["PHP_SELF"],"a.datep2",$param,'','align="center"',$sortfield,$sortorder); diff --git a/htdocs/comm/action/rapport/index.php b/htdocs/comm/action/rapport/index.php index 33a30e9c6b6..fa100e532f3 100644 --- a/htdocs/comm/action/rapport/index.php +++ b/htdocs/comm/action/rapport/index.php @@ -132,7 +132,7 @@ if ($resql) if (file_exists($file)) { - print ''; + print ''; print ''; print ''; } diff --git a/htdocs/comm/propal.php b/htdocs/comm/propal.php index c178c37078b..2a7c92dce56 100644 --- a/htdocs/comm/propal.php +++ b/htdocs/comm/propal.php @@ -1534,7 +1534,7 @@ else require_once DOL_DOCUMENT_ROOT .'/core/class/notify.class.php'; $notify=new Notify($db); $text.='
'; - $text.=$notify->confirmMessage('NOTIFY_VAL_PROPAL',$object->socid); + $text.=$notify->confirmMessage('PROPAL_VALIDATE',$object->socid); } if (! $error) $formconfirm=$form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('ValidateProp'), $text, 'confirm_validate','',0,1); @@ -2171,7 +2171,7 @@ else //print '
'.img_pdf().''.img_pdf().''.dol_print_date(dol_filemtime($file),'dayhour').''.dol_print_size(dol_filesize($file)).'
'; - print '
'; + print ''; } diff --git a/htdocs/comm/propal/apercu.php b/htdocs/comm/propal/apercu.php index fa01f818b16..8972baaac88 100644 --- a/htdocs/comm/propal/apercu.php +++ b/htdocs/comm/propal/apercu.php @@ -142,7 +142,7 @@ if ($id > 0 || ! empty($ref)) print "".$langs->trans("Propal")." PDF"; - print ''.$object->ref.'.pdf'; + print ''.$object->ref.'.pdf'; print ''.dol_print_size(dol_filesize($file)).''; print ''.dol_print_date(dol_filemtime($file),'dayhour').''; diff --git a/htdocs/comm/propal/list.php b/htdocs/comm/propal/list.php index 4063802ffa4..1d4d5b82c24 100644 --- a/htdocs/comm/propal/list.php +++ b/htdocs/comm/propal/list.php @@ -3,7 +3,7 @@ * Copyright (C) 2004-2011 Laurent Destailleur * Copyright (C) 2004 Eric Seigne * Copyright (C) 2005 Marc Barilley / Ocebo - * Copyright (C) 2005-2012 Regis Houssin + * Copyright (C) 2005-2013 Regis Houssin * Copyright (C) 2006 Andre Cianfarani * Copyright (C) 2010-2011 Juanjo Menent * Copyright (C) 2010-2011 Philippe Grand @@ -165,7 +165,7 @@ if ($search_societe) } if ($search_montant_ht) { - $sql.= " AND p.total_ht='".$db->escape(trim($search_montant_ht))."'"; + $sql.= " AND p.total_ht='".$db->escape(price2num(trim($search_montant_ht)))."'"; } if ($sall) $sql.= " AND (s.nom LIKE '%".$db->escape($sall)."%' OR p.note LIKE '%".$db->escape($sall)."%' OR pd.description LIKE '%".$db->escape($sall)."%')"; if ($socid) $sql.= ' AND s.rowid = '.$socid; diff --git a/htdocs/commande/apercu.php b/htdocs/commande/apercu.php index 03957361ae2..f92a309a53c 100644 --- a/htdocs/commande/apercu.php +++ b/htdocs/commande/apercu.php @@ -128,7 +128,7 @@ if ($id > 0 || ! empty($ref)) print "".$langs->trans("Order")." PDF"; - print ''.$object->ref.'.pdf'; + print ''.$object->ref.'.pdf'; print ''.dol_print_size(dol_filesize($file)).''; print ''.dol_print_date(dol_filemtime($file),'dayhour').''; print ''; @@ -139,7 +139,7 @@ if ($id > 0 || ! empty($ref)) { print "Commande detaillee"; - print ''.$object->ref.'-detail.pdf'; + print ''.$object->ref.'-detail.pdf'; print ''.dol_print_size(dol_filesize($filedetail)).''; print ''.dol_print_date(dol_filemtime($filedetail),'dayhour').''; print ''; diff --git a/htdocs/commande/fiche.php b/htdocs/commande/fiche.php index 2a501f10f73..4801305a091 100644 --- a/htdocs/commande/fiche.php +++ b/htdocs/commande/fiche.php @@ -1,34 +1,34 @@ * Copyright (C) 2004-2013 Laurent Destailleur - * Copyright (C) 2005 Marc Barilley / Ocebo - * Copyright (C) 2005-2013 Regis Houssin - * Copyright (C) 2006 Andre Cianfarani - * Copyright (C) 2010-2013 Juanjo Menent - * Copyright (C) 2011 Philippe Grand - * Copyright (C) 2012 Christophe Battarel - * Copyright (C) 2012 Marcos García - * 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 . - */ +* Copyright (C) 2005 Marc Barilley / Ocebo +* Copyright (C) 2005-2013 Regis Houssin +* Copyright (C) 2006 Andre Cianfarani +* Copyright (C) 2010-2013 Juanjo Menent +* Copyright (C) 2011 Philippe Grand +* Copyright (C) 2012 Christophe Battarel +* Copyright (C) 2012 Marcos García +* 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/commande/fiche.php - * \ingroup commande - * \brief Page to show customer order - */ +* \ingroup commande +* \brief Page to show customer order +*/ require '../main.inc.php'; require_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php'; @@ -541,7 +541,7 @@ else if ($action == 'setnote_public' && $user->rights->commande->creer) else if ($action == 'setnote_private' && $user->rights->commande->creer) { - $result=$object->update_note_rivate(dol_html_entity_decode(GETPOST('note_private'), ENT_QUOTES)); + $result=$object->update_note(dol_html_entity_decode(GETPOST('note_private'), ENT_QUOTES), '_private'); if ($result < 0) dol_print_error($db,$object->error); } @@ -1121,7 +1121,7 @@ else if ($action == 'print_file' AND $user->rights->printipp->use) { require_once DOL_DOCUMENT_ROOT.'/core/class/dolprintipp.class.php'; $printer = new dolPrintIPP($db,$conf->global->PRINTIPP_HOST,$conf->global->PRINTIPP_PORT,$user->login,$conf->global->PRINTIPP_USER,$conf->global->PRINTIPP_PASSWORD); - $printer->print_file(GETPOST('file','alpha'),GETPOST('printer','alpha')); + $printer->print_file(GETPOST('file','alpha'),GETPOST('printer','alpha')); } else if ($action == 'update_extras') @@ -1784,7 +1784,7 @@ else require_once DOL_DOCUMENT_ROOT .'/core/class/notify.class.php'; $notify=new Notify($db); $text.='
'; - $text.=$notify->confirmMessage('NOTIFY_VAL_ORDER',$object->socid); + $text.=$notify->confirmMessage('ORDER_VALIDATE',$object->socid); } $formquestion=array(); if (! empty($conf->global->STOCK_CALCULATE_ON_VALIDATE_ORDER) && $object->hasProductsOrServices(1)) @@ -1935,15 +1935,15 @@ else print ''.$soc->getNomUrl(1).''; print ''; - if (! empty($conf->global->FACTURE_DEPOSITS_ARE_JUST_PAYMENTS)) - { - $filterabsolutediscount="fk_facture_source IS NULL"; // If we want deposit to be substracted to payments only and not to total of final invoice - $filtercreditnote="fk_facture_source IS NOT NULL"; // If we want deposit to be substracted to payments only and not to total of final invoice - } - else - { - $filterabsolutediscount="fk_facture_source IS NULL OR (fk_facture_source IS NOT NULL AND description='(DEPOSIT)')"; - $filtercreditnote="fk_facture_source IS NOT NULL AND description <> '(DEPOSIT)'"; + if (! empty($conf->global->FACTURE_DEPOSITS_ARE_JUST_PAYMENTS)) + { + $filterabsolutediscount="fk_facture_source IS NULL"; // If we want deposit to be substracted to payments only and not to total of final invoice + $filtercreditnote="fk_facture_source IS NOT NULL"; // If we want deposit to be substracted to payments only and not to total of final invoice + } + else + { + $filterabsolutediscount="fk_facture_source IS NULL OR (fk_facture_source IS NOT NULL AND description='(DEPOSIT)')"; + $filtercreditnote="fk_facture_source IS NOT NULL AND description <> '(DEPOSIT)'"; } // Relative and absolute discounts @@ -2135,49 +2135,24 @@ else $reshook=$hookmanager->executeHooks('formObjectOptions',$parameters,$object,$action); // Note that $action and $object may have been modified by hook if (empty($reshook) && ! empty($extrafields->attribute_label)) { - - if ($action == 'edit_extras') - { - print '
'; - print ''; - print ''; - print ''; - } - - // TODO : use showOptionals($extrafields) function - foreach($extrafields->attribute_label as $key=>$label) - { - $value=(isset($_POST["options_".$key])?$_POST["options_".$key]:$object->array_options["options_".$key]); - if ($extrafields->attribute_type[$key] == 'separate') - { - print $extrafields->showSeparator($key); - } - else - { - print 'attribute_required[$key])) print ' class="fieldrequired"'; - print '>'.$label.''; - - // Convert date into timestamp format - if (in_array($extrafields->attribute_type[$key],array('date','datetime'))) - { - $value = isset($_POST["options_".$key])?dol_mktime($_POST["options_".$key."hour"], $_POST["options_".$key."min"], 0, $_POST["options_".$key."month"], $_POST["options_".$key."day"], $_POST["options_".$key."year"]):$object->array_options['options_'.$key]; - } - - if ($action == 'edit_extras' && $user->rights->propal->creer) - { - print $extrafields->showInputField($key,$value); - } - else - { - print $extrafields->showOutputField($key,$value); - } - print ''."\n"; - } - } - if(count($extrafields->attribute_label) > 0) { + if ($action == 'edit_extras') + { + print ''; + print ''; + print ''; + print ''; + } + + + if ($action == 'edit_extras' && $user->rights->propal->creer) { + print $object->showOptionals($extrafields,'edit'); + } + else { + print $object->showOptionals($extrafields); + } + if ($action == 'edit_extras' && $user->rights->propal->creer) { print ''; @@ -2195,9 +2170,9 @@ else } } - $rowspan=4; - if ($mysoc->localtax1_assuj=="1") $rowspan++; - if ($mysoc->localtax2_assuj=="1") $rowspan++; + $rowspan=4; + if ($mysoc->localtax1_assuj=="1") $rowspan++; + if ($mysoc->localtax2_assuj=="1") $rowspan++; // Total HT print ''.$langs->trans('AmountHT').''; @@ -2307,7 +2282,7 @@ else /* * Boutons actions - */ + */ if ($action != 'presend') { if ($user->societe_id == 0 && $action <> 'editline') @@ -2436,7 +2411,7 @@ else print ''; } } - print '
'; + print '
'; if ($action != 'presend') @@ -2447,7 +2422,7 @@ else /* * Documents generes - */ + */ $comref = dol_sanitizeFileName($object->ref); $file = $conf->commande->dir_output . '/' . $comref . '/' . $comref . '.pdf'; $relativepath = $comref.'/'.$comref.'.pdf'; @@ -2461,7 +2436,7 @@ else /* * Linked object block - */ + */ $somethingshown=$object->showLinkedObjectBlock(); print '
'; @@ -2473,7 +2448,7 @@ else $somethingshown=$formactions->showactions($object,'order',$socid); //print ''; - print '
'; + print ''; } diff --git a/htdocs/compta/facture.php b/htdocs/compta/facture.php index 53e839e0241..6c190bac20b 100644 --- a/htdocs/compta/facture.php +++ b/htdocs/compta/facture.php @@ -1,34 +1,34 @@ * Copyright (C) 2004 Eric Seigne - * Copyright (C) 2004-2013 Laurent Destailleur - * Copyright (C) 2005 Marc Barilley / Ocebo - * Copyright (C) 2005-2012 Regis Houssin - * Copyright (C) 2006 Andre Cianfarani - * Copyright (C) 2010-2013 Juanjo Menent - * Copyright (C) 2012 Christophe Battarel - * Copyright (C) 2013 Jean-Francois FERRY - * 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 . - */ +* Copyright (C) 2004-2013 Laurent Destailleur +* Copyright (C) 2005 Marc Barilley / Ocebo +* Copyright (C) 2005-2012 Regis Houssin +* Copyright (C) 2006 Andre Cianfarani +* Copyright (C) 2010-2013 Juanjo Menent +* Copyright (C) 2012 Christophe Battarel +* Copyright (C) 2013 Jean-Francois FERRY +* 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/compta/facture.php - * \ingroup facture - * \brief Page to create/see an invoice - */ +* \ingroup facture +* \brief Page to create/see an invoice +*/ require '../main.inc.php'; require_once DOL_DOCUMENT_ROOT . '/compta/facture/class/facture.class.php'; @@ -99,7 +99,7 @@ $hookmanager->initHooks(array('invoicecard')); /* * Actions - */ +*/ $parameters=array('socid'=>$socid); $reshook=$hookmanager->executeHooks('doActions',$parameters,$object,$action); // Note that $action and $object may have been modified by some hooks @@ -108,47 +108,47 @@ $reshook=$hookmanager->executeHooks('doActions',$parameters,$object,$action); // Action clone object if ($action == 'confirm_clone' && $confirm == 'yes' && $user->rights->facture->creer) { - if (1==0 && empty($_REQUEST["clone_content"]) && empty($_REQUEST["clone_receivers"])) - { - $mesgs[]='
'.$langs->trans("NoCloneOptionsSpecified").'
'; - } - else - { - if ($object->fetch($id) > 0) - { - $result=$object->createFromClone($socid); - if ($result > 0) - { - header("Location: ".$_SERVER['PHP_SELF'].'?facid='.$result); - exit; - } - else - { - $mesgs[]=$object->error; - $action=''; - } - } - } + if (1==0 && empty($_REQUEST["clone_content"]) && empty($_REQUEST["clone_receivers"])) + { + $mesgs[]='
'.$langs->trans("NoCloneOptionsSpecified").'
'; + } + else + { + if ($object->fetch($id) > 0) + { + $result=$object->createFromClone($socid); + if ($result > 0) + { + header("Location: ".$_SERVER['PHP_SELF'].'?facid='.$result); + exit; + } + else + { + $mesgs[]=$object->error; + $action=''; + } + } + } } // Change status of invoice else if ($action == 'reopen' && $user->rights->facture->creer) { - $result = $object->fetch($id); - if ($object->statut == 2 - || ($object->statut == 3 && $object->close_code != 'replaced')) - { - $result = $object->set_unpaid($user); - if ($result > 0) - { - header('Location: '.$_SERVER["PHP_SELF"].'?facid='.$id); - exit; - } - else - { - $mesgs[]='
'.$object->error.'
'; - } - } + $result = $object->fetch($id); + if ($object->statut == 2 + || ($object->statut == 3 && $object->close_code != 'replaced')) + { + $result = $object->set_unpaid($user); + if ($result > 0) + { + header('Location: '.$_SERVER["PHP_SELF"].'?facid='.$id); + exit; + } + else + { + $mesgs[]='
'.$object->error.'
'; + } + } } // Delete invoice @@ -156,7 +156,20 @@ else if ($action == 'confirm_delete' && $confirm == 'yes' && $user->rights->fact { $result = $object->fetch($id); $object->fetch_thirdparty(); - $result = $object->delete(); + + $idwarehouse=GETPOST('idwarehouse'); + + $qualified_for_stock_change=0; + if (empty($conf->global->STOCK_SUPPORTS_SERVICES)) + { + $qualified_for_stock_change=$object->hasProductsOrServices(2); + } + else + { + $qualified_for_stock_change=$object->hasProductsOrServices(1); + } + + $result = $object->delete(0,0,$idwarehouse); if ($result > 0) { header('Location: '.DOL_URL_ROOT.'/compta/facture/list.php'); @@ -208,146 +221,146 @@ else if ($action == 'confirm_deleteline' && $confirm == 'yes' && $user->rights-> // Delete link of credit note to invoice else if ($action == 'unlinkdiscount' && $user->rights->facture->creer) { - $discount=new DiscountAbsolute($db); - $result=$discount->fetch($_GET["discountid"]); - $discount->unlink_invoice(); + $discount=new DiscountAbsolute($db); + $result=$discount->fetch($_GET["discountid"]); + $discount->unlink_invoice(); } // Validation else if ($action == 'valid' && $user->rights->facture->creer) { - $object->fetch($id); + $object->fetch($id); - // On verifie signe facture - if ($object->type == 2) - { - // Si avoir, le signe doit etre negatif - if ($object->total_ht >= 0) - { - $mesgs[]='
'.$langs->trans("ErrorInvoiceAvoirMustBeNegative").'
'; - $action=''; - } - } - else - { - // Si non avoir, le signe doit etre positif - if (empty($conf->global->FACTURE_ENABLE_NEGATIVE) && $object->total_ht < 0) - { - $mesgs[]='
'.$langs->trans("ErrorInvoiceOfThisTypeMustBePositive").'
'; - $action=''; - } - } + // On verifie signe facture + if ($object->type == 2) + { + // Si avoir, le signe doit etre negatif + if ($object->total_ht >= 0) + { + $mesgs[]='
'.$langs->trans("ErrorInvoiceAvoirMustBeNegative").'
'; + $action=''; + } + } + else + { + // Si non avoir, le signe doit etre positif + if (empty($conf->global->FACTURE_ENABLE_NEGATIVE) && $object->total_ht < 0) + { + $mesgs[]='
'.$langs->trans("ErrorInvoiceOfThisTypeMustBePositive").'
'; + $action=''; + } + } } else if ($action == 'set_thirdparty' && $user->rights->facture->creer) { - $object->fetch($id); - $object->setValueFrom('fk_soc',$socid); + $object->fetch($id); + $object->setValueFrom('fk_soc',$socid); - header('Location: '.$_SERVER["PHP_SELF"].'?facid='.$id); - exit; + header('Location: '.$_SERVER["PHP_SELF"].'?facid='.$id); + exit; } else if ($action == 'classin' && $user->rights->facture->creer) { - $object->fetch($id); - $object->setProject($_POST['projectid']); + $object->fetch($id); + $object->setProject($_POST['projectid']); } else if ($action == 'setmode' && $user->rights->facture->creer) { - $object->fetch($id); - $result = $object->setPaymentMethods(GETPOST('mode_reglement_id','int')); - if ($result < 0) dol_print_error($db,$object->error); + $object->fetch($id); + $result = $object->setPaymentMethods(GETPOST('mode_reglement_id','int')); + if ($result < 0) dol_print_error($db,$object->error); } else if ($action == 'setinvoicedate' && $user->rights->facture->creer) { - $object->fetch($id); - $old_date_lim_reglement=$object->date_lim_reglement; - $object->date=dol_mktime(12,0,0,$_POST['invoicedatemonth'],$_POST['invoicedateday'],$_POST['invoicedateyear']); - $new_date_lim_reglement=$object->calculate_date_lim_reglement(); - if ($new_date_lim_reglement > $old_date_lim_reglement) $object->date_lim_reglement=$new_date_lim_reglement; - if ($object->date_lim_reglement < $object->date) $object->date_lim_reglement=$object->date; - $result=$object->update($user); - if ($result < 0) dol_print_error($db,$object->error); + $object->fetch($id); + $old_date_lim_reglement=$object->date_lim_reglement; + $object->date=dol_mktime(12,0,0,$_POST['invoicedatemonth'],$_POST['invoicedateday'],$_POST['invoicedateyear']); + $new_date_lim_reglement=$object->calculate_date_lim_reglement(); + if ($new_date_lim_reglement > $old_date_lim_reglement) $object->date_lim_reglement=$new_date_lim_reglement; + if ($object->date_lim_reglement < $object->date) $object->date_lim_reglement=$object->date; + $result=$object->update($user); + if ($result < 0) dol_print_error($db,$object->error); } else if ($action == 'setconditions' && $user->rights->facture->creer) { - $object->fetch($id); - $object->cond_reglement_code=0; // To clean property - $object->cond_reglement_id=0; // To clean property - $result=$object->setPaymentTerms(GETPOST('cond_reglement_id','int')); - if ($result < 0) dol_print_error($db,$object->error); + $object->fetch($id); + $object->cond_reglement_code=0; // To clean property + $object->cond_reglement_id=0; // To clean property + $result=$object->setPaymentTerms(GETPOST('cond_reglement_id','int')); + if ($result < 0) dol_print_error($db,$object->error); - $old_date_lim_reglement=$object->date_lim_reglement; - $new_date_lim_reglement=$object->calculate_date_lim_reglement(); - if ($new_date_lim_reglement > $old_date_lim_reglement) $object->date_lim_reglement=$new_date_lim_reglement; - if ($object->date_lim_reglement < $object->date) $object->date_lim_reglement=$object->date; - $result=$object->update($user); - if ($result < 0) dol_print_error($db,$object->error); + $old_date_lim_reglement=$object->date_lim_reglement; + $new_date_lim_reglement=$object->calculate_date_lim_reglement(); + if ($new_date_lim_reglement > $old_date_lim_reglement) $object->date_lim_reglement=$new_date_lim_reglement; + if ($object->date_lim_reglement < $object->date) $object->date_lim_reglement=$object->date; + $result=$object->update($user); + if ($result < 0) dol_print_error($db,$object->error); } else if ($action == 'setpaymentterm' && $user->rights->facture->creer) { - $object->fetch($id); - $object->date_lim_reglement=dol_mktime(12,0,0,$_POST['paymenttermmonth'],$_POST['paymenttermday'],$_POST['paymenttermyear']); - if ($object->date_lim_reglement < $object->date) - { - $object->date_lim_reglement=$object->calculate_date_lim_reglement(); - setEventMessage($langs->trans("DatePaymentTermCantBeLowerThanObjectDate"),'warnings'); - } - $result=$object->update($user); - if ($result < 0) dol_print_error($db,$object->error); + $object->fetch($id); + $object->date_lim_reglement=dol_mktime(12,0,0,$_POST['paymenttermmonth'],$_POST['paymenttermday'],$_POST['paymenttermyear']); + if ($object->date_lim_reglement < $object->date) + { + $object->date_lim_reglement=$object->calculate_date_lim_reglement(); + setEventMessage($langs->trans("DatePaymentTermCantBeLowerThanObjectDate"),'warnings'); + } + $result=$object->update($user); + if ($result < 0) dol_print_error($db,$object->error); } else if ($action == 'setrevenuestamp' && $user->rights->facture->creer) { - $object->fetch($id); - $object->revenuestamp=GETPOST('revenuestamp'); - $result=$object->update($user); - $object->update_price(1); - if ($result < 0) dol_print_error($db,$object->error); + $object->fetch($id); + $object->revenuestamp=GETPOST('revenuestamp'); + $result=$object->update($user); + $object->update_price(1); + if ($result < 0) dol_print_error($db,$object->error); } else if ($action == 'setremisepercent' && $user->rights->facture->creer) { - $object->fetch($id); - $result = $object->set_remise($user, $_POST['remise_percent']); + $object->fetch($id); + $result = $object->set_remise($user, $_POST['remise_percent']); } else if ($action == "setabsolutediscount" && $user->rights->facture->creer) { - // POST[remise_id] ou POST[remise_id_for_payment] - if (! empty($_POST["remise_id"])) - { - $ret=$object->fetch($id); - if ($ret > 0) - { - $result=$object->insert_discount($_POST["remise_id"]); - if ($result < 0) - { - $mesgs[]='
'.$object->error.'
'; - } - } - else - { - dol_print_error($db,$object->error); - } - } - if (! empty($_POST["remise_id_for_payment"])) - { - require_once DOL_DOCUMENT_ROOT.'/core/class/discount.class.php'; - $discount = new DiscountAbsolute($db); - $discount->fetch($_POST["remise_id_for_payment"]); + // POST[remise_id] ou POST[remise_id_for_payment] + if (! empty($_POST["remise_id"])) + { + $ret=$object->fetch($id); + if ($ret > 0) + { + $result=$object->insert_discount($_POST["remise_id"]); + if ($result < 0) + { + $mesgs[]='
'.$object->error.'
'; + } + } + else + { + dol_print_error($db,$object->error); + } + } + if (! empty($_POST["remise_id_for_payment"])) + { + require_once DOL_DOCUMENT_ROOT.'/core/class/discount.class.php'; + $discount = new DiscountAbsolute($db); + $discount->fetch($_POST["remise_id_for_payment"]); - $result=$discount->link_to_invoice(0,$id); - if ($result < 0) - { - $mesgs[]='
'.$discount->error.'
'; - } - } + $result=$discount->link_to_invoice(0,$id); + if ($result < 0) + { + $mesgs[]='
'.$discount->error.'
'; + } + } } else if ($action == 'set_ref_client' && $user->rights->facture->creer) { - $object->fetch($id); - $object->set_ref_client($_POST['ref_client']); + $object->fetch($id); + $object->set_ref_client($_POST['ref_client']); } else if ($action == 'setnote_public' && $user->rights->facture->creer) @@ -367,864 +380,967 @@ else if ($action == 'setnote_private' && $user->rights->facture->creer) // Classify to validated else if ($action == 'confirm_valid' && $confirm == 'yes' && $user->rights->facture->valider) { - $idwarehouse=GETPOST('idwarehouse'); + $idwarehouse=GETPOST('idwarehouse'); - $object->fetch($id); - $object->fetch_thirdparty(); + $object->fetch($id); + $object->fetch_thirdparty(); - // Check parameters + // Check parameters - // Check for mandatory prof id - for ($i = 1; $i < 5; $i++) - { + // Check for mandatory prof id + for ($i = 1; $i < 5; $i++) + { - $idprof_mandatory ='SOCIETE_IDPROF'.($i).'_INVOICE_MANDATORY'; - $idprof='idprof'.$i; - if (! $object->thirdparty->$idprof && ! empty($conf->global->$idprof_mandatory)) - { - if (! $error) $langs->load("errors"); - $error++; + $idprof_mandatory ='SOCIETE_IDPROF'.($i).'_INVOICE_MANDATORY'; + $idprof='idprof'.$i; + if (! $object->thirdparty->$idprof && ! empty($conf->global->$idprof_mandatory)) + { + if (! $error) $langs->load("errors"); + $error++; - setEventMessage($langs->trans('ErrorProdIdIsMandatory',$langs->transcountry('ProfId'.$i, $object->thirdparty->country_code)),'errors'); - } - } + setEventMessage($langs->trans('ErrorProdIdIsMandatory',$langs->transcountry('ProfId'.$i, $object->thirdparty->country_code)),'errors'); + } + } - //Check for warehouse - if ($object->type != 3 && ! empty($conf->global->STOCK_CALCULATE_ON_BILL) && $object->hasProductsOrServices(1)) - { - if (! $idwarehouse || $idwarehouse == -1) - { - $error++; - setEventMessage($langs->trans('ErrorFieldRequired',$langs->transnoentitiesnoconv("Warehouse")),'errors'); - $action=''; - } - } + $qualified_for_stock_change=0; + if (empty($conf->global->STOCK_SUPPORTS_SERVICES)) + { + $qualified_for_stock_change=$object->hasProductsOrServices(2); + } + else + { + $qualified_for_stock_change=$object->hasProductsOrServices(1); + } - if (! $error) - { - $result = $object->validate($user,'',$idwarehouse); - if ($result >= 0) - { - // Define output language - $outputlangs = $langs; - $newlang=''; - if ($conf->global->MAIN_MULTILANGS && empty($newlang) && ! empty($_REQUEST['lang_id'])) $newlang=$_REQUEST['lang_id']; - if ($conf->global->MAIN_MULTILANGS && empty($newlang)) $newlang=$object->client->default_lang; - if (! empty($newlang)) - { - $outputlangs = new Translate("",$conf); - $outputlangs->setDefaultLang($newlang); - } - if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) - { - $ret=$object->fetch($id); // Reload to get new records - facture_pdf_create($db, $object, $object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref); - } - } - else - { - setEventMessage($object->error,'errors'); - } - } + //Check for warehouse + if ($object->type != 3 && ! empty($conf->global->STOCK_CALCULATE_ON_BILL) && $qualified_for_stock_change) + { + if (! $idwarehouse || $idwarehouse == -1) + { + $error++; + setEventMessage($langs->trans('ErrorFieldRequired',$langs->transnoentitiesnoconv("Warehouse")),'errors'); + $action=''; + } + } + + if (! $error) + { + $result = $object->validate($user,'',$idwarehouse); + if ($result >= 0) + { + // Define output language + $outputlangs = $langs; + $newlang=''; + if ($conf->global->MAIN_MULTILANGS && empty($newlang) && ! empty($_REQUEST['lang_id'])) $newlang=$_REQUEST['lang_id']; + if ($conf->global->MAIN_MULTILANGS && empty($newlang)) $newlang=$object->client->default_lang; + if (! empty($newlang)) + { + $outputlangs = new Translate("",$conf); + $outputlangs->setDefaultLang($newlang); + } + if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) + { + $ret=$object->fetch($id); // Reload to get new records + facture_pdf_create($db, $object, $object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref); + } + } + else + { + setEventMessage($object->error,'errors'); + } + } } // Go back to draft status (unvalidate) else if ($action == 'confirm_modif' && ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && $user->rights->facture->valider) || $user->rights->facture->invoice_advance->unvalidate)) { - $idwarehouse=GETPOST('idwarehouse'); + $idwarehouse=GETPOST('idwarehouse'); - $object->fetch($id); - $object->fetch_thirdparty(); + $object->fetch($id); + $object->fetch_thirdparty(); - // Check parameters - if ($object->type != 3 && ! empty($conf->global->STOCK_CALCULATE_ON_BILL) && $object->hasProductsOrServices(1)) - { - if (! $idwarehouse || $idwarehouse == -1) - { - $error++; - setEventMessage($langs->trans('ErrorFieldRequired',$langs->transnoentitiesnoconv("Warehouse")),'errors'); - $action=''; - } - } + $qualified_for_stock_change=0; + if (empty($conf->global->STOCK_SUPPORTS_SERVICES)) + { + $qualified_for_stock_change=$object->hasProductsOrServices(2); + } + else + { + $qualified_for_stock_change=$object->hasProductsOrServices(1); + } - if (! $error) - { - // On verifie si la facture a des paiements - $sql = 'SELECT pf.amount'; - $sql.= ' FROM '.MAIN_DB_PREFIX.'paiement_facture as pf'; - $sql.= ' WHERE pf.fk_facture = '.$object->id; + // Check parameters + if ($object->type != 3 && ! empty($conf->global->STOCK_CALCULATE_ON_BILL) && $qualified_for_stock_change) + { + if (! $idwarehouse || $idwarehouse == -1) + { + $error++; + setEventMessage($langs->trans('ErrorFieldRequired',$langs->transnoentitiesnoconv("Warehouse")),'errors'); + $action=''; + } + } - $result = $db->query($sql); - if ($result) - { - $i = 0; - $num = $db->num_rows($result); + if (! $error) + { + // On verifie si la facture a des paiements + $sql = 'SELECT pf.amount'; + $sql.= ' FROM '.MAIN_DB_PREFIX.'paiement_facture as pf'; + $sql.= ' WHERE pf.fk_facture = '.$object->id; - while ($i < $num) - { - $objp = $db->fetch_object($result); - $totalpaye += $objp->amount; - $i++; - } - } - else - { - dol_print_error($db,''); - } + $result = $db->query($sql); + if ($result) + { + $i = 0; + $num = $db->num_rows($result); - $resteapayer = $object->total_ttc - $totalpaye; + while ($i < $num) + { + $objp = $db->fetch_object($result); + $totalpaye += $objp->amount; + $i++; + } + } + else + { + dol_print_error($db,''); + } - // On verifie si les lignes de factures ont ete exportees en compta et/ou ventilees - $ventilExportCompta = $object->getVentilExportCompta(); + $resteapayer = $object->total_ttc - $totalpaye; - // On verifie si aucun paiement n'a ete effectue - if ($resteapayer == $object->total_ttc && $object->paye == 0 && $ventilExportCompta == 0) - { - $object->set_draft($user, $idwarehouse); + // On verifie si les lignes de factures ont ete exportees en compta et/ou ventilees + $ventilExportCompta = $object->getVentilExportCompta(); - // Define output language - $outputlangs = $langs; - $newlang=''; - if ($conf->global->MAIN_MULTILANGS && empty($newlang) && ! empty($_REQUEST['lang_id'])) $newlang=$_REQUEST['lang_id']; - if ($conf->global->MAIN_MULTILANGS && empty($newlang)) $newlang=$object->client->default_lang; - if (! empty($newlang)) - { - $outputlangs = new Translate("",$conf); - $outputlangs->setDefaultLang($newlang); - } - if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) - { - $ret=$object->fetch($id); // Reload to get new records - facture_pdf_create($db, $object, $object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref); - } - } - } + // On verifie si aucun paiement n'a ete effectue + if ($resteapayer == $object->total_ttc && $object->paye == 0 && $ventilExportCompta == 0) + { + $object->set_draft($user, $idwarehouse); + + // Define output language + $outputlangs = $langs; + $newlang=''; + if ($conf->global->MAIN_MULTILANGS && empty($newlang) && ! empty($_REQUEST['lang_id'])) $newlang=$_REQUEST['lang_id']; + if ($conf->global->MAIN_MULTILANGS && empty($newlang)) $newlang=$object->client->default_lang; + if (! empty($newlang)) + { + $outputlangs = new Translate("",$conf); + $outputlangs->setDefaultLang($newlang); + } + if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) + { + $ret=$object->fetch($id); // Reload to get new records + facture_pdf_create($db, $object, $object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref); + } + } + } } // Classify "paid" else if ($action == 'confirm_paid' && $confirm == 'yes' && $user->rights->facture->paiement) { - $object->fetch($id); - $result = $object->set_paid($user); + $object->fetch($id); + $result = $object->set_paid($user); } // Classif "paid partialy" else if ($action == 'confirm_paid_partially' && $confirm == 'yes' && $user->rights->facture->paiement) { - $object->fetch($id); - $close_code=$_POST["close_code"]; - $close_note=$_POST["close_note"]; - if ($close_code) - { - $result = $object->set_paid($user,$close_code,$close_note); - } - else - { - setEventMessage($langs->trans("ErrorFieldRequired",$langs->transnoentitiesnoconv("Reason")),'errors'); - } + $object->fetch($id); + $close_code=$_POST["close_code"]; + $close_note=$_POST["close_note"]; + if ($close_code) + { + $result = $object->set_paid($user,$close_code,$close_note); + } + else + { + setEventMessage($langs->trans("ErrorFieldRequired",$langs->transnoentitiesnoconv("Reason")),'errors'); + } } // Classify "abandoned" else if ($action == 'confirm_canceled' && $confirm == 'yes') { - $object->fetch($id); - $close_code=$_POST["close_code"]; - $close_note=$_POST["close_note"]; - if ($close_code) - { - $result = $object->set_canceled($user,$close_code,$close_note); - } - else - { - setEventMessage($langs->trans("ErrorFieldRequired",$langs->transnoentitiesnoconv("Reason")),'errors'); - } + $object->fetch($id); + $close_code=$_POST["close_code"]; + $close_note=$_POST["close_note"]; + if ($close_code) + { + $result = $object->set_canceled($user,$close_code,$close_note); + } + else + { + setEventMessage($langs->trans("ErrorFieldRequired",$langs->transnoentitiesnoconv("Reason")),'errors'); + } } // Convertir en reduc else if ($action == 'confirm_converttoreduc' && $confirm == 'yes' && $user->rights->facture->creer) { - $db->begin(); + $db->begin(); - $object->fetch($id); - $object->fetch_thirdparty(); - $object->fetch_lines(); + $object->fetch($id); + $object->fetch_thirdparty(); + $object->fetch_lines(); - if (! $object->paye) // protection against multiple submit - { - // Boucle sur chaque taux de tva - $i=0; - foreach($object->lines as $line) - { - $amount_ht[$line->tva_tx]+=$line->total_ht; - $amount_tva[$line->tva_tx]+=$line->total_tva; - $amount_ttc[$line->tva_tx]+=$line->total_ttc; - $i++; - } + if (! $object->paye) // protection against multiple submit + { + // Boucle sur chaque taux de tva + $i=0; + foreach($object->lines as $line) + { + $amount_ht[$line->tva_tx]+=$line->total_ht; + $amount_tva[$line->tva_tx]+=$line->total_tva; + $amount_ttc[$line->tva_tx]+=$line->total_ttc; + $i++; + } - // Insert one discount by VAT rate category - $discount = new DiscountAbsolute($db); - if ($object->type == 2) $discount->description='(CREDIT_NOTE)'; - elseif ($object->type == 3) $discount->description='(DEPOSIT)'; - else { - $this->error="CantConvertToReducAnInvoiceOfThisType"; - return -1; - } - $discount->tva_tx=abs($object->total_ttc); - $discount->fk_soc=$object->socid; - $discount->fk_facture_source=$object->id; + // Insert one discount by VAT rate category + $discount = new DiscountAbsolute($db); + if ($object->type == 2) $discount->description='(CREDIT_NOTE)'; + elseif ($object->type == 3) $discount->description='(DEPOSIT)'; + else { + $this->error="CantConvertToReducAnInvoiceOfThisType"; + return -1; + } + $discount->tva_tx=abs($object->total_ttc); + $discount->fk_soc=$object->socid; + $discount->fk_facture_source=$object->id; - $error=0; - foreach($amount_ht as $tva_tx => $xxx) - { - $discount->amount_ht=abs($amount_ht[$tva_tx]); - $discount->amount_tva=abs($amount_tva[$tva_tx]); - $discount->amount_ttc=abs($amount_ttc[$tva_tx]); - $discount->tva_tx=abs($tva_tx); + $error=0; + foreach($amount_ht as $tva_tx => $xxx) + { + $discount->amount_ht=abs($amount_ht[$tva_tx]); + $discount->amount_tva=abs($amount_tva[$tva_tx]); + $discount->amount_ttc=abs($amount_ttc[$tva_tx]); + $discount->tva_tx=abs($tva_tx); - $result=$discount->create($user); - if ($result < 0) - { - $error++; - break; - } - } + $result=$discount->create($user); + if ($result < 0) + { + $error++; + break; + } + } - if (! $error) - { - // Classe facture - $result=$object->set_paid($user); - if ($result > 0) - { - //$mesgs[]='OK'.$discount->id; - $db->commit(); - } - else - { - $mesgs[]='
'.$object->error.'
'; - $db->rollback(); - } - } - else - { - $mesgs[]='
'.$discount->error.'
'; - $db->rollback(); - } - } + if (! $error) + { + // Classe facture + $result=$object->set_paid($user); + if ($result > 0) + { + //$mesgs[]='OK'.$discount->id; + $db->commit(); + } + else + { + $mesgs[]='
'.$object->error.'
'; + $db->rollback(); + } + } + else + { + $mesgs[]='
'.$discount->error.'
'; + $db->rollback(); + } + } } /* * Insert new invoice in database - */ +*/ else if ($action == 'add' && $user->rights->facture->creer) { if ($socid>0) - $object->socid=GETPOST('socid','int'); + $object->socid=GETPOST('socid','int'); - $db->begin(); + $db->begin(); - $error=0; + $error=0; - // Get extra fields - foreach($_POST as $key => $value) - { - if (preg_match("/^options_/",$key)) - { - $object->array_options[$key]=GETPOST($key); - } - } + // Get extra fields + foreach($_POST as $key => $value) + { + if (preg_match("/^options_/",$key)) + { + $object->array_options[$key]=GETPOST($key); + } + } - // Replacement invoice - if ($_POST['type'] == 1) - { - $datefacture = dol_mktime(12, 0, 0, $_POST['remonth'], $_POST['reday'], $_POST['reyear']); - if (empty($datefacture)) - { - $error++; - setEventMessage($langs->trans("ErrorFieldRequired",$langs->transnoentitiesnoconv("Date")),'errors'); - } + // Replacement invoice + if ($_POST['type'] == 1) + { + $datefacture = dol_mktime(12, 0, 0, $_POST['remonth'], $_POST['reday'], $_POST['reyear']); + if (empty($datefacture)) + { + $error++; + setEventMessage($langs->trans("ErrorFieldRequired",$langs->transnoentitiesnoconv("Date")),'errors'); + } - if (! ($_POST['fac_replacement'] > 0)) - { - $error++; - setEventMessage($langs->trans("ErrorFieldRequired",$langs->transnoentitiesnoconv("ReplaceInvoice")),'errors'); - } + if (! ($_POST['fac_replacement'] > 0)) + { + $error++; + setEventMessage($langs->trans("ErrorFieldRequired",$langs->transnoentitiesnoconv("ReplaceInvoice")),'errors'); + } - if (! $error) - { - // This is a replacement invoice - $result=$object->fetch($_POST['fac_replacement']); - $object->fetch_thirdparty(); + if (! $error) + { + // This is a replacement invoice + $result=$object->fetch($_POST['fac_replacement']); + $object->fetch_thirdparty(); - $object->date = $datefacture; - $object->note_public = trim($_POST['note_public']); - $object->note = trim($_POST['note']); - $object->ref_client = $_POST['ref_client']; - $object->ref_int = $_POST['ref_int']; - $object->modelpdf = $_POST['model']; - $object->fk_project = $_POST['projectid']; - $object->cond_reglement_id = $_POST['cond_reglement_id']; - $object->mode_reglement_id = $_POST['mode_reglement_id']; - $object->remise_absolue = $_POST['remise_absolue']; - $object->remise_percent = $_POST['remise_percent']; + $object->date = $datefacture; + $object->note_public = trim($_POST['note_public']); + $object->note = trim($_POST['note']); + $object->ref_client = $_POST['ref_client']; + $object->ref_int = $_POST['ref_int']; + $object->modelpdf = $_POST['model']; + $object->fk_project = $_POST['projectid']; + $object->cond_reglement_id = $_POST['cond_reglement_id']; + $object->mode_reglement_id = $_POST['mode_reglement_id']; + $object->remise_absolue = $_POST['remise_absolue']; + $object->remise_percent = $_POST['remise_percent']; - // Proprietes particulieres a facture de remplacement - $object->fk_facture_source = $_POST['fac_replacement']; - $object->type = 1; + // Proprietes particulieres a facture de remplacement + $object->fk_facture_source = $_POST['fac_replacement']; + $object->type = 1; - $id=$object->createFromCurrent($user); - if ($id <= 0) $mesgs[]=$object->error; - } - } + $id=$object->createFromCurrent($user); + if ($id <= 0) $mesgs[]=$object->error; + } + } - // Credit note invoice - if ($_POST['type'] == 2) - { - if (! $_POST['fac_avoir'] > 0) - { - $error++; - setEventMessage($langs->trans("ErrorFieldRequired",$langs->transnoentitiesnoconv("CorrectInvoice")),'errors'); - } + // Credit note invoice + if ($_POST['type'] == 2) + { + if (! $_POST['fac_avoir'] > 0) + { + $error++; + setEventMessage($langs->trans("ErrorFieldRequired",$langs->transnoentitiesnoconv("CorrectInvoice")),'errors'); + } - $datefacture = dol_mktime(12, 0, 0, $_POST['remonth'], $_POST['reday'], $_POST['reyear']); - if (empty($datefacture)) - { - $error++; - setEventMessage($langs->trans("ErrorFieldRequired",$langs->trans("Date")),'errors'); - } + $datefacture = dol_mktime(12, 0, 0, $_POST['remonth'], $_POST['reday'], $_POST['reyear']); + if (empty($datefacture)) + { + $error++; + setEventMessage($langs->trans("ErrorFieldRequired",$langs->trans("Date")),'errors'); + } - if (! $error) - { - // Si facture avoir - $datefacture = dol_mktime(12, 0, 0, $_POST['remonth'], $_POST['reday'], $_POST['reyear']); + if (! $error) + { + // Si facture avoir + $datefacture = dol_mktime(12, 0, 0, $_POST['remonth'], $_POST['reday'], $_POST['reyear']); - //$result=$object->fetch($_POST['fac_avoir']); + //$result=$object->fetch($_POST['fac_avoir']); - $object->socid = GETPOST('socid','int'); - $object->number = $_POST['facnumber']; - $object->date = $datefacture; - $object->note_public = trim($_POST['note_public']); - $object->note = trim($_POST['note']); - $object->ref_client = $_POST['ref_client']; - $object->ref_int = $_POST['ref_int']; - $object->modelpdf = $_POST['model']; - $object->fk_project = $_POST['projectid']; - $object->cond_reglement_id = 0; - $object->mode_reglement_id = $_POST['mode_reglement_id']; - $object->remise_absolue = $_POST['remise_absolue']; - $object->remise_percent = $_POST['remise_percent']; + $object->socid = GETPOST('socid','int'); + $object->number = $_POST['facnumber']; + $object->date = $datefacture; + $object->note_public = trim($_POST['note_public']); + $object->note = trim($_POST['note']); + $object->ref_client = $_POST['ref_client']; + $object->ref_int = $_POST['ref_int']; + $object->modelpdf = $_POST['model']; + $object->fk_project = $_POST['projectid']; + $object->cond_reglement_id = 0; + $object->mode_reglement_id = $_POST['mode_reglement_id']; + $object->remise_absolue = $_POST['remise_absolue']; + $object->remise_percent = $_POST['remise_percent']; - // Proprietes particulieres a facture avoir - $object->fk_facture_source = $_POST['fac_avoir']; - $object->type = 2; + // Proprietes particulieres a facture avoir + $object->fk_facture_source = $_POST['fac_avoir']; + $object->type = 2; - $id = $object->create($user); + $id = $object->create($user); - // Add predefined lines - for ($i = 1; $i <= $NBLINES; $i++) - { - if ($_POST['idprod'.$i]) - { - $product=new Product($db); - $product->fetch($_POST['idprod'.$i]); - $startday=dol_mktime(12, 0, 0, $_POST['date_start'.$i.'month'], $_POST['date_start'.$i.'day'], $_POST['date_start'.$i.'year']); - $endday=dol_mktime(12, 0, 0, $_POST['date_end'.$i.'month'], $_POST['date_end'.$i.'day'], $_POST['date_end'.$i.'year']); - $result=$object->addline($id,$product->description,$product->price, $_POST['qty'.$i], $product->tva_tx, $product->localtax1_tx, $product->localtax2_tx, $_POST['idprod'.$i], $_POST['remise_percent'.$i], $startday, $endday, 0, 0, '', $product->price_base_type, $product->price_ttc, $product->type); - } - } - } - } + // Add predefined lines + for ($i = 1; $i <= $NBLINES; $i++) + { + if ($_POST['idprod'.$i]) + { + $product=new Product($db); + $product->fetch($_POST['idprod'.$i]); + $startday=dol_mktime(12, 0, 0, $_POST['date_start'.$i.'month'], $_POST['date_start'.$i.'day'], $_POST['date_start'.$i.'year']); + $endday=dol_mktime(12, 0, 0, $_POST['date_end'.$i.'month'], $_POST['date_end'.$i.'day'], $_POST['date_end'.$i.'year']); + $result=$object->addline($id,$product->description,$product->price, $_POST['qty'.$i], $product->tva_tx, $product->localtax1_tx, $product->localtax2_tx, $_POST['idprod'.$i], $_POST['remise_percent'.$i], $startday, $endday, 0, 0, '', $product->price_base_type, $product->price_ttc, $product->type); + } + } + } + } - // Standard invoice or Deposit invoice created from a Predefined invoice - if (($_POST['type'] == 0 || $_POST['type'] == 3) && $_POST['fac_rec'] > 0) - { - $datefacture = dol_mktime(12, 0, 0, $_POST['remonth'], $_POST['reday'], $_POST['reyear']); - if (empty($datefacture)) - { - $error++; - setEventMessage($langs->trans("ErrorFieldRequired",$langs->transnoentitiesnoconv("Date")),'errors'); - } + // Standard invoice or Deposit invoice created from a Predefined invoice + if (($_POST['type'] == 0 || $_POST['type'] == 3) && $_POST['fac_rec'] > 0) + { + $datefacture = dol_mktime(12, 0, 0, $_POST['remonth'], $_POST['reday'], $_POST['reyear']); + if (empty($datefacture)) + { + $error++; + setEventMessage($langs->trans("ErrorFieldRequired",$langs->transnoentitiesnoconv("Date")),'errors'); + } - if (! $error) - { - $object->socid = GETPOST('socid','int'); - $object->type = $_POST['type']; - $object->number = $_POST['facnumber']; - $object->date = $datefacture; - $object->note_public = trim($_POST['note_public']); - $object->note_private = trim($_POST['note_private']); - $object->ref_client = $_POST['ref_client']; - $object->ref_int = $_POST['ref_int']; - $object->modelpdf = $_POST['model']; + if (! $error) + { + $object->socid = GETPOST('socid','int'); + $object->type = $_POST['type']; + $object->number = $_POST['facnumber']; + $object->date = $datefacture; + $object->note_public = trim($_POST['note_public']); + $object->note_private = trim($_POST['note_private']); + $object->ref_client = $_POST['ref_client']; + $object->ref_int = $_POST['ref_int']; + $object->modelpdf = $_POST['model']; - // Source facture - $object->fac_rec = $_POST['fac_rec']; + // Source facture + $object->fac_rec = $_POST['fac_rec']; - $id = $object->create($user); - } - } + $id = $object->create($user); + } + } - // Standard or deposit or proforma invoice - if (($_POST['type'] == 0 || $_POST['type'] == 3 || $_POST['type'] == 4) && $_POST['fac_rec'] <= 0) - { - if (GETPOST('socid','int')<1) - { - $error++; - setEventMessage($langs->trans("ErrorFieldRequired",$langs->transnoentitiesnoconv("Customer")),'errors'); - } - $datefacture = dol_mktime(12, 0, 0, $_POST['remonth'], $_POST['reday'], $_POST['reyear']); - if (empty($datefacture)) - { - $error++; - setEventMessage($langs->trans("ErrorFieldRequired",$langs->transnoentitiesnoconv("Date")),'errors'); - } - if (! $error) - { - // Si facture standard - $object->socid = GETPOST('socid','int'); - $object->type = GETPOST('type'); - $object->number = $_POST['facnumber']; - $object->date = $datefacture; - $object->note_public = trim($_POST['note_public']); - $object->note_private = trim($_POST['note_private']); - $object->ref_client = $_POST['ref_client']; - $object->ref_int = $_POST['ref_int']; - $object->modelpdf = $_POST['model']; - $object->fk_project = $_POST['projectid']; - $object->cond_reglement_id = ($_POST['type'] == 3?1:$_POST['cond_reglement_id']); - $object->mode_reglement_id = $_POST['mode_reglement_id']; - $object->amount = $_POST['amount']; - $object->remise_absolue = $_POST['remise_absolue']; - $object->remise_percent = $_POST['remise_percent']; - $object->fetch_thirdparty(); + // Standard or deposit or proforma invoice + if (($_POST['type'] == 0 || $_POST['type'] == 3 || $_POST['type'] == 4) && $_POST['fac_rec'] <= 0) + { + if (GETPOST('socid','int')<1) + { + $error++; + setEventMessage($langs->trans("ErrorFieldRequired",$langs->transnoentitiesnoconv("Customer")),'errors'); + } - // If creation from another object of another module (Example: origin=propal, originid=1) - if ($_POST['origin'] && $_POST['originid']) - { - // Parse element/subelement (ex: project_task) - $element = $subelement = $_POST['origin']; - if (preg_match('/^([^_]+)_([^_]+)/i',$_POST['origin'],$regs)) - { - $element = $regs[1]; - $subelement = $regs[2]; - } + $datefacture = dol_mktime(12, 0, 0, $_POST['remonth'], $_POST['reday'], $_POST['reyear']); + if (empty($datefacture)) + { + $error++; + setEventMessage($langs->trans("ErrorFieldRequired",$langs->transnoentitiesnoconv("Date")),'errors'); + } - // For compatibility - if ($element == 'order') { $element = $subelement = 'commande'; } - if ($element == 'propal') { $element = 'comm/propal'; $subelement = 'propal'; } - if ($element == 'contract') { $element = $subelement = 'contrat'; } - if ($element == 'inter') { $element = $subelement = 'ficheinter'; } - if ($element == 'shipping') { $element = $subelement = 'expedition'; } + if (! $error) + { + // Si facture standard + $object->socid = GETPOST('socid','int'); + $object->type = GETPOST('type'); + $object->number = $_POST['facnumber']; + $object->date = $datefacture; + $object->note_public = trim($_POST['note_public']); + $object->note_private = trim($_POST['note_private']); + $object->ref_client = $_POST['ref_client']; + $object->ref_int = $_POST['ref_int']; + $object->modelpdf = $_POST['model']; + $object->fk_project = $_POST['projectid']; + $object->cond_reglement_id = ($_POST['type'] == 3?1:$_POST['cond_reglement_id']); + $object->mode_reglement_id = $_POST['mode_reglement_id']; + $object->amount = $_POST['amount']; + $object->remise_absolue = $_POST['remise_absolue']; + $object->remise_percent = $_POST['remise_percent']; + $object->fetch_thirdparty(); - $object->origin = $_POST['origin']; - $object->origin_id = $_POST['originid']; + // If creation from another object of another module (Example: origin=propal, originid=1) + if ($_POST['origin'] && $_POST['originid']) + { + // Parse element/subelement (ex: project_task) + $element = $subelement = $_POST['origin']; + if (preg_match('/^([^_]+)_([^_]+)/i',$_POST['origin'],$regs)) + { + $element = $regs[1]; + $subelement = $regs[2]; + } - // 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']); - } + // For compatibility + if ($element == 'order') { + $element = $subelement = 'commande'; + } + if ($element == 'propal') { + $element = 'comm/propal'; $subelement = 'propal'; + } + if ($element == 'contract') { + $element = $subelement = 'contrat'; + } + if ($element == 'inter') { + $element = $subelement = 'ficheinter'; + } + if ($element == 'shipping') { + $element = $subelement = 'expedition'; + } - $id = $object->create($user); + $object->origin = $_POST['origin']; + $object->origin_id = $_POST['originid']; - if ($id > 0) - { - dol_include_once('/'.$element.'/class/'.$subelement.'.class.php'); + // 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']); + } - $classname = ucfirst($subelement); - $srcobject = new $classname($db); + $id = $object->create($user); - 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')) $lines = $srcobject->fetch_lines(); + if ($id > 0) + { + //If deposit invoice + if ($_POST['type'] == 3) { + $typeamount=GETPOST('typedeposit','alpha'); + $valuedeposit=GETPOST('valuedeposit','int'); + + if ($typeamount=='amount') { + $amountdeposit=$valuedeposit; + }else { + $amountdeposit=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 deposit line"); + $result=$srcobject->fetch($object->origin_id); + if ($result > 0) + { + $totalamount=0; + $lines = $srcobject->lines; + $num=count($lines); + for ($i=0;$i<$num;$i++) + { + $totalamount=+$lines[$i]->subprice; + } + + if ($totalamount!=0) { + $amountdeposit=($totalamount*$valuedeposit)/100; + } + } + else + { + $mesgs[]=$srcobject->error; + $error++; + } + + } + + $result = $object->addline( + $id, + $langs->trans('Deposit'), + $amountdeposit, //subprice + 1, //quantity + $lines[$i]->tva_tx, + 0, //localtax1_tx + 0, //localtax2_tx + 0, //fk_product + 0, //remise_percent + 0, //date_start + 0, //date_end + 0, + $lines[$i]->info_bits, //info_bits + 0, //info_bits + 'HT', + 0, + 0, //product_type + 1, + $lines[$i]->special_code, + $object->origin, + 0, + 0, + 0, + 0, + $langs->trans('Deposit') + ); + - $fk_parent_line=0; - $num=count($lines); + }else { - 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); + dol_include_once('/'.$element.'/class/'.$subelement.'.class.php'); - if ($lines[$i]->subprice < 0) - { - // Negative line, we create a discount line - $discount = new DiscountAbsolute($db); - $discount->fk_soc=$object->socid; - $discount->amount_ht=abs($lines[$i]->total_ht); - $discount->amount_tva=abs($lines[$i]->total_tva); - $discount->amount_ttc=abs($lines[$i]->total_ttc); - $discount->tva_tx=$lines[$i]->tva_tx; - $discount->fk_user=$user->id; - $discount->description=$desc; - $discountid=$discount->create($user); - if ($discountid > 0) - { - $result=$object->insert_discount($discountid); // This include link_to_invoice - } - else - { - $mesgs[]=$discount->error; - $error++; - break; - } - } - else - { - // Positive line - $product_type=($lines[$i]->product_type?$lines[$i]->product_type:0); + $classname = ucfirst($subelement); + $srcobject = new $classname($db); - // Date start - $date_start=false; - if ($lines[$i]->date_debut_prevue) $date_start=$lines[$i]->date_debut_prevue; - if ($lines[$i]->date_debut_reel) $date_start=$lines[$i]->date_debut_reel; - if ($lines[$i]->date_start) $date_start=$lines[$i]->date_start; + 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')) $lines = $srcobject->fetch_lines(); - //Date end - $date_end=false; - if ($lines[$i]->date_fin_prevue) $date_end=$lines[$i]->date_fin_prevue; - if ($lines[$i]->date_fin_reel) $date_end=$lines[$i]->date_fin_reel; - if ($lines[$i]->date_end) $date_end=$lines[$i]->date_end; + $fk_parent_line=0; + $num=count($lines); - // 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; - } + 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); - $result = $object->addline( - $id, - $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, - $date_start, - $date_end, - 0, - $lines[$i]->info_bits, - $lines[$i]->fk_remise_except, - 'HT', - 0, - $product_type, - $lines[$i]->rang, - $lines[$i]->special_code, - $object->origin, - $lines[$i]->rowid, - $fk_parent_line, - $lines[$i]->fk_fournprice, - $lines[$i]->pa_ht, - $label - ); + if ($lines[$i]->subprice < 0) + { + // Negative line, we create a discount line + $discount = new DiscountAbsolute($db); + $discount->fk_soc=$object->socid; + $discount->amount_ht=abs($lines[$i]->total_ht); + $discount->amount_tva=abs($lines[$i]->total_tva); + $discount->amount_ttc=abs($lines[$i]->total_ttc); + $discount->tva_tx=$lines[$i]->tva_tx; + $discount->fk_user=$user->id; + $discount->description=$desc; + $discountid=$discount->create($user); + if ($discountid > 0) + { + $result=$object->insert_discount($discountid); // This include link_to_invoice + } + else + { + $mesgs[]=$discount->error; + $error++; + break; + } + } + else + { + // Positive line + $product_type=($lines[$i]->product_type?$lines[$i]->product_type:0); - if ($result > 0) - { - $lineid=$result; - } - else - { - $lineid=0; - $error++; - break; - } + // Date start + $date_start=false; + if ($lines[$i]->date_debut_prevue) $date_start=$lines[$i]->date_debut_prevue; + if ($lines[$i]->date_debut_reel) $date_start=$lines[$i]->date_debut_reel; + if ($lines[$i]->date_start) $date_start=$lines[$i]->date_start; - // Defined the new fk_parent_line - if ($result > 0 && $lines[$i]->product_type == 9) { - $fk_parent_line = $result; - } - } - } + //Date end + $date_end=false; + if ($lines[$i]->date_fin_prevue) $date_end=$lines[$i]->date_fin_prevue; + if ($lines[$i]->date_fin_reel) $date_end=$lines[$i]->date_fin_reel; + if ($lines[$i]->date_end) $date_end=$lines[$i]->date_end; - // 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 - { - $mesgs[]=$srcobject->error; - $error++; - } - } - else - { - $mesgs[]=$object->error; - $error++; - } - } - // If some invoice's lines already known - else - { - $id = $object->create($user); + // 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; + } - for ($i = 1; $i <= $NBLINES; $i++) - { - if ($_POST['idprod'.$i]) - { - $product=new Product($db); - $product->fetch($_POST['idprod'.$i]); - $startday=dol_mktime(12, 0, 0, $_POST['date_start'.$i.'month'], $_POST['date_start'.$i.'day'], $_POST['date_start'.$i.'year']); - $endday=dol_mktime(12, 0, 0, $_POST['date_end'.$i.'month'], $_POST['date_end'.$i.'day'], $_POST['date_end'.$i.'year']); - $result=$object->addline($id,$product->description,$product->price, $_POST['qty'.$i], $product->tva_tx, $product->localtax1_tx, $product->localtax2_tx, $_POST['idprod'.$i], $_POST['remise_percent'.$i], $startday, $endday, 0, 0, '', $product->price_base_type, $product->price_ttc, $product->type); - } - } - } - } - } + $result = $object->addline( + $id, + $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, + $date_start, + $date_end, + 0, + $lines[$i]->info_bits, + $lines[$i]->fk_remise_except, + 'HT', + 0, + $product_type, + $lines[$i]->rang, + $lines[$i]->special_code, + $object->origin, + $lines[$i]->rowid, + $fk_parent_line, + $lines[$i]->fk_fournprice, + $lines[$i]->pa_ht, + $label + ); - // End of object creation, we show it - if ($id > 0 && ! $error) - { - $db->commit(); - header('Location: '.$_SERVER["PHP_SELF"].'?facid='.$id); - exit; - } - else - { - $db->rollback(); - $action='create'; - $_GET["origin"]=$_POST["origin"]; - $_GET["originid"]=$_POST["originid"]; - $mesgs[]='
'.$object->error.'
'; - } + 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 + { + $mesgs[]=$srcobject->error; + $error++; + } + } + } + else + { + $mesgs[]=$object->error; + $error++; + } + } + // If some invoice's lines already known + else + { + $id = $object->create($user); + + for ($i = 1; $i <= $NBLINES; $i++) + { + if ($_POST['idprod'.$i]) + { + $product=new Product($db); + $product->fetch($_POST['idprod'.$i]); + $startday=dol_mktime(12, 0, 0, $_POST['date_start'.$i.'month'], $_POST['date_start'.$i.'day'], $_POST['date_start'.$i.'year']); + $endday=dol_mktime(12, 0, 0, $_POST['date_end'.$i.'month'], $_POST['date_end'.$i.'day'], $_POST['date_end'.$i.'year']); + $result=$object->addline($id,$product->description,$product->price, $_POST['qty'.$i], $product->tva_tx, $product->localtax1_tx, $product->localtax2_tx, $_POST['idprod'.$i], $_POST['remise_percent'.$i], $startday, $endday, 0, 0, '', $product->price_base_type, $product->price_ttc, $product->type); + } + } + } + } + } + + // End of object creation, we show it + if ($id > 0 && ! $error) + { + $db->commit(); + header('Location: '.$_SERVER["PHP_SELF"].'?facid='.$id); + exit; + } + else + { + $db->rollback(); + $action='create'; + $_GET["origin"]=$_POST["origin"]; + $_GET["originid"]=$_POST["originid"]; + $mesgs[]='
'.$object->error.'
'; + } } // Add a new line else if (($action == 'addline' || $action == 'addline_predef') && $user->rights->facture->creer) { $langs->load('errors'); - $error = 0; + $error = 0; - $idprod=GETPOST('idprod', 'int'); + $idprod=GETPOST('idprod', 'int'); $product_desc = (GETPOST('product_desc')?GETPOST('product_desc'):(GETPOST('np_desc')?GETPOST('np_desc'):(GETPOST('dp_desc')?GETPOST('dp_desc'):''))); $price_ht = GETPOST('price_ht'); $tva_tx=(GETPOST('tva_tx')?GETPOST('tva_tx'):0); if ((empty($idprod) || GETPOST('usenewaddlineform')) && ($price_ht < 0) && (GETPOST('qty') < 0)) - { - setEventMessage($langs->trans('ErrorBothFieldCantBeNegative', $langs->transnoentitiesnoconv('UnitPriceHT'), $langs->transnoentitiesnoconv('Qty')), 'errors'); - $error++; - } - if (empty($idprod) && GETPOST('type') < 0) - { - setEventMessage($langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv('Type')), 'errors'); - $error++; - } + { + setEventMessage($langs->trans('ErrorBothFieldCantBeNegative', $langs->transnoentitiesnoconv('UnitPriceHT'), $langs->transnoentitiesnoconv('Qty')), 'errors'); + $error++; + } + if (empty($idprod) && GETPOST('type') < 0) + { + setEventMessage($langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv('Type')), 'errors'); + $error++; + } if ((empty($idprod) || GETPOST('usenewaddlineform')) && (!($price_ht >= 0) || $price_ht == '')) // Unit price can be 0 but not '' { setEventMessage($langs->trans("ErrorFieldRequired",$langs->transnoentitiesnoconv("UnitPriceHT")), 'errors'); $error++; } - if (! GETPOST('qty') && GETPOST('qty') == '') - { - setEventMessage($langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv('Qty')), 'errors'); - $error++; - } - if (empty($idprod) && empty($product_desc)) - { - setEventMessage($langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv('Description')), 'errors'); - $error++; - } + if (! GETPOST('qty') && GETPOST('qty') == '') + { + setEventMessage($langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv('Qty')), 'errors'); + $error++; + } + if (empty($idprod) && empty($product_desc)) + { + setEventMessage($langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv('Description')), 'errors'); + $error++; + } - if (! $error && (GETPOST('qty') >= 0) && (! empty($product_desc) || ! empty($idprod))) - { - $ret=$object->fetch($id); - if ($ret < 0) - { - dol_print_error($db,$object->error); - exit; - } - $ret=$object->fetch_thirdparty(); + if (! $error && (GETPOST('qty') >= 0) && (! empty($product_desc) || ! empty($idprod))) + { + $ret=$object->fetch($id); + if ($ret < 0) + { + dol_print_error($db,$object->error); + exit; + } + $ret=$object->fetch_thirdparty(); - // Clean parameters - $predef=((! empty($idprod) && $conf->global->MAIN_FEATURES_LEVEL < 2) ? '_predef' : ''); - $date_start=dol_mktime(GETPOST('date_start'.$predef.'hour'), GETPOST('date_start'.$predef.'min'), GETPOST('date_start'.$predef.'sec'), GETPOST('date_start'.$predef.'month'), GETPOST('date_start'.$predef.'day'), GETPOST('date_start'.$predef.'year')); - $date_end=dol_mktime(GETPOST('date_end'.$predef.'hour'), GETPOST('date_end'.$predef.'min'), GETPOST('date_end'.$predef.'sec'), GETPOST('date_end'.$predef.'month'), GETPOST('date_end'.$predef.'day'), GETPOST('date_end'.$predef.'year')); - $price_base_type = (GETPOST('price_base_type', 'alpha')?GETPOST('price_base_type', 'alpha'):'HT'); + // Clean parameters + $predef=((! empty($idprod) && $conf->global->MAIN_FEATURES_LEVEL < 2) ? '_predef' : ''); + $date_start=dol_mktime(GETPOST('date_start'.$predef.'hour'), GETPOST('date_start'.$predef.'min'), GETPOST('date_start'.$predef.'sec'), GETPOST('date_start'.$predef.'month'), GETPOST('date_start'.$predef.'day'), GETPOST('date_start'.$predef.'year')); + $date_end=dol_mktime(GETPOST('date_end'.$predef.'hour'), GETPOST('date_end'.$predef.'min'), GETPOST('date_end'.$predef.'sec'), GETPOST('date_end'.$predef.'month'), GETPOST('date_end'.$predef.'day'), GETPOST('date_end'.$predef.'year')); + $price_base_type = (GETPOST('price_base_type', 'alpha')?GETPOST('price_base_type', 'alpha'):'HT'); - // Define special_code for special lines - $special_code=0; - //if (empty($_POST['qty'])) $special_code=3; // Options should not exists on invoices + // Define special_code for special lines + $special_code=0; + //if (empty($_POST['qty'])) $special_code=3; // Options should not exists on invoices - // Ecrase $pu par celui du produit - // Ecrase $desc par celui du produit - // Ecrase $txtva par celui du produit - // Ecrase $base_price_type par celui du produit - if (! empty($idprod)) - { - $prod = new Product($db); - $prod->fetch($idprod); + // Ecrase $pu par celui du produit + // Ecrase $desc par celui du produit + // Ecrase $txtva par celui du produit + // Ecrase $base_price_type 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'):''); + $label = ((GETPOST('product_label') && GETPOST('product_label')!=$prod->label)?GETPOST('product_label'):''); - // Update if prices fields are defined - if (GETPOST('usenewaddlineform')) - { - $pu_ht=price2num($price_ht, 'MU'); + // Update if prices fields are defined + if (GETPOST('usenewaddlineform')) + { + $pu_ht=price2num($price_ht, 'MU'); $pu_ttc=price2num(GETPOST('price_ttc'), 'MU'); $tva_npr=(preg_match('/\*/', $tva_tx)?1:0); $tva_tx=str_replace('*','', $tva_tx); $desc = $product_desc; - } - else + } + else { - $tva_tx = get_default_tva($mysoc,$object->client,$prod->id); - $tva_npr = get_default_npr($mysoc,$object->client,$prod->id); + $tva_tx = get_default_tva($mysoc,$object->client,$prod->id); + $tva_npr = get_default_npr($mysoc,$object->client,$prod->id); - // We define price for product - if (! empty($conf->global->PRODUIT_MULTIPRICES) && ! empty($object->client->price_level)) - { - $pu_ht = $prod->multiprices[$object->client->price_level]; - $pu_ttc = $prod->multiprices_ttc[$object->client->price_level]; - $price_min = $prod->multiprices_min[$object->client->price_level]; - $price_base_type = $prod->multiprices_base_type[$object->client->price_level]; - } - else - { - $pu_ht = $prod->price; - $pu_ttc = $prod->price_ttc; - $price_min = $prod->price_min; - $price_base_type = $prod->price_base_type; - } + // We define price for product + if (! empty($conf->global->PRODUIT_MULTIPRICES) && ! empty($object->client->price_level)) + { + $pu_ht = $prod->multiprices[$object->client->price_level]; + $pu_ttc = $prod->multiprices_ttc[$object->client->price_level]; + $price_min = $prod->multiprices_min[$object->client->price_level]; + $price_base_type = $prod->multiprices_base_type[$object->client->price_level]; + } + else + { + $pu_ht = $prod->price; + $pu_ttc = $prod->price_ttc; + $price_min = $prod->price_min; + $price_base_type = $prod->price_base_type; + } - // On reevalue prix selon taux tva car taux tva transaction peut etre different - // de ceux du produit par defaut (par exemple si pays different entre vendeur et acheteur). - if ($tva_tx != $prod->tva_tx) - { - if ($price_base_type != 'HT') - { - $pu_ht = price2num($pu_ttc / (1 + ($tva_tx/100)), 'MU'); - } - else - { - $pu_ttc = price2num($pu_ht * (1 + ($tva_tx/100)), 'MU'); - } - } + // On reevalue prix selon taux tva car taux tva transaction peut etre different + // de ceux du produit par defaut (par exemple si pays different entre vendeur et acheteur). + if ($tva_tx != $prod->tva_tx) + { + if ($price_base_type != 'HT') + { + $pu_ht = price2num($pu_ttc / (1 + ($tva_tx/100)), 'MU'); + } + else + { + $pu_ttc = price2num($pu_ht * (1 + ($tva_tx/100)), 'MU'); + } + } - $desc=''; + $desc=''; - // Define output language - if (! empty($conf->global->MAIN_MULTILANGS) && ! empty($conf->global->PRODUIT_TEXTS_IN_THIRDPARTY_LANGUAGE)) - { - $outputlangs = $langs; - $newlang=''; - if (empty($newlang) && GETPOST('lang_id')) $newlang=GETPOST('lang_id'); - if (empty($newlang)) $newlang=$object->client->default_lang; - if (! empty($newlang)) - { - $outputlangs = new Translate("",$conf); - $outputlangs->setDefaultLang($newlang); - } + // Define output language + if (! empty($conf->global->MAIN_MULTILANGS) && ! empty($conf->global->PRODUIT_TEXTS_IN_THIRDPARTY_LANGUAGE)) + { + $outputlangs = $langs; + $newlang=''; + if (empty($newlang) && GETPOST('lang_id')) $newlang=GETPOST('lang_id'); + if (empty($newlang)) $newlang=$object->client->default_lang; + if (! empty($newlang)) + { + $outputlangs = new Translate("",$conf); + $outputlangs->setDefaultLang($newlang); + } - $desc = (! empty($prod->multilangs[$outputlangs->defaultlang]["description"])) ? $prod->multilangs[$outputlangs->defaultlang]["description"] : $prod->description; - } - else - { - $desc = $prod->description; - } + $desc = (! empty($prod->multilangs[$outputlangs->defaultlang]["description"])) ? $prod->multilangs[$outputlangs->defaultlang]["description"] : $prod->description; + } + else + { + $desc = $prod->description; + } - $desc=dol_concatdesc($desc,$product_desc); + $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); - } - } + // 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'); + $type = $prod->type; + } + else + { + $pu_ht = price2num($price_ht, 'MU'); $pu_ttc = price2num(GETPOST('price_ttc'), 'MU'); $tva_npr = (preg_match('/\*/', $tva_tx)?1:0); $tva_tx = str_replace('*', '', $tva_tx); $label = (GETPOST('product_label')?GETPOST('product_label'):''); $desc = $product_desc; $type = GETPOST('type'); - } + } - // Margin - $fournprice=(GETPOST('fournprice')?GETPOST('fournprice'):''); + // Margin + $fournprice=(GETPOST('fournprice')?GETPOST('fournprice'):''); $buyingprice=(GETPOST('buying_price')?GETPOST('buying_price'):''); - // Local Taxes - $localtax1_tx= get_localtax($tva_tx, 1, $object->client); - $localtax2_tx= get_localtax($tva_tx, 2, $object->client); + // Local Taxes + $localtax1_tx= get_localtax($tva_tx, 1, $object->client); + $localtax2_tx= get_localtax($tva_tx, 2, $object->client); - $info_bits=0; - if ($tva_npr) $info_bits |= 0x01; + $info_bits=0; + if ($tva_npr) $info_bits |= 0x01; - if (! empty($price_min) && (price2num($pu_ht)*(1-price2num(GETPOST('remise_percent'))/100) < price2num($price_min))) - { - $mesg = $langs->trans("CantBeLessThanMinPrice",price2num($price_min,'MU').$langs->getCurrencySymbol($conf->currency)); + if (! empty($price_min) && (price2num($pu_ht)*(1-price2num(GETPOST('remise_percent'))/100) < price2num($price_min))) + { + $mesg = $langs->trans("CantBeLessThanMinPrice",price2num($price_min,'MU').$langs->getCurrencySymbol($conf->currency)); setEventMessage($mesg, 'errors'); - } - else - { - // Insert line - $result = $object->addline( - $id, - $desc, - $pu_ht, - GETPOST('qty'), - $tva_tx, - $localtax1_tx, - $localtax2_tx, - $idprod, - GETPOST('remise_percent'), - $date_start, - $date_end, - 0, - $info_bits, - '', - $price_base_type, - $pu_ttc, - $type, - -1, - $special_code, - '', - 0, - GETPOST('fk_parent_line'), - $fournprice, - $buyingprice, - $label - ); + } + else + { + // Insert line + $result = $object->addline( + $id, + $desc, + $pu_ht, + GETPOST('qty'), + $tva_tx, + $localtax1_tx, + $localtax2_tx, + $idprod, + GETPOST('remise_percent'), + $date_start, + $date_end, + 0, + $info_bits, + '', + $price_base_type, + $pu_ttc, + $type, + -1, + $special_code, + '', + 0, + GETPOST('fk_parent_line'), + $fournprice, + $buyingprice, + $label + ); - if ($result > 0) - { - if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) - { - // Define output language - $outputlangs = $langs; - $newlang=GETPOST('lang_id','alpha'); - if (! empty($conf->global->MAIN_MULTILANGS) && empty($newlang)) $newlang=$object->client->default_lang; - if (! empty($newlang)) - { - $outputlangs = new Translate("",$conf); - $outputlangs->setDefaultLang($newlang); - } + if ($result > 0) + { + if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) + { + // Define output language + $outputlangs = $langs; + $newlang=GETPOST('lang_id','alpha'); + if (! empty($conf->global->MAIN_MULTILANGS) && empty($newlang)) $newlang=$object->client->default_lang; + if (! empty($newlang)) + { + $outputlangs = new Translate("",$conf); + $outputlangs->setDefaultLang($newlang); + } - $ret=$object->fetch($id); // Reload to get new records - facture_pdf_create($db, $object, $object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref); - } + $ret=$object->fetch($id); // Reload to get new records + facture_pdf_create($db, $object, $object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref); + } - unset($_POST['qty']); - unset($_POST['type']); - unset($_POST['idprod']); - unset($_POST['remise_percent']); - unset($_POST['price_ht']); + unset($_POST['qty']); + unset($_POST['type']); + unset($_POST['idprod']); + unset($_POST['remise_percent']); + unset($_POST['price_ht']); unset($_POST['price_ttc']); unset($_POST['tva_tx']); unset($_POST['product_ref']); @@ -1236,99 +1352,99 @@ else if (($action == 'addline' || $action == 'addline_predef') && $user->rights- // old method unset($_POST['np_desc']); unset($_POST['dp_desc']); - } - else - { - setEventMessage($object->error, 'errors'); - } + } + else + { + setEventMessage($object->error, 'errors'); + } - $action=''; - } - } + $action=''; + } + } } else if ($action == 'updateligne' && $user->rights->facture->creer && $_POST['save'] == $langs->trans('Save')) { - if (! $object->fetch($id) > 0) dol_print_error($db); - $object->fetch_thirdparty(); + if (! $object->fetch($id) > 0) dol_print_error($db); + $object->fetch_thirdparty(); - // Clean parameters - $date_start=''; - $date_end=''; - $date_start=dol_mktime(GETPOST('date_starthour'), GETPOST('date_startmin'), GETPOST('date_startsec'), GETPOST('date_startmonth'), GETPOST('date_startday'), GETPOST('date_startyear')); - $date_end=dol_mktime(GETPOST('date_endhour'), GETPOST('date_endmin'), GETPOST('date_endsec'), GETPOST('date_endmonth'), GETPOST('date_endday'), GETPOST('date_endyear')); - $description=dol_htmlcleanlastbr(GETPOST('product_desc')); - $pu_ht=GETPOST('price_ht'); - $vat_rate=(GETPOST('tva_tx')?GETPOST('tva_tx'):0); + // Clean parameters + $date_start=''; + $date_end=''; + $date_start=dol_mktime(GETPOST('date_starthour'), GETPOST('date_startmin'), GETPOST('date_startsec'), GETPOST('date_startmonth'), GETPOST('date_startday'), GETPOST('date_startyear')); + $date_end=dol_mktime(GETPOST('date_endhour'), GETPOST('date_endmin'), GETPOST('date_endsec'), GETPOST('date_endmonth'), GETPOST('date_endday'), GETPOST('date_endyear')); + $description=dol_htmlcleanlastbr(GETPOST('product_desc')); + $pu_ht=GETPOST('price_ht'); + $vat_rate=(GETPOST('tva_tx')?GETPOST('tva_tx'):0); - // Define info_bits - $info_bits=0; - if (preg_match('/\*/', $vat_rate)) $info_bits |= 0x01; + // Define info_bits + $info_bits=0; + if (preg_match('/\*/', $vat_rate)) $info_bits |= 0x01; - // Define vat_rate - $vat_rate=str_replace('*','',$vat_rate); - $localtax1_rate=get_localtax($vat_rate,1,$object->client); - $localtax2_rate=get_localtax($vat_rate,2,$object->client); + // Define vat_rate + $vat_rate=str_replace('*','',$vat_rate); + $localtax1_rate=get_localtax($vat_rate,1,$object->client); + $localtax2_rate=get_localtax($vat_rate,2,$object->client); - // Add buying price + // Add buying price $fournprice=(GETPOST('fournprice')?GETPOST('fournprice'):''); $buyingprice=(GETPOST('buying_price')?GETPOST('buying_price'):''); - // Check minimum price + // Check minimum price $productid = GETPOST('productid', 'int'); - if (! empty($productid)) - { - $product = new Product($db); - $product->fetch($productid); + if (! empty($productid)) + { + $product = new Product($db); + $product->fetch($productid); - $type=$product->type; + $type=$product->type; - $price_min = $product->price_min; - if (! empty($conf->global->PRODUIT_MULTIPRICES) && ! empty($object->client->price_level)) - $price_min = $product->multiprices_min[$object->client->price_level]; + $price_min = $product->price_min; + if (! empty($conf->global->PRODUIT_MULTIPRICES) && ! empty($object->client->price_level)) + $price_min = $product->multiprices_min[$object->client->price_level]; - $label = ((GETPOST('update_label') && GETPOST('product_label')) ? GETPOST('product_label'):''); + $label = ((GETPOST('update_label') && GETPOST('product_label')) ? GETPOST('product_label'):''); - if ($price_min && (price2num($pu_ht)*(1-price2num(GETPOST('remise_percent'))/100) < price2num($price_min))) - { - setEventMessage($langs->trans("CantBeLessThanMinPrice", price2num($price_min,'MU')).$langs->getCurrencySymbol($conf->currency), 'errors'); - $error++; - } - } - else - { - $type = GETPOST('type'); - $label = (GETPOST('product_label') ? GETPOST('product_label'):''); + if ($price_min && (price2num($pu_ht)*(1-price2num(GETPOST('remise_percent'))/100) < price2num($price_min))) + { + setEventMessage($langs->trans("CantBeLessThanMinPrice", price2num($price_min,'MU')).$langs->getCurrencySymbol($conf->currency), 'errors'); + $error++; + } + } + else + { + $type = GETPOST('type'); + $label = (GETPOST('product_label') ? GETPOST('product_label'):''); - // Check parameters - if (GETPOST('type') < 0) { - setEventMessage($langs->trans("ErrorFieldRequired",$langs->transnoentitiesnoconv("Type")), 'errors'); - $error++; - } - } + // Check parameters + if (GETPOST('type') < 0) { + setEventMessage($langs->trans("ErrorFieldRequired",$langs->transnoentitiesnoconv("Type")), 'errors'); + $error++; + } + } // Update line if (! $error) { $result = $object->updateline( - GETPOST('lineid'), - $description, - $pu_ht, - GETPOST('qty'), - GETPOST('remise_percent'), - $date_start, - $date_end, - $vat_rate, - $localtax1_rate, - $localtax2_rate, - 'HT', - $info_bits, - $type, - GETPOST('fk_parent_line'), - 0, - $fournprice, - $buyingprice, - $label + GETPOST('lineid'), + $description, + $pu_ht, + GETPOST('qty'), + GETPOST('remise_percent'), + $date_start, + $date_end, + $vat_rate, + $localtax1_rate, + $localtax2_rate, + 'HT', + $info_bits, + $type, + GETPOST('fk_parent_line'), + 0, + $fournprice, + $buyingprice, + $label ); if ($result >= 0) @@ -1367,295 +1483,297 @@ else if ($action == 'updateligne' && $user->rights->facture->creer && $_POST['sa { setEventMessage($object->error, 'errors'); } - } + } } else if ($action == 'updateligne' && $user->rights->facture->creer && $_POST['cancel'] == $langs->trans('Cancel')) { - header('Location: '.$_SERVER["PHP_SELF"].'?facid='.$id); // Pour reaffichage de la fiche en cours d'edition - exit; + header('Location: '.$_SERVER["PHP_SELF"].'?facid='.$id); // Pour reaffichage de la fiche en cours d'edition + exit; } // Modify line position (up) else if ($action == 'up' && $user->rights->facture->creer) { - $object->fetch($id); - $object->fetch_thirdparty(); - $object->line_up($_GET['rowid']); + $object->fetch($id); + $object->fetch_thirdparty(); + $object->line_up($_GET['rowid']); - // Define output language - $outputlangs = $langs; - $newlang=''; - if ($conf->global->MAIN_MULTILANGS && empty($newlang) && ! empty($_REQUEST['lang_id'])) $newlang=$_REQUEST['lang_id']; - if ($conf->global->MAIN_MULTILANGS && empty($newlang)) $newlang=$object->client->default_lang; - if (! empty($newlang)) - { - $outputlangs = new Translate("",$conf); - $outputlangs->setDefaultLang($newlang); - } - if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) facture_pdf_create($db, $object, $object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref); + // Define output language + $outputlangs = $langs; + $newlang=''; + if ($conf->global->MAIN_MULTILANGS && empty($newlang) && ! empty($_REQUEST['lang_id'])) $newlang=$_REQUEST['lang_id']; + if ($conf->global->MAIN_MULTILANGS && empty($newlang)) $newlang=$object->client->default_lang; + if (! empty($newlang)) + { + $outputlangs = new Translate("",$conf); + $outputlangs->setDefaultLang($newlang); + } + if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) facture_pdf_create($db, $object, $object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref); - header('Location: '.$_SERVER["PHP_SELF"].'?facid='.$object->id.'#'.$_GET['rowid']); - exit; + header('Location: '.$_SERVER["PHP_SELF"].'?facid='.$object->id.'#'.$_GET['rowid']); + exit; } // Modify line position (down) else if ($action == 'down' && $user->rights->facture->creer) { - $object->fetch($id); - $object->fetch_thirdparty(); - $object->line_down($_GET['rowid']); + $object->fetch($id); + $object->fetch_thirdparty(); + $object->line_down($_GET['rowid']); - // Define output language - $outputlangs = $langs; - $newlang=''; - if ($conf->global->MAIN_MULTILANGS && empty($newlang) && ! empty($_REQUEST['lang_id'])) $newlang=$_REQUEST['lang_id']; - if ($conf->global->MAIN_MULTILANGS && empty($newlang)) $newlang=$object->client->default_lang; - if (! empty($newlang)) - { - $outputlangs = new Translate("",$conf); - $outputlangs->setDefaultLang($newlang); - } - if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) facture_pdf_create($db, $object, $object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref); + // Define output language + $outputlangs = $langs; + $newlang=''; + if ($conf->global->MAIN_MULTILANGS && empty($newlang) && ! empty($_REQUEST['lang_id'])) $newlang=$_REQUEST['lang_id']; + if ($conf->global->MAIN_MULTILANGS && empty($newlang)) $newlang=$object->client->default_lang; + if (! empty($newlang)) + { + $outputlangs = new Translate("",$conf); + $outputlangs->setDefaultLang($newlang); + } + if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) facture_pdf_create($db, $object, $object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref); - header('Location: '.$_SERVER["PHP_SELF"].'?facid='.$object->id.'#'.$_GET['rowid']); - exit; + header('Location: '.$_SERVER["PHP_SELF"].'?facid='.$object->id.'#'.$_GET['rowid']); + exit; } /* * Add file in email form - */ +*/ if (GETPOST('addfile')) { - require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; + require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; - // Set tmp user directory - $vardir=$conf->user->dir_output."/".$user->id; - $upload_dir_tmp = $vardir.'/temp'; + // Set tmp user directory + $vardir=$conf->user->dir_output."/".$user->id; + $upload_dir_tmp = $vardir.'/temp'; - dol_add_file_process($upload_dir_tmp,0,0); - $action='presend'; + dol_add_file_process($upload_dir_tmp,0,0); + $action='presend'; } /* * Remove file in email form - */ +*/ if (! empty($_POST['removedfile'])) { - require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; + require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; - // Set tmp user directory - $vardir=$conf->user->dir_output."/".$user->id; - $upload_dir_tmp = $vardir.'/temp'; + // Set tmp user directory + $vardir=$conf->user->dir_output."/".$user->id; + $upload_dir_tmp = $vardir.'/temp'; // TODO Delete only files that was uploaded from email form - dol_remove_file_process($_POST['removedfile'],0); - $action='presend'; + dol_remove_file_process($_POST['removedfile'],0); + $action='presend'; } /* * Send mail - */ +*/ if (($action == 'send' || $action == 'relance') && ! $_POST['addfile'] && ! $_POST['removedfile'] && ! $_POST['cancel']) { - $langs->load('mails'); + $langs->load('mails'); - $actiontypecode='';$subject='';$actionmsg='';$actionmsg2=''; + $actiontypecode='';$subject='';$actionmsg='';$actionmsg2=''; - $result=$object->fetch($id); - $result=$object->fetch_thirdparty(); + $result=$object->fetch($id); + $result=$object->fetch_thirdparty(); - if ($result > 0) - { -// $ref = dol_sanitizeFileName($object->ref); -// $file = $conf->facture->dir_output . '/' . $ref . '/' . $ref . '.pdf'; + if ($result > 0) + { + // $ref = dol_sanitizeFileName($object->ref); + // $file = $conf->facture->dir_output . '/' . $ref . '/' . $ref . '.pdf'; -// if (is_readable($file)) -// { - if ($_POST['sendto']) - { - // Le destinataire a ete fourni via le champ libre - $sendto = $_POST['sendto']; - $sendtoid = 0; - } - elseif ($_POST['receiver'] != '-1') - { - // Recipient was provided from combo list - if ($_POST['receiver'] == 'thirdparty') // Id of third party - { - $sendto = $object->client->email; - $sendtoid = 0; - } - else // Id du contact - { - $sendto = $object->client->contact_get_property($_POST['receiver'],'email'); - $sendtoid = $_POST['receiver']; - } - } + // if (is_readable($file)) + // { + if ($_POST['sendto']) + { + // Le destinataire a ete fourni via le champ libre + $sendto = $_POST['sendto']; + $sendtoid = 0; + } + elseif ($_POST['receiver'] != '-1') + { + // Recipient was provided from combo list + if ($_POST['receiver'] == 'thirdparty') // Id of third party + { + $sendto = $object->client->email; + $sendtoid = 0; + } + else // Id du contact + { + $sendto = $object->client->contact_get_property($_POST['receiver'],'email'); + $sendtoid = $_POST['receiver']; + } + } - if (dol_strlen($sendto)) - { - $langs->load("commercial"); + if (dol_strlen($sendto)) + { + $langs->load("commercial"); - $from = $_POST['fromname'] . ' <' . $_POST['frommail'] .'>'; - $replyto = $_POST['replytoname']. ' <' . $_POST['replytomail'].'>'; - $message = $_POST['message']; - $sendtocc = $_POST['sendtocc']; - $deliveryreceipt = $_POST['deliveryreceipt']; + $from = $_POST['fromname'] . ' <' . $_POST['frommail'] .'>'; + $replyto = $_POST['replytoname']. ' <' . $_POST['replytomail'].'>'; + $message = $_POST['message']; + $sendtocc = $_POST['sendtocc']; + $deliveryreceipt = $_POST['deliveryreceipt']; - if ($action == 'send') - { - if (dol_strlen($_POST['subject'])) $subject = $_POST['subject']; - else $subject = $langs->transnoentities('Bill').' '.$object->ref; - $actiontypecode='AC_FAC'; - $actionmsg=$langs->transnoentities('MailSentBy').' '.$from.' '.$langs->transnoentities('To').' '.$sendto.".\n"; - if ($message) - { - $actionmsg.=$langs->transnoentities('MailTopic').": ".$subject."\n"; - $actionmsg.=$langs->transnoentities('TextUsedInTheMessageBody').":\n"; - $actionmsg.=$message; - } - //$actionmsg2=$langs->transnoentities('Action'.$actiontypecode); - } - if ($action == 'relance') - { - if (dol_strlen($_POST['subject'])) $subject = $_POST['subject']; - else $subject = $langs->transnoentities('Relance facture '.$object->ref); - $actiontypecode='AC_FAC'; - $actionmsg=$langs->transnoentities('MailSentBy').' '.$from.' '.$langs->transnoentities('To').' '.$sendto.".\n"; - if ($message) { - $actionmsg.=$langs->transnoentities('MailTopic').": ".$subject."\n"; - $actionmsg.=$langs->transnoentities('TextUsedInTheMessageBody').":\n"; - $actionmsg.=$message; - } - //$actionmsg2=$langs->transnoentities('Action'.$actiontypecode); - } + if ($action == 'send') + { + if (dol_strlen($_POST['subject'])) $subject = $_POST['subject']; + else $subject = $langs->transnoentities('Bill').' '.$object->ref; + $actiontypecode='AC_FAC'; + $actionmsg=$langs->transnoentities('MailSentBy').' '.$from.' '.$langs->transnoentities('To').' '.$sendto.".\n"; + if ($message) + { + $actionmsg.=$langs->transnoentities('MailTopic').": ".$subject."\n"; + $actionmsg.=$langs->transnoentities('TextUsedInTheMessageBody').":\n"; + $actionmsg.=$message; + } + //$actionmsg2=$langs->transnoentities('Action'.$actiontypecode); + } + if ($action == 'relance') + { + if (dol_strlen($_POST['subject'])) $subject = $_POST['subject']; + else $subject = $langs->transnoentities('Relance facture '.$object->ref); + $actiontypecode='AC_FAC'; + $actionmsg=$langs->transnoentities('MailSentBy').' '.$from.' '.$langs->transnoentities('To').' '.$sendto.".\n"; + if ($message) { + $actionmsg.=$langs->transnoentities('MailTopic').": ".$subject."\n"; + $actionmsg.=$langs->transnoentities('TextUsedInTheMessageBody').":\n"; + $actionmsg.=$message; + } + //$actionmsg2=$langs->transnoentities('Action'.$actiontypecode); + } - // Create form object - include_once DOL_DOCUMENT_ROOT.'/core/class/html.formmail.class.php'; - $formmail = new FormMail($db); + // Create form object + include_once DOL_DOCUMENT_ROOT.'/core/class/html.formmail.class.php'; + $formmail = new FormMail($db); - $attachedfiles=$formmail->get_attached_files(); - $filepath = $attachedfiles['paths']; - $filename = $attachedfiles['names']; - $mimetype = $attachedfiles['mimes']; + $attachedfiles=$formmail->get_attached_files(); + $filepath = $attachedfiles['paths']; + $filename = $attachedfiles['names']; + $mimetype = $attachedfiles['mimes']; - // Send mail - require_once DOL_DOCUMENT_ROOT.'/core/class/CMailFile.class.php'; - $mailfile = new CMailFile($subject,$sendto,$from,$message,$filepath,$mimetype,$filename,$sendtocc,'',$deliveryreceipt,-1); - if ($mailfile->error) - { - $mesgs[]='
'.$mailfile->error.'
'; - } - else - { - $result=$mailfile->sendfile(); - if ($result) - { - $error=0; + // Send mail + require_once DOL_DOCUMENT_ROOT.'/core/class/CMailFile.class.php'; + $mailfile = new CMailFile($subject,$sendto,$from,$message,$filepath,$mimetype,$filename,$sendtocc,'',$deliveryreceipt,-1); + if ($mailfile->error) + { + $mesgs[]='
'.$mailfile->error.'
'; + } + else + { + $result=$mailfile->sendfile(); + if ($result) + { + $error=0; - // Initialisation donnees - $object->sendtoid = $sendtoid; - $object->actiontypecode = $actiontypecode; - $object->actionmsg = $actionmsg; // Long text - $object->actionmsg2 = $actionmsg2; // Short text - $object->fk_element = $object->id; - $object->elementtype = $object->element; + // Initialisation donnees + $object->sendtoid = $sendtoid; + $object->actiontypecode = $actiontypecode; + $object->actionmsg = $actionmsg; // Long text + $object->actionmsg2 = $actionmsg2; // Short text + $object->fk_element = $object->id; + $object->elementtype = $object->element; - // Appel des triggers - include_once DOL_DOCUMENT_ROOT . '/core/class/interfaces.class.php'; - $interface=new Interfaces($db); - $result=$interface->run_triggers('BILL_SENTBYMAIL',$object,$user,$langs,$conf); - if ($result < 0) { $error++; $this->errors=$interface->errors; } - // Fin appel triggers + // Appel des triggers + include_once DOL_DOCUMENT_ROOT . '/core/class/interfaces.class.php'; + $interface=new Interfaces($db); + $result=$interface->run_triggers('BILL_SENTBYMAIL',$object,$user,$langs,$conf); + if ($result < 0) { + $error++; $this->errors=$interface->errors; + } + // Fin appel triggers - if ($error) - { - dol_print_error($db); - } - else - { - // Redirect here - // This avoid sending mail twice if going out and then back to page - $mesg=$langs->trans('MailSuccessfulySent',$mailfile->getValidAddress($from,2),$mailfile->getValidAddress($sendto,2)); - setEventMessage($mesg); - header('Location: '.$_SERVER["PHP_SELF"].'?facid='.$object->id); - exit; - } - } - else - { - $langs->load("other"); - $mesg='
'; - if ($mailfile->error) - { - $mesg.=$langs->trans('ErrorFailedToSendMail',$from,$sendto); - $mesg.='
'.$mailfile->error; - } - else - { - $mesg.='No mail sent. Feature is disabled by option MAIN_DISABLE_ALL_MAILS'; - } - $mesg.='
'; - $mesgs[]=$mesg; - } - } -/* } - else - { - $langs->load("other"); - $mesgs[]='
'.$langs->trans('ErrorMailRecipientIsEmpty').'
'; - dol_syslog('Recipient email is empty'); - }*/ - } - else - { - $langs->load("errors"); - $mesgs[]='
'.$langs->trans('ErrorCantReadFile',$file).'
'; - dol_syslog('Failed to read file: '.$file); - } - } - else - { - $langs->load("other"); - $mesgs[]='
'.$langs->trans('ErrorFailedToReadEntity',$langs->trans("Invoice")).'
'; - dol_syslog('Impossible de lire les donnees de la facture. Le fichier facture n\'a peut-etre pas ete genere.'); - } + if ($error) + { + dol_print_error($db); + } + else + { + // Redirect here + // This avoid sending mail twice if going out and then back to page + $mesg=$langs->trans('MailSuccessfulySent',$mailfile->getValidAddress($from,2),$mailfile->getValidAddress($sendto,2)); + setEventMessage($mesg); + header('Location: '.$_SERVER["PHP_SELF"].'?facid='.$object->id); + exit; + } + } + else + { + $langs->load("other"); + $mesg='
'; + if ($mailfile->error) + { + $mesg.=$langs->trans('ErrorFailedToSendMail',$from,$sendto); + $mesg.='
'.$mailfile->error; + } + else + { + $mesg.='No mail sent. Feature is disabled by option MAIN_DISABLE_ALL_MAILS'; + } + $mesg.='
'; + $mesgs[]=$mesg; + } + } + /* } + else + { + $langs->load("other"); + $mesgs[]='
'.$langs->trans('ErrorMailRecipientIsEmpty').'
'; + dol_syslog('Recipient email is empty'); + }*/ + } + else + { + $langs->load("errors"); + $mesgs[]='
'.$langs->trans('ErrorCantReadFile',$file).'
'; + dol_syslog('Failed to read file: '.$file); + } + } + else + { + $langs->load("other"); + $mesgs[]='
'.$langs->trans('ErrorFailedToReadEntity',$langs->trans("Invoice")).'
'; + dol_syslog('Impossible de lire les donnees de la facture. Le fichier facture n\'a peut-etre pas ete genere.'); + } - $action = 'presend'; + $action = 'presend'; } /* * Generate document - */ +*/ else if ($action == 'builddoc') // En get ou en post { - $object->fetch($id); - $object->fetch_thirdparty(); + $object->fetch($id); + $object->fetch_thirdparty(); - if (GETPOST('model')) $object->setDocModel($user, GETPOST('model')); + if (GETPOST('model')) $object->setDocModel($user, GETPOST('model')); if (GETPOST('fk_bank')) $object->fk_bank=GETPOST('fk_bank'); - // Define output language - $outputlangs = $langs; - $newlang=''; - if ($conf->global->MAIN_MULTILANGS && empty($newlang) && GETPOST('lang_id')) $newlang=GETPOST('lang_id'); - if ($conf->global->MAIN_MULTILANGS && empty($newlang)) $newlang=$object->client->default_lang; - if (! empty($newlang)) - { - $outputlangs = new Translate("",$conf); - $outputlangs->setDefaultLang($newlang); - } - $result=facture_pdf_create($db, $object, $object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref); - if ($result <= 0) - { - dol_print_error($db,$result); - exit; - } - else - { - header('Location: '.$_SERVER["PHP_SELF"].'?facid='.$object->id.(empty($conf->global->MAIN_JUMP_TAG)?'':'#builddoc')); - exit; - } + // Define output language + $outputlangs = $langs; + $newlang=''; + if ($conf->global->MAIN_MULTILANGS && empty($newlang) && GETPOST('lang_id')) $newlang=GETPOST('lang_id'); + if ($conf->global->MAIN_MULTILANGS && empty($newlang)) $newlang=$object->client->default_lang; + if (! empty($newlang)) + { + $outputlangs = new Translate("",$conf); + $outputlangs->setDefaultLang($newlang); + } + $result=facture_pdf_create($db, $object, $object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref); + if ($result <= 0) + { + dol_print_error($db,$result); + exit; + } + else + { + header('Location: '.$_SERVER["PHP_SELF"].'?facid='.$object->id.(empty($conf->global->MAIN_JUMP_TAG)?'':'#builddoc')); + exit; + } } // Remove file in doc form @@ -1767,7 +1885,7 @@ if ($action == 'update_extras') /* * View - */ +*/ $form = new Form($db); $formother=new FormOther($db); @@ -1781,276 +1899,290 @@ llxHeader('',$langs->trans('Bill'),'EN:Customers_Invoices|FR:Factures_Clients|ES /********************************************************************* * - * Mode creation - * - **********************************************************************/ +* Mode creation +* +**********************************************************************/ if ($action == 'create') { - $facturestatic=new Facture($db); - $extralabels=$extrafields->fetch_name_optionals_label('facture'); + $facturestatic=new Facture($db); + $extralabels=$extrafields->fetch_name_optionals_label('facture'); - print_fiche_titre($langs->trans('NewBill')); + print_fiche_titre($langs->trans('NewBill')); - $soc = new Societe($db); - if ($socid>0) $res=$soc->fetch($socid); + $soc = new Societe($db); + if ($socid>0) $res=$soc->fetch($socid); - if (! empty($origin) && ! empty($originid)) - { - // Parse element/subelement (ex: project_task) - $element = $subelement = $origin; - if (preg_match('/^([^_]+)_([^_]+)/i', $origin, $regs)) - { - $element = $regs[1]; - $subelement = $regs[2]; - } - - if ($element == 'project') - { - $projectid=$originid; - } - else - { - // For compatibility - if ($element == 'order' || $element == 'commande') { $element = $subelement = 'commande'; } - if ($element == 'propal') { $element = 'comm/propal'; $subelement = 'propal'; } - if ($element == 'contract') { $element = $subelement = 'contrat'; } - if ($element == 'shipping') { $element = $subelement = 'expedition'; } - - 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:''); - $ref_client = (! empty($objectsrc->ref_client)?$objectsrc->ref_client:''); - $ref_int = (! empty($objectsrc->ref_int)?$objectsrc->ref_int:''); - - $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)); - $dateinvoice = empty($conf->global->MAIN_AUTOFILL_DATE)?-1:0; - } - } - else - { - $cond_reglement_id = $soc->cond_reglement_id; - $mode_reglement_id = $soc->mode_reglement_id; - $remise_percent = $soc->remise_percent; - $remise_absolue = 0; - $dateinvoice = empty($conf->global->MAIN_AUTOFILL_DATE)?-1:0; - } - $absolute_discount=$soc->getAvailableDiscounts(); - - - if (! empty($conf->use_javascript_ajax)) - { - print ajax_combobox('fac_replacement'); - print ajax_combobox('fac_avoir'); - } - - print ''; - print ''; - print ''; - if ($soc->id > 0) - print '' ."\n"; - print ''; - print ''; - print ''; - print ''; - print ''; - - print ''; - - // Ref - print ''; - - // Factures predefinies - if (empty($origin) && empty($originid) && $socid>0) - { - $sql = 'SELECT r.rowid, r.titre, r.total_ttc'; - $sql.= ' FROM '.MAIN_DB_PREFIX.'facture_rec as r'; - $sql.= ' WHERE r.fk_soc = '.$soc->id; - - $resql=$db->query($sql); - if ($resql) - { - $num = $db->num_rows($resql); - $i = 0; - - if ($num > 0) - { - print ''; - } - $db->free($resql); - } - else - { - dol_print_error($db); - } - } - - // Tiers - print ''; - print ''; - if($soc->id > 0) - { - print ''; - } - else - { - print ''; - } - print ''."\n"; - - // Type de facture - $facids=$facturestatic->list_replacable_invoices($soc->id); - if ($facids < 0) - { - dol_print_error($db,$facturestatic); - exit; - } - $options=""; - foreach ($facids as $facparam) - { - $options.=''; - } - - $facids=$facturestatic->list_qualified_avoir_invoices($soc->id); - if ($facids < 0) - { - dol_print_error($db,$facturestatic); - exit; - } - $optionsav=""; - $newinvoice_static=new Facture($db); - foreach ($facids as $key => $valarray) - { - $newinvoice_static->id=$key; - $newinvoice_static->ref=$valarray['ref']; - $newinvoice_static->statut=$valarray['status']; - $newinvoice_static->type=$valarray['type']; - $newinvoice_static->paye=$valarray['paye']; - - $optionsav.=''; - } - - print ''; + } + } - print "
'.$langs->trans('Ref').''.$langs->trans('Draft').'
'.$langs->trans('CreateFromRepeatableInvoice').''; - print '
'.$langs->trans('Customer').''; - print $soc->getNomUrl(1); - print ''; - print ''; - print $form->select_company('','socid','s.client = 1 OR s.client = 3',1); - print '
'.$langs->trans('Type').''; - print ''."\n"; - - // Standard invoice - print ''."\n"; - - // Proforma - if (! empty($conf->global->FACTURE_USE_PROFORMAT)) - { - print ''."\n"; - } - - if (empty($origin)) - { - // Deposit - print ''."\n"; - } - - if ($socid > 0) + if (! empty($origin) && ! empty($originid)) { - // Replacement - print ''."\n"; + // Parse element/subelement (ex: project_task) + $element = $subelement = $origin; + if (preg_match('/^([^_]+)_([^_]+)/i', $origin, $regs)) + { + $element = $regs[1]; + $subelement = $regs[2]; + } + + if ($element == 'project') + { + $projectid=$originid; + } + else + { + // For compatibility + if ($element == 'order' || $element == 'commande') { + $element = $subelement = 'commande'; + } + if ($element == 'propal') { + $element = 'comm/propal'; $subelement = 'propal'; + } + if ($element == 'contract') { + $element = $subelement = 'contrat'; + } + if ($element == 'shipping') { + $element = $subelement = 'expedition'; + } + + 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:''); + $ref_client = (! empty($objectsrc->ref_client)?$objectsrc->ref_client:''); + $ref_int = (! empty($objectsrc->ref_int)?$objectsrc->ref_int:''); + + $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)); + $dateinvoice = empty($conf->global->MAIN_AUTOFILL_DATE)?-1:0; + } + } + else + { + $cond_reglement_id = $soc->cond_reglement_id; + $mode_reglement_id = $soc->mode_reglement_id; + $remise_percent = $soc->remise_percent; + $remise_absolue = 0; + $dateinvoice = empty($conf->global->MAIN_AUTOFILL_DATE)?-1:0; + } + $absolute_discount=$soc->getAvailableDiscounts(); + + + if (! empty($conf->use_javascript_ajax)) + { + print ajax_combobox('fac_replacement'); + print ajax_combobox('fac_avoir'); } - if (empty($origin) && $socid > 0) - { - // Credit note - print ''."\n"; - } + print ''; + print ''; + print ''; + if ($soc->id > 0) + print '' ."\n"; + print ''; + print ''; + print ''; + print ''; + print ''; + + print '
'; - print ''; - print ''; - $desc=$form->textwithpicto($langs->trans("InvoiceStandardAsk"),$langs->transnoentities("InvoiceStandardDesc"),1); - print $desc; - print '
'; - print ''; - print ''; - $desc=$form->textwithpicto($langs->trans("InvoiceProForma"),$langs->transnoentities("InvoiceProFormaDesc"),1); - print $desc; - print '
'; - print ''; - print ''; - $desc=$form->textwithpicto($langs->trans("InvoiceDeposit"),$langs->transnoentities("InvoiceDepositDesc"),1); - print $desc; - print '
'; - print ''; - print ''; - $text=$langs->trans("InvoiceReplacementAsk").' '; - $text.=''; - $desc=$form->textwithpicto($text,$langs->transnoentities("InvoiceReplacementDesc"),1); - print $desc; - print '
'; - print ''; - print ''; - $text=$langs->transnoentities("InvoiceAvoirAsk").' '; - // $text.=''; - $text.=''; - $desc=$form->textwithpicto($text,$langs->transnoentities("InvoiceAvoirDesc"),1); - print $desc; - print '
'; + + // Ref + print ''; + + // Factures predefinies + if (empty($origin) && empty($originid) && $socid>0) + { + $sql = 'SELECT r.rowid, r.titre, r.total_ttc'; + $sql.= ' FROM '.MAIN_DB_PREFIX.'facture_rec as r'; + $sql.= ' WHERE r.fk_soc = '.$soc->id; + + $resql=$db->query($sql); + if ($resql) + { + $num = $db->num_rows($resql); + $i = 0; + + if ($num > 0) + { + print ''; + } + $db->free($resql); + } + else + { + dol_print_error($db); + } + } + + // Tiers + print ''; + print ''; + if($soc->id > 0) + { + print ''; + } + else + { + print ''; + } + print ''."\n"; + + // Type de facture + $facids=$facturestatic->list_replacable_invoices($soc->id); + if ($facids < 0) + { + dol_print_error($db,$facturestatic); + exit; + } + $options=""; + foreach ($facids as $facparam) + { + $options.=''; + } + + $facids=$facturestatic->list_qualified_avoir_invoices($soc->id); + if ($facids < 0) + { + dol_print_error($db,$facturestatic); + exit; + } + $optionsav=""; + $newinvoice_static=new Facture($db); + foreach ($facids as $key => $valarray) + { + $newinvoice_static->id=$key; + $newinvoice_static->ref=$valarray['ref']; + $newinvoice_static->statut=$valarray['status']; + $newinvoice_static->type=$valarray['type']; + $newinvoice_static->paye=$valarray['paye']; + + $optionsav.=''; + } + + print ''; @@ -2061,7 +2193,7 @@ if ($action == 'create') print ''; } - // Date invoice - print ''; + // Date invoice + print ''; - // Payment term - print ''; + // Payment term + print ''; - // Payment mode - print ''; + // Payment mode + print ''; - // Project - if (! empty($conf->projet->enabled) && $socid>0) - { - $langs->load('projects'); - print ''; - } + // Project + if (! empty($conf->projet->enabled) && $socid>0) + { + $langs->load('projects'); + print ''; + } - // Other attributes - $parameters=array('objectsrc' => $objectsrc, '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'); - } + // Other attributes + $parameters=array('objectsrc' => $objectsrc, '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'); + } - // Modele PDF - print ''; - print '"; + // Modele PDF + print ''; + print '"; - // Public note - print ''; - print ''; - print ''; + print ''; + print ''; + //print ''; - // Private note - if (empty($user->societe_id)) - { - print ''; - print ''; - print ''; - } + // Private note + if (empty($user->societe_id)) + { + print ''; + print ''; + print ''; + } - 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); - } + 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 "\n"; + print "\n"; + print ''."\n"; + print ''."\n"; + print ''."\n"; + print ''; + print ''; - $newclassname=$classname; - if ($newclassname == 'Propal') $newclassname = 'CommercialProposal'; - elseif ($newclassname == 'Commande') $newclassname = 'Order'; + $newclassname=$classname; + if ($newclassname == 'Propal') $newclassname = 'CommercialProposal'; + elseif ($newclassname == 'Commande') $newclassname = 'Order'; - print ''; - print ''; - print '"; - if ($mysoc->localtax1_assuj=="1") //Localtax1 RE - { - print '"; - } + print ''; + print ''; + print '"; + if ($mysoc->localtax1_assuj=="1") //Localtax1 RE + { + print '"; + } - if ($mysoc->localtax2_assuj=="1") //Localtax2 IRPF - { - print '"; - } - print '"; - } - else - { - // Show deprecated optional form to add product line here - if (! empty($conf->global->PRODUCT_SHOW_WHEN_CREATE)) - { - print '"; + } + print '"; + } + else + { + // Show deprecated optional form to add product line here + if (! empty($conf->global->PRODUCT_SHOW_WHEN_CREATE)) + { + print ''; - } - } + print '
'.$langs->trans('Ref').''.$langs->trans('Draft').'
'.$langs->trans('CreateFromRepeatableInvoice').''; + print '
'.$langs->trans('Customer').''; + print $soc->getNomUrl(1); + print ''; + print ''; + print $form->select_company('','socid','s.client = 1 OR s.client = 3',1); + print '
'.$langs->trans('Type').''; + print ''."\n"; + + // Standard invoice + print ''."\n"; + + // Proforma + if (! empty($conf->global->FACTURE_USE_PROFORMAT)) + { + print ''."\n"; + } + + if ((empty($origin)) || (($origin=='propal') && (!empty($originid)))) + { + // Deposit + print ''."\n"; + } + + if ($socid > 0) + { + // Replacement + print ''."\n"; + } + + if (empty($origin) && $socid > 0) + { + // Credit note + print ''."\n"; + } print '
'; + print ''; + print ''; + $desc=$form->textwithpicto($langs->trans("InvoiceStandardAsk"),$langs->transnoentities("InvoiceStandardDesc"),1); + print $desc; + print '
'; + print ''; + print ''; + $desc=$form->textwithpicto($langs->trans("InvoiceProForma"),$langs->transnoentities("InvoiceProFormaDesc"),1); + print $desc; + print '
'; + print ''; + print ''; + $desc=$form->textwithpicto($langs->trans("InvoiceDeposit"),$langs->transnoentities("InvoiceDepositDesc"),1); + print ''; + if (($origin=='propal') ) { + print ''; + print '
'.$desc.''.$langs->trans('Value').':'; + } + print '
'; + print '
'; + print ''; + print ''; + $text=$langs->trans("InvoiceReplacementAsk").' '; + $text.=''; + $desc=$form->textwithpicto($text,$langs->transnoentities("InvoiceReplacementDesc"),1); + print $desc; + print '
'; + print ''; + print ''; + $text=$langs->transnoentities("InvoiceAvoirAsk").' '; + // $text.=''; + $text.=''; + $desc=$form->textwithpicto($text,$langs->transnoentities("InvoiceAvoirDesc"),1); + print $desc; + print '
'; print '
'.$langs->trans('Discounts').''; if ($soc->remise_client) print $langs->trans("CompanyHasRelativeDiscount",''.$soc->remise_client.''); else print $langs->trans("CompanyHasNoRelativeDiscount"); - print ' ('.$langs->trans("EditRelativeDiscount").')'; + print ' ('.$langs->trans("EditRelativeDiscount").')'; print '. '; print '
'; if ($absolute_discount) print $langs->trans("CompanyHasAbsoluteDiscount",''.price($absolute_discount).'',$langs->trans("Currency".$conf->currency)); @@ -2071,481 +2203,527 @@ if ($action == 'create') print '
'.$langs->trans('Date').''; - $form->select_date($dateinvoice,'','','','',"add",1,1); - print '
'.$langs->trans('Date').''; + $form->select_date($dateinvoice,'','','','',"add",1,1); + print '
'.$langs->trans('PaymentConditionsShort').''; - $form->select_conditions_paiements(isset($_POST['cond_reglement_id'])?$_POST['cond_reglement_id']:$cond_reglement_id,'cond_reglement_id'); - print '
'.$langs->trans('PaymentConditionsShort').''; + $form->select_conditions_paiements(isset($_POST['cond_reglement_id'])?$_POST['cond_reglement_id']:$cond_reglement_id,'cond_reglement_id'); + print '
'.$langs->trans('PaymentMode').''; - $form->select_types_paiements(isset($_POST['mode_reglement_id'])?$_POST['mode_reglement_id']:$mode_reglement_id,'mode_reglement_id'); - print '
'.$langs->trans('PaymentMode').''; + $form->select_types_paiements(isset($_POST['mode_reglement_id'])?$_POST['mode_reglement_id']:$mode_reglement_id,'mode_reglement_id'); + print '
'.$langs->trans('Project').''; - select_projects($soc->id, $projectid, 'projectid'); - print '
'.$langs->trans('Project').''; + select_projects($soc->id, $projectid, 'projectid'); + print '
'.$langs->trans('Model').''; - include_once DOL_DOCUMENT_ROOT.'/core/modules/facture/modules_facture.php'; - $liste=ModelePDFFactures::liste_modeles($db); - print $form->selectarray('model',$liste,$conf->global->FACTURE_ADDON_PDF); - print "
'.$langs->trans('Model').''; + include_once DOL_DOCUMENT_ROOT.'/core/modules/facture/modules_facture.php'; + $liste=ModelePDFFactures::liste_modeles($db); + print $form->selectarray('model',$liste,$conf->global->FACTURE_ADDON_PDF); + print "
'.$langs->trans('NotePublic').''; - $note_public=''; - if (is_object($objectsrc)) // Take value from source object - { - $note_public=$objectsrc->note_public; - } - $doleditor = new DolEditor('note_public', $note_public, '', 80, 'dolibarr_notes', 'In', 0, false, true, ROWS_3, 70); - print $doleditor->Create(1); + // Public note + print '
'.$langs->trans('NotePublic').''; + $note_public=''; + if (is_object($objectsrc)) // Take value from source object + { + $note_public=$objectsrc->note_public; + } + $doleditor = new DolEditor('note_public', $note_public, '', 80, 'dolibarr_notes', 'In', 0, false, true, ROWS_3, 70); + print $doleditor->Create(1); - //print '
'.$langs->trans('NotePrivate').''; - $note_private=''; - if (! empty($origin) && ! empty($originid) && is_object($objectsrc)) // Take value from source object - { - $note_private=$objectsrc->note_private; - } - $doleditor = new DolEditor('note_private', $note_private, '', 80, 'dolibarr_notes', 'In', 0, false, true, ROWS_3, 70); - print $doleditor->Create(1); - //print '
'.$langs->trans('NotePrivate').''; + $note_private=''; + if (! empty($origin) && ! empty($originid) && is_object($objectsrc)) // Take value from source object + { + $note_private=$objectsrc->note_private; + } + $doleditor = new DolEditor('note_private', $note_private, '', 80, 'dolibarr_notes', 'In', 0, false, true, ROWS_3, 70); + print $doleditor->Create(1); + //print '
'.$langs->trans($newclassname).''.$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->trans($newclassname).''.$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)."
'; + if ($mysoc->localtax2_assuj=="1") //Localtax2 IRPF + { + print '
'.$langs->transcountry("AmountLT2",$mysoc->country_code).''.price($objectsrc->total_localtax2)."
'.$langs->trans('TotalTTC').''.price($objectsrc->total_ttc)."
'; - // Zone de choix des produits predefinis a la creation - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - if (! empty($conf->service->enabled)) - { - print ''; - } - print ''; - for ($i = 1 ; $i <= $NBLINES ; $i++) - { - print ''; - print ''; - print ''; - print ''; - print ''; - // Si le module service est actif, on propose des dates de debut et fin a la ligne - if (! empty($conf->service->enabled)) - { - print ''; - } - print "\n"; - } + // Zone de choix des produits predefinis a la creation + print '
'.$langs->trans('ProductsAndServices').''.$langs->trans('Qty').''.$langs->trans('ReductionShort').'     '.$langs->trans('ServiceLimitedDuration').'
'; - // multiprix - if (! empty($conf->global->PRODUIT_MULTIPRICES)) - $form->select_produits('','idprod'.$i,'',$conf->product->limit_size,$soc->price_level); - else - $form->select_produits('','idprod'.$i,'',$conf->product->limit_size); - print '% '; - print ''; - print ''; - print '
'; - print $langs->trans('From').' '; - print ''; - print $form->select_date('','date_start'.$i,$usehm,$usehm,1,"add"); - print '
'; - print $langs->trans('to').' '; - print ''; - print $form->select_date('','date_end'.$i,$usehm,$usehm,1,"add"); - print '
'; - print '
'; + print ''; + print ''; + print ''; + print ''; + print ''; + if (! empty($conf->service->enabled)) + { + print ''; + } + print ''; + for ($i = 1 ; $i <= $NBLINES ; $i++) + { + print ''; + print ''; + print ''; + print ''; + print ''; + // Si le module service est actif, on propose des dates de debut et fin a la ligne + if (! empty($conf->service->enabled)) + { + print ''; + } + print "\n"; + } - print '
'.$langs->trans('ProductsAndServices').''.$langs->trans('Qty').''.$langs->trans('ReductionShort').'     '.$langs->trans('ServiceLimitedDuration').'
'; + // multiprix + if (! empty($conf->global->PRODUIT_MULTIPRICES)) + $form->select_produits('','idprod'.$i,'',$conf->product->limit_size,$soc->price_level); + else + $form->select_produits('','idprod'.$i,'',$conf->product->limit_size); + print '% '; + print ''; + print ''; + print '
'; + print $langs->trans('From').' '; + print ''; + print $form->select_date('','date_start'.$i,$usehm,$usehm,1,"add"); + print '
'; + print $langs->trans('to').' '; + print ''; + print $form->select_date('','date_end'.$i,$usehm,$usehm,1,"add"); + print '
'; + print '
'; - print '
'; + print '
\n"; + print "\n"; - // Button "Create Draft" - print '
'; + // Button "Create Draft" + print '
'; - print "\n"; + print "\n"; - // Show origin lines - if (! empty($origin) && ! empty($originid) && is_object($objectsrc)) - { - print '
'; + // Show origin lines + if (! empty($origin) && ! empty($originid) && is_object($objectsrc)) + { + print '
'; - $title=$langs->trans('ProductsAndServices'); - print_titre($title); + $title=$langs->trans('ProductsAndServices'); + print_titre($title); - print ''; + print '
'; - $objectsrc->printOriginLinesList(); + $objectsrc->printOriginLinesList(); - print '
'; - } + print ''; + } } else if ($id > 0 || ! empty($ref)) { - /* - * Show object in view mode - */ + /* + * Show object in view mode + */ - $result=$object->fetch($id,$ref); + $result=$object->fetch($id,$ref); - // fetch optionals attributes and labels - $extralabels=$extrafields->fetch_name_optionals_label('facture'); + // fetch optionals attributes and labels + $extralabels=$extrafields->fetch_name_optionals_label('facture'); - if ($result > 0) - { - if ($user->societe_id>0 && $user->societe_id!=$object->socid) accessforbidden('',0); + if ($result > 0) + { + if ($user->societe_id>0 && $user->societe_id!=$object->socid) accessforbidden('',0); - $result=$object->fetch_thirdparty(); + $result=$object->fetch_thirdparty(); - $soc = new Societe($db); - $soc->fetch($object->socid); - $selleruserevenustamp=$mysoc->useRevenueStamp(); + $soc = new Societe($db); + $soc->fetch($object->socid); + $selleruserevenustamp=$mysoc->useRevenueStamp(); - $totalpaye = $object->getSommePaiement(); - $totalcreditnotes = $object->getSumCreditNotesUsed(); - $totaldeposits = $object->getSumDepositsUsed(); - //print "totalpaye=".$totalpaye." totalcreditnotes=".$totalcreditnotes." totaldeposts=".$totaldeposits." selleruserrevenuestamp=".$selleruserevenustamp; + $totalpaye = $object->getSommePaiement(); + $totalcreditnotes = $object->getSumCreditNotesUsed(); + $totaldeposits = $object->getSumDepositsUsed(); + //print "totalpaye=".$totalpaye." totalcreditnotes=".$totalcreditnotes." totaldeposts=".$totaldeposits." selleruserrevenuestamp=".$selleruserevenustamp; - // We can also use bcadd to avoid pb with floating points - // For example print 239.2 - 229.3 - 9.9; does not return 0. - //$resteapayer=bcadd($object->total_ttc,$totalpaye,$conf->global->MAIN_MAX_DECIMALS_TOT); - //$resteapayer=bcadd($resteapayer,$totalavoir,$conf->global->MAIN_MAX_DECIMALS_TOT); - $resteapayer = price2num($object->total_ttc - $totalpaye - $totalcreditnotes - $totaldeposits,'MT'); + // We can also use bcadd to avoid pb with floating points + // For example print 239.2 - 229.3 - 9.9; does not return 0. + //$resteapayer=bcadd($object->total_ttc,$totalpaye,$conf->global->MAIN_MAX_DECIMALS_TOT); + //$resteapayer=bcadd($resteapayer,$totalavoir,$conf->global->MAIN_MAX_DECIMALS_TOT); + $resteapayer = price2num($object->total_ttc - $totalpaye - $totalcreditnotes - $totaldeposits,'MT'); - if ($object->paye) $resteapayer=0; - $resteapayeraffiche=$resteapayer; + if ($object->paye) $resteapayer=0; + $resteapayeraffiche=$resteapayer; - if (! empty($conf->global->FACTURE_DEPOSITS_ARE_JUST_PAYMENTS)) - { - $filterabsolutediscount="fk_facture_source IS NULL"; // If we want deposit to be substracted to payments only and not to total of final invoice - $filtercreditnote="fk_facture_source IS NOT NULL"; // If we want deposit to be substracted to payments only and not to total of final invoice - } - else - { - $filterabsolutediscount="fk_facture_source IS NULL OR (fk_facture_source IS NOT NULL AND description='(DEPOSIT)')"; - $filtercreditnote="fk_facture_source IS NOT NULL AND description <> '(DEPOSIT)'"; - } + if (! empty($conf->global->FACTURE_DEPOSITS_ARE_JUST_PAYMENTS)) + { + $filterabsolutediscount="fk_facture_source IS NULL"; // If we want deposit to be substracted to payments only and not to total of final invoice + $filtercreditnote="fk_facture_source IS NOT NULL"; // If we want deposit to be substracted to payments only and not to total of final invoice + } + else + { + $filterabsolutediscount="fk_facture_source IS NULL OR (fk_facture_source IS NOT NULL AND description='(DEPOSIT)')"; + $filtercreditnote="fk_facture_source IS NOT NULL AND description <> '(DEPOSIT)'"; + } - $absolute_discount=$soc->getAvailableDiscounts('',$filterabsolutediscount); - $absolute_creditnote=$soc->getAvailableDiscounts('',$filtercreditnote); - $absolute_discount=price2num($absolute_discount,'MT'); - $absolute_creditnote=price2num($absolute_creditnote,'MT'); + $absolute_discount=$soc->getAvailableDiscounts('',$filterabsolutediscount); + $absolute_creditnote=$soc->getAvailableDiscounts('',$filtercreditnote); + $absolute_discount=price2num($absolute_discount,'MT'); + $absolute_creditnote=price2num($absolute_creditnote,'MT'); - $author = new User($db); - if ($object->user_author) - { - $author->fetch($object->user_author); - } + $author = new User($db); + if ($object->user_author) + { + $author->fetch($object->user_author); + } - $objectidnext=$object->getIdReplacingInvoice(); + $objectidnext=$object->getIdReplacingInvoice(); - $head = facture_prepare_head($object); + $head = facture_prepare_head($object); - dol_fiche_head($head, 'compta', $langs->trans('InvoiceCustomer'), 0, 'bill'); + dol_fiche_head($head, 'compta', $langs->trans('InvoiceCustomer'), 0, 'bill'); - $formconfirm=''; + $formconfirm=''; - // Confirmation de la conversion de l'avoir en reduc - if ($action == 'converttoreduc') - { - $text=$langs->trans('ConfirmConvertToReduc'); - $formconfirm=$form->formconfirm($_SERVER['PHP_SELF'].'?facid='.$object->id,$langs->trans('ConvertToReduc'),$text,'confirm_converttoreduc','',"yes",2); - } + // Confirmation de la conversion de l'avoir en reduc + if ($action == 'converttoreduc') + { + $text=$langs->trans('ConfirmConvertToReduc'); + $formconfirm=$form->formconfirm($_SERVER['PHP_SELF'].'?facid='.$object->id,$langs->trans('ConvertToReduc'),$text,'confirm_converttoreduc','',"yes",2); + } - // Confirmation to delete invoice - if ($action == 'delete') - { - $text=$langs->trans('ConfirmDeleteBill'); - $formconfirm=$form->formconfirm($_SERVER['PHP_SELF'].'?facid='.$object->id,$langs->trans('DeleteBill'),$text,'confirm_delete','',0,1); - } + // Confirmation to delete invoice + if ($action == 'delete') + { + $text=$langs->trans('ConfirmDeleteBill',$object->ref); + $formquestion=array(); - // Confirmation de la validation - if ($action == 'valid') - { - // on verifie si l'objet est en numerotation provisoire - $objectref = substr($object->ref, 1, 4); - if ($objectref == 'PROV') - { - $savdate=$object->date; - if (! empty($conf->global->FAC_FORCE_DATE_VALIDATION)) - { - $object->date=dol_now(); - $object->date_lim_reglement=$object->calculate_date_lim_reglement(); - } - $numref = $object->getNextNumRef($soc); - //$object->date=$savdate; - } - else - { - $numref = $object->ref; - } + $qualified_for_stock_change=0; + if (empty($conf->global->STOCK_SUPPORTS_SERVICES)) + { + $qualified_for_stock_change=$object->hasProductsOrServices(2); + } + else + { + $qualified_for_stock_change=$object->hasProductsOrServices(1); + } - $text=$langs->trans('ConfirmValidateBill',$numref); - if (! empty($conf->notification->enabled)) - { - require_once DOL_DOCUMENT_ROOT .'/core/class/notify.class.php'; - $notify=new Notify($db); - $text.='
'; - $text.=$notify->confirmMessage('NOTIFY_VAL_FAC',$object->socid); - } - $formquestion=array(); + if ($object->type != 3 && ! empty($conf->global->STOCK_CALCULATE_ON_BILL) && $qualified_for_stock_change && $object->statut>=1) + { + $langs->load("stocks"); + require_once DOL_DOCUMENT_ROOT.'/product/class/html.formproduct.class.php'; + $formproduct=new FormProduct($db); + $label=$object->type==2?$langs->trans("SelectWarehouseForStockDecrease"):$langs->trans("SelectWarehouseForStockIncrease"); + $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' => 'idwarehouse', 'label' => $label, 'value' => $formproduct->selectWarehouses(GETPOST('idwarehouse'),'idwarehouse','',1,0,0,$langs->trans("NoStockAction")))); + $formconfirm=$form->formconfirm($_SERVER['PHP_SELF'].'?facid='.$object->id,$langs->trans('DeleteBill'),$text,'confirm_delete',$formquestion,"yes",1); + }else { + $formconfirm=$form->formconfirm($_SERVER['PHP_SELF'].'?facid='.$object->id,$langs->trans('DeleteBill'),$text,'confirm_delete','','',1); + } + } - if ($object->type != 3 && ! empty($conf->global->STOCK_CALCULATE_ON_BILL) && $object->hasProductsOrServices(1)) - { - $langs->load("stocks"); - require_once DOL_DOCUMENT_ROOT.'/product/class/html.formproduct.class.php'; - $formproduct=new FormProduct($db); - $label=$object->type==2?$langs->trans("SelectWarehouseForStockIncrease"):$langs->trans("SelectWarehouseForStockDecrease"); - $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' => 'idwarehouse', 'label' => $label, 'value' => $formproduct->selectWarehouses(GETPOST('idwarehouse'),'idwarehouse','',1))); - } - if ($object->type != 2 && $object->total_ttc < 0) // Can happen only if $conf->global->FACTURE_ENABLE_NEGATIVE is on - { - $text.='
'.img_warning().' '.$langs->trans("ErrorInvoiceOfThisTypeMustBePositive"); - } - $formconfirm=$form->formconfirm($_SERVER["PHP_SELF"].'?facid='.$object->id,$langs->trans('ValidateBill'),$text,'confirm_valid',$formquestion,(($object->type != 2 && $object->total_ttc < 0)?"no":"yes"),($conf->notification->enabled?0:2)); - } + // Confirmation de la validation + if ($action == 'valid') + { + // on verifie si l'objet est en numerotation provisoire + $objectref = substr($object->ref, 1, 4); + if ($objectref == 'PROV') + { + $savdate=$object->date; + if (! empty($conf->global->FAC_FORCE_DATE_VALIDATION)) + { + $object->date=dol_now(); + $object->date_lim_reglement=$object->calculate_date_lim_reglement(); + } + $numref = $object->getNextNumRef($soc); + //$object->date=$savdate; + } + else + { + $numref = $object->ref; + } - // Confirm back to draft status - if ($action == 'modif') - { - $text=$langs->trans('ConfirmUnvalidateBill',$object->ref); - $formquestion=array(); - if ($object->type != 3 && ! empty($conf->global->STOCK_CALCULATE_ON_BILL) && $object->hasProductsOrServices(1)) - { - $langs->load("stocks"); - require_once DOL_DOCUMENT_ROOT.'/product/class/html.formproduct.class.php'; - $formproduct=new FormProduct($db); - $label=$object->type==2?$langs->trans("SelectWarehouseForStockDecrease"):$langs->trans("SelectWarehouseForStockIncrease"); - $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' => 'idwarehouse', 'label' => $label, 'value' => $formproduct->selectWarehouses(GETPOST('idwarehouse'),'idwarehouse','',1))); - } + $text=$langs->trans('ConfirmValidateBill',$numref); + if (! empty($conf->notification->enabled)) + { + require_once DOL_DOCUMENT_ROOT .'/core/class/notify.class.php'; + $notify=new Notify($db); + $text.='
'; + $text.=$notify->confirmMessage('BILL_VALIDATE',$object->socid); + } + $formquestion=array(); - $formconfirm=$form->formconfirm($_SERVER["PHP_SELF"].'?facid='.$object->id,$langs->trans('UnvalidateBill'),$text,'confirm_modif',$formquestion,"yes",1); - } + $qualified_for_stock_change=0; + if (empty($conf->global->STOCK_SUPPORTS_SERVICES)) + { + $qualified_for_stock_change=$object->hasProductsOrServices(2); + } + else + { + $qualified_for_stock_change=$object->hasProductsOrServices(1); + } - // Confirmation du classement paye - if ($action == 'paid' && $resteapayer <= 0) - { - $formconfirm=$form->formconfirm($_SERVER["PHP_SELF"].'?facid='.$object->id,$langs->trans('ClassifyPaid'),$langs->trans('ConfirmClassifyPaidBill',$object->ref),'confirm_paid','',"yes",1); - } - if ($action == 'paid' && $resteapayer > 0) - { - // Code - $i=0; - $close[$i]['code']='discount_vat';$i++; - $close[$i]['code']='badcustomer';$i++; - // Help - $i=0; - $close[$i]['label']=$langs->trans("HelpEscompte").'

'.$langs->trans("ConfirmClassifyPaidPartiallyReasonDiscountVatDesc");$i++; - $close[$i]['label']=$langs->trans("ConfirmClassifyPaidPartiallyReasonBadCustomerDesc");$i++; - // Texte - $i=0; - $close[$i]['reason']=$form->textwithpicto($langs->transnoentities("ConfirmClassifyPaidPartiallyReasonDiscountVat",$resteapayer,$langs->trans("Currency".$conf->currency)),$close[$i]['label'],1);$i++; - $close[$i]['reason']=$form->textwithpicto($langs->transnoentities("ConfirmClassifyPaidPartiallyReasonBadCustomer",$resteapayer,$langs->trans("Currency".$conf->currency)),$close[$i]['label'],1);$i++; - // arrayreasons[code]=reason - foreach($close as $key => $val) - { - $arrayreasons[$close[$key]['code']]=$close[$key]['reason']; - } + if ($object->type != 3 && ! empty($conf->global->STOCK_CALCULATE_ON_BILL) && $qualified_for_stock_change) + { + $langs->load("stocks"); + require_once DOL_DOCUMENT_ROOT.'/product/class/html.formproduct.class.php'; + $formproduct=new FormProduct($db); + $label=$object->type==2?$langs->trans("SelectWarehouseForStockIncrease"):$langs->trans("SelectWarehouseForStockDecrease"); + $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' => 'idwarehouse', 'label' => $label, 'value' => $formproduct->selectWarehouses(GETPOST('idwarehouse'),'idwarehouse','',1))); + } + if ($object->type != 2 && $object->total_ttc < 0) // Can happen only if $conf->global->FACTURE_ENABLE_NEGATIVE is on + { + $text.='
'.img_warning().' '.$langs->trans("ErrorInvoiceOfThisTypeMustBePositive"); + } + $formconfirm=$form->formconfirm($_SERVER["PHP_SELF"].'?facid='.$object->id,$langs->trans('ValidateBill'),$text,'confirm_valid',$formquestion,(($object->type != 2 && $object->total_ttc < 0)?"no":"yes"),($conf->notification->enabled?0:2)); + } - // Cree un tableau formulaire - $formquestion=array( + // Confirm back to draft status + if ($action == 'modif') + { + $text=$langs->trans('ConfirmUnvalidateBill',$object->ref); + $formquestion=array(); + + $qualified_for_stock_change=0; + if (empty($conf->global->STOCK_SUPPORTS_SERVICES)) + { + $qualified_for_stock_change=$object->hasProductsOrServices(2); + } + else + { + $qualified_for_stock_change=$object->hasProductsOrServices(1); + } + if ($object->type != 3 && ! empty($conf->global->STOCK_CALCULATE_ON_BILL) && $qualified_for_stock_change) + { + $langs->load("stocks"); + require_once DOL_DOCUMENT_ROOT.'/product/class/html.formproduct.class.php'; + $formproduct=new FormProduct($db); + $label=$object->type==2?$langs->trans("SelectWarehouseForStockDecrease"):$langs->trans("SelectWarehouseForStockIncrease"); + $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' => 'idwarehouse', 'label' => $label, 'value' => $formproduct->selectWarehouses(GETPOST('idwarehouse'),'idwarehouse','',1))); + } + + $formconfirm=$form->formconfirm($_SERVER["PHP_SELF"].'?facid='.$object->id,$langs->trans('UnvalidateBill'),$text,'confirm_modif',$formquestion,"yes",1); + } + + // Confirmation du classement paye + if ($action == 'paid' && $resteapayer <= 0) + { + $formconfirm=$form->formconfirm($_SERVER["PHP_SELF"].'?facid='.$object->id,$langs->trans('ClassifyPaid'),$langs->trans('ConfirmClassifyPaidBill',$object->ref),'confirm_paid','',"yes",1); + } + if ($action == 'paid' && $resteapayer > 0) + { + // Code + $i=0; + $close[$i]['code']='discount_vat';$i++; + $close[$i]['code']='badcustomer';$i++; + // Help + $i=0; + $close[$i]['label']=$langs->trans("HelpEscompte").'

'.$langs->trans("ConfirmClassifyPaidPartiallyReasonDiscountVatDesc");$i++; + $close[$i]['label']=$langs->trans("ConfirmClassifyPaidPartiallyReasonBadCustomerDesc");$i++; + // Texte + $i=0; + $close[$i]['reason']=$form->textwithpicto($langs->transnoentities("ConfirmClassifyPaidPartiallyReasonDiscountVat",$resteapayer,$langs->trans("Currency".$conf->currency)),$close[$i]['label'],1);$i++; + $close[$i]['reason']=$form->textwithpicto($langs->transnoentities("ConfirmClassifyPaidPartiallyReasonBadCustomer",$resteapayer,$langs->trans("Currency".$conf->currency)),$close[$i]['label'],1);$i++; + // arrayreasons[code]=reason + foreach($close as $key => $val) + { + $arrayreasons[$close[$key]['code']]=$close[$key]['reason']; + } + + // Cree un tableau formulaire + $formquestion=array( 'text' => $langs->trans("ConfirmClassifyPaidPartiallyQuestion"), - array('type' => 'radio', 'name' => 'close_code', 'label' => $langs->trans("Reason"), 'values' => $arrayreasons), - array('type' => 'text', 'name' => 'close_note', 'label' => $langs->trans("Comment"), 'value' => '', 'size' => '100') - ); - // Paiement incomplet. On demande si motif = escompte ou autre - $formconfirm=$form->formconfirm($_SERVER["PHP_SELF"].'?facid='.$object->id,$langs->trans('ClassifyPaid'),$langs->trans('ConfirmClassifyPaidPartially',$object->ref),'confirm_paid_partially',$formquestion,"yes"); - } + array('type' => 'radio', 'name' => 'close_code', 'label' => $langs->trans("Reason"), 'values' => $arrayreasons), + array('type' => 'text', 'name' => 'close_note', 'label' => $langs->trans("Comment"), 'value' => '', 'size' => '100') + ); + // Paiement incomplet. On demande si motif = escompte ou autre + $formconfirm=$form->formconfirm($_SERVER["PHP_SELF"].'?facid='.$object->id,$langs->trans('ClassifyPaid'),$langs->trans('ConfirmClassifyPaidPartially',$object->ref),'confirm_paid_partially',$formquestion,"yes"); + } - // Confirmation du classement abandonne - if ($action == 'canceled') - { - // S'il y a une facture de remplacement pas encore validee (etat brouillon), - // on ne permet pas de classer abandonner la facture. - if ($objectidnext) - { - $facturereplacement=new Facture($db); - $facturereplacement->fetch($objectidnext); - $statusreplacement=$facturereplacement->statut; - } - if ($objectidnext && $statusreplacement == 0) - { - print '
'.$langs->trans("ErrorCantCancelIfReplacementInvoiceNotValidated").'
'; - } - else - { - // Code - $close[1]['code']='badcustomer'; - $close[2]['code']='abandon'; - // Help - $close[1]['label']=$langs->trans("ConfirmClassifyPaidPartiallyReasonBadCustomerDesc"); - $close[2]['label']=$langs->trans("ConfirmClassifyAbandonReasonOtherDesc"); - // Texte - $close[1]['reason']=$form->textwithpicto($langs->transnoentities("ConfirmClassifyPaidPartiallyReasonBadCustomer",$object->ref),$close[1]['label'],1); - $close[2]['reason']=$form->textwithpicto($langs->transnoentities("ConfirmClassifyAbandonReasonOther"),$close[2]['label'],1); - // arrayreasons - $arrayreasons[$close[1]['code']]=$close[1]['reason']; - $arrayreasons[$close[2]['code']]=$close[2]['reason']; + // Confirmation du classement abandonne + if ($action == 'canceled') + { + // S'il y a une facture de remplacement pas encore validee (etat brouillon), + // on ne permet pas de classer abandonner la facture. + if ($objectidnext) + { + $facturereplacement=new Facture($db); + $facturereplacement->fetch($objectidnext); + $statusreplacement=$facturereplacement->statut; + } + if ($objectidnext && $statusreplacement == 0) + { + print '
'.$langs->trans("ErrorCantCancelIfReplacementInvoiceNotValidated").'
'; + } + else + { + // Code + $close[1]['code']='badcustomer'; + $close[2]['code']='abandon'; + // Help + $close[1]['label']=$langs->trans("ConfirmClassifyPaidPartiallyReasonBadCustomerDesc"); + $close[2]['label']=$langs->trans("ConfirmClassifyAbandonReasonOtherDesc"); + // Texte + $close[1]['reason']=$form->textwithpicto($langs->transnoentities("ConfirmClassifyPaidPartiallyReasonBadCustomer",$object->ref),$close[1]['label'],1); + $close[2]['reason']=$form->textwithpicto($langs->transnoentities("ConfirmClassifyAbandonReasonOther"),$close[2]['label'],1); + // arrayreasons + $arrayreasons[$close[1]['code']]=$close[1]['reason']; + $arrayreasons[$close[2]['code']]=$close[2]['reason']; - // Cree un tableau formulaire - $formquestion=array( + // Cree un tableau formulaire + $formquestion=array( 'text' => $langs->trans("ConfirmCancelBillQuestion"), - array('type' => 'radio', 'name' => 'close_code', 'label' => $langs->trans("Reason"), 'values' => $arrayreasons), - array('type' => 'text', 'name' => 'close_note', 'label' => $langs->trans("Comment"), 'value' => '', 'size' => '100') - ); + array('type' => 'radio', 'name' => 'close_code', 'label' => $langs->trans("Reason"), 'values' => $arrayreasons), + array('type' => 'text', 'name' => 'close_note', 'label' => $langs->trans("Comment"), 'value' => '', 'size' => '100') + ); - $formconfirm=$form->formconfirm($_SERVER['PHP_SELF'].'?facid='.$object->id,$langs->trans('CancelBill'),$langs->trans('ConfirmCancelBill',$object->ref),'confirm_canceled',$formquestion,"yes"); - } - } + $formconfirm=$form->formconfirm($_SERVER['PHP_SELF'].'?facid='.$object->id,$langs->trans('CancelBill'),$langs->trans('ConfirmCancelBill',$object->ref),'confirm_canceled',$formquestion,"yes"); + } + } - // Confirmation de la suppression d'une ligne produit - if ($action == 'ask_deleteline') - { - $formconfirm=$form->formconfirm($_SERVER["PHP_SELF"].'?facid='.$object->id.'&lineid='.$lineid, $langs->trans('DeleteProductLine'), $langs->trans('ConfirmDeleteProductLine'), 'confirm_deleteline', '', 'no', 1); - } + // Confirmation de la suppression d'une ligne produit + if ($action == 'ask_deleteline') + { + $formconfirm=$form->formconfirm($_SERVER["PHP_SELF"].'?facid='.$object->id.'&lineid='.$lineid, $langs->trans('DeleteProductLine'), $langs->trans('ConfirmDeleteProductLine'), 'confirm_deleteline', '', 'no', 1); + } - // 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) - ); - // Paiement incomplet. On demande si motif = escompte ou autre - $formconfirm=$form->formconfirm($_SERVER["PHP_SELF"].'?facid='.$object->id,$langs->trans('CloneInvoice'),$langs->trans('ConfirmCloneInvoice',$object->ref),'confirm_clone',$formquestion,'yes',1); - } + // 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) + ); + // Paiement incomplet. On demande si motif = escompte ou autre + $formconfirm=$form->formconfirm($_SERVER["PHP_SELF"].'?facid='.$object->id,$langs->trans('CloneInvoice'),$langs->trans('ConfirmCloneInvoice',$object->ref),'confirm_clone',$formquestion,'yes',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 - } + 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 form confirm + print $formconfirm; - // Invoice content + // Invoice content - print ''; + print '
'; - $linkback = ''.$langs->trans("BackToList").''; + $linkback = ''.$langs->trans("BackToList").''; - // Ref - print ''; - print ''; + // Ref + print ''; + print ''; // Ref customer - print ''; - print ''; + print ''; - // Third party - print ''; - - // Type - print ''; - - // Relative and absolute discounts - $addrelativediscount=''.$langs->trans("EditRelativeDiscounts").''; - $addabsolutediscount=''.$langs->trans("EditGlobalDiscounts").''; - $addcreditnote=''.$langs->trans("AddCreditNote").''; - - print ''; - - // Date invoice - print ''; - - - /* - * List of payments - */ - - $sign=1; - if ($object->type == 2) $sign=-1; - - $nbrows=8; $nbcols=2; - if (! empty($conf->projet->enabled)) $nbrows++; - if (! empty($conf->banque->enabled)) $nbcols++; - if($mysoc->localtax1_assuj=="1") $nbrows++; - if($mysoc->localtax2_assuj=="1") $nbrows++; - if ($selleruserevenustamp) $nbrows++; - - print ''; - - // Conditions de reglement - print ''; - - // Date payment term - print ''; - - // Payment mode - print ''; - - // Amount - print ''; - print ''; - print ''; print ''; - // Amount Local Taxes - if ($mysoc->localtax1_assuj=="1" && $mysoc->useLocalTax(1)) //Localtax1 (example RE) - { - print ''; - print ''; - } - if ($mysoc->localtax2_assuj=="1" && $mysoc->useLocalTax(2)) //Localtax2 (example IRPF) - { - print ''; - print ''; - } - - // Revenue stamp - if ($selleruserevenustamp) // Test company use revenue stamp - { - print ''; - } - - // Total with tax - print ''; - - // Statut - print ''; - print ''; - - // Project - if (! empty($conf->projet->enabled)) - { - $langs->load('projects'); - print ''; - print ''; - print ''; - } - - // Other attributes - $res=$object->fetch_optionals($object->id,$extralabels); - $parameters=array('colspan' => ' colspan="2"'); - $reshook=$hookmanager->executeHooks('formObjectOptions',$parameters,$object,$action); // Note that $action and $object may have been modified by hook - if (empty($reshook) && ! empty($extrafields->attribute_label)) - { - - if ($action == 'edit_extras') - { - print ''; - print ''; - print ''; - print ''; - } - - foreach($extrafields->attribute_label as $key=>$label) - { - $value=(isset($_POST["options_".$key])?$_POST["options_".$key]:$object->array_options["options_".$key]); - if ($extrafields->attribute_type[$key] == 'separate') - { - print $extrafields->showSeparator($key); - } - else - { - print 'attribute_required[$key])) print ' class="fieldrequired"'; - print '>'.$label.''."\n"; - } - } - - if(count($extrafields->attribute_label) > 0) { - - if ($action == 'edit_extras' && $user->rights->facture->creer) - { - print ''; - - } - else { - if ($object->statut == 0 && $user->rights->facture->creer) - { - print ''; - } - } - } - } - - print '
'.$langs->trans('Ref').''; - $morehtmlref=''; - $discount=new DiscountAbsolute($db); - $result=$discount->fetch(0,$object->id); - if ($result > 0) - { - $morehtmlref=' ('.$langs->trans("CreditNoteConvertedIntoDiscount",$discount->getNomUrl(1,'discount')).')'; - } - if ($result < 0) - { - dol_print_error('',$discount->error); - } - print $form->showrefnav($object, 'ref', $linkback, 1, 'facnumber', 'ref', $morehtmlref); - print '
'.$langs->trans('Ref').''; + $morehtmlref=''; + $discount=new DiscountAbsolute($db); + $result=$discount->fetch(0,$object->id); + if ($result > 0) + { + $morehtmlref=' ('.$langs->trans("CreditNoteConvertedIntoDiscount",$discount->getNomUrl(1,'discount')).')'; + } + if ($result < 0) + { + dol_print_error('',$discount->error); + } + print $form->showrefnav($object, 'ref', $linkback, 1, 'facnumber', 'ref', $morehtmlref); + print '
'; - print ''; - if ($action != 'refclient' && ! empty($object->brouillon)) print ''; - print '
'; - print $langs->trans('RefCustomer'); - print ''.img_edit($langs->trans('Modify')).'
'; - print '
'; - if ($user->rights->facture->creer && $action == 'refclient') + print '
'; + print ''; + if ($action != 'refclient' && ! empty($object->brouillon)) print ''; + print '
'; + print $langs->trans('RefCustomer'); + print ''.img_edit($langs->trans('Modify')).'
'; + print '
'; + if ($user->rights->facture->creer && $action == 'refclient') { print '
'; print ''; @@ -2560,1050 +2738,1050 @@ else if ($id > 0 || ! empty($ref)) } print '
'; - print ''; - print ''; - print ''; - print '
'.$langs->trans('Company').''; - if (! empty($conf->global->FACTURE_CHANGE_THIRDPARTY) && $action != 'editthirdparty' && $object->brouillon && $user->rights->facture->creer) - print 'id.'">'.img_edit($langs->trans('SetLinkToThirdParty'),1).'
'; - print '
'; - if ($action == 'editthirdparty') - { - $form->form_thirdparty($_SERVER['PHP_SELF'].'?facid='.$object->id,$object->socid,'socid'); - } - else - { - print '  '.$soc->getNomUrl(1,'compta'); - print '   ('.$langs->trans('OtherBills').')'; - } - print '
'.$langs->trans('Type').''; - print $object->getLibType(); - if ($object->type == 1) - { - $facreplaced=new Facture($db); - $facreplaced->fetch($object->fk_facture_source); - print ' ('.$langs->transnoentities("ReplaceInvoice",$facreplaced->getNomUrl(1)).')'; - } - if ($object->type == 2) - { - $facusing=new Facture($db); - $facusing->fetch($object->fk_facture_source); - print ' ('.$langs->transnoentities("CorrectInvoice",$facusing->getNomUrl(1)).')'; - } - - $facidavoir=$object->getListIdAvoirFromInvoice(); - if (count($facidavoir) > 0) - { - print ' ('.$langs->transnoentities("InvoiceHasAvoir"); - $i=0; - foreach($facidavoir as $id) - { - if ($i==0) print ' '; - else print ','; - $facavoir=new Facture($db); - $facavoir->fetch($id); - print $facavoir->getNomUrl(1); - } - print ')'; - } - if ($objectidnext > 0) - { - $facthatreplace=new Facture($db); - $facthatreplace->fetch($objectidnext); - print ' ('.$langs->transnoentities("ReplacedByInvoice",$facthatreplace->getNomUrl(1)).')'; - } - print '
'.$langs->trans('Discounts'); - print ''; - if ($soc->remise_client) print $langs->trans("CompanyHasRelativeDiscount",$soc->remise_client); - else print $langs->trans("CompanyHasNoRelativeDiscount"); - //print ' ('.$addrelativediscount.')'; - - if ($absolute_discount > 0) - { - print '. '; - if ($object->statut > 0 || $object->type == 2 || $object->type == 3) - { - if ($object->statut == 0) - { - print $langs->trans("CompanyHasAbsoluteDiscount",price($absolute_discount),$langs->transnoentities("Currency".$conf->currency)); - print '. '; - } - else - { - if ($object->statut < 1 || $object->type == 2 || $object->type == 3) - { - $text=$langs->trans("CompanyHasAbsoluteDiscount",price($absolute_discount),$langs->transnoentities("Currency".$conf->currency)); - print '
'.$text.'.
'; - } - else - { - $text=$langs->trans("CompanyHasAbsoluteDiscount",price($absolute_discount),$langs->transnoentities("Currency".$conf->currency)); - $text2=$langs->trans("AbsoluteDiscountUse"); - print $form->textwithpicto($text,$text2); - } - } - } - else - { - // Remise dispo de type remise fixe (not credit note) - print '
'; - $form->form_remise_dispo($_SERVER["PHP_SELF"].'?facid='.$object->id, GETPOST('discountid'), 'remise_id', $soc->id, $absolute_discount, $filterabsolutediscount, $resteapayer, ' ('.$addabsolutediscount.')'); - } - } - else - { - if ($absolute_creditnote > 0) // If not, link will be added later - { - if ($object->statut == 0 && $object->type != 2 && $object->type != 3) print ' ('.$addabsolutediscount.')
'; - else print '. '; - } - else print '. '; - } - if ($absolute_creditnote > 0) - { - // If validated, we show link "add credit note to payment" - if ($object->statut != 1 || $object->type == 2 || $object->type == 3) - { - if ($object->statut == 0 && $object->type != 3) - { - $text=$langs->trans("CompanyHasCreditNote",price($absolute_creditnote),$langs->transnoentities("Currency".$conf->currency)); - print $form->textwithpicto($text,$langs->trans("CreditNoteDepositUse")); - } - else - { - print $langs->trans("CompanyHasCreditNote",price($absolute_creditnote),$langs->transnoentities("Currency".$conf->currency)).'.'; - } - } - else - { - // Remise dispo de type avoir - if (! $absolute_discount) print '
'; - //$form->form_remise_dispo($_SERVER["PHP_SELF"].'?facid='.$object->id, 0, 'remise_id_for_payment', $soc->id, $absolute_creditnote, $filtercreditnote, $resteapayer); - $form->form_remise_dispo($_SERVER["PHP_SELF"].'?facid='.$object->id, 0, 'remise_id_for_payment', $soc->id, $absolute_creditnote, $filtercreditnote, 0); // We must allow credit not even if amount is higher - } - } - if (! $absolute_discount && ! $absolute_creditnote) - { - print $langs->trans("CompanyHasNoAbsoluteDiscount"); - if ($object->statut == 0 && $object->type != 2 && $object->type != 3) print ' ('.$addabsolutediscount.')
'; - else print '. '; - } - /*if ($object->statut == 0 && $object->type != 2 && $object->type != 3) - { - if (! $absolute_discount && ! $absolute_creditnote) print '
'; - //print '   -   '; - print $addabsolutediscount; - //print '   -   '.$addcreditnote; // We disbale link to credit note - }*/ - print '
'; - print ''; - if ($object->type != 2 && $action != 'editinvoicedate' && ! empty($object->brouillon) && $user->rights->facture->creer) print ''; - print '
'; - print $langs->trans('Date'); - print 'id.'">'.img_edit($langs->trans('SetDate'),1).'
'; - print '
'; - - if ($object->type != 2) - { - if ($action == 'editinvoicedate') - { - $form->form_date($_SERVER['PHP_SELF'].'?facid='.$object->id,$object->date,'invoicedate'); - } - else - { - print dol_print_date($object->date,'daytext'); - } - } - else - { - print dol_print_date($object->date,'daytext'); - } - print ''; - - print ''; - - // List of payments already done - print ''; - print ''; - print ''; - if (! empty($conf->banque->enabled)) print ''; - print ''; - print ''; - print ''; - - $var=true; - - // Payments already done (from payment on this invoice) - $sql = 'SELECT p.datep as dp, p.num_paiement, p.rowid, p.fk_bank,'; - $sql.= ' c.code as payment_code, c.libelle as payment_label,'; - $sql.= ' pf.amount,'; - $sql.= ' ba.rowid as baid, ba.ref, ba.label'; - $sql.= ' FROM '.MAIN_DB_PREFIX.'c_paiement as c, '.MAIN_DB_PREFIX.'paiement_facture as pf, '.MAIN_DB_PREFIX.'paiement as p'; - $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'bank as b ON p.fk_bank = b.rowid'; - $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'bank_account as ba ON b.fk_account = ba.rowid'; - $sql.= ' WHERE pf.fk_facture = '.$object->id.' AND p.fk_paiement = c.id AND pf.fk_paiement = p.rowid'; - $sql.= ' ORDER BY p.datep, p.tms'; - - $result = $db->query($sql); - if ($result) - { - $num = $db->num_rows($result); - $i = 0; - - //if ($object->type != 2) - //{ - if ($num > 0) - { - while ($i < $num) - { - $objp = $db->fetch_object($result); - $var=!$var; - print ''; - $label=($langs->trans("PaymentType".$objp->payment_code)!=("PaymentType".$objp->payment_code))?$langs->trans("PaymentType".$objp->payment_code):$objp->payment_label; - print ''; - if (! empty($conf->banque->enabled)) - { - $bankaccountstatic->id=$objp->baid; - $bankaccountstatic->ref=$objp->ref; - $bankaccountstatic->label=$objp->ref; - print ''; - } - print ''; - print ''; - print ''; - $i++; - } - } - else - { - print ''; - } - //} - $db->free($result); - } - else - { - dol_print_error($db); - } - - if ($object->type != 2) - { - // Total already paid - print ''; - - $resteapayeraffiche=$resteapayer; - - // Loop on each credit note or deposit amount applied - $creditnoteamount=0; - $depositamount=0; - $sql = "SELECT re.rowid, re.amount_ht, re.amount_tva, re.amount_ttc,"; - $sql.= " re.description, re.fk_facture_source"; - $sql.= " FROM ".MAIN_DB_PREFIX ."societe_remise_except as re"; - $sql.= " WHERE fk_facture = ".$object->id; - $resql=$db->query($sql); - if ($resql) - { - $num = $db->num_rows($resql); - $i = 0; - $invoice=new Facture($db); - while ($i < $num) - { - $obj = $db->fetch_object($resql); - $invoice->fetch($obj->fk_facture_source); - print ''; - print ''; - print ''; - $i++; - if ($invoice->type == 2) $creditnoteamount += $obj->amount_ttc; - if ($invoice->type == 3) $depositamount += $obj->amount_ttc; - } - } - else - { - dol_print_error($db); - } - - // Paye partiellement 'escompte' - if (($object->statut == 2 || $object->statut == 3) && $object->close_code == 'discount_vat') - { - print ''; - $resteapayeraffiche=0; - } - // Paye partiellement ou Abandon 'badcustomer' - if (($object->statut == 2 || $object->statut == 3) && $object->close_code == 'badcustomer') - { - print ''; - //$resteapayeraffiche=0; - } - // Paye partiellement ou Abandon 'product_returned' - if (($object->statut == 2 || $object->statut == 3) && $object->close_code == 'product_returned') - { - print ''; - $resteapayeraffiche=0; - } - // Paye partiellement ou Abandon 'abandon' - if (($object->statut == 2 || $object->statut == 3) && $object->close_code == 'abandon') - { - print ''; - $resteapayeraffiche=0; - } - - // Billed - print ''; - - // Remainder to pay - print ''; - print ''; - print ''; - } - else // Credit note - { - // Total already paid back - print ''; - - // Billed - print ''; - - // Remainder to pay back - print ''; - print ''; - print ''; - - // Sold credit note - //print ''; - //print ''; - } - - print '
'.($object->type == 2 ? $langs->trans("PaymentsBack") : $langs->trans('Payments')).''.$langs->trans('Type').''.$langs->trans('BankAccount').''.$langs->trans('Amount').' 
'; - print ''.img_object($langs->trans('ShowPayment'),'payment').' '; - print dol_print_date($db->jdate($objp->dp),'day').''.$label.' '.$objp->num_paiement.''; - if ($bankaccountstatic->id) print $bankaccountstatic->getNomUrl(1,'transactions'); - print ''.price($sign * $objp->amount).' 
'.$langs->trans("None").'
'; - if ($object->type != 3) print $langs->trans('AlreadyPaidNoCreditNotesNoDeposits'); - else print $langs->trans('AlreadyPaid'); - print ' :'.price($totalpaye).' 
'; - if ($invoice->type == 2) print $langs->trans("CreditNote").' '; - if ($invoice->type == 3) print $langs->trans("Deposit").' '; - print $invoice->getNomUrl(0); - print ' :'.price($obj->amount_ttc).''; - print 'rowid.'">'.img_delete().''; - print '
'; - print $form->textwithpicto($langs->trans("Discount").':',$langs->trans("HelpEscompte"),-1); - print ''.price($object->total_ttc - $creditnoteamount - $depositamount - $totalpaye).' 
'; - print $form->textwithpicto($langs->trans("Abandoned").':',$langs->trans("HelpAbandonBadCustomer"),-1); - print ''.price($object->total_ttc - $creditnoteamount - $depositamount - $totalpaye).' 
'; - print $form->textwithpicto($langs->trans("ProductReturned").':',$langs->trans("HelpAbandonProductReturned"),-1); - print ''.price($object->total_ttc - $creditnoteamount - $depositamount - $totalpaye).' 
'; - $text=$langs->trans("HelpAbandonOther"); - if ($object->close_note) $text.='

'.$langs->trans("Reason").':'.$object->close_note; - print $form->textwithpicto($langs->trans("Abandoned").':',$text,-1); - print '
'.price($object->total_ttc - $creditnoteamount - $depositamount - $totalpaye).' 
'.$langs->trans("Billed").' :'.price($object->total_ttc).' 
'; - if ($resteapayeraffiche >= 0) print $langs->trans('RemainderToPay'); - else print $langs->trans('ExcessReceived'); - print ' :'.price($resteapayeraffiche).' 
'; - print $langs->trans('AlreadyPaidBack'); - print ' :'.price($sign * $totalpaye).' 
'.$langs->trans("Billed").' :'.price($sign * $object->total_ttc).' 
'; - if ($resteapayeraffiche <= 0) print $langs->trans('RemainderToPayBack'); - else print $langs->trans('ExcessPaydBack'); - print ' :'.price($sign * $resteapayeraffiche).' 
'.$langs->trans('TotalTTC').' :'.price($sign * $object->total_ttc).' 
'; - - // Margin Infos - if (! empty($conf->margin->enabled)) + // Third party + print '
'; + print ''; + print ''; + print ''; + print '
'.$langs->trans('Company').''; + if (! empty($conf->global->FACTURE_CHANGE_THIRDPARTY) && $action != 'editthirdparty' && $object->brouillon && $user->rights->facture->creer) + print 'id.'">'.img_edit($langs->trans('SetLinkToThirdParty'),1).'
'; + print '
'; + if ($action == 'editthirdparty') { - print '
'; - $object->displayMarginInfos($object->statut > 0); + $form->form_thirdparty($_SERVER['PHP_SELF'].'?facid='.$object->id,$object->socid,'socid'); + } + else + { + print '  '.$soc->getNomUrl(1,'compta'); + print '   ('.$langs->trans('OtherBills').')'; } - - print '
'; - print ''; - if ($object->type != 2 && $action != 'editconditions' && ! empty($object->brouillon) && $user->rights->facture->creer) print ''; - print '
'; - print $langs->trans('PaymentConditionsShort'); - print 'id.'">'.img_edit($langs->trans('SetConditions'),1).'
'; - print '
'; - if ($object->type != 2) - { - if ($action == 'editconditions') - { - $form->form_conditions_reglement($_SERVER['PHP_SELF'].'?facid='.$object->id,$object->cond_reglement_id,'cond_reglement_id'); - } - else - { - $form->form_conditions_reglement($_SERVER['PHP_SELF'].'?facid='.$object->id,$object->cond_reglement_id,'none'); - } - } - else - { - print ' '; - } - print '
'; - print ''; - if ($object->type != 2 && $action != 'editpaymentterm' && ! empty($object->brouillon) && $user->rights->facture->creer) print ''; - print '
'; - print $langs->trans('DateMaxPayment'); - print 'id.'">'.img_edit($langs->trans('SetDate'),1).'
'; - print '
'; - if ($object->type != 2) - { - if ($action == 'editpaymentterm') - { - $form->form_date($_SERVER['PHP_SELF'].'?facid='.$object->id,$object->date_lim_reglement,'paymentterm'); - } - else - { - print dol_print_date($object->date_lim_reglement,'daytext'); - if ($object->date_lim_reglement < ($now - $conf->facture->client->warning_delay) && ! $object->paye && $object->statut == 1 && ! isset($object->am)) print img_warning($langs->trans('Late')); - } - } - else - { - print ' '; - } - print '
'; - print ''; - if ($action != 'editmode' && ! empty($object->brouillon) && $user->rights->facture->creer) print ''; - print '
'; - print $langs->trans('PaymentMode'); - print 'id.'">'.img_edit($langs->trans('SetMode'),1).'
'; - print '
'; - if ($action == 'editmode') - { - $form->form_modes_reglement($_SERVER['PHP_SELF'].'?facid='.$object->id,$object->mode_reglement_id,'mode_reglement_id'); - } - else - { - $form->form_modes_reglement($_SERVER['PHP_SELF'].'?facid='.$object->id,$object->mode_reglement_id,'none'); - } - print '
'.$langs->trans('AmountHT').''.price($object->total_ht,1,'',1,-1,-1,$conf->currency).'
'.$langs->trans('AmountVAT').''.price($object->total_tva,1,'',1,-1,-1,$conf->currency).'
'.$langs->transcountry("AmountLT1",$mysoc->country_code).''.price($object->total_localtax1,1,'',1,-1,-1,$conf->currency).'
'.$langs->transcountry("AmountLT2",$mysoc->country_code).''.price($object->total_localtax2,1,'',1,-1,-1,$conf->currency).'
'; - print ''; - if ($action != 'editrevenuestamp' && ! empty($object->brouillon) && $user->rights->facture->creer) print ''; - print '
'; - print $langs->trans('RevenueStamp'); - print 'id.'">'.img_edit($langs->trans('SetRevenuStamp'),1).'
'; - print '
'; - if ($action == 'editrevenuestamp') - { - print ''; - print ''; - print ''; - print $formother->select_revenue_stamp(GETPOST('revenuestamp'), 'revenuestamp', $mysoc->country_code); - //print ''; - print ' '; - print ''; - } - else - { - print price($object->revenuestamp,1,'',1,-1,-1,$conf->currency); - } - print '
'.$langs->trans('AmountTTC').''.price($object->total_ttc,1,'',1,-1,-1,$conf->currency).'
'.$langs->trans('Status').''.($object->getLibStatut(4,$totalpaye)).'
'; - - print ''; - if ($action != 'classify') - { - print ''; - } - print '
'; - print $langs->trans('Project'); - print 'id.'">'; - print img_edit($langs->trans('SetProject'),1); - print '
'; - - print '
'; - if ($action == 'classify') - { - $form->form_project($_SERVER['PHP_SELF'].'?facid='.$object->id,$object->socid,$object->fk_project,'projectid'); - } - else - { - $form->form_project($_SERVER['PHP_SELF'].'?facid='.$object->id,$object->socid,$object->fk_project,'none'); - } - print '
'; - // Convert date into timestamp format - if (in_array($extrafields->attribute_type[$key],array('date','datetime'))) - { - $value = isset($_POST["options_".$key])?dol_mktime($_POST["options_".$key."hour"], $_POST["options_".$key."min"], 0, $_POST["options_".$key."month"], $_POST["options_".$key."day"], $_POST["options_".$key."year"]):$object->array_options['options_'.$key]; - } - - if ($action == 'edit_extras' && $user->rights->facture->creer) - { - print $extrafields->showInputField($key,$value); - } - else - { - print $extrafields->showOutputField($key,$value); - } - print '
'; - print ''; - print ''; - print '
'.img_picto('','edit').' '.$langs->trans('Modify').'

'; - - 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 - */ - $result = $object->getLinesArray(); - - if (! empty($conf->use_javascript_ajax) && $object->statut == 0) - { - include DOL_DOCUMENT_ROOT.'/core/tpl/ajaxrow.tpl.php'; - } - - print ''; - - // Show object lines - if (! empty($object->lines)) - $ret=$object->printObjectLines($action,$mysoc,$soc,$lineid,1); - - /* - * Form to add new line - */ - if ($object->statut == 0 && $user->rights->facture->creer && $action <> 'valid' && $action <> 'editline') - { - $var=true; - - if ($conf->global->MAIN_FEATURES_LEVEL > 1) - { - // Add free or predefined products/services - $object->formAddObjectLine(1,$mysoc,$soc); - } - else - { - // Add free products/services - $object->formAddFreeProduct(1,$mysoc,$soc); - - // Add predefined products/services - if (! empty($conf->product->enabled) || ! empty($conf->service->enabled)) - { - $var=!$var; - $object->formAddPredefinedProduct(1,$mysoc,$soc); - } - } - - $parameters=array(); - $reshook=$hookmanager->executeHooks('formAddObjectLine',$parameters,$object,$action); // Note that $action and $object may have been modified by hook - } - - print "
\n"; - - print "\n"; - - - /* - * Boutons actions - */ - - if ($action != 'prerelance' && $action != 'presend') - { - if ($user->societe_id == 0 && $action <> 'valid' && $action <> 'editline') - { - print '
'; - - // Editer une facture deja validee, sans paiement effectue et pas exporte en compta - if ($object->statut == 1) - { - // On verifie si les lignes de factures ont ete exportees en compta et/ou ventilees - $ventilExportCompta = $object->getVentilExportCompta(); - - if ($resteapayer == $object->total_ttc && $object->paye == 0 && $ventilExportCompta == 0) - { - if (! $objectidnext) - { - if ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && $user->rights->facture->valider) || $user->rights->facture->invoice_advance->unvalidate) - { - print ''; - } - else - { - print '
'.$langs->trans('Modify').'
'; - } - } - else - { - print '
'.$langs->trans('Modify').'
'; - } - } - } - - // Reopen a standard paid invoice - if (($object->type == 0 || $object->type == 1) && ($object->statut == 2 || $object->statut == 3)) // A paid invoice (partially or completely) - { - if (! $objectidnext && $object->close_code != 'replaced') // Not replaced by another invoice - { - print ''; - } - else - { - print '
'.$langs->trans('ReOpen').'
'; - } - } - - // Validate - if ($object->statut == 0 && count($object->lines) > 0 && - ( - (($object->type == 0 || $object->type == 1 || $object->type == 3 || $object->type == 4) && (! empty($conf->global->FACTURE_ENABLE_NEGATIVE) || $object->total_ttc >= 0)) - || ($object->type == 2 && $object->total_ttc <= 0)) - ) - { - if ($user->rights->facture->valider) - { - print ''; - } - } - - // Send by mail - if (($object->statut == 1 || $object->statut == 2)) - { - if ($objectidnext) - { - print '
'.$langs->trans('SendByMail').'
'; - } - else - { - if (empty($conf->global->MAIN_USE_ADVANCED_PERMS) || $user->rights->facture->invoice_advance->send) - { - print ''; - } - else print ''; - } - } - - if (! empty($conf->global->FACTURE_SHOW_SEND_REMINDER)) // For backward compatibility - { - if (($object->statut == 1 || $object->statut == 2) && $resteapayer > 0) - { - if ($objectidnext) - { - print '
'.$langs->trans('SendRemindByMail').'
'; - } - else - { - if (empty($conf->global->MAIN_USE_ADVANCED_PERMS) || $user->rights->facture->invoice_advance->send) - { - print ''; - } - else print ''; - } - } - } - - // Create payment - if ($object->type != 2 && $object->statut == 1 && $object->paye == 0 && $user->rights->facture->paiement) - { - if ($objectidnext) - { - print '
'.$langs->trans('DoPayment').'
'; - } - else - { - if ($resteapayer == 0) - { - print '
'.$langs->trans('DoPayment').'
'; - } - else - { - print ''; - } - } - } - - // Reverse back money or convert to reduction - if ($object->type == 2 || $object->type == 3) - { - // For credit note only - if ($object->type == 2 && $object->statut == 1 && $object->paye == 0 && $user->rights->facture->paiement) - { - print ''; - } - // For credit note - if ($object->type == 2 && $object->statut == 1 && $object->paye == 0 && $user->rights->facture->creer && $object->getSommePaiement() == 0) - { - print ''; - } - // For deposit invoice - if ($object->type == 3 && $object->statut == 1 && $resteapayer == 0 && $user->rights->facture->creer) - { - print ''; - } - } - - // Classify paid (if not deposit and not credit note. Such invoice are "converted") - if ($object->statut == 1 && $object->paye == 0 && $user->rights->facture->paiement && - (($object->type != 2 && $object->type != 3 && $resteapayer <= 0) || ($object->type == 2 && $resteapayer >= 0)) ) - { - print ''; - } - - // Classify 'closed not completely paid' (possible si validee et pas encore classee payee) - if ($object->statut == 1 && $object->paye == 0 && $resteapayer > 0 - && $user->rights->facture->paiement) - { - if ($totalpaye > 0 || $totalcreditnotes > 0) - { - // If one payment or one credit note was linked to this invoice - print ''; - } - else - { - if ($objectidnext) - { - print '
'.$langs->trans('ClassifyCanceled').'
'; - } - else - { - print ''; - } - } - } - - // Clone - if (($object->type == 0 || $object->type == 3 || $object->type == 4) && $user->rights->facture->creer) - { - print ''; - } - - // Clone as predefined - if (($object->type == 0 || $object->type == 3 || $object->type == 4) && $object->statut == 0 && $user->rights->facture->creer) - { - if (! $objectidnext) - { - print ''; - } - } - - // Delete - if ($user->rights->facture->supprimer) - { - if (! $object->is_erasable()) - { - print ''; - } - else if ($objectidnext) - { - print ''; - } - elseif ($object->getSommePaiement()) - { - print ''; - } - else - { - print ''; - } - } - else - { - print ''; - } - - print '
'; - } - } - print '
'; - - if ($action != 'prerelance' && $action != 'presend') - { - print '
'; - //print '
'; - //print ''; // ancre - - /* - * Documents generes - */ - $filename=dol_sanitizeFileName($object->ref); - $filedir=$conf->facture->dir_output . '/' . dol_sanitizeFileName($object->ref); - $urlsource=$_SERVER['PHP_SELF'].'?facid='.$object->id; - $genallowed=$user->rights->facture->creer; - $delallowed=$user->rights->facture->supprimer; - - print $formfile->showdocuments('facture',$filename,$filedir,$urlsource,$genallowed,$delallowed,$object->modelpdf,1,0,0,28,0,'','','',$soc->default_lang); - $somethingshown=$formfile->numoffiles; - - /* - * Linked object block - */ - $somethingshown=$object->showLinkedObjectBlock(); - - // Link for paypal payment - if (! empty($conf->paypal->enabled) && $object->statut != 0) - { - include_once DOL_DOCUMENT_ROOT.'/paypal/lib/paypal.lib.php'; - print showPaypalPaymentUrl('invoice',$object->ref); - } - - print '
'; - //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,'invoice',$socid); - - //print '
'; - print '
'; - } - else - { - /* - * Affiche formulaire mail - */ - - // By default if $action=='presend' - $titreform='SendBillByMail'; - $topicmail='SendBillRef'; - $action='send'; - $modelmail='facture_send'; - - if ($action == 'prerelance') // For backward compatibility - { - $titrefrom='SendReminderBillByMail'; - $topicmail='SendReminderBillRef'; - $action='relance'; - $modelmail='facture_relance'; - } - - $ref = dol_sanitizeFileName($object->ref); - include_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; - $fileparams = dol_most_recent_file($conf->facture->dir_output . '/' . $ref, preg_quote($ref,'/')); - $file=$fileparams['fullname']; - - // Build document if it not exists - if (! $file || ! is_readable($file)) - { - // Define output language - $outputlangs = $langs; - $newlang=''; - if ($conf->global->MAIN_MULTILANGS && empty($newlang) && ! empty($_REQUEST['lang_id'])) $newlang=$_REQUEST['lang_id']; - if ($conf->global->MAIN_MULTILANGS && empty($newlang)) $newlang=$object->client->default_lang; - if (! empty($newlang)) - { - $outputlangs = new Translate("",$conf); - $outputlangs->setDefaultLang($newlang); - } - - $result=facture_pdf_create($db, $object, GETPOST('model')?GETPOST('model'):$object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref); - if ($result <= 0) - { - dol_print_error($db,$result); - exit; - } - $fileparams = dol_most_recent_file($conf->facture->dir_output . '/' . $ref, preg_quote($ref,'/')); - $file=$fileparams['fullname']; - } - - print '
'; - print_titre($langs->trans($titreform)); - - // Cree l'objet formulaire mail - include_once DOL_DOCUMENT_ROOT.'/core/class/html.formmail.class.php'; - $formmail = new FormMail($db); - $formmail->fromtype = 'user'; - $formmail->fromid = $user->id; - $formmail->fromname = $user->getFullName($langs); - $formmail->frommail = $user->email; - $formmail->withfrom=1; - $liste=array(); - foreach ($object->thirdparty->thirdparty_and_contact_email_array(1) as $key=>$value) $liste[$key]=$value; - $formmail->withto=GETPOST('sendto')?GETPOST('sendto'):$liste; - $formmail->withtocc=$liste; - $formmail->withtoccc=$conf->global->MAIN_EMAIL_USECCC; - $formmail->withtopic=$langs->transnoentities($topicmail,'__FACREF__'); - $formmail->withfile=2; - $formmail->withbody=1; - $formmail->withdeliveryreceipt=1; - $formmail->withcancel=1; - // Tableau des substitutions - $formmail->substit['__FACREF__']=$object->ref; - $formmail->substit['__SIGNATURE__']=$user->signature; - $formmail->substit['__PERSONALIZED__']=''; - $formmail->substit['__CONTACTCIVNAME__']=''; - - //Find the good contact adress - $custcontact=''; - $contactarr=array(); - $contactarr=$object->liste_contact(-1,'external'); - - if (is_array($contactarr) && count($contactarr)>0) { - foreach($contactarr as $contact) { - if ($contact['libelle']==$langs->trans('TypeContact_facture_external_BILLING')) { - - require_once DOL_DOCUMENT_ROOT . '/contact/class/contact.class.php'; - - $contactstatic=new Contact($db); - $contactstatic->fetch($contact['id']); - $custcontact=$contactstatic->getFullName($langs,1); - } - } - - if (!empty($custcontact)) { - $formmail->substit['__CONTACTCIVNAME__']=$custcontact; - } - } - - - // Tableau des parametres complementaires du post - $formmail->param['action']=$action; - $formmail->param['models']=$modelmail; - $formmail->param['facid']=$object->id; - $formmail->param['returnurl']=$_SERVER["PHP_SELF"].'?id='.$object->id; - - // Init list of files - if (GETPOST("mode")=='init') - { - $formmail->clear_attached_files(); - $formmail->add_attached_files($file,basename($file),dol_mimetype($file)); - } - - $formmail->show_form(); - - print '
'; - } - } - else - { - dol_print_error($db,$object->error); - } + // Type + print ''.$langs->trans('Type').''; + print $object->getLibType(); + if ($object->type == 1) + { + $facreplaced=new Facture($db); + $facreplaced->fetch($object->fk_facture_source); + print ' ('.$langs->transnoentities("ReplaceInvoice",$facreplaced->getNomUrl(1)).')'; + } + if ($object->type == 2) + { + $facusing=new Facture($db); + $facusing->fetch($object->fk_facture_source); + print ' ('.$langs->transnoentities("CorrectInvoice",$facusing->getNomUrl(1)).')'; + } + + $facidavoir=$object->getListIdAvoirFromInvoice(); + if (count($facidavoir) > 0) + { + print ' ('.$langs->transnoentities("InvoiceHasAvoir"); + $i=0; + foreach($facidavoir as $id) + { + if ($i==0) print ' '; + else print ','; + $facavoir=new Facture($db); + $facavoir->fetch($id); + print $facavoir->getNomUrl(1); + } + print ')'; + } + if ($objectidnext > 0) + { + $facthatreplace=new Facture($db); + $facthatreplace->fetch($objectidnext); + print ' ('.$langs->transnoentities("ReplacedByInvoice",$facthatreplace->getNomUrl(1)).')'; + } + print ''; + + // Relative and absolute discounts + $addrelativediscount=''.$langs->trans("EditRelativeDiscounts").''; + $addabsolutediscount=''.$langs->trans("EditGlobalDiscounts").''; + $addcreditnote=''.$langs->trans("AddCreditNote").''; + + print ''.$langs->trans('Discounts'); + print ''; + if ($soc->remise_client) print $langs->trans("CompanyHasRelativeDiscount",$soc->remise_client); + else print $langs->trans("CompanyHasNoRelativeDiscount"); + //print ' ('.$addrelativediscount.')'; + + if ($absolute_discount > 0) + { + print '. '; + if ($object->statut > 0 || $object->type == 2 || $object->type == 3) + { + if ($object->statut == 0) + { + print $langs->trans("CompanyHasAbsoluteDiscount",price($absolute_discount),$langs->transnoentities("Currency".$conf->currency)); + print '. '; + } + else + { + if ($object->statut < 1 || $object->type == 2 || $object->type == 3) + { + $text=$langs->trans("CompanyHasAbsoluteDiscount",price($absolute_discount),$langs->transnoentities("Currency".$conf->currency)); + print '
'.$text.'.
'; + } + else + { + $text=$langs->trans("CompanyHasAbsoluteDiscount",price($absolute_discount),$langs->transnoentities("Currency".$conf->currency)); + $text2=$langs->trans("AbsoluteDiscountUse"); + print $form->textwithpicto($text,$text2); + } + } + } + else + { + // Remise dispo de type remise fixe (not credit note) + print '
'; + $form->form_remise_dispo($_SERVER["PHP_SELF"].'?facid='.$object->id, GETPOST('discountid'), 'remise_id', $soc->id, $absolute_discount, $filterabsolutediscount, $resteapayer, ' ('.$addabsolutediscount.')'); + } + } + else + { + if ($absolute_creditnote > 0) // If not, link will be added later + { + if ($object->statut == 0 && $object->type != 2 && $object->type != 3) print ' ('.$addabsolutediscount.')
'; + else print '. '; + } + else print '. '; + } + if ($absolute_creditnote > 0) + { + // If validated, we show link "add credit note to payment" + if ($object->statut != 1 || $object->type == 2 || $object->type == 3) + { + if ($object->statut == 0 && $object->type != 3) + { + $text=$langs->trans("CompanyHasCreditNote",price($absolute_creditnote),$langs->transnoentities("Currency".$conf->currency)); + print $form->textwithpicto($text,$langs->trans("CreditNoteDepositUse")); + } + else + { + print $langs->trans("CompanyHasCreditNote",price($absolute_creditnote),$langs->transnoentities("Currency".$conf->currency)).'.'; + } + } + else + { + // Remise dispo de type avoir + if (! $absolute_discount) print '
'; + //$form->form_remise_dispo($_SERVER["PHP_SELF"].'?facid='.$object->id, 0, 'remise_id_for_payment', $soc->id, $absolute_creditnote, $filtercreditnote, $resteapayer); + $form->form_remise_dispo($_SERVER["PHP_SELF"].'?facid='.$object->id, 0, 'remise_id_for_payment', $soc->id, $absolute_creditnote, $filtercreditnote, 0); // We must allow credit not even if amount is higher + } + } + if (! $absolute_discount && ! $absolute_creditnote) + { + print $langs->trans("CompanyHasNoAbsoluteDiscount"); + if ($object->statut == 0 && $object->type != 2 && $object->type != 3) print ' ('.$addabsolutediscount.')
'; + else print '. '; + } + /*if ($object->statut == 0 && $object->type != 2 && $object->type != 3) + { + if (! $absolute_discount && ! $absolute_creditnote) print '
'; + //print '   -   '; + print $addabsolutediscount; + //print '   -   '.$addcreditnote; // We disbale link to credit note + }*/ + print ''; + + // Date invoice + print ''; + print ''; + if ($object->type != 2 && $action != 'editinvoicedate' && ! empty($object->brouillon) && $user->rights->facture->creer) print ''; + print '
'; + print $langs->trans('Date'); + print 'id.'">'.img_edit($langs->trans('SetDate'),1).'
'; + print ''; + + if ($object->type != 2) + { + if ($action == 'editinvoicedate') + { + $form->form_date($_SERVER['PHP_SELF'].'?facid='.$object->id,$object->date,'invoicedate'); + } + else + { + print dol_print_date($object->date,'daytext'); + } + } + else + { + print dol_print_date($object->date,'daytext'); + } + print ''; + + + /* + * List of payments + */ + + $sign=1; + if ($object->type == 2) $sign=-1; + + $nbrows=8; $nbcols=2; + if (! empty($conf->projet->enabled)) $nbrows++; + if (! empty($conf->banque->enabled)) $nbcols++; + if($mysoc->localtax1_assuj=="1") $nbrows++; + if($mysoc->localtax2_assuj=="1") $nbrows++; + if ($selleruserevenustamp) $nbrows++; + + print ''; + + print ''; + + // List of payments already done + print ''; + print ''; + print ''; + if (! empty($conf->banque->enabled)) print ''; + print ''; + print ''; + print ''; + + $var=true; + + // Payments already done (from payment on this invoice) + $sql = 'SELECT p.datep as dp, p.num_paiement, p.rowid, p.fk_bank,'; + $sql.= ' c.code as payment_code, c.libelle as payment_label,'; + $sql.= ' pf.amount,'; + $sql.= ' ba.rowid as baid, ba.ref, ba.label'; + $sql.= ' FROM '.MAIN_DB_PREFIX.'c_paiement as c, '.MAIN_DB_PREFIX.'paiement_facture as pf, '.MAIN_DB_PREFIX.'paiement as p'; + $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'bank as b ON p.fk_bank = b.rowid'; + $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'bank_account as ba ON b.fk_account = ba.rowid'; + $sql.= ' WHERE pf.fk_facture = '.$object->id.' AND p.fk_paiement = c.id AND pf.fk_paiement = p.rowid'; + $sql.= ' ORDER BY p.datep, p.tms'; + + $result = $db->query($sql); + if ($result) + { + $num = $db->num_rows($result); + $i = 0; + + //if ($object->type != 2) + //{ + if ($num > 0) + { + while ($i < $num) + { + $objp = $db->fetch_object($result); + $var=!$var; + print ''; + $label=($langs->trans("PaymentType".$objp->payment_code)!=("PaymentType".$objp->payment_code))?$langs->trans("PaymentType".$objp->payment_code):$objp->payment_label; + print ''; + if (! empty($conf->banque->enabled)) + { + $bankaccountstatic->id=$objp->baid; + $bankaccountstatic->ref=$objp->ref; + $bankaccountstatic->label=$objp->ref; + print ''; + } + print ''; + print ''; + print ''; + $i++; + } + } + else + { + print ''; + } + //} + $db->free($result); + } + else + { + dol_print_error($db); + } + + if ($object->type != 2) + { + // Total already paid + print ''; + + $resteapayeraffiche=$resteapayer; + + // Loop on each credit note or deposit amount applied + $creditnoteamount=0; + $depositamount=0; + $sql = "SELECT re.rowid, re.amount_ht, re.amount_tva, re.amount_ttc,"; + $sql.= " re.description, re.fk_facture_source"; + $sql.= " FROM ".MAIN_DB_PREFIX ."societe_remise_except as re"; + $sql.= " WHERE fk_facture = ".$object->id; + $resql=$db->query($sql); + if ($resql) + { + $num = $db->num_rows($resql); + $i = 0; + $invoice=new Facture($db); + while ($i < $num) + { + $obj = $db->fetch_object($resql); + $invoice->fetch($obj->fk_facture_source); + print ''; + print ''; + print ''; + $i++; + if ($invoice->type == 2) $creditnoteamount += $obj->amount_ttc; + if ($invoice->type == 3) $depositamount += $obj->amount_ttc; + } + } + else + { + dol_print_error($db); + } + + // Paye partiellement 'escompte' + if (($object->statut == 2 || $object->statut == 3) && $object->close_code == 'discount_vat') + { + print ''; + $resteapayeraffiche=0; + } + // Paye partiellement ou Abandon 'badcustomer' + if (($object->statut == 2 || $object->statut == 3) && $object->close_code == 'badcustomer') + { + print ''; + //$resteapayeraffiche=0; + } + // Paye partiellement ou Abandon 'product_returned' + if (($object->statut == 2 || $object->statut == 3) && $object->close_code == 'product_returned') + { + print ''; + $resteapayeraffiche=0; + } + // Paye partiellement ou Abandon 'abandon' + if (($object->statut == 2 || $object->statut == 3) && $object->close_code == 'abandon') + { + print ''; + $resteapayeraffiche=0; + } + + // Billed + print ''; + + // Remainder to pay + print ''; + print ''; + print ''; + } + else // Credit note + { + // Total already paid back + print ''; + + // Billed + print ''; + + // Remainder to pay back + print ''; + print ''; + print ''; + + // Sold credit note + //print ''; + //print ''; + } + + print '
'.($object->type == 2 ? $langs->trans("PaymentsBack") : $langs->trans('Payments')).''.$langs->trans('Type').''.$langs->trans('BankAccount').''.$langs->trans('Amount').' 
'; + print ''.img_object($langs->trans('ShowPayment'),'payment').' '; + print dol_print_date($db->jdate($objp->dp),'day').''.$label.' '.$objp->num_paiement.''; + if ($bankaccountstatic->id) print $bankaccountstatic->getNomUrl(1,'transactions'); + print ''.price($sign * $objp->amount).' 
'.$langs->trans("None").'
'; + if ($object->type != 3) print $langs->trans('AlreadyPaidNoCreditNotesNoDeposits'); + else print $langs->trans('AlreadyPaid'); + print ' :'.price($totalpaye).' 
'; + if ($invoice->type == 2) print $langs->trans("CreditNote").' '; + if ($invoice->type == 3) print $langs->trans("Deposit").' '; + print $invoice->getNomUrl(0); + print ' :'.price($obj->amount_ttc).''; + print 'rowid.'">'.img_delete().''; + print '
'; + print $form->textwithpicto($langs->trans("Discount").':',$langs->trans("HelpEscompte"),-1); + print ''.price($object->total_ttc - $creditnoteamount - $depositamount - $totalpaye).' 
'; + print $form->textwithpicto($langs->trans("Abandoned").':',$langs->trans("HelpAbandonBadCustomer"),-1); + print ''.price($object->total_ttc - $creditnoteamount - $depositamount - $totalpaye).' 
'; + print $form->textwithpicto($langs->trans("ProductReturned").':',$langs->trans("HelpAbandonProductReturned"),-1); + print ''.price($object->total_ttc - $creditnoteamount - $depositamount - $totalpaye).' 
'; + $text=$langs->trans("HelpAbandonOther"); + if ($object->close_note) $text.='

'.$langs->trans("Reason").':'.$object->close_note; + print $form->textwithpicto($langs->trans("Abandoned").':',$text,-1); + print '
'.price($object->total_ttc - $creditnoteamount - $depositamount - $totalpaye).' 
'.$langs->trans("Billed").' :'.price($object->total_ttc).' 
'; + if ($resteapayeraffiche >= 0) print $langs->trans('RemainderToPay'); + else print $langs->trans('ExcessReceived'); + print ' :'.price($resteapayeraffiche).' 
'; + print $langs->trans('AlreadyPaidBack'); + print ' :'.price($sign * $totalpaye).' 
'.$langs->trans("Billed").' :'.price($sign * $object->total_ttc).' 
'; + if ($resteapayeraffiche <= 0) print $langs->trans('RemainderToPayBack'); + else print $langs->trans('ExcessPaydBack'); + print ' :'.price($sign * $resteapayeraffiche).' 
'.$langs->trans('TotalTTC').' :'.price($sign * $object->total_ttc).' 
'; + + // Margin Infos + if (! empty($conf->margin->enabled)) + { + print '
'; + $object->displayMarginInfos($object->statut > 0); + } + + print ''; + + // Conditions de reglement + print ''; + print ''; + if ($object->type != 2 && $action != 'editconditions' && ! empty($object->brouillon) && $user->rights->facture->creer) print ''; + print '
'; + print $langs->trans('PaymentConditionsShort'); + print 'id.'">'.img_edit($langs->trans('SetConditions'),1).'
'; + print ''; + if ($object->type != 2) + { + if ($action == 'editconditions') + { + $form->form_conditions_reglement($_SERVER['PHP_SELF'].'?facid='.$object->id,$object->cond_reglement_id,'cond_reglement_id'); + } + else + { + $form->form_conditions_reglement($_SERVER['PHP_SELF'].'?facid='.$object->id,$object->cond_reglement_id,'none'); + } + } + else + { + print ' '; + } + print ''; + + // Date payment term + print ''; + print ''; + if ($object->type != 2 && $action != 'editpaymentterm' && ! empty($object->brouillon) && $user->rights->facture->creer) print ''; + print '
'; + print $langs->trans('DateMaxPayment'); + print 'id.'">'.img_edit($langs->trans('SetDate'),1).'
'; + print ''; + if ($object->type != 2) + { + if ($action == 'editpaymentterm') + { + $form->form_date($_SERVER['PHP_SELF'].'?facid='.$object->id,$object->date_lim_reglement,'paymentterm'); + } + else + { + print dol_print_date($object->date_lim_reglement,'daytext'); + if ($object->date_lim_reglement < ($now - $conf->facture->client->warning_delay) && ! $object->paye && $object->statut == 1 && ! isset($object->am)) print img_warning($langs->trans('Late')); + } + } + else + { + print ' '; + } + print ''; + + // Payment mode + print ''; + print ''; + if ($action != 'editmode' && ! empty($object->brouillon) && $user->rights->facture->creer) print ''; + print '
'; + print $langs->trans('PaymentMode'); + print 'id.'">'.img_edit($langs->trans('SetMode'),1).'
'; + print ''; + if ($action == 'editmode') + { + $form->form_modes_reglement($_SERVER['PHP_SELF'].'?facid='.$object->id,$object->mode_reglement_id,'mode_reglement_id'); + } + else + { + $form->form_modes_reglement($_SERVER['PHP_SELF'].'?facid='.$object->id,$object->mode_reglement_id,'none'); + } + print ''; + + // Amount + print ''.$langs->trans('AmountHT').''; + print ''.price($object->total_ht,1,'',1,-1,-1,$conf->currency).''; + print ''.$langs->trans('AmountVAT').''.price($object->total_tva,1,'',1,-1,-1,$conf->currency).''; + print ''; + + // Amount Local Taxes + if ($mysoc->localtax1_assuj=="1" && $mysoc->useLocalTax(1)) //Localtax1 (example RE) + { + print ''.$langs->transcountry("AmountLT1",$mysoc->country_code).''; + print ''.price($object->total_localtax1,1,'',1,-1,-1,$conf->currency).''; + } + if ($mysoc->localtax2_assuj=="1" && $mysoc->useLocalTax(2)) //Localtax2 (example IRPF) + { + print ''.$langs->transcountry("AmountLT2",$mysoc->country_code).''; + print ''.price($object->total_localtax2,1,'',1,-1,-1,$conf->currency).''; + } + + // Revenue stamp + if ($selleruserevenustamp) // Test company use revenue stamp + { + print ''; + print ''; + if ($action != 'editrevenuestamp' && ! empty($object->brouillon) && $user->rights->facture->creer) print ''; + print '
'; + print $langs->trans('RevenueStamp'); + print 'id.'">'.img_edit($langs->trans('SetRevenuStamp'),1).'
'; + print ''; + if ($action == 'editrevenuestamp') + { + print '
'; + print ''; + print ''; + print $formother->select_revenue_stamp(GETPOST('revenuestamp'), 'revenuestamp', $mysoc->country_code); + //print ''; + print ' '; + print '
'; + } + else + { + print price($object->revenuestamp,1,'',1,-1,-1,$conf->currency); + } + print ''; + } + + // Total with tax + print ''.$langs->trans('AmountTTC').''.price($object->total_ttc,1,'',1,-1,-1,$conf->currency).''; + + // Statut + print ''.$langs->trans('Status').''; + print ''.($object->getLibStatut(4,$totalpaye)).''; + + // Project + if (! empty($conf->projet->enabled)) + { + $langs->load('projects'); + print ''; + print ''; + + print ''; + if ($action != 'classify') + { + print ''; + } + print '
'; + print $langs->trans('Project'); + print 'id.'">'; + print img_edit($langs->trans('SetProject'),1); + print '
'; + + print ''; + if ($action == 'classify') + { + $form->form_project($_SERVER['PHP_SELF'].'?facid='.$object->id,$object->socid,$object->fk_project,'projectid'); + } + else + { + $form->form_project($_SERVER['PHP_SELF'].'?facid='.$object->id,$object->socid,$object->fk_project,'none'); + } + print ''; + print ''; + } + + // Other attributes + $res=$object->fetch_optionals($object->id,$extralabels); + $parameters=array('colspan' => ' colspan="2"'); + $reshook=$hookmanager->executeHooks('formObjectOptions',$parameters,$object,$action); // Note that $action and $object may have been modified by hook + if (empty($reshook) && ! empty($extrafields->attribute_label)) + { + + if ($action == 'edit_extras') + { + print '
'; + print ''; + print ''; + print ''; + } + + foreach($extrafields->attribute_label as $key=>$label) + { + $value=(isset($_POST["options_".$key])?$_POST["options_".$key]:$object->array_options["options_".$key]); + if ($extrafields->attribute_type[$key] == 'separate') + { + print $extrafields->showSeparator($key); + } + else + { + print 'attribute_required[$key])) print ' class="fieldrequired"'; + print '>'.$label.''; + // Convert date into timestamp format + if (in_array($extrafields->attribute_type[$key],array('date','datetime'))) + { + $value = isset($_POST["options_".$key])?dol_mktime($_POST["options_".$key."hour"], $_POST["options_".$key."min"], 0, $_POST["options_".$key."month"], $_POST["options_".$key."day"], $_POST["options_".$key."year"]):$object->array_options['options_'.$key]; + } + + if ($action == 'edit_extras' && $user->rights->facture->creer) + { + print $extrafields->showInputField($key,$value); + } + else + { + print $extrafields->showOutputField($key,$value); + } + print ''."\n"; + } + } + + if(count($extrafields->attribute_label) > 0) { + + if ($action == 'edit_extras' && $user->rights->facture->creer) + { + print ''; + print ''; + print ''; + print ''; + + } + else { + if ($object->statut == 0 && $user->rights->facture->creer) + { + print ''.img_picto('','edit').' '.$langs->trans('Modify').''; + } + } + } + } + + 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 + */ + $result = $object->getLinesArray(); + + if (! empty($conf->use_javascript_ajax) && $object->statut == 0) + { + include DOL_DOCUMENT_ROOT.'/core/tpl/ajaxrow.tpl.php'; + } + + print ''; + + // Show object lines + if (! empty($object->lines)) + $ret=$object->printObjectLines($action,$mysoc,$soc,$lineid,1); + + /* + * Form to add new line + */ + if ($object->statut == 0 && $user->rights->facture->creer && $action <> 'valid' && $action <> 'editline') + { + $var=true; + + if ($conf->global->MAIN_FEATURES_LEVEL > 1) + { + // Add free or predefined products/services + $object->formAddObjectLine(1,$mysoc,$soc); + } + else + { + // Add free products/services + $object->formAddFreeProduct(1,$mysoc,$soc); + + // Add predefined products/services + if (! empty($conf->product->enabled) || ! empty($conf->service->enabled)) + { + $var=!$var; + $object->formAddPredefinedProduct(1,$mysoc,$soc); + } + } + + $parameters=array(); + $reshook=$hookmanager->executeHooks('formAddObjectLine',$parameters,$object,$action); // Note that $action and $object may have been modified by hook + } + + print "
\n"; + + print "\n"; + + + /* + * Boutons actions + */ + + if ($action != 'prerelance' && $action != 'presend') + { + if ($user->societe_id == 0 && $action <> 'valid' && $action <> 'editline') + { + print '
'; + + // Editer une facture deja validee, sans paiement effectue et pas exporte en compta + if ($object->statut == 1) + { + // On verifie si les lignes de factures ont ete exportees en compta et/ou ventilees + $ventilExportCompta = $object->getVentilExportCompta(); + + if ($resteapayer == $object->total_ttc && $object->paye == 0 && $ventilExportCompta == 0) + { + if (! $objectidnext) + { + if ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && $user->rights->facture->valider) || $user->rights->facture->invoice_advance->unvalidate) + { + print ''; + } + else + { + print '
'.$langs->trans('Modify').'
'; + } + } + else + { + print '
'.$langs->trans('Modify').'
'; + } + } + } + + // Reopen a standard paid invoice + if (($object->type == 0 || $object->type == 1) && ($object->statut == 2 || $object->statut == 3)) // A paid invoice (partially or completely) + { + if (! $objectidnext && $object->close_code != 'replaced') // Not replaced by another invoice + { + print ''; + } + else + { + print '
'.$langs->trans('ReOpen').'
'; + } + } + + // Validate + if ($object->statut == 0 && count($object->lines) > 0 && + ( + (($object->type == 0 || $object->type == 1 || $object->type == 3 || $object->type == 4) && (! empty($conf->global->FACTURE_ENABLE_NEGATIVE) || $object->total_ttc >= 0)) + || ($object->type == 2 && $object->total_ttc <= 0)) + ) + { + if ($user->rights->facture->valider) + { + print ''; + } + } + + // Send by mail + if (($object->statut == 1 || $object->statut == 2)) + { + if ($objectidnext) + { + print '
'.$langs->trans('SendByMail').'
'; + } + else + { + if (empty($conf->global->MAIN_USE_ADVANCED_PERMS) || $user->rights->facture->invoice_advance->send) + { + print ''; + } + else print ''; + } + } + + if (! empty($conf->global->FACTURE_SHOW_SEND_REMINDER)) // For backward compatibility + { + if (($object->statut == 1 || $object->statut == 2) && $resteapayer > 0) + { + if ($objectidnext) + { + print '
'.$langs->trans('SendRemindByMail').'
'; + } + else + { + if (empty($conf->global->MAIN_USE_ADVANCED_PERMS) || $user->rights->facture->invoice_advance->send) + { + print ''; + } + else print ''; + } + } + } + + // Create payment + if ($object->type != 2 && $object->statut == 1 && $object->paye == 0 && $user->rights->facture->paiement) + { + if ($objectidnext) + { + print '
'.$langs->trans('DoPayment').'
'; + } + else + { + if ($resteapayer == 0) + { + print '
'.$langs->trans('DoPayment').'
'; + } + else + { + print ''; + } + } + } + + // Reverse back money or convert to reduction + if ($object->type == 2 || $object->type == 3) + { + // For credit note only + if ($object->type == 2 && $object->statut == 1 && $object->paye == 0 && $user->rights->facture->paiement) + { + print ''; + } + // For credit note + if ($object->type == 2 && $object->statut == 1 && $object->paye == 0 && $user->rights->facture->creer && $object->getSommePaiement() == 0) + { + print ''; + } + // For deposit invoice + if ($object->type == 3 && $object->statut == 1 && $resteapayer == 0 && $user->rights->facture->creer) + { + print ''; + } + } + + // Classify paid (if not deposit and not credit note. Such invoice are "converted") + if ($object->statut == 1 && $object->paye == 0 && $user->rights->facture->paiement && + (($object->type != 2 && $object->type != 3 && $resteapayer <= 0) || ($object->type == 2 && $resteapayer >= 0)) ) + { + print ''; + } + + // Classify 'closed not completely paid' (possible si validee et pas encore classee payee) + if ($object->statut == 1 && $object->paye == 0 && $resteapayer > 0 + && $user->rights->facture->paiement) + { + if ($totalpaye > 0 || $totalcreditnotes > 0) + { + // If one payment or one credit note was linked to this invoice + print ''; + } + else + { + if ($objectidnext) + { + print '
'.$langs->trans('ClassifyCanceled').'
'; + } + else + { + print ''; + } + } + } + + // Clone + if (($object->type == 0 || $object->type == 3 || $object->type == 4) && $user->rights->facture->creer) + { + print ''; + } + + // Clone as predefined + if (($object->type == 0 || $object->type == 3 || $object->type == 4) && $object->statut == 0 && $user->rights->facture->creer) + { + if (! $objectidnext) + { + print ''; + } + } + + // Delete + if ($user->rights->facture->supprimer) + { + if (! $object->is_erasable()) + { + print ''; + } + else if ($objectidnext) + { + print ''; + } + elseif ($object->getSommePaiement()) + { + print ''; + } + else + { + print ''; + } + } + else + { + print ''; + } + + print '
'; + } + } + print '
'; + + if ($action != 'prerelance' && $action != 'presend') + { + print '
'; + //print '
'; + //print ''; // ancre + + /* + * Documents generes + */ + $filename=dol_sanitizeFileName($object->ref); + $filedir=$conf->facture->dir_output . '/' . dol_sanitizeFileName($object->ref); + $urlsource=$_SERVER['PHP_SELF'].'?facid='.$object->id; + $genallowed=$user->rights->facture->creer; + $delallowed=$user->rights->facture->supprimer; + + print $formfile->showdocuments('facture',$filename,$filedir,$urlsource,$genallowed,$delallowed,$object->modelpdf,1,0,0,28,0,'','','',$soc->default_lang); + $somethingshown=$formfile->numoffiles; + + /* + * Linked object block + */ + $somethingshown=$object->showLinkedObjectBlock(); + + // Link for paypal payment + if (! empty($conf->paypal->enabled) && $object->statut != 0) + { + include_once DOL_DOCUMENT_ROOT.'/paypal/lib/paypal.lib.php'; + print showPaypalPaymentUrl('invoice',$object->ref); + } + + print '
'; + //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,'invoice',$socid); + + //print '
'; + print '
'; + } + else + { + /* + * Affiche formulaire mail + */ + + // By default if $action=='presend' + $titreform='SendBillByMail'; + $topicmail='SendBillRef'; + $action='send'; + $modelmail='facture_send'; + + if ($action == 'prerelance') // For backward compatibility + { + $titrefrom='SendReminderBillByMail'; + $topicmail='SendReminderBillRef'; + $action='relance'; + $modelmail='facture_relance'; + } + + $ref = dol_sanitizeFileName($object->ref); + include_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; + $fileparams = dol_most_recent_file($conf->facture->dir_output . '/' . $ref, preg_quote($ref,'/')); + $file=$fileparams['fullname']; + + // Build document if it not exists + if (! $file || ! is_readable($file)) + { + // Define output language + $outputlangs = $langs; + $newlang=''; + if ($conf->global->MAIN_MULTILANGS && empty($newlang) && ! empty($_REQUEST['lang_id'])) $newlang=$_REQUEST['lang_id']; + if ($conf->global->MAIN_MULTILANGS && empty($newlang)) $newlang=$object->client->default_lang; + if (! empty($newlang)) + { + $outputlangs = new Translate("",$conf); + $outputlangs->setDefaultLang($newlang); + } + + $result=facture_pdf_create($db, $object, GETPOST('model')?GETPOST('model'):$object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref); + if ($result <= 0) + { + dol_print_error($db,$result); + exit; + } + $fileparams = dol_most_recent_file($conf->facture->dir_output . '/' . $ref, preg_quote($ref,'/')); + $file=$fileparams['fullname']; + } + + print '
'; + print_titre($langs->trans($titreform)); + + // Cree l'objet formulaire mail + include_once DOL_DOCUMENT_ROOT.'/core/class/html.formmail.class.php'; + $formmail = new FormMail($db); + $formmail->fromtype = 'user'; + $formmail->fromid = $user->id; + $formmail->fromname = $user->getFullName($langs); + $formmail->frommail = $user->email; + $formmail->withfrom=1; + $liste=array(); + foreach ($object->thirdparty->thirdparty_and_contact_email_array(1) as $key=>$value) $liste[$key]=$value; + $formmail->withto=GETPOST('sendto')?GETPOST('sendto'):$liste; + $formmail->withtocc=$liste; + $formmail->withtoccc=$conf->global->MAIN_EMAIL_USECCC; + $formmail->withtopic=$langs->transnoentities($topicmail,'__FACREF__'); + $formmail->withfile=2; + $formmail->withbody=1; + $formmail->withdeliveryreceipt=1; + $formmail->withcancel=1; + // Tableau des substitutions + $formmail->substit['__FACREF__']=$object->ref; + $formmail->substit['__SIGNATURE__']=$user->signature; + $formmail->substit['__PERSONALIZED__']=''; + $formmail->substit['__CONTACTCIVNAME__']=''; + + //Find the good contact adress + $custcontact=''; + $contactarr=array(); + $contactarr=$object->liste_contact(-1,'external'); + + if (is_array($contactarr) && count($contactarr)>0) { + foreach($contactarr as $contact) { + if ($contact['libelle']==$langs->trans('TypeContact_facture_external_BILLING')) { + + require_once DOL_DOCUMENT_ROOT . '/contact/class/contact.class.php'; + + $contactstatic=new Contact($db); + $contactstatic->fetch($contact['id']); + $custcontact=$contactstatic->getFullName($langs,1); + } + } + + if (!empty($custcontact)) { + $formmail->substit['__CONTACTCIVNAME__']=$custcontact; + } + } + + + // Tableau des parametres complementaires du post + $formmail->param['action']=$action; + $formmail->param['models']=$modelmail; + $formmail->param['facid']=$object->id; + $formmail->param['returnurl']=$_SERVER["PHP_SELF"].'?id='.$object->id; + + // Init list of files + if (GETPOST("mode")=='init') + { + $formmail->clear_attached_files(); + $formmail->add_attached_files($file,basename($file),dol_mimetype($file)); + } + + $formmail->show_form(); + + print '
'; + } + } + else + { + dol_print_error($db,$object->error); + } } dol_htmloutput_mesg('',$mesgs); diff --git a/htdocs/compta/facture/apercu.php b/htdocs/compta/facture/apercu.php index 2db60bada79..f31f0a50f0f 100644 --- a/htdocs/compta/facture/apercu.php +++ b/htdocs/compta/facture/apercu.php @@ -318,7 +318,7 @@ if ($id > 0 || ! empty($ref)) print "".$langs->trans("Bill")." PDF"; - print ''.$object->ref.'.pdf'; + print ''.$object->ref.'.pdf'; print ''.dol_print_size(dol_filesize($file)). ''; print ''.dol_print_date(dol_filemtime($file),'dayhour').''; print ''; @@ -328,7 +328,7 @@ if ($id > 0 || ! empty($ref)) { print "Facture detaillee"; - print ''.$object->ref.'-detail.pdf'; + print ''.$object->ref.'-detail.pdf'; print ''.dol_print_size(dol_filesize($filedetail)).''; print ''.dol_print_date(dol_filemtime($filedetail),'dayhour').''; print ''; diff --git a/htdocs/compta/facture/class/facture.class.php b/htdocs/compta/facture/class/facture.class.php index f36ddc88a1d..a2a9cf6da13 100644 --- a/htdocs/compta/facture/class/facture.class.php +++ b/htdocs/compta/facture/class/facture.class.php @@ -1,37 +1,37 @@ * Copyright (C) 2004-2012 Laurent Destailleur - * Copyright (C) 2004 Sebastien Di Cintio - * Copyright (C) 2004 Benoit Mortier - * Copyright (C) 2005 Marc Barilley / Ocebo - * Copyright (C) 2005-2013 Regis Houssin - * Copyright (C) 2006 Andre Cianfarani - * Copyright (C) 2007 Franky Van Liedekerke - * Copyright (C) 2010-2012 Juanjo Menent - * Copyright (C) 2012 Christophe Battarel - * Copyright (C) 2012 Marcos García - * Copyright (C) 2013 Cedric Gross - * 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 . - */ +* Copyright (C) 2004 Sebastien Di Cintio +* Copyright (C) 2004 Benoit Mortier +* Copyright (C) 2005 Marc Barilley / Ocebo +* Copyright (C) 2005-2013 Regis Houssin +* Copyright (C) 2006 Andre Cianfarani +* Copyright (C) 2007 Franky Van Liedekerke +* Copyright (C) 2010-2012 Juanjo Menent +* Copyright (C) 2012 Christophe Battarel +* Copyright (C) 2012 Marcos García +* Copyright (C) 2013 Cedric Gross +* 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/compta/facture/class/facture.class.php - * \ingroup facture - * \brief File of class to manage invoices - */ +* \ingroup facture +* \brief File of class to manage invoices +*/ include_once DOL_DOCUMENT_ROOT.'/core/class/commoninvoice.class.php'; require_once DOL_DOCUMENT_ROOT .'/product/class/product.class.php'; @@ -44,1831 +44,1870 @@ require_once DOL_DOCUMENT_ROOT .'/margin/lib/margins.lib.php'; */ class Facture extends CommonInvoice { - public $element='facture'; - public $table_element='facture'; - public $table_element_line = 'facturedet'; - public $fk_element = 'fk_facture'; - protected $ismultientitymanaged = 1; // 0=No test on entity, 1=Test with field entity, 2=Test with link by societe + public $element='facture'; + public $table_element='facture'; + public $table_element_line = 'facturedet'; + public $fk_element = 'fk_facture'; + protected $ismultientitymanaged = 1; // 0=No test on entity, 1=Test with field entity, 2=Test with link by societe - var $id; - //! Id client - var $socid; - //! Objet societe client (to load with fetch_client method) - var $client; - var $author; - var $fk_user_author; - var $fk_user_valid; - //! Invoice date - var $date; // Invoice date - var $date_creation; // Creation date - var $date_validation; // Validation date - var $datem; - var $ref; - var $ref_client; - var $ref_ext; - var $ref_int; - //! 0=Standard invoice, 1=Replacement invoice, 2=Credit note invoice, 3=Deposit invoice, 4=Proforma invoice - var $type=0; + var $id; + //! Id client + var $socid; + //! Objet societe client (to load with fetch_client method) + var $client; + var $author; + var $fk_user_author; + var $fk_user_valid; + //! Invoice date + var $date; // Invoice date + var $date_creation; // Creation date + var $date_validation; // Validation date + var $datem; + var $ref; + var $ref_client; + var $ref_ext; + var $ref_int; + //! 0=Standard invoice, 1=Replacement invoice, 2=Credit note invoice, 3=Deposit invoice, 4=Proforma invoice + var $type=0; - //var $amount; - var $remise_absolue; - var $remise_percent; - var $total_ht=0; - var $total_tva=0; - var $total_ttc=0; - var $revenuestamp; - var $note; // deprecated - var $note_private; - var $note_public; - //! 0=draft, - //! 1=validated (need to be paid), - //! 2=classified paid partially (close_code='discount_vat','badcustomer') or completely (close_code=null), - //! 3=classified abandoned and no payment done (close_code='badcustomer','abandon' or 'replaced') - var $statut; - //! Fermeture apres paiement partiel: discount_vat, badcustomer, abandon - //! Fermeture alors que aucun paiement: replaced (si remplace), abandon - var $close_code; - //! Commentaire si mis a paye sans paiement complet - var $close_note; - //! 1 if invoice paid COMPLETELY, 0 otherwise (do not use it anymore, use statut and close_code - var $paye; - //! id of source invoice if replacement invoice or credit note - var $fk_facture_source; - var $origin; - var $origin_id; - var $linked_objects=array(); - var $fk_project; - var $date_lim_reglement; - var $cond_reglement_id; // Id in llx_c_paiement - var $cond_reglement_code; // Code in llx_c_paiement - var $mode_reglement_id; // Id in llx_c_paiement - var $mode_reglement_code; // Code in llx_c_paiement - var $fk_bank; // Field to store bank id to use when payment mode is withdraw - var $modelpdf; - var $products=array(); // deprecated - var $lines=array(); - var $line; - var $extraparams=array(); - //! Pour board - var $nbtodo; - var $nbtodolate; - var $specimen; + //var $amount; + var $remise_absolue; + var $remise_percent; + var $total_ht=0; + var $total_tva=0; + var $total_ttc=0; + var $revenuestamp; + var $note; // deprecated + var $note_private; + var $note_public; + //! 0=draft, + //! 1=validated (need to be paid), + //! 2=classified paid partially (close_code='discount_vat','badcustomer') or completely (close_code=null), + //! 3=classified abandoned and no payment done (close_code='badcustomer','abandon' or 'replaced') + var $statut; + //! Fermeture apres paiement partiel: discount_vat, badcustomer, abandon + //! Fermeture alors que aucun paiement: replaced (si remplace), abandon + var $close_code; + //! Commentaire si mis a paye sans paiement complet + var $close_note; + //! 1 if invoice paid COMPLETELY, 0 otherwise (do not use it anymore, use statut and close_code + var $paye; + //! id of source invoice if replacement invoice or credit note + var $fk_facture_source; + var $origin; + var $origin_id; + var $linked_objects=array(); + var $fk_project; + var $date_lim_reglement; + var $cond_reglement_id; // Id in llx_c_paiement + var $cond_reglement_code; // Code in llx_c_paiement + var $mode_reglement_id; // Id in llx_c_paiement + var $mode_reglement_code; // Code in llx_c_paiement + var $fk_bank; // Field to store bank id to use when payment mode is withdraw + var $modelpdf; + var $products=array(); // deprecated + var $lines=array(); + var $line; + var $extraparams=array(); + //! Pour board + var $nbtodo; + var $nbtodolate; + var $specimen; - var $fac_rec; + var $fac_rec; - /** - * Constructor - * + /** + * Constructor + * * @param DoliDB $db Database handler - */ - function __construct($db) - { - $this->db = $db; - } + */ + function __construct($db) + { + $this->db = $db; + } - /** - * Create invoice in database - * Note: this->ref can be set or empty. If empty, we will use "(PROV)" - * - * @param User $user Object user that create - * @param int $notrigger 1=Does not execute triggers, 0 otherwise - * @param int $forceduedate 1=Do not recalculate due date from payment condition but force it with value - * @return int <0 if KO, >0 if OK - */ - function create($user,$notrigger=0,$forceduedate=0) - { - global $langs,$conf,$mysoc,$hookmanager; - $error=0; + /** + * Create invoice in database + * Note: this->ref can be set or empty. If empty, we will use "(PROV)" + * + * @param User $user Object user that create + * @param int $notrigger 1=Does not execute triggers, 0 otherwise + * @param int $forceduedate 1=Do not recalculate due date from payment condition but force it with value + * @return int <0 if KO, >0 if OK + */ + function create($user,$notrigger=0,$forceduedate=0) + { + global $langs,$conf,$mysoc,$hookmanager; + $error=0; - // Clean parameters - if (empty($this->type)) $this->type = 0; - $this->ref_client=trim($this->ref_client); - $this->note=(isset($this->note) ? trim($this->note) : trim($this->note_private)); // deprecated - $this->note_private=(isset($this->note_private) ? trim($this->note_private) : trim($this->note_private)); - $this->note_public=trim($this->note_public); - if (! $this->cond_reglement_id) $this->cond_reglement_id = 0; - if (! $this->mode_reglement_id) $this->mode_reglement_id = 0; - $this->brouillon = 1; + // Clean parameters + if (empty($this->type)) $this->type = 0; + $this->ref_client=trim($this->ref_client); + $this->note=(isset($this->note) ? trim($this->note) : trim($this->note_private)); // deprecated + $this->note_private=(isset($this->note_private) ? trim($this->note_private) : trim($this->note_private)); + $this->note_public=trim($this->note_public); + if (! $this->cond_reglement_id) $this->cond_reglement_id = 0; + if (! $this->mode_reglement_id) $this->mode_reglement_id = 0; + $this->brouillon = 1; - dol_syslog(get_class($this)."::create user=".$user->id); + dol_syslog(get_class($this)."::create user=".$user->id); - // Check parameters - if (empty($this->date) || empty($user->id)) - { - $this->error="ErrorBadParameter"; - dol_syslog(get_class($this)."::create Try to create an invoice with an empty parameter (user, date, ...)", LOG_ERR); - return -3; - } - $soc = new Societe($this->db); - $result=$soc->fetch($this->socid); - if ($result < 0) - { - $this->error="Failed to fetch company"; - dol_syslog(get_class($this)."::create ".$this->error, LOG_ERR); - return -2; - } + // Check parameters + if (empty($this->date) || empty($user->id)) + { + $this->error="ErrorBadParameter"; + dol_syslog(get_class($this)."::create Try to create an invoice with an empty parameter (user, date, ...)", LOG_ERR); + return -3; + } + $soc = new Societe($this->db); + $result=$soc->fetch($this->socid); + if ($result < 0) + { + $this->error="Failed to fetch company"; + dol_syslog(get_class($this)."::create ".$this->error, LOG_ERR); + return -2; + } - $now=dol_now(); + $now=dol_now(); - $this->db->begin(); + $this->db->begin(); - // Create invoice from a predefined invoice - if ($this->fac_rec > 0) - { - require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture-rec.class.php'; - $_facrec = new FactureRec($this->db); - $result=$_facrec->fetch($this->fac_rec); + // Create invoice from a predefined invoice + if ($this->fac_rec > 0) + { + require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture-rec.class.php'; + $_facrec = new FactureRec($this->db); + $result=$_facrec->fetch($this->fac_rec); - $this->fk_project = $_facrec->fk_project; - $this->cond_reglement = $_facrec->cond_reglement_id; - $this->cond_reglement_id = $_facrec->cond_reglement_id; - $this->mode_reglement = $_facrec->mode_reglement_id; - $this->mode_reglement_id = $_facrec->mode_reglement_id; - $this->remise_absolue = $_facrec->remise_absolue; - $this->remise_percent = $_facrec->remise_percent; + $this->fk_project = $_facrec->fk_project; + $this->cond_reglement = $_facrec->cond_reglement_id; + $this->cond_reglement_id = $_facrec->cond_reglement_id; + $this->mode_reglement = $_facrec->mode_reglement_id; + $this->mode_reglement_id = $_facrec->mode_reglement_id; + $this->remise_absolue = $_facrec->remise_absolue; + $this->remise_percent = $_facrec->remise_percent; - // Clean parametres - if (! $this->type) $this->type = 0; - $this->ref_client=trim($this->ref_client); - $this->note_private=trim($this->note_private); - $this->note_public=trim($this->note_public); - //if (! $this->remise) $this->remise = 0; - if (! $this->mode_reglement_id) $this->mode_reglement_id = 0; - $this->brouillon = 1; - } + // Clean parametres + if (! $this->type) $this->type = 0; + $this->ref_client=trim($this->ref_client); + $this->note_private=trim($this->note_private); + $this->note_public=trim($this->note_public); + //if (! $this->remise) $this->remise = 0; + if (! $this->mode_reglement_id) $this->mode_reglement_id = 0; + $this->brouillon = 1; + } - // Define due date if not already defined - $datelim=(empty($forceduedate)?$this->calculate_date_lim_reglement():$forceduedate); + // Define due date if not already defined + $datelim=(empty($forceduedate)?$this->calculate_date_lim_reglement():$forceduedate); - // Insert into database - $socid = $this->socid; + // Insert into database + $socid = $this->socid; - $sql = "INSERT INTO ".MAIN_DB_PREFIX."facture ("; - $sql.= " facnumber"; - $sql.= ", entity"; - $sql.= ", ref_ext"; - $sql.= ", type"; - $sql.= ", fk_soc"; - $sql.= ", datec"; - $sql.= ", remise_absolue"; - $sql.= ", remise_percent"; - $sql.= ", datef"; - $sql.= ", note_private"; - $sql.= ", note_public"; - $sql.= ", ref_client, ref_int"; - $sql.= ", fk_facture_source, fk_user_author, fk_projet"; - $sql.= ", fk_cond_reglement, fk_mode_reglement, date_lim_reglement, model_pdf"; - $sql.= ")"; - $sql.= " VALUES ("; - $sql.= "'(PROV)'"; - $sql.= ", ".$conf->entity; - $sql.= ", ".($this->ref_ext?"'".$this->db->escape($this->ref_ext)."'":"null"); - $sql.= ", '".$this->type."'"; - $sql.= ", '".$socid."'"; - $sql.= ", '".$this->db->idate($now)."'"; - $sql.= ",".($this->remise_absolue>0?$this->remise_absolue:'NULL'); - $sql.= ",".($this->remise_percent>0?$this->remise_percent:'NULL'); - $sql.= ", '".$this->db->idate($this->date)."'"; - $sql.= ",".($this->note_private?"'".$this->db->escape($this->note_private)."'":"null"); - $sql.= ",".($this->note_public?"'".$this->db->escape($this->note_public)."'":"null"); - $sql.= ",".($this->ref_client?"'".$this->db->escape($this->ref_client)."'":"null"); - $sql.= ",".($this->ref_int?"'".$this->db->escape($this->ref_int)."'":"null"); - $sql.= ",".($this->fk_facture_source?"'".$this->db->escape($this->fk_facture_source)."'":"null"); - $sql.= ",".($user->id > 0 ? "'".$user->id."'":"null"); - $sql.= ",".($this->fk_project?$this->fk_project:"null"); - $sql.= ','.$this->cond_reglement_id; - $sql.= ",".$this->mode_reglement_id; - $sql.= ", '".$this->db->idate($datelim)."', '".$this->modelpdf."')"; + $sql = "INSERT INTO ".MAIN_DB_PREFIX."facture ("; + $sql.= " facnumber"; + $sql.= ", entity"; + $sql.= ", ref_ext"; + $sql.= ", type"; + $sql.= ", fk_soc"; + $sql.= ", datec"; + $sql.= ", remise_absolue"; + $sql.= ", remise_percent"; + $sql.= ", datef"; + $sql.= ", note_private"; + $sql.= ", note_public"; + $sql.= ", ref_client, ref_int"; + $sql.= ", fk_facture_source, fk_user_author, fk_projet"; + $sql.= ", fk_cond_reglement, fk_mode_reglement, date_lim_reglement, model_pdf"; + $sql.= ")"; + $sql.= " VALUES ("; + $sql.= "'(PROV)'"; + $sql.= ", ".$conf->entity; + $sql.= ", ".($this->ref_ext?"'".$this->db->escape($this->ref_ext)."'":"null"); + $sql.= ", '".$this->type."'"; + $sql.= ", '".$socid."'"; + $sql.= ", '".$this->db->idate($now)."'"; + $sql.= ",".($this->remise_absolue>0?$this->remise_absolue:'NULL'); + $sql.= ",".($this->remise_percent>0?$this->remise_percent:'NULL'); + $sql.= ", '".$this->db->idate($this->date)."'"; + $sql.= ",".($this->note_private?"'".$this->db->escape($this->note_private)."'":"null"); + $sql.= ",".($this->note_public?"'".$this->db->escape($this->note_public)."'":"null"); + $sql.= ",".($this->ref_client?"'".$this->db->escape($this->ref_client)."'":"null"); + $sql.= ",".($this->ref_int?"'".$this->db->escape($this->ref_int)."'":"null"); + $sql.= ",".($this->fk_facture_source?"'".$this->db->escape($this->fk_facture_source)."'":"null"); + $sql.= ",".($user->id > 0 ? "'".$user->id."'":"null"); + $sql.= ",".($this->fk_project?$this->fk_project:"null"); + $sql.= ','.$this->cond_reglement_id; + $sql.= ",".$this->mode_reglement_id; + $sql.= ", '".$this->db->idate($datelim)."', '".$this->modelpdf."')"; - dol_syslog(get_class($this)."::create sql=".$sql); - $resql=$this->db->query($sql); - if ($resql) - { - $this->id = $this->db->last_insert_id(MAIN_DB_PREFIX.'facture'); + dol_syslog(get_class($this)."::create sql=".$sql); + $resql=$this->db->query($sql); + if ($resql) + { + $this->id = $this->db->last_insert_id(MAIN_DB_PREFIX.'facture'); - // Update ref with new one - $this->ref='(PROV'.$this->id.')'; - $sql = 'UPDATE '.MAIN_DB_PREFIX."facture SET facnumber='".$this->ref."' WHERE rowid=".$this->id; + // Update ref with new one + $this->ref='(PROV'.$this->id.')'; + $sql = 'UPDATE '.MAIN_DB_PREFIX."facture SET facnumber='".$this->ref."' WHERE rowid=".$this->id; - dol_syslog(get_class($this)."::create sql=".$sql); - $resql=$this->db->query($sql); - if (! $resql) $error++; + dol_syslog(get_class($this)."::create sql=".$sql); + $resql=$this->db->query($sql); + if (! $resql) $error++; - // Add object linked - if (! $error && $this->id && is_array($this->linked_objects) && ! empty($this->linked_objects)) - { - foreach($this->linked_objects as $origin => $origin_id) - { - $ret = $this->add_object_linked($origin, $origin_id); - if (! $ret) - { - dol_print_error($this->db); - $error++; - } + // Add object linked + if (! $error && $this->id && is_array($this->linked_objects) && ! empty($this->linked_objects)) + { + foreach($this->linked_objects as $origin => $origin_id) + { + $ret = $this->add_object_linked($origin, $origin_id); + if (! $ret) + { + dol_print_error($this->db); + $error++; + } - // TODO mutualiser - if ($origin == 'commande') - { - // On recupere les differents contact interne et externe - $order = new Commande($this->db); - $order->id = $origin_id; + // TODO mutualiser + if ($origin == 'commande') + { + // On recupere les differents contact interne et externe + $order = new Commande($this->db); + $order->id = $origin_id; - // On recupere le commercial suivi propale - $this->userid = $order->getIdcontact('internal', 'SALESREPFOLL'); + // On recupere le commercial suivi propale + $this->userid = $order->getIdcontact('internal', 'SALESREPFOLL'); - if ($this->userid) - { - //On passe le commercial suivi commande en commercial suivi paiement - $this->add_contact($this->userid[0], 'SALESREPFOLL', 'internal'); - } + if ($this->userid) + { + //On passe le commercial suivi commande en commercial suivi paiement + $this->add_contact($this->userid[0], 'SALESREPFOLL', 'internal'); + } - // On recupere le contact client facturation commande - $this->contactid = $order->getIdcontact('external', 'BILLING'); + // On recupere le contact client facturation commande + $this->contactid = $order->getIdcontact('external', 'BILLING'); - if ($this->contactid) - { - //On passe le contact client facturation commande en contact client facturation - $this->add_contact($this->contactid[0], 'BILLING', 'external'); - } - } - } - } + if ($this->contactid) + { + //On passe le contact client facturation commande en contact client facturation + $this->add_contact($this->contactid[0], 'BILLING', 'external'); + } + } + } + } - /* - * Insert lines of invoices into database - */ - if (count($this->lines) && is_object($this->lines[0])) - { - $fk_parent_line = 0; + /* + * Insert lines of invoices into database + */ + if (count($this->lines) && is_object($this->lines[0])) + { + $fk_parent_line = 0; - dol_syslog("There is ".count($this->lines)." lines that are invoice lines objects"); - foreach ($this->lines as $i => $val) - { - $newinvoiceline=new FactureLigne($this->db); - $newinvoiceline=$this->lines[$i]; - $newinvoiceline->fk_facture=$this->id; - if ($result >= 0 && ($newinvoiceline->info_bits & 0x01) == 0) // We keep only lines with first bit = 0 - { - // Reset fk_parent_line for no child products and special product + dol_syslog("There is ".count($this->lines)." lines that are invoice lines objects"); + foreach ($this->lines as $i => $val) + { + $newinvoiceline=new FactureLigne($this->db); + $newinvoiceline=$this->lines[$i]; + $newinvoiceline->fk_facture=$this->id; + if ($result >= 0 && ($newinvoiceline->info_bits & 0x01) == 0) // We keep only lines with first bit = 0 + { + // Reset fk_parent_line for no child products and special product if (($newinvoiceline->product_type != 9 && empty($newinvoiceline->fk_parent_line)) || $newinvoiceline->product_type == 9) { $fk_parent_line = 0; } - $newinvoiceline->fk_parent_line=$fk_parent_line; + $newinvoiceline->fk_parent_line=$fk_parent_line; $result=$newinvoiceline->insert(); - // Defined the new fk_parent_line + // Defined the new fk_parent_line if ($result > 0 && $newinvoiceline->product_type == 9) { $fk_parent_line = $result; } - } - if ($result < 0) - { - $this->error=$newinvoiceline->error; - $error++; - break; - } - } - } - else - { - $fk_parent_line = 0; + } + if ($result < 0) + { + $this->error=$newinvoiceline->error; + $error++; + break; + } + } + } + else + { + $fk_parent_line = 0; - dol_syslog("There is ".count($this->lines)." lines that are array lines"); - foreach ($this->lines as $i => $val) - { - if (($this->lines[$i]->info_bits & 0x01) == 0) // We keep only lines with first bit = 0 - { - // Reset fk_parent_line for no child products and special product + dol_syslog("There is ".count($this->lines)." lines that are array lines"); + foreach ($this->lines as $i => $val) + { + if (($this->lines[$i]->info_bits & 0x01) == 0) // We keep only lines with first bit = 0 + { + // 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->id, - $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, - $this->lines[$i]->date_start, - $this->lines[$i]->date_end, - $this->lines[$i]->fk_code_ventilation, - $this->lines[$i]->info_bits, - $this->lines[$i]->fk_remise_except, - 'HT', - 0, - $this->lines[$i]->product_type, - $this->lines[$i]->rang, - $this->lines[$i]->special_code, - '', - 0, - $fk_parent_line, - $this->lines[$i]->fk_fournprice, - $this->lines[$i]->pa_ht, - $this->lines[$i]->label - ); - if ($result < 0) - { - $this->error=$this->db->lasterror(); - dol_print_error($this->db); - $this->db->rollback(); - return -1; - } + $result = $this->addline( + $this->id, + $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, + $this->lines[$i]->date_start, + $this->lines[$i]->date_end, + $this->lines[$i]->fk_code_ventilation, + $this->lines[$i]->info_bits, + $this->lines[$i]->fk_remise_except, + 'HT', + 0, + $this->lines[$i]->product_type, + $this->lines[$i]->rang, + $this->lines[$i]->special_code, + '', + 0, + $fk_parent_line, + $this->lines[$i]->fk_fournprice, + $this->lines[$i]->pa_ht, + $this->lines[$i]->label + ); + if ($result < 0) + { + $this->error=$this->db->lasterror(); + dol_print_error($this->db); + $this->db->rollback(); + return -1; + } - // Defined the new fk_parent_line + // Defined the new fk_parent_line if ($result > 0 && $this->lines[$i]->product_type == 9) { $fk_parent_line = $result; } - } - } - } + } + } + } - /* - * Insert lines of predefined invoices - */ - if (! $error && $this->fac_rec > 0) - { - foreach ($_facrec->lines as $i => $val) - { - if ($_facrec->lines[$i]->fk_product) - { - $prod = new Product($this->db); - $res=$prod->fetch($_facrec->lines[$i]->fk_product); - } - $tva_tx = get_default_tva($mysoc,$soc,$prod->id); - $localtax1_tx=get_localtax($tva_tx,1,$soc); - $localtax2_tx=get_localtax($tva_tx,2,$soc); + /* + * Insert lines of predefined invoices + */ + if (! $error && $this->fac_rec > 0) + { + foreach ($_facrec->lines as $i => $val) + { + if ($_facrec->lines[$i]->fk_product) + { + $prod = new Product($this->db); + $res=$prod->fetch($_facrec->lines[$i]->fk_product); + } + $tva_tx = get_default_tva($mysoc,$soc,$prod->id); + $localtax1_tx=get_localtax($tva_tx,1,$soc); + $localtax2_tx=get_localtax($tva_tx,2,$soc); - $result_insert = $this->addline( - $this->id, - $_facrec->lines[$i]->desc, - $_facrec->lines[$i]->subprice, - $_facrec->lines[$i]->qty, - $tva_tx, - $localtax1_tx, - $localtax2_tx, - $_facrec->lines[$i]->fk_product, - $_facrec->lines[$i]->remise_percent, - '','',0,0,'','HT',0, - $_facrec->lines[$i]->product_type, - $_facrec->lines[$i]->rang, - $_facrec->lines[$i]->special_code, - '', - 0, - 0, - null, - 0, - $_facrec->lines[$i]->label - ); + $result_insert = $this->addline( + $this->id, + $_facrec->lines[$i]->desc, + $_facrec->lines[$i]->subprice, + $_facrec->lines[$i]->qty, + $tva_tx, + $localtax1_tx, + $localtax2_tx, + $_facrec->lines[$i]->fk_product, + $_facrec->lines[$i]->remise_percent, + '','',0,0,'','HT',0, + $_facrec->lines[$i]->product_type, + $_facrec->lines[$i]->rang, + $_facrec->lines[$i]->special_code, + '', + 0, + 0, + null, + 0, + $_facrec->lines[$i]->label + ); - if ( $result_insert < 0) - { - $error++; - $this->error=$this->db->error(); - break; - } - } - } + if ( $result_insert < 0) + { + $error++; + $this->error=$this->db->error(); + break; + } + } + } - if (! $error) - { - $result=$this->update_price(1); - if ($result > 0) - { - // Actions on extra fields (by external module or standard code) - // FIXME le hook fait double emploi avec le trigger !! - $hookmanager->initHooks(array('invoicedao')); - $parameters=array('invoiceid'=>$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) + { + $result=$this->update_price(1); + if ($result > 0) + { + // Actions on extra fields (by external module or standard code) + // FIXME le hook fait double emploi avec le trigger !! + $hookmanager->initHooks(array('invoicedao')); + $parameters=array('invoiceid'=>$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++; - // Appel des triggers - include_once DOL_DOCUMENT_ROOT . '/core/class/interfaces.class.php'; - $interface=new Interfaces($this->db); - $result=$interface->run_triggers('BILL_CREATE',$this,$user,$langs,$conf); - if ($result < 0) { $error++; $this->errors=$interface->errors; } - // Fin appel triggers + // Appel des triggers + include_once DOL_DOCUMENT_ROOT . '/core/class/interfaces.class.php'; + $interface=new Interfaces($this->db); + $result=$interface->run_triggers('BILL_CREATE',$this,$user,$langs,$conf); + if ($result < 0) { + $error++; $this->errors=$interface->errors; + } + // Fin appel triggers - if (! $error) - { - $this->db->commit(); - return $this->id; - } - else - { - $this->db->rollback(); - return -4; - } - } - else - { - $this->error=$langs->trans('FailedToUpdatePrice'); - $this->db->rollback(); - return -3; - } - } - else - { - dol_syslog(get_class($this)."::create error ".$this->error, LOG_ERR); - $this->db->rollback(); - return -2; - } - } - else - { - $this->error=$this->db->error(); - dol_syslog(get_class($this)."::create error ".$this->error." sql=".$sql, LOG_ERR); - $this->db->rollback(); - return -1; - } - } + if (! $error) + { + $this->db->commit(); + return $this->id; + } + else + { + $this->db->rollback(); + return -4; + } + } + else + { + $this->error=$langs->trans('FailedToUpdatePrice'); + $this->db->rollback(); + return -3; + } + } + else + { + dol_syslog(get_class($this)."::create error ".$this->error, LOG_ERR); + $this->db->rollback(); + return -2; + } + } + else + { + $this->error=$this->db->error(); + dol_syslog(get_class($this)."::create error ".$this->error." sql=".$sql, LOG_ERR); + $this->db->rollback(); + return -1; + } + } - /** - * Create a new invoice in database from current invoice - * - * @param User $user Object user that ask creation - * @param int $invertdetail Reverse sign of amounts for lines - * @return int <0 if KO, >0 if OK - */ - function createFromCurrent($user,$invertdetail=0) - { - // Charge facture source - $facture=new Facture($this->db); + /** + * Create a new invoice in database from current invoice + * + * @param User $user Object user that ask creation + * @param int $invertdetail Reverse sign of amounts for lines + * @return int <0 if KO, >0 if OK + */ + function createFromCurrent($user,$invertdetail=0) + { + // Charge facture source + $facture=new Facture($this->db); - $facture->fk_facture_source = $this->fk_facture_source; - $facture->type = $this->type; - $facture->socid = $this->socid; - $facture->date = $this->date; - $facture->note_public = $this->note_public; - $facture->note_private = $this->note_private; - $facture->ref_client = $this->ref_client; - $facture->modelpdf = $this->modelpdf; - $facture->fk_project = $this->fk_project; - $facture->cond_reglement_id = $this->cond_reglement_id; - $facture->mode_reglement_id = $this->mode_reglement_id; - $facture->remise_absolue = $this->remise_absolue; - $facture->remise_percent = $this->remise_percent; + $facture->fk_facture_source = $this->fk_facture_source; + $facture->type = $this->type; + $facture->socid = $this->socid; + $facture->date = $this->date; + $facture->note_public = $this->note_public; + $facture->note_private = $this->note_private; + $facture->ref_client = $this->ref_client; + $facture->modelpdf = $this->modelpdf; + $facture->fk_project = $this->fk_project; + $facture->cond_reglement_id = $this->cond_reglement_id; + $facture->mode_reglement_id = $this->mode_reglement_id; + $facture->remise_absolue = $this->remise_absolue; + $facture->remise_percent = $this->remise_percent; - $facture->lines = $this->lines; // Tableau des lignes de factures - $facture->products = $this->lines; // Tant que products encore utilise + $facture->lines = $this->lines; // Tableau des lignes de factures + $facture->products = $this->lines; // Tant que products encore utilise - // Loop on each line of new invoice - foreach($facture->lines as $i => $line) - { - if ($invertdetail) - { - $facture->lines[$i]->subprice = -$facture->lines[$i]->subprice; - $facture->lines[$i]->total_ht = -$facture->lines[$i]->total_ht; - $facture->lines[$i]->total_tva = -$facture->lines[$i]->total_tva; - $facture->lines[$i]->total_localtax1 = -$facture->lines[$i]->total_localtax1; - $facture->lines[$i]->total_localtax2 = -$facture->lines[$i]->total_localtax2; - $facture->lines[$i]->total_ttc = -$facture->lines[$i]->total_ttc; - } - } + // Loop on each line of new invoice + foreach($facture->lines as $i => $line) + { + if ($invertdetail) + { + $facture->lines[$i]->subprice = -$facture->lines[$i]->subprice; + $facture->lines[$i]->total_ht = -$facture->lines[$i]->total_ht; + $facture->lines[$i]->total_tva = -$facture->lines[$i]->total_tva; + $facture->lines[$i]->total_localtax1 = -$facture->lines[$i]->total_localtax1; + $facture->lines[$i]->total_localtax2 = -$facture->lines[$i]->total_localtax2; + $facture->lines[$i]->total_ttc = -$facture->lines[$i]->total_ttc; + } + } - dol_syslog(get_class($this)."::createFromCurrent invertdetail=".$invertdetail." socid=".$this->socid." nboflines=".count($facture->lines)); + dol_syslog(get_class($this)."::createFromCurrent invertdetail=".$invertdetail." socid=".$this->socid." nboflines=".count($facture->lines)); - $facid = $facture->create($user); - if ($facid <= 0) - { - $this->error=$facture->error; - $this->errors=$facture->errors; - } + $facid = $facture->create($user); + if ($facid <= 0) + { + $this->error=$facture->error; + $this->errors=$facture->errors; + } - return $facid; - } + return $facid; + } - /** - * 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 $conf,$user,$langs; + /** + * 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 $conf,$user,$langs; - $error=0; + $error=0; - $this->db->begin(); + $this->db->begin(); - // Load source object - $objFrom = dol_clone($this); + // Load source object + $objFrom = dol_clone($this); - // Change socid if needed - if (! empty($socid) && $socid != $this->socid) - { - $objsoc = new Societe($this->db); + // Change socid if needed + if (! empty($socid) && $socid != $this->socid) + { + $objsoc = new Societe($this->db); - 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 = ''; - $this->fk_delivery_address = ''; - } + 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 = ''; + $this->fk_delivery_address = ''; + } - // TODO Change product price if multi-prices - } + // TODO Change product price if multi-prices + } - $this->id=0; - $this->statut=0; + $this->id=0; + $this->statut=0; - // Clear fields - $this->user_author = $user->id; - $this->user_valid = ''; - $this->fk_facture_source = 0; - $this->date_creation = ''; - $this->date_validation = ''; - $this->ref_client = ''; - $this->close_code = ''; - $this->close_note = ''; - $this->products = $this->lines; // Tant que products encore utilise + // Clear fields + $this->user_author = $user->id; + $this->user_valid = ''; + $this->fk_facture_source = 0; + $this->date_creation = ''; + $this->date_validation = ''; + $this->ref_client = ''; + $this->close_code = ''; + $this->close_note = ''; + $this->products = $this->lines; // Tant que products encore utilise - // Loop on each line of new invoice - foreach($this->lines as $i => $line) - { - if (($this->lines[$i]->info_bits & 0x02) == 0x02) // We do not clone line of discounts - { - unset($this->lines[$i]); - unset($this->products[$i]); // Tant que products encore utilise - } - } + // Loop on each line of new invoice + foreach($this->lines as $i => $line) + { + if (($this->lines[$i]->info_bits & 0x02) == 0x02) // We do not clone line of discounts + { + unset($this->lines[$i]); + unset($this->products[$i]); // Tant que products encore utilise + } + } - // Create clone - $result=$this->create($user); - if ($result < 0) $error++; + // Create clone + $result=$this->create($user); + if ($result < 0) $error++; - if (! $error) - { - // Hook of thirdparty module + if (! $error) + { + // Hook of thirdparty module if (is_object($hookmanager)) { - $parameters=array('objFrom'=>$objFrom); - $action=''; + $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++; } - // Appel des triggers - include_once DOL_DOCUMENT_ROOT . '/core/class/interfaces.class.php'; - $interface=new Interfaces($this->db); - $result=$interface->run_triggers('BILL_CLONE',$this,$user,$langs,$conf); - if ($result < 0) { $error++; $this->errors=$interface->errors; } - // Fin appel triggers - } - - // End - if (! $error) - { - $this->db->commit(); - return $this->id; - } - else - { - $this->db->rollback(); - return -1; - } - } - - /** - * Load an object from an order and create a new invoice into database - * - * @param Object $object Object source - * @return int <0 if KO, 0 if nothing done, 1 if OK - */ - function createFromOrder($object) - { - global $conf,$user,$langs,$hookmanager; - - $error=0; - - // Closed order - $this->date = dol_now(); - $this->source = 0; - - $num=count($object->lines); - for ($i = 0; $i < $num; $i++) - { - $line = new FactureLigne($this->db); - - $line->libelle = $object->lines[$i]->libelle; - $line->label = $object->lines[$i]->label; - $line->desc = $object->lines[$i]->desc; - $line->subprice = $object->lines[$i]->subprice; - $line->total_ht = $object->lines[$i]->total_ht; - $line->total_tva = $object->lines[$i]->total_tva; - $line->total_ttc = $object->lines[$i]->total_ttc; - $line->tva_tx = $object->lines[$i]->tva_tx; - $line->localtax1_tx = $object->lines[$i]->localtax1_tx; - $line->localtax2_tx = $object->lines[$i]->localtax2_tx; - $line->qty = $object->lines[$i]->qty; - $line->fk_remise_except = $object->lines[$i]->fk_remise_except; - $line->remise_percent = $object->lines[$i]->remise_percent; - $line->fk_product = $object->lines[$i]->fk_product; - $line->info_bits = $object->lines[$i]->info_bits; - $line->product_type = $object->lines[$i]->product_type; - $line->rang = $object->lines[$i]->rang; - $line->special_code = $object->lines[$i]->special_code; - $line->fk_parent_line = $object->lines[$i]->fk_parent_line; - - $this->lines[$i] = $line; - } - - $this->socid = $object->socid; - $this->fk_project = $object->fk_project; - $this->cond_reglement_id = $object->cond_reglement_id; - $this->mode_reglement_id = $object->mode_reglement_id; - $this->availability_id = $object->availability_id; - $this->demand_reason_id = $object->demand_reason_id; - $this->date_livraison = $object->date_livraison; - $this->fk_delivery_address = $object->fk_delivery_address; - $this->contact_id = $object->contactid; - $this->ref_client = $object->ref_client; - $this->note_private = $object->note_private; - $this->note_public = $object->note_public; - - $this->origin = $object->element; - $this->origin_id = $object->id; - - // Possibility to add external linked objects with hooks - $this->linked_objects[$this->origin] = $this->origin_id; - if (! empty($object->other_linked_objects) && is_array($object->other_linked_objects)) - { - $this->linked_objects = array_merge($this->linked_objects, $object->other_linked_objects); - } - - $ret = $this->create($user); - - if ($ret > 0) - { - // Actions hooked (by external module) - $hookmanager->initHooks(array('invoicedao')); - - $parameters=array('objFrom'=>$object); - $action=''; - $reshook=$hookmanager->executeHooks('createFrom',$parameters,$this,$action); // Note that $action and $object may have been modified by some hooks - if ($reshook < 0) $error++; - - if (! $error) - { - return 1; - } - else return -1; - } - else return -1; - } - - /** - * Return clicable link of object (with eventually picto) - * - * @param int $withpicto Add picto into link - * @param string $option Where point the link - * @param int $max Maxlength of ref - * @param int $short 1=Return just URL - * @param string $moretitle Add more text to title tooltip - * @return string String with URL - */ - function getNomUrl($withpicto=0,$option='',$max=0,$short=0,$moretitle='') - { - global $langs; - - $result=''; - - if ($option == 'withdraw') $url = DOL_URL_ROOT.'/compta/facture/prelevement.php?facid='.$this->id; - else $url = DOL_URL_ROOT.'/compta/facture.php?facid='.$this->id; - - if ($short) return $url; - - $picto='bill'; - if ($this->type == 1) $picto.='r'; // Replacement invoice - if ($this->type == 2) $picto.='a'; // Credit note - if ($this->type == 3) $picto.='d'; // Deposit invoice - - $label=$langs->trans("ShowInvoice").': '.$this->ref; - if ($this->type == 1) $label=$langs->transnoentitiesnoconv("ShowInvoiceReplace").': '.$this->ref; - if ($this->type == 2) $label=$langs->transnoentitiesnoconv("ShowInvoiceAvoir").': '.$this->ref; - if ($this->type == 3) $label=$langs->transnoentitiesnoconv("ShowInvoiceDeposit").': '.$this->ref; - if ($moretitle) $label.=' - '.$moretitle; - - //$linkstart=''; - $linkstart=''; - $linkend=''; - - if ($withpicto) $result.=($linkstart.img_object(($max?dol_trunc($label,$max):$label),$picto).$linkend); - if ($withpicto && $withpicto != 2) $result.=' '; - if ($withpicto != 2) $result.=$linkstart.($max?dol_trunc($this->ref,$max):$this->ref).$linkend; - return $result; - } - - - /** - * Get object and lines from database - * - * @param int $rowid Id of object to load - * @param string $ref Reference of invoice - * @param string $ref_ext External reference of invoice - * @param int $ref_int Internal reference of other object - * @return int >0 if OK, <0 if KO, 0 if not found - */ - function fetch($rowid, $ref='', $ref_ext='', $ref_int='') - { - global $conf; - - if (empty($rowid) && empty($ref) && empty($ref_ext) && empty($ref_int)) return -1; - - $sql = 'SELECT f.rowid,f.facnumber,f.ref_client,f.ref_ext,f.ref_int,f.type,f.fk_soc,f.amount,f.tva, f.localtax1, f.localtax2, f.total, f.total_ttc, f.revenuestamp'; - $sql.= ', f.remise_percent, f.remise_absolue, f.remise'; - $sql.= ', f.datef as df'; - $sql.= ', f.date_lim_reglement as dlr'; - $sql.= ', f.datec as datec'; - $sql.= ', f.date_valid as datev'; - $sql.= ', f.tms as datem'; - $sql.= ', f.note_private, f.note_public, f.fk_statut, f.paye, f.close_code, f.close_note, f.fk_user_author, f.fk_user_valid, f.model_pdf'; - $sql.= ', f.fk_facture_source'; - $sql.= ', f.fk_mode_reglement, f.fk_cond_reglement, f.fk_projet, f.extraparams'; - $sql.= ', p.code as mode_reglement_code, p.libelle as mode_reglement_libelle'; - $sql.= ', c.code as cond_reglement_code, c.libelle as cond_reglement_libelle, c.libelle_facture as cond_reglement_libelle_doc'; - $sql.= ' FROM '.MAIN_DB_PREFIX.'facture as f'; - $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_payment_term as c ON f.fk_cond_reglement = c.rowid'; - $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_paiement as p ON f.fk_mode_reglement = p.id'; - $sql.= ' WHERE f.entity = '.$conf->entity; - if ($rowid) $sql.= " AND f.rowid=".$rowid; - if ($ref) $sql.= " AND f.facnumber='".$this->db->escape($ref)."'"; - if ($ref_ext) $sql.= " AND f.ref_ext='".$this->db->escape($ref_ext)."'"; - if ($ref_int) $sql.= " AND f.ref_int='".$this->db->escape($ref_int)."'"; - - dol_syslog(get_class($this)."::fetch sql=".$sql, LOG_DEBUG); - $result = $this->db->query($sql); - if ($result) - { - if ($this->db->num_rows($result)) - { - $obj = $this->db->fetch_object($result); - - $this->id = $obj->rowid; - $this->ref = $obj->facnumber; - $this->ref_client = $obj->ref_client; - $this->ref_ext = $obj->ref_ext; - $this->ref_int = $obj->ref_int; - $this->type = $obj->type; - $this->date = $this->db->jdate($obj->df); - $this->date_creation = $this->db->jdate($obj->datec); - $this->date_validation = $this->db->jdate($obj->datev); - $this->datem = $this->db->jdate($obj->datem); - $this->remise_percent = $obj->remise_percent; - $this->remise_absolue = $obj->remise_absolue; - //$this->remise = $obj->remise; - $this->total_ht = $obj->total; - $this->total_tva = $obj->tva; - $this->total_localtax1 = $obj->localtax1; - $this->total_localtax2 = $obj->localtax2; - $this->total_ttc = $obj->total_ttc; - $this->revenuestamp = $obj->revenuestamp; - $this->paye = $obj->paye; - $this->close_code = $obj->close_code; - $this->close_note = $obj->close_note; - $this->socid = $obj->fk_soc; - $this->statut = $obj->fk_statut; - $this->date_lim_reglement = $this->db->jdate($obj->dlr); - $this->mode_reglement_id = $obj->fk_mode_reglement; - $this->mode_reglement_code = $obj->mode_reglement_code; - $this->mode_reglement = $obj->mode_reglement_libelle; - $this->cond_reglement_id = $obj->fk_cond_reglement; - $this->cond_reglement_code = $obj->cond_reglement_code; - $this->cond_reglement = $obj->cond_reglement_libelle; - $this->cond_reglement_doc = $obj->cond_reglement_libelle_doc; - $this->fk_project = $obj->fk_projet; - $this->fk_facture_source = $obj->fk_facture_source; - $this->note = $obj->note_private; // deprecated - $this->note_private = $obj->note_private; - $this->note_public = $obj->note_public; - $this->user_author = $obj->fk_user_author; - $this->user_valid = $obj->fk_user_valid; - $this->modelpdf = $obj->model_pdf; - - $this->extraparams = (array) json_decode($obj->extraparams, true); - - if ($this->statut == 0) $this->brouillon = 1; - - // Retreive all extrafield for invoice - // fetch optionals attributes and labels - if(!class_exists('Extrafields')) - require_once(DOL_DOCUMENT_ROOT.'/core/class/extrafields.class.php'); - $extrafields=new ExtraFields($this->db); - $extralabels=$extrafields->fetch_name_optionals_label('facture',true); - if (count($extralabels)>0) { - $this->array_options = array(); - } - foreach($extrafields->attribute_label as $key=>$label) - { - $this->array_options['options_'.$key]=$label; - } - - /* - * Lines - */ - - $this->lines = array(); - - $result=$this->fetch_lines(); - if ($result < 0) - { - $this->error=$this->db->error(); - dol_syslog(get_class($this)."::fetch Error ".$this->error, LOG_ERR); - return -3; - } - return 1; - } - else - { - $this->error='Bill with id '.$rowid.' or ref '.$ref.' not found sql='.$sql; - dol_syslog(get_class($this)."::fetch Error ".$this->error, LOG_ERR); - return 0; - } - } - else - { - $this->error=$this->db->error(); - dol_syslog(get_class($this)."::fetch Error ".$this->error, LOG_ERR); - return -1; - } - } - - - /** - * Load all detailed lines into this->lines - * - * @return int 1 if OK, < 0 if KO - */ - function fetch_lines() - { - $this->lines=array(); - - $sql = 'SELECT l.rowid, l.fk_product, l.fk_parent_line, l.label as custom_label, l.description, l.product_type, l.price, l.qty, l.tva_tx, '; - $sql.= ' l.localtax1_tx, l.localtax2_tx, l.remise, l.remise_percent, l.fk_remise_except, l.subprice,'; - $sql.= ' l.rang, l.special_code,'; - $sql.= ' l.date_start as date_start, l.date_end as date_end,'; - $sql.= ' l.info_bits, l.total_ht, l.total_tva, l.total_localtax1, l.total_localtax2, l.total_ttc, l.fk_code_ventilation, l.fk_product_fournisseur_price as fk_fournprice, l.buy_price_ht as pa_ht,'; - $sql.= ' p.ref as product_ref, p.fk_product_type as fk_product_type, p.label as product_label, p.description as product_desc'; - $sql.= ' FROM '.MAIN_DB_PREFIX.'facturedet as l'; - $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'product as p ON l.fk_product = p.rowid'; - $sql.= ' WHERE l.fk_facture = '.$this->id; - $sql.= ' ORDER BY l.rang'; - - dol_syslog(get_class($this).'::fetch_lines sql='.$sql, LOG_DEBUG); - $result = $this->db->query($sql); - if ($result) - { - $num = $this->db->num_rows($result); - $i = 0; - while ($i < $num) - { - $objp = $this->db->fetch_object($result); - $line = new FactureLigne($this->db); - - $line->rowid = $objp->rowid; - $line->label = $objp->custom_label; - $line->desc = $objp->description; // Description line - $line->product_type = $objp->product_type; // Type of line - $line->product_ref = $objp->product_ref; // Ref product - $line->libelle = $objp->product_label; // TODO deprecated - $line->product_label = $objp->product_label; // Label product - $line->product_desc = $objp->product_desc; // Description product - $line->fk_product_type = $objp->fk_product_type; // Type of product - $line->qty = $objp->qty; - $line->subprice = $objp->subprice; - $line->tva_tx = $objp->tva_tx; - $line->localtax1_tx = $objp->localtax1_tx; - $line->localtax2_tx = $objp->localtax2_tx; - $line->remise_percent = $objp->remise_percent; - $line->fk_remise_except = $objp->fk_remise_except; - $line->fk_product = $objp->fk_product; - $line->date_start = $this->db->jdate($objp->date_start); - $line->date_end = $this->db->jdate($objp->date_end); - $line->date_start = $this->db->jdate($objp->date_start); - $line->date_end = $this->db->jdate($objp->date_end); - $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->code_ventilation = $objp->fk_code_ventilation; - $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->rang = $objp->rang; - $line->special_code = $objp->special_code; - $line->fk_parent_line = $objp->fk_parent_line; - - // Ne plus utiliser - //$line->price = $objp->price; - //$line->remise = $objp->remise; - - $this->lines[$i] = $line; - - $i++; - } - $this->db->free($result); - return 1; - } - else - { - $this->error=$this->db->error(); - dol_syslog(get_class($this).'::fetch_lines '.$this->error,LOG_ERR); - return -3; - } - } - - - /** - * Update database - * - * @param User $user User that modify - * @param int $notrigger 0=launch triggers after, 1=disable triggers - * @return int <0 if KO, >0 if OK - */ - function update($user=0, $notrigger=0) - { - global $conf, $langs; - $error=0; - - // Clean parameters - if (empty($this->type)) $this->type=0; - if (isset($this->facnumber)) $this->facnumber=trim($this->ref); - if (isset($this->ref_client)) $this->ref_client=trim($this->ref_client); - if (isset($this->increment)) $this->increment=trim($this->increment); - if (isset($this->close_code)) $this->close_code=trim($this->close_code); - if (isset($this->close_note)) $this->close_note=trim($this->close_note); - if (isset($this->note) || isset($this->note_private)) $this->note=(isset($this->note) ? trim($this->note) : trim($this->note_private)); // deprecated - if (isset($this->note) || isset($this->note_private)) $this->note_private=(isset($this->note_private) ? trim($this->note_private) : trim($this->note)); - if (isset($this->note_public)) $this->note_public=trim($this->note_public); - if (isset($this->modelpdf)) $this->modelpdf=trim($this->modelpdf); - if (isset($this->import_key)) $this->import_key=trim($this->import_key); - - // Check parameters - // Put here code to add control on parameters values - - // Update request - $sql = "UPDATE ".MAIN_DB_PREFIX."facture SET"; - - $sql.= " facnumber=".(isset($this->ref)?"'".$this->db->escape($this->ref)."'":"null").","; - $sql.= " type=".(isset($this->type)?$this->type:"null").","; - $sql.= " ref_client=".(isset($this->ref_client)?"'".$this->db->escape($this->ref_client)."'":"null").","; - $sql.= " increment=".(isset($this->increment)?"'".$this->db->escape($this->increment)."'":"null").","; - $sql.= " fk_soc=".(isset($this->socid)?$this->socid:"null").","; - $sql.= " datec=".(strval($this->date_creation)!='' ? "'".$this->db->idate($this->date_creation)."'" : 'null').","; - $sql.= " datef=".(strval($this->date)!='' ? "'".$this->db->idate($this->date)."'" : 'null').","; - $sql.= " date_valid=".(strval($this->date_validation)!='' ? "'".$this->db->idate($this->date_validation)."'" : 'null').","; - $sql.= " paye=".(isset($this->paye)?$this->paye:"null").","; - $sql.= " remise_percent=".(isset($this->remise_percent)?$this->remise_percent:"null").","; - $sql.= " remise_absolue=".(isset($this->remise_absolue)?$this->remise_absolue:"null").","; - //$sql.= " remise=".(isset($this->remise)?$this->remise:"null").","; - $sql.= " close_code=".(isset($this->close_code)?"'".$this->db->escape($this->close_code)."'":"null").","; - $sql.= " close_note=".(isset($this->close_note)?"'".$this->db->escape($this->close_note)."'":"null").","; - $sql.= " tva=".(isset($this->total_tva)?$this->total_tva:"null").","; - $sql.= " localtax1=".(isset($this->total_localtax1)?$this->total_localtax1:"null").","; - $sql.= " localtax2=".(isset($this->total_localtax2)?$this->total_localtax2:"null").","; - $sql.= " total=".(isset($this->total_ht)?$this->total_ht:"null").","; - $sql.= " total_ttc=".(isset($this->total_ttc)?$this->total_ttc:"null").","; - $sql.= " revenuestamp=".((isset($this->revenuestamp) && $this->revenuestamp != '')?$this->revenuestamp:"null").","; - $sql.= " fk_statut=".(isset($this->statut)?$this->statut:"null").","; - $sql.= " fk_user_author=".(isset($this->user_author)?$this->user_author:"null").","; - $sql.= " fk_user_valid=".(isset($this->fk_user_valid)?$this->fk_user_valid:"null").","; - $sql.= " fk_facture_source=".(isset($this->fk_facture_source)?$this->fk_facture_source:"null").","; - $sql.= " fk_projet=".(isset($this->fk_project)?$this->fk_project:"null").","; - $sql.= " fk_cond_reglement=".(isset($this->cond_reglement_id)?$this->cond_reglement_id:"null").","; - $sql.= " fk_mode_reglement=".(isset($this->mode_reglement_id)?$this->mode_reglement_id:"null").","; - $sql.= " date_lim_reglement=".(strval($this->date_lim_reglement)!='' ? "'".$this->db->idate($this->date_lim_reglement)."'" : 'null').","; - $sql.= " note_private=".(isset($this->note_private)?"'".$this->db->escape($this->note_private)."'":"null").","; - $sql.= " note_public=".(isset($this->note_public)?"'".$this->db->escape($this->note_public)."'":"null").","; - $sql.= " model_pdf=".(isset($this->modelpdf)?"'".$this->db->escape($this->modelpdf)."'":"null").","; - $sql.= " import_key=".(isset($this->import_key)?"'".$this->db->escape($this->import_key)."'":"null").""; - - $sql.= " WHERE rowid=".$this->id; - - $this->db->begin(); - - dol_syslog(get_class($this)."::update sql=".$sql, LOG_DEBUG); - $resql = $this->db->query($sql); - if (! $resql) { $error++; $this->errors[]="Error ".$this->db->lasterror(); } - - if (! $error) - { - if (! $notrigger) - { - // Call triggers - include_once DOL_DOCUMENT_ROOT . '/core/class/interfaces.class.php'; - $interface=new Interfaces($this->db); - $result=$interface->run_triggers('BILL_MODIFY',$this,$user,$langs,$conf); - if ($result < 0) { $error++; $this->errors=$interface->errors; } - // End call triggers - } - } - - // Commit or rollback - if ($error) - { - 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; - } - } - - - /** - * Add a discount line into invoice using an existing absolute discount - * - * @param int $idremise Id of absolute 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; - } - - $facligne=new FactureLigne($this->db); - $facligne->fk_facture=$this->id; - $facligne->fk_remise_except=$remise->id; - $facligne->desc=$remise->description; // Description ligne - $facligne->tva_tx=$remise->tva_tx; - $facligne->subprice=-$remise->amount_ht; - $facligne->fk_product=0; // Id produit predefini - $facligne->qty=1; - $facligne->remise_percent=0; - $facligne->rang=-1; - $facligne->info_bits=2; - - $facligne->total_ht = -$remise->amount_ht; - $facligne->total_tva = -$remise->amount_tva; - $facligne->total_ttc = -$remise->amount_ttc; - - $lineid=$facligne->insert(); - if ($lineid > 0) - { - $result=$this->update_price(1); - if ($result > 0) - { - // Create linke between discount and invoice line - $result=$remise->link_to_invoice($lineid,0); - if ($result < 0) - { - $this->error=$remise->error; - $this->db->rollback(); - return -4; - } - - $this->db->commit(); - return 1; - } - else - { - $this->error=$facligne->error; - $this->db->rollback(); - return -1; - } - } - else - { - $this->error=$facligne->error; - $this->db->rollback(); - return -2; - } - } - else - { - $this->db->rollback(); - return -3; - } - } - - /** - * Set customer ref - * - * @param string $ref_client Customer ref - * @return int <0 if KO, >0 if OK - */ - function set_ref_client($ref_client) - { - $sql = 'UPDATE '.MAIN_DB_PREFIX.'facture'; - if (empty($ref_client)) - $sql .= ' SET ref_client = NULL'; - else - $sql .= ' SET ref_client = \''.$this->db->escape($ref_client).'\''; - $sql .= ' WHERE rowid = '.$this->id; - if ($this->db->query($sql)) - { - $this->ref_client = $ref_client; - return 1; - } - else - { - dol_print_error($this->db); - return -1; - } - } - - /** - * Delete invoice - * - * @param int $rowid Id of invoice to delete. If empty, we delete current instance of invoice - * @param int $notrigger 1=Does not execute triggers, 0= execute triggers - * @return int <0 if KO, >0 if OK - */ - function delete($rowid=0, $notrigger=0) - { - global $user,$langs,$conf; - require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; - - if (! $rowid) $rowid=$this->id; - - dol_syslog(get_class($this)."::delete rowid=".$rowid, LOG_DEBUG); - - // TODO Test if there is at least on payment. If yes, refuse to delete. - - $error=0; - $this->db->begin(); - - if (! $error && ! $notrigger) - { - // Appel des triggers - include_once DOL_DOCUMENT_ROOT . '/core/class/interfaces.class.php'; - $interface=new Interfaces($this->db); - $result=$interface->run_triggers('BILL_DELETE',$this,$user,$langs,$conf); - if ($result < 0) { - $error++; $this->errors=$interface->errors; - } - // Fin appel triggers - } - - if (! $error) - { - // Delete linked object - $res = $this->deleteObjectLinked(); - if ($res < 0) $error++; - } - - if (! $error) - { - // If invoice was converted into a discount not yet consumed, we remove discount - $sql = 'DELETE FROM '.MAIN_DB_PREFIX.'societe_remise_except'; - $sql.= ' WHERE fk_facture_source = '.$rowid; - $sql.= ' AND fk_facture_line IS NULL'; - $resql=$this->db->query($sql); - - // If invoice has consumned discounts - $this->fetch_lines(); - $list_rowid_det=array(); - foreach($this->lines as $key => $invoiceline) - { - $list_rowid_det[]=$invoiceline->rowid; - } - - // Consumned discounts are freed - if (count($list_rowid_det)) - { - $sql = 'UPDATE '.MAIN_DB_PREFIX.'societe_remise_except'; - $sql.= ' SET fk_facture = NULL, fk_facture_line = NULL'; - $sql.= ' WHERE fk_facture_line IN ('.join(',',$list_rowid_det).')'; - - dol_syslog(get_class($this)."::delete sql=".$sql); - if (! $this->db->query($sql)) - { - $this->error=$this->db->error()." sql=".$sql; - dol_syslog(get_class($this)."::delete ".$this->error, LOG_ERR); - $this->db->rollback(); - return -5; - } - } - - // Delete invoice line - $sql = 'DELETE FROM '.MAIN_DB_PREFIX.'facturedet WHERE fk_facture = '.$rowid; - if ($this->db->query($sql) && $this->delete_linked_contact()) - { - $sql = 'DELETE FROM '.MAIN_DB_PREFIX.'facture WHERE rowid = '.$rowid; - $resql=$this->db->query($sql); - if ($resql) - { - // On efface le repertoire de pdf provisoire - $ref = dol_sanitizeFileName($this->ref); - if ($conf->facture->dir_output) - { - $dir = $conf->facture->dir_output . "/" . $ref; - $file = $conf->facture->dir_output . "/" . $ref . "/" . $ref . ".pdf"; - if (file_exists($file)) // We must delete all files before deleting directory - { - $ret=dol_delete_preview($this); - - if (! dol_delete_file($file,0,0,0,$this)) // For triggers - { - $this->error=$langs->trans("ErrorCanNotDeleteFile",$file); - $this->db->rollback(); - return 0; - } - } - if (file_exists($dir)) - { - if (! dol_delete_dir_recursive($dir)) // For remove dir and meta - { - $this->error=$langs->trans("ErrorCanNotDeleteDir",$dir); - $this->db->rollback(); - return 0; - } - } - } - - $this->db->commit(); - return 1; - } - else - { - $this->error=$this->db->lasterror()." sql=".$sql; - dol_syslog(get_class($this)."::delete ".$this->error, LOG_ERR); - $this->db->rollback(); - return -6; - } - } - else - { - $this->error=$this->db->lasterror()." sql=".$sql; - dol_syslog(get_class($this)."::delete ".$this->error, LOG_ERR); - $this->db->rollback(); - return -4; - } - } - else - { - $this->error=$this->db->lasterror(); - dol_syslog(get_class($this)."::delete ".$this->error, LOG_ERR); - $this->db->rollback(); - return -2; - } - } - - - /** - * Renvoi une date limite de reglement de facture en fonction des - * conditions de reglements de la facture et date de facturation - * - * @param string $cond_reglement Condition of payment (code or id) to use. If 0, we use current condition. - * @return date Date limite de reglement si ok, <0 si ko - */ - function calculate_date_lim_reglement($cond_reglement=0) - { - if (! $cond_reglement) $cond_reglement=$this->cond_reglement_code; - if (! $cond_reglement) $cond_reglement=$this->cond_reglement_id; - - $cdr_nbjour=0; $cdr_fdm=0; $cdr_decalage=0; - - $sqltemp = 'SELECT c.fdm,c.nbjour,c.decalage'; - $sqltemp.= ' FROM '.MAIN_DB_PREFIX.'c_payment_term as c'; - if (is_numeric($cond_reglement)) $sqltemp.= " WHERE c.rowid=".$cond_reglement; - else $sqltemp.= " WHERE c.code='".$this->db->escape($cond_reglement)."'"; - - dol_syslog(get_class($this).'::calculate_date_lim_reglement sql='.$sqltemp); - $resqltemp=$this->db->query($sqltemp); - if ($resqltemp) - { - if ($this->db->num_rows($resqltemp)) - { - $obj = $this->db->fetch_object($resqltemp); - $cdr_nbjour = $obj->nbjour; - $cdr_fdm = $obj->fdm; - $cdr_decalage = $obj->decalage; - } - } - else - { - $this->error=$this->db->error(); - return -1; - } - $this->db->free($resqltemp); - - /* Definition de la date limite */ - - // 1 : ajout du nombre de jours - $datelim = $this->date + ($cdr_nbjour * 3600 * 24); - - // 2 : application de la regle "fin de mois" - if ($cdr_fdm) - { - $mois=date('m', $datelim); - $annee=date('Y', $datelim); - if ($mois == 12) - { - $mois = 1; - $annee += 1; - } - else - { - $mois += 1; - } - // On se deplace au debut du mois suivant, et on retire un jour - $datelim=dol_mktime(12,0,0,$mois,1,$annee); - $datelim -= (3600 * 24); - } - - // 3 : application du decalage - $datelim += ($cdr_decalage * 3600 * 24); - - return $datelim; - } - - /** - * Tag la facture comme paye completement (close_code non renseigne) ou partiellement (close_code renseigne) + appel trigger BILL_PAYED - * - * @param User $user Objet utilisateur qui modifie - * @param string $close_code Code renseigne si on classe a payee completement alors que paiement incomplet (cas escompte par exemple) - * @param string $close_note Commentaire renseigne si on classe a payee alors que paiement incomplet (cas escompte par exemple) - * @return int <0 if KO, >0 if OK - */ - function set_paid($user,$close_code='',$close_note='') - { - global $conf,$langs; - $error=0; - - if ($this->paye != 1) - { - $this->db->begin(); - - dol_syslog(get_class($this)."::set_paid rowid=".$this->id, LOG_DEBUG); - $sql = 'UPDATE '.MAIN_DB_PREFIX.'facture SET'; - $sql.= ' fk_statut=2'; - if (! $close_code) $sql.= ', paye=1'; - if ($close_code) $sql.= ", close_code='".$this->db->escape($close_code)."'"; - if ($close_note) $sql.= ", close_note='".$this->db->escape($close_note)."'"; - $sql.= ' WHERE rowid = '.$this->id; - - $resql = $this->db->query($sql); - if ($resql) - { - // Appel des triggers - include_once DOL_DOCUMENT_ROOT . '/core/class/interfaces.class.php'; - $interface=new Interfaces($this->db); - $result=$interface->run_triggers('BILL_PAYED',$this,$user,$langs,$conf); - if ($result < 0) { $error++; $this->errors=$interface->errors; } - // Fin appel triggers - } - else - { - $error++; - $this->error=$this->db->error(); - dol_print_error($this->db); - } - - if (! $error) - { - $this->db->commit(); - return 1; - } - else - { - $this->db->rollback(); - return -1; - } - } - else - { - return 0; - } - } - - - /** - * Tag la facture comme non payee completement + appel trigger BILL_UNPAYED - * Fonction utilisee quand un paiement prelevement est refuse, - * ou quand une facture annulee et reouverte. - * - * @param User $user Object user that change status - * @return int <0 if KO, >0 if OK - */ - function set_unpaid($user) - { - global $conf,$langs; - $error=0; - - $this->db->begin(); - - $sql = 'UPDATE '.MAIN_DB_PREFIX.'facture'; - $sql.= ' SET paye=0, fk_statut=1, close_code=null, close_note=null'; - $sql.= ' WHERE rowid = '.$this->id; - - dol_syslog(get_class($this)."::set_unpaid sql=".$sql); - $resql = $this->db->query($sql); - if ($resql) - { - // Appel des triggers - include_once DOL_DOCUMENT_ROOT . '/core/class/interfaces.class.php'; - $interface=new Interfaces($this->db); - $result=$interface->run_triggers('BILL_UNPAYED',$this,$user,$langs,$conf); - if ($result < 0) { $error++; $this->errors=$interface->errors; } - // Fin appel triggers - } - else - { - $error++; - $this->error=$this->db->error(); - dol_print_error($this->db); - } - - if (! $error) - { - $this->db->commit(); - return 1; - } - else - { - $this->db->rollback(); - return -1; - } - } - - - /** - * Tag invoice as canceled, with no payment on it (example for replacement invoice or payment never received) + call trigger BILL_CANCEL - * Warning, if option to decrease stock on invoice was set, this function does not change stock (it might be a cancel because - * of no payment even if merchandises were sent). - * - * @param User $user Object user making change - * @param string $close_code Code de fermeture - * @param string $close_note Comment - * @return int <0 if KO, >0 if OK - */ - function set_canceled($user,$close_code='',$close_note='') - { - global $conf,$langs; + // Appel des triggers + include_once DOL_DOCUMENT_ROOT . '/core/class/interfaces.class.php'; + $interface=new Interfaces($this->db); + $result=$interface->run_triggers('BILL_CLONE',$this,$user,$langs,$conf); + if ($result < 0) { + $error++; $this->errors=$interface->errors; + } + // Fin appel triggers + } + + // End + if (! $error) + { + $this->db->commit(); + return $this->id; + } + else + { + $this->db->rollback(); + return -1; + } + } + + /** + * Load an object from an order and create a new invoice into database + * + * @param Object $object Object source + * @return int <0 if KO, 0 if nothing done, 1 if OK + */ + function createFromOrder($object) + { + global $conf,$user,$langs,$hookmanager; $error=0; - dol_syslog(get_class($this)."::set_canceled rowid=".$this->id, LOG_DEBUG); + // Closed order + $this->date = dol_now(); + $this->source = 0; - $this->db->begin(); + $num=count($object->lines); + for ($i = 0; $i < $num; $i++) + { + $line = new FactureLigne($this->db); - $sql = 'UPDATE '.MAIN_DB_PREFIX.'facture SET'; - $sql.= ' fk_statut=3'; - if ($close_code) $sql.= ", close_code='".$this->db->escape($close_code)."'"; - if ($close_note) $sql.= ", close_note='".$this->db->escape($close_note)."'"; - $sql.= ' WHERE rowid = '.$this->id; + $line->libelle = $object->lines[$i]->libelle; + $line->label = $object->lines[$i]->label; + $line->desc = $object->lines[$i]->desc; + $line->subprice = $object->lines[$i]->subprice; + $line->total_ht = $object->lines[$i]->total_ht; + $line->total_tva = $object->lines[$i]->total_tva; + $line->total_ttc = $object->lines[$i]->total_ttc; + $line->tva_tx = $object->lines[$i]->tva_tx; + $line->localtax1_tx = $object->lines[$i]->localtax1_tx; + $line->localtax2_tx = $object->lines[$i]->localtax2_tx; + $line->qty = $object->lines[$i]->qty; + $line->fk_remise_except = $object->lines[$i]->fk_remise_except; + $line->remise_percent = $object->lines[$i]->remise_percent; + $line->fk_product = $object->lines[$i]->fk_product; + $line->info_bits = $object->lines[$i]->info_bits; + $line->product_type = $object->lines[$i]->product_type; + $line->rang = $object->lines[$i]->rang; + $line->special_code = $object->lines[$i]->special_code; + $line->fk_parent_line = $object->lines[$i]->fk_parent_line; - $resql = $this->db->query($sql); - if ($resql) - { - // On desaffecte de la facture les remises liees - // car elles n'ont pas ete utilisees vu que la facture est abandonnee. - $sql = 'UPDATE '.MAIN_DB_PREFIX.'societe_remise_except'; - $sql.= ' SET fk_facture = NULL'; - $sql.= ' WHERE fk_facture = '.$this->id; + $this->lines[$i] = $line; + } - $resql=$this->db->query($sql); - if ($resql) - { - // Appel des triggers - include_once DOL_DOCUMENT_ROOT . '/core/class/interfaces.class.php'; - $interface=new Interfaces($this->db); - $result=$interface->run_triggers('BILL_CANCEL',$this,$user,$langs,$conf); - if ($result < 0) { $error++; $this->errors=$interface->errors; } - // Fin appel triggers + $this->socid = $object->socid; + $this->fk_project = $object->fk_project; + $this->cond_reglement_id = $object->cond_reglement_id; + $this->mode_reglement_id = $object->mode_reglement_id; + $this->availability_id = $object->availability_id; + $this->demand_reason_id = $object->demand_reason_id; + $this->date_livraison = $object->date_livraison; + $this->fk_delivery_address = $object->fk_delivery_address; + $this->contact_id = $object->contactid; + $this->ref_client = $object->ref_client; + $this->note_private = $object->note_private; + $this->note_public = $object->note_public; - $this->db->commit(); - return 1; - } - else - { - $this->error=$this->db->error()." sql=".$sql; - $this->db->rollback(); - return -1; - } - } - else - { - $this->error=$this->db->error()." sql=".$sql; - $this->db->rollback(); - return -2; - } - } + $this->origin = $object->element; + $this->origin_id = $object->id; - /** - * Tag invoice as validated + call trigger BILL_VALIDATE - * Object must have lines loaded with fetch_lines - * - * @param User $user Object user that validate - * @param string $force_number Reference to force on invoice - * @param int $idwarehouse Id of warehouse to use for stock decrease - * @return int <0 if KO, >0 if OK - */ - function validate($user, $force_number='', $idwarehouse=0) - { - global $conf,$langs; - require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; + // Possibility to add external linked objects with hooks + $this->linked_objects[$this->origin] = $this->origin_id; + if (! empty($object->other_linked_objects) && is_array($object->other_linked_objects)) + { + $this->linked_objects = array_merge($this->linked_objects, $object->other_linked_objects); + } - $now=dol_now(); + $ret = $this->create($user); - $error=0; - dol_syslog(get_class($this).'::validate user='.$user->id.', force_number='.$force_number.', idwarehouse='.$idwarehouse); + if ($ret > 0) + { + // Actions hooked (by external module) + $hookmanager->initHooks(array('invoicedao')); - // Check parameters - if (! $this->brouillon) - { - dol_syslog(get_class($this)."::validate no draft status", LOG_WARNING); - return 0; - } + $parameters=array('objFrom'=>$object); + $action=''; + $reshook=$hookmanager->executeHooks('createFrom',$parameters,$this,$action); // Note that $action and $object may have been modified by some hooks + if ($reshook < 0) $error++; - if (! $user->rights->facture->valider) - { - $this->error='Permission denied'; - dol_syslog(get_class($this)."::validate ".$this->error, LOG_ERR); - return -1; - } + if (! $error) + { + return 1; + } + else return -1; + } + else return -1; + } - $this->db->begin(); + /** + * Return clicable link of object (with eventually picto) + * + * @param int $withpicto Add picto into link + * @param string $option Where point the link + * @param int $max Maxlength of ref + * @param int $short 1=Return just URL + * @param string $moretitle Add more text to title tooltip + * @return string String with URL + */ + function getNomUrl($withpicto=0,$option='',$max=0,$short=0,$moretitle='') + { + global $langs; - $this->fetch_thirdparty(); - $this->fetch_lines(); + $result=''; - // Check parameters - if ($this->type == 1) // si facture de remplacement - { - // Controle que facture source connue - if ($this->fk_facture_source <= 0) - { - $this->error=$langs->trans("ErrorFieldRequired",$langs->trans("InvoiceReplacement")); - $this->db->rollback(); - return -10; - } + if ($option == 'withdraw') $url = DOL_URL_ROOT.'/compta/facture/prelevement.php?facid='.$this->id; + else $url = DOL_URL_ROOT.'/compta/facture.php?facid='.$this->id; - // Charge la facture source a remplacer - $facreplaced=new Facture($this->db); - $result=$facreplaced->fetch($this->fk_facture_source); - if ($result <= 0) - { - $this->error=$langs->trans("ErrorBadInvoice"); - $this->db->rollback(); - return -11; - } + if ($short) return $url; - // Controle que facture source non deja remplacee par une autre - $idreplacement=$facreplaced->getIdReplacingInvoice('validated'); - if ($idreplacement && $idreplacement != $this->id) - { - $facreplacement=new Facture($this->db); - $facreplacement->fetch($idreplacement); - $this->error=$langs->trans("ErrorInvoiceAlreadyReplaced",$facreplaced->ref,$facreplacement->ref); - $this->db->rollback(); - return -12; - } + $picto='bill'; + if ($this->type == 1) $picto.='r'; // Replacement invoice + if ($this->type == 2) $picto.='a'; // Credit note + if ($this->type == 3) $picto.='d'; // Deposit invoice - $result=$facreplaced->set_canceled($user,'replaced',''); - if ($result < 0) - { - $this->error=$facreplaced->error; - $this->db->rollback(); - return -13; - } - } + $label=$langs->trans("ShowInvoice").': '.$this->ref; + if ($this->type == 1) $label=$langs->transnoentitiesnoconv("ShowInvoiceReplace").': '.$this->ref; + if ($this->type == 2) $label=$langs->transnoentitiesnoconv("ShowInvoiceAvoir").': '.$this->ref; + if ($this->type == 3) $label=$langs->transnoentitiesnoconv("ShowInvoiceDeposit").': '.$this->ref; + if ($moretitle) $label.=' - '.$moretitle; - // Define new ref - if ($force_number) - { - $num = $force_number; - } - else if (preg_match('/^[\(]?PROV/i', $this->ref)) - { - if (! empty($conf->global->FAC_FORCE_DATE_VALIDATION)) // If option enabled, we force invoice date - { - $this->date=dol_now(); - $this->date_lim_reglement=$this->calculate_date_lim_reglement(); - } - $num = $this->getNextNumRef($this->client); - } - else - { - $num = $this->ref; - } + //$linkstart=''; + $linkstart=''; + $linkend=''; - if ($num) - { - $this->update_price(1); + if ($withpicto) $result.=($linkstart.img_object(($max?dol_trunc($label,$max):$label),$picto).$linkend); + if ($withpicto && $withpicto != 2) $result.=' '; + if ($withpicto != 2) $result.=$linkstart.($max?dol_trunc($this->ref,$max):$this->ref).$linkend; + return $result; + } - // Validate - $sql = 'UPDATE '.MAIN_DB_PREFIX.'facture'; - $sql.= " SET facnumber='".$num."', fk_statut = 1, fk_user_valid = ".$user->id.", date_valid = '".$this->db->idate($now)."'"; - if (! empty($conf->global->FAC_FORCE_DATE_VALIDATION)) // If option enabled, we force invoice date - { - $sql.= ', datef='.$this->db->idate($this->date); - $sql.= ', date_lim_reglement='.$this->db->idate($this->date_lim_reglement); - } - $sql.= ' WHERE rowid = '.$this->id; - dol_syslog(get_class($this)."::validate sql=".$sql); - $resql=$this->db->query($sql); - if (! $resql) - { - dol_syslog(get_class($this)."::validate Echec update - 10 - sql=".$sql, LOG_ERR); - dol_print_error($this->db); - $error++; - } + /** + * Get object and lines from database + * + * @param int $rowid Id of object to load + * @param string $ref Reference of invoice + * @param string $ref_ext External reference of invoice + * @param int $ref_int Internal reference of other object + * @return int >0 if OK, <0 if KO, 0 if not found + */ + function fetch($rowid, $ref='', $ref_ext='', $ref_int='') + { + global $conf; - // On verifie si la facture etait une provisoire - if (! $error && (preg_match('/^[\(]?PROV/i', $this->ref))) - { - // La verif qu'une remise n'est pas utilisee 2 fois est faite au moment de l'insertion de ligne - } + if (empty($rowid) && empty($ref) && empty($ref_ext) && empty($ref_int)) return -1; - if (! $error) - { - // Define third party as a customer - $result=$this->client->set_as_client(); + $sql = 'SELECT f.rowid,f.facnumber,f.ref_client,f.ref_ext,f.ref_int,f.type,f.fk_soc,f.amount,f.tva, f.localtax1, f.localtax2, f.total, f.total_ttc, f.revenuestamp'; + $sql.= ', f.remise_percent, f.remise_absolue, f.remise'; + $sql.= ', f.datef as df'; + $sql.= ', f.date_lim_reglement as dlr'; + $sql.= ', f.datec as datec'; + $sql.= ', f.date_valid as datev'; + $sql.= ', f.tms as datem'; + $sql.= ', f.note_private, f.note_public, f.fk_statut, f.paye, f.close_code, f.close_note, f.fk_user_author, f.fk_user_valid, f.model_pdf'; + $sql.= ', f.fk_facture_source'; + $sql.= ', f.fk_mode_reglement, f.fk_cond_reglement, f.fk_projet, f.extraparams'; + $sql.= ', p.code as mode_reglement_code, p.libelle as mode_reglement_libelle'; + $sql.= ', c.code as cond_reglement_code, c.libelle as cond_reglement_libelle, c.libelle_facture as cond_reglement_libelle_doc'; + $sql.= ' FROM '.MAIN_DB_PREFIX.'facture as f'; + $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_payment_term as c ON f.fk_cond_reglement = c.rowid'; + $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_paiement as p ON f.fk_mode_reglement = p.id'; + $sql.= ' WHERE f.entity = '.$conf->entity; + if ($rowid) $sql.= " AND f.rowid=".$rowid; + if ($ref) $sql.= " AND f.facnumber='".$this->db->escape($ref)."'"; + if ($ref_ext) $sql.= " AND f.ref_ext='".$this->db->escape($ref_ext)."'"; + if ($ref_int) $sql.= " AND f.ref_int='".$this->db->escape($ref_int)."'"; - // Si active on decremente le produit principal et ses composants a la validation de facture - if ($this->type != 3 && $result >= 0 && ! empty($conf->stock->enabled) && ! empty($conf->global->STOCK_CALCULATE_ON_BILL)) - { - require_once DOL_DOCUMENT_ROOT.'/product/stock/class/mouvementstock.class.php'; - $langs->load("agenda"); + dol_syslog(get_class($this)."::fetch sql=".$sql, LOG_DEBUG); + $result = $this->db->query($sql); + if ($result) + { + if ($this->db->num_rows($result)) + { + $obj = $this->db->fetch_object($result); - // Loop on each line - $cpt=count($this->lines); - for ($i = 0; $i < $cpt; $i++) - { - if ($this->lines[$i]->fk_product > 0) - { - $mouvP = new MouvementStock($this->db); - // We decrease stock for product - if ($this->type == 2) $result=$mouvP->reception($user, $this->lines[$i]->fk_product, $idwarehouse, $this->lines[$i]->qty, $this->lines[$i]->subprice, $langs->trans("InvoiceValidatedInDolibarr",$num)); - else $result=$mouvP->livraison($user, $this->lines[$i]->fk_product, $idwarehouse, $this->lines[$i]->qty, $this->lines[$i]->subprice, $langs->trans("InvoiceValidatedInDolibarr",$num)); - if ($result < 0) { $error++; } - } - } - } - } + $this->id = $obj->rowid; + $this->ref = $obj->facnumber; + $this->ref_client = $obj->ref_client; + $this->ref_ext = $obj->ref_ext; + $this->ref_int = $obj->ref_int; + $this->type = $obj->type; + $this->date = $this->db->jdate($obj->df); + $this->date_creation = $this->db->jdate($obj->datec); + $this->date_validation = $this->db->jdate($obj->datev); + $this->datem = $this->db->jdate($obj->datem); + $this->remise_percent = $obj->remise_percent; + $this->remise_absolue = $obj->remise_absolue; + //$this->remise = $obj->remise; + $this->total_ht = $obj->total; + $this->total_tva = $obj->tva; + $this->total_localtax1 = $obj->localtax1; + $this->total_localtax2 = $obj->localtax2; + $this->total_ttc = $obj->total_ttc; + $this->revenuestamp = $obj->revenuestamp; + $this->paye = $obj->paye; + $this->close_code = $obj->close_code; + $this->close_note = $obj->close_note; + $this->socid = $obj->fk_soc; + $this->statut = $obj->fk_statut; + $this->date_lim_reglement = $this->db->jdate($obj->dlr); + $this->mode_reglement_id = $obj->fk_mode_reglement; + $this->mode_reglement_code = $obj->mode_reglement_code; + $this->mode_reglement = $obj->mode_reglement_libelle; + $this->cond_reglement_id = $obj->fk_cond_reglement; + $this->cond_reglement_code = $obj->cond_reglement_code; + $this->cond_reglement = $obj->cond_reglement_libelle; + $this->cond_reglement_doc = $obj->cond_reglement_libelle_doc; + $this->fk_project = $obj->fk_projet; + $this->fk_facture_source = $obj->fk_facture_source; + $this->note = $obj->note_private; // deprecated + $this->note_private = $obj->note_private; + $this->note_public = $obj->note_public; + $this->user_author = $obj->fk_user_author; + $this->user_valid = $obj->fk_user_valid; + $this->modelpdf = $obj->model_pdf; - if (! $error) - { - $this->oldref = ''; + $this->extraparams = (array) json_decode($obj->extraparams, true); - // Rename directory if dir was a temporary ref - if (preg_match('/^[\(]?PROV/i', $this->ref)) - { - // On renomme repertoire facture ($this->ref = ancienne ref, $num = nouvelle ref) - // afin de ne pas perdre les fichiers attaches - $facref = dol_sanitizeFileName($this->ref); - $snumfa = dol_sanitizeFileName($num); - $dirsource = $conf->facture->dir_output.'/'.$facref; - $dirdest = $conf->facture->dir_output.'/'.$snumfa; - if (file_exists($dirsource)) - { - dol_syslog(get_class($this)."::validate rename dir ".$dirsource." into ".$dirdest); + if ($this->statut == 0) $this->brouillon = 1; - if (@rename($dirsource, $dirdest)) - { - $this->oldref = $facref; + // Retreive all extrafield for invoice + // fetch optionals attributes and labels + if(!class_exists('Extrafields')) + require_once(DOL_DOCUMENT_ROOT.'/core/class/extrafields.class.php'); + $extrafields=new ExtraFields($this->db); + $extralabels=$extrafields->fetch_name_optionals_label('facture',true); + if (count($extralabels)>0) { + $this->array_options = array(); + } + foreach($extrafields->attribute_label as $key=>$label) + { + $this->array_options['options_'.$key]=$label; + } - dol_syslog("Rename ok"); - // Suppression ancien fichier PDF dans nouveau rep - dol_delete_file($conf->facture->dir_output.'/'.$snumfa.'/'.$facref.'*.*'); - } - } - } - } + /* + * Lines + */ - // Set new ref and define current statut - if (! $error) - { - $this->ref = $num; - $this->facnumber=$num; - $this->statut=1; - $this->brouillon=0; - $this->date_validation=$now; - } + $this->lines = array(); - // Trigger calls - if (! $error) - { - // Appel des triggers - include_once DOL_DOCUMENT_ROOT . '/core/class/interfaces.class.php'; - $interface=new Interfaces($this->db); - $result=$interface->run_triggers('BILL_VALIDATE',$this,$user,$langs,$conf); - if ($result < 0) { $error++; $this->errors=$interface->errors; } - // Fin appel triggers - } - } - else - { - $error++; - } + $result=$this->fetch_lines(); + if ($result < 0) + { + $this->error=$this->db->error(); + dol_syslog(get_class($this)."::fetch Error ".$this->error, LOG_ERR); + return -3; + } + return 1; + } + else + { + $this->error='Bill with id '.$rowid.' or ref '.$ref.' not found sql='.$sql; + dol_syslog(get_class($this)."::fetch Error ".$this->error, LOG_ERR); + return 0; + } + } + else + { + $this->error=$this->db->error(); + dol_syslog(get_class($this)."::fetch Error ".$this->error, LOG_ERR); + return -1; + } + } - if (! $error) - { - $this->db->commit(); - return 1; - } - else - { - $this->db->rollback(); - $this->error=$this->db->lasterror(); - return -1; - } - } - /** - * Set draft status - * - * @param User $user Object user that modify - * @param int $idwarehouse Id warehouse to use for stock change. - * @return int <0 if KO, >0 if OK - */ - function set_draft($user,$idwarehouse=-1) - { - global $conf,$langs; + /** + * Load all detailed lines into this->lines + * + * @return int 1 if OK, < 0 if KO + */ + function fetch_lines() + { + $this->lines=array(); - $error=0; + $sql = 'SELECT l.rowid, l.fk_product, l.fk_parent_line, l.label as custom_label, l.description, l.product_type, l.price, l.qty, l.tva_tx, '; + $sql.= ' l.localtax1_tx, l.localtax2_tx, l.remise, l.remise_percent, l.fk_remise_except, l.subprice,'; + $sql.= ' l.rang, l.special_code,'; + $sql.= ' l.date_start as date_start, l.date_end as date_end,'; + $sql.= ' l.info_bits, l.total_ht, l.total_tva, l.total_localtax1, l.total_localtax2, l.total_ttc, l.fk_code_ventilation, l.fk_product_fournisseur_price as fk_fournprice, l.buy_price_ht as pa_ht,'; + $sql.= ' p.ref as product_ref, p.fk_product_type as fk_product_type, p.label as product_label, p.description as product_desc'; + $sql.= ' FROM '.MAIN_DB_PREFIX.'facturedet as l'; + $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'product as p ON l.fk_product = p.rowid'; + $sql.= ' WHERE l.fk_facture = '.$this->id; + $sql.= ' ORDER BY l.rang'; - if ($this->statut == 0) - { - dol_syslog(get_class($this)."::set_draft already draft status", LOG_WARNING); - return 0; - } + dol_syslog(get_class($this).'::fetch_lines sql='.$sql, LOG_DEBUG); + $result = $this->db->query($sql); + if ($result) + { + $num = $this->db->num_rows($result); + $i = 0; + while ($i < $num) + { + $objp = $this->db->fetch_object($result); + $line = new FactureLigne($this->db); - $this->db->begin(); + $line->rowid = $objp->rowid; + $line->label = $objp->custom_label; + $line->desc = $objp->description; // Description line + $line->product_type = $objp->product_type; // Type of line + $line->product_ref = $objp->product_ref; // Ref product + $line->libelle = $objp->product_label; // TODO deprecated + $line->product_label = $objp->product_label; // Label product + $line->product_desc = $objp->product_desc; // Description product + $line->fk_product_type = $objp->fk_product_type; // Type of product + $line->qty = $objp->qty; + $line->subprice = $objp->subprice; + $line->tva_tx = $objp->tva_tx; + $line->localtax1_tx = $objp->localtax1_tx; + $line->localtax2_tx = $objp->localtax2_tx; + $line->remise_percent = $objp->remise_percent; + $line->fk_remise_except = $objp->fk_remise_except; + $line->fk_product = $objp->fk_product; + $line->date_start = $this->db->jdate($objp->date_start); + $line->date_end = $this->db->jdate($objp->date_end); + $line->date_start = $this->db->jdate($objp->date_start); + $line->date_end = $this->db->jdate($objp->date_end); + $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->code_ventilation = $objp->fk_code_ventilation; + $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->rang = $objp->rang; + $line->special_code = $objp->special_code; + $line->fk_parent_line = $objp->fk_parent_line; - $sql = "UPDATE ".MAIN_DB_PREFIX."facture"; - $sql.= " SET fk_statut = 0"; - $sql.= " WHERE rowid = ".$this->id; + // Ne plus utiliser + //$line->price = $objp->price; + //$line->remise = $objp->remise; - dol_syslog(get_class($this)."::set_draft sql=".$sql, LOG_DEBUG); - $result=$this->db->query($sql); - if ($result) - { - // Si on decremente le produit principal et ses composants a la validation de facture, on réincrement - if ($this->type != 3 && $result >= 0 && ! empty($conf->stock->enabled) && ! empty($conf->global->STOCK_CALCULATE_ON_BILL)) - { - require_once DOL_DOCUMENT_ROOT.'/product/stock/class/mouvementstock.class.php'; - $langs->load("agenda"); + $this->lines[$i] = $line; - $num=count($this->lines); - for ($i = 0; $i < $num; $i++) - { - if ($this->lines[$i]->fk_product > 0) - { - $mouvP = new MouvementStock($this->db); - // We decrease stock for product - if ($this->type == 2) $result=$mouvP->livraison($user, $this->lines[$i]->fk_product, $idwarehouse, $this->lines[$i]->qty, $this->lines[$i]->subprice, $langs->trans("InvoiceBackToDraftInDolibarr",$this->ref)); - else $result=$mouvP->reception($user, $this->lines[$i]->fk_product, $idwarehouse, $this->lines[$i]->qty, 0, $langs->trans("InvoiceBackToDraftInDolibarr",$this->ref)); // we use 0 for price, to not change the weighted average value - } - } - } + $i++; + } + $this->db->free($result); + return 1; + } + else + { + $this->error=$this->db->error(); + dol_syslog(get_class($this).'::fetch_lines '.$this->error,LOG_ERR); + return -3; + } + } + + + /** + * Update database + * + * @param User $user User that modify + * @param int $notrigger 0=launch triggers after, 1=disable triggers + * @return int <0 if KO, >0 if OK + */ + function update($user=0, $notrigger=0) + { + global $conf, $langs; + $error=0; + + // Clean parameters + if (empty($this->type)) $this->type=0; + if (isset($this->facnumber)) $this->facnumber=trim($this->ref); + if (isset($this->ref_client)) $this->ref_client=trim($this->ref_client); + if (isset($this->increment)) $this->increment=trim($this->increment); + if (isset($this->close_code)) $this->close_code=trim($this->close_code); + if (isset($this->close_note)) $this->close_note=trim($this->close_note); + if (isset($this->note) || isset($this->note_private)) $this->note=(isset($this->note) ? trim($this->note) : trim($this->note_private)); // deprecated + if (isset($this->note) || isset($this->note_private)) $this->note_private=(isset($this->note_private) ? trim($this->note_private) : trim($this->note)); + if (isset($this->note_public)) $this->note_public=trim($this->note_public); + if (isset($this->modelpdf)) $this->modelpdf=trim($this->modelpdf); + if (isset($this->import_key)) $this->import_key=trim($this->import_key); + + // Check parameters + // Put here code to add control on parameters values + + // Update request + $sql = "UPDATE ".MAIN_DB_PREFIX."facture SET"; + + $sql.= " facnumber=".(isset($this->ref)?"'".$this->db->escape($this->ref)."'":"null").","; + $sql.= " type=".(isset($this->type)?$this->type:"null").","; + $sql.= " ref_client=".(isset($this->ref_client)?"'".$this->db->escape($this->ref_client)."'":"null").","; + $sql.= " increment=".(isset($this->increment)?"'".$this->db->escape($this->increment)."'":"null").","; + $sql.= " fk_soc=".(isset($this->socid)?$this->socid:"null").","; + $sql.= " datec=".(strval($this->date_creation)!='' ? "'".$this->db->idate($this->date_creation)."'" : 'null').","; + $sql.= " datef=".(strval($this->date)!='' ? "'".$this->db->idate($this->date)."'" : 'null').","; + $sql.= " date_valid=".(strval($this->date_validation)!='' ? "'".$this->db->idate($this->date_validation)."'" : 'null').","; + $sql.= " paye=".(isset($this->paye)?$this->paye:"null").","; + $sql.= " remise_percent=".(isset($this->remise_percent)?$this->remise_percent:"null").","; + $sql.= " remise_absolue=".(isset($this->remise_absolue)?$this->remise_absolue:"null").","; + //$sql.= " remise=".(isset($this->remise)?$this->remise:"null").","; + $sql.= " close_code=".(isset($this->close_code)?"'".$this->db->escape($this->close_code)."'":"null").","; + $sql.= " close_note=".(isset($this->close_note)?"'".$this->db->escape($this->close_note)."'":"null").","; + $sql.= " tva=".(isset($this->total_tva)?$this->total_tva:"null").","; + $sql.= " localtax1=".(isset($this->total_localtax1)?$this->total_localtax1:"null").","; + $sql.= " localtax2=".(isset($this->total_localtax2)?$this->total_localtax2:"null").","; + $sql.= " total=".(isset($this->total_ht)?$this->total_ht:"null").","; + $sql.= " total_ttc=".(isset($this->total_ttc)?$this->total_ttc:"null").","; + $sql.= " revenuestamp=".((isset($this->revenuestamp) && $this->revenuestamp != '')?$this->revenuestamp:"null").","; + $sql.= " fk_statut=".(isset($this->statut)?$this->statut:"null").","; + $sql.= " fk_user_author=".(isset($this->user_author)?$this->user_author:"null").","; + $sql.= " fk_user_valid=".(isset($this->fk_user_valid)?$this->fk_user_valid:"null").","; + $sql.= " fk_facture_source=".(isset($this->fk_facture_source)?$this->fk_facture_source:"null").","; + $sql.= " fk_projet=".(isset($this->fk_project)?$this->fk_project:"null").","; + $sql.= " fk_cond_reglement=".(isset($this->cond_reglement_id)?$this->cond_reglement_id:"null").","; + $sql.= " fk_mode_reglement=".(isset($this->mode_reglement_id)?$this->mode_reglement_id:"null").","; + $sql.= " date_lim_reglement=".(strval($this->date_lim_reglement)!='' ? "'".$this->db->idate($this->date_lim_reglement)."'" : 'null').","; + $sql.= " note_private=".(isset($this->note_private)?"'".$this->db->escape($this->note_private)."'":"null").","; + $sql.= " note_public=".(isset($this->note_public)?"'".$this->db->escape($this->note_public)."'":"null").","; + $sql.= " model_pdf=".(isset($this->modelpdf)?"'".$this->db->escape($this->modelpdf)."'":"null").","; + $sql.= " import_key=".(isset($this->import_key)?"'".$this->db->escape($this->import_key)."'":"null").""; + + $sql.= " WHERE rowid=".$this->id; + + $this->db->begin(); + + dol_syslog(get_class($this)."::update sql=".$sql, LOG_DEBUG); + $resql = $this->db->query($sql); + if (! $resql) { + $error++; $this->errors[]="Error ".$this->db->lasterror(); + } + + if (! $error) + { + if (! $notrigger) + { + // Call triggers + include_once DOL_DOCUMENT_ROOT . '/core/class/interfaces.class.php'; + $interface=new Interfaces($this->db); + $result=$interface->run_triggers('BILL_MODIFY',$this,$user,$langs,$conf); + if ($result < 0) { + $error++; $this->errors=$interface->errors; + } + // End call triggers + } + } + + // Commit or rollback + if ($error) + { + 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; + } + } + + + /** + * Add a discount line into invoice using an existing absolute discount + * + * @param int $idremise Id of absolute 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; + } + + $facligne=new FactureLigne($this->db); + $facligne->fk_facture=$this->id; + $facligne->fk_remise_except=$remise->id; + $facligne->desc=$remise->description; // Description ligne + $facligne->tva_tx=$remise->tva_tx; + $facligne->subprice=-$remise->amount_ht; + $facligne->fk_product=0; // Id produit predefini + $facligne->qty=1; + $facligne->remise_percent=0; + $facligne->rang=-1; + $facligne->info_bits=2; + + $facligne->total_ht = -$remise->amount_ht; + $facligne->total_tva = -$remise->amount_tva; + $facligne->total_ttc = -$remise->amount_ttc; + + $lineid=$facligne->insert(); + if ($lineid > 0) + { + $result=$this->update_price(1); + if ($result > 0) + { + // Create linke between discount and invoice line + $result=$remise->link_to_invoice($lineid,0); + if ($result < 0) + { + $this->error=$remise->error; + $this->db->rollback(); + return -4; + } + + $this->db->commit(); + return 1; + } + else + { + $this->error=$facligne->error; + $this->db->rollback(); + return -1; + } + } + else + { + $this->error=$facligne->error; + $this->db->rollback(); + return -2; + } + } + else + { + $this->db->rollback(); + return -3; + } + } + + /** + * Set customer ref + * + * @param string $ref_client Customer ref + * @return int <0 if KO, >0 if OK + */ + function set_ref_client($ref_client) + { + $sql = 'UPDATE '.MAIN_DB_PREFIX.'facture'; + if (empty($ref_client)) + $sql .= ' SET ref_client = NULL'; + else + $sql .= ' SET ref_client = \''.$this->db->escape($ref_client).'\''; + $sql .= ' WHERE rowid = '.$this->id; + if ($this->db->query($sql)) + { + $this->ref_client = $ref_client; + return 1; + } + else + { + dol_print_error($this->db); + return -1; + } + } + + /** + * Delete invoice + * + * @param int $rowid Id of invoice to delete. If empty, we delete current instance of invoice + * @param int $notrigger 1=Does not execute triggers, 0= execute triggers + * @param int $idwarehouse Id warehouse to use for stock change. + * @return int <0 if KO, >0 if OK + */ + function delete($rowid=0, $notrigger=0, $idwarehouse=-1) + { + global $user,$langs,$conf; + require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; + + if (empty($rowid)) $rowid=$this->id; + + dol_syslog(get_class($this)."::delete rowid=".$rowid, LOG_DEBUG); + + // TODO Test if there is at least on payment. If yes, refuse to delete. + + $error=0; + $this->db->begin(); + + if (! $error && ! $notrigger) + { + // Appel des triggers + include_once DOL_DOCUMENT_ROOT . '/core/class/interfaces.class.php'; + $interface=new Interfaces($this->db); + $result=$interface->run_triggers('BILL_DELETE',$this,$user,$langs,$conf); + if ($result < 0) { + $error++; $this->errors=$interface->errors; + } + // Fin appel triggers + } + + if (! $error) + { + // Delete linked object + $res = $this->deleteObjectLinked(); + if ($res < 0) $error++; + } + + if (! $error) + { + // If invoice was converted into a discount not yet consumed, we remove discount + $sql = 'DELETE FROM '.MAIN_DB_PREFIX.'societe_remise_except'; + $sql.= ' WHERE fk_facture_source = '.$rowid; + $sql.= ' AND fk_facture_line IS NULL'; + $resql=$this->db->query($sql); + + // If invoice has consumned discounts + $this->fetch_lines(); + $list_rowid_det=array(); + foreach($this->lines as $key => $invoiceline) + { + $list_rowid_det[]=$invoiceline->rowid; + } + + // Consumned discounts are freed + if (count($list_rowid_det)) + { + $sql = 'UPDATE '.MAIN_DB_PREFIX.'societe_remise_except'; + $sql.= ' SET fk_facture = NULL, fk_facture_line = NULL'; + $sql.= ' WHERE fk_facture_line IN ('.join(',',$list_rowid_det).')'; + + dol_syslog(get_class($this)."::delete sql=".$sql); + if (! $this->db->query($sql)) + { + $this->error=$this->db->error()." sql=".$sql; + dol_syslog(get_class($this)."::delete ".$this->error, LOG_ERR); + $this->db->rollback(); + return -5; + } + } + + // If we decrament stock on invoice validation, we increment + if ($this->type != 3 && $result >= 0 && ! empty($conf->stock->enabled) && ! empty($conf->global->STOCK_CALCULATE_ON_BILL) && $idwarehouse!=-1) + { + require_once DOL_DOCUMENT_ROOT.'/product/stock/class/mouvementstock.class.php'; + $langs->load("agenda"); + + $num=count($this->lines); + for ($i = 0; $i < $num; $i++) + { + if ($this->lines[$i]->fk_product > 0) + { + $mouvP = new MouvementStock($this->db); + // We decrease stock for product + if ($this->type == 2) $result=$mouvP->livraison($user, $this->lines[$i]->fk_product, $idwarehouse, $this->lines[$i]->qty, $this->lines[$i]->subprice, $langs->trans("InvoiceDeleteDolibarr",$this->ref)); + else $result=$mouvP->reception($user, $this->lines[$i]->fk_product, $idwarehouse, $this->lines[$i]->qty, 0, $langs->trans("InvoiceDeleteDolibarr",$this->ref)); // we use 0 for price, to not change the weighted average value + } + } + } + + + // Delete invoice line + $sql = 'DELETE FROM '.MAIN_DB_PREFIX.'facturedet WHERE fk_facture = '.$rowid; + if ($this->db->query($sql) && $this->delete_linked_contact()) + { + $sql = 'DELETE FROM '.MAIN_DB_PREFIX.'facture WHERE rowid = '.$rowid; + $resql=$this->db->query($sql); + if ($resql) + { + // On efface le repertoire de pdf provisoire + $ref = dol_sanitizeFileName($this->ref); + if ($conf->facture->dir_output) + { + $dir = $conf->facture->dir_output . "/" . $ref; + $file = $conf->facture->dir_output . "/" . $ref . "/" . $ref . ".pdf"; + if (file_exists($file)) // We must delete all files before deleting directory + { + $ret=dol_delete_preview($this); + + if (! dol_delete_file($file,0,0,0,$this)) // For triggers + { + $this->error=$langs->trans("ErrorCanNotDeleteFile",$file); + $this->db->rollback(); + return 0; + } + } + if (file_exists($dir)) + { + if (! dol_delete_dir_recursive($dir)) // For remove dir and meta + { + $this->error=$langs->trans("ErrorCanNotDeleteDir",$dir); + $this->db->rollback(); + return 0; + } + } + } + + $this->db->commit(); + return 1; + } + else + { + $this->error=$this->db->lasterror()." sql=".$sql; + dol_syslog(get_class($this)."::delete ".$this->error, LOG_ERR); + $this->db->rollback(); + return -6; + } + } + else + { + $this->error=$this->db->lasterror()." sql=".$sql; + dol_syslog(get_class($this)."::delete ".$this->error, LOG_ERR); + $this->db->rollback(); + return -4; + } + } + else + { + $this->error=$this->db->lasterror(); + dol_syslog(get_class($this)."::delete ".$this->error, LOG_ERR); + $this->db->rollback(); + return -2; + } + } + + + /** + * Renvoi une date limite de reglement de facture en fonction des + * conditions de reglements de la facture et date de facturation + * + * @param string $cond_reglement Condition of payment (code or id) to use. If 0, we use current condition. + * @return date Date limite de reglement si ok, <0 si ko + */ + function calculate_date_lim_reglement($cond_reglement=0) + { + if (! $cond_reglement) $cond_reglement=$this->cond_reglement_code; + if (! $cond_reglement) $cond_reglement=$this->cond_reglement_id; + + $cdr_nbjour=0; $cdr_fdm=0; $cdr_decalage=0; + + $sqltemp = 'SELECT c.fdm,c.nbjour,c.decalage'; + $sqltemp.= ' FROM '.MAIN_DB_PREFIX.'c_payment_term as c'; + if (is_numeric($cond_reglement)) $sqltemp.= " WHERE c.rowid=".$cond_reglement; + else $sqltemp.= " WHERE c.code='".$this->db->escape($cond_reglement)."'"; + + dol_syslog(get_class($this).'::calculate_date_lim_reglement sql='.$sqltemp); + $resqltemp=$this->db->query($sqltemp); + if ($resqltemp) + { + if ($this->db->num_rows($resqltemp)) + { + $obj = $this->db->fetch_object($resqltemp); + $cdr_nbjour = $obj->nbjour; + $cdr_fdm = $obj->fdm; + $cdr_decalage = $obj->decalage; + } + } + else + { + $this->error=$this->db->error(); + return -1; + } + $this->db->free($resqltemp); + + /* Definition de la date limite */ + + // 1 : ajout du nombre de jours + $datelim = $this->date + ($cdr_nbjour * 3600 * 24); + + // 2 : application de la regle "fin de mois" + if ($cdr_fdm) + { + $mois=date('m', $datelim); + $annee=date('Y', $datelim); + if ($mois == 12) + { + $mois = 1; + $annee += 1; + } + else + { + $mois += 1; + } + // On se deplace au debut du mois suivant, et on retire un jour + $datelim=dol_mktime(12,0,0,$mois,1,$annee); + $datelim -= (3600 * 24); + } + + // 3 : application du decalage + $datelim += ($cdr_decalage * 3600 * 24); + + return $datelim; + } + + /** + * Tag la facture comme paye completement (close_code non renseigne) ou partiellement (close_code renseigne) + appel trigger BILL_PAYED + * + * @param User $user Objet utilisateur qui modifie + * @param string $close_code Code renseigne si on classe a payee completement alors que paiement incomplet (cas escompte par exemple) + * @param string $close_note Commentaire renseigne si on classe a payee alors que paiement incomplet (cas escompte par exemple) + * @return int <0 if KO, >0 if OK + */ + function set_paid($user,$close_code='',$close_note='') + { + global $conf,$langs; + $error=0; + + if ($this->paye != 1) + { + $this->db->begin(); + + dol_syslog(get_class($this)."::set_paid rowid=".$this->id, LOG_DEBUG); + $sql = 'UPDATE '.MAIN_DB_PREFIX.'facture SET'; + $sql.= ' fk_statut=2'; + if (! $close_code) $sql.= ', paye=1'; + if ($close_code) $sql.= ", close_code='".$this->db->escape($close_code)."'"; + if ($close_note) $sql.= ", close_note='".$this->db->escape($close_note)."'"; + $sql.= ' WHERE rowid = '.$this->id; + + $resql = $this->db->query($sql); + if ($resql) + { + // Appel des triggers + include_once DOL_DOCUMENT_ROOT . '/core/class/interfaces.class.php'; + $interface=new Interfaces($this->db); + $result=$interface->run_triggers('BILL_PAYED',$this,$user,$langs,$conf); + if ($result < 0) { + $error++; $this->errors=$interface->errors; + } + // Fin appel triggers + } + else + { + $error++; + $this->error=$this->db->error(); + dol_print_error($this->db); + } + + if (! $error) + { + $this->db->commit(); + return 1; + } + else + { + $this->db->rollback(); + return -1; + } + } + else + { + return 0; + } + } + + + /** + * Tag la facture comme non payee completement + appel trigger BILL_UNPAYED + * Fonction utilisee quand un paiement prelevement est refuse, + * ou quand une facture annulee et reouverte. + * + * @param User $user Object user that change status + * @return int <0 if KO, >0 if OK + */ + function set_unpaid($user) + { + global $conf,$langs; + $error=0; + + $this->db->begin(); + + $sql = 'UPDATE '.MAIN_DB_PREFIX.'facture'; + $sql.= ' SET paye=0, fk_statut=1, close_code=null, close_note=null'; + $sql.= ' WHERE rowid = '.$this->id; + + dol_syslog(get_class($this)."::set_unpaid sql=".$sql); + $resql = $this->db->query($sql); + if ($resql) + { + // Appel des triggers + include_once DOL_DOCUMENT_ROOT . '/core/class/interfaces.class.php'; + $interface=new Interfaces($this->db); + $result=$interface->run_triggers('BILL_UNPAYED',$this,$user,$langs,$conf); + if ($result < 0) { + $error++; $this->errors=$interface->errors; + } + // Fin appel triggers + } + else + { + $error++; + $this->error=$this->db->error(); + dol_print_error($this->db); + } + + if (! $error) + { + $this->db->commit(); + return 1; + } + else + { + $this->db->rollback(); + return -1; + } + } + + + /** + * Tag invoice as canceled, with no payment on it (example for replacement invoice or payment never received) + call trigger BILL_CANCEL + * Warning, if option to decrease stock on invoice was set, this function does not change stock (it might be a cancel because + * of no payment even if merchandises were sent). + * + * @param User $user Object user making change + * @param string $close_code Code de fermeture + * @param string $close_note Comment + * @return int <0 if KO, >0 if OK + */ + function set_canceled($user,$close_code='',$close_note='') + { + global $conf,$langs; + + $error=0; + + dol_syslog(get_class($this)."::set_canceled rowid=".$this->id, LOG_DEBUG); + + $this->db->begin(); + + $sql = 'UPDATE '.MAIN_DB_PREFIX.'facture SET'; + $sql.= ' fk_statut=3'; + if ($close_code) $sql.= ", close_code='".$this->db->escape($close_code)."'"; + if ($close_note) $sql.= ", close_note='".$this->db->escape($close_note)."'"; + $sql.= ' WHERE rowid = '.$this->id; + + $resql = $this->db->query($sql); + if ($resql) + { + // On desaffecte de la facture les remises liees + // car elles n'ont pas ete utilisees vu que la facture est abandonnee. + $sql = 'UPDATE '.MAIN_DB_PREFIX.'societe_remise_except'; + $sql.= ' SET fk_facture = NULL'; + $sql.= ' WHERE fk_facture = '.$this->id; + + $resql=$this->db->query($sql); + if ($resql) + { + // Appel des triggers + include_once DOL_DOCUMENT_ROOT . '/core/class/interfaces.class.php'; + $interface=new Interfaces($this->db); + $result=$interface->run_triggers('BILL_CANCEL',$this,$user,$langs,$conf); + if ($result < 0) { + $error++; $this->errors=$interface->errors; + } + // Fin appel triggers + + $this->db->commit(); + return 1; + } + else + { + $this->error=$this->db->error()." sql=".$sql; + $this->db->rollback(); + return -1; + } + } + else + { + $this->error=$this->db->error()." sql=".$sql; + $this->db->rollback(); + return -2; + } + } + + /** + * Tag invoice as validated + call trigger BILL_VALIDATE + * Object must have lines loaded with fetch_lines + * + * @param User $user Object user that validate + * @param string $force_number Reference to force on invoice + * @param int $idwarehouse Id of warehouse to use for stock decrease + * @return int <0 if KO, >0 if OK + */ + function validate($user, $force_number='', $idwarehouse=0) + { + global $conf,$langs; + require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; + + $now=dol_now(); + + $error=0; + dol_syslog(get_class($this).'::validate user='.$user->id.', force_number='.$force_number.', idwarehouse='.$idwarehouse); + + // Check parameters + if (! $this->brouillon) + { + dol_syslog(get_class($this)."::validate no draft status", LOG_WARNING); + return 0; + } + + if (! $user->rights->facture->valider) + { + $this->error='Permission denied'; + dol_syslog(get_class($this)."::validate ".$this->error, LOG_ERR); + return -1; + } + + $this->db->begin(); + + $this->fetch_thirdparty(); + $this->fetch_lines(); + + // Check parameters + if ($this->type == 1) // si facture de remplacement + { + // Controle que facture source connue + if ($this->fk_facture_source <= 0) + { + $this->error=$langs->trans("ErrorFieldRequired",$langs->trans("InvoiceReplacement")); + $this->db->rollback(); + return -10; + } + + // Charge la facture source a remplacer + $facreplaced=new Facture($this->db); + $result=$facreplaced->fetch($this->fk_facture_source); + if ($result <= 0) + { + $this->error=$langs->trans("ErrorBadInvoice"); + $this->db->rollback(); + return -11; + } + + // Controle que facture source non deja remplacee par une autre + $idreplacement=$facreplaced->getIdReplacingInvoice('validated'); + if ($idreplacement && $idreplacement != $this->id) + { + $facreplacement=new Facture($this->db); + $facreplacement->fetch($idreplacement); + $this->error=$langs->trans("ErrorInvoiceAlreadyReplaced",$facreplaced->ref,$facreplacement->ref); + $this->db->rollback(); + return -12; + } + + $result=$facreplaced->set_canceled($user,'replaced',''); + if ($result < 0) + { + $this->error=$facreplaced->error; + $this->db->rollback(); + return -13; + } + } + + // Define new ref + if ($force_number) + { + $num = $force_number; + } + else if (preg_match('/^[\(]?PROV/i', $this->ref)) + { + if (! empty($conf->global->FAC_FORCE_DATE_VALIDATION)) // If option enabled, we force invoice date + { + $this->date=dol_now(); + $this->date_lim_reglement=$this->calculate_date_lim_reglement(); + } + $num = $this->getNextNumRef($this->client); + } + else + { + $num = $this->ref; + } + + if ($num) + { + $this->update_price(1); + + // Validate + $sql = 'UPDATE '.MAIN_DB_PREFIX.'facture'; + $sql.= " SET facnumber='".$num."', fk_statut = 1, fk_user_valid = ".$user->id.", date_valid = '".$this->db->idate($now)."'"; + if (! empty($conf->global->FAC_FORCE_DATE_VALIDATION)) // If option enabled, we force invoice date + { + $sql.= ', datef='.$this->db->idate($this->date); + $sql.= ', date_lim_reglement='.$this->db->idate($this->date_lim_reglement); + } + $sql.= ' WHERE rowid = '.$this->id; + + dol_syslog(get_class($this)."::validate sql=".$sql); + $resql=$this->db->query($sql); + if (! $resql) + { + dol_syslog(get_class($this)."::validate Echec update - 10 - sql=".$sql, LOG_ERR); + dol_print_error($this->db); + $error++; + } + + // On verifie si la facture etait une provisoire + if (! $error && (preg_match('/^[\(]?PROV/i', $this->ref))) + { + // La verif qu'une remise n'est pas utilisee 2 fois est faite au moment de l'insertion de ligne + } + + if (! $error) + { + // Define third party as a customer + $result=$this->client->set_as_client(); + + // Si active on decremente le produit principal et ses composants a la validation de facture + if ($this->type != 3 && $result >= 0 && ! empty($conf->stock->enabled) && ! empty($conf->global->STOCK_CALCULATE_ON_BILL)) + { + require_once DOL_DOCUMENT_ROOT.'/product/stock/class/mouvementstock.class.php'; + $langs->load("agenda"); + + // Loop on each line + $cpt=count($this->lines); + for ($i = 0; $i < $cpt; $i++) + { + if ($this->lines[$i]->fk_product > 0) + { + $mouvP = new MouvementStock($this->db); + // We decrease stock for product + if ($this->type == 2) $result=$mouvP->reception($user, $this->lines[$i]->fk_product, $idwarehouse, $this->lines[$i]->qty, $this->lines[$i]->subprice, $langs->trans("InvoiceValidatedInDolibarr",$num)); + else $result=$mouvP->livraison($user, $this->lines[$i]->fk_product, $idwarehouse, $this->lines[$i]->qty, $this->lines[$i]->subprice, $langs->trans("InvoiceValidatedInDolibarr",$num)); + if ($result < 0) { + $error++; + } + } + } + } + } + + if (! $error) + { + $this->oldref = ''; + + // Rename directory if dir was a temporary ref + if (preg_match('/^[\(]?PROV/i', $this->ref)) + { + // On renomme repertoire facture ($this->ref = ancienne ref, $num = nouvelle ref) + // afin de ne pas perdre les fichiers attaches + $facref = dol_sanitizeFileName($this->ref); + $snumfa = dol_sanitizeFileName($num); + $dirsource = $conf->facture->dir_output.'/'.$facref; + $dirdest = $conf->facture->dir_output.'/'.$snumfa; + if (file_exists($dirsource)) + { + dol_syslog(get_class($this)."::validate rename dir ".$dirsource." into ".$dirdest); + + if (@rename($dirsource, $dirdest)) + { + $this->oldref = $facref; + + dol_syslog("Rename ok"); + // Suppression ancien fichier PDF dans nouveau rep + dol_delete_file($conf->facture->dir_output.'/'.$snumfa.'/'.$facref.'*.*'); + } + } + } + } + + // Set new ref and define current statut + if (! $error) + { + $this->ref = $num; + $this->facnumber=$num; + $this->statut=1; + $this->brouillon=0; + $this->date_validation=$now; + } + + // Trigger calls + if (! $error) + { + // Appel des triggers + include_once DOL_DOCUMENT_ROOT . '/core/class/interfaces.class.php'; + $interface=new Interfaces($this->db); + $result=$interface->run_triggers('BILL_VALIDATE',$this,$user,$langs,$conf); + if ($result < 0) { + $error++; $this->errors=$interface->errors; + } + // Fin appel triggers + } + } + else + { + $error++; + } + + if (! $error) + { + $this->db->commit(); + return 1; + } + else + { + $this->db->rollback(); + $this->error=$this->db->lasterror(); + return -1; + } + } + + /** + * Set draft status + * + * @param User $user Object user that modify + * @param int $idwarehouse Id warehouse to use for stock change. + * @return int <0 if KO, >0 if OK + */ + function set_draft($user,$idwarehouse=-1) + { + global $conf,$langs; + + $error=0; + + if ($this->statut == 0) + { + dol_syslog(get_class($this)."::set_draft already draft status", LOG_WARNING); + return 0; + } + + $this->db->begin(); + + $sql = "UPDATE ".MAIN_DB_PREFIX."facture"; + $sql.= " SET fk_statut = 0"; + $sql.= " WHERE rowid = ".$this->id; + + dol_syslog(get_class($this)."::set_draft sql=".$sql, LOG_DEBUG); + $result=$this->db->query($sql); + if ($result) + { + // Si on decremente le produit principal et ses composants a la validation de facture, on réincrement + if ($this->type != 3 && $result >= 0 && ! empty($conf->stock->enabled) && ! empty($conf->global->STOCK_CALCULATE_ON_BILL)) + { + require_once DOL_DOCUMENT_ROOT.'/product/stock/class/mouvementstock.class.php'; + $langs->load("agenda"); + + $num=count($this->lines); + for ($i = 0; $i < $num; $i++) + { + if ($this->lines[$i]->fk_product > 0) + { + $mouvP = new MouvementStock($this->db); + // We decrease stock for product + if ($this->type == 2) $result=$mouvP->livraison($user, $this->lines[$i]->fk_product, $idwarehouse, $this->lines[$i]->qty, $this->lines[$i]->subprice, $langs->trans("InvoiceBackToDraftInDolibarr",$this->ref)); + else $result=$mouvP->reception($user, $this->lines[$i]->fk_product, $idwarehouse, $this->lines[$i]->qty, 0, $langs->trans("InvoiceBackToDraftInDolibarr",$this->ref)); // we use 0 for price, to not change the weighted average value + } + } + } if ($error == 0) - { + { $old_statut=$this->statut; - $this->brouillon = 1; - $this->statut = 0; + $this->brouillon = 1; + $this->statut = 0; // Appel des triggers include_once DOL_DOCUMENT_ROOT . '/core/class/interfaces.class.php'; $interface=new Interfaces($this->db); @@ -1885,270 +1924,270 @@ class Facture extends CommonInvoice return -1; } - if ($error == 0) - { - $this->db->commit(); - return 1; - } - else - { - $this->db->rollback(); - return -1; - } - } - else - { - $this->error=$this->db->error(); - $this->db->rollback(); - return -1; - } - } + if ($error == 0) + { + $this->db->commit(); + return 1; + } + else + { + $this->db->rollback(); + return -1; + } + } + else + { + $this->error=$this->db->error(); + $this->db->rollback(); + return -1; + } + } - /** - * Add an invoice 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 int $facid Id de la facture - * @param string $desc Description de la ligne - * @param double $pu_ht Prix unitaire HT (> 0 even for credit note) - * @param double $qty Quantite - * @param double $txtva Taux de tva force, sinon -1 - * @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 timestamp $date_start Date de debut de validite du service - * @param timestamp $date_end Date de fin de validite du service - * @param int $ventil Code de ventilation comptable - * @param int $info_bits Bits de type de lignes - * @param int $fk_remise_except Id remise - * @param string $price_base_type HT or TTC - * @param double $pu_ttc Prix unitaire TTC (> 0 even for credit note) - * @param int $type Type of line (0=product, 1=service) - * @param int $rang Position of line - * @param int $special_code Special code (also used by externals modules!) - * @param string $origin 'order', ... - * @param int $origin_id Id of origin object - * @param int $fk_parent_line Id of parent line - * @param int $fk_fournprice To calculate margin - * @param int $pa_ht Buying price of line - * @param string $label Label of the line - * @return int <0 if KO, Id of line if OK - */ - function addline($facid, $desc, $pu_ht, $qty, $txtva, $txlocaltax1=0, $txlocaltax2=0, $fk_product=0, $remise_percent=0, $date_start='', $date_end='', $ventil=0, $info_bits=0, $fk_remise_except='', $price_base_type='HT', $pu_ttc=0, $type=0, $rang=-1, $special_code=0, $origin='', $origin_id=0, $fk_parent_line=0, $fk_fournprice=null, $pa_ht=0, $label='') - { - dol_syslog(get_class($this)."::Addline facid=$facid,desc=$desc,pu_ht=$pu_ht,qty=$qty,txtva=$txtva, txlocaltax1=$txlocaltax1, txlocaltax2=$txlocaltax2, fk_product=$fk_product,remise_percent=$remise_percent,date_start=$date_start,date_end=$date_end,ventil=$ventil,info_bits=$info_bits,fk_remise_except=$fk_remise_except,price_base_type=$price_base_type,pu_ttc=$pu_ttc,type=$type", LOG_DEBUG); - include_once DOL_DOCUMENT_ROOT.'/core/lib/price.lib.php'; + /** + * Add an invoice 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 int $facid Id de la facture + * @param string $desc Description de la ligne + * @param double $pu_ht Prix unitaire HT (> 0 even for credit note) + * @param double $qty Quantite + * @param double $txtva Taux de tva force, sinon -1 + * @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 timestamp $date_start Date de debut de validite du service + * @param timestamp $date_end Date de fin de validite du service + * @param int $ventil Code de ventilation comptable + * @param int $info_bits Bits de type de lignes + * @param int $fk_remise_except Id remise + * @param string $price_base_type HT or TTC + * @param double $pu_ttc Prix unitaire TTC (> 0 even for credit note) + * @param int $type Type of line (0=product, 1=service) + * @param int $rang Position of line + * @param int $special_code Special code (also used by externals modules!) + * @param string $origin 'order', ... + * @param int $origin_id Id of origin object + * @param int $fk_parent_line Id of parent line + * @param int $fk_fournprice To calculate margin + * @param int $pa_ht Buying price of line + * @param string $label Label of the line + * @return int <0 if KO, Id of line if OK + */ + function addline($facid, $desc, $pu_ht, $qty, $txtva, $txlocaltax1=0, $txlocaltax2=0, $fk_product=0, $remise_percent=0, $date_start='', $date_end='', $ventil=0, $info_bits=0, $fk_remise_except='', $price_base_type='HT', $pu_ttc=0, $type=0, $rang=-1, $special_code=0, $origin='', $origin_id=0, $fk_parent_line=0, $fk_fournprice=null, $pa_ht=0, $label='') + { + dol_syslog(get_class($this)."::Addline facid=$facid,desc=$desc,pu_ht=$pu_ht,qty=$qty,txtva=$txtva, txlocaltax1=$txlocaltax1, txlocaltax2=$txlocaltax2, fk_product=$fk_product,remise_percent=$remise_percent,date_start=$date_start,date_end=$date_end,ventil=$ventil,info_bits=$info_bits,fk_remise_except=$fk_remise_except,price_base_type=$price_base_type,pu_ttc=$pu_ttc,type=$type", LOG_DEBUG); + 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($ventil)) $ventil=0; - if (empty($txtva)) $txtva=0; - if (empty($txlocaltax1)) $txlocaltax1=0; - if (empty($txlocaltax2)) $txlocaltax2=0; - if (empty($fk_parent_line) || $fk_parent_line < 0) $fk_parent_line=0; + // 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($ventil)) $ventil=0; + if (empty($txtva)) $txtva=0; + if (empty($txlocaltax1)) $txlocaltax1=0; + if (empty($txlocaltax2)) $txlocaltax2=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); - $pa_ht=price2num($pa_ht); - $txtva=price2num($txtva); - $txlocaltax1=price2num($txlocaltax1); - $txlocaltax2=price2num($txlocaltax2); + $remise_percent=price2num($remise_percent); + $qty=price2num($qty); + $pu_ht=price2num($pu_ht); + $pu_ttc=price2num($pu_ttc); + $pa_ht=price2num($pa_ht); + $txtva=price2num($txtva); + $txlocaltax1=price2num($txlocaltax1); + $txlocaltax2=price2num($txlocaltax2); - if ($price_base_type=='HT') - { - $pu=$pu_ht; - } - else - { - $pu=$pu_ttc; - } + if ($price_base_type=='HT') + { + $pu=$pu_ht; + } + else + { + $pu=$pu_ttc; + } - // Check parameters - if ($type < 0) return -1; + // Check parameters + if ($type < 0) return -1; - if (! empty($this->brouillon)) - { - $this->db->begin(); + if (! empty($this->brouillon)) + { + $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. - $tabprice = calcul_price_total($qty, $pu, $remise_percent, $txtva, $txlocaltax1, $txlocaltax2, 0, $price_base_type, $info_bits, $type); - $total_ht = $tabprice[0]; - $total_tva = $tabprice[1]; - $total_ttc = $tabprice[2]; - $total_localtax1 = $tabprice[9]; - $total_localtax2 = $tabprice[10]; - $pu_ht = $tabprice[3]; + // 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. + $tabprice = calcul_price_total($qty, $pu, $remise_percent, $txtva, $txlocaltax1, $txlocaltax2, 0, $price_base_type, $info_bits, $type); + $total_ht = $tabprice[0]; + $total_tva = $tabprice[1]; + $total_ttc = $tabprice[2]; + $total_localtax1 = $tabprice[9]; + $total_localtax2 = $tabprice[10]; + $pu_ht = $tabprice[3]; - // Rang to use - $rangtouse = $rang; - if ($rangtouse == -1) - { - $rangmax = $this->line_max($fk_parent_line); - $rangtouse = $rangmax + 1; - } + // Rang to use + $rangtouse = $rang; + if ($rangtouse == -1) + { + $rangmax = $this->line_max($fk_parent_line); + $rangtouse = $rangmax + 1; + } - $product_type=$type; - if ($fk_product) - { - $product=new Product($this->db); - $result=$product->fetch($fk_product); - $product_type=$product->type; - } + $product_type=$type; + if ($fk_product) + { + $product=new Product($this->db); + $result=$product->fetch($fk_product); + $product_type=$product->type; + } - // Insert line - $this->line=new FactureLigne($this->db); - $this->line->fk_facture=$facid; - $this->line->label=$label; - $this->line->desc=$desc; - $this->line->qty= ($this->type==2?abs($qty):$qty); // For credit note, quantity is always positive and unit price negative - $this->line->tva_tx=$txtva; - $this->line->localtax1_tx=$txlocaltax1; - $this->line->localtax2_tx=$txlocaltax2; - $this->line->fk_product=$fk_product; - $this->line->product_type=$product_type; - $this->line->remise_percent=$remise_percent; - $this->line->subprice= ($this->type==2?-abs($pu_ht):$pu_ht); // For credit note, unit price always negative, always positive otherwise - $this->line->date_start=$date_start; - $this->line->date_end=$date_end; - $this->line->ventil=$ventil; - $this->line->rang=$rangtouse; - $this->line->info_bits=$info_bits; - $this->line->fk_remise_except=$fk_remise_except; - $this->line->total_ht= (($this->type==2||$qty<0)?-abs($total_ht):$total_ht); // For credit note and if qty is negative, total is negative - $this->line->total_tva= (($this->type==2||$qty<0)?-abs($total_tva):$total_tva); - $this->line->total_localtax1=(($this->type==2||$qty<0)?-abs($total_localtax1):$total_localtax1); - $this->line->total_localtax2=(($this->type==2||$qty<0)?-abs($total_localtax2):$total_localtax2); - $this->line->total_ttc= (($this->type==2||$qty<0)?-abs($total_ttc):$total_ttc); - $this->line->special_code=$special_code; - $this->line->fk_parent_line=$fk_parent_line; - $this->line->origin=$origin; - $this->line->origin_id=$origin_id; + // Insert line + $this->line=new FactureLigne($this->db); + $this->line->fk_facture=$facid; + $this->line->label=$label; + $this->line->desc=$desc; + $this->line->qty= ($this->type==2?abs($qty):$qty); // For credit note, quantity is always positive and unit price negative + $this->line->tva_tx=$txtva; + $this->line->localtax1_tx=$txlocaltax1; + $this->line->localtax2_tx=$txlocaltax2; + $this->line->fk_product=$fk_product; + $this->line->product_type=$product_type; + $this->line->remise_percent=$remise_percent; + $this->line->subprice= ($this->type==2?-abs($pu_ht):$pu_ht); // For credit note, unit price always negative, always positive otherwise + $this->line->date_start=$date_start; + $this->line->date_end=$date_end; + $this->line->ventil=$ventil; + $this->line->rang=$rangtouse; + $this->line->info_bits=$info_bits; + $this->line->fk_remise_except=$fk_remise_except; + $this->line->total_ht= (($this->type==2||$qty<0)?-abs($total_ht):$total_ht); // For credit note and if qty is negative, total is negative + $this->line->total_tva= (($this->type==2||$qty<0)?-abs($total_tva):$total_tva); + $this->line->total_localtax1=(($this->type==2||$qty<0)?-abs($total_localtax1):$total_localtax1); + $this->line->total_localtax2=(($this->type==2||$qty<0)?-abs($total_localtax2):$total_localtax2); + $this->line->total_ttc= (($this->type==2||$qty<0)?-abs($total_ttc):$total_ttc); + $this->line->special_code=$special_code; + $this->line->fk_parent_line=$fk_parent_line; + $this->line->origin=$origin; + $this->line->origin_id=$origin_id; // infos marge $this->line->fk_fournprice = $fk_fournprice; $this->line->pa_ht = $pa_ht; - $result=$this->line->insert(); - if ($result > 0) - { - // Reorder if child line + $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 facture meme - $this->id=$facid; // TODO To move this we must remove parameter facid into this function declaration - $result=$this->update_price(1); - if ($result > 0) - { - $this->db->commit(); - return $this->line->rowid; - } - else - { - $this->error=$this->db->error(); - dol_syslog("Error sql=$sql, error=".$this->error,LOG_ERR); - $this->db->rollback(); - return -1; - } - } - else - { - $this->error=$this->line->error; - $this->db->rollback(); - return -2; - } - } - } + // Mise a jour informations denormalisees au niveau de la facture meme + $this->id=$facid; // TODO To move this we must remove parameter facid into this function declaration + $result=$this->update_price(1); + if ($result > 0) + { + $this->db->commit(); + return $this->line->rowid; + } + else + { + $this->error=$this->db->error(); + dol_syslog("Error sql=$sql, error=".$this->error,LOG_ERR); + $this->db->rollback(); + return -1; + } + } + else + { + $this->error=$this->line->error; + $this->db->rollback(); + return -2; + } + } + } - /** - * Update a detail line - * - * @param int $rowid Id of line to update - * @param string $desc Description of line - * @param double $pu Prix unitaire (HT ou TTC selon price_base_type) (> 0 even for credit note lines) - * @param double $qty Quantity - * @param double $remise_percent Pourcentage de remise de la ligne - * @param date $date_start Date de debut de validite du service - * @param date $date_end Date de fin de validite du service - * @param double $txtva VAT Rate - * @param double $txlocaltax1 Local tax 1 rate - * @param double $txlocaltax2 Local tax 2 rate - * @param string $price_base_type HT or TTC - * @param int $info_bits Miscellaneous informations - * @param int $type Type of line (0=product, 1=service) - * @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 Label of the line - * @param int $special_code Special code (also used by externals modules!) - * @return int < 0 if KO, > 0 if OK - */ - function updateline($rowid, $desc, $pu, $qty, $remise_percent, $date_start, $date_end, $txtva, $txlocaltax1=0, $txlocaltax2=0, $price_base_type='HT', $info_bits=0, $type=0, $fk_parent_line=0, $skip_update_total=0, $fk_fournprice=null, $pa_ht=0, $label='', $special_code=0) - { - include_once DOL_DOCUMENT_ROOT.'/core/lib/price.lib.php'; + /** + * Update a detail line + * + * @param int $rowid Id of line to update + * @param string $desc Description of line + * @param double $pu Prix unitaire (HT ou TTC selon price_base_type) (> 0 even for credit note lines) + * @param double $qty Quantity + * @param double $remise_percent Pourcentage de remise de la ligne + * @param date $date_start Date de debut de validite du service + * @param date $date_end Date de fin de validite du service + * @param double $txtva VAT Rate + * @param double $txlocaltax1 Local tax 1 rate + * @param double $txlocaltax2 Local tax 2 rate + * @param string $price_base_type HT or TTC + * @param int $info_bits Miscellaneous informations + * @param int $type Type of line (0=product, 1=service) + * @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 Label of the line + * @param int $special_code Special code (also used by externals modules!) + * @return int < 0 if KO, > 0 if OK + */ + function updateline($rowid, $desc, $pu, $qty, $remise_percent, $date_start, $date_end, $txtva, $txlocaltax1=0, $txlocaltax2=0, $price_base_type='HT', $info_bits=0, $type=0, $fk_parent_line=0, $skip_update_total=0, $fk_fournprice=null, $pa_ht=0, $label='', $special_code=0) + { + include_once DOL_DOCUMENT_ROOT.'/core/lib/price.lib.php'; - dol_syslog(get_class($this)."::updateline $rowid, $desc, $pu, $qty, $remise_percent, $date_start, $date_end, $txtva, $txlocaltax1, $txlocaltax2, $price_base_type, $info_bits, $type, $fk_parent_line", LOG_DEBUG); + dol_syslog(get_class($this)."::updateline $rowid, $desc, $pu, $qty, $remise_percent, $date_start, $date_end, $txtva, $txlocaltax1, $txlocaltax2, $price_base_type, $info_bits, $type, $fk_parent_line", LOG_DEBUG); - if ($this->brouillon) - { - $this->db->begin(); + if ($this->brouillon) + { + $this->db->begin(); - // Clean parameters - if (empty($qty)) $qty=0; - if (empty($fk_parent_line) || $fk_parent_line < 0) $fk_parent_line=0; - if (empty($special_code) || $special_code == 3) $special_code=0; + // Clean parameters + if (empty($qty)) $qty=0; + if (empty($fk_parent_line) || $fk_parent_line < 0) $fk_parent_line=0; + if (empty($special_code) || $special_code == 3) $special_code=0; - $remise_percent = price2num($remise_percent); - $qty = price2num($qty); - $pu = price2num($pu); - $pa_ht = price2num($pa_ht); - $txtva = price2num($txtva); - $txlocaltax1 = price2num($txlocaltax1); - $txlocaltax2 = price2num($txlocaltax2); + $remise_percent = price2num($remise_percent); + $qty = price2num($qty); + $pu = price2num($pu); + $pa_ht = price2num($pa_ht); + $txtva = price2num($txtva); + $txlocaltax1 = price2num($txlocaltax1); + $txlocaltax2 = price2num($txlocaltax2); - // Check parameters - if ($type < 0) return -1; + // Check parameters + if ($type < 0) return -1; - // Calculate total with, without tax and tax from qty, pu, remise_percent and 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. - $tabprice=calcul_price_total($qty, $pu, $remise_percent, $txtva, $txlocaltax1, $txlocaltax2, 0, $price_base_type, $info_bits, $type); - $total_ht = $tabprice[0]; - $total_tva = $tabprice[1]; - $total_ttc = $tabprice[2]; - $total_localtax1=$tabprice[9]; - $total_localtax2=$tabprice[10]; - $pu_ht = $tabprice[3]; - $pu_tva = $tabprice[4]; - $pu_ttc = $tabprice[5]; + // Calculate total with, without tax and tax from qty, pu, remise_percent and 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. + $tabprice=calcul_price_total($qty, $pu, $remise_percent, $txtva, $txlocaltax1, $txlocaltax2, 0, $price_base_type, $info_bits, $type); + $total_ht = $tabprice[0]; + $total_tva = $tabprice[1]; + $total_ttc = $tabprice[2]; + $total_localtax1=$tabprice[9]; + $total_localtax2=$tabprice[10]; + $pu_ht = $tabprice[3]; + $pu_tva = $tabprice[4]; + $pu_ttc = $tabprice[5]; - // Old properties: $price, $remise (deprecated) - $price = $pu; - $remise = 0; - if ($remise_percent > 0) - { - $remise = round(($pu * $remise_percent / 100),2); - $price = ($pu - $remise); - } - $price = price2num($price); + // Old properties: $price, $remise (deprecated) + $price = $pu; + $remise = 0; + if ($remise_percent > 0) + { + $remise = round(($pu * $remise_percent / 100),2); + $price = ($pu - $remise); + } + $price = price2num($price); - // Update line into database - $this->line=new FactureLigne($this->db); + // Update line into database + $this->line=new FactureLigne($this->db); - // Stock previous line records + // Stock previous line records $staticline=new FactureLigne($this->db); $staticline->fetch($rowid); $this->line->oldline = $staticline; @@ -2160,981 +2199,981 @@ class Facture extends CommonInvoice $this->line->rang = $rangmax + 1; } - $this->line->rowid = $rowid; - $this->line->label = $label; - $this->line->desc = $desc; - $this->line->qty = ($this->type==2?abs($qty):$qty); // For credit note, quantity is always positive and unit price negative - $this->line->tva_tx = $txtva; - $this->line->localtax1_tx = $txlocaltax1; - $this->line->localtax2_tx = $txlocaltax2; - $this->line->remise_percent = $remise_percent; - $this->line->subprice = ($this->type==2?-abs($pu_ht):$pu_ht); // For credit note, unit price always negative, always positive otherwise - $this->line->date_start = $date_start; - $this->line->date_end = $date_end; - $this->line->total_ht = (($this->type==2||$qty<0)?-abs($total_ht):$total_ht); // For credit note and if qty is negative, total is negative - $this->line->total_tva = (($this->type==2||$qty<0)?-abs($total_tva):$total_tva); - $this->line->total_localtax1 = (($this->type==2||$qty<0)?-abs($total_localtax1):$total_localtax1); - $this->line->total_localtax2 = (($this->type==2||$qty<0)?-abs($total_localtax2):$total_localtax2); - $this->line->total_ttc = (($this->type==2||$qty<0)?-abs($total_ttc):$total_ttc); - $this->line->info_bits = $info_bits; - $this->line->special_code = $special_code; - $this->line->product_type = $type; - $this->line->fk_parent_line = $fk_parent_line; - $this->line->skip_update_total = $skip_update_total; + $this->line->rowid = $rowid; + $this->line->label = $label; + $this->line->desc = $desc; + $this->line->qty = ($this->type==2?abs($qty):$qty); // For credit note, quantity is always positive and unit price negative + $this->line->tva_tx = $txtva; + $this->line->localtax1_tx = $txlocaltax1; + $this->line->localtax2_tx = $txlocaltax2; + $this->line->remise_percent = $remise_percent; + $this->line->subprice = ($this->type==2?-abs($pu_ht):$pu_ht); // For credit note, unit price always negative, always positive otherwise + $this->line->date_start = $date_start; + $this->line->date_end = $date_end; + $this->line->total_ht = (($this->type==2||$qty<0)?-abs($total_ht):$total_ht); // For credit note and if qty is negative, total is negative + $this->line->total_tva = (($this->type==2||$qty<0)?-abs($total_tva):$total_tva); + $this->line->total_localtax1 = (($this->type==2||$qty<0)?-abs($total_localtax1):$total_localtax1); + $this->line->total_localtax2 = (($this->type==2||$qty<0)?-abs($total_localtax2):$total_localtax2); + $this->line->total_ttc = (($this->type==2||$qty<0)?-abs($total_ttc):$total_ttc); + $this->line->info_bits = $info_bits; + $this->line->special_code = $special_code; + $this->line->product_type = $type; + $this->line->fk_parent_line = $fk_parent_line; + $this->line->skip_update_total = $skip_update_total; // infos marge $this->line->fk_fournprice = $fk_fournprice; $this->line->pa_ht = $pa_ht; - // A ne plus utiliser - //$this->line->price=$price; - //$this->line->remise=$remise; + // A ne plus utiliser + //$this->line->price=$price; + //$this->line->remise=$remise; - $result=$this->line->update(); - if ($result > 0) - { - // Reorder if child line - if (! empty($fk_parent_line)) $this->line_order(true,'DESC'); + $result=$this->line->update(); + if ($result > 0) + { + // Reorder if child line + if (! empty($fk_parent_line)) $this->line_order(true,'DESC'); - // Mise a jour info denormalisees au niveau facture - $this->update_price(1); - $this->db->commit(); - return $result; - } - else - { - $this->db->rollback(); - return -1; - } - } - else - { - $this->error="Invoice statut makes operation forbidden"; - return -2; - } - } + // Mise a jour info denormalisees au niveau facture + $this->update_price(1); + $this->db->commit(); + return $result; + } + else + { + $this->db->rollback(); + return -1; + } + } + else + { + $this->error="Invoice statut makes operation forbidden"; + return -2; + } + } - /** - * Delete line in database - * - * @param int $rowid Id of line to delete - * @return int <0 if KO, >0 if OK - */ - function deleteline($rowid) - { - global $langs, $conf; + /** + * Delete line in database + * + * @param int $rowid Id of line to delete + * @return int <0 if KO, >0 if OK + */ + function deleteline($rowid) + { + global $langs, $conf; - dol_syslog(get_class($this)."::deleteline rowid=".$rowid, LOG_DEBUG); + dol_syslog(get_class($this)."::deleteline rowid=".$rowid, LOG_DEBUG); - if (! $this->brouillon) - { - $this->error='ErrorBadStatus'; - return -1; - } + if (! $this->brouillon) + { + $this->error='ErrorBadStatus'; + return -1; + } - $this->db->begin(); + $this->db->begin(); - // Libere remise liee a ligne de facture - $sql = 'UPDATE '.MAIN_DB_PREFIX.'societe_remise_except'; - $sql.= ' SET fk_facture_line = NULL'; - $sql.= ' WHERE fk_facture_line = '.$rowid; + // Libere remise liee a ligne de facture + $sql = 'UPDATE '.MAIN_DB_PREFIX.'societe_remise_except'; + $sql.= ' SET fk_facture_line = NULL'; + $sql.= ' WHERE fk_facture_line = '.$rowid; - dol_syslog(get_class($this)."::deleteline sql=".$sql); - $result = $this->db->query($sql); - if (! $result) - { - $this->error=$this->db->error(); - dol_syslog(get_class($this)."::deleteline Error ".$this->error, LOG_ERR); - $this->db->rollback(); - return -1; - } + dol_syslog(get_class($this)."::deleteline sql=".$sql); + $result = $this->db->query($sql); + if (! $result) + { + $this->error=$this->db->error(); + dol_syslog(get_class($this)."::deleteline Error ".$this->error, LOG_ERR); + $this->db->rollback(); + return -1; + } - $line=new FactureLigne($this->db); + $line=new FactureLigne($this->db); - // For triggers - $line->fetch($rowid); + // For triggers + $line->fetch($rowid); - if ($line->delete() > 0) - { - $result=$this->update_price(1); + if ($line->delete() > 0) + { + $result=$this->update_price(1); - if ($result > 0) - { - $this->db->commit(); - return 1; - } - else - { - $this->db->rollback(); - $this->error=$this->db->lasterror(); - return -1; - } - } - else - { - $this->db->rollback(); - $this->error=$this->db->lasterror(); - return -1; - } - } + if ($result > 0) + { + $this->db->commit(); + return 1; + } + else + { + $this->db->rollback(); + $this->error=$this->db->lasterror(); + return -1; + } + } + else + { + $this->db->rollback(); + $this->error=$this->db->lasterror(); + return -1; + } + } - /** - * Set percent discount - * - * @param User $user User that set discount - * @param double $remise Discount - * @return int <0 if ko, >0 if ok - */ - function set_remise($user, $remise) - { - // Clean parameters - if (empty($remise)) $remise=0; + /** + * Set percent discount + * + * @param User $user User that set discount + * @param double $remise Discount + * @return int <0 if ko, >0 if ok + */ + function set_remise($user, $remise) + { + // Clean parameters + if (empty($remise)) $remise=0; - if ($user->rights->facture->creer) - { - $remise=price2num($remise); + if ($user->rights->facture->creer) + { + $remise=price2num($remise); - $sql = 'UPDATE '.MAIN_DB_PREFIX.'facture'; - $sql.= ' SET remise_percent = '.$remise; - $sql.= ' WHERE rowid = '.$this->id; - $sql.= ' AND fk_statut = 0 ;'; + $sql = 'UPDATE '.MAIN_DB_PREFIX.'facture'; + $sql.= ' SET remise_percent = '.$remise; + $sql.= ' WHERE rowid = '.$this->id; + $sql.= ' 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; - } - } - } + if ($this->db->query($sql)) + { + $this->remise_percent = $remise; + $this->update_price(1); + return 1; + } + else + { + $this->error=$this->db->error(); + return -1; + } + } + } - /** - * Set absolute discount - * - * @param User $user User that set discount - * @param double $remise Discount - * @return int <0 if KO, >0 if OK - */ - function set_remise_absolue($user, $remise) - { - if (empty($remise)) $remise=0; + /** + * Set absolute discount + * + * @param User $user User that set discount + * @param double $remise Discount + * @return int <0 if KO, >0 if OK + */ + function set_remise_absolue($user, $remise) + { + if (empty($remise)) $remise=0; - if ($user->rights->facture->creer) - { - $remise=price2num($remise); + if ($user->rights->facture->creer) + { + $remise=price2num($remise); - $sql = 'UPDATE '.MAIN_DB_PREFIX.'facture'; - $sql.= ' SET remise_absolue = '.$remise; - $sql.= ' WHERE rowid = '.$this->id; - $sql.= ' AND fk_statut = 0 ;'; + $sql = 'UPDATE '.MAIN_DB_PREFIX.'facture'; + $sql.= ' SET remise_absolue = '.$remise; + $sql.= ' WHERE rowid = '.$this->id; + $sql.= ' AND fk_statut = 0 ;'; - dol_syslog(get_class($this)."::set_remise_absolue sql=$sql"); + dol_syslog(get_class($this)."::set_remise_absolue sql=$sql"); - if ($this->db->query($sql)) - { - $this->remise_absolue = $remise; - $this->update_price(1); - return 1; - } - else - { - $this->error=$this->db->error(); - return -1; - } - } - } + if ($this->db->query($sql)) + { + $this->remise_absolue = $remise; + $this->update_price(1); + return 1; + } + else + { + $this->error=$this->db->error(); + return -1; + } + } + } - /** - * Return list of payments - * - * @param string $filtertype 1 to filter on type of payment == 'PRE' - * @return array Array with list of payments - */ - function getListOfPayments($filtertype='') - { - $retarray=array(); + /** + * Return list of payments + * + * @param string $filtertype 1 to filter on type of payment == 'PRE' + * @return array Array with list of payments + */ + function getListOfPayments($filtertype='') + { + $retarray=array(); - $table='paiement_facture'; - $table2='paiement'; - $field='fk_facture'; - $field2='fk_paiement'; - if ($this->element == 'facture_fourn' || $this->element == 'invoice_supplier') - { - $table='paiementfourn_facturefourn'; - $table2='paiementfourn'; - $field='fk_facturefourn'; - $field2='fk_paiementfourn'; - } + $table='paiement_facture'; + $table2='paiement'; + $field='fk_facture'; + $field2='fk_paiement'; + if ($this->element == 'facture_fourn' || $this->element == 'invoice_supplier') + { + $table='paiementfourn_facturefourn'; + $table2='paiementfourn'; + $field='fk_facturefourn'; + $field2='fk_paiementfourn'; + } - $sql = 'SELECT pf.amount, p.fk_paiement, p.datep, t.code'; - $sql.= ' FROM '.MAIN_DB_PREFIX.$table.' as pf, '.MAIN_DB_PREFIX.$table2.' as p, '.MAIN_DB_PREFIX.'c_paiement as t'; - $sql.= ' WHERE pf.'.$field.' = '.$this->id; - $sql.= ' AND pf.'.$field2.' = p.rowid'; - $sql.= ' AND p.fk_paiement = t.id'; - if ($filtertype) $sql.=" AND t.code='PRE'"; + $sql = 'SELECT pf.amount, p.fk_paiement, p.datep, t.code'; + $sql.= ' FROM '.MAIN_DB_PREFIX.$table.' as pf, '.MAIN_DB_PREFIX.$table2.' as p, '.MAIN_DB_PREFIX.'c_paiement as t'; + $sql.= ' WHERE pf.'.$field.' = '.$this->id; + $sql.= ' AND pf.'.$field2.' = p.rowid'; + $sql.= ' AND p.fk_paiement = t.id'; + if ($filtertype) $sql.=" AND t.code='PRE'"; - dol_syslog(get_class($this)."::getListOfPayments sql=".$sql, 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); - $retarray[]=array('amount'=>$obj->amount,'type'=>$obj->code, 'date'=>$obj->datep); - $i++; - } - $this->db->free($resql); - return $retarray; - } - else - { - $this->error=$this->db->lasterror(); - dol_print_error($this->db); - return array(); - } - } + dol_syslog(get_class($this)."::getListOfPayments sql=".$sql, 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); + $retarray[]=array('amount'=>$obj->amount,'type'=>$obj->code, 'date'=>$obj->datep); + $i++; + } + $this->db->free($resql); + return $retarray; + } + else + { + $this->error=$this->db->lasterror(); + dol_print_error($this->db); + return array(); + } + } - /** - * Return amount (with tax) of all credit notes and deposits invoices used by invoice - * - * @return int <0 if KO, Sum of credit notes and deposits amount otherwise - */ - function getSumCreditNotesUsed() - { - require_once DOL_DOCUMENT_ROOT.'/core/class/discount.class.php'; + /** + * Return amount (with tax) of all credit notes and deposits invoices used by invoice + * + * @return int <0 if KO, Sum of credit notes and deposits amount otherwise + */ + function getSumCreditNotesUsed() + { + require_once DOL_DOCUMENT_ROOT.'/core/class/discount.class.php'; - $discountstatic=new DiscountAbsolute($this->db); - $result=$discountstatic->getSumCreditNotesUsed($this); - if ($result >= 0) - { - return $result; - } - else - { - $this->error=$discountstatic->error; - return -1; - } - } + $discountstatic=new DiscountAbsolute($this->db); + $result=$discountstatic->getSumCreditNotesUsed($this); + if ($result >= 0) + { + return $result; + } + else + { + $this->error=$discountstatic->error; + return -1; + } + } - /** - * Return amount (with tax) of all deposits invoices used by invoice - * - * @return int <0 if KO, Sum of deposits amount otherwise - */ - function getSumDepositsUsed() - { - require_once DOL_DOCUMENT_ROOT.'/core/class/discount.class.php'; + /** + * Return amount (with tax) of all deposits invoices used by invoice + * + * @return int <0 if KO, Sum of deposits amount otherwise + */ + function getSumDepositsUsed() + { + require_once DOL_DOCUMENT_ROOT.'/core/class/discount.class.php'; - $discountstatic=new DiscountAbsolute($this->db); - $result=$discountstatic->getSumDepositsUsed($this); - if ($result >= 0) - { - return $result; - } - else - { - $this->error=$discountstatic->error; - return -1; - } - } + $discountstatic=new DiscountAbsolute($this->db); + $result=$discountstatic->getSumDepositsUsed($this); + if ($result >= 0) + { + return $result; + } + else + { + $this->error=$discountstatic->error; + return -1; + } + } - /** - * Return next reference of customer invoice not already used (or last reference) - * according to numbering module defined into constant FACTURE_ADDON - * - * @param Society $soc object company - * @param string $mode 'next' for next value or 'last' for last value - * @return string free ref or last ref - */ - function getNextNumRef($soc,$mode='next') - { - global $conf, $db, $langs; - $langs->load("bills"); + /** + * Return next reference of customer invoice not already used (or last reference) + * according to numbering module defined into constant FACTURE_ADDON + * + * @param Society $soc object company + * @param string $mode 'next' for next value or 'last' for last value + * @return string free ref or last ref + */ + function getNextNumRef($soc,$mode='next') + { + global $conf, $db, $langs; + $langs->load("bills"); - // Clean parameters (if not defined or using deprecated value) - if (empty($conf->global->FACTURE_ADDON)) $conf->global->FACTURE_ADDON='mod_facture_terre'; - else if ($conf->global->FACTURE_ADDON=='terre') $conf->global->FACTURE_ADDON='mod_facture_terre'; - else if ($conf->global->FACTURE_ADDON=='mercure') $conf->global->FACTURE_ADDON='mod_facture_mercure'; + // Clean parameters (if not defined or using deprecated value) + if (empty($conf->global->FACTURE_ADDON)) $conf->global->FACTURE_ADDON='mod_facture_terre'; + else if ($conf->global->FACTURE_ADDON=='terre') $conf->global->FACTURE_ADDON='mod_facture_terre'; + else if ($conf->global->FACTURE_ADDON=='mercure') $conf->global->FACTURE_ADDON='mod_facture_mercure'; - $mybool=false; + $mybool=false; - $file = $conf->global->FACTURE_ADDON.".php"; - $classname = $conf->global->FACTURE_ADDON; - // Include file with class - foreach ($conf->file->dol_document_root as $dirroot) - { - $dir = $dirroot."/core/modules/facture/"; - // Load file with numbering class (if found) - $mybool|=@include_once $dir.$file; - } + $file = $conf->global->FACTURE_ADDON.".php"; + $classname = $conf->global->FACTURE_ADDON; + // Include file with class + foreach ($conf->file->dol_document_root as $dirroot) + { + $dir = $dirroot."/core/modules/facture/"; + // Load file with numbering class (if found) + $mybool|=@include_once $dir.$file; + } - // For compatibility - if (! $mybool) - { - $file = $conf->global->FACTURE_ADDON."/".$conf->global->FACTURE_ADDON.".modules.php"; - $classname = "mod_facture_".$conf->global->FACTURE_ADDON; - // Include file with class - foreach ($conf->file->dol_document_root as $dirroot) - { - $dir = $dirroot."/core/modules/facture/"; - // Load file with numbering class (if found) - $mybool|=@include_once $dir.$file; - } - } - //print "xx".$mybool.$dir.$file."-".$classname; + // For compatibility + if (! $mybool) + { + $file = $conf->global->FACTURE_ADDON."/".$conf->global->FACTURE_ADDON.".modules.php"; + $classname = "mod_facture_".$conf->global->FACTURE_ADDON; + // Include file with class + foreach ($conf->file->dol_document_root as $dirroot) + { + $dir = $dirroot."/core/modules/facture/"; + // Load file with numbering class (if found) + $mybool|=@include_once $dir.$file; + } + } + //print "xx".$mybool.$dir.$file."-".$classname; - if (! $mybool) - { - dol_print_error('',"Failed to include file ".$file); - return ''; - } + if (! $mybool) + { + dol_print_error('',"Failed to include file ".$file); + return ''; + } - $obj = new $classname(); + $obj = new $classname(); - $numref = ""; - $numref = $obj->getNumRef($soc,$this,$mode); + $numref = ""; + $numref = $obj->getNumRef($soc,$this,$mode); - if ( $numref != "") - { - return $numref; - } - else - { - //dol_print_error($db,get_class($this)."::getNextNumRef ".$obj->error); - return false; - } - } + if ( $numref != "") + { + return $numref; + } + else + { + //dol_print_error($db,get_class($this)."::getNextNumRef ".$obj->error); + return false; + } + } - /** - * Load miscellaneous information for tab "Info" - * - * @param int $id Id of object to load - * @return void - */ - function info($id) - { - $sql = 'SELECT c.rowid, datec, date_valid as datev, tms as datem,'; - $sql.= ' fk_user_author, fk_user_valid'; - $sql.= ' FROM '.MAIN_DB_PREFIX.'facture as c'; - $sql.= ' WHERE c.rowid = '.$id; + /** + * Load miscellaneous information for tab "Info" + * + * @param int $id Id of object to load + * @return void + */ + function info($id) + { + $sql = 'SELECT c.rowid, datec, date_valid as datev, tms as datem,'; + $sql.= ' fk_user_author, fk_user_valid'; + $sql.= ' FROM '.MAIN_DB_PREFIX.'facture 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; - if ($obj->fk_user_author) - { - $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; - } - $this->date_creation = $this->db->jdate($obj->datec); - $this->date_modification = $this->db->jdate($obj->datem); - $this->date_validation = $this->db->jdate($obj->datev); // Should be in log table - } - $this->db->free($result); - } - else - { - dol_print_error($this->db); - } - } + $result=$this->db->query($sql); + if ($result) + { + if ($this->db->num_rows($result)) + { + $obj = $this->db->fetch_object($result); + $this->id = $obj->rowid; + if ($obj->fk_user_author) + { + $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; + } + $this->date_creation = $this->db->jdate($obj->datec); + $this->date_modification = $this->db->jdate($obj->datem); + $this->date_validation = $this->db->jdate($obj->datev); // Should be in log table + } + $this->db->free($result); + } + else + { + dol_print_error($this->db); + } + } - /** - * Renvoi si les lignes de facture sont ventilees et/ou exportees en compta - * - * @return int <0 if KO, 0=no, 1=yes - */ - function getVentilExportCompta() - { - // On verifie si les lignes de factures ont ete exportees en compta et/ou ventilees - $ventilExportCompta = 0 ; - $num=count($this->lines); - for ($i = 0; $i < $num; $i++) - { - if ($this->lines[$i]->export_compta <> 0 && $this->lines[$i]->code_ventilation <> 0) - { - $ventilExportCompta++; - } - } + /** + * Renvoi si les lignes de facture sont ventilees et/ou exportees en compta + * + * @return int <0 if KO, 0=no, 1=yes + */ + function getVentilExportCompta() + { + // On verifie si les lignes de factures ont ete exportees en compta et/ou ventilees + $ventilExportCompta = 0 ; + $num=count($this->lines); + for ($i = 0; $i < $num; $i++) + { + if ($this->lines[$i]->export_compta <> 0 && $this->lines[$i]->code_ventilation <> 0) + { + $ventilExportCompta++; + } + } - if ($ventilExportCompta <> 0) - { - return 1; - } - else - { - return 0; - } - } + if ($ventilExportCompta <> 0) + { + return 1; + } + else + { + return 0; + } + } - /** - * Return if an invoice can be deleted - * Rule is: - * If hidden option INVOICE_CAN_ALWAYS_BE_REMOVED is on, we can - * If invoice has a definitive ref, is last, without payment and not dipatched into accountancy -> yes end of rule - * If invoice is draft and ha a temporary ref -> yes - * - * @return int <0 if KO, 0=no, 1=yes - */ - function is_erasable() - { - global $conf; + /** + * Return if an invoice can be deleted + * Rule is: + * If hidden option INVOICE_CAN_ALWAYS_BE_REMOVED is on, we can + * If invoice has a definitive ref, is last, without payment and not dipatched into accountancy -> yes end of rule + * If invoice is draft and ha a temporary ref -> yes + * + * @return int <0 if KO, 0=no, 1=yes + */ + function is_erasable() + { + global $conf; - if (! empty($conf->global->INVOICE_CAN_ALWAYS_BE_REMOVED)) return 1; - if (! empty($conf->global->INVOICE_CAN_NEVER_BE_REMOVED)) return 0; + if (! empty($conf->global->INVOICE_CAN_ALWAYS_BE_REMOVED)) return 1; + if (! empty($conf->global->INVOICE_CAN_NEVER_BE_REMOVED)) return 0; - // on verifie si la facture est en numerotation provisoire - $facref = substr($this->ref, 1, 4); + // on verifie si la facture est en numerotation provisoire + $facref = substr($this->ref, 1, 4); - // If not a draft invoice and not temporary invoice - if ($facref != 'PROV') - { - $maxfacnumber = $this->getNextNumRef($this->client,'last'); - $ventilExportCompta = $this->getVentilExportCompta(); - // If there is no invoice into the reset range and not already dispatched, we can delete - if ($maxfacnumber == '' && $ventilExportCompta == 0) return 1; - // If invoice to delete is last one and not already dispatched, we can delete - if ($maxfacnumber == $this->ref && $ventilExportCompta == 0) return 1; - } - else if ($this->statut == 0 && $facref == 'PROV') // Si facture brouillon et provisoire - { - return 1; - } + // If not a draft invoice and not temporary invoice + if ($facref != 'PROV') + { + $maxfacnumber = $this->getNextNumRef($this->client,'last'); + $ventilExportCompta = $this->getVentilExportCompta(); + // If there is no invoice into the reset range and not already dispatched, we can delete + if ($maxfacnumber == '' && $ventilExportCompta == 0) return 1; + // If invoice to delete is last one and not already dispatched, we can delete + if ($maxfacnumber == $this->ref && $ventilExportCompta == 0) return 1; + } + else if ($this->statut == 0 && $facref == 'PROV') // Si facture brouillon et provisoire + { + return 1; + } - return 0; - } + return 0; + } - /** - * Renvoi liste des factures remplacables - * Statut validee ou abandonnee pour raison autre + non payee + aucun paiement + pas deja remplacee - * - * @param int $socid Id societe - * @return array Tableau des factures ('id'=>id, 'ref'=>ref, 'status'=>status, 'paymentornot'=>0/1) - */ - function list_replacable_invoices($socid=0) - { - global $conf; + /** + * Renvoi liste des factures remplacables + * Statut validee ou abandonnee pour raison autre + non payee + aucun paiement + pas deja remplacee + * + * @param int $socid Id societe + * @return array Tableau des factures ('id'=>id, 'ref'=>ref, 'status'=>status, 'paymentornot'=>0/1) + */ + function list_replacable_invoices($socid=0) + { + global $conf; - $return = array(); + $return = array(); - $sql = "SELECT f.rowid as rowid, f.facnumber, f.fk_statut,"; - $sql.= " ff.rowid as rowidnext"; - $sql.= " FROM ".MAIN_DB_PREFIX."facture as f"; - $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."paiement_facture as pf ON f.rowid = pf.fk_facture"; - $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."facture as ff ON f.rowid = ff.fk_facture_source"; - $sql.= " WHERE (f.fk_statut = 1 OR (f.fk_statut = 3 AND f.close_code = 'abandon'))"; - $sql.= " AND f.entity = ".$conf->entity; - $sql.= " AND f.paye = 0"; // Pas classee payee completement - $sql.= " AND pf.fk_paiement IS NULL"; // Aucun paiement deja fait - $sql.= " AND ff.fk_statut IS NULL"; // Renvoi vrai si pas facture de remplacement - if ($socid > 0) $sql.=" AND f.fk_soc = ".$socid; - $sql.= " ORDER BY f.facnumber"; + $sql = "SELECT f.rowid as rowid, f.facnumber, f.fk_statut,"; + $sql.= " ff.rowid as rowidnext"; + $sql.= " FROM ".MAIN_DB_PREFIX."facture as f"; + $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."paiement_facture as pf ON f.rowid = pf.fk_facture"; + $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."facture as ff ON f.rowid = ff.fk_facture_source"; + $sql.= " WHERE (f.fk_statut = 1 OR (f.fk_statut = 3 AND f.close_code = 'abandon'))"; + $sql.= " AND f.entity = ".$conf->entity; + $sql.= " AND f.paye = 0"; // Pas classee payee completement + $sql.= " AND pf.fk_paiement IS NULL"; // Aucun paiement deja fait + $sql.= " AND ff.fk_statut IS NULL"; // Renvoi vrai si pas facture de remplacement + if ($socid > 0) $sql.=" AND f.fk_soc = ".$socid; + $sql.= " ORDER BY f.facnumber"; - dol_syslog(get_class($this)."::list_replacable_invoices sql=$sql"); - $resql=$this->db->query($sql); - if ($resql) - { - while ($obj=$this->db->fetch_object($resql)) - { - $return[$obj->rowid]=array( 'id' => $obj->rowid, + dol_syslog(get_class($this)."::list_replacable_invoices sql=$sql"); + $resql=$this->db->query($sql); + if ($resql) + { + while ($obj=$this->db->fetch_object($resql)) + { + $return[$obj->rowid]=array( 'id' => $obj->rowid, 'ref' => $obj->facnumber, 'status' => $obj->fk_statut); - } - //print_r($return); - return $return; - } - else - { - $this->error=$this->db->error(); - dol_syslog(get_class($this)."::list_replacable_invoices ".$this->error, LOG_ERR); - return -1; - } - } + } + //print_r($return); + return $return; + } + else + { + $this->error=$this->db->error(); + dol_syslog(get_class($this)."::list_replacable_invoices ".$this->error, LOG_ERR); + return -1; + } + } - /** - * Renvoi liste des factures qualifiables pour correction par avoir - * Les factures qui respectent les regles suivantes sont retournees: - * (validee + paiement en cours) ou classee (payee completement ou payee partiellement) + pas deja remplacee + pas deja avoir - * - * @param int $socid Id societe - * @return array Tableau des factures ($id => array('ref'=>,'paymentornot'=>,'status'=>,'paye'=>) - */ - function list_qualified_avoir_invoices($socid=0) - { - global $conf; + /** + * Renvoi liste des factures qualifiables pour correction par avoir + * Les factures qui respectent les regles suivantes sont retournees: + * (validee + paiement en cours) ou classee (payee completement ou payee partiellement) + pas deja remplacee + pas deja avoir + * + * @param int $socid Id societe + * @return array Tableau des factures ($id => array('ref'=>,'paymentornot'=>,'status'=>,'paye'=>) + */ + function list_qualified_avoir_invoices($socid=0) + { + global $conf; - $return = array(); + $return = array(); - $sql = "SELECT f.rowid as rowid, f.facnumber, f.fk_statut, f.type, f.paye, pf.fk_paiement"; - $sql.= " FROM ".MAIN_DB_PREFIX."facture as f"; - $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."paiement_facture as pf ON f.rowid = pf.fk_facture"; - $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."facture as ff ON (f.rowid = ff.fk_facture_source AND ff.type=1)"; - $sql.= " WHERE f.entity = ".$conf->entity; - $sql.= " AND f.fk_statut in (1,2)"; - // $sql.= " WHERE f.fk_statut >= 1"; - // $sql.= " AND (f.paye = 1"; // Classee payee completement - // $sql.= " OR f.close_code IS NOT NULL)"; // Classee payee partiellement - $sql.= " AND ff.type IS NULL"; // Renvoi vrai si pas facture de remplacement - $sql.= " AND f.type != 2"; // Type non 2 si facture non avoir - if ($socid > 0) $sql.=" AND f.fk_soc = ".$socid; - $sql.= " ORDER BY f.facnumber"; + $sql = "SELECT f.rowid as rowid, f.facnumber, f.fk_statut, f.type, f.paye, pf.fk_paiement"; + $sql.= " FROM ".MAIN_DB_PREFIX."facture as f"; + $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."paiement_facture as pf ON f.rowid = pf.fk_facture"; + $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."facture as ff ON (f.rowid = ff.fk_facture_source AND ff.type=1)"; + $sql.= " WHERE f.entity = ".$conf->entity; + $sql.= " AND f.fk_statut in (1,2)"; + // $sql.= " WHERE f.fk_statut >= 1"; + // $sql.= " AND (f.paye = 1"; // Classee payee completement + // $sql.= " OR f.close_code IS NOT NULL)"; // Classee payee partiellement + $sql.= " AND ff.type IS NULL"; // Renvoi vrai si pas facture de remplacement + $sql.= " AND f.type != 2"; // Type non 2 si facture non avoir + if ($socid > 0) $sql.=" AND f.fk_soc = ".$socid; + $sql.= " ORDER BY f.facnumber"; - dol_syslog(get_class($this)."::list_qualified_avoir_invoices sql=".$sql); - $resql=$this->db->query($sql); - if ($resql) - { - while ($obj=$this->db->fetch_object($resql)) - { - $qualified=0; - if ($obj->fk_statut == 1) $qualified=1; - if ($obj->fk_statut == 2) $qualified=1; - if ($qualified) - { - //$ref=$obj->facnumber; - $paymentornot=($obj->fk_paiement?1:0); - $return[$obj->rowid]=array('ref'=>$obj->facnumber,'status'=>$obj->fk_statut,'type'=>$obj->type,'paye'=>$obj->paye,'paymentornot'=>$paymentornot); - } - } + dol_syslog(get_class($this)."::list_qualified_avoir_invoices sql=".$sql); + $resql=$this->db->query($sql); + if ($resql) + { + while ($obj=$this->db->fetch_object($resql)) + { + $qualified=0; + if ($obj->fk_statut == 1) $qualified=1; + if ($obj->fk_statut == 2) $qualified=1; + if ($qualified) + { + //$ref=$obj->facnumber; + $paymentornot=($obj->fk_paiement?1:0); + $return[$obj->rowid]=array('ref'=>$obj->facnumber,'status'=>$obj->fk_statut,'type'=>$obj->type,'paye'=>$obj->paye,'paymentornot'=>$paymentornot); + } + } - return $return; - } - else - { - $this->error=$this->db->error(); - dol_syslog(get_class($this)."::list_avoir_invoices ".$this->error, LOG_ERR); - return -1; - } - } + return $return; + } + else + { + $this->error=$this->db->error(); + dol_syslog(get_class($this)."::list_avoir_invoices ".$this->error, LOG_ERR); + return -1; + } + } - /** - * Create a withdrawal request for a standing order - * - * @param User $user User asking standing order - * @return int <0 if KO, >0 if OK - */ - function demande_prelevement($user) - { - dol_syslog(get_class($this)."::demande_prelevement", LOG_DEBUG); + /** + * Create a withdrawal request for a standing order + * + * @param User $user User asking standing order + * @return int <0 if KO, >0 if OK + */ + function demande_prelevement($user) + { + dol_syslog(get_class($this)."::demande_prelevement", LOG_DEBUG); - $soc = new Societe($this->db); - $soc->id = $this->socid; - $soc->load_ban(); + $soc = new Societe($this->db); + $soc->id = $this->socid; + $soc->load_ban(); - if ($this->statut > 0 && $this->paye == 0) - { - $sql = 'SELECT count(*)'; - $sql.= ' FROM '.MAIN_DB_PREFIX.'prelevement_facture_demande'; - $sql.= ' WHERE fk_facture = '.$this->id; - $sql.= ' AND traite = 0'; + if ($this->statut > 0 && $this->paye == 0) + { + $sql = 'SELECT count(*)'; + $sql.= ' FROM '.MAIN_DB_PREFIX.'prelevement_facture_demande'; + $sql.= ' WHERE fk_facture = '.$this->id; + $sql.= ' AND traite = 0'; - $resql=$this->db->query($sql); - if ($resql) - { - $row = $this->db->fetch_row($resql); - if ($row[0] == 0) - { - $now=dol_now(); + $resql=$this->db->query($sql); + if ($resql) + { + $row = $this->db->fetch_row($resql); + if ($row[0] == 0) + { + $now=dol_now(); - $sql = 'INSERT INTO '.MAIN_DB_PREFIX.'prelevement_facture_demande'; - $sql .= ' (fk_facture, amount, date_demande, fk_user_demande, code_banque, code_guichet, number, cle_rib)'; - $sql .= ' VALUES ('.$this->id; - $sql .= ",'".price2num($this->total_ttc)."'"; - $sql .= ",".$this->db->idate($now).",".$user->id; - $sql .= ",'".$soc->bank_account->code_banque."'"; - $sql .= ",'".$soc->bank_account->code_guichet."'"; - $sql .= ",'".$soc->bank_account->number."'"; - $sql .= ",'".$soc->bank_account->cle_rib."')"; - if ( $this->db->query($sql)) - { - return 1; - } - else - { - $this->error=$this->db->error(); - dol_syslog(get_class($this).'::demandeprelevement Erreur'); - return -1; - } - } - else - { - $this->error="A request already exists"; - dol_syslog(get_class($this).'::demandeprelevement Impossible de creer une demande, demande deja en cours'); - } - } - else - { - $this->error=$this->db->error(); - dol_syslog(get_class($this).'::demandeprelevement Erreur -2'); - return -2; - } - } - else - { - $this->error="Status of invoice does not allow this"; - dol_syslog(get_class($this)."::demandeprelevement ".$this->error." $this->statut, $this->paye, $this->mode_reglement_id"); - return -3; - } - } + $sql = 'INSERT INTO '.MAIN_DB_PREFIX.'prelevement_facture_demande'; + $sql .= ' (fk_facture, amount, date_demande, fk_user_demande, code_banque, code_guichet, number, cle_rib)'; + $sql .= ' VALUES ('.$this->id; + $sql .= ",'".price2num($this->total_ttc)."'"; + $sql .= ",".$this->db->idate($now).",".$user->id; + $sql .= ",'".$soc->bank_account->code_banque."'"; + $sql .= ",'".$soc->bank_account->code_guichet."'"; + $sql .= ",'".$soc->bank_account->number."'"; + $sql .= ",'".$soc->bank_account->cle_rib."')"; + if ( $this->db->query($sql)) + { + return 1; + } + else + { + $this->error=$this->db->error(); + dol_syslog(get_class($this).'::demandeprelevement Erreur'); + return -1; + } + } + else + { + $this->error="A request already exists"; + dol_syslog(get_class($this).'::demandeprelevement Impossible de creer une demande, demande deja en cours'); + } + } + else + { + $this->error=$this->db->error(); + dol_syslog(get_class($this).'::demandeprelevement Erreur -2'); + return -2; + } + } + else + { + $this->error="Status of invoice does not allow this"; + dol_syslog(get_class($this)."::demandeprelevement ".$this->error." $this->statut, $this->paye, $this->mode_reglement_id"); + return -3; + } + } - /** - * Supprime une demande de prelevement - * - * @param Use $user utilisateur creant la demande - * @param int $did id de la demande a supprimer - * @return int <0 if OK, >0 if KO - */ - function demande_prelevement_delete($user, $did) - { - $sql = 'DELETE FROM '.MAIN_DB_PREFIX.'prelevement_facture_demande'; - $sql .= ' WHERE rowid = '.$did; - $sql .= ' AND traite = 0'; - if ( $this->db->query($sql) ) - { - return 0; - } - else - { - $this->error=$this->db->lasterror(); - dol_syslog(get_class($this).'::demande_prelevement_delete Error '.$this->error); - return -1; - } - } + /** + * Supprime une demande de prelevement + * + * @param Use $user utilisateur creant la demande + * @param int $did id de la demande a supprimer + * @return int <0 if OK, >0 if KO + */ + function demande_prelevement_delete($user, $did) + { + $sql = 'DELETE FROM '.MAIN_DB_PREFIX.'prelevement_facture_demande'; + $sql .= ' WHERE rowid = '.$did; + $sql .= ' AND traite = 0'; + if ( $this->db->query($sql) ) + { + return 0; + } + else + { + $this->error=$this->db->lasterror(); + dol_syslog(get_class($this).'::demande_prelevement_delete Error '.$this->error); + return -1; + } + } - /** - * Load indicators for dashboard (this->nbtodo and this->nbtodolate) - * - * @param User $user Object user - * @return int <0 if KO, >0 if OK - */ - function load_board($user) - { - global $conf, $user; + /** + * Load indicators for dashboard (this->nbtodo and this->nbtodolate) + * + * @param User $user Object user + * @return int <0 if KO, >0 if OK + */ + function load_board($user) + { + global $conf, $user; - $now=dol_now(); + $now=dol_now(); - $this->nbtodo=$this->nbtodolate=0; - $clause = " WHERE"; + $this->nbtodo=$this->nbtodolate=0; + $clause = " WHERE"; - $sql = "SELECT f.rowid, f.date_lim_reglement as datefin"; - $sql.= " FROM ".MAIN_DB_PREFIX."facture as f"; - if (!$user->rights->societe->client->voir && !$user->societe_id) - { - $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."societe_commerciaux as sc ON f.fk_soc = sc.fk_soc"; - $sql.= " WHERE sc.fk_user = " .$user->id; - $clause = " AND"; - } - $sql.= $clause." f.paye=0"; - $sql.= " AND f.entity = ".$conf->entity; - $sql.= " AND f.fk_statut = 1"; - if ($user->societe_id) $sql.= " AND f.fk_soc = ".$user->societe_id; + $sql = "SELECT f.rowid, f.date_lim_reglement as datefin"; + $sql.= " FROM ".MAIN_DB_PREFIX."facture as f"; + if (!$user->rights->societe->client->voir && !$user->societe_id) + { + $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."societe_commerciaux as sc ON f.fk_soc = sc.fk_soc"; + $sql.= " WHERE sc.fk_user = " .$user->id; + $clause = " AND"; + } + $sql.= $clause." f.paye=0"; + $sql.= " AND f.entity = ".$conf->entity; + $sql.= " AND f.fk_statut = 1"; + if ($user->societe_id) $sql.= " AND f.fk_soc = ".$user->societe_id; - $resql=$this->db->query($sql); - if ($resql) - { - while ($obj=$this->db->fetch_object($resql)) - { - $this->nbtodo++; - if ($this->db->jdate($obj->datefin) < ($now - $conf->facture->client->warning_delay)) $this->nbtodolate++; - } - return 1; - } - else - { - dol_print_error($this->db); - $this->error=$this->db->error(); - return -1; - } - } + $resql=$this->db->query($sql); + if ($resql) + { + while ($obj=$this->db->fetch_object($resql)) + { + $this->nbtodo++; + if ($this->db->jdate($obj->datefin) < ($now - $conf->facture->client->warning_delay)) $this->nbtodolate++; + } + return 1; + } + else + { + dol_print_error($this->db); + $this->error=$this->db->error(); + return -1; + } + } - /* gestion des contacts d'une facture */ + /* gestion des contacts d'une facture */ - /** - * Retourne id des contacts clients de facturation - * - * @return array Liste des id contacts facturation - */ - function getIdBillingContact() - { - return $this->getIdContact('external','BILLING'); - } + /** + * Retourne id des contacts clients de facturation + * + * @return array Liste des id contacts facturation + */ + function getIdBillingContact() + { + return $this->getIdContact('external','BILLING'); + } - /** - * Retourne id des contacts clients de livraison - * - * @return array Liste des id contacts livraison - */ - function getIdShippingContact() - { - return $this->getIdContact('external','SHIPPING'); - } + /** + * Retourne id des contacts clients de livraison + * + * @return array Liste des id contacts livraison + */ + function getIdShippingContact() + { + return $this->getIdContact('external','SHIPPING'); + } - /** - * Initialise an instance with random values. - * Used to build previews or test instances. - * id must be 0 if object instance is a specimen. - * - * @param string $option ''=Create a specimen invoice with lines, 'nolines'=No lines - * @return void - */ - function initAsSpecimen($option='') - { - global $user,$langs,$conf; + /** + * Initialise an instance with random values. + * Used to build previews or test instances. + * id must be 0 if object instance is a specimen. + * + * @param string $option ''=Create a specimen invoice with lines, 'nolines'=No lines + * @return void + */ + function initAsSpecimen($option='') + { + global $user,$langs,$conf; - $now=dol_now(); - $arraynow=dol_getdate($now); - $nownotime=dol_mktime(0, 0, 0, $arraynow['mon'], $arraynow['mday'], $arraynow['year']); + $now=dol_now(); + $arraynow=dol_getdate($now); + $nownotime=dol_mktime(0, 0, 0, $arraynow['mon'], $arraynow['mday'], $arraynow['year']); - $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]; - } - } + $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]; + } + } - // Initialize parameters - $this->id=0; - $this->ref = 'SPECIMEN'; - $this->specimen=1; - $this->socid = 1; - $this->date = $nownotime; - $this->date_lim_reglement = $nownotime + 3600 * 24 *30; - $this->cond_reglement_id = 1; - $this->cond_reglement_code = 'RECEP'; - $this->date_lim_reglement=$this->calculate_date_lim_reglement(); - $this->mode_reglement_id = 0; // Not forced to show payment mode CHQ + VIR - $this->mode_reglement_code = ''; // Not forced to show payment mode CHQ + VIR - $this->note_public='This is a comment (public)'; - $this->note_private='This is a comment (private)'; - $this->note='This is a comment (private)'; + // Initialize parameters + $this->id=0; + $this->ref = 'SPECIMEN'; + $this->specimen=1; + $this->socid = 1; + $this->date = $nownotime; + $this->date_lim_reglement = $nownotime + 3600 * 24 *30; + $this->cond_reglement_id = 1; + $this->cond_reglement_code = 'RECEP'; + $this->date_lim_reglement=$this->calculate_date_lim_reglement(); + $this->mode_reglement_id = 0; // Not forced to show payment mode CHQ + VIR + $this->mode_reglement_code = ''; // Not forced to show payment mode CHQ + VIR + $this->note_public='This is a comment (public)'; + $this->note_private='This is a comment (private)'; + $this->note='This is a comment (private)'; - if (empty($option) || $option != 'nolines') - { - // Lines - $nbp = 5; - $xnbp = 0; - while ($xnbp < $nbp) - { - $line=new FactureLigne($this->db); - $line->desc=$langs->trans("Description")." ".$xnbp; - $line->qty=1; - $line->subprice=100; - $line->tva_tx=19.6; - $line->localtax1_tx=0; - $line->localtax2_tx=0; - $line->remise_percent=0; - if ($xnbp == 1) // Qty is negative (product line) - { - $prodid = rand(1, $num_prods); - $line->fk_product=$prodids[$prodid]; - $line->qty=-1; - $line->total_ht=-100; - $line->total_ttc=-119.6; - $line->total_tva=-19.6; - } - else if ($xnbp == 2) // UP is negative (free line) - { - $line->subprice=-100; - $line->total_ht=-100; - $line->total_ttc=-119.6; - $line->total_tva=-19.6; - $line->remise_percent=0; - } - else if ($xnbp == 3) // Discount is 50% (product line) - { - $prodid = rand(1, $num_prods); - $line->fk_product=$prodids[$prodid]; - $line->total_ht=50; - $line->total_ttc=59.8; - $line->total_tva=9.8; - $line->remise_percent=50; - } - else // (product line) - { - $prodid = rand(1, $num_prods); - $line->fk_product=$prodids[$prodid]; - $line->total_ht=100; - $line->total_ttc=119.6; - $line->total_tva=19.6; - $line->remise_percent=00; - } + if (empty($option) || $option != 'nolines') + { + // Lines + $nbp = 5; + $xnbp = 0; + while ($xnbp < $nbp) + { + $line=new FactureLigne($this->db); + $line->desc=$langs->trans("Description")." ".$xnbp; + $line->qty=1; + $line->subprice=100; + $line->tva_tx=19.6; + $line->localtax1_tx=0; + $line->localtax2_tx=0; + $line->remise_percent=0; + if ($xnbp == 1) // Qty is negative (product line) + { + $prodid = rand(1, $num_prods); + $line->fk_product=$prodids[$prodid]; + $line->qty=-1; + $line->total_ht=-100; + $line->total_ttc=-119.6; + $line->total_tva=-19.6; + } + else if ($xnbp == 2) // UP is negative (free line) + { + $line->subprice=-100; + $line->total_ht=-100; + $line->total_ttc=-119.6; + $line->total_tva=-19.6; + $line->remise_percent=0; + } + else if ($xnbp == 3) // Discount is 50% (product line) + { + $prodid = rand(1, $num_prods); + $line->fk_product=$prodids[$prodid]; + $line->total_ht=50; + $line->total_ttc=59.8; + $line->total_tva=9.8; + $line->remise_percent=50; + } + else // (product line) + { + $prodid = rand(1, $num_prods); + $line->fk_product=$prodids[$prodid]; + $line->total_ht=100; + $line->total_ttc=119.6; + $line->total_tva=19.6; + $line->remise_percent=00; + } - $this->lines[$xnbp]=$line; - $xnbp++; + $this->lines[$xnbp]=$line; + $xnbp++; - $this->total_ht += $line->total_ht; - $this->total_tva += $line->total_tva; - $this->total_ttc += $line->total_ttc; - } - $this->revenuestamp = 0; - - // Add a line "offered" - $line=new FactureLigne($this->db); - $line->desc=$langs->trans("Description")." (offered line)"; - $line->qty=1; - $line->subprice=100; - $line->tva_tx=19.6; - $line->localtax1_tx=0; - $line->localtax2_tx=0; - $line->remise_percent=100; - $line->total_ht=0; - $line->total_ttc=0; // 90 * 1.196 - $line->total_tva=0; - $prodid = rand(1, $num_prods); - $line->fk_product=$prodids[$prodid]; + $this->total_ht += $line->total_ht; + $this->total_tva += $line->total_tva; + $this->total_ttc += $line->total_ttc; + } + $this->revenuestamp = 0; - $this->lines[$xnbp]=$line; - $xnbp++; - } - } + // Add a line "offered" + $line=new FactureLigne($this->db); + $line->desc=$langs->trans("Description")." (offered line)"; + $line->qty=1; + $line->subprice=100; + $line->tva_tx=19.6; + $line->localtax1_tx=0; + $line->localtax2_tx=0; + $line->remise_percent=100; + $line->total_ht=0; + $line->total_ttc=0; // 90 * 1.196 + $line->total_tva=0; + $prodid = rand(1, $num_prods); + $line->fk_product=$prodids[$prodid]; - /** - * Load indicators for dashboard (this->nbtodo and this->nbtodolate) - * + $this->lines[$xnbp]=$line; + $xnbp++; + } + } + + /** + * Load indicators for dashboard (this->nbtodo and this->nbtodolate) + * * @return int <0 if KO, >0 if OK - */ - function load_state_board() - { - global $conf, $user; + */ + function load_state_board() + { + global $conf, $user; - $this->nb=array(); + $this->nb=array(); - $clause = "WHERE"; + $clause = "WHERE"; - $sql = "SELECT count(f.rowid) as nb"; - $sql.= " FROM ".MAIN_DB_PREFIX."facture as f"; - $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."societe as s ON f.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." f.entity = ".$conf->entity; + $sql = "SELECT count(f.rowid) as nb"; + $sql.= " FROM ".MAIN_DB_PREFIX."facture as f"; + $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."societe as s ON f.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." f.entity = ".$conf->entity; - $resql=$this->db->query($sql); - if ($resql) - { - while ($obj=$this->db->fetch_object($resql)) - { - $this->nb["invoices"]=$obj->nb; - } - return 1; - } - else - { - dol_print_error($this->db); - $this->error=$this->db->error(); - return -1; - } - } + $resql=$this->db->query($sql); + if ($resql) + { + while ($obj=$this->db->fetch_object($resql)) + { + $this->nb["invoices"]=$obj->nb; + } + return 1; + } + else + { + dol_print_error($this->db); + $this->error=$this->db->error(); + return -1; + } + } - /** - * Create an array of invoice lines - * - * @return int >0 if OK, <0 if KO - */ - function getLinesArray() - { - $sql = 'SELECT l.rowid, l.label as custom_label, l.description, l.fk_product, l.product_type, l.qty, l.tva_tx,'; - $sql.= ' l.fk_remise_except, l.localtax1_tx, l.localtax2_tx,'; - $sql.= ' l.remise_percent, l.subprice, l.info_bits, l.rang, l.special_code, l.fk_parent_line,'; - $sql.= ' l.total_ht, l.total_tva, l.total_ttc, l.fk_product_fournisseur_price as fk_fournprice, l.buy_price_ht as pa_ht,'; - $sql.= ' l.date_start, l.date_end,'; - $sql.= ' p.ref as product_ref, p.fk_product_type, p.label as product_label,'; - $sql.= ' p.description as product_desc'; - $sql.= ' FROM '.MAIN_DB_PREFIX.'facturedet as l'; - $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'product p ON l.fk_product=p.rowid'; - $sql.= ' WHERE l.fk_facture = '.$this->id; - $sql.= ' ORDER BY l.rang ASC, l.rowid'; + /** + * Create an array of invoice lines + * + * @return int >0 if OK, <0 if KO + */ + function getLinesArray() + { + $sql = 'SELECT l.rowid, l.label as custom_label, l.description, l.fk_product, l.product_type, l.qty, l.tva_tx,'; + $sql.= ' l.fk_remise_except, l.localtax1_tx, l.localtax2_tx,'; + $sql.= ' l.remise_percent, l.subprice, l.info_bits, l.rang, l.special_code, l.fk_parent_line,'; + $sql.= ' l.total_ht, l.total_tva, l.total_ttc, l.fk_product_fournisseur_price as fk_fournprice, l.buy_price_ht as pa_ht,'; + $sql.= ' l.date_start, l.date_end,'; + $sql.= ' p.ref as product_ref, p.fk_product_type, p.label as product_label,'; + $sql.= ' p.description as product_desc'; + $sql.= ' FROM '.MAIN_DB_PREFIX.'facturedet as l'; + $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'product p ON l.fk_product=p.rowid'; + $sql.= ' WHERE l.fk_facture = '.$this->id; + $sql.= ' ORDER BY l.rang ASC, l.rowid'; - $resql = $this->db->query($sql); - if ($resql) - { - $num = $this->db->num_rows($resql); - $i = 0; + $resql = $this->db->query($sql); + if ($resql) + { + $num = $this->db->num_rows($resql); + $i = 0; - while ($i < $num) - { - $obj = $this->db->fetch_object($resql); + while ($i < $num) + { + $obj = $this->db->fetch_object($resql); - $this->lines[$i]->id = $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->product_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; - $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_parent_line = $obj->fk_parent_line; - $this->lines[$i]->special_code = $obj->special_code; - $this->lines[$i]->rang = $obj->rang; - $this->lines[$i]->date_start = $this->db->jdate($obj->date_start); - $this->lines[$i]->date_end = $this->db->jdate($obj->date_end); + $this->lines[$i]->id = $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->product_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; + $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_parent_line = $obj->fk_parent_line; + $this->lines[$i]->special_code = $obj->special_code; + $this->lines[$i]->rang = $obj->rang; + $this->lines[$i]->date_start = $this->db->jdate($obj->date_start); + $this->lines[$i]->date_end = $this->db->jdate($obj->date_end); $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]; - $i++; - } - $this->db->free($resql); + $i++; + } + $this->db->free($resql); - return 1; - } - else - { - $this->error=$this->db->error(); - dol_syslog("Error sql=".$sql.", error=".$this->error,LOG_ERR); - return -1; - } - } + return 1; + } + else + { + $this->error=$this->db->error(); + dol_syslog("Error sql=".$sql.", error=".$this->error,LOG_ERR); + return -1; + } + } } @@ -3147,322 +3186,324 @@ class Facture extends CommonInvoice */ class FactureLigne { - var $db; - var $error; + var $db; + var $error; - var $oldline; + var $oldline; - //! From llx_facturedet - var $rowid; - //! Id facture - var $fk_facture; - //! Id parent line - var $fk_parent_line; - var $label; - //! Description ligne - var $desc; - var $fk_product; // Id of predefined product - var $product_type = 0; // Type 0 = product, 1 = Service + //! From llx_facturedet + var $rowid; + //! Id facture + var $fk_facture; + //! Id parent line + var $fk_parent_line; + var $label; + //! Description ligne + var $desc; + var $fk_product; // Id of predefined product + var $product_type = 0; // Type 0 = product, 1 = Service - var $qty; // Quantity (example 2) - var $tva_tx; // Taux tva produit/service (example 19.6) - var $localtax1_tx; // Local tax 1 - var $localtax2_tx; // Local tax 2 - var $subprice; // P.U. HT (example 100) - var $remise_percent; // % de la remise ligne (example 20%) - var $fk_remise_except; // Link to line into llx_remise_except - var $rang = 0; + var $qty; // Quantity (example 2) + var $tva_tx; // Taux tva produit/service (example 19.6) + var $localtax1_tx; // Local tax 1 + var $localtax2_tx; // Local tax 2 + var $subprice; // P.U. HT (example 100) + var $remise_percent; // % de la remise ligne (example 20%) + var $fk_remise_except; // Link to line into llx_remise_except + var $rang = 0; - var $fk_fournprice; - var $pa_ht; - var $marge_tx; - var $marque_tx; + var $fk_fournprice; + var $pa_ht; + var $marge_tx; + var $marque_tx; - var $info_bits = 0; // Liste d'options cumulables: - // Bit 0: 0 si TVA normal - 1 si TVA NPR - // Bit 1: 0 si ligne normal - 1 si bit discount (link to line into llx_remise_except) + var $info_bits = 0; // Liste d'options cumulables: + // Bit 0: 0 si TVA normal - 1 si TVA NPR + // Bit 1: 0 si ligne normal - 1 si bit discount (link to line into llx_remise_except) - var $special_code; // Liste d'options non cumulabels: - // 1: frais de port - // 2: ecotaxe - // 3: ?? + var $special_code; // Liste d'options non cumulabels: + // 1: frais de port + // 2: ecotaxe + // 3: ?? - var $origin; - var $origin_id; + var $origin; + var $origin_id; - //! Total HT de la ligne toute quantite et incluant la remise ligne - var $total_ht; - //! Total TVA de la ligne toute quantite et incluant la remise ligne - var $total_tva; - var $total_localtax1; //Total Local tax 1 de la ligne - var $total_localtax2; //Total Local tax 2 de la ligne - //! Total TTC de la ligne toute quantite et incluant la remise ligne - var $total_ttc; + //! Total HT de la ligne toute quantite et incluant la remise ligne + var $total_ht; + //! Total TVA de la ligne toute quantite et incluant la remise ligne + var $total_tva; + var $total_localtax1; //Total Local tax 1 de la ligne + var $total_localtax2; //Total Local tax 2 de la ligne + //! Total TTC de la ligne toute quantite et incluant la remise ligne + var $total_ttc; - var $fk_code_ventilation = 0; + var $fk_code_ventilation = 0; - var $date_start; - var $date_end; + var $date_start; + var $date_end; - // Ne plus utiliser - //var $price; // P.U. HT apres remise % de ligne (exemple 80) - //var $remise; // Montant calcule de la remise % sur PU HT (exemple 20) + // Ne plus utiliser + //var $price; // P.U. HT apres remise % de ligne (exemple 80) + //var $remise; // Montant calcule de la remise % sur PU HT (exemple 20) - // From llx_product - var $ref; // Product ref (deprecated) - var $product_ref; // Product ref - var $libelle; // Product label (deprecated) - var $product_label; // Product label - var $product_desc; // Description produit + // From llx_product + var $ref; // Product ref (deprecated) + var $product_ref; // Product ref + var $libelle; // Product label (deprecated) + var $product_label; // Product label + var $product_desc; // Description produit - var $skip_update_total; // Skip update price total for special lines + var $skip_update_total; // Skip update price total for special lines - /** - * Constructor - * - * @param DoliDB $db Database handler - */ - function __construct($db) - { - $this->db = $db; - } + /** + * Constructor + * + * @param DoliDB $db Database handler + */ + function __construct($db) + { + $this->db = $db; + } - /** - * Load invoice line from database - * - * @param int $rowid id of invoice line to get - * @return int <0 if KO, >0 if OK - */ - function fetch($rowid) - { - $sql = 'SELECT fd.rowid, fd.fk_facture, fd.fk_parent_line, fd.fk_product, fd.product_type, fd.label as custom_label, fd.description, fd.price, fd.qty, fd.tva_tx,'; - $sql.= ' fd.localtax1_tx, fd. localtax2_tx, fd.remise, fd.remise_percent, fd.fk_remise_except, fd.subprice,'; - $sql.= ' fd.date_start as date_start, fd.date_end as date_end, fd.fk_product_fournisseur_price as fk_fournprice, fd.buy_price_ht as pa_ht,'; - $sql.= ' fd.info_bits, fd.total_ht, fd.total_tva, fd.total_ttc, fd.total_localtax1, fd.total_localtax2, fd.rang,'; - $sql.= ' fd.fk_code_ventilation,'; - $sql.= ' p.ref as product_ref, p.label as product_libelle, p.description as product_desc'; - $sql.= ' FROM '.MAIN_DB_PREFIX.'facturedet as fd'; - $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'product as p ON fd.fk_product = p.rowid'; - $sql.= ' WHERE fd.rowid = '.$rowid; + /** + * Load invoice line from database + * + * @param int $rowid id of invoice line to get + * @return int <0 if KO, >0 if OK + */ + function fetch($rowid) + { + $sql = 'SELECT fd.rowid, fd.fk_facture, fd.fk_parent_line, fd.fk_product, fd.product_type, fd.label as custom_label, fd.description, fd.price, fd.qty, fd.tva_tx,'; + $sql.= ' fd.localtax1_tx, fd. localtax2_tx, fd.remise, fd.remise_percent, fd.fk_remise_except, fd.subprice,'; + $sql.= ' fd.date_start as date_start, fd.date_end as date_end, fd.fk_product_fournisseur_price as fk_fournprice, fd.buy_price_ht as pa_ht,'; + $sql.= ' fd.info_bits, fd.total_ht, fd.total_tva, fd.total_ttc, fd.total_localtax1, fd.total_localtax2, fd.rang,'; + $sql.= ' fd.fk_code_ventilation,'; + $sql.= ' p.ref as product_ref, p.label as product_libelle, p.description as product_desc'; + $sql.= ' FROM '.MAIN_DB_PREFIX.'facturedet as fd'; + $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'product as p ON fd.fk_product = p.rowid'; + $sql.= ' WHERE fd.rowid = '.$rowid; - $result = $this->db->query($sql); - if ($result) - { - $objp = $this->db->fetch_object($result); + $result = $this->db->query($sql); + if ($result) + { + $objp = $this->db->fetch_object($result); - $this->rowid = $objp->rowid; - $this->fk_facture = $objp->fk_facture; - $this->fk_parent_line = $objp->fk_parent_line; - $this->label = $objp->custom_label; - $this->desc = $objp->description; - $this->qty = $objp->qty; - $this->subprice = $objp->subprice; - $this->tva_tx = $objp->tva_tx; - $this->localtax1_tx = $objp->localtax1_tx; - $this->localtax2_tx = $objp->localtax2_tx; - $this->remise_percent = $objp->remise_percent; - $this->fk_remise_except = $objp->fk_remise_except; - $this->fk_product = $objp->fk_product; - $this->product_type = $objp->product_type; - $this->date_start = $this->db->jdate($objp->date_start); - $this->date_end = $this->db->jdate($objp->date_end); - $this->info_bits = $objp->info_bits; - $this->total_ht = $objp->total_ht; - $this->total_tva = $objp->total_tva; - $this->total_localtax1 = $objp->total_localtax1; - $this->total_localtax2 = $objp->total_localtax2; - $this->total_ttc = $objp->total_ttc; - $this->fk_code_ventilation = $objp->fk_code_ventilation; - $this->rang = $objp->rang; + $this->rowid = $objp->rowid; + $this->fk_facture = $objp->fk_facture; + $this->fk_parent_line = $objp->fk_parent_line; + $this->label = $objp->custom_label; + $this->desc = $objp->description; + $this->qty = $objp->qty; + $this->subprice = $objp->subprice; + $this->tva_tx = $objp->tva_tx; + $this->localtax1_tx = $objp->localtax1_tx; + $this->localtax2_tx = $objp->localtax2_tx; + $this->remise_percent = $objp->remise_percent; + $this->fk_remise_except = $objp->fk_remise_except; + $this->fk_product = $objp->fk_product; + $this->product_type = $objp->product_type; + $this->date_start = $this->db->jdate($objp->date_start); + $this->date_end = $this->db->jdate($objp->date_end); + $this->info_bits = $objp->info_bits; + $this->total_ht = $objp->total_ht; + $this->total_tva = $objp->total_tva; + $this->total_localtax1 = $objp->total_localtax1; + $this->total_localtax2 = $objp->total_localtax2; + $this->total_ttc = $objp->total_ttc; + $this->fk_code_ventilation = $objp->fk_code_ventilation; + $this->rang = $objp->rang; $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->ref = $objp->product_ref; // deprecated - $this->product_ref = $objp->product_ref; - $this->libelle = $objp->product_libelle; // deprecated - $this->product_label = $objp->product_libelle; - $this->product_desc = $objp->product_desc; + $this->ref = $objp->product_ref; // deprecated + $this->product_ref = $objp->product_ref; + $this->libelle = $objp->product_libelle; // deprecated + $this->product_label = $objp->product_libelle; + $this->product_desc = $objp->product_desc; - $this->db->free($result); - } - else - { - dol_print_error($this->db); - } - } + $this->db->free($result); + } + else + { + dol_print_error($this->db); + } + } - /** - * Insert line in database - * - * @param int $notrigger 1 no triggers - * @return int <0 if KO, >0 if OK - */ - function insert($notrigger=0) - { - global $langs,$user,$conf; + /** + * Insert line in database + * + * @param int $notrigger 1 no triggers + * @return int <0 if KO, >0 if OK + */ + function insert($notrigger=0) + { + global $langs,$user,$conf; $error=0; - dol_syslog(get_class($this)."::insert rang=".$this->rang, LOG_DEBUG); + dol_syslog(get_class($this)."::insert rang=".$this->rang, LOG_DEBUG); - // Clean parameters - $this->desc=trim($this->desc); - 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->rang)) $this->rang=0; - if (empty($this->remise_percent)) $this->remise_percent=0; - if (empty($this->info_bits)) $this->info_bits=0; - if (empty($this->subprice)) $this->subprice=0; - if (empty($this->special_code)) $this->special_code=0; - if (empty($this->fk_parent_line)) $this->fk_parent_line=0; + // Clean parameters + $this->desc=trim($this->desc); + 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->rang)) $this->rang=0; + if (empty($this->remise_percent)) $this->remise_percent=0; + if (empty($this->info_bits)) $this->info_bits=0; + if (empty($this->subprice)) $this->subprice=0; + if (empty($this->special_code)) $this->special_code=0; + if (empty($this->fk_parent_line)) $this->fk_parent_line=0; - if (empty($this->pa_ht)) $this->pa_ht=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); - } + // 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; + // Check parameters + if ($this->product_type < 0) return -1; - $this->db->begin(); + $this->db->begin(); - // Insertion dans base de la ligne - $sql = 'INSERT INTO '.MAIN_DB_PREFIX.'facturedet'; - $sql.= ' (fk_facture, fk_parent_line, label, description, qty, tva_tx, localtax1_tx, localtax2_tx,'; - $sql.= ' fk_product, product_type, remise_percent, subprice, fk_remise_except,'; - $sql.= ' date_start, date_end, fk_code_ventilation, '; - $sql.= ' rang, special_code, fk_product_fournisseur_price, buy_price_ht,'; - $sql.= ' info_bits, total_ht, total_tva, total_ttc, total_localtax1, total_localtax2)'; - $sql.= " VALUES (".$this->fk_facture.","; - $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.= " ".price2num($this->qty).","; - $sql.= " ".price2num($this->tva_tx).","; - $sql.= " ".price2num($this->localtax1_tx).","; - $sql.= " ".price2num($this->localtax2_tx).","; - $sql.= ' '.(! empty($this->fk_product)?$this->fk_product:"null").','; - $sql.= " ".$this->product_type.","; - $sql.= " ".price2num($this->remise_percent).","; - $sql.= " ".price2num($this->subprice).","; - $sql.= ' '.(! empty($this->fk_remise_except)?$this->fk_remise_except:"null").','; - $sql.= " ".(! empty($this->date_start)?"'".$this->db->idate($this->date_start)."'":"null").","; - $sql.= " ".(! empty($this->date_end)?"'".$this->db->idate($this->date_end)."'":"null").","; - $sql.= ' '.$this->fk_code_ventilation.','; - $sql.= ' '.$this->rang.','; - $sql.= ' '.$this->special_code.','; - $sql.= ' '.(! empty($this->fk_fournprice)?$this->fk_fournprice:"null").','; - $sql.= ' '.price2num($this->pa_ht).','; - $sql.= " '".$this->info_bits."',"; - $sql.= " ".price2num($this->total_ht).","; + // Insertion dans base de la ligne + $sql = 'INSERT INTO '.MAIN_DB_PREFIX.'facturedet'; + $sql.= ' (fk_facture, fk_parent_line, label, description, qty, tva_tx, localtax1_tx, localtax2_tx,'; + $sql.= ' fk_product, product_type, remise_percent, subprice, fk_remise_except,'; + $sql.= ' date_start, date_end, fk_code_ventilation, '; + $sql.= ' rang, special_code, fk_product_fournisseur_price, buy_price_ht,'; + $sql.= ' info_bits, total_ht, total_tva, total_ttc, total_localtax1, total_localtax2)'; + $sql.= " VALUES (".$this->fk_facture.","; + $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.= " ".price2num($this->qty).","; + $sql.= " ".price2num($this->tva_tx).","; + $sql.= " ".price2num($this->localtax1_tx).","; + $sql.= " ".price2num($this->localtax2_tx).","; + $sql.= ' '.(! empty($this->fk_product)?$this->fk_product:"null").','; + $sql.= " ".$this->product_type.","; + $sql.= " ".price2num($this->remise_percent).","; + $sql.= " ".price2num($this->subprice).","; + $sql.= ' '.(! empty($this->fk_remise_except)?$this->fk_remise_except:"null").','; + $sql.= " ".(! empty($this->date_start)?"'".$this->db->idate($this->date_start)."'":"null").","; + $sql.= " ".(! empty($this->date_end)?"'".$this->db->idate($this->date_end)."'":"null").","; + $sql.= ' '.$this->fk_code_ventilation.','; + $sql.= ' '.$this->rang.','; + $sql.= ' '.$this->special_code.','; + $sql.= ' '.(! empty($this->fk_fournprice)?$this->fk_fournprice:"null").','; + $sql.= ' '.price2num($this->pa_ht).','; + $sql.= " '".$this->info_bits."',"; + $sql.= " ".price2num($this->total_ht).","; $sql.= " ".price2num($this->total_tva).","; $sql.= " ".price2num($this->total_ttc).","; - $sql.= " ".price2num($this->total_localtax1).","; - $sql.= " ".price2num($this->total_localtax2); - $sql.= ')'; + $sql.= " ".price2num($this->total_localtax1).","; + $sql.= " ".price2num($this->total_localtax2); + $sql.= ')'; - dol_syslog(get_class($this)."::insert sql=".$sql); - $resql=$this->db->query($sql); - if ($resql) - { - $this->rowid=$this->db->last_insert_id(MAIN_DB_PREFIX.'facturedet'); + dol_syslog(get_class($this)."::insert sql=".$sql); + $resql=$this->db->query($sql); + if ($resql) + { + $this->rowid=$this->db->last_insert_id(MAIN_DB_PREFIX.'facturedet'); - // Si fk_remise_except defini, on lie la remise a la facture - // ce qui la flague comme "consommee". - if ($this->fk_remise_except) - { - $discount=new DiscountAbsolute($this->db); - $result=$discount->fetch($this->fk_remise_except); - if ($result >= 0) - { - // Check if discount was found - if ($result > 0) - { - // Check if discount not already affected to another invoice - if ($discount->fk_facture) - { - $this->error=$langs->trans("ErrorDiscountAlreadyUsed",$discount->id); - dol_syslog(get_class($this)."::insert Error ".$this->error, LOG_ERR); - $this->db->rollback(); - return -3; - } - else - { - $result=$discount->link_to_invoice($this->rowid,0); - if ($result < 0) - { - $this->error=$discount->error; - dol_syslog(get_class($this)."::insert Error ".$this->error, LOG_ERR); - $this->db->rollback(); - return -3; - } - } - } - else - { - $this->error=$langs->trans("ErrorADiscountThatHasBeenRemovedIsIncluded"); - dol_syslog(get_class($this)."::insert Error ".$this->error, LOG_ERR); - $this->db->rollback(); - return -3; - } - } - else - { - $this->error=$discount->error; - dol_syslog(get_class($this)."::insert Error ".$this->error, LOG_ERR); - $this->db->rollback(); - return -3; - } - } + // Si fk_remise_except defini, on lie la remise a la facture + // ce qui la flague comme "consommee". + if ($this->fk_remise_except) + { + $discount=new DiscountAbsolute($this->db); + $result=$discount->fetch($this->fk_remise_except); + if ($result >= 0) + { + // Check if discount was found + if ($result > 0) + { + // Check if discount not already affected to another invoice + if ($discount->fk_facture) + { + $this->error=$langs->trans("ErrorDiscountAlreadyUsed",$discount->id); + dol_syslog(get_class($this)."::insert Error ".$this->error, LOG_ERR); + $this->db->rollback(); + return -3; + } + else + { + $result=$discount->link_to_invoice($this->rowid,0); + if ($result < 0) + { + $this->error=$discount->error; + dol_syslog(get_class($this)."::insert Error ".$this->error, LOG_ERR); + $this->db->rollback(); + return -3; + } + } + } + else + { + $this->error=$langs->trans("ErrorADiscountThatHasBeenRemovedIsIncluded"); + dol_syslog(get_class($this)."::insert Error ".$this->error, LOG_ERR); + $this->db->rollback(); + return -3; + } + } + else + { + $this->error=$discount->error; + dol_syslog(get_class($this)."::insert Error ".$this->error, LOG_ERR); + $this->db->rollback(); + return -3; + } + } - if (! $notrigger) - { - // Appel des triggers - include_once DOL_DOCUMENT_ROOT . '/core/class/interfaces.class.php'; - $interface=new Interfaces($this->db); - $result = $interface->run_triggers('LINEBILL_INSERT',$this,$user,$langs,$conf); - if ($result < 0) { $error++; $this->errors=$interface->errors; } - // Fin appel triggers - } + if (! $notrigger) + { + // Appel des triggers + include_once DOL_DOCUMENT_ROOT . '/core/class/interfaces.class.php'; + $interface=new Interfaces($this->db); + $result = $interface->run_triggers('LINEBILL_INSERT',$this,$user,$langs,$conf); + if ($result < 0) { + $error++; $this->errors=$interface->errors; + } + // Fin appel triggers + } - $this->db->commit(); - return $this->rowid; + $this->db->commit(); + return $this->rowid; - } - else - { - $this->error=$this->db->error(); - dol_syslog(get_class($this)."::insert Error ".$this->error, LOG_ERR); - $this->db->rollback(); - return -2; - } - } + } + else + { + $this->error=$this->db->error(); + dol_syslog(get_class($this)."::insert Error ".$this->error, LOG_ERR); + $this->db->rollback(); + return -2; + } + } - /** - * Update line into database - * - * @param User $user User object - * @param int $notrigger Disable triggers - * @return int <0 if KO, >0 if OK - */ - function update($user='',$notrigger=0) - { - global $user,$langs,$conf; + /** + * Update line into database + * + * @param User $user User object + * @param int $notrigger Disable triggers + * @return int <0 if KO, >0 if OK + */ + function update($user='',$notrigger=0) + { + global $user,$langs,$conf; $error=0; - // Clean parameters - $this->desc=trim($this->desc); + // Clean parameters + $this->desc=trim($this->desc); 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; @@ -3474,18 +3515,18 @@ class FactureLigne if (empty($this->product_type)) $this->product_type=0; if (empty($this->fk_parent_line)) $this->fk_parent_line=0; - // Check parameters - if ($this->product_type < 0) return -1; + // Check parameters + if ($this->product_type < 0) return -1; - if (empty($this->pa_ht)) $this->pa_ht=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); - } + // 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(); + $this->db->begin(); // Mise a jour ligne en base $sql = "UPDATE ".MAIN_DB_PREFIX."facturedet SET"; @@ -3512,36 +3553,38 @@ class FactureLigne $sql.= ",total_localtax1=".price2num($this->total_localtax1).""; $sql.= ",total_localtax2=".price2num($this->total_localtax2).""; } - $sql.= " , fk_product_fournisseur_price='".$this->fk_fournprice."'"; + $sql.= " , fk_product_fournisseur_price=".(! empty($this->fk_fournprice)?"'".$this->db->escape($this->fk_fournprice)."'":"null"); $sql.= " , buy_price_ht='".price2num($this->pa_ht)."'"; - $sql.= ",fk_parent_line=".($this->fk_parent_line>0?$this->fk_parent_line:"null"); - if (! empty($this->rang)) $sql.= ", rang=".$this->rang; - $sql.= " WHERE rowid = ".$this->rowid; + $sql.= ",fk_parent_line=".($this->fk_parent_line>0?$this->fk_parent_line:"null"); + if (! empty($this->rang)) $sql.= ", rang=".$this->rang; + $sql.= " WHERE rowid = ".$this->rowid; - dol_syslog(get_class($this)."::update sql=".$sql, LOG_DEBUG); - $resql=$this->db->query($sql); - if ($resql) - { - if (! $notrigger) - { - // Appel des triggers - include_once DOL_DOCUMENT_ROOT . '/core/class/interfaces.class.php'; - $interface=new Interfaces($this->db); - $result = $interface->run_triggers('LINEBILL_UPDATE',$this,$user,$langs,$conf); - if ($result < 0) { $error++; $this->errors=$interface->errors; } - // Fin appel triggers - } - $this->db->commit(); - return 1; - } - else - { - $this->error=$this->db->error(); - dol_syslog(get_class($this)."::update Error ".$this->error, LOG_ERR); - $this->db->rollback(); - return -2; - } - } + dol_syslog(get_class($this)."::update sql=".$sql, LOG_DEBUG); + $resql=$this->db->query($sql); + if ($resql) + { + if (! $notrigger) + { + // Appel des triggers + include_once DOL_DOCUMENT_ROOT . '/core/class/interfaces.class.php'; + $interface=new Interfaces($this->db); + $result = $interface->run_triggers('LINEBILL_UPDATE',$this,$user,$langs,$conf); + if ($result < 0) { + $error++; $this->errors=$interface->errors; + } + // Fin appel triggers + } + $this->db->commit(); + return 1; + } + else + { + $this->error=$this->db->error(); + dol_syslog(get_class($this)."::update Error ".$this->error, LOG_ERR); + $this->db->rollback(); + return -2; + } + } /** * Delete line in database @@ -3564,7 +3607,9 @@ class FactureLigne include_once DOL_DOCUMENT_ROOT . '/core/class/interfaces.class.php'; $interface=new Interfaces($this->db); $result = $interface->run_triggers('LINEBILL_DELETE',$this,$user,$langs,$conf); - if ($result < 0) { $error++; $this->errors=$interface->errors; } + if ($result < 0) { + $error++; $this->errors=$interface->errors; + } // Fin appel triggers $this->db->commit(); @@ -3580,45 +3625,45 @@ class FactureLigne } } - /** - * Mise a jour en base des champs total_xxx de ligne de facture - * - * @return int <0 if KO, >0 if OK - */ - function update_total() - { - $this->db->begin(); - dol_syslog(get_class($this)."::update_total", LOG_DEBUG); + /** + * Mise a jour en base des champs total_xxx de ligne de facture + * + * @return int <0 if KO, >0 if OK + */ + function update_total() + { + $this->db->begin(); + dol_syslog(get_class($this)."::update_total", LOG_DEBUG); - // Clean parameters + // Clean parameters if (empty($this->total_localtax1)) $this->total_localtax1=0; if (empty($this->total_localtax2)) $this->total_localtax2=0; - // Mise a jour ligne en base - $sql = "UPDATE ".MAIN_DB_PREFIX."facturedet SET"; - $sql.= " total_ht=".price2num($this->total_ht).""; - $sql.= ",total_tva=".price2num($this->total_tva).""; - $sql.= ",total_localtax1=".price2num($this->total_localtax1).""; - $sql.= ",total_localtax2=".price2num($this->total_localtax2).""; - $sql.= ",total_ttc=".price2num($this->total_ttc).""; - $sql.= " WHERE rowid = ".$this->rowid; + // Mise a jour ligne en base + $sql = "UPDATE ".MAIN_DB_PREFIX."facturedet SET"; + $sql.= " total_ht=".price2num($this->total_ht).""; + $sql.= ",total_tva=".price2num($this->total_tva).""; + $sql.= ",total_localtax1=".price2num($this->total_localtax1).""; + $sql.= ",total_localtax2=".price2num($this->total_localtax2).""; + $sql.= ",total_ttc=".price2num($this->total_ttc).""; + $sql.= " WHERE rowid = ".$this->rowid; - dol_syslog(get_class($this)."::update_total sql=".$sql, LOG_DEBUG); + dol_syslog(get_class($this)."::update_total sql=".$sql, LOG_DEBUG); - $resql=$this->db->query($sql); - if ($resql) - { - $this->db->commit(); - return 1; - } - else - { - $this->error=$this->db->error(); - dol_syslog(get_class($this)."::update_total Error ".$this->error, LOG_ERR); - $this->db->rollback(); - return -2; - } - } + $resql=$this->db->query($sql); + if ($resql) + { + $this->db->commit(); + return 1; + } + else + { + $this->error=$this->db->error(); + dol_syslog(get_class($this)."::update_total Error ".$this->error, LOG_ERR); + $this->db->rollback(); + return -2; + } + } } ?> diff --git a/htdocs/compta/facture/list.php b/htdocs/compta/facture/list.php index 1003dd23700..952fc760af5 100644 --- a/htdocs/compta/facture/list.php +++ b/htdocs/compta/facture/list.php @@ -3,7 +3,7 @@ * Copyright (C) 2004 Eric Seigne * Copyright (C) 2004-2012 Laurent Destailleur * Copyright (C) 2005 Marc Barilley / Ocebo - * Copyright (C) 2005-2012 Regis Houssin + * Copyright (C) 2005-2013 Regis Houssin * Copyright (C) 2006 Andre Cianfarani * Copyright (C) 2010-2012 Juanjo Menent * Copyright (C) 2012 Christophe Battarel @@ -183,11 +183,11 @@ if ($search_societe) } if ($search_montant_ht) { - $sql.= ' AND f.total = \''.$db->escape(trim($search_montant_ht)).'\''; + $sql.= ' AND f.total = \''.$db->escape(price2num(trim($search_montant_ht))).'\''; } if ($search_montant_ttc) { - $sql.= ' AND f.total_ttc = \''.$db->escape(trim($search_montant_ttc)).'\''; + $sql.= ' AND f.total_ttc = \''.$db->escape(price2num(trim($search_montant_ttc))).'\''; } if ($month > 0) { diff --git a/htdocs/compta/journal/purchasesjournal.php b/htdocs/compta/journal/purchasesjournal.php index a37d5c240df..2269c0035b9 100755 --- a/htdocs/compta/journal/purchasesjournal.php +++ b/htdocs/compta/journal/purchasesjournal.php @@ -3,7 +3,8 @@ * Copyright (C) 2007-2010 Jean Heimburger * Copyright (C) 2011 Juanjo Menent * Copyright (C) 2012 Regis Houssin - * Copyright (C) 2011-2012 Alexandre Spangaro + * Copyright (C) 2011-2012 Alexandre spangaro + * Copyright (C) 2013 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 @@ -99,12 +100,9 @@ $sql = "SELECT f.rowid, f.ref_supplier, f.type, f.datef, f.libelle,"; $sql.= " fd.total_ttc, fd.tva_tx, fd.total_ht, fd.tva as total_tva, fd.product_type, fd.localtax1_tx, fd.localtax2_tx, fd.total_localtax1, fd.total_localtax2,"; $sql.= " s.rowid as socid, s.nom as name, s.code_compta_fournisseur,"; $sql.= " p.rowid as pid, p.ref as ref, p.accountancy_code_buy,"; -$sql.= " ct.accountancy_code_buy as account_tva, ct.recuperableonly,"; -$sql.= " ctl1.accountancy_code_buy as account_localtax1, ctl2.accountancy_code_buy as account_localtax2"; +$sql.= " ct.accountancy_code_buy as account_tva, ct.recuperableonly"; $sql.= " FROM ".MAIN_DB_PREFIX."facture_fourn_det fd"; $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."c_tva ct ON fd.tva_tx = ct.taux AND fd.info_bits = ct.recuperableonly AND ct.fk_pays = '".$idpays."'"; -$sql.= " LEFT JOIN ".MAIN_DB_PREFIX."c_tva ctl1 ON fd.localtax1_tx = ctl1.localtax1 AND ctl1.fk_pays = '".$idpays."'"; -$sql.= " LEFT JOIN ".MAIN_DB_PREFIX."c_tva ctl2 ON fd.localtax2_tx = ctl2.localtax2 AND ctl2.fk_pays = '".$idpays."'"; $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."product p ON p.rowid = fd.fk_product"; $sql.= " JOIN ".MAIN_DB_PREFIX."facture_fourn f ON f.rowid = fd.fk_facture_fourn"; $sql.= " JOIN ".MAIN_DB_PREFIX."societe s ON s.rowid = f.fk_soc" ; @@ -145,6 +143,11 @@ if ($result) $compta_localtax1 = (! empty($obj->account_localtax1)?$obj->account_localtax1:$langs->trans("CodeNotDef")); $compta_localtax2 = (! empty($obj->account_localtax2)?$obj->account_localtax2:$langs->trans("CodeNotDef")); + $account_localtax1=getLocalTaxesFromRate($obj->tva_tx, 1, $mysoc); + $compta_localtax1= (! empty($account_localtax1[2])?$account_localtax1[2]:$langs->trans("CodeNotDef")); + $account_localtax2=getLocalTaxesFromRate($obj->tva_tx, 2, $mysoc); + $compta_localtax2= (! empty($account_localtax2[2])?$account_localtax2[2]:$langs->trans("CodeNotDef")); + $tabfac[$obj->rowid]["date"] = $obj->datef; $tabfac[$obj->rowid]["ref"] = $obj->ref_supplier; $tabfac[$obj->rowid]["type"] = $obj->type; @@ -166,7 +169,6 @@ else { /* * Show result array */ -$i = 0; print ""; print ""; ///print ""; @@ -177,96 +179,71 @@ print "\n"; $var=true; -$r=''; $invoicestatic=new FactureFournisseur($db); $companystatic=new Fournisseur($db); foreach ($tabfac as $key => $val) { - $invoicestatic->id=$key; - $invoicestatic->ref=$val["ref"]; - $invoicestatic->type=$val["type"]; + $invoicestatic->id = $key; + $invoicestatic->ref = $val["ref"]; + $invoicestatic->type = $val["type"]; - // product - foreach ($tabht[$key] as $k => $mt) + $companystatic->id = $tabcompany[$key]['id']; + $companystatic->name = $tabcompany[$key]['name']; + + $lines = array( + array( + 'var' => $tabht[$key], + 'label' => $langs->trans('Products'), + ), + array( + 'var' => $tabtva[$key], + 'label' => $langs->trans('VAT') + ), + array( + 'var' => $tablocaltax1[$key], + 'label' => $langs->transcountry('LT1', $mysoc->country_code) + ), + array( + 'var' => $tablocaltax2[$key], + 'label' => $langs->transcountry('LT2', $mysoc->country_code) + ), + array( + 'var' => $tabttc[$key], + 'label' => $langs->trans('ThirdParty').' ('.$companystatic->getNomUrl(0, 'supplier', 16).')', + 'nomtcheck' => true, + 'inv' => true + ) + ); + + foreach ($lines as $line) { - if ($mt) + foreach ($line['var'] as $k => $mt) { - print ""; - //print ""; - print ""; - print ""; - print ""; - print '"; - print '"; - print ""; + if (isset($line['nomtcheck']) || $mt) + { + print ""; + //print ""; + print ""; + print ""; + print ""; + + if (isset($line['inv'])) + { + print '"; + print '"; + } + else + { + print '"; + print '"; + } + + print ""; + } } } - // vat - foreach ($tabtva[$key] as $k => $mt) - { - if ($mt) - { - print ""; - //print ""; - print ""; - print ""; - print ""; - print '"; - print '"; - print ""; - } - } - // localtax1 - foreach ($tablocaltax1[$key] as $k => $mt) - { - if ($mt) - { - print ""; - //print ""; - print ""; - print ""; - print ""; - print ""; - print ""; - print ""; - } - } - // localtax2 - foreach ($tablocaltax2[$key] as $k => $mt) - { - if ($mt) - { - print ""; - //print ""; - print ""; - print ""; - print ""; - print ""; - print ""; - print ""; - } - } - print ""; - // third party - //print ""; - print ""; - print ""; - - foreach ($tabttc[$key] as $k => $mt) - { - $companystatic->id=$tabcompany[$key]['id']; - $companystatic->name=$tabcompany[$key]['name']; - - print ""; - print '"; - print '"; - } - print ""; $var = !$var; } diff --git a/htdocs/compta/journal/sellsjournal.php b/htdocs/compta/journal/sellsjournal.php index ddb12839bf4..859c1ff2ea5 100755 --- a/htdocs/compta/journal/sellsjournal.php +++ b/htdocs/compta/journal/sellsjournal.php @@ -3,8 +3,8 @@ * Copyright (C) 2007-2010 Jean Heimburger * Copyright (C) 2011 Juanjo Menent * Copyright (C) 2012 Regis Houssin - * Copyright (C) 2011-2012 Alexandre Spangaro - * Copyright (C) 2013 Marcos García + * Copyright (C) 2011-2012 Alexandre Spangaro + * Copyright (C) 2013 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 @@ -102,15 +102,12 @@ $sql = "SELECT f.rowid, f.facnumber, f.type, f.datef, f.ref_client,"; $sql.= " fd.product_type, fd.total_ht, fd.total_tva, fd.tva_tx, fd.total_ttc, fd.localtax1_tx, fd.localtax2_tx, fd.total_localtax1, fd.total_localtax2,"; $sql.= " s.rowid as socid, s.nom as name, s.code_compta, s.client,"; $sql.= " p.rowid as pid, p.ref as pref, p.accountancy_code_sell,"; -$sql.= " ct.accountancy_code_sell as account_tva, ct.recuperableonly,"; -$sql.= " ctl1.accountancy_code_sell as account_localtax1, ctl2.accountancy_code_sell as account_localtax2"; +$sql.= " ct.accountancy_code_sell as account_tva, ct.recuperableonly"; $sql.= " FROM ".MAIN_DB_PREFIX."facturedet fd"; $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."product p ON p.rowid = fd.fk_product"; $sql.= " JOIN ".MAIN_DB_PREFIX."facture f ON f.rowid = fd.fk_facture"; $sql.= " JOIN ".MAIN_DB_PREFIX."societe s ON s.rowid = f.fk_soc"; $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."c_tva ct ON fd.tva_tx = ct.taux AND fd.info_bits = ct.recuperableonly AND ct.fk_pays = '".$idpays."'"; -$sql.= " LEFT JOIN ".MAIN_DB_PREFIX."c_tva ctl1 ON fd.localtax1_tx = ctl1.localtax1 AND ctl1.fk_pays = '".$idpays."'"; -$sql.= " LEFT JOIN ".MAIN_DB_PREFIX."c_tva ctl2 ON fd.localtax2_tx = ctl2.localtax2 AND ctl2.fk_pays = '".$idpays."'"; $sql.= " WHERE f.entity = ".$conf->entity; $sql.= " AND f.fk_statut > 0"; if (! empty($conf->global->FACTURE_DEPOSITS_ARE_JUST_PAYMENTS)) $sql.= " AND f.type IN (0,1,2)"; @@ -129,6 +126,8 @@ if ($result) $tablocaltax2 = array(); $tabttc = array(); $tabcompany = array(); + $account_localtax1=0; + $account_localtax2=0; $num = $db->num_rows($result); $i=0; @@ -147,9 +146,12 @@ if ($result) } $cpttva = (! empty($conf->global->COMPTA_VAT_ACCOUNT)?$conf->global->COMPTA_VAT_ACCOUNT:$langs->trans("CodeNotDef")); $compta_tva = (! empty($obj->account_tva)?$obj->account_tva:$cpttva); - $compta_localtax1 = (! empty($obj->account_localtax1)?$obj->account_localtax1:$langs->trans("CodeNotDef")); - $compta_localtax2 = (! empty($obj->account_localtax2)?$obj->account_localtax2:$langs->trans("CodeNotDef")); + $account_localtax1=getLocalTaxesFromRate($obj->tva_tx, 1, $mysoc); + $compta_localtax1= (! empty($account_localtax1[3])?$account_localtax1[3]:$langs->trans("CodeNotDef")); + $account_localtax2=getLocalTaxesFromRate($obj->tva_tx, 2, $mysoc); + $compta_localtax2= (! empty($account_localtax2[3])?$account_localtax2[3]:$langs->trans("CodeNotDef")); + //la ligne facture $tabfac[$obj->rowid]["date"] = $obj->datef; $tabfac[$obj->rowid]["ref"] = $obj->facnumber; @@ -178,17 +180,15 @@ else { */ -$i = 0; -print "
".$langs->trans("JournalNum")."".$langs->trans("Type")."".$langs->trans("Debi print "
".$conf->global->COMPTA_JOURNAL_BUY."".$val["date"]."".$invoicestatic->getNomUrl(1)."".$k."".$langs->trans("Products")."'.($mt>=0?price($mt):'')."'.($mt<0?price(-$mt):'')."
".$conf->global->COMPTA_JOURNAL_BUY."".$val["date"]."".$invoicestatic->getNomUrl(1)."".$k."".$line['label']."'.($mt<0?price(-$mt):'')."'.($mt>=0?price($mt):'')."'.($mt>=0?price($mt):'')."'.($mt<0?price(-$mt):'')."
".$conf->global->COMPTA_JOURNAL_BUY."".$val["date"]."".$invoicestatic->getNomUrl(1)."".$k."".$langs->trans("VAT")."'.($mt>=0?price($mt):'')."'.($mt<0?price(-$mt):'')."
".$conf->global->COMPTA_JOURNAL_BUY."".$val["date"]."".$invoicestatic->getNomUrl(1)."".$k."".$langs->transcountrynoentities("LT1",$mysoc->country_code)."".($mt>=0?price($mt):'')."".($mt<0?price(-$mt):'')."
".$conf->global->COMPTA_JOURNAL_BUY."".$val["date"]."".$invoicestatic->getNomUrl(1)."".$k."".$langs->transcountrynoentities("LT2",$mysoc->country_code)."".($mt>=0?price($mt):'')."".($mt<0?price(-$mt):'')."
".$conf->global->COMPTA_JOURNAL_BUY."".$val["date"]."".$invoicestatic->getNomUrl(1)."".$k; - print "".$langs->trans("ThirdParty"); - print ' ('.$companystatic->getNomUrl(0,'supplier',16).')'; - print "'.($mt<0?price(-$mt):'')."'.($mt>=0?price($mt):'')."
"; -print ""; +print '
'; +print ''; //print ""; -print ""; -print ""; -print ""; +print ''; +print ''; +print ''; print "\n"; $var=true; -$r=''; $invoicestatic=new Facture($db); $companystatic=new Client($db); @@ -199,74 +199,62 @@ foreach ($tabfac as $key => $val) $invoicestatic->ref=$val["ref"]; $invoicestatic->type=$val["type"]; - print ""; - // third party - //print ""; - print ""; - print ""; - foreach ($tabttc[$key] as $k => $mt) + $companystatic->id=$tabcompany[$key]['id']; + $companystatic->name=$tabcompany[$key]['name']; + $companystatic->client=$tabcompany[$key]['client']; + + $lines = array( + array( + 'var' => $tabttc[$key], + 'label' => $langs->trans('ThirdParty').' ('.$companystatic->getNomUrl(0, 'customer', 16).')', + 'nomtcheck' => true, + 'inv' => true + ), + array( + 'var' => $tabht[$key], + 'label' => $langs->trans('Products'), + ), + array( + 'var' => $tabtva[$key], + 'label' => $langs->trans('VAT') + ), + array( + 'var' => $tablocaltax1[$key], + 'label' => $langs->transcountry('LT1', $mysoc->country_code) + ), + array( + 'var' => $tablocaltax2[$key], + 'label' => $langs->transcountry('LT2', $mysoc->country_code) + ) + ); + + foreach ($lines as $line) { - $companystatic->id=$tabcompany[$key]['id']; - $companystatic->name=$tabcompany[$key]['name']; - $companystatic->client=$tabcompany[$key]['client']; - print ""; - } - print ""; - // product - foreach ($tabht[$key] as $k => $mt) - { - if ($mt) + foreach ($line['var'] as $k => $mt) { - print ""; - //print ""; - print ""; - print ""; - print ""; + if (isset($line['nomtcheck']) || $mt) + { + print ""; + //print ""; + print ""; + print ""; + print ""; + + if (isset($line['inv'])) + { + print '"; + print '"; + } + else + { + print '"; + print '"; + } + + print ""; + } } } - // vat - foreach ($tabtva[$key] as $k => $mt) - { - if ($mt) - { - print ""; - //print ""; - print ""; - print ""; - print ""; - } - } - // localtax1 - foreach ($tablocaltax1[$key] as $k => $mt) - { - if ($mt) - { - print ""; - //print ""; - print ""; - print ""; - print ""; - } - } - // localtax2 - foreach ($tablocaltax2[$key] as $k => $mt) - { - if ($mt) - { - print ""; - //print ""; - print ""; - print ""; - print ""; - } - } $var = !$var; } diff --git a/htdocs/compta/paiement.php b/htdocs/compta/paiement.php index 4a8f93a52f6..232126d68e2 100644 --- a/htdocs/compta/paiement.php +++ b/htdocs/compta/paiement.php @@ -286,7 +286,8 @@ if ($action == 'create' || $action == 'confirm_paiement' || $action == 'add_paie $(\'.fieldrequireddyn\').addClass(\'fieldrequired\'); if ($(\'#fieldchqemetteur\').val() == \'\') { - $(\'#fieldchqemetteur\').val(jQuery(\'#thirdpartylabel\').val()); + var emetteur = ('.$facture->type.' == 2) ? \''.dol_escape_htmltag(MAIN_INFO_SOCIETE_NOM).'\' : jQuery(\'#thirdpartylabel\').val(); + $(\'#fieldchqemetteur\').val(emetteur); } } else diff --git a/htdocs/compta/paiement/rapport.php b/htdocs/compta/paiement/rapport.php index 1bb4ad3a9ca..ce4a3b7cb7f 100644 --- a/htdocs/compta/paiement/rapport.php +++ b/htdocs/compta/paiement/rapport.php @@ -154,7 +154,7 @@ if ($year) $var=!$var; $tfile = $dir . '/'.$year.'/'.$file; $relativepath = $year.'/'.$file; - print "".''; + print "".''; print ''; print ''; } diff --git a/htdocs/compta/prelevement/bon.php b/htdocs/compta/prelevement/bon.php index 6448a5b3df5..89b40e095bc 100644 --- a/htdocs/compta/prelevement/bon.php +++ b/htdocs/compta/prelevement/bon.php @@ -63,7 +63,7 @@ if ($id > 0 || ! empty($ref)) $relativepath = 'bon/'.$object->ref; - print ''.$object->ref.''; + print ''.$object->ref.''; print ''; print '
".$langs->trans("JournalNum")."".$langs->trans("Date")."".$langs->trans("Piece").' ('.$langs->trans("InvoiceRef").")".$langs->trans("Account")."".$langs->trans("Type")."".$langs->trans("Debit")."".$langs->trans("Credit")."'.$langs->trans('Date').''.$langs->trans('Piece').' ('.$langs->trans('InvoiceRef').')'.$langs->trans('Account').''.$langs->trans('Type').''.$langs->trans('Debit').''.$langs->trans('Credit').'
".$conf->global->COMPTA_JOURNAL_SELL."".$val["date"]."".$invoicestatic->getNomUrl(1)."".$k; - print "".$langs->trans("ThirdParty"); - print ' ('.$companystatic->getNomUrl(0,'customer',16).')'; - print "".($mt>=0?price($mt):'')."".($mt<0?price(-$mt):'')."
".$conf->global->COMPTA_JOURNAL_SELL."".$val["date"]."".$invoicestatic->getNomUrl(1)."".$k; - print "".$langs->trans("Products")."".($mt<0?price(-$mt):'')."".($mt>=0?price($mt):'')."
".$conf->global->COMPTA_JOURNAL_SELL."".$val["date"]."".$invoicestatic->getNomUrl(1)."".$k."".$line['label']."'.($mt>=0?price($mt):'')."'.($mt<0?price(-$mt):'')."'.($mt<0?price(-$mt):'')."'.($mt>=0?price($mt):'')."
".$conf->global->COMPTA_JOURNAL_SELL."".$val["date"]."".$invoicestatic->getNomUrl(1)."".$k; - print "".$langs->trans("VAT")."".($mt<0?price(-$mt):'')."".($mt>=0?price($mt):'')."
".$conf->global->COMPTA_JOURNAL_SELL."".$val["date"]."".$invoicestatic->getNomUrl(1)."".$k; - print "".$langs->transcountrynoentities("LT1",$mysoc->country_code)."".($mt<0?price(-$mt):'')."".($mt>=0?price($mt):'')."
".$conf->global->COMPTA_JOURNAL_SELL."".$val["date"]."".$invoicestatic->getNomUrl(1)."".$k; - print "".$langs->transcountrynoentities("LT2",$mysoc->country_code)."".($mt<0?price(-$mt):'')."".($mt>=0?price($mt):'')."
'.img_pdf().' '.$file.'
'.img_pdf().' '.$file.''.dol_print_size(dol_filesize($tfile)).''.dol_print_date(dol_filemtime($tfile),"dayhour").'

'; diff --git a/htdocs/compta/prelevement/factures.php b/htdocs/compta/prelevement/factures.php index 5271dbd03b4..ee5558b8ba2 100644 --- a/htdocs/compta/prelevement/factures.php +++ b/htdocs/compta/prelevement/factures.php @@ -94,7 +94,7 @@ if ($prev_id) print '
'; print $langs->trans("WithdrawalFile").''; $relativepath = 'receipts/'.$bon->ref; - print ''.$relativepath.''; + print ''.$relativepath.''; print '
'; dol_fiche_end(); diff --git a/htdocs/compta/prelevement/fiche-rejet.php b/htdocs/compta/prelevement/fiche-rejet.php index 3cc372094a3..335bfbc26c6 100644 --- a/htdocs/compta/prelevement/fiche-rejet.php +++ b/htdocs/compta/prelevement/fiche-rejet.php @@ -93,7 +93,7 @@ if ($prev_id) print '
'; print $langs->trans("WithdrawalFile").''; $relativepath = 'receipts/'.$bon->ref; - print ''.$relativepath.''; + print ''.$relativepath.''; print '
'; dol_fiche_end(); diff --git a/htdocs/compta/prelevement/fiche-stat.php b/htdocs/compta/prelevement/fiche-stat.php index 20e9c09145f..ee03e0d18b2 100644 --- a/htdocs/compta/prelevement/fiche-stat.php +++ b/htdocs/compta/prelevement/fiche-stat.php @@ -92,7 +92,7 @@ if ($prev_id) print '
'; print $langs->trans("WithdrawalFile").''; $relativepath = 'receipts/'.$bon->ref; - print ''.$relativepath.''; + print ''.$relativepath.''; print '
'; dol_fiche_end(); diff --git a/htdocs/compta/prelevement/fiche.php b/htdocs/compta/prelevement/fiche.php index 283f0c24183..fee2f1ecc24 100644 --- a/htdocs/compta/prelevement/fiche.php +++ b/htdocs/compta/prelevement/fiche.php @@ -191,7 +191,7 @@ if ($id > 0) print '
'; print $langs->trans("WithdrawalFile").''; $relativepath = 'receipts/'.$bon->ref; - print ''.$relativepath.''; + print ''.$relativepath.''; print '
'; dol_fiche_end(); diff --git a/htdocs/compta/prelevement/lignes.php b/htdocs/compta/prelevement/lignes.php index 298effa2b15..5e186774abe 100644 --- a/htdocs/compta/prelevement/lignes.php +++ b/htdocs/compta/prelevement/lignes.php @@ -101,7 +101,7 @@ if ($prev_id) print '
'; print $langs->trans("WithdrawalFile").''; $relativepath = 'receipts/'.$bon->ref; - print ''.$relativepath.''; + print ''.$relativepath.''; print '
'; dol_fiche_end(); diff --git a/htdocs/compta/stats/cabyprodserv.php b/htdocs/compta/stats/cabyprodserv.php new file mode 100644 index 00000000000..6adbd4ebf06 --- /dev/null +++ b/htdocs/compta/stats/cabyprodserv.php @@ -0,0 +1,390 @@ + + * + * 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/stats/cabyprodserv.php + * \brief Page reporting TO by Products & Services + */ + +require '../../main.inc.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/report.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/tax.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/core/class/html.formother.class.php'; + +$langs->load("products"); +$langs->load("categories"); +$langs->load("errors"); + +// Security pack (data & check) +$socid = GETPOST('socid','int'); + +if ($user->societe_id > 0) $socid = $user->societe_id; +if (! empty($conf->comptabilite->enabled)) $result=restrictedArea($user,'compta','','','resultat'); +if (! empty($conf->accounting->enabled)) $result=restrictedArea($user,'accounting','','','comptarapport'); + +// Define modecompta ('CREANCES-DETTES' or 'RECETTES-DEPENSES') +$modecompta = $conf->global->COMPTA_MODE; +if (GETPOST("modecompta")) $modecompta=GETPOST("modecompta"); + +$sortorder=isset($_GET["sortorder"])?$_GET["sortorder"]:$_POST["sortorder"]; +$sortfield=isset($_GET["sortfield"])?$_GET["sortfield"]:$_POST["sortfield"]; +if (! $sortorder) $sortorder="asc"; +if (! $sortfield) $sortfield="name"; + +// Category +$selected_cat = (int)GETPOST('search_categ', 'int'); +$subcat = false; +if (GETPOST('subcat', 'alpha') === 'yes') { + $subcat = true; +} + +// Date range +$year=GETPOST("year"); +$month=GETPOST("month"); +$date_startyear = GETPOST("date_startyear"); +$date_startmonth = GETPOST("date_startmonth"); +$date_startday = GETPOST("date_startday"); +$date_endyear = GETPOST("date_endyear"); +$date_endmonth = GETPOST("date_endmonth"); +$date_endday = GETPOST("date_endday"); +if (empty($year)) +{ + $year_current = strftime("%Y",dol_now()); + $month_current = strftime("%m",dol_now()); + $year_start = $year_current; +} else { + $year_current = $year; + $month_current = strftime("%m",dol_now()); + $year_start = $year; +} +$date_start=dol_mktime(0,0,0,$_REQUEST["date_startmonth"],$_REQUEST["date_startday"],$_REQUEST["date_startyear"]); +$date_end=dol_mktime(23,59,59,$_REQUEST["date_endmonth"],$_REQUEST["date_endday"],$_REQUEST["date_endyear"]); +// Quarter +if (empty($date_start) || empty($date_end)) // We define date_start and date_end +{ + $q=GETPOST("q")?GETPOST("q"):0; + if ($q==0) + { + // We define date_start and date_end + $month_start=GETPOST("month")?GETPOST("month"):($conf->global->SOCIETE_FISCAL_MONTH_START?($conf->global->SOCIETE_FISCAL_MONTH_START):1); + $year_end=$year_start; + $month_end=$month_start; + if (! GETPOST("month")) // If month not forced + { + if (! GETPOST('year') && $month_start > $month_current) + { + $year_start--; + $year_end--; + } + $month_end=$month_start-1; + if ($month_end < 1) $month_end=12; + else $year_end++; + } + $date_start=dol_get_first_day($year_start,$month_start,false); $date_end=dol_get_last_day($year_end,$month_end,false); + } + if ($q==1) { $date_start=dol_get_first_day($year_start,1,false); $date_end=dol_get_last_day($year_start,3,false); } + if ($q==2) { $date_start=dol_get_first_day($year_start,4,false); $date_end=dol_get_last_day($year_start,6,false); } + if ($q==3) { $date_start=dol_get_first_day($year_start,7,false); $date_end=dol_get_last_day($year_start,9,false); } + if ($q==4) { $date_start=dol_get_first_day($year_start,10,false); $date_end=dol_get_last_day($year_start,12,false); } +} else { + // TODO We define q +} + +$commonparams=array(); +$commonparams['modecompta']=$modecompta; +$commonparams['sortorder'] = $sortorder; +$commonparams['sortfield'] = $sortfield; + +$headerparams = array(); +$headerparams['date_startyear'] = $date_startyear; +$headerparams['date_startmonth'] = $date_startmonth; +$headerparams['date_startday'] = $date_startday; +$headerparams['date_endyear'] = $date_endyear; +$headerparams['date_endmonth'] = $date_endmonth; +$headerparams['date_endday'] = $date_endday; +$headerparams['q'] = $q; + +$tableparams = array(); +$tableparams['search_categ'] = $selected_cat; +$tableparams['subcat'] = ($subcat === true)?'yes':''; + +// Adding common parameters +$allparams = array_merge($commonparams, $headerparams, $tableparams); +$headerparams = array_merge($commonparams, $headerparams); +$tableparams = array_merge($commonparams, $tableparams); + +foreach($allparams as $key => $value) { + $paramslink .= '&' . $key . '=' . $value; +} +/* + * View + */ +llxHeader(); +$form=new Form($db); +$formother = new FormOther($db); + +// Show report header +$nom=$langs->trans("SalesTurnover").', '.$langs->trans("ByProductsAndServices"); + +if ($modecompta=="CREANCES-DETTES") { + $nom.='
('.$langs->trans("SeeReportInInputOutputMode",'','').')'; + + $period=$form->select_date($date_start,'date_start',0,0,0,'',1,0,1).' - '.$form->select_date($date_end,'date_end',0,0,0,'',1,0,1); + + $description=$langs->trans("RulesCADue"); + if (! empty($conf->global->FACTURE_DEPOSITS_ARE_JUST_PAYMENTS)) { + $description.= $langs->trans("DepositsAreNotIncluded"); + } else { + $description.= $langs->trans("DepositsAreIncluded"); + } + + $builddate=time(); +} else { + $nom.='
('.$langs->trans("SeeReportInDueDebtMode",'','').')'; + + $period=$form->select_date($date_start,'date_start',0,0,0,'',1,0,1).' - '.$form->select_date($date_end,'date_end',0,0,0,'',1,0,1); + + $description=$langs->trans("RulesCAIn"); + $description.= $langs->trans("DepositsAreIncluded"); + + $builddate=time(); +} + +report_header($nom,$nomlink,$period,$periodlink,$description,$builddate,$exportlink,$tableparams); + + +// SQL request +$catotal=0; + +if ($modecompta == 'CREANCES-DETTES') { + $sql = "SELECT DISTINCT p.rowid as rowid, p.ref as ref, p.label as label,"; + $sql.= " sum(DISTINCT l.total_ht) as amount, sum(DISTINCT l.total_ttc) as amount_ttc"; + $sql.= " FROM ".MAIN_DB_PREFIX."product as p"; + $sql.= " JOIN ".MAIN_DB_PREFIX."facturedet as l"; + $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."facture as f ON l.fk_facture = f.rowid"; + if ($selected_cat === -2) { + $sql.=" LEFT OUTER JOIN ".MAIN_DB_PREFIX."categorie_product as cp ON p.rowid = cp.fk_product"; + } + if ($selected_cat && $selected_cat !== -2) { + $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."categorie as c ON c.rowid = " . $selected_cat; + if ($subcat) { + $sql.=" OR c.fk_parent = " . $selected_cat; + } + $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."categorie_product as cp ON cp.fk_categorie = c.rowid"; + } + $sql.= " WHERE l.fk_product = p.rowid"; + $sql.= " AND f.fk_statut in (1,2)"; + if (! empty($conf->global->FACTURE_DEPOSITS_ARE_JUST_PAYMENTS)) { + $sql.= " AND f.type IN (0,1,2)"; + } else { + $sql.= " AND f.type IN (0,1,2,3)"; + } + if ($date_start && $date_end) { + $sql.= " AND f.datef >= '".$db->idate($date_start)."' AND f.datef <= '".$db->idate($date_end)."'"; + } + if ($selected_cat === -2) { + $sql.=" AND cp.fk_product is null"; + } + if ($selected_cat && $selected_cat !== -2) { + $sql.= " AND cp.fk_product = p.rowid"; + } + $sql.= " AND f.entity = ".$conf->entity; + $sql.= " GROUP BY p.rowid "; + $sql.= "ORDER BY p.ref "; + + $result = $db->query($sql); + if ($result) { + $num = $db->num_rows($result); + $i=0; + while ($i < $num) { + $obj = $db->fetch_object($result); + $amount_ht[$obj->rowid] = $obj->amount; + $amount[$obj->rowid] = $obj->amount_ttc; + $name[$obj->rowid] = $obj->ref . ' - ' . $obj->label; + $catotal_ht+=$obj->amount; + $catotal+=$obj->amount_ttc; + $i++; + } + } else { + dol_print_error($db); + } + + // Show Array + $i=0; + print '
'; + // Extra parameters management + foreach($headerparams as $key => $value) + { + print ''; + } + + print ''; + // Category filter + print ''; + print ''; + print ''; + // Array header + print ""; + print_liste_field_titre( + $langs->trans("Product"), + $_SERVER["PHP_SELF"], + "name", + "", + $paramslink, + "", + $sortfield, + $sortorder + ); + print_liste_field_titre( + $langs->trans('AmountHT'), + $_SERVER["PHP_SELF"], + "amount_ht", + "", + $paramslink, + 'align="right"', + $sortfield, + $sortorder + ); + print_liste_field_titre( + $langs->trans("AmountTTC"), + $_SERVER["PHP_SELF"], + "amount_ttc", + "", + $paramslink, + 'align="right"', + $sortfield, + $sortorder + ); + print_liste_field_titre( + $langs->trans("Percentage"), + $_SERVER["PHP_SELF"], + "amount_ttc", + "", + $paramslink, + 'align="right"', + $sortfield, + $sortorder + ); + // TODO: statistics? + print "\n"; + + // Array Data + $var=true; + + if (count($amount)) { + $arrayforsort=$name; + // defining arrayforsort + if ($sortfield == 'nom' && $sortorder == 'asc') { + asort($name); + $arrayforsort=$name; + } + if ($sortfield == 'nom' && $sortorder == 'desc') { + arsort($name); + $arrayforsort=$name; + } + if ($sortfield == 'amount_ht' && $sortorder == 'asc') { + asort($amount_ht); + $arrayforsort=$amount_ht; + } + if ($sortfield == 'amount_ht' && $sortorder == 'desc') { + arsort($amount_ht); + $arrayforsort=$amount_ht; + } + if ($sortfield == 'amount_ttc' && $sortorder == 'asc') { + asort($amount); + $arrayforsort=$amount; + } + if ($sortfield == 'amount_ttc' && $sortorder == 'desc') { + arsort($amount); + $arrayforsort=$amount; + } + foreach($arrayforsort as $key=>$value) { + $var=!$var; + print ""; + + // Third party + $fullname=$name[$key]; + if ($key >= 0) { + $linkname=''.img_object($langs->trans("ShowProduct"),'product').' '.$fullname.''; + } else { + $linkname=$langs->trans("PaymentsNotLinkedToProduct"); + } + + print "\n"; + + // Amount w/o VAT + print ''; + + // Amount with VAT + print ''; + + // Percent; + print ''; + + // TODO: statistics? + + print "\n"; + $i++; + } + + // Total + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + + $db->free($result); + } + print "
'; + print $langs->trans("Category") . ': ' . $formother->select_categories(0, $selected_cat, 'search_categ', true); + print ' '; + print $langs->trans("SubCats") . '? '; + print ''; + print ''; + print '
".$linkname."'; + if ($key > 0) { + print ''; + } else { + print ''; + } + print price($amount_ht[$key]); + print ''; + if ($key > 0) { + print ''; + } else { + print ''; + } + print price($amount[$key]); + print ''; + print ''.($catotal > 0 ? round(100 * $amount[$key] / $catotal, 2).'%' : ' ').'
'.$langs->trans("Total").''.price($catotal_ht).''.price($catotal).' 
"; + print '
'; +} else { + // $modecompta != 'CREANCES-DETTES' + // TODO: better message + print '
' . $langs->trans("WarningNotRelevant") . '
'; +} + +llxFooter(); +$db->close(); +?> diff --git a/htdocs/compta/stats/cabyuser.php b/htdocs/compta/stats/cabyuser.php index 86f16cf3684..82bbff465eb 100644 --- a/htdocs/compta/stats/cabyuser.php +++ b/htdocs/compta/stats/cabyuser.php @@ -2,6 +2,7 @@ /* Copyright (C) 2001-2003 Rodolphe Quiedeville * Copyright (C) 2004-2011 Laurent Destailleur * Copyright (C) 2005-2009 Regis Houssin + * Copyright (C) 2013 Antoine Iauch * * 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 @@ -46,6 +47,12 @@ if (! $sortfield) $sortfield="name"; // Date range $year=GETPOST("year"); $month=GETPOST("month"); +$date_startyear = GETPOST("date_startyear"); +$date_startmonth = GETPOST("date_startmonth"); +$date_startday = GETPOST("date_startday"); +$date_endyear = GETPOST("date_endyear"); +$date_endmonth = GETPOST("date_endmonth"); +$date_endday = GETPOST("date_endday"); if (empty($year)) { $year_current = strftime("%Y",dol_now()); @@ -89,9 +96,34 @@ if (empty($date_start) || empty($date_end)) // We define date_start and date_end else { // TODO We define q - } +$commonparams=array(); +$commonparams['modecompta']=$modecompta; +$commonparams['sortorder'] = $sortorder; +$commonparams['sortfield'] = $sortfield; + +$headerparams = array(); +$headerparams['date_startyear'] = $date_startyear; +$headerparams['date_startmonth'] = $date_startmonth; +$headerparams['date_startday'] = $date_startday; +$headerparams['date_endyear'] = $date_endyear; +$headerparams['date_endmonth'] = $date_endmonth; +$headerparams['date_endday'] = $date_endday; +$headerparams['q'] = $q; + +$tableparams = array(); +$tableparams['search_categ'] = $selected_cat; +$tableparams['subcat'] = ($subcat === true)?'yes':''; + +// Adding common parameters +$allparams = array_merge($commonparams, $headerparams, $tableparams); +$headerparams = array_merge($commonparams, $headerparams); +$tableparams = array_merge($commonparams, $tableparams); + +foreach($allparams as $key => $value) { + $paramslink .= '&' . $key . '=' . $value; +} /* * View @@ -102,9 +134,8 @@ llxHeader(); $form=new Form($db); -// Affiche en-tete du rapport -if ($modecompta=="CREANCES-DETTES") -{ +// Show report header +if ($modecompta=="CREANCES-DETTES") { $nom=$langs->trans("SalesTurnover").', '.$langs->trans("ByUserAuthorOfInvoice"); $nom.='
('.$langs->trans("SeeReportInInputOutputMode",'','').')'; $period=$form->select_date($date_start,'date_start',0,0,0,'',1,0,1).' - '.$form->select_date($date_end,'date_end',0,0,0,'',1,0,1); @@ -114,8 +145,7 @@ if ($modecompta=="CREANCES-DETTES") else $description.= $langs->trans("DepositsAreIncluded"); $builddate=time(); //$exportlink=$langs->trans("NotYetAvailable"); -} -else { +} else { $nom=$langs->trans("SalesTurnover").', '.$langs->trans("ByUserAuthorOfInvoice"); $nom.='
('.$langs->trans("SeeReportInDueDebtMode",'','').')'; $period=$form->select_date($date_start,'date_start',0,0,0,'',1,0,1).' - '.$form->select_date($date_end,'date_end',0,0,0,'',1,0,1); @@ -131,20 +161,29 @@ if (! empty($modecompta)) $moreparam['modecompta']=$modecompta; report_header($nom,$nomlink,$period,$periodlink,$description,$builddate,$exportlink,$moreparam); -// Charge tableau -$catotal=0; -if ($modecompta == 'CREANCES-DETTES') +// Show array +print '
'; +// Extra parameters management +foreach($headerparams as $key => $value) { + print ''; +} + +$catotal=0; +if ($modecompta == 'CREANCES-DETTES') { $sql = "SELECT u.rowid as rowid, u.lastname as name, u.firstname as firstname, sum(f.total) as amount, sum(f.total_ttc) as amount_ttc"; $sql.= " FROM ".MAIN_DB_PREFIX."user as u"; $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."facture as f ON f.fk_user_author = u.rowid"; $sql.= " WHERE f.fk_statut in (1,2)"; - if (! empty($conf->global->FACTURE_DEPOSITS_ARE_JUST_PAYMENTS)) $sql.= " AND f.type IN (0,1,2)"; - else $sql.= " AND f.type IN (0,1,2,3)"; - if ($date_start && $date_end) $sql.= " AND f.datef >= '".$db->idate($date_start)."' AND f.datef <= '".$db->idate($date_end)."'"; -} -else -{ + if (! empty($conf->global->FACTURE_DEPOSITS_ARE_JUST_PAYMENTS)) { + $sql.= " AND f.type IN (0,1,2)"; + } else { + $sql.= " AND f.type IN (0,1,2,3)"; + } + if ($date_start && $date_end) { + $sql.= " AND f.datef >= '".$db->idate($date_start)."' AND f.datef <= '".$db->idate($date_end)."'"; + } +} else { /* * Liste des paiements (les anciens paiements ne sont pas vus par cette requete car, sur les * vieilles versions, ils n'etaient pas lies via paiement_facture. On les ajoute plus loin) @@ -155,7 +194,9 @@ else $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."paiement_facture as pf ON pf.fk_facture = f.rowid"; $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."paiement as p ON p.rowid = pf.fk_paiement"; $sql.= " WHERE 1=1"; - if ($date_start && $date_end) $sql.= " AND p.datep >= '".$db->idate($date_start)."' AND p.datep <= '".$db->idate($date_end)."'"; + if ($date_start && $date_end) { + $sql.= " AND p.datep >= '".$db->idate($date_start)."' AND p.datep <= '".$db->idate($date_end)."'"; + } } $sql.= " AND f.entity = ".$conf->entity; if ($socid) $sql.= " AND f.fk_soc = ".$socid; @@ -163,27 +204,25 @@ $sql .= " GROUP BY u.rowid, u.lastname, u.firstname"; $sql .= " ORDER BY u.rowid"; $result = $db->query($sql); -if ($result) -{ +if ($result) { $num = $db->num_rows($result); $i=0; - while ($i < $num) - { + while ($i < $num) { $obj = $db->fetch_object($result); - $amount[$obj->rowid] = $obj->amount_ttc; - $name[$obj->rowid] = $obj->lastname.' '.$obj->firstname; - $catotal+=$obj->amount_ttc; - $i++; + $amount_ht[$obj->rowid] = $obj->amount; + $amount[$obj->rowid] = $obj->amount_ttc; + $name[$obj->rowid] = $obj->name.' '.$obj->firstname; + $catotal_ht+=$obj->amount; + $catotal+=$obj->amount_ttc; + $i++; } -} -else { +} else { dol_print_error($db); } -// On ajoute les paiements ancienne version, non lies par paiement_facture donc sans user -if ($modecompta != 'CREANCES-DETTES') -{ - $sql = "SELECT -1 as rowidx, '' as lastname, '' as firstname, sum(p.amount) as amount_ttc"; +// Adding old-version payments, non-bound by "paiement_facture" then without User +if ($modecompta != 'CREANCES-DETTES') { + $sql = "SELECT -1 as rowidx, '' as name, '' as firstname, sum(DISTINCT p.amount) as amount_ttc"; $sql.= " FROM ".MAIN_DB_PREFIX."bank as b"; $sql.= ", ".MAIN_DB_PREFIX."bank_account as ba"; $sql.= ", ".MAIN_DB_PREFIX."paiement as p"; @@ -192,42 +231,86 @@ if ($modecompta != 'CREANCES-DETTES') $sql.= " AND p.fk_bank = b.rowid"; $sql.= " AND b.fk_account = ba.rowid"; $sql.= " AND ba.entity = ".$conf->entity; - if ($date_start && $date_end) $sql.= " AND p.datep >= '".$db->idate($date_start)."' AND p.datep <= '".$db->idate($date_end)."'"; + if ($date_start && $date_end) { + $sql.= " AND p.datep >= '".$db->idate($date_start)."' AND p.datep <= '".$db->idate($date_end)."'"; + } $sql.= " GROUP BY rowidx, name, firstname"; $sql.= " ORDER BY rowidx"; $result = $db->query($sql); - if ($result) - { + if ($result) { $num = $db->num_rows($result); $i=0; - while ($i < $num) - { + while ($i < $num) { $obj = $db->fetch_object($result); $amount[$obj->rowidx] = $obj->amount_ttc; - $name[$obj->rowidx] = $obj->lastname.' '.$obj->firstname; + $name[$obj->rowidx] = $obj->name.' '.$obj->firstname; $catotal+=$obj->amount_ttc; $i++; } - } - else { + } else { dol_print_error($db); } } - $i = 0; print ""; print ""; -print_liste_field_titre($langs->trans("User"),$_SERVER["PHP_SELF"],"name","",'&year='.($year).'&modecompta='.$modecompta,"",$sortfield,$sortorder); -print_liste_field_titre($langs->trans("AmountTTC"),$_SERVER["PHP_SELF"],"amount_ttc","",'&year='.($year).'&modecompta='.$modecompta,'align="right"',$sortfield,$sortorder); -print_liste_field_titre($langs->trans("Percentage"),$_SERVER["PHP_SELF"],"amount_ttc","",'&year='.($year).'&modecompta='.$modecompta,'align="right"',$sortfield,$sortorder); -print_liste_field_titre($langs->trans("OtherStatistics"),$_SERVER["PHP_SELF"],"","","",'align="center" width="20%"'); +print_liste_field_titre( + $langs->trans("User"), + $_SERVER["PHP_SELF"], + "name", + "", + $paramslink, + "", + $sortfield, + $sortorder + ); +if ($modecompta == 'CREANCES-DETTES') { + print_liste_field_titre( + $langs->trans('AmountHT'), + $_SERVER["PHP_SELF"], + "amount_ht", + "", + $paramslink, + 'align="right"', + $sortfield, + $sortorder + ); + } else { + print ''; +} +print_liste_field_titre( + $langs->trans("AmountTTC"), + $_SERVER["PHP_SELF"], + "amount_ttc", + "", + $paramslink, + 'align="right"', + $sortfield, + $sortorder + ); +print_liste_field_titre( + $langs->trans("Percentage"), + $_SERVER["PHP_SELF"],"amount_ttc", + "", + $paramslink, + 'align="right"', + $sortfield, + $sortorder + ); +print_liste_field_titre( + $langs->trans("OtherStatistics"), + $_SERVER["PHP_SELF"], + "", + "", + "", + 'align="center" width="20%"' + ); print "\n"; $var=true; -if (count($amount)) -{ +if (count($amount)) { $arrayforsort=$name; // We define arrayforsort @@ -239,6 +322,14 @@ if (count($amount)) arsort($name); $arrayforsort=$name; } + if ($sortfield == 'amount_ht' && $sortorder == 'asc') { + asort($amount_ht); + $arrayforsort=$amount_ht; + } + if ($sortfield == 'amount_ht' && $sortorder == 'desc') { + arsort($amount_ht); + $arrayforsort=$amount_ht; + } if ($sortfield == 'amount_ttc' && $sortorder == 'asc') { asort($amount); $arrayforsort=$amount; @@ -248,8 +339,7 @@ if (count($amount)) $arrayforsort=$amount; } - foreach($arrayforsort as $key => $value) - { + foreach($arrayforsort as $key => $value) { $var=!$var; print ""; @@ -257,23 +347,44 @@ if (count($amount)) $fullname=$name[$key]; if ($key >= 0) { $linkname=''.img_object($langs->trans("ShowUser"),'user').' '.$fullname.''; - } - else { + } else { $linkname=$langs->trans("PaymentsNotLinkedToUser"); } print "\n"; - // Amount + // Amount w/o VAT print ''; + + // Amount with VAT + print ''; @@ -283,17 +394,30 @@ if (count($amount)) // Other stats print ''; - print "\n"; $i++; } // Total - print ''; + print ''; + print ''; + if ($modecompta != 'CREANCES-DETTES') { + print ''; + } else { + print ''; + } + print ''; + print ''; print ''; print ''; diff --git a/htdocs/compta/stats/casoc.php b/htdocs/compta/stats/casoc.php index b658cf636d6..32d527cc779 100644 --- a/htdocs/compta/stats/casoc.php +++ b/htdocs/compta/stats/casoc.php @@ -3,6 +3,7 @@ * Copyright (C) 2004-2011 Laurent Destailleur * Copyright (C) 2005-2009 Regis Houssin * Copyright (C) 2007 Franky Van Liedekerke + * Copyright (C) 2013 Antoine Iauch * * 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 @@ -27,8 +28,10 @@ require '../../main.inc.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/report.lib.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/tax.lib.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/core/class/html.formother.class.php'; $langs->load("companies"); +$langs->load("categories"); // Define modecompta ('CREANCES-DETTES' or 'RECETTES-DEPENSES') $modecompta = $conf->global->COMPTA_MODE; @@ -41,6 +44,13 @@ if (! $sortfield) $sortfield="nom"; $socid = GETPOST('socid','int'); +// Category +$selected_cat = (int)GETPOST('search_categ', 'int'); +$subcat = false; +if (GETPOST('subcat', 'alpha') === 'yes') { + $subcat = true; +} + // Security check if ($user->societe_id > 0) $socid = $user->societe_id; if (! empty($conf->comptabilite->enabled)) $result=restrictedArea($user,'compta','','','resultat'); @@ -49,6 +59,12 @@ if (! empty($conf->accounting->enabled)) $result=restrictedArea($user,'accountin // Date range $year=GETPOST("year"); $month=GETPOST("month"); +$date_startyear = GETPOST("date_startyear"); +$date_startmonth = GETPOST("date_startmonth"); +$date_startday = GETPOST("date_startday"); +$date_endyear = GETPOST("date_endyear"); +$date_endmonth = GETPOST("date_endmonth"); +$date_endday = GETPOST("date_endday"); if (empty($year)) { $year_current = strftime("%Y",dol_now()); @@ -92,10 +108,34 @@ if (empty($date_start) || empty($date_end)) // We define date_start and date_end else { // TODO We define q - } +$commonparams=array(); +$commonparams['modecompta']=$modecompta; +$commonparams['sortorder'] = $sortorder; +$commonparams['sortfield'] = $sortfield; +$headerparams = array(); +$headerparams['date_startyear'] = $date_startyear; +$headerparams['date_startmonth'] = $date_startmonth; +$headerparams['date_startday'] = $date_startday; +$headerparams['date_endyear'] = $date_endyear; +$headerparams['date_endmonth'] = $date_endmonth; +$headerparams['date_endday'] = $date_endday; +$headerparams['q'] = $q; + +$tableparams = array(); +$tableparams['search_categ'] = $selected_cat; +$tableparams['subcat'] = ($subcat === true)?'yes':''; + +// Adding common parameters +$allparams = array_merge($commonparams, $headerparams, $tableparams); +$headerparams = array_merge($commonparams, $headerparams); +$tableparams = array_merge($commonparams, $tableparams); + +foreach($allparams as $key => $value) { + $paramslink .= '&' . $key . '=' . $value; +} /* * View @@ -105,8 +145,9 @@ llxHeader(); $form=new Form($db); $thirdparty_static=new Societe($db); +$formother = new FormOther($db); -// Affiche en-tete de rapport +// Show report header if ($modecompta=="CREANCES-DETTES") { $nom=$langs->trans("SalesTurnover").', '.$langs->trans("ByThirdParties"); @@ -118,8 +159,7 @@ if ($modecompta=="CREANCES-DETTES") else $description.= $langs->trans("DepositsAreIncluded"); $builddate=time(); //$exportlink=$langs->trans("NotYetAvailable"); -} -else { +} else { $nom=$langs->trans("SalesTurnover").', '.$langs->trans("ByThirdParties"); $nom.='
('.$langs->trans("SeeReportInDueDebtMode",'','').')'; $period=$form->select_date($date_start,'date_start',0,0,0,'',1,0,1).' - '.$form->select_date($date_end,'date_end',0,0,0,'',1,0,1); @@ -129,26 +169,44 @@ else { $builddate=time(); //$exportlink=$langs->trans("NotYetAvailable"); } -$moreparam=array(); -if (! empty($modecompta)) $moreparam['modecompta']=$modecompta; -report_header($nom,$nomlink,$period,$periodlink,$description,$builddate,$exportlink,$moreparam); + +report_header($nom,$nomlink,$period,$periodlink,$description,$builddate,$exportlink,$tableparams); -// Charge tableau +// Show Array $catotal=0; -if ($modecompta == 'CREANCES-DETTES') -{ - $sql = "SELECT s.rowid as socid, s.nom as name, sum(f.total) as amount, sum(f.total_ttc) as amount_ttc"; +if ($modecompta == 'CREANCES-DETTES') { + $sql = "SELECT DISTINCT s.rowid as socid, s.nom as name,"; + $sql.= " sum(DISTINCT f.total) as amount, sum(DISTINCT f.total_ttc) as amount_ttc"; $sql.= " FROM ".MAIN_DB_PREFIX."societe as s"; - $sql.= ", ".MAIN_DB_PREFIX."facture as f"; + $sql.= " JOIN ".MAIN_DB_PREFIX."facture as f"; + if ($selected_cat === -2) { + $sql.= " LEFT OUTER JOIN ".MAIN_DB_PREFIX."categorie_societe as cs ON s.rowid = cs.fk_societe"; + } + if ($selected_cat && $selected_cat !== -2) { + $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."categorie as c ON c.rowid = ".$selected_cat; + if (subcat) { + $sql.=" OR c.fk_parent = " . $selected_cat; + } + $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."categorie_societe as cs ON cs.fk_categorie = c.rowid"; + } $sql.= " WHERE f.fk_statut in (1,2)"; - if (! empty($conf->global->FACTURE_DEPOSITS_ARE_JUST_PAYMENTS)) $sql.= " AND f.type IN (0,1,2)"; - else $sql.= " AND f.type IN (0,1,2,3)"; + if (! empty($conf->global->FACTURE_DEPOSITS_ARE_JUST_PAYMENTS)) { + $sql.= " AND f.type IN (0,1,2)"; + } else { + $sql.= " AND f.type IN (0,1,2,3)"; + } $sql.= " AND f.fk_soc = s.rowid"; - if ($date_start && $date_end) $sql.= " AND f.datef >= '".$db->idate($date_start)."' AND f.datef <= '".$db->idate($date_end)."'"; -} -else -{ + if ($date_start && $date_end) { + $sql.= " AND f.datef >= '".$db->idate($date_start)."' AND f.datef <= '".$db->idate($date_end)."'"; + } + if ($selected_cat === -2) { + $sql.=" AND cs.fk_societe is null"; + } + if ($selected_cat && $selected_cat !== -2) { + $sql.= " AND cs.fk_societe = s.rowid"; + } + } else { /* * Liste des paiements (les anciens paiements ne sont pas vus par cette requete car, sur les * vieilles versions, ils n'etaient pas lies via paiement_facture. On les ajoute plus loin) @@ -161,7 +219,9 @@ else $sql .= " WHERE p.rowid = pf.fk_paiement"; $sql.= " AND pf.fk_facture = f.rowid"; $sql.= " AND f.fk_soc = s.rowid"; - if ($date_start && $date_end) $sql.= " AND p.datep >= '".$db->idate($date_start)."' AND p.datep <= '".$db->idate($date_end)."'"; + if ($date_start && $date_end) { + $sql.= " AND p.datep >= '".$db->idate($date_start)."' AND p.datep <= '".$db->idate($date_end)."'"; + } } $sql.= " AND f.entity = ".$conf->entity; if ($socid) $sql.= " AND f.fk_soc = ".$socid; @@ -169,27 +229,26 @@ $sql.= " GROUP BY s.rowid, s.nom"; $sql.= " ORDER BY s.rowid"; $result = $db->query($sql); -if ($result) -{ +if ($result) { $num = $db->num_rows($result); $i=0; - while ($i < $num) - { + while ($i < $num) { $obj = $db->fetch_object($result); - $amount[$obj->socid] += $obj->amount_ttc; - $name[$obj->socid] = $obj->name; - $catotal+=$obj->amount_ttc; - $i++; + $amount_ht[$obj->socid] = $obj->amount; + $amount[$obj->socid] = $obj->amount_ttc; + $name[$obj->socid] = $obj->name.' '.$obj->firstname; + $catotal_ht+=$obj->amount; + $catotal+=$obj->amount_ttc; + $i++; + } -} -else { +} else { dol_print_error($db); } // On ajoute les paiements anciennes version, non lies par paiement_facture -if ($modecompta != 'CREANCES-DETTES') -{ - $sql = "SELECT '0' as socid, 'Autres' as name, sum(p.amount) as amount_ttc"; +if ($modecompta != 'CREANCES-DETTES') { + $sql = "SELECT '0' as socid, 'Autres' as name, sum(DISTINCT p.amount) as amount_ttc"; $sql.= " FROM ".MAIN_DB_PREFIX."bank as b"; $sql.= ", ".MAIN_DB_PREFIX."bank_account as ba"; $sql.= ", ".MAIN_DB_PREFIX."paiement as p"; @@ -203,20 +262,17 @@ if ($modecompta != 'CREANCES-DETTES') $sql.= " ORDER BY name"; $result = $db->query($sql); - if ($result) - { + if ($result) { $num = $db->num_rows($result); $i=0; - while ($i < $num) - { + while ($i < $num) { $obj = $db->fetch_object($result); $amount[$obj->rowid] += $obj->amount_ttc; $name[$obj->rowid] = $obj->name; $catotal+=$obj->amount_ttc; $i++; } - } - else { + } else { dol_print_error($db); } } @@ -224,20 +280,87 @@ if ($modecompta != 'CREANCES-DETTES') // Show array $i = 0; +print ''; +// Extra parameters management +foreach($headerparams as $key => $value) +{ + print ''; +} print "
".$linkname."'; if ($modecompta != 'CREANCES-DETTES') { - if ($key > 0) print ''; - else print ''; + if ($key > 0) { + print ''; + } else { + print ''; + } + } else { + if ($key > 0) { + print ''; + } else { + print ''; + } + print price($amount_ht[$key]); } - else - { - if ($key > 0) print ''; - else print ''; + print ''; + if ($modecompta != 'CREANCES-DETTES') { + if ($key > 0) { + print ''; + } else { + print ''; + } + } else { + if ($key > 0) { + print ''; + } else { + print ''; + } } print price($amount[$key]); print ''; - if (! empty($conf->propal->enabled) && $key>0) print ' '.img_picto($langs->trans("ProposalStats"),"stats").' '; - if (! empty($conf->commande->enabled) && $key>0) print ' '.img_picto($langs->trans("OrderStats"),"stats").' '; - if (! empty($conf->facture->enabled) && $key>0) print ' '.img_picto($langs->trans("InvoiceStats"),"stats").' '; + if (! empty($conf->propal->enabled) && $key>0) { + print ' '.img_picto($langs->trans("ProposalStats"),"stats").' '; + } + if (! empty($conf->commande->enabled) && $key>0) { + print ' '.img_picto($langs->trans("OrderStats"),"stats").' '; + } + if (! empty($conf->facture->enabled) && $key>0) { + print ' '.img_picto($langs->trans("InvoiceStats"),"stats").' '; + } print '
'.$langs->trans("Total").''.price($catotal).' 
'.$langs->trans("Total").''.price($catotal_ht).''.price($catotal).'  
"; -print ""; -print_liste_field_titre($langs->trans("Company"),$_SERVER["PHP_SELF"],"nom","",'&year='.($year).'&modecompta='.$modecompta,"",$sortfield,$sortorder); -print_liste_field_titre($langs->trans("AmountTTC"),$_SERVER["PHP_SELF"],"amount_ttc","",'&year='.($year).'&modecompta='.$modecompta,'align="right"',$sortfield,$sortorder); -print_liste_field_titre($langs->trans("Percentage"),$_SERVER["PHP_SELF"],"amount_ttc","",'&year='.($year).'&modecompta='.$modecompta,'align="right"',$sortfield,$sortorder); -print_liste_field_titre($langs->trans("OtherStatistics"),$_SERVER["PHP_SELF"],"","","",'align="center" width="20%"'); + // Category filter +print ''; +print ''; +print ''; +print ''; + // Array titles +print ""; +print_liste_field_titre( + $langs->trans("Company"), + $_SERVER["PHP_SELF"], + "nom", + "", + $paramslink, + "", + $sortfield,$sortorder + ); +if ($modecompta == 'CREANCES-DETTES') { + print_liste_field_titre( + $langs->trans('AmountHT'), + $_SERVER["PHP_SELF"], + "amount_ht", + "", + $paramslink, + 'align="right"', + $sortfield, + $sortorder + ); + } else { + print ''; +} +print_liste_field_titre( + $langs->trans("AmountTTC"), + $_SERVER["PHP_SELF"], + "amount_ttc", + "", + $paramslink, + 'align="right"', + $sortfield, + $sortorder + ); +print_liste_field_titre( + $langs->trans("Percentage"), + $_SERVER["PHP_SELF"], + "amount_ttc", + "", + $paramslink, + 'align="right"', + $sortfield, + $sortorder + ); +print_liste_field_titre( + $langs->trans("OtherStatistics"), + $_SERVER["PHP_SELF"], + "", + "", + "", + 'align="center" width="20%"' + ); print "\n"; $var=true; -if (count($amount)) -{ +if (count($amount)) { $arrayforsort=$name; - - // On definit tableau arrayforsort + // Defining array arrayforsort if ($sortfield == 'nom' && $sortorder == 'asc') { asort($name); $arrayforsort=$name; @@ -246,6 +369,14 @@ if (count($amount)) arsort($name); $arrayforsort=$name; } + if ($sortfield == 'amount_ht' && $sortorder == 'asc') { + asort($amount_ht); + $arrayforsort=$amount_ht; + } + if ($sortfield == 'amount_ht' && $sortorder == 'desc') { + arsort($amount_ht); + $arrayforsort=$amount_ht; + } if ($sortfield == 'amount_ttc' && $sortorder == 'asc') { asort($amount); $arrayforsort=$amount; @@ -255,8 +386,7 @@ if (count($amount)) $arrayforsort=$amount; } - foreach($arrayforsort as $key=>$value) - { + foreach($arrayforsort as $key=>$value) { $var=!$var; print ""; @@ -267,23 +397,43 @@ if (count($amount)) $thirdparty_static->name=$fullname; $thirdparty_static->client=1; $linkname=$thirdparty_static->getNomUrl(1,'customer'); - } - else { + } else { $linkname=$langs->trans("PaymentsNotLinkedToInvoice"); } print "\n"; - // Amount + // Amount w/o VAT print ''; + + // Amount with VAT + print ''; - - print "\n"; - $i++; + print "\n"; + $i++; } // Total - print ''; + print ''; + print ''; + if ($modecompta != 'CREANCES-DETTES') { + print ''; + } else { + print ''; + } + print ''; + print ''; print ''; print ''; @@ -312,8 +475,7 @@ if (count($amount)) } print "
'; +print $langs->trans("Category") . ': ' . $formother->select_categories(2, $selected_cat, 'search_categ', true); +print ' '; +print $langs->trans("SubCats") . '? '; +print ''; +print ''; +print '
".$linkname."'; - if ($modecompta != 'CREANCES-DETTES') - { - if ($key > 0) print ''; - else print ''; + if ($modecompta != 'CREANCES-DETTES') { + if ($key > 0) { + print ''; + } else { + print ''; + } + } else { + if ($key > 0) { + print ''; + } else { + print ''; + } + print price($amount_ht[$key]); } - else - { - if ($key > 0) print ''; - else print ''; + print ''; + if ($modecompta != 'CREANCES-DETTES') { + if ($key > 0) { + print ''; + } else { + print ''; + } + } else { + if ($key > 0) { + print ''; + } else { + print ''; + } } print price($amount[$key]); print ''; @@ -294,17 +444,30 @@ if (count($amount)) // Other stats print ''; - if (! empty($conf->propal->enabled) && $key>0) print ' '.img_picto($langs->trans("ProposalStats"),"stats").' '; - if (! empty($conf->commande->enabled) && $key>0) print ' '.img_picto($langs->trans("OrderStats"),"stats").' '; - if (! empty($conf->facture->enabled) && $key>0) print ' '.img_picto($langs->trans("InvoiceStats"),"stats").' '; + if (! empty($conf->propal->enabled) && $key>0) { + print ' '.img_picto($langs->trans("ProposalStats"),"stats").' '; + } + if (! empty($conf->commande->enabled) && $key>0) { + print ' '.img_picto($langs->trans("OrderStats"),"stats").' '; + } + if (! empty($conf->facture->enabled) && $key>0) { + print ' '.img_picto($langs->trans("InvoiceStats"),"stats").' '; + } print '
'.$langs->trans("Total").''.price($catotal).' 
'.$langs->trans("Total").''.price($catotal_ht).''.price($catotal).'  
"; -print '
'; - +print '
'; llxFooter(); diff --git a/htdocs/contrat/note.php b/htdocs/contrat/note.php index ee66e4583f7..c8edf493f63 100644 --- a/htdocs/contrat/note.php +++ b/htdocs/contrat/note.php @@ -50,7 +50,7 @@ $object->fetch($id,$ref); if ($action == 'setnote_public' && $user->rights->contrat->creer) { - $result=$object->update_note(dol_html_entity_decode(dol_htmlcleanlastbr(GETPOST('note_public')), ENT_QUOTES),'_pubic'); + $result=$object->update_note(dol_html_entity_decode(dol_htmlcleanlastbr(GETPOST('note_public')), ENT_QUOTES),'_public'); if ($result < 0) dol_print_error($db,$object->error); } diff --git a/htdocs/core/ajax/ajaxdirpreview.php b/htdocs/core/ajax/ajaxdirpreview.php index ef4d976d4d7..2389a681000 100644 --- a/htdocs/core/ajax/ajaxdirpreview.php +++ b/htdocs/core/ajax/ajaxdirpreview.php @@ -4,6 +4,7 @@ * Copyright (C) 2005 Simon Tosser * Copyright (C) 2005-2012 Regis Houssin * Copyright (C) 2010 Pierre Morin + * Copyright (C) 2013 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 @@ -139,8 +140,7 @@ if (! dol_is_dir($upload_dir)) print ''."\n"; print ''."\n"; -$param=''; -$param.=($sortfield?'&sortfield='.$sortfield:'').($sortorder?'&sortorder='.$sortorder:''); +$param=($sortfield?'&sortfield='.$sortfield:'').($sortorder?'&sortorder='.$sortorder:''); $url=DOL_URL_ROOT.'/ecm/index.php'; // Dir scan @@ -149,126 +149,73 @@ if ($type == 'directory') $formfile=new FormFile($db); $maxlengthname=40; + $excludefiles = array('^SPECIMEN\.pdf$','^\.','\.meta$','^temp$','^payments$','^CVS$','^thumbs$'); + $sorting = (strtolower($sortorder)=='desc'?SORT_DESC:SORT_ASC); // Right area. If module is defined, we are in automatic ecm. - if ($module == 'company') // Auto area for suppliers invoices - { - $upload_dir = $conf->societe->dir_output; // TODO change for multicompany sharing - $filearray=dol_dir_list($upload_dir,"files",1,'',array('^SPECIMEN\.pdf$','^\.','\.meta$','^temp$','^payments$','^CVS$','^thumbs$'),$sortfield,(strtolower($sortorder)=='desc'?SORT_DESC:SORT_ASC),1); + $automodules = array('company', 'invoice', 'invoice_supplier', 'propal', 'order', 'order_supplier', 'contract', 'product', 'tax', 'project'); - $param.='&module='.$module; - $textifempty=($section?$langs->trans("NoFileFound"):($showonrightsize=='featurenotyetavailable'?$langs->trans("FeatureNotYetAvailable"):$langs->trans("NoFileFound"))); - - $formfile->list_of_autoecmfiles($upload_dir,$filearray,$module,$param,1,'',$user->rights->ecm->upload,1,$textifempty,$maxlengthname,$url); - } - else if ($module == 'invoice') // Auto area for suppliers invoices - { - $upload_dir = $conf->facture->dir_output; - $filearray=dol_dir_list($upload_dir,"files",1,'',array('^SPECIMEN\.pdf$','^\.','\.meta$','^temp$','^payments$','^CVS$','^thumbs$'),$sortfield,(strtolower($sortorder)=='desc'?SORT_DESC:SORT_ASC),1); - - $param.='&module='.$module; - $textifempty=($section?$langs->trans("NoFileFound"):($showonrightsize=='featurenotyetavailable'?$langs->trans("FeatureNotYetAvailable"):$langs->trans("NoFileFound"))); - - $formfile->list_of_autoecmfiles($upload_dir,$filearray,$module,$param,1,'',$user->rights->ecm->upload,1,$textifempty,$maxlengthname,$url); - } - else if ($module == 'invoice_supplier') // Auto area for suppliers invoices + // TODO change for multicompany sharing + // Auto area for suppliers invoices + if ($module == 'company') $upload_dir = $conf->societe->dir_output; + // Auto area for suppliers invoices + else if ($module == 'invoice') $upload_dir = $conf->facture->dir_output; + // Auto area for suppliers invoices + else if ($module == 'invoice_supplier') { $relativepath='facture'; $upload_dir = $conf->fournisseur->dir_output.'/'.$relativepath; - $filearray=dol_dir_list($upload_dir,"files",1,'',array('^SPECIMEN\.pdf$','^\.','\.meta$','^temp$','^CVS$','^thumbs$'),$sortfield,(strtolower($sortorder)=='desc'?SORT_DESC:SORT_ASC),1); - $param.='&module='.$module; - $textifempty=($section?$langs->trans("NoFileFound"):($showonrightsize=='featurenotyetavailable'?$langs->trans("FeatureNotYetAvailable"):$langs->trans("NoFileFound"))); - $formfile->list_of_autoecmfiles($upload_dir,$filearray,$module,$param,1,'',$user->rights->ecm->upload,1,$textifempty,$maxlengthname,$url); } - else if ($module == 'propal') // Auto area for customers orders - { - $upload_dir = $conf->propal->dir_output; - $filearray=dol_dir_list($upload_dir,"files",1,'',array('^SPECIMEN\.pdf$','^\.','\.meta$','^temp$','^payments$','^CVS$','^thumbs$'),$sortfield,(strtolower($sortorder)=='desc'?SORT_DESC:SORT_ASC),1); - - $param.='&module='.$module; - $textifempty=($section?$langs->trans("NoFileFound"):($showonrightsize=='featurenotyetavailable'?$langs->trans("FeatureNotYetAvailable"):$langs->trans("NoFileFound"))); - - $formfile->list_of_autoecmfiles($upload_dir,$filearray,$module,$param,1,'',$user->rights->ecm->upload,1,$textifempty,$maxlengthname,$url); - } - else if ($module == 'order') // Auto area for customers orders - { - $upload_dir = $conf->commande->dir_output; - $filearray=dol_dir_list($upload_dir,"files",1,'',array('^SPECIMEN\.pdf$','^\.','\.meta$','^temp$','^payments$','^CVS$','^thumbs$'),$sortfield,(strtolower($sortorder)=='desc'?SORT_DESC:SORT_ASC),1); - - $param.='&module='.$module; - $textifempty=($section?$langs->trans("NoFileFound"):($showonrightsize=='featurenotyetavailable'?$langs->trans("FeatureNotYetAvailable"):$langs->trans("NoFileFound"))); - - $formfile->list_of_autoecmfiles($upload_dir,$filearray,$module,$param,1,'',$user->rights->ecm->upload,1,$textifempty,$maxlengthname,$url); - } - else if ($module == 'order_supplier') // Auto area for suppliers orders + // Auto area for customers orders + else if ($module == 'propal') $upload_dir = $conf->propal->dir_output; + // Auto area for customers orders + else if ($module == 'order') $upload_dir = $conf->commande->dir_output; + // Auto area for suppliers orders + else if ($module == 'order_supplier') { $relativepath='commande'; $upload_dir = $conf->fournisseur->dir_output.'/'.$relativepath; - $filearray=dol_dir_list($upload_dir,"files",1,'',array('^SPECIMEN\.pdf$','^\.','\.meta$','^temp$','^payments$','^CVS$','^thumbs$'),$sortfield,(strtolower($sortorder)=='desc'?SORT_DESC:SORT_ASC),1); + } + // Auto area for suppliers invoices + else if ($module == 'contract') $upload_dir = $conf->contrat->dir_output; + // Auto area for products + else if ($module == 'product') $upload_dir = $conf->product->dir_output; + // Auto area for suppliers invoices + else if ($module == 'tax') $upload_dir = $conf->tax->dir_output; + // Auto area for projects + else if ($module == 'project') $upload_dir = $conf->projet->dir_output; + if (in_array($module, $automodules)) + { $param.='&module='.$module; $textifempty=($section?$langs->trans("NoFileFound"):($showonrightsize=='featurenotyetavailable'?$langs->trans("FeatureNotYetAvailable"):$langs->trans("NoFileFound"))); + $filearray=dol_dir_list($upload_dir,"files",1,'', $excludefiles, $sortfield, $sorting,1); $formfile->list_of_autoecmfiles($upload_dir,$filearray,$module,$param,1,'',$user->rights->ecm->upload,1,$textifempty,$maxlengthname,$url); } - else if ($module == 'contract') // Auto area for suppliers invoices - { - $upload_dir = $conf->contrat->dir_output; - $filearray=dol_dir_list($upload_dir,"files",1,'',array('^SPECIMEN\.pdf$','^\.','\.meta$','^temp$','^CVS$','^thumbs$'),$sortfield,(strtolower($sortorder)=='desc'?SORT_DESC:SORT_ASC),1); - - $param.='&module='.$module; - $textifempty=($section?$langs->trans("NoFileFound"):($showonrightsize=='featurenotyetavailable'?$langs->trans("FeatureNotYetAvailable"):$langs->trans("NoFileFound"))); - - $formfile->list_of_autoecmfiles($upload_dir,$filearray,$module,$param,1,'',$user->rights->ecm->upload,1,$textifempty,$maxlengthname,$url); - } - else if ($module == 'product') // Auto area for products - { - $upload_dir = $conf->product->dir_output; - $filearray=dol_dir_list($upload_dir,"files",1,'',array('^SPECIMEN\.pdf$','^\.','\.meta$','^temp$','^CVS$','^thumbs$'),$sortfield,(strtolower($sortorder)=='desc'?SORT_DESC:SORT_ASC),1); - - $param.='&module='.$module; - $textifempty=($section?$langs->trans("NoFileFound"):($showonrightsize=='featurenotyetavailable'?$langs->trans("FeatureNotYetAvailable"):$langs->trans("NoFileFound"))); - - $formfile->list_of_autoecmfiles($upload_dir,$filearray,$module,$param,1,'',$user->rights->ecm->upload,1,$textifempty,$maxlengthname,$url); - } - else if ($module == 'tax') // Auto area for suppliers invoices - { - $upload_dir = $conf->tax->dir_output; - $filearray=dol_dir_list($upload_dir,"files",1,'',array('^SPECIMEN\.pdf$','^\.','\.meta$','^temp$','^CVS$','^thumbs$'),$sortfield,(strtolower($sortorder)=='desc'?SORT_DESC:SORT_ASC),1); - - $param.='&module='.$module; - $textifempty=($section?$langs->trans("NoFileFound"):($showonrightsize=='featurenotyetavailable'?$langs->trans("FeatureNotYetAvailable"):$langs->trans("NoFileFound"))); - - $formfile->list_of_autoecmfiles($upload_dir,$filearray,$module,$param,1,'',$user->rights->ecm->upload,1,$textifempty,$maxlengthname,$url); - } - else if ($module == 'project') // Auto area for projects - { - $upload_dir = $conf->projet->dir_output; - $filearray=dol_dir_list($upload_dir,"files",1,'',array('^SPECIMEN\.pdf$','^\.','\.meta$','^temp$','^CVS$','^thumbs$'),$sortfield,(strtolower($sortorder)=='desc'?SORT_DESC:SORT_ASC),1); - - $param.='&module='.$module; - $textifempty=($section?$langs->trans("NoFileFound"):($showonrightsize=='featurenotyetavailable'?$langs->trans("FeatureNotYetAvailable"):$langs->trans("NoFileFound"))); - - $formfile->list_of_autoecmfiles($upload_dir,$filearray,$module,$param,1,'',$user->rights->ecm->upload,1,$textifempty,$maxlengthname,$url); - } - else // Manual area + //Manual area + else { $relativepath=$ecmdir->getRelativePath(); $upload_dir = $conf->ecm->dir_output.'/'.$relativepath; - $filearray=dol_dir_list($upload_dir,"files",0,'',array('^\.','\.meta$','^temp$','^CVS$'),$sortfield,(strtolower($sortorder)=='desc'?SORT_DESC:SORT_ASC),1); - - if ($section) $param.='§ion='.$section; - $textifempty=($section?$langs->trans("NoFileFound"):($showonrightsize=='featurenotyetavailable'?$langs->trans("FeatureNotYetAvailable"):$langs->trans("ECMSelectASection"))); // If $section defined with value 0 if ($section === '0') { - $filearray=array(); - $textifempty='
'.$langs->trans("DirNotSynchronizedSyncFirst").'

'; + $filearray=array(); + $textifempty='
'.$langs->trans("DirNotSynchronizedSyncFirst").'

'; } + else $filearray=dol_dir_list($upload_dir,"files",0,'',array('^\.','\.meta$','^temp$','^CVS$'),$sortfield, $sorting,1); + + if ($section) + { + $param.='§ion='.$section; + $textifempty = $langs->trans('NoFileFound'); + } + else $textifempty=($showonrightsize=='featurenotyetavailable'?$langs->trans("FeatureNotYetAvailable"):$langs->trans("ECMSelectASection")); + $formfile->list_of_documents($filearray,'','ecm',$param,1,$relativepath,$user->rights->ecm->upload,1,$textifempty,$maxlengthname,'',$url); } - } if (! empty($conf->use_javascript_ajax) && empty($conf->global->MAIN_ECM_DISABLE_JS)) diff --git a/htdocs/core/ajax/ajaxdirtree.php b/htdocs/core/ajax/ajaxdirtree.php index ded1a4a30c4..db8af5ba265 100644 --- a/htdocs/core/ajax/ajaxdirtree.php +++ b/htdocs/core/ajax/ajaxdirtree.php @@ -117,7 +117,7 @@ if (file_exists($fullpathselecteddir)) // Loop on all database entries (sqltree) to find the one matching the subdir found into dir to scan foreach($sqltree as $key => $tmpval) { - //print "-- key=".$key." - ".$val['fullrelativename']." vs ".(($selecteddir != '/'?$selecteddir.'/':'').$file).'
'; + //print "-- key=".$key." - ".$tmpval['fullrelativename']." vs ".(($selecteddir != '/'?$selecteddir.'/':'').$file)."
\n"; if ($tmpval['fullrelativename'] == (($selecteddir != '/'?$selecteddir.'/':'').$file)) // We found equivalent record into database { $val=$tmpval; diff --git a/htdocs/core/boxes/box_produits_alerte_stock.php b/htdocs/core/boxes/box_produits_alerte_stock.php index 41070298cac..57c2cc4de4c 100644 --- a/htdocs/core/boxes/box_produits_alerte_stock.php +++ b/htdocs/core/boxes/box_produits_alerte_stock.php @@ -64,20 +64,23 @@ class box_produits_alerte_stock extends ModeleBoxes if ($user->rights->produit->lire || $user->rights->service->lire) { - $sql = "SELECT p.rowid, p.label, p.price, p.price_base_type, p.price_ttc, p.fk_product_type, p.tms, p.tosell, p.tobuy, p.seuil_stock_alerte, s.reel"; + $sql = "SELECT p.rowid, p.label, p.price, p.price_base_type, p.price_ttc, p.fk_product_type, p.tms, p.tosell, p.tobuy, p.seuil_stock_alerte,"; + $sql.= " SUM(".$db->ifsql("s.reel IS NULL","0","s.reel").") as total_stock"; $sql.= " FROM ".MAIN_DB_PREFIX."product as p"; $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."product_stock as s on p.rowid = s.fk_product"; $sql.= ' WHERE p.entity IN ('.getEntity($productstatic->element, 1).')'; - $sql.= " AND p.tosell = 1"; + $sql.= " AND p.tosell = 1 AND p.seuil_stock_alerte > 0"; if (empty($user->rights->produit->lire)) $sql.=' AND p.fk_product_type != 0'; if (empty($user->rights->service->lire)) $sql.=' AND p.fk_product_type != 1'; - $sql.= " HAVING s.reel < p.seuil_stock_alerte"; - $sql.= $db->order('s.reel', 'DESC'); + $sql.= " GROUP BY p.rowid, p.label, p.price, p.price_base_type, p.price_ttc, p.fk_product_type, p.tms, p.tosell, p.tobuy, p.seuil_stock_alerte"; + $sql.= " HAVING SUM(".$db->ifsql("s.reel IS NULL","0","s.reel").") < p.seuil_stock_alerte"; + $sql.= $db->order('p.seuil_stock_alerte', 'DESC'); $sql.= $db->plimit($max, 0); $result = $db->query($sql); if ($result) { + $langs->load("stocks"); $num = $db->num_rows($result); $i = 0; while ($i < $num) @@ -128,7 +131,8 @@ class box_produits_alerte_stock extends ModeleBoxes 'text' => $price_base_type); $this->info_box_contents[$i][4] = array('td' => 'align="center"', - 'text' => $objp->reel . ' / '.$objp->seuil_stock_alerte); + 'text' => $objp->total_stock . ' / '.$objp->seuil_stock_alerte, + 'text2'=>img_warning($langs->transnoentitiesnoconv("StockLowerThanLimit"))); $this->info_box_contents[$i][5] = array('td' => 'align="right" width="18"', 'text' => $productstatic->LibStatut($objp->tosell,3,0)); @@ -138,7 +142,7 @@ class box_produits_alerte_stock extends ModeleBoxes $i++; } - if ($num==0) $this->info_box_contents[$i][0] = array('td' => 'align="center"','text'=>$langs->trans("NoRecordedProducts")); + if ($num==0) $this->info_box_contents[$i][0] = array('td' => 'align="center"','text'=>$langs->trans("NoTooLowStockProducts")); } else { diff --git a/htdocs/core/boxes/modules_boxes.php b/htdocs/core/boxes/modules_boxes.php index 2bd51b87f98..c681395f5af 100644 --- a/htdocs/core/boxes/modules_boxes.php +++ b/htdocs/core/boxes/modules_boxes.php @@ -165,7 +165,8 @@ class ModeleBoxes // Can't be abtract as it is instanciated to build "empty" print ''; // The image must have the class 'boxhandle' beause it's value used in DOM draggable objects to define the area used to catch the full object print img_picto($langs->trans("MoveBox",$this->box_id),'grip','class="boxhandle hideonsmartphone" style="cursor:move;"'); - print img_picto($langs->trans("Close",$this->box_id),'close','class="boxclose" style="cursor:pointer;" id="imgclose'.$this->box_id.'"'); + print img_picto($langs->trans("Close",$this->box_id),'close','class="boxclose" rel="x:y" style="cursor:pointer;" id="imgclose'.$this->box_id.'"'); + print ''; print ''; } print ''; diff --git a/htdocs/core/class/commonobject.class.php b/htdocs/core/class/commonobject.class.php index 9f8a2aabf7d..73d7e7b0e5d 100644 --- a/htdocs/core/class/commonobject.class.php +++ b/htdocs/core/class/commonobject.class.php @@ -2310,7 +2310,7 @@ abstract class CommonObject /** * Function to say how many lines object contains * - * @param int $predefined -1=All, 0=Count free product/service only, 1=Count predefined product/service only + * @param int $predefined -1=All, 0=Count free product/service only, 1=Count predefined product/service only, 2=Count predefined product, 3=Count predefined service * @return int <0 if KO, 0 if no predefined products, nb of lines with predefined products if found */ function hasProductsOrServices($predefined=-1) @@ -2323,6 +2323,8 @@ abstract class CommonObject if ($predefined == -1) $qualified=1; if ($predefined == 1 && $val->fk_product > 0) $qualified=1; if ($predefined == 0 && $val->fk_product <= 0) $qualified=1; + if ($predefined == 2 && $val->fk_product > 0 && $val->product_type==0) $qualified=1; + if ($predefined == 3 && $val->fk_product > 0 && $val->product_type==1) $qualified=1; if ($qualified) $nb++; } dol_syslog(get_class($this).'::hasProductsOrServices we found '.$nb.' qualified lines of products/servcies'); @@ -2946,11 +2948,11 @@ abstract class CommonObject global $conf,$langs,$bc; //var_dump($line); - if (!empty($line->date_start)) - { + if (!empty($line->date_start)) + { $date_start=$line->date_start; } - else + else { $date_start=$line->date_debut_prevue; if ($line->date_debut_reel) $date_start=$line->date_debut_reel; @@ -2959,7 +2961,7 @@ abstract class CommonObject { $date_end=$line->date_end; } - else + else { $date_end=$line->date_fin_prevue; if ($line->date_fin_reel) $date_end=$line->date_fin_reel; @@ -2995,7 +2997,7 @@ abstract class CommonObject $this->tpl['label'].=$line->desc; }else { $this->tpl['label'].= ($line->label ? ' '.$line->label : ''); - } + } // Dates if ($line->product_type == 1 && ($date_start || $date_end)) { @@ -3048,149 +3050,160 @@ abstract class CommonObject } + /** + * + * @param string $force_price + * @return multitype:number string NULL + */ + function getMarginInfos($force_price=false) { + global $conf; + require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.product.class.php'; - function getMarginInfos($force_price=false) { - global $conf; - require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.product.class.php'; - $marginInfos = array( - 'pa_products' => 0, - 'pv_products' => 0, - 'margin_on_products' => 0, - 'margin_rate_products' => '', - 'mark_rate_products' => '', - 'pa_services' => 0, - 'pv_services' => 0, - 'margin_on_services' => 0, - 'margin_rate_services' => '', - 'mark_rate_services' => '', - 'pa_total' => 0, - 'pv_total' => 0, - 'total_margin' => 0, - 'total_margin_rate' => '', - 'total_mark_rate' => '' - ); - foreach($this->lines as $line) { - if (isset($line->fk_fournprice) && !$force_price) { - $product = new ProductFournisseur($this->db); - if ($product->fetch_product_fournisseur_price($line->fk_fournprice)) - $line->pa_ht = $product->fourn_unitprice; - if (isset($conf->global->MARGIN_TYPE) && $conf->global->MARGIN_TYPE == "2" && $product->fourn_unitcharges > 0) - $line->pa_ht += $product->fourn_unitcharges; - } - // si prix d'achat non renseigné et devrait l'être, alors prix achat = prix vente - if ((!isset($line->pa_ht) || $line->pa_ht == 0) && $line->subprice > 0 && (isset($conf->global->ForceBuyingPriceIfNull) && $conf->global->ForceBuyingPriceIfNull == 1)) { - $line->pa_ht = $line->subprice * (1 - ($line->remise_percent / 100)); - } + $marginInfos = array( + 'pa_products' => 0, + 'pv_products' => 0, + 'margin_on_products' => 0, + 'margin_rate_products' => '', + 'mark_rate_products' => '', + 'pa_services' => 0, + 'pv_services' => 0, + 'margin_on_services' => 0, + 'margin_rate_services' => '', + 'mark_rate_services' => '', + 'pa_total' => 0, + 'pv_total' => 0, + 'total_margin' => 0, + 'total_margin_rate' => '', + 'total_mark_rate' => '' + ); - // calcul des marges - if (isset($line->fk_remise_except) && isset($conf->global->MARGIN_METHODE_FOR_DISCOUNT)) { // remise - if ($conf->global->MARGIN_METHODE_FOR_DISCOUNT == '1') { // remise globale considérée comme produit - $marginInfos['pa_products'] += $line->pa_ht;// ($line->pa_ht != 0)?$line->pa_ht:$line->subprice * (1 - $line->remise_percent / 100); - $marginInfos['pv_products'] += $line->subprice * (1 - $line->remise_percent / 100); - $marginInfos['pa_total'] += $line->pa_ht;// ($line->pa_ht != 0)?$line->pa_ht:$line->subprice * (1 - $line->remise_percent / 100); - $marginInfos['pv_total'] += $line->subprice * (1 - $line->remise_percent / 100); + foreach($this->lines as $line) { + if (empty($line->pa_ht) && isset($line->fk_fournprice) && !$force_price) { + $product = new ProductFournisseur($this->db); + if ($product->fetch_product_fournisseur_price($line->fk_fournprice)) + $line->pa_ht = $product->fourn_unitprice; + if (isset($conf->global->MARGIN_TYPE) && $conf->global->MARGIN_TYPE == "2" && $product->fourn_unitcharges > 0) + $line->pa_ht += $product->fourn_unitcharges; + } + // si prix d'achat non renseigné et devrait l'être, alors prix achat = prix vente + if ((!isset($line->pa_ht) || $line->pa_ht == 0) && $line->subprice > 0 && (isset($conf->global->ForceBuyingPriceIfNull) && $conf->global->ForceBuyingPriceIfNull == 1)) { + $line->pa_ht = $line->subprice * (1 - ($line->remise_percent / 100)); + } + + // calcul des marges + if (isset($line->fk_remise_except) && isset($conf->global->MARGIN_METHODE_FOR_DISCOUNT)) { // remise + if ($conf->global->MARGIN_METHODE_FOR_DISCOUNT == '1') { // remise globale considérée comme produit + $marginInfos['pa_products'] += $line->pa_ht;// ($line->pa_ht != 0)?$line->pa_ht:$line->subprice * (1 - $line->remise_percent / 100); + $marginInfos['pv_products'] += $line->subprice * (1 - $line->remise_percent / 100); + $marginInfos['pa_total'] += $line->pa_ht;// ($line->pa_ht != 0)?$line->pa_ht:$line->subprice * (1 - $line->remise_percent / 100); + $marginInfos['pv_total'] += $line->subprice * (1 - $line->remise_percent / 100); } - elseif ($conf->global->MARGIN_METHODE_FOR_DISCOUNT == '2') { // remise globale considérée comme service - $marginInfos['pa_services'] += $line->pa_ht;// ($line->pa_ht != 0)?$line->pa_ht:$line->subprice * (1 - $line->remise_percent / 100); - $marginInfos['pv_services'] += $line->subprice * (1 - ($line->remise_percent / 100)); - $marginInfos['pa_total'] += $line->pa_ht;// ($line->pa_ht != 0)?$line->pa_ht:$line->subprice * (1 - $line->remise_percent / 100); - $marginInfos['pv_total'] += $line->subprice * (1 - $line->remise_percent / 100); + elseif ($conf->global->MARGIN_METHODE_FOR_DISCOUNT == '2') { // remise globale considérée comme service + $marginInfos['pa_services'] += $line->pa_ht;// ($line->pa_ht != 0)?$line->pa_ht:$line->subprice * (1 - $line->remise_percent / 100); + $marginInfos['pv_services'] += $line->subprice * (1 - ($line->remise_percent / 100)); + $marginInfos['pa_total'] += $line->pa_ht;// ($line->pa_ht != 0)?$line->pa_ht:$line->subprice * (1 - $line->remise_percent / 100); + $marginInfos['pv_total'] += $line->subprice * (1 - $line->remise_percent / 100); } - elseif ($conf->global->MARGIN_METHODE_FOR_DISCOUNT == '3') { // remise globale prise en compte uniqt sur total - $marginInfos['pa_total'] += $line->pa_ht;// ($line->pa_ht != 0)?$line->pa_ht:$line->subprice * (1 - $line->remise_percent / 100); - $marginInfos['pv_total'] += $line->subprice * (1 - ($line->remise_percent / 100)); + elseif ($conf->global->MARGIN_METHODE_FOR_DISCOUNT == '3') { // remise globale prise en compte uniqt sur total + $marginInfos['pa_total'] += $line->pa_ht;// ($line->pa_ht != 0)?$line->pa_ht:$line->subprice * (1 - $line->remise_percent / 100); + $marginInfos['pv_total'] += $line->subprice * (1 - ($line->remise_percent / 100)); } } - else { - $type=$line->product_type?$line->product_type:$line->fk_product_type; - if ($type == 0) { // product - $marginInfos['pa_products'] += $line->qty * $line->pa_ht; - $marginInfos['pv_products'] += $line->qty * $line->subprice * (1 - $line->remise_percent / 100); - $marginInfos['pa_total'] += $line->qty * $line->pa_ht; - $marginInfos['pv_total'] += $line->qty * $line->subprice * (1 - $line->remise_percent / 100); - } - elseif ($type == 1) { // service - $marginInfos['pa_services'] += $line->qty * $line->pa_ht; - $marginInfos['pv_services'] += $line->qty * $line->subprice * (1 - ($line->remise_percent / 100)); - $marginInfos['pa_total'] += $line->qty * $line->pa_ht; - $marginInfos['pv_total'] += $line->qty * $line->subprice * (1 - $line->remise_percent / 100); - } - } - } + else { + $type=$line->product_type?$line->product_type:$line->fk_product_type; + if ($type == 0) { // product + $marginInfos['pa_products'] += $line->qty * $line->pa_ht; + $marginInfos['pv_products'] += $line->qty * $line->subprice * (1 - $line->remise_percent / 100); + $marginInfos['pa_total'] += $line->qty * $line->pa_ht; + $marginInfos['pv_total'] += $line->qty * $line->subprice * (1 - $line->remise_percent / 100); + } + elseif ($type == 1) { // service + $marginInfos['pa_services'] += $line->qty * $line->pa_ht; + $marginInfos['pv_services'] += $line->qty * $line->subprice * (1 - ($line->remise_percent / 100)); + $marginInfos['pa_total'] += $line->qty * $line->pa_ht; + $marginInfos['pv_total'] += $line->qty * $line->subprice * (1 - $line->remise_percent / 100); + } + } + } - $marginInfos['margin_on_products'] = $marginInfos['pv_products'] - $marginInfos['pa_products']; - if ($marginInfos['pa_products'] > 0) - $marginInfos['margin_rate_products'] = 100 * round($marginInfos['margin_on_products'] / $marginInfos['pa_products'],5); - if ($marginInfos['pv_products'] > 0) - $marginInfos['mark_rate_products'] = 100 * round($marginInfos['margin_on_products'] / $marginInfos['pv_products'],5); + $marginInfos['margin_on_products'] = $marginInfos['pv_products'] - $marginInfos['pa_products']; + if ($marginInfos['pa_products'] > 0) + $marginInfos['margin_rate_products'] = 100 * round($marginInfos['margin_on_products'] / $marginInfos['pa_products'],5); + if ($marginInfos['pv_products'] > 0) + $marginInfos['mark_rate_products'] = 100 * round($marginInfos['margin_on_products'] / $marginInfos['pv_products'],5); - $marginInfos['margin_on_services'] = $marginInfos['pv_services'] - $marginInfos['pa_services']; - if ($marginInfos['pa_services'] > 0) - $marginInfos['margin_rate_services'] = 100 * round($marginInfos['margin_on_services'] / $marginInfos['pa_services'],5); - if ($marginInfos['pv_services'] > 0) - $marginInfos['mark_rate_services'] = 100 * round($marginInfos['margin_on_services'] / $marginInfos['pv_services'],5); + $marginInfos['margin_on_services'] = $marginInfos['pv_services'] - $marginInfos['pa_services']; + if ($marginInfos['pa_services'] > 0) + $marginInfos['margin_rate_services'] = 100 * round($marginInfos['margin_on_services'] / $marginInfos['pa_services'],5); + if ($marginInfos['pv_services'] > 0) + $marginInfos['mark_rate_services'] = 100 * round($marginInfos['margin_on_services'] / $marginInfos['pv_services'],5); + $marginInfos['total_margin'] = $marginInfos['pv_total'] - $marginInfos['pa_total']; + if ($marginInfos['pa_total'] > 0) + $marginInfos['total_margin_rate'] = 100 * round($marginInfos['total_margin'] / $marginInfos['pa_total'],5); + if ($marginInfos['pv_total'] > 0) + $marginInfos['total_mark_rate'] = 100 * round($marginInfos['total_margin'] / $marginInfos['pv_total'],5); - $marginInfos['total_margin'] = $marginInfos['pv_total'] - $marginInfos['pa_total']; - if ($marginInfos['pa_total'] > 0) - $marginInfos['total_margin_rate'] = 100 * round($marginInfos['total_margin'] / $marginInfos['pa_total'],5); - if ($marginInfos['pv_total'] > 0) - $marginInfos['total_mark_rate'] = 100 * round($marginInfos['total_margin'] / $marginInfos['pv_total'],5); + return $marginInfos; + } - return $marginInfos; - } + /** + * + * @param string $force_price + */ + function displayMarginInfos($force_price=false) { + global $langs, $conf; + + $marginInfo = $this->getMarginInfos($force_price); + + print ''; + print ''; + print ''; + print ''; + if ($conf->global->MARGIN_TYPE == "1") + print ''; + else + print ''; + print ''; + if (! empty($conf->global->DISPLAY_MARGIN_RATES)) + print ''; + if (! empty($conf->global->DISPLAY_MARK_RATES)) + print ''; + print ''; + //if ($marginInfo['margin_on_products'] != 0 && $marginInfo['margin_on_services'] != 0) { + print ''; + print ''; + print ''; + print ''; + print ''; + if (! empty($conf->global->DISPLAY_MARGIN_RATES)) + print ''; + if (! empty($conf->global->DISPLAY_MARK_RATES)) + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + if (! empty($conf->global->DISPLAY_MARGIN_RATES)) + print ''; + if (! empty($conf->global->DISPLAY_MARK_RATES)) + print ''; + print ''; + //} + print ''; + print ''; + print ''; + print ''; + print ''; + if (! empty($conf->global->DISPLAY_MARGIN_RATES)) + print ''; + if (! empty($conf->global->DISPLAY_MARK_RATES)) + print ''; + print ''; + print '
'.$langs->trans('Margins').''.$langs->trans('SellingPrice').''.$langs->trans('BuyingPrice').''.$langs->trans('CostPrice').''.$langs->trans('Margin').''.$langs->trans('MarginRate').''.$langs->trans('MarkRate').'
'.$langs->trans('MarginOnProducts').''.price($marginInfo['pv_products']).''.price($marginInfo['pa_products']).''.price($marginInfo['margin_on_products']).''.(($marginInfo['margin_rate_products'] == '')?'n/a':price($marginInfo['margin_rate_products']).'%').''.(($marginInfo['mark_rate_products'] == '')?'n/a':price($marginInfo['mark_rate_products']).'%').'
'.$langs->trans('MarginOnServices').''.price($marginInfo['pv_services']).''.price($marginInfo['pa_services']).''.price($marginInfo['margin_on_services']).''.(($marginInfo['margin_rate_services'] == '')?'n/a':price($marginInfo['margin_rate_services']).'%').''.(($marginInfo['mark_rate_services'] == '')?'n/a':price($marginInfo['mark_rate_services']).'%').'
'.$langs->trans('TotalMargin').''.price($marginInfo['pv_total']).''.price($marginInfo['pa_total']).''.price($marginInfo['total_margin']).''.(($marginInfo['total_margin_rate'] == '')?'n/a':price($marginInfo['total_margin_rate']).'%').''.(($marginInfo['total_mark_rate'] == '')?'n/a':price($marginInfo['total_mark_rate']).'%').'
'; + } - function displayMarginInfos($force_price=false) { - global $langs, $conf; - $marginInfo = $this->getMarginInfos($force_price); - print ''; - print ''; - print ''; - print ''; - if ($conf->global->MARGIN_TYPE == "1") - print ''; - else - print ''; - print ''; - if (! empty($conf->global->DISPLAY_MARGIN_RATES)) - print ''; - if (! empty($conf->global->DISPLAY_MARK_RATES)) - print ''; - print ''; - //if ($marginInfo['margin_on_products'] != 0 && $marginInfo['margin_on_services'] != 0) { - print ''; - print ''; - print ''; - print ''; - print ''; - if (! empty($conf->global->DISPLAY_MARGIN_RATES)) - print ''; - if (! empty($conf->global->DISPLAY_MARK_RATES)) - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - if (! empty($conf->global->DISPLAY_MARGIN_RATES)) - print ''; - if (! empty($conf->global->DISPLAY_MARK_RATES)) - print ''; - print ''; - //} - print ''; - print ''; - print ''; - print ''; - print ''; - if (! empty($conf->global->DISPLAY_MARGIN_RATES)) - print ''; - if (! empty($conf->global->DISPLAY_MARK_RATES)) - print ''; - print ''; - print '
'.$langs->trans('Margins').''.$langs->trans('SellingPrice').''.$langs->trans('BuyingPrice').''.$langs->trans('CostPrice').''.$langs->trans('Margin').''.$langs->trans('MarginRate').''.$langs->trans('MarkRate').'
'.$langs->trans('MarginOnProducts').''.price($marginInfo['pv_products']).''.price($marginInfo['pa_products']).''.price($marginInfo['margin_on_products']).''.(($marginInfo['margin_rate_products'] == '')?'n/a':price($marginInfo['margin_rate_products']).'%').''.(($marginInfo['mark_rate_products'] == '')?'n/a':price($marginInfo['mark_rate_products']).'%').'
'.$langs->trans('MarginOnServices').''.price($marginInfo['pv_services']).''.price($marginInfo['pa_services']).''.price($marginInfo['margin_on_services']).''.(($marginInfo['margin_rate_services'] == '')?'n/a':price($marginInfo['margin_rate_services']).'%').''.(($marginInfo['mark_rate_services'] == '')?'n/a':price($marginInfo['mark_rate_services']).'%').'
'.$langs->trans('TotalMargin').''.price($marginInfo['pv_total']).''.price($marginInfo['pa_total']).''.price($marginInfo['total_margin']).''.(($marginInfo['total_margin_rate'] == '')?'n/a':price($marginInfo['total_margin_rate']).'%').''.(($marginInfo['total_mark_rate'] == '')?'n/a':price($marginInfo['total_mark_rate']).'%').'
'; - } } - ?> diff --git a/htdocs/core/class/extrafields.class.php b/htdocs/core/class/extrafields.class.php index aae14dba217..e2986615dde 100755 --- a/htdocs/core/class/extrafields.class.php +++ b/htdocs/core/class/extrafields.class.php @@ -1,34 +1,34 @@ * Copyright (C) 2002-2003 Jean-Louis Bergamo - * Copyright (C) 2004 Sebastien Di Cintio - * Copyright (C) 2004 Benoit Mortier - * Copyright (C) 2009-2012 Laurent Destailleur - * Copyright (C) 2009-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 . - */ +* Copyright (C) 2004 Sebastien Di Cintio +* Copyright (C) 2004 Benoit Mortier +* Copyright (C) 2009-2012 Laurent Destailleur +* Copyright (C) 2009-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/core/class/extrafields.class.php - * \ingroup core - * \brief File of class to manage extra fields - */ +* \ingroup core +* \brief File of class to manage extra fields +*/ /** * Class to manage standard extra fields - */ +*/ class ExtraFields { var $db; @@ -53,27 +53,29 @@ class ExtraFields var $errno; static $type2label=array( - 'varchar'=>'String', - 'text'=>'TextLong', - 'int'=>'Int', - 'double'=>'Float', - 'date'=>'Date', - 'datetime'=>'DateAndTime', - 'boolean'=>'Boolean', - 'price'=>'ExtrafieldPrice', - 'phone'=>'ExtrafieldPhone', - 'mail'=>'ExtrafieldMail', - 'select' => 'ExtrafieldSelect', - 'separate' => 'ExtrafieldSeparator', - 'checkbox' => 'ExtrafieldCheckBox', - 'radio' => 'ExtrafieldRadio', + 'varchar'=>'String', + 'text'=>'TextLong', + 'int'=>'Int', + 'double'=>'Float', + 'date'=>'Date', + 'datetime'=>'DateAndTime', + 'boolean'=>'Boolean', + 'price'=>'ExtrafieldPrice', + 'phone'=>'ExtrafieldPhone', + 'mail'=>'ExtrafieldMail', + 'select' => 'ExtrafieldSelect', + 'sellist' => 'ExtrafieldSelectList', + 'separate' => 'ExtrafieldSeparator', + 'checkbox' => 'ExtrafieldCheckBox', + 'radio' => 'ExtrafieldRadio', + ); /** * Constructor * * @param DoliDB $db Database handler - */ + */ function __construct($db) { $this->db = $db; @@ -86,49 +88,49 @@ class ExtraFields $this->attribute_required = array(); } - /** - * Add a new extra field parameter - * - * @param string $attrname Code of attribute - * @param string $label label of attribute - * @param int $type Type of attribute ('int', 'text', 'varchar', 'date', 'datehour') - * @param int $pos Position of attribute - * @param int $size Size/length of attribute - * @param string $elementtype Element type ('member', 'product', 'company', ...) - * @param int $unique Is field unique or not - * @param int $required Is field required or not - * @param string $default_value Defaulted value - * @param array $param Params for field - * @return int <=0 if KO, >0 if OK - */ - function addExtraField($attrname, $label, $type, $pos, $size, $elementtype, $unique=0, $required=0,$default_value='', $param=0) + /** + * Add a new extra field parameter + * + * @param string $attrname Code of attribute + * @param string $label label of attribute + * @param int $type Type of attribute ('int', 'text', 'varchar', 'date', 'datehour') + * @param int $pos Position of attribute + * @param int $size Size/length of attribute + * @param string $elementtype Element type ('member', 'product', 'company', ...) + * @param int $unique Is field unique or not + * @param int $required Is field required or not + * @param string $default_value Defaulted value + * @param array $param Params for field + * @return int <=0 if KO, >0 if OK + */ + function addExtraField($attrname, $label, $type, $pos, $size, $elementtype, $unique=0, $required=0,$default_value='', $param=0) { - if (empty($attrname)) return -1; - if (empty($label)) return -1; + if (empty($attrname)) return -1; + if (empty($label)) return -1; - // Create field into database except for separator type which is not stored in database - if ($type != 'separate') - { - $result=$this->create($attrname,$type,$size,$elementtype, $unique, $required, $default_value,$param); - } - $err1=$this->errno; - if ($result > 0 || $err1 == 'DB_ERROR_COLUMN_ALREADY_EXISTS' || $type == 'separate') - { - // Add declaration of field into table - $result2=$this->create_label($attrname,$label,$type,$pos,$size,$elementtype, $unique, $required, $param); - $err2=$this->errno; - if ($result2 > 0 || ($err1 == 'DB_ERROR_COLUMN_ALREADY_EXISTS' && $err2 == 'DB_ERROR_RECORD_ALREADY_EXISTS')) - { - $this->error=''; - $this->errno=0; - return 1; - } - else return -2; - } - else - { - return -1; - } + // Create field into database except for separator type which is not stored in database + if ($type != 'separate') + { + $result=$this->create($attrname,$type,$size,$elementtype, $unique, $required, $default_value,$param); + } + $err1=$this->errno; + if ($result > 0 || $err1 == 'DB_ERROR_COLUMN_ALREADY_EXISTS' || $type == 'separate') + { + // Add declaration of field into table + $result2=$this->create_label($attrname,$label,$type,$pos,$size,$elementtype, $unique, $required, $param); + $err2=$this->errno; + if ($result2 > 0 || ($err1 == 'DB_ERROR_COLUMN_ALREADY_EXISTS' && $err2 == 'DB_ERROR_RECORD_ALREADY_EXISTS')) + { + $this->error=''; + $this->errno=0; + return 1; + } + else return -2; + } + else + { + return -1; + } } /** @@ -138,22 +140,22 @@ class ExtraFields * @param string $attrname code of attribute * @param int $type Type of attribute ('int', 'text', 'varchar', 'date', 'datehour') * @param int $length Size/length of attribute - * @param string $elementtype Element type ('member', 'product', 'company', 'contact', ...) - * @param int $unique Is field unique or not - * @param int $required Is field required or not - * @param string $default_value Default value for field - * @param array $param Params for field (ex for select list : array('options'=>array('value'=>'label of option')) - * - * @return int <=0 if KO, >0 if OK + * @param string $elementtype Element type ('member', 'product', 'company', 'contact', ...) + * @param int $unique Is field unique or not + * @param int $required Is field required or not + * @param string $default_value Default value for field + * @param array $param Params for field (ex for select list : array('options'=>array('value'=>'label of option')) + * + * @return int <=0 if KO, >0 if OK */ private function create($attrname, $type='varchar', $length=255, $elementtype='member', $unique=0, $required=0, $default_value='',$param='') { - $table=$elementtype.'_extrafields'; - - // Special case for not normalized table names - if ($elementtype == 'member') $table='adherent_extrafields'; - elseif ($elementtype == 'company') $table='societe_extrafields'; - elseif ($elementtype == 'contact') $table='socpeople_extrafields'; + $table=$elementtype.'_extrafields'; + + // Special case for not normalized table names + if ($elementtype == 'member') $table='adherent_extrafields'; + elseif ($elementtype == 'company') $table='societe_extrafields'; + elseif ($elementtype == 'contact') $table='socpeople_extrafields'; if (isset($attrname) && $attrname != '' && preg_match("/^\w[a-zA-Z0-9-_]*$/",$attrname)) { @@ -169,7 +171,7 @@ class ExtraFields }elseif($type=='mail') { $typedb='varchar'; $lengthdb='128'; - } elseif (($type=='select') || ($type=='radio') ||($type=='checkbox')){ + } elseif (($type=='select') || ($type=='sellist') || ($type=='radio') ||($type=='checkbox')){ $typedb='text'; $lengthdb=''; } else { @@ -177,12 +179,12 @@ class ExtraFields $lengthdb=$length; } $field_desc = array( - 'type'=>$typedb, - 'value'=>$lengthdb, - 'null'=>($required?'NOT NULL':'NULL'), - 'default' => $default_value + 'type'=>$typedb, + 'value'=>$lengthdb, + 'null'=>($required?'NOT NULL':'NULL'), + 'default' => $default_value ); - + $result=$this->db->DDLAddField(MAIN_DB_PREFIX.$table, $attrname, $field_desc); if ($result > 0) { @@ -215,9 +217,9 @@ class ExtraFields * @param int $pos Position of attribute * @param int $size Size/length of attribute * @param string $elementtype Element type ('member', 'product', 'company', ...) - * @param int $unique Is field unique or not - * @param int $required Is field required or not - * @param array $param Params for field (ex for select list : array('options' => array(value'=>'label of option')) ) + * @param int $unique Is field unique or not + * @param int $required Is field required or not + * @param array $param Params for field (ex for select list : array('options' => array(value'=>'label of option')) ) * @return int <=0 if KO, >0 if OK */ private function create_label($attrname, $label='', $type='', $pos=0, $size=0, $elementtype='member', $unique=0, $required=0, $param='') @@ -227,7 +229,7 @@ class ExtraFields // Clean parameters if (empty($pos)) $pos=0; - + if (isset($attrname) && $attrname != '' && preg_match("/^\w[a-zA-Z0-9-_]*$/",$attrname)) { if(is_array($param) and count($param) > 0) @@ -242,7 +244,7 @@ class ExtraFields { $params=''; } - + $sql = "INSERT INTO ".MAIN_DB_PREFIX."extrafields(name, label, type, pos, size, entity, elementtype, fieldunique, fieldrequired, param)"; $sql.= " VALUES('".$attrname."',"; $sql.= " '".$this->db->escape($label)."',"; @@ -250,11 +252,11 @@ class ExtraFields $sql.= " '".$pos."',"; $sql.= " '".$size."',"; $sql.= " ".$conf->entity.","; - $sql.= " '".$elementtype."',"; - $sql.= " '".$unique."',"; - $sql.= " '".$required."',"; - $sql.= " '".$params."'"; - $sql.=')'; + $sql.= " '".$elementtype."',"; + $sql.= " '".$unique."',"; + $sql.= " '".$required."',"; + $sql.= " '".$params."'"; + $sql.=')'; dol_syslog(get_class($this)."::create_label sql=".$sql); if ($this->db->query($sql)) @@ -279,16 +281,16 @@ class ExtraFields */ function delete($attrname, $elementtype='member') { - $table=$elementtype.'_extrafields'; + $table=$elementtype.'_extrafields'; - // Special case for not normalized table names - if ($elementtype == 'member') $table='adherent_extrafields'; - elseif ($elementtype == 'company') $table='societe_extrafields'; - elseif ($elementtype == 'contact') $table='socpeople_extrafields'; + // Special case for not normalized table names + if ($elementtype == 'member') $table='adherent_extrafields'; + elseif ($elementtype == 'company') $table='societe_extrafields'; + elseif ($elementtype == 'contact') $table='socpeople_extrafields'; if (! empty($attrname) && preg_match("/^\w[a-zA-Z0-9-_]*$/",$attrname)) { - $result=$this->db->DDLDropField(MAIN_DB_PREFIX.$table,$attrname); // This also drop the unique key + $result=$this->db->DDLDropField(MAIN_DB_PREFIX.$table,$attrname); // This also drop the unique key if ($result < 0) { $this->error=$this->db->lasterror(); @@ -310,8 +312,8 @@ class ExtraFields * Delete description of an optionnal attribute * * @param string $attrname Code of attribute to delete - * @param string $elementtype Element type ('member', 'product', 'company', ...) - * @return int < 0 if KO, 0 if nothing is done, 1 if OK + * @param string $elementtype Element type ('member', 'product', 'company', ...) + * @return int < 0 if KO, 0 if nothing is done, 1 if OK */ private function delete_label($attrname, $elementtype='member') { @@ -322,7 +324,7 @@ class ExtraFields $sql = "DELETE FROM ".MAIN_DB_PREFIX."extrafields"; $sql.= " WHERE name = '".$attrname."'"; $sql.= " AND entity = ".$conf->entity; - $sql.= " AND elementtype = '".$elementtype."'"; + $sql.= " AND elementtype = '".$elementtype."'"; dol_syslog(get_class($this)."::delete_label sql=".$sql); $resql=$this->db->query($sql); @@ -350,22 +352,22 @@ class ExtraFields * @param string $label Label of attribute * @param string $type Type of attribute * @param int $length Length of attribute - * @param string $elementtype Element type ('member', 'product', 'company', 'contact', ...) - * @param int $unique Is field unique or not - * @param int $required Is field required or not - * @param int $pos Position of attribute - * @param array $param Params for field (ex for select list : array('options' => array(value'=>'label of option')) ) + * @param string $elementtype Element type ('member', 'product', 'company', 'contact', ...) + * @param int $unique Is field unique or not + * @param int $required Is field required or not + * @param int $pos Position of attribute + * @param array $param Params for field (ex for select list : array('options' => array(value'=>'label of option')) ) * @return int >0 if OK, <=0 if KO */ function update($attrname,$label,$type,$length,$elementtype,$unique=0,$required=0,$pos=0,$param='') { - $table=$elementtype.'_extrafields'; - // Special case for not normalized table names - if ($elementtype == 'member') $table='adherent_extrafields'; - elseif ($elementtype == 'company') $table='societe_extrafields'; - elseif ($elementtype == 'contact') $table='socpeople_extrafields'; + $table=$elementtype.'_extrafields'; + // Special case for not normalized table names + if ($elementtype == 'member') $table='adherent_extrafields'; + elseif ($elementtype == 'company') $table='societe_extrafields'; + elseif ($elementtype == 'contact') $table='socpeople_extrafields'; - if (isset($attrname) && $attrname != '' && preg_match("/^\w[a-zA-Z0-9-_]*$/",$attrname)) + if (isset($attrname) && $attrname != '' && preg_match("/^\w[a-zA-Z0-9-_]*$/",$attrname)) { if ($type=='boolean') { $typedb='int'; @@ -379,7 +381,7 @@ class ExtraFields }elseif($type=='mail') { $typedb='varchar'; $lengthdb='128'; - } elseif (($type=='select') || ($type=='radio') ||($type=='checkbox')) { + } elseif (($type=='select') || ($type=='sellist') || ($type=='radio') ||($type=='checkbox')) { $typedb='text'; $lengthdb=''; } else { @@ -387,7 +389,7 @@ class ExtraFields $lengthdb=$length; } $field_desc = array('type'=>$typedb, 'value'=>$lengthdb, 'null'=>($required?'NOT NULL':'NULL')); - + if ($type != 'separate') // No table update when separate type { $result=$this->db->DDLUpdateField(MAIN_DB_PREFIX.$table, $attrname, $field_desc); @@ -437,15 +439,15 @@ class ExtraFields * * @param string $attrname Name of attribute * @param string $label Label of attribute - * @param string $type Type of attribute - * @param int $size Length of attribute - * @param string $elementtype Element type ('member', 'product', 'company', ...) - * @param int $unique Is field unique or not - * @param int $required Is field required or not - * @param int $pos Position of attribute - * @param array $param Params for field (ex for select list : array('options' => array(value'=>'label of option')) ) - * @return int <=0 if KO, >0 if OK - */ + * @param string $type Type of attribute + * @param int $size Length of attribute + * @param string $elementtype Element type ('member', 'product', 'company', ...) + * @param int $unique Is field unique or not + * @param int $required Is field required or not + * @param int $pos Position of attribute + * @param array $param Params for field (ex for select list : array('options' => array(value'=>'label of option')) ) + * @return int <=0 if KO, >0 if OK + */ private function update_label($attrname,$label,$type,$size,$elementtype,$unique=0,$required=0,$pos=0,$param='') { global $conf; @@ -454,12 +456,12 @@ class ExtraFields if (isset($attrname) && $attrname != '' && preg_match("/^\w[a-zA-Z0-9-_]*$/",$attrname)) { $this->db->begin(); - + if(is_array($param) && count($param) > 0) { $param = serialize($param); } - + $sql_del = "DELETE FROM ".MAIN_DB_PREFIX."extrafields"; $sql_del.= " WHERE name = '".$attrname."'"; $sql_del.= " AND entity = ".$conf->entity; @@ -484,12 +486,12 @@ class ExtraFields $sql.= " '".$this->db->escape($label)."',"; $sql.= " '".$type."',"; $sql.= " '".$size."',"; - $sql.= " '".$elementtype."',"; - $sql.= " '".$unique."',"; - $sql.= " '".$required."',"; - $sql.= " '".$pos."',"; - $sql.= " '".$param."'"; - $sql.= ")"; + $sql.= " '".$elementtype."',"; + $sql.= " '".$unique."',"; + $sql.= " '".$required."',"; + $sql.= " '".$pos."',"; + $sql.= " '".$param."'"; + $sql.= ")"; dol_syslog(get_class($this)."::update_label sql=".$sql); $resql2=$this->db->query($sql); @@ -555,7 +557,7 @@ class ExtraFields { while ($tab = $this->db->fetch_object($resql)) { - + // we can add this attribute to adherent object if ($tab->type != 'separate') { @@ -565,11 +567,11 @@ class ExtraFields $this->attribute_type[$tab->name]=$tab->type; $this->attribute_label[$tab->name]=$tab->label; $this->attribute_size[$tab->name]=$tab->size; - $this->attribute_elementtype[$tab->name]=$tab->elementtype; - $this->attribute_unique[$tab->name]=$tab->fieldunique; - $this->attribute_required[$tab->name]=$tab->fieldrequired; - $this->attribute_param[$tab->name]=unserialize($tab->param); - $this->attribute_pos[$tab->name]=$tab->pos; + $this->attribute_elementtype[$tab->name]=$tab->elementtype; + $this->attribute_unique[$tab->name]=$tab->fieldunique; + $this->attribute_required[$tab->name]=$tab->fieldrequired; + $this->attribute_param[$tab->name]=unserialize($tab->param); + $this->attribute_pos[$tab->name]=$tab->pos; } } return $array_name_label; @@ -593,268 +595,332 @@ class ExtraFields { global $conf,$langs; - $label=$this->attribute_label[$key]; - $type =$this->attribute_type[$key]; - $size =$this->attribute_size[$key]; - $elementtype=$this->attribute_elementtype[$key]; - $unique=$this->attribute_unique[$key]; - $required=$this->attribute_required[$key]; - $param=$this->attribute_param[$key]; - if ($type == 'date') - { - $showsize=10; - } - elseif ($type == 'datetime') - { - $showsize=19; - } - elseif (in_array($type,array('int','double'))) - { - $showsize=10; - } - else - { - $showsize=round($size); - if ($showsize > 48) $showsize=48; - } + $label=$this->attribute_label[$key]; + $type =$this->attribute_type[$key]; + $size =$this->attribute_size[$key]; + $elementtype=$this->attribute_elementtype[$key]; + $unique=$this->attribute_unique[$key]; + $required=$this->attribute_required[$key]; + $param=$this->attribute_param[$key]; + if ($type == 'date') + { + $showsize=10; + } + elseif ($type == 'datetime') + { + $showsize=19; + } + elseif (in_array($type,array('int','double'))) + { + $showsize=10; + } + else + { + $showsize=round($size); + if ($showsize > 48) $showsize=48; + } if (in_array($type,array('date','datetime'))) - { - $tmp=explode(',',$size); - $newsize=$tmp[0]; - if(!class_exists('Form')) - require_once DOL_DOCUMENT_ROOT.'/core/class/html.form.class.php'; - $formstat = new Form($db); - - $showtime = in_array($type,array('datetime')) ? 1 : 0; - // Do not show current date when field not required (see select_date() method) - if(!$required && $value == '') - $value = '-1'; - - $out = $formstat->select_date($value, 'options_'.$key, $showtime, $showtime, $required, '', 1, 1, 1, 0, 1); - //$out=''; - } - elseif (in_array($type,array('int','double'))) - { - $tmp=explode(',',$size); - $newsize=$tmp[0]; - $out=''; - } - elseif ($type == 'varchar') - { - $out=''; - } - elseif ($type == 'text') - { - require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php'; - $doleditor=new DolEditor('options_'.$key,$value,'',200,'dolibarr_notes','In',false,false,! empty($conf->fckeditor->enabled) && $conf->global->FCKEDITOR_ENABLE_SOCIETE,5,100); - $out=$doleditor->Create(1); - } - elseif ($type == 'boolean') - { - $checked=''; - if (!empty($value)) { - $checked=' checked="checked" value="1" '; - } else { - $checked=' value="1" '; - } - $out=''; - } - elseif ($type == 'mail') - { - $out=''; - } - elseif ($type == 'phone') - { - $out=''; - } - elseif ($type == 'price') - { - $out=' '.$langs->getCurrencySymbol($conf->currency); - } - elseif ($type == 'select') - { - $out=''; - } - elseif ($type == 'checkbox') - { - $out=''; - $value_arr=explode(',',$value); + { + $tmp=explode(',',$size); + $newsize=$tmp[0]; + if(!class_exists('Form')) + require_once DOL_DOCUMENT_ROOT.'/core/class/html.form.class.php'; + $formstat = new Form($db); - foreach ($param['options'] as $keyopt=>$val ) - { - - $out.=''; - } - } - elseif ($type == 'radio') - { - $out=''; - foreach ($param['options'] as $keyopt=>$val ) - { - $out.=''; - } - } - /* Add comments - if ($type == 'date') $out.=' (YYYY-MM-DD)'; - elseif ($type == 'datetime') $out.=' (YYYY-MM-DD HH:MM:SS)'; - */ - return $out; + $showtime = in_array($type,array('datetime')) ? 1 : 0; + // Do not show current date when field not required (see select_date() method) + if(!$required && $value == '') + $value = '-1'; + + $out = $formstat->select_date($value, 'options_'.$key, $showtime, $showtime, $required, '', 1, 1, 1, 0, 1); + //$out=''; + } + elseif (in_array($type,array('int','double'))) + { + $tmp=explode(',',$size); + $newsize=$tmp[0]; + $out=''; + } + elseif ($type == 'varchar') + { + $out=''; + } + elseif ($type == 'text') + { + require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php'; + $doleditor=new DolEditor('options_'.$key,$value,'',200,'dolibarr_notes','In',false,false,! empty($conf->fckeditor->enabled) && $conf->global->FCKEDITOR_ENABLE_SOCIETE,5,100); + $out=$doleditor->Create(1); + } + elseif ($type == 'boolean') + { + $checked=''; + if (!empty($value)) { + $checked=' checked="checked" value="1" '; + } else { + $checked=' value="1" '; + } + $out=''; + } + elseif ($type == 'mail') + { + $out=''; + } + elseif ($type == 'phone') + { + $out=''; + } + elseif ($type == 'price') + { + $out=' '.$langs->getCurrencySymbol($conf->currency); + } + elseif ($type == 'select') + { + $out=''; + } + elseif ($type == 'sellist') + { + $out=''; + } + elseif ($type == 'checkbox') + { + $out=''; + $value_arr=explode(',',$value); + + foreach ($param['options'] as $keyopt=>$val ) + { + + $out.=''; + } + } + elseif ($type == 'radio') + { + $out=''; + foreach ($param['options'] as $keyopt=>$val ) + { + $out.=''; + } + } + /* Add comments + if ($type == 'date') $out.=' (YYYY-MM-DD)'; + elseif ($type == 'datetime') $out.=' (YYYY-MM-DD HH:MM:SS)'; + */ + return $out; } - /** - * Return HTML string to put an output field into a page - * - * @param string $key Key of attribute - * @param string $value Value to show - * @param string $moreparam More param - * @return string Formated value - */ - function showOutputField($key,$value,$moreparam='') - { + /** + * Return HTML string to put an output field into a page + * + * @param string $key Key of attribute + * @param string $value Value to show + * @param string $moreparam More param + * @return string Formated value + */ + function showOutputField($key,$value,$moreparam='') + { global $conf,$langs; - $label=$this->attribute_label[$key]; - $type=$this->attribute_type[$key]; - $size=$this->attribute_size[$key]; - $elementtype=$this->attribute_elementtype[$key]; - $unique=$this->attribute_unique[$key]; - $required=$this->attribute_required[$key]; - $params=$this->attribute_param[$key]; - if ($type == 'date') - { - $showsize=10; - $value=dol_print_date($value,'day'); - } - elseif ($type == 'datetime') - { - $showsize=19; - $value=dol_print_date($value,'dayhour'); - } - elseif ($type == 'int') - { - $showsize=10; - } - elseif ($type == 'boolean') - { - $checked=''; - if (!empty($value)) { - $checked=' checked="checked" '; - } - $value=''; - } - elseif ($type == 'mail') - { - $value=dol_print_email($value); - } - elseif ($type == 'phone') - { - $value=dol_print_phone($value); - } - elseif ($type == 'price') - { - $value=price($value).' '.$langs->getCurrencySymbol($conf->currency); - } - elseif ($type == 'select') - { - $value=$params['options'][$value]; - } - elseif ($type == 'radio') - { - $value=$params['options'][$value]; - } - elseif ($type == 'checkbox') - { - $value_arr=explode(',',$value); - $value=''; - if (is_array($value_arr)) - { - foreach ($value_arr as $keyval=>$valueval) { - $value.=$params['options'][$valueval].'
'; - } - } - } - else - { - $showsize=round($size); - if ($showsize > 48) $showsize=48; - } - //print $type.'-'.$size; - $out=$value; - return $out; - } + $label=$this->attribute_label[$key]; + $type=$this->attribute_type[$key]; + $size=$this->attribute_size[$key]; + $elementtype=$this->attribute_elementtype[$key]; + $unique=$this->attribute_unique[$key]; + $required=$this->attribute_required[$key]; + $params=$this->attribute_param[$key]; + if ($type == 'date') + { + $showsize=10; + $value=dol_print_date($value,'day'); + } + elseif ($type == 'datetime') + { + $showsize=19; + $value=dol_print_date($value,'dayhour'); + } + elseif ($type == 'int') + { + $showsize=10; + } + elseif ($type == 'boolean') + { + $checked=''; + if (!empty($value)) { + $checked=' checked="checked" '; + } + $value=''; + } + elseif ($type == 'mail') + { + $value=dol_print_email($value); + } + elseif ($type == 'phone') + { + $value=dol_print_phone($value); + } + elseif ($type == 'price') + { + $value=price($value).' '.$langs->getCurrencySymbol($conf->currency); + } + elseif ($type == 'select') + { + $value=$params['options'][$value]; + } + elseif ($type == 'sellist') + { + $InfoFieldList = explode(":", $params); + $keyList='rowid'; + if (count($InfoFieldList)==3) + $keyList=$InfoFieldList[2]; - /** - * Return HTML string to print separator extrafield - * - * @param string $key Key of attribute - * @return string - */ - function showSeparator($key) - { - $out = ''.$this->attribute_label[$key].''; - return $out; - } - - /** - * Fill array_options array for object by extrafields value (using for data send by forms) - * - * @param array $extralabels $array of extrafields - * @param object &$object object - * @return int 1 if array_options set / 0 if no value - */ - function setOptionalsFromPost($extralabels,&$object) - { - global $_POST; - - if (is_array($extralabels)) - { - // Get extra fields - foreach ($extralabels as $key => $value) - { - $key_type = $this->attribute_type[$key]; - - if (in_array($key_type,array('date','datetime'))) - { - // Clean parameters - $value_key=dol_mktime($_POST["options_".$key."hour"], $_POST["options_".$key."min"], 0, $_POST["options_".$key."month"], $_POST["options_".$key."day"], $_POST["options_".$key."year"]); - } - else if (in_array($key_type,array('checkbox'))) - { - $value_arr=GETPOST("options_".$key); - $value_key=implode($value_arr,','); - } - else - { - $value_key=GETPOST("options_".$key); - } - $object->array_options["options_".$key]=$value_key; - } - - return 1; - } - else { - return 0; - } - } + $sql = 'SELECT '.$InfoFieldList[1]; + $sql.= ' FROM '.MAIN_DB_PREFIX .$InfoFieldList[0]; + $sql.= ' where '.$keyList.'="'.$value.'"'; + + $resql = $this->db->query($sql); + if ($resql) + { + $obj = $this->db->fetch_object($resql); + $value=$obj->$InfoFieldList[1]; + } + } + elseif ($type == 'radio') + { + $value=$params['options'][$value]; + } + elseif ($type == 'checkbox') + { + $value_arr=explode(',',$value); + $value=''; + if (is_array($value_arr)) + { + foreach ($value_arr as $keyval=>$valueval) { + $value.=$params['options'][$valueval].'
'; + } + } + } + else + { + $showsize=round($size); + if ($showsize > 48) $showsize=48; + } + //print $type.'-'.$size; + $out=$value; + return $out; + } + + /** + * Return HTML string to print separator extrafield + * + * @param string $key Key of attribute + * @return string + */ + function showSeparator($key) + { + $out = ''.$this->attribute_label[$key].''; + return $out; + } + + /** + * Fill array_options array for object by extrafields value (using for data send by forms) + * + * @param array $extralabels $array of extrafields + * @param object &$object object + * @return int 1 if array_options set / 0 if no value + */ + function setOptionalsFromPost($extralabels,&$object) + { + global $_POST; + + if (is_array($extralabels)) + { + // Get extra fields + foreach ($extralabels as $key => $value) + { + $key_type = $this->attribute_type[$key]; + + if (in_array($key_type,array('date','datetime'))) + { + // Clean parameters + $value_key=dol_mktime($_POST["options_".$key."hour"], $_POST["options_".$key."min"], 0, $_POST["options_".$key."month"], $_POST["options_".$key."day"], $_POST["options_".$key."year"]); + } + else if (in_array($key_type,array('checkbox'))) + { + $value_arr=GETPOST("options_".$key); + $value_key=implode($value_arr,','); + } + else + { + $value_key=GETPOST("options_".$key); + } + $object->array_options["options_".$key]=$value_key; + } + + return 1; + } + else { + return 0; + } + } } ?> diff --git a/htdocs/core/class/hookmanager.class.php b/htdocs/core/class/hookmanager.class.php index 0284872cb92..6deb0161c2a 100755 --- a/htdocs/core/class/hookmanager.class.php +++ b/htdocs/core/class/hookmanager.class.php @@ -144,7 +144,6 @@ class HookManager foreach($modules as $module => $actionclassinstance) { //print 'class='.get_class($actionclassinstance).' method='.$method.' action='.$action; - // jump to next class if method does not exists if (! method_exists($actionclassinstance,$method)) continue; // test to avoid to run twice a hook, when a module implements several active contexts @@ -178,7 +177,7 @@ class HookManager $result = $actionclassinstance->$method($parameters, $object, $action, $this); // $object and $action can be changed by method ($object->id during creation for example or $action to go back to other action for example) - if (is_array($actionclassinstance->results)) $this->resArray =array_merge($this->resArray, $actionclassinstance->results); + if (! empty($actionclassinstance->results) && is_array($actionclassinstance->results)) $this->resArray =array_merge($this->resArray, $actionclassinstance->results); if (! empty($actionclassinstance->resprints)) $this->resPrint.=$actionclassinstance->resprints; // TODO. remove this. array result must be set into $actionclassinstance->results diff --git a/htdocs/core/class/html.form.class.php b/htdocs/core/class/html.form.class.php index ae60706f523..97658572831 100644 --- a/htdocs/core/class/html.form.class.php +++ b/htdocs/core/class/html.form.class.php @@ -344,7 +344,7 @@ class Form * Show a text and picto with tooltip on text or picto * * @param string $text Text to show - * @param string $htmltext Content html of tooltip. Must be HTML/UTF8 encoded. + * @param string $htmltext HTML content of tooltip. Must be HTML/UTF8 encoded. * @param int $tooltipon 1=tooltip sur texte, 2=tooltip sur picto, 3=tooltip sur les 2 * @param int $direction -1=Le picto est avant, 0=pas de picto, 1=le picto est apres * @param string $img Code img du picto (use img_xxx() function to get it) @@ -383,7 +383,7 @@ class Form //if ($text != '') $s.='<'.$tag.$paramfortooltiptd.'>'.(($direction < 0)?' ':'').$text.(($direction > 0)?' ':'').''; $paramfortooltiptd.= (($direction < 0)?' style="padding-left: 3px !important;"':''); $paramfortooltiptd.= (($direction > 0)?' style="padding-right: 3px !important;"':''); - if ($text != '') $s.='<'.$tag.$paramfortooltiptd.'>'.$text.''; + if ((string) $text != '') $s.='<'.$tag.$paramfortooltiptd.'>'.$text.''; if ($direction > 0) $s.='<'.$tag.$paramfortooltipimg.' valign="top" width="14">'.$img.''; if (empty($notabs)) $s.=''; @@ -3333,7 +3333,7 @@ class Form if (strval($set_time) != '' && $set_time != -1) { //$formated_date=dol_print_date($set_time,$conf->format_date_short); - $formated_date=dol_print_date($set_time,$langs->trans("FormatDateShort")); // FormatDateShort for dol_print_date/FormatDateShortJava that is same for javascript + $formated_date=dol_print_date($set_time,$langs->trans("FormatDateShortInput")); // FormatDateShortInput for dol_print_date / FormatDateShortJavaInput that is same for javascript } // Calendrier popup version eldy @@ -3342,7 +3342,7 @@ class Form // Zone de saisie manuelle de la date $retstring.='trans("FormatDateShortJava").'\'); "'; // FormatDateShort for dol_print_date/FormatDateShortJava that is same for javascript + $retstring.=' onChange="dpChangeDay(\''.$prefix.'\',\''.$langs->trans("FormatDateShortJavaInput").'\'); "'; // FormatDateShortInput for dol_print_date / FormatDateShortJavaInput that is same for javascript $retstring.='>'; // Icone calendrier @@ -3350,7 +3350,7 @@ class Form { $retstring.=''; + $retstring.=' onClick="showDP(\''.$base.'\',\''.$prefix.'\',\''.$langs->trans("FormatDateShortJavaInput").'\',\''.$langs->defaultlang.'\');">'.img_object($langs->trans("SelectDate"),'calendarday','class="datecallink"').''; } else $retstring.=''; @@ -3359,7 +3359,7 @@ class Form $retstring.=''."\n"; } else - { + { print "Bad value of MAIN_POPUP_CALENDAR"; } } @@ -3453,7 +3453,7 @@ class Form if ($usecalendar == "eldy") { $base=DOL_URL_ROOT.'/core/'; - $reset_scripts .= 'resetDP(\''.$base.'\',\''.$prefix.'\',\''.$langs->trans("FormatDateShortJava").'\',\''.$langs->defaultlang.'\');'; + $reset_scripts .= 'resetDP(\''.$base.'\',\''.$prefix.'\',\''.$langs->trans("FormatDateShortJavaInput").'\',\''.$langs->defaultlang.'\');'; } else { diff --git a/htdocs/core/class/html.formactions.class.php b/htdocs/core/class/html.formactions.class.php index 827a65ed51f..b7477c203f5 100644 --- a/htdocs/core/class/html.formactions.class.php +++ b/htdocs/core/class/html.formactions.class.php @@ -209,10 +209,10 @@ class FormActions /** * Output list of type of event * - * @param string $selected Type pre-selectionne + * @param string $selected Type pre-selected (can be 'manual', 'auto' or 'AC_xxx' * @param string $htmlname Nom champ formulaire * @param string $excludetype Type to exclude - * @param string $onlyautoornot Group list by auto events or not + * @param string $onlyautoornot Group list by auto events or not: We keep only the 2 generic lines (AC_OTH and AC_OTH_AUTO) * @return void */ function select_type_actions($selected='',$htmlname='actioncode',$excludetype='',$onlyautoornot=0) @@ -224,11 +224,14 @@ class FormActions $caction=new CActionComm($this->db); $form=new Form($this->db); - // Suggest a list with manual event or all auto events + // Suggest a list with manual events or all auto events $arraylist=$caction->liste_array(1, 'code', $excludetype, $onlyautoornot); array_unshift($arraylist,' '); // Add empty line at start //asort($arraylist); + if ($selected == 'manual') $selected='AC_OTH'; + if ($selected == 'auto') $selected='AC_OTH_AUTO'; + print $form->selectarray($htmlname, $arraylist, $selected); if ($user->admin && empty($onlyautoornot)) print info_admin($langs->trans("YouCanChangeValuesForThisListFromDictionnarySetup"),1); } diff --git a/htdocs/core/class/html.formfile.class.php b/htdocs/core/class/html.formfile.class.php index 71541ab4a5d..699977c05ff 100644 --- a/htdocs/core/class/html.formfile.class.php +++ b/htdocs/core/class/html.formfile.class.php @@ -480,10 +480,10 @@ class FormFile // Show file name with link to download $out.= ''; - $out.= 'trans("File").': '.$file["name"]).' '.dol_trunc($file["name"],$maxfilenamelength); $out.= ''."\n"; $out.= ''; @@ -575,7 +575,7 @@ class FormFile } // Show file name with link to download - $out.= ''; print ''; //print "XX".$file['name']; //$file['name'] must be utf8 - print ''; @@ -855,7 +855,7 @@ class FormFile print ''; print ''; //print "XX".$file['name']; //$file['name'] must be utf8 - print ''; print img_mime($file['name'],$file['name'].' ('.dol_print_size($file['size'],0,0).')').' '; @@ -865,7 +865,7 @@ class FormFile print ''.dol_print_size($file['size'],1,1).''; print ''.dol_print_date($file['date'],"dayhour").''; print ''; - if (! empty($useinecm)) print ''; print img_view().'   '; diff --git a/htdocs/core/class/html.formother.class.php b/htdocs/core/class/html.formother.class.php index 3de291bbe76..a0d63e42b4a 100644 --- a/htdocs/core/class/html.formother.class.php +++ b/htdocs/core/class/html.formother.class.php @@ -893,9 +893,34 @@ class FormOther $selectboxlist=$form->selectarray('boxcombo', $arrayboxtoactivatelabel,'',1); } + // Javascript code for dynamic actions if (! empty($conf->use_javascript_ajax)) { print ''; + if (! count($arrayboxtoactivatelabel)) print 'jQuery("#boxcombo").hide();'; + print ' + + jQuery("#left, #right").sortable({ + /* placeholder: \'ui-state-highlight\', */ + handle: \'.boxhandle\', + revert: \'invalid\', + items: \'.box\', + containment: \'.fiche\', + connectWith: \'.connectedSortable\', + stop: function(event, ui) { + updateBoxOrder(0); + } + }); + + jQuery(".boxclose").click(function() { + var self = this; // because JQuery can modify this + var boxid=self.id.substring(8); + var label=jQuery(\'#boxlabelentry\'+boxid).val(); + jQuery(\'#boxto_\'+boxid).remove(); + // TODO Add id, label into combo list + updateBoxOrder(1); + }); + + });'."\n"; + + print ''."\n"; } $nbboxactivated=count($boxidactivatedforuser); @@ -996,59 +1044,6 @@ class FormOther print ""; print ""; - - if ($conf->use_javascript_ajax) - { - print "\n"; - print ''."\n"; - } } return count($boxactivated); diff --git a/htdocs/core/datepicker.php b/htdocs/core/datepicker.php index 76b8dbb4b79..a976eb83f01 100644 --- a/htdocs/core/datepicker.php +++ b/htdocs/core/datepicker.php @@ -224,16 +224,16 @@ function displayBox($selectedDate,$month,$year) if($thedate==$selDate) $dayclass="dpSelected"; elseif($thedate==$today) $dayclass="dpToday"; - if ($langs->trans("FormatDateShortJava")=="FormatDateShortJava") + if ($langs->trans("FormatDateShortJavaInput")=="FormatDateShortJavaInput") { - print "ERROR FormatDateShortJava not defined for language ".$langs->defaultlang; + print "ERROR FormatDateShortJavaInput not defined for language ".$langs->defaultlang; exit; } // Sur click dans calendrier, appelle fonction dpClickDay echo "trans("FormatDateShortJava")."')\""; + echo " onClick=\"dpClickDay(".$mydate["year"].",parseInt('".dol_print_date($thedate,"%m")."',10),".$mydate["mday"].",'".$langs->trans("FormatDateShortJavaInput")."')\""; echo ">".sprintf("%02s",$mydate["mday"]).""; $cols++; diff --git a/htdocs/core/get_menudiv.php b/htdocs/core/get_menudiv.php index 0d9e3c0a54b..51bda89ffd0 100644 --- a/htdocs/core/get_menudiv.php +++ b/htdocs/core/get_menudiv.php @@ -40,11 +40,6 @@ $langs->load("main"); $right=($langs->trans("DIRECTION")=='rtl'?'left':'right'); $left=($langs->trans("DIRECTION")=='rtl'?'right':'left'); -//var_dump($langs->defaultlang); -//var_dump($conf->format_date_short_java); -//var_dump($langs->trans("FormatDateShortJava")); - - /* * View diff --git a/htdocs/core/lib/agenda.lib.php b/htdocs/core/lib/agenda.lib.php index 531ea49eb96..a11fdac4dda 100644 --- a/htdocs/core/lib/agenda.lib.php +++ b/htdocs/core/lib/agenda.lib.php @@ -40,9 +40,10 @@ * @param int $pid Product id * @param int $socid Third party id * @param array $showextcals Array with list of external calendars, or -1 to show no legend + * @param string $actioncode Preselected value of actioncode for filter on type * @return void */ -function print_actions_filter($form,$canedit,$status,$year,$month,$day,$showbirthday,$filtera,$filtert,$filterd,$pid,$socid,$showextcals=array()) +function print_actions_filter($form,$canedit,$status,$year,$month,$day,$showbirthday,$filtera,$filtert,$filterd,$pid,$socid,$showextcals=array(),$actioncode='') { global $conf,$user,$langs,$db; @@ -94,8 +95,7 @@ function print_actions_filter($form,$canedit,$status,$year,$month,$day,$showbirt print $langs->trans("Type"); print '  '; - // print $formactions->select_type_actions(GETPOST('actioncode'), "actioncode"); - print $formactions->select_type_actions(GETPOST('actioncode')?GETPOST('actioncode'):'manual', "actioncode", '', (empty($conf->global->AGENDA_USE_EVENT_TYPE)?1:0)); + print $formactions->select_type_actions($actioncode, "actioncode", '', (empty($conf->global->AGENDA_USE_EVENT_TYPE)?1:0)); print ''; } @@ -384,6 +384,11 @@ function agenda_prepare_head() $head[$h][2] = 'extsites'; $h++; + $head[$h][0] = DOL_URL_ROOT."/admin/agenda_other.php"; + $head[$h][1] = $langs->trans("Other"); + $head[$h][2] = 'other'; + $h++; + complete_head_from_modules($conf,$langs,$object,$head,$h,'agenda_admin'); $head[$h][0] = DOL_URL_ROOT."/admin/agenda_extrafields.php"; diff --git a/htdocs/core/lib/company.lib.php b/htdocs/core/lib/company.lib.php index d01c0456250..695b6deb2c1 100644 --- a/htdocs/core/lib/company.lib.php +++ b/htdocs/core/lib/company.lib.php @@ -47,7 +47,7 @@ function societe_prepare_head($object) { $head[$h][0] = DOL_URL_ROOT.'/comm/fiche.php?socid='.$object->id; if (empty($conf->global->SOCIETE_DISABLE_PROSPECTS) && ($object->client==2 || $object->client==3)) $head[$h][1] = $langs->trans("Prospect"); - if ($object->client==3) $head[$h][1] .= '/'; + if (empty($conf->global->SOCIETE_DISABLE_PROSPECTS) && empty($conf->global->SOCIETE_DISABLE_CUSTOMERS) && $object->client==3) $head[$h][1] .= '/'; if (empty($conf->global->SOCIETE_DISABLE_CUSTOMERS) && ($object->client==1 || $object->client==3)) $head[$h][1] .= $langs->trans("Customer"); $head[$h][2] = 'customer'; $h++; diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index 7ea8087613e..b2c2998a462 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -814,13 +814,14 @@ function dol_print_date($time,$format='',$tzoutput='tzserver',$outputlangs='',$e } if (! is_object($outputlangs)) $outputlangs=$langs; if (! $format) $format='daytextshort'; - + $reduceformat=(! empty($conf->dol_optimize_smallscreen) && in_array($format,array('day','hour')))?1:0; + // Change predefined format into computer format. If found translation in lang file we use it, otherwise we use default. - if ($format == 'day') $format=($outputlangs->trans("FormatDateShort")!="FormatDateShort"?$outputlangs->trans("FormatDateShort"):$conf->format_date_short); - else if ($format == 'hour') $format=($outputlangs->trans("FormatHourShort")!="FormatHourShort"?$outputlangs->trans("FormatHourShort"):$conf->format_hour_short); - else if ($format == 'hourduration') $format=($outputlangs->trans("FormatHourShortDuration")!="FormatHourShortDuration"?$outputlangs->trans("FormatHourShortDuration"):$conf->format_hour_short_duration); + if ($format == 'day') $format=($outputlangs->trans("FormatDateShort")!="FormatDateShort"?$outputlangs->trans("FormatDateShort"):$conf->format_date_short); + else if ($format == 'hour') $format=($outputlangs->trans("FormatHourShort")!="FormatHourShort"?$outputlangs->trans("FormatHourShort"):$conf->format_hour_short); + else if ($format == 'hourduration') $format=($outputlangs->trans("FormatHourShortDuration")!="FormatHourShortDuration"?$outputlangs->trans("FormatHourShortDuration"):$conf->format_hour_short_duration); else if ($format == 'daytext') $format=($outputlangs->trans("FormatDateText")!="FormatDateText"?$outputlangs->trans("FormatDateText"):$conf->format_date_text); - else if ($format == 'daytextshort') $format=($outputlangs->trans("FormatDateTextShort")!="FormatDateTextShort"?$outputlangs->trans("FormatDateTextShort"):$conf->format_date_text_short); + else if ($format == 'daytextshort') $format=($outputlangs->trans("FormatDateTextShort")!="FormatDateTextShort"?$outputlangs->trans("FormatDateTextShort"):$conf->format_date_text_short); else if ($format == 'dayhour') $format=($outputlangs->trans("FormatDateHourShort")!="FormatDateHourShort"?$outputlangs->trans("FormatDateHourShort"):$conf->format_date_hour_short); else if ($format == 'dayhoursec') $format=($outputlangs->trans("FormatDateHourSecShort")!="FormatDateHourSecShort"?$outputlangs->trans("FormatDateHourSecShort"):$conf->format_date_hour_sec_short); else if ($format == 'dayhourtext') $format=($outputlangs->trans("FormatDateHourText")!="FormatDateHourText"?$outputlangs->trans("FormatDateHourText"):$conf->format_date_hour_text); @@ -828,12 +829,18 @@ function dol_print_date($time,$format='',$tzoutput='tzserver',$outputlangs='',$e // Format not sensitive to language else if ($format == 'dayhourlog') $format='%Y%m%d%H%M%S'; else if ($format == 'dayhourldap') $format='%Y%m%d%H%M%SZ'; - else if ($format == 'dayhourxcard') $format='%Y%m%dT%H%M%SZ'; - else if ($format == 'dayxcard') $format='%Y%m%d'; + else if ($format == 'dayhourxcard') $format='%Y%m%dT%H%M%SZ'; + else if ($format == 'dayxcard') $format='%Y%m%d'; else if ($format == 'dayrfc') $format='%Y-%m-%d'; // DATE_RFC3339 else if ($format == 'dayhourrfc') $format='%Y-%m-%dT%H:%M:%SZ'; // DATETIME RFC3339 - else if ($format == 'standard') $format='%Y-%m-%d %H:%M:%S'; + else if ($format == 'standard') $format='%Y-%m-%d %H:%M:%S'; + if ($reduceformat) + { + $format=str_replace('%Y','%y',$format); + $format=str_replace('yyyy','yy',$format); + } + // If date undefined or "", we return "" if (dol_strlen($time) == 0) return ''; // $time=0 allowed (it means 01/01/1970 00:00:00) @@ -1072,9 +1079,11 @@ function dol_now($mode='gmt') */ function dol_print_size($size,$shortvalue=0,$shortunit=0) { - global $langs; + global $conf,$langs; $level=1024; - + + if (! empty($conf->dol_optimize_smallscreen)) $shortunit=1; + // Set value text if (empty($shortvalue) || $size < ($level*10)) { @@ -2846,7 +2855,7 @@ function getLocalTaxesFromRate($vatrate, $local, $thirdparty) dol_syslog("getLocalTaxesFromRate vatrate=".$vatrate." local=".$local." thirdparty id=".(is_object($thirdparty)?$thirdparty->id:'')); // Search local taxes - $sql = "SELECT t.localtax1, t.localtax1_type, t.localtax2, t.localtax2_type"; + $sql = "SELECT t.localtax1, t.localtax1_type, t.localtax2, t.localtax2_type,t.accountancy_code_sell,t.accountancy_code_buy"; $sql .= " FROM ".MAIN_DB_PREFIX."c_tva as t, ".MAIN_DB_PREFIX."c_pays as p"; $sql .= " WHERE t.fk_pays = p.rowid AND p.code = '".$thirdparty->country_code."'"; $sql .= " AND t.taux = ".$vatrate." AND t.active = 1"; @@ -2855,9 +2864,9 @@ function getLocalTaxesFromRate($vatrate, $local, $thirdparty) if ($resql) { $obj = $db->fetch_object($resql); - if ($local == 1) return array($obj->localtax1_type, $obj->localtax1); - elseif ($local == 2) return array($obj->localtax2_type, $obj->localtax2); - else return array($obj->localtax1_type, $obj->localtax1, $obj->localtax2_type, $obj->localtax2); + if ($local == 1) return array($obj->localtax1_type, $obj->localtax1,$obj->accountancy_code_sell,$obj->accountancy_code_buy); + elseif ($local == 2) return array($obj->localtax2_type, $obj->localtax2,$obj->accountancy_code_sell,$obj->accountancy_code_buy); + else return array($obj->localtax1_type, $obj->localtax1, $obj->localtax2_type, $obj->localtax2,$obj->accountancy_code_sell,$obj->accountancy_code_buy); } return 0; @@ -3105,12 +3114,16 @@ function get_default_npr($thirdparty_seller, $thirdparty_buyer, $idprod=0, $idpr if ($idprodfournprice > 0) { + if (! class_exists('ProductFournisseur')) + require DOL_DOCUMENT_ROOT . '/fourn/class/fournisseur.product.class.php'; $prodprice = new ProductFournisseur($db); $prodprice->fetch_product_fournisseur_price($idprodfournprice); return $prodprice->fourn_tva_npr; } elseif ($idprod > 0) { + if (! class_exists('Product')) + require DOL_DOCUMENT_ROOT . '/product/class/product.class.php'; $prod = new Product($db); $prod->fetch($idprod); return $prod->tva_npr; diff --git a/htdocs/core/lib/functions2.lib.php b/htdocs/core/lib/functions2.lib.php index 059400d7399..dc6c57002c9 100644 --- a/htdocs/core/lib/functions2.lib.php +++ b/htdocs/core/lib/functions2.lib.php @@ -1283,7 +1283,7 @@ function getListOfModels($db,$type,$maxfilenamelength=0) if (! $tmpdir) { unset($listofdir[$key]); continue; } if (is_dir($tmpdir)) { - $tmpfiles=dol_dir_list($tmpdir,'files',0,'\.odt','','name',SORT_ASC,0,true); // Disable hook for the moment + $tmpfiles=dol_dir_list($tmpdir,'files',0,'\.od(s|t)$','','name',SORT_ASC,0,true); // Disable hook for the moment if (count($tmpfiles)) $listoffiles=array_merge($listoffiles,$tmpfiles); } } diff --git a/htdocs/core/lib/usergroups.lib.php b/htdocs/core/lib/usergroups.lib.php index b9f12ca3f6c..10099ab7feb 100644 --- a/htdocs/core/lib/usergroups.lib.php +++ b/htdocs/core/lib/usergroups.lib.php @@ -78,14 +78,15 @@ function user_prepare_head($object) $head[$h][2] = 'clicktodial'; $h++; } - + // Show more tabs from modules // Entries must be declared in modules descriptor with line // $this->tabs = array('entity:+tabname:Title:@mymodule:/mymodule/mypage.php?id=__ID__'); to add new tab // $this->tabs = array('entity:-tabname); to remove a tab complete_head_from_modules($conf,$langs,$object,$head,$h,'user'); - - if (! empty($user->societe_id)) + + //Info on users is visible only by internal user + if (empty($user->societe_id)) { $head[$h][0] = DOL_URL_ROOT.'/user/note.php?id='.$object->id; $head[$h][1] = $langs->trans("Note"); diff --git a/htdocs/core/menus/standard/eldy.lib.php b/htdocs/core/menus/standard/eldy.lib.php index 641925f42a9..f4d7f3581db 100644 --- a/htdocs/core/menus/standard/eldy.lib.php +++ b/htdocs/core/menus/standard/eldy.lib.php @@ -852,6 +852,8 @@ function print_left_eldy_menu($db,$menu_array_before,$menu_array_after,&$tabMenu */ if (empty($leftmenu) || $leftmenu=="ca") $newmenu->add("/compta/stats/casoc.php?leftmenu=ca",$langs->trans("ByCompanies"),2,$user->rights->compta->resultat->lire||$user->rights->accounting->comptarapport->lire); if (empty($leftmenu) || $leftmenu=="ca") $newmenu->add("/compta/stats/cabyuser.php?leftmenu=ca",$langs->trans("ByUsers"),2,$user->rights->compta->resultat->lire||$user->rights->accounting->comptarapport->lire); + if (empty($leftmenu) || $leftmenu=="ca") $newmenu->add("/compta/stats/cabyprodserv.php?leftmenu=ca", $langs->trans("ByProductsAndServices"),2,$user->rights->compta->resultat->lire||$user->rights->accounting->comptarapport->lire); + // Journaux //if ($leftmenu=="ca") $newmenu->add("/compta/journaux/index.php?leftmenu=ca",$langs->trans("Journaux"),1,$user->rights->compta->resultat->lire||$user->rights->accounting->comptarapport->lire); diff --git a/htdocs/core/modules/commande/doc/doc_generic_order_odt.modules.php b/htdocs/core/modules/commande/doc/doc_generic_order_odt.modules.php index 00658b7b9cb..3330f491e70 100644 --- a/htdocs/core/modules/commande/doc/doc_generic_order_odt.modules.php +++ b/htdocs/core/modules/commande/doc/doc_generic_order_odt.modules.php @@ -519,8 +519,12 @@ class doc_generic_order_odt extends ModelePDFCommandes $reshook=$hookmanager->executeHooks('beforeODTSave',$parameters,$this,$action); // Note that $action and $object may have been modified by some hooks // Write new file - //$result=$odfHandler->exportAsAttachedFile('toto'); - $odfHandler->saveToDisk($file); + if (!empty($conf->global->MAIN_ODT_AS_PDF)) { + $odfHandler->exportAsAttachedPDF($file); + } + else { + $odfHandler->saveToDisk($file); + } if (! empty($conf->global->MAIN_UMASK)) @chmod($file, octdec($conf->global->MAIN_UMASK)); diff --git a/htdocs/core/modules/expedition/methode_expedition.modules.php b/htdocs/core/modules/expedition/methode_expedition.modules.php deleted file mode 100644 index 3ea7ba97ce9..00000000000 --- a/htdocs/core/modules/expedition/methode_expedition.modules.php +++ /dev/null @@ -1,68 +0,0 @@ - - * Copyright (C) 2007 Laurent Destailleur - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * or see http://www.gnu.org/ - */ - -/** - * \file htdocs/core/modules/expedition/methode_expedition.modules.php - * \ingroup expedition - * \brief Fichier contenant la classe mere de generation de bon de livraison en PDF - * et la classe mere de numerotation des bons de livraisons - */ -require_once DOL_DOCUMENT_ROOT.'/core/lib/pdf.lib.php'; - - -/** - * Parent class for shipping method classes - */ -class ModeleShippingMethod -{ - /** - * Constructo - * - * @param DoliDB $db Database handler - */ - function __construct($db) - { - $this->db = $db; - $this->name = "NOT DEFINED"; - $this->description = "ERROR IN MODULE DESCRIPTION"; - } - - - /** - * Return list of active generation modules - * - * @param DoliDB $db Database handler - * @param string $maxfilenamelength Max length of value to show - * @return array List of templates - */ - static function liste_modeles($db,$maxfilenamelength=0) - { - global $conf; - - $type='???'; - $liste=array(); - - include_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php'; - $liste=getListOfModels($db,$type,$maxfilenamelength); - - return $liste; - } -} - -?> diff --git a/htdocs/core/modules/expedition/methode_expedition_colsui.modules.php b/htdocs/core/modules/expedition/methode_expedition_colsui.modules.php deleted file mode 100644 index fca7ffc38ff..00000000000 --- a/htdocs/core/modules/expedition/methode_expedition_colsui.modules.php +++ /dev/null @@ -1,56 +0,0 @@ - - * Copyright (C) 2008 Bearstech - http://bearstech.com/ - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -/** - * \file htdocs/core/modules/expedition/methode_expedition_colsui.modules.php - * \ingroup expedition - */ -include_once 'methode_expedition.modules.php'; - -/** - * Class to manage shipment Colsui - */ -class methode_expedition_colsui extends ModeleShippingMethod -{ - /** - * Constructor - * - * @param DoliDB $db Database handler - */ - function __construct($db=0) - { - $this->db = $db; - $this->id = 3; // Do not change this value - $this->code = "COLSUI"; // Do not change this value - $this->name = "Colissimo Suivi"; - $this->description = "Colissimo Suivi"; - } - - /** - * Return URL of provider - * - * @param string $tracking_number Tracking number - * @return string URL for tracking - */ - function provider_url_status($tracking_number) - { - return sprintf("http://www.coliposte.net/particulier/suivi_particulier.jsp?colispart=%s",$tracking_number); - } -} - -?> diff --git a/htdocs/core/modules/expedition/methode_expedition_enl.modules.php b/htdocs/core/modules/expedition/methode_expedition_enl.modules.php deleted file mode 100644 index 17e5cf35be9..00000000000 --- a/htdocs/core/modules/expedition/methode_expedition_enl.modules.php +++ /dev/null @@ -1,57 +0,0 @@ - - * - * 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/core/modules/expedition/methode_expedition_enl.modules.php - * \ingroup expedition - */ -include_once 'methode_expedition.modules.php'; - - -/** - * Class to manage shipment Enl - */ -class methode_expedition_enl extends ModeleShippingMethod -{ - /** - * Constructor - * - * @param DoliDB $db Database handler - */ - function __construct($db=0) - { - global $langs; - $this->db = $db; - $this->id = 1; // Do not change this value - $this->name = "Enlevement"; - $this->code = "ENL"; - $this->description = $langs->trans("Enlevement"); - } - - /** - * Return URL of provider - * - * @param string $tracking_number Tracking number - * @return string URL for tracking - */ - function provider_url_status($tracking_number) - { - return ''; - } -} - -?> diff --git a/htdocs/core/modules/expedition/methode_expedition_lettremax.modules.php b/htdocs/core/modules/expedition/methode_expedition_lettremax.modules.php deleted file mode 100644 index c8150af9497..00000000000 --- a/htdocs/core/modules/expedition/methode_expedition_lettremax.modules.php +++ /dev/null @@ -1,57 +0,0 @@ - - * - * 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/core/modules/expedition/methode_expedition_lettremax.modules.php - * \ingroup expedition - */ - -include_once 'methode_expedition.modules.php'; - - -/** - * Class to manage shipment lettremax - */ -class methode_expedition_lettremax extends ModeleShippingMethod -{ - /** - * Constructor - * - * @param DoliDB $db Database handler - */ - function __construct($db=0) - { - $this->db = $db; - $this->id = 4; // Do not change this value - $this->code = "LETTREMAX"; // Do not change this value - $this->name = "Lettre max"; - $this->description = "Courrier suivi et lettre max"; - } - - /** - * Return URL of provider - * - * @param string $tracking_number Tracking number - * @return string URL for tracking - */ - function provider_url_status($tracking_number) - { - return sprintf("http://www.csuivi.courrier.laposte.fr/default.asp?EZ_ACTION=rechercheRapide&numObjet=%s",$tracking_number); - } -} - -?> diff --git a/htdocs/core/modules/expedition/methode_expedition_trans.modules.php b/htdocs/core/modules/expedition/methode_expedition_trans.modules.php deleted file mode 100644 index d974b7c161a..00000000000 --- a/htdocs/core/modules/expedition/methode_expedition_trans.modules.php +++ /dev/null @@ -1,59 +0,0 @@ - - * - * 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/core/modules/expedition/methode_expedition_trans.modules.php - * \ingroup expedition - */ -include_once 'methode_expedition.modules.php'; - - -/** - * Class to manage shipment Trans - */ -class methode_expedition_trans extends ModeleShippingMethod -{ - - /** - * Constructor - * - * @param DoliDB $db Database handler - */ - function __construct($db=0) - { - global $langs; - - $this->db = $db; - $this->id = 2; // Ne pas changer cette valeur - $this->code = "TRANS"; - $this->name = "Transporteur"; - $this->description = $langs->trans("GenericTransport"); - } - - /** - * Return URL of provider - * - * @param string $tracking_number Tracking number - * @return string URL for tracking - */ - function provider_url_status($tracking_number) - { - return ''; - } -} - -?> diff --git a/htdocs/core/modules/facture/doc/doc_generic_invoice_odt.modules.php b/htdocs/core/modules/facture/doc/doc_generic_invoice_odt.modules.php index 512bf98be8b..8aa417c83c0 100644 --- a/htdocs/core/modules/facture/doc/doc_generic_invoice_odt.modules.php +++ b/htdocs/core/modules/facture/doc/doc_generic_invoice_odt.modules.php @@ -497,8 +497,12 @@ class doc_generic_invoice_odt extends ModelePDFFactures $reshook=$hookmanager->executeHooks('beforeODTSave',$parameters,$this,$action); // Note that $action and $object may have been modified by some hooks // Write new file - //$result=$odfHandler->exportAsAttachedFile('toto'); - $odfHandler->saveToDisk($file); + if (!empty($conf->global->MAIN_ODT_AS_PDF)) { + $odfHandler->exportAsAttachedPDF($file); + } + else { + $odfHandler->saveToDisk($file); + } if (! empty($conf->global->MAIN_UMASK)) @chmod($file, octdec($conf->global->MAIN_UMASK)); diff --git a/htdocs/core/modules/livraison/pdf/pdf_typhon.modules.php b/htdocs/core/modules/livraison/pdf/pdf_typhon.modules.php index c4a1150d505..adf1b8689b1 100644 --- a/htdocs/core/modules/livraison/pdf/pdf_typhon.modules.php +++ b/htdocs/core/modules/livraison/pdf/pdf_typhon.modules.php @@ -38,6 +38,22 @@ require_once DOL_DOCUMENT_ROOT.'/core/lib/pdf.lib.php'; */ class pdf_typhon extends ModelePDFDeliveryOrder { + var $db; + var $name; + var $description; + var $type; + + var $phpmin = array(4,3,0); // Minimum version of PHP required by module + var $version = 'dolibarr'; + + var $page_largeur; + var $page_hauteur; + var $format; + var $marge_gauche; + var $marge_droite; + var $marge_haute; + var $marge_basse; + var $emetteur; // Objet societe qui emet /** @@ -75,26 +91,26 @@ class pdf_typhon extends ModelePDFDeliveryOrder $this->franchise=!$mysoc->tva_assuj; - // Recupere emmetteur + // Get source company $this->emetteur=$mysoc; - if (! $this->emetteur->country_code) $this->emetteur->country_code=substr($langs->defaultlang,-2); // By default if not defined + if (empty($this->emetteur->country_code)) $this->emetteur->country_code=substr($langs->defaultlang,-2); // By default, if was not defined - // Defini position des colonnes + // Define position of columns $this->posxdesc=$this->marge_gauche+1; - $this->posxcomm=120; + $this->posxcomm=111; //$this->posxtva=111; - $this->posxup=132; - $this->posxqty=168; - $this->posxdiscount=162; - $this->postotalht=177; + //$this->posxup=126; + $this->posxqty=174; + //$this->posxdiscount=162; + //$this->postotalht=174; if ($this->page_largeur < 210) // To work with US executive format { $this->posxcomm-=20; //$this->posxtva-=20; - $this->posxup-=20; + //$this->posxup-=20; $this->posxqty-=20; - $this->posxdiscount-=20; - $this->postotalht-=20; + //$this->posxdiscount-=20; + //$this->postotalht-=20; } $this->tva=array(); @@ -104,15 +120,19 @@ class pdf_typhon extends ModelePDFDeliveryOrder /** - * Fonction generant le bon de livraison sur le disque - * - * @param Object $object Object livraison a generer - * @param Translate $outputlangs Lang output object - * @return int 1 if OK, <=0 if KO + * Function to build pdf onto disk + * + * @param Object $object Object to generate + * @param Translate $outputlangs Lang output object + * @param string $srctemplatepath Full path of source filename for generator using a template file + * @param int $hidedetails Do not show line details + * @param int $hidedesc Do not show desc + * @param int $hideref Do not show ref + * @return int 1=OK, 0=KO */ - function write_file($object,$outputlangs) + function write_file($object,$outputlangs,$srctemplatepath='',$hidedetails=0,$hidedesc=0,$hideref=0) { - global $user,$langs,$conf; + global $user,$langs,$conf,$mysoc,$hookmanager; if (! is_object($outputlangs)) $outputlangs=$langs; // For backward compatibility with FPDF, force output charset to ISO, because FPDF expect text to be encoded in ISO @@ -126,17 +146,23 @@ class pdf_typhon extends ModelePDFDeliveryOrder $outputlangs->load("deliveries"); $outputlangs->load("sendings"); - if ($conf->expedition->dir_output."/receipt") + if ($conf->expedition->dir_output) { $object->fetch_thirdparty(); - $nblines = count($object->lines); - - $objectref = dol_sanitizeFileName($object->ref); - $dir = $conf->expedition->dir_output."/receipt"; - if (! preg_match('/specimen/i',$objectref)) $dir.= "/" . $objectref; - $file = $dir . "/" . $objectref . ".pdf"; - + // Definition of $dir and $file + if ($object->specimen) + { + $dir = $conf->expedition->dir_output."/receipt"; + $file = $dir . "/SPECIMEN.pdf"; + } + else + { + $objectref = dol_sanitizeFileName($object->ref); + $dir = $conf->expedition->dir_output."/receipt/" . $objectref; + $file = $dir . "/" . $objectref . ".pdf"; + } + if (! file_exists($dir)) { if (dol_mkdir($dir) < 0) @@ -148,9 +174,12 @@ class pdf_typhon extends ModelePDFDeliveryOrder if (file_exists($dir)) { - $pdf=pdf_getInstance($this->format); + $nblines = count($object->lines); + + // Create pdf instance + $pdf=pdf_getInstance($this->format); $default_font_size = pdf_getPDFFontSize($outputlangs); // Must be after pdf_getInstance - $heightforinfotot = 50; // Height reserved to output the info and total part + $heightforinfotot = 30; // Height reserved to output the info and total part $heightforfreetext= (isset($conf->global->MAIN_PDF_FREETEXT_HEIGHT)?$conf->global->MAIN_PDF_FREETEXT_HEIGHT:5); // Height reserved to output the free text on last page $heightforfooter = $this->marge_basse + 8; // Height reserved to output the footer (value include bottom margin) $pdf->SetAutoPageBreak(1,0); @@ -195,7 +224,7 @@ class pdf_typhon extends ModelePDFDeliveryOrder /* // Positionne $this->atleastonediscount si on a au moins une remise - for ($i = 0 ; $i < $nblignes ; $i++) + for ($i = 0 ; $i < $nblines ; $i++) { if ($object->lines[$i]->remise_percent) { @@ -214,7 +243,7 @@ class pdf_typhon extends ModelePDFDeliveryOrder $pdf->SetTextColor(0,0,0); $tab_top = 90; - $tab_top_newpage = (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)?22:10); + $tab_top_newpage = (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)?42:10); $tab_height = 130; $tab_height_newpage = 150; @@ -223,7 +252,7 @@ class pdf_typhon extends ModelePDFDeliveryOrder { $tab_top = 88; - $pdf->SetFont('','', $default_font_size - 1); // Dans boucle pour gerer multi-page + $pdf->SetFont('','', $default_font_size - 1); $pdf->writeHTMLCell(190, 3, $this->posxdesc-1, $tab_top, dol_htmlentitiesbr($object->note_public), 0, 1); $nexY = $pdf->GetY(); $height_note=$nexY-$tab_top; @@ -252,13 +281,46 @@ class pdf_typhon extends ModelePDFDeliveryOrder $pdf->SetTextColor(0,0,0); $pdf->setTopMargin($tab_top_newpage); - $pdf->setPageOrientation('', 1, $heightforfooter+$heightforfreetext); // The only function to edit the bottom margin of current page to set it. + $pdf->setPageOrientation('', 1, $heightforfooter+$heightforfreetext+$heightforinfotot); // The only function to edit the bottom margin of current page to set it. $pageposbefore=$pdf->getPage(); // Description of product line $curX = $this->posxdesc-1; - pdf_writelinedesc($pdf,$object,$i,$outputlangs,108,3,$curX,$curY); + $showpricebeforepagebreak=1; + + $pdf->startTransaction(); + pdf_writelinedesc($pdf,$object,$i,$outputlangs,$this->posxcomm-$curX,3,$curX,$curY,$hideref,$hidedesc); + $pageposafter=$pdf->getPage(); + if ($pageposafter > $pageposbefore) // There is a pagebreak + { + $pdf->rollbackTransaction(true); + $pageposafter=$pageposbefore; + //print $pageposafter.'-'.$pageposbefore;exit; + $pdf->setPageOrientation('', 1, $heightforfooter); // The only function to edit the bottom margin of current page to set it. + pdf_writelinedesc($pdf,$object,$i,$outputlangs,$this->posxcomm-$curX,4,$curX,$curY,$hideref,$hidedesc); + $posyafter=$pdf->GetY(); + if ($posyafter > ($this->page_hauteur - ($heightforfooter+$heightforfreetext+$heightforinfotot))) // There is no space left for total+free text + { + if ($i == ($nblines-1)) // No more lines, and no space left to show total, so we create a new page + { + $pdf->AddPage('','',true); + if (! empty($tplidx)) $pdf->useTemplate($tplidx); + if (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)) $this->_pagehead($pdf, $object, 0, $outputlangs); + $pdf->setPage($pagenb+1); + } + } + else + { + // We found a page break + $showpricebeforepagebreak=0; + } + } + else // No pagebreak + { + $pdf->commitTransaction(); + } + $nexY = $pdf->GetY(); $pageposafter=$pdf->getPage(); $pdf->setPage($pageposbefore); @@ -266,17 +328,15 @@ class pdf_typhon extends ModelePDFDeliveryOrder $pdf->setPageOrientation('', 1, 0); // The only function to edit the bottom margin of current page to set it. // We suppose that a too long description is moved completely on next page - if ($pageposafter > $pageposbefore) { + if ($pageposafter > $pageposbefore && empty($showpricebeforepagebreak)) { $pdf->setPage($pageposafter); $curY = $tab_top_newpage; } $pdf->SetFont('','', $default_font_size - 1); // On repositionne la police par defaut - $nexY = $pdf->GetY()+4; - /* // TVA - $pdf->SetXY($this->posxtva, $curY); + $pdf->SetXY($this->posxcomm, $curY); $pdf->MultiCell(10, 4, ($object->lines[$i]->tva_tx < 0 ? '*':'').abs($object->lines[$i]->tva_tx), 0, 'R'); // Prix unitaire HT avant remise @@ -284,8 +344,9 @@ class pdf_typhon extends ModelePDFDeliveryOrder $pdf->MultiCell(20, 4, price($object->lines[$i]->subprice), 0, 'R', 0); */ // Quantity + //$qty = pdf_getlineqty($object, $i, $outputlangs, $hidedetails); $pdf->SetXY($this->posxqty, $curY); - $pdf->MultiCell(30, 3, $object->lines[$i]->qty_shipped, 0, 'R'); + $pdf->MultiCell($this->page_largeur-$this->marge_droite-$this->posxqty, 3, $object->lines[$i]->qty_shipped, 0, 'R'); /* // Remise sur ligne $pdf->SetXY($this->posxdiscount, $curY); @@ -307,7 +368,7 @@ class pdf_typhon extends ModelePDFDeliveryOrder */ // Add line - if (! empty($conf->global->MAIN_PDF_DASH_BETWEEN_LINES) && $i < ($nblignes - 1)) + if (! empty($conf->global->MAIN_PDF_DASH_BETWEEN_LINES) && $i < ($nblines - 1)) { $pdf->SetLineStyle(array('dash'=>'1,1','color'=>array(210,210,210))); //$pdf->SetDrawColor(190,190,200); @@ -333,6 +394,7 @@ class pdf_typhon extends ModelePDFDeliveryOrder $pagenb++; $pdf->setPage($pagenb); $pdf->setPageOrientation('', 1, 0); // The only function to edit the bottom margin of current page to set it. + if (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)) $this->_pagehead($pdf, $object, 0, $outputlangs); } if (isset($object->lines[$i+1]->pagebreak) && $object->lines[$i+1]->pagebreak) { @@ -349,34 +411,38 @@ class pdf_typhon extends ModelePDFDeliveryOrder $pdf->AddPage(); if (! empty($tplidx)) $pdf->useTemplate($tplidx); $pagenb++; + if (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)) $this->_pagehead($pdf, $object, 0, $outputlangs); } } // Show square if ($pagenb == 1) { - $this->_tableau($pdf, $tab_top, $this->page_hauteur - $tab_top - $heightforinfotot - $heightforfreetext - $heightforfooter, 0, $outputlangs, 0); - $bottomlasttab=$this->page_hauteur - $heightforinfotot - $heightforfooter + 1; + $this->_tableau($pdf, $tab_top, $this->page_hauteur - $tab_top - $heightforinfotot - $heightforfreetext - $heightforfooter, 0, $outputlangs, 0, 0); + $bottomlasttab=$this->page_hauteur - $heightforinfotot - $heightforfreetext - $heightforfooter + 1; } else { - $this->_tableau($pdf, $tab_top_newpage, $this->page_hauteur - $tab_top_newpage - $heightforinfotot - $heightforfreetext - $heightforfooter, 0, $outputlangs, 1); - $bottomlasttab=$this->page_hauteur - $heightforinfotot - $heightforfooter + 1; + $this->_tableau($pdf, $tab_top_newpage, $this->page_hauteur - $tab_top_newpage - $heightforinfotot - $heightforfreetext - $heightforfooter, 0, $outputlangs, 1, 0); + $bottomlasttab=$this->page_hauteur - $heightforinfotot - $heightforfreetext - $heightforfooter + 1; } - /* - * Pied de page - */ + // Affiche zone infos + $posy=$this->_tableau_info($pdf, $object, $bottomlasttab, $outputlangs); + + // Pied de page $this->_pagefoot($pdf,$object,$outputlangs); - + $pdf->AliasNbPages(); + // Check product remaining to be delivered // TODO doit etre modifie //$waitingDelivery = $object->getRemainingDelivered(); + /* $waitingDelivery=''; if (is_array($waitingDelivery) & !empty($waitingDelivery)) { - $pdf->AddPage('P', 'A4'); + $pdf->AddPage(); $this->_pagehead($pdf, $object, 1, $outputlangs); $pdf-> SetY(90); @@ -426,17 +492,28 @@ class pdf_typhon extends ModelePDFDeliveryOrder $this->_pagefoot($pdf,$object,$outputlangs); - } - - $pdf->AliasNbPages(); + $pdf->AliasNbPages(); + }*/ $pdf->Close(); $pdf->Output($file,'F'); - if (! empty($conf->global->MAIN_UMASK)) - @chmod($file, octdec($conf->global->MAIN_UMASK)); - return 1; + // Add pdfgeneration hook + if (! is_object($hookmanager)) + { + include_once DOL_DOCUMENT_ROOT.'/core/class/hookmanager.class.php'; + $hookmanager=new HookManager($this->db); + } + $hookmanager->initHooks(array('pdfgeneration')); + $parameters=array('file'=>$file,'object'=>$object,'outputlangs'=>$outputlangs); + global $action; + $reshook=$hookmanager->executeHooks('afterPDFCreation',$parameters,$this,$action); // Note that $action and $object may have been modified by some hooks + + if (! empty($conf->global->MAIN_UMASK)) + @chmod($file, octdec($conf->global->MAIN_UMASK)); + + return 1; // pas d'erreur } else { @@ -449,66 +526,90 @@ class pdf_typhon extends ModelePDFDeliveryOrder return 0; } - + /** + * Show miscellaneous information (payment mode, payment term, ...) + * + * @param PDF &$pdf Object PDF + * @param Object $object Object to show + * @param int $posy Y + * @param Translate $outputlangs Langs object + * @return void + */ + function _tableau_info(&$pdf, $object, $posy, $outputlangs) + { + global $conf; + $default_font_size = pdf_getPDFFontSize($outputlangs); + + $pdf->SetFont('','', $default_font_size); + $pdf->SetXY($this->marge_gauche, $posy); + + $larg_sign = ($this->page_largeur-$this->marge_gauche-$this->marge_droite)/3; + $pdf->Rect($this->marge_gauche, $posy + 1, $larg_sign, 25); + $pdf->SetXY($this->marge_gauche + 2, $posy + 2); + $pdf->MultiCell($larg_sign,2, $outputlangs->trans("For").' '.$outputlangs->convToOutputCharset($mysoc->name).":",'','L'); + + $pdf->Rect(2*$larg_sign+$this->marge_gauche, $posy + 1, $larg_sign, 25); + $pdf->SetXY(2*$larg_sign+$this->marge_gauche + 2, $posy + 2); + $pdf->MultiCell($larg_sign,2, $outputlangs->trans("ForCustomer").':','','L'); + } + /** * Show table for lines * * @param PDF &$pdf Object PDF * @param string $tab_top Top position of table * @param string $tab_height Height of table (rectangle) - * @param int $nexY Y + * @param int $nexY Y (not used) * @param Translate $outputlangs Langs object - * @param int $hidetop Hide top bar of array + * @param int $hidetop 1=Hide top bar of array and title, 0=Hide nothing, -1=Hide only title * @param int $hidebottom Hide bottom bar of array * @return void */ function _tableau(&$pdf, $tab_top, $tab_height, $nexY, $outputlangs, $hidetop=0, $hidebottom=0) { global $conf,$mysoc; + + // Force to disable hidetop and hidebottom + $hidebottom=0; + if ($hidetop) $hidetop=-1; + $default_font_size = pdf_getPDFFontSize($outputlangs); - - $pdf->SetDrawColor(128,128,128); - - // Rect prend une longueur en 3eme param - $pdf->Rect($this->marge_gauche, $tab_top, $this->page_largeur-$this->marge_gauche-$this->marge_droite, $tab_height); - // line prend une position y en 3eme param - if (empty($hidetop)) - $pdf->line($this->marge_gauche, $tab_top+6, $this->page_largeur-$this->marge_droite, $tab_top+6); - + + // Amount in (at tab_top - 1) $pdf->SetTextColor(0,0,0); + $pdf->SetFont('','', $default_font_size - 2); + + // Output Rec + $this->printRect($pdf, $this->marge_gauche, $tab_top, $this->page_largeur-$this->marge_gauche-$this->marge_droite, $tab_height, $hidetop, $hidebottom); // Rect prend une longueur en 3eme param et 4eme param + + if (empty($hidetop)) + { + $pdf->line($this->marge_gauche, $tab_top+6, $this->page_largeur-$this->marge_droite, $tab_top+6); + } + + $pdf->SetDrawColor(128,128,128); $pdf->SetFont('','', $default_font_size - 1); - if (empty($hidetop)) { + if (empty($hidetop)) + { $pdf->SetXY($this->posxdesc-1, $tab_top+1); - $pdf->MultiCell(80,2, $outputlangs->transnoentities("Designation"),'','L'); + $pdf->MultiCell($this->posxcomm - $this->posxdesc,2, $outputlangs->transnoentities("Designation"),'','L'); } // Modif SEB pour avoir une col en plus pour les commentaires clients $pdf->line($this->posxcomm, $tab_top, $this->posxcomm, $tab_top + $tab_height); if (empty($hidetop)) { $pdf->SetXY($this->posxcomm, $tab_top+1); - $pdf->MultiCell(80,2, $outputlangs->transnoentities("Comments"),'','L'); + $pdf->MultiCell($this->posxqty - $this->posxcomm,2, $outputlangs->transnoentities("Comments"),'','L'); } // Qty $pdf->line($this->posxqty-1, $tab_top, $this->posxqty-1, $tab_top + $tab_height); if (empty($hidetop)) { $pdf->SetXY($this->posxqty-1, $tab_top+1); - $pdf->MultiCell(30, 2, $outputlangs->transnoentities("QtyShipped"),'','R'); + $pdf->MultiCell($this->page_largeur-$this->marge_droite-$this->posxqty, 2, $outputlangs->transnoentities("QtyShipped"),'','R'); } - if (empty($hidebottom)) { - // Modif Seb cadres signatures - $pdf->SetFont('','', $default_font_size); - $larg_sign = ($this->page_largeur-$this->marge_gauche-$this->marge_droite)/3; - $pdf->Rect($this->marge_gauche, ($tab_top + $tab_height + 3), $larg_sign, 25); - $pdf->SetXY($this->marge_gauche + 2, $tab_top + $tab_height + 5); - $pdf->MultiCell($larg_sign,2, $outputlangs->trans("For").' '.$outputlangs->convToOutputCharset($mysoc->name).":",'','L'); - - $pdf->Rect(2*$larg_sign+$this->marge_gauche, ($tab_top + $tab_height + 3), $larg_sign, 25); - $pdf->SetXY(2*$larg_sign+$this->marge_gauche + 2, $tab_top + $tab_height + 5); - $pdf->MultiCell($larg_sign,2, $outputlangs->trans("ForCustomer").':','','L'); - } } /** @@ -522,22 +623,29 @@ class pdf_typhon extends ModelePDFDeliveryOrder */ function _pagehead(&$pdf, $object, $showaddress, $outputlangs) { - global $langs,$conf,$mysoc; + global $conf,$langs,$hookmanager; + $default_font_size = pdf_getPDFFontSize($outputlangs); pdf_pagehead($pdf,$outputlangs,$this->page_hauteur); - $pdf->SetTextColor(0,0,60); - $pdf->SetFont('','B', $default_font_size + 3); - - $posx=$this->page_largeur-$this->marge_droite-100; - $posy=$this->marge_haute; - - $pdf->SetXY($this->marge_gauche,$posy); - + // Show Draft Watermark + if($object->statut==0 && (! empty($conf->global->COMMANDE_DRAFT_WATERMARK)) ) + { + pdf_watermark($pdf,$outputlangs,$this->page_hauteur,$this->page_largeur,'mm',$conf->global->COMMANDE_DRAFT_WATERMARK); + } + + $pdf->SetTextColor(0,0,60); + $pdf->SetFont('','B', $default_font_size + 3); + + $posy=$this->marge_haute; + $posx=$this->page_largeur-$this->marge_droite-100; + + $pdf->SetXY($this->marge_gauche,$posy); + // Logo - $logo=$conf->mycompany->dir_output.'/logos/'.$mysoc->logo; - if ($mysoc->logo) + $logo=$conf->mycompany->dir_output.'/logos/'.$this->emetteur->logo; + if ($this->emetteur->logo) { if (is_readable($logo)) { @@ -548,8 +656,8 @@ class pdf_typhon extends ModelePDFDeliveryOrder { $pdf->SetTextColor(200,0,0); $pdf->SetFont('','B', $default_font_size - 2); - $pdf->MultiCell(100, 3, $langs->transnoentities("ErrorLogoFileNotFound",$logo), 0, 'L'); - $pdf->MultiCell(100, 3, $langs->transnoentities("ErrorGoToModuleSetup"), 0, 'L'); + $pdf->MultiCell(100, 3, $outputlangs->transnoentities("ErrorLogoFileNotFound",$logo), 0, 'L'); + $pdf->MultiCell(100, 3, $outputlangs->transnoentities("ErrorGoToGlobalSetup"), 0, 'L'); } } else $pdf->MultiCell(100, 4, $this->emetteur->name, 0, 'L'); @@ -557,7 +665,7 @@ class pdf_typhon extends ModelePDFDeliveryOrder $pdf->SetFont('','B', $default_font_size + 2); $pdf->SetXY($posx,$posy); $pdf->SetTextColor(0,0,60); - $pdf->MultiCell(100, 4, $outputlangs->transnoentities("DeliveryOrder")." ".$outputlangs->convToOutputCharset($object->ref), '', 'R'); + $pdf->MultiCell(100, 3, $outputlangs->transnoentities("DeliveryOrder")." ".$outputlangs->convToOutputCharset($object->ref), '', 'R'); $pdf->SetFont('','',$default_font_size + 2); @@ -585,69 +693,42 @@ class pdf_typhon extends ModelePDFDeliveryOrder $pdf->SetTextColor(0,0,60); - // Add origin linked objects - // TODO extend to other objects - $object->fetchObjectLinked('','',$object->id,'delivery'); - - if (! empty($object->linkedObjects)) - { - $outputlangs->load('orders'); - - foreach($object->linkedObjects as $elementtype => $objects) - { - $object->fetchObjectLinked('','',$objects[0]->id,$objects[0]->element); - - foreach($object->linkedObjects as $elementtype => $objects) - { - $num=count($objects); - for ($i=0;$i<$num;$i++) - { - $order=new Commande($this->db); - $result=$order->fetch($objects[$i]->id); - if ($result >= 0) - { - $posy+=5; - $pdf->SetXY($posx,$posy); - $pdf->SetFont('','', $default_font_size - 1); - $text=$order->ref; - if ($order->ref_client) $text.=' ('.$order->ref_client.')'; - $pdf->MultiCell(100, 4, $outputlangs->transnoentities("RefOrder")." : ".$outputlangs->transnoentities($text), '', 'R'); - } - } - } - } - } - + $posy+=2; + + // Show list of linked objects + $posy = pdf_writeLinkedObjects($pdf, $object, $outputlangs, $posx, $posy, 100, 3, 'R', $default_font_size); + if ($showaddress) { - // Emetteur + // Sender properties + $carac_emetteur = pdf_build_address($outputlangs,$this->emetteur); + + // Show sender $posy=42; + $posx=$this->marge_gauche; + if (! empty($conf->global->MAIN_INVERT_SENDER_RECIPIENT)) $posx=$this->page_largeur-$this->marge_droite-80; $hautcadre=40; + + // Show sender frame $pdf->SetTextColor(0,0,0); $pdf->SetFont('','', $default_font_size - 2); - $pdf->SetXY($this->marge_gauche,$posy-5); - $pdf->MultiCell(66,5, $outputlangs->transnoentities("BillFrom").":"); - - - $pdf->SetXY($this->marge_gauche,$posy); + $pdf->SetXY($posx,$posy-5); + $pdf->MultiCell(66,5, $outputlangs->transnoentities("BillFrom").":", 0, 'L'); + $pdf->SetXY($posx,$posy); $pdf->SetFillColor(230,230,230); $pdf->MultiCell(82, $hautcadre, "", 0, 'R', 1); - - - $pdf->SetXY($this->marge_gauche+2,$posy+3); - - // Nom emetteur $pdf->SetTextColor(0,0,60); + + // Show sender name + $pdf->SetXY($posx+2,$posy+3); $pdf->SetFont('','B',$default_font_size); $pdf->MultiCell(80, 4, $outputlangs->convToOutputCharset($this->emetteur->name), 0, 'L'); - // Sender properties - $carac_emetteur = pdf_build_address($outputlangs,$this->emetteur); - - $pdf->SetFont('','', $default_font_size - 1); - $pdf->SetXY($this->marge_gauche+2,$posy+9); - $pdf->MultiCell(80, 3, $carac_emetteur, 0, 'L'); - + // Show sender information + $pdf->SetXY($posx+2,$posy+8); + $pdf->SetFont('','', $default_font_size - 1); + $pdf->MultiCell(80, 4, $carac_emetteur, 0, 'L'); + // Client destinataire $posy=42; $pdf->SetTextColor(0,0,0); @@ -655,7 +736,7 @@ class pdf_typhon extends ModelePDFDeliveryOrder $pdf->SetXY(102,$posy-5); $pdf->MultiCell(80,5, $outputlangs->transnoentities("DeliveryAddress").":", 0, 'L'); - // If SHIPPING contact defined on invoice, we use it + // If SHIPPING contact defined on order, we use it $usecontact=false; $arrayidcontact=$object->commande->getIdContact('external','SHIPPING'); if (count($arrayidcontact) > 0) @@ -677,7 +758,7 @@ class pdf_typhon extends ModelePDFDeliveryOrder $carac_client_name=$outputlangs->convToOutputCharset($object->client->nom); } - $carac_client=pdf_build_address($outputlangs,$this->emetteur,$object->client,$object->contact,$usecontact,'target'); + $carac_client=pdf_build_address($outputlangs,$this->emetteur,$object->client,($usecontact?$object->contact:''),$usecontact,'target'); // Show recipient $widthrecbox=100; @@ -700,7 +781,7 @@ class pdf_typhon extends ModelePDFDeliveryOrder // Show recipient information $pdf->SetFont('','', $default_font_size - 1); - $pdf->SetXY($posx+2,$posy+8); + $pdf->SetXY($posx+2,$posy+4+(dol_nboflines_bis($carac_client_name,50)*4)); $pdf->MultiCell($widthrecbox, 4, $carac_client, 0, 'L'); } @@ -713,7 +794,7 @@ class pdf_typhon extends ModelePDFDeliveryOrder * @param Object $object Object to show * @param Translate $outputlangs Object lang for output * @param int $hidefreetext 1=Hide free text - * @return void + * @return int Return height of bottom margin including footer text */ function _pagefoot(&$pdf,$object,$outputlangs,$hidefreetext=0) { diff --git a/htdocs/core/modules/modBarcode.class.php b/htdocs/core/modules/modBarcode.class.php index b4c933ccf69..856f4251e9c 100644 --- a/htdocs/core/modules/modBarcode.class.php +++ b/htdocs/core/modules/modBarcode.class.php @@ -111,12 +111,12 @@ class modBarcode extends DolibarrModules $this->remove($options); $sql = array( - array('sql'=>'INSERT INTO llx_c_barcode_type (code, libelle, coder, example, entity) VALUES ("EAN8", "EAN8", 0, "1234567", __ENTITY__)','ignoreerror'=>1), - array('sql'=>'INSERT INTO llx_c_barcode_type (code, libelle, coder, example, entity) VALUES ("EAN13", "EAN13", 0, "123456789012", __ENTITY__)','ignoreerror'=>1), - array('sql'=>'INSERT INTO llx_c_barcode_type (code, libelle, coder, example, entity) VALUES ("UPC", "UPC", 0, "123456789012", __ENTITY__)','ignoreerror'=>1), - array('sql'=>'INSERT INTO llx_c_barcode_type (code, libelle, coder, example, entity) VALUES ("ISBN", "ISBN", 0, "123456789", __ENTITY__)','ignoreerror'=>1), - array('sql'=>'INSERT INTO llx_c_barcode_type (code, libelle, coder, example, entity) VALUES ("C39", "Code 39", 0, "1234567890", __ENTITY__)','ignoreerror'=>1), - array('sql'=>'INSERT INTO llx_c_barcode_type (code, libelle, coder, example, entity) VALUES ("C128", "Code 128", 0, "ABCD1234567890", __ENTITY__)','ignoreerror'=>1) + array('sql'=>"INSERT INTO llx_c_barcode_type (code, libelle, coder, example, entity) VALUES ('EAN8', 'EAN8', 0, '1234567', __ENTITY__)",'ignoreerror'=>1), + array('sql'=>"INSERT INTO llx_c_barcode_type (code, libelle, coder, example, entity) VALUES ('EAN13', 'EAN13', 0, '123456789012', __ENTITY__)",'ignoreerror'=>1), + array('sql'=>"INSERT INTO llx_c_barcode_type (code, libelle, coder, example, entity) VALUES ('UPC', 'UPC', 0, '123456789012', __ENTITY__)",'ignoreerror'=>1), + array('sql'=>"INSERT INTO llx_c_barcode_type (code, libelle, coder, example, entity) VALUES ('ISBN', 'ISBN', 0, '123456789', __ENTITY__)",'ignoreerror'=>1), + array('sql'=>"INSERT INTO llx_c_barcode_type (code, libelle, coder, example, entity) VALUES ('C39', 'Code 39', 0, '1234567890', __ENTITY__)",'ignoreerror'=>1), + array('sql'=>"INSERT INTO llx_c_barcode_type (code, libelle, coder, example, entity) VALUES ('C128', 'Code 128', 0, 'ABCD1234567890', __ENTITY__)",'ignoreerror'=>1) ); return $this->_init($sql, $options); diff --git a/htdocs/core/modules/modFacture.class.php b/htdocs/core/modules/modFacture.class.php index 666bcb9a22a..4d18c3d8757 100644 --- a/htdocs/core/modules/modFacture.class.php +++ b/htdocs/core/modules/modFacture.class.php @@ -198,10 +198,10 @@ class modFacture extends DolibarrModules $this->export_label[$r]='CustomersInvoicesAndPayments'; // Translation key (used only if key ExportDataset_xxx_z not found) $this->export_icon[$r]='bill'; $this->export_permission[$r]=array(array("facture","facture","export")); - $this->export_fields_array[$r]=array('s.rowid'=>"IdCompany",'s.nom'=>'CompanyName','s.address'=>'Address','s.zip'=>'Zip','s.town'=>'Town','c.code'=>'CountryCode','s.phone'=>'Phone','s.siren'=>'ProfId1','s.siret'=>'ProfId2','s.ape'=>'ProfId3','s.idprof4'=>'ProfId4','s.code_compta'=>'CustomerAccountancyCode','s.code_compta_fournisseur'=>'SupplierAccountancyCode','s.tva_intra'=>'VATIntra','f.rowid'=>"InvoiceId",'f.facnumber'=>"InvoiceRef",'f.datec'=>"InvoiceDateCreation",'f.datef'=>"DateInvoice",'f.date_lim_reglement'=>"DateDue",'f.total'=>"TotalHT",'f.total_ttc'=>"TotalTTC",'f.tva'=>"TotalVAT",'f.paye'=>"InvoicePaid",'f.fk_statut'=>'InvoiceStatus','f.note'=>"NotePrivate",'f.note_public'=>"NotePublic",'p.rowid'=>'PaymentId','pf.amount'=>'AmountPayment','p.datep'=>'DatePayment','p.num_paiement'=>'PaymentNumber'); - //$this->export_TypeFields_array[$r]=array('s.rowid'=>"List:societe:nom",'s.nom'=>'Text','s.address'=>'Text','s.zip'=>'Text','s.town'=>'Text','c.code'=>'Text','s.phone'=>'Text','s.siren'=>'Text','s.siret'=>'Text','s.ape'=>'Text','s.idprof4'=>'Text','s.code_compta'=>'Text','s.code_compta_fournisseur'=>'Text','s.tva_intra'=>'Text','f.rowid'=>"List:facture:facnumber",'f.facnumber'=>"Text",'f.datec'=>"Date",'f.datef'=>"Date",'f.date_lim_reglement'=>"Date",'f.total'=>"Number",'f.total_ttc'=>"Number",'f.tva'=>"Number",'f.paye'=>"Boolean",'f.fk_statut'=>'Status','f.note'=>"Text",'f.note_public'=>"Text",'pf.amount'=>'Number','p.datep'=>'Date','p.num_paiement'=>'Number'); - $this->export_TypeFields_array[$r]=array('s.nom'=>'Text','s.address'=>'Text','s.zip'=>'Text','s.town'=>'Text','c.code'=>'Text','s.phone'=>'Text','s.siren'=>'Text','s.siret'=>'Text','s.ape'=>'Text','s.idprof4'=>'Text','s.code_compta'=>'Text','s.code_compta_fournisseur'=>'Text','s.tva_intra'=>'Text','f.rowid'=>"List:facture:facnumber",'f.facnumber'=>"Text",'f.datec'=>"Date",'f.datef'=>"Date",'f.date_lim_reglement'=>"Date",'f.total'=>"Number",'f.total_ttc'=>"Number",'f.tva'=>"Number",'f.paye'=>"Boolean",'f.fk_statut'=>'Status','f.note'=>"Text",'f.note_public'=>"Text",'pf.amount'=>'Number','p.datep'=>'Date','p.num_paiement'=>'Number'); - $this->export_entities_array[$r]=array('s.rowid'=>"company",'s.nom'=>'company','s.address'=>'company','s.zip'=>'company','s.town'=>'company','c.code'=>'company','s.phone'=>'company','s.siren'=>'company','s.siret'=>'company','s.ape'=>'company','s.idprof4'=>'company','s.code_compta'=>'company','s.code_compta_fournisseur'=>'company','s.tva_intra'=>'company','f.rowid'=>"invoice",'f.facnumber'=>"invoice",'f.datec'=>"invoice",'f.datef'=>"invoice",'f.date_lim_reglement'=>"invoice",'f.total'=>"invoice",'f.total_ttc'=>"invoice",'f.tva'=>"invoice",'f.paye'=>"invoice",'f.fk_statut'=>'invoice','f.note'=>"invoice",'f.note_public'=>"invoice",'p.rowid'=>'payment','pf.amount'=>'payment','p.datep'=>'payment','p.num_paiement'=>'payment'); + $this->export_fields_array[$r]=array('s.rowid'=>"IdCompany",'s.nom'=>'CompanyName','s.address'=>'Address','s.zip'=>'Zip','s.town'=>'Town','c.code'=>'CountryCode','s.phone'=>'Phone','s.siren'=>'ProfId1','s.siret'=>'ProfId2','s.ape'=>'ProfId3','s.idprof4'=>'ProfId4','s.code_compta'=>'CustomerAccountancyCode','s.code_compta_fournisseur'=>'SupplierAccountancyCode','s.tva_intra'=>'VATIntra','f.rowid'=>"InvoiceId",'f.facnumber'=>"InvoiceRef",'f.datec'=>"InvoiceDateCreation",'f.datef'=>"DateInvoice",'f.date_lim_reglement'=>"DateDue",'f.total'=>"TotalHT",'f.total_ttc'=>"TotalTTC",'f.tva'=>"TotalVAT",'f.paye'=>"InvoicePaid",'f.fk_statut'=>'InvoiceStatus','f.note_private'=>"NotePrivate",'f.note_public'=>"NotePublic",'p.rowid'=>'PaymentId','pf.amount'=>'AmountPayment','p.datep'=>'DatePayment','p.num_paiement'=>'PaymentNumber'); + //$this->export_TypeFields_array[$r]=array('s.rowid'=>"List:societe:nom",'s.nom'=>'Text','s.address'=>'Text','s.zip'=>'Text','s.town'=>'Text','c.code'=>'Text','s.phone'=>'Text','s.siren'=>'Text','s.siret'=>'Text','s.ape'=>'Text','s.idprof4'=>'Text','s.code_compta'=>'Text','s.code_compta_fournisseur'=>'Text','s.tva_intra'=>'Text','f.rowid'=>"List:facture:facnumber",'f.facnumber'=>"Text",'f.datec'=>"Date",'f.datef'=>"Date",'f.date_lim_reglement'=>"Date",'f.total'=>"Number",'f.total_ttc'=>"Number",'f.tva'=>"Number",'f.paye'=>"Boolean",'f.fk_statut'=>'Status','f.note_private'=>"Text",'f.note_public'=>"Text",'pf.amount'=>'Number','p.datep'=>'Date','p.num_paiement'=>'Number'); + $this->export_TypeFields_array[$r]=array('s.nom'=>'Text','s.address'=>'Text','s.zip'=>'Text','s.town'=>'Text','c.code'=>'Text','s.phone'=>'Text','s.siren'=>'Text','s.siret'=>'Text','s.ape'=>'Text','s.idprof4'=>'Text','s.code_compta'=>'Text','s.code_compta_fournisseur'=>'Text','s.tva_intra'=>'Text','f.rowid'=>"List:facture:facnumber",'f.facnumber'=>"Text",'f.datec'=>"Date",'f.datef'=>"Date",'f.date_lim_reglement'=>"Date",'f.total'=>"Number",'f.total_ttc'=>"Number",'f.tva'=>"Number",'f.paye'=>"Boolean",'f.fk_statut'=>'Status','f.note_private'=>"Text",'f.note_public'=>"Text",'pf.amount'=>'Number','p.datep'=>'Date','p.num_paiement'=>'Number'); + $this->export_entities_array[$r]=array('s.rowid'=>"company",'s.nom'=>'company','s.address'=>'company','s.zip'=>'company','s.town'=>'company','c.code'=>'company','s.phone'=>'company','s.siren'=>'company','s.siret'=>'company','s.ape'=>'company','s.idprof4'=>'company','s.code_compta'=>'company','s.code_compta_fournisseur'=>'company','s.tva_intra'=>'company','f.rowid'=>"invoice",'f.facnumber'=>"invoice",'f.datec'=>"invoice",'f.datef'=>"invoice",'f.date_lim_reglement'=>"invoice",'f.total'=>"invoice",'f.total_ttc'=>"invoice",'f.tva'=>"invoice",'f.paye'=>"invoice",'f.fk_statut'=>'invoice','f.note_private'=>"invoice",'f.note_public'=>"invoice",'p.rowid'=>'payment','pf.amount'=>'payment','p.datep'=>'payment','p.num_paiement'=>'payment'); $this->export_dependencies_array[$r]=array('payment'=>'p.rowid'); // To add unique key if we ask a field of a child to avoid the DISTINCT to discard them $this->export_sql_start[$r]='SELECT DISTINCT '; diff --git a/htdocs/core/modules/modOpenSurvey.class.php b/htdocs/core/modules/modOpenSurvey.class.php index 0930f7dfa94..6c49a1c2143 100755 --- a/htdocs/core/modules/modOpenSurvey.class.php +++ b/htdocs/core/modules/modOpenSurvey.class.php @@ -1,7 +1,18 @@ +/* Copyright (C) 2013 Laurent Destailleur * - * Licensed under the GNU GPL v3 or higher (See file gpl-3.0.html) + * 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 . */ /** @@ -184,10 +195,11 @@ class modOpenSurvey extends DolibarrModules */ function init($options='') { + // Permissions + $this->remove($options); + $sql = array(); - $result=$this->load_tables(); - return $this->_init($sql,$options); } @@ -205,20 +217,6 @@ class modOpenSurvey extends DolibarrModules return $this->_remove($sql,$options); } - - - /** - * Create tables and keys required by module - * Files mymodule.sql and mymodule.key.sql with create table and create keys - * commands must be stored in directory /mymodule/sql/ - * This function is called by this->init. - * - * @return int <=0 if KO, >0 if OK - */ - function load_tables() - { - return $this->_load_tables('/opensurvey/sql/'); - } } ?> diff --git a/htdocs/core/modules/project/pdf/doc_generic_project_odt.modules.php b/htdocs/core/modules/project/pdf/doc_generic_project_odt.modules.php index 1fbd02bbe6f..4c81babaa55 100644 --- a/htdocs/core/modules/project/pdf/doc_generic_project_odt.modules.php +++ b/htdocs/core/modules/project/pdf/doc_generic_project_odt.modules.php @@ -650,7 +650,7 @@ class doc_generic_project_odt extends ModelePDFProjects //Time ressources $sql = "SELECT t.rowid, t.task_date, t.task_duration, t.fk_user, t.note"; - $sql.= ", u.name, u.firstname"; + $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 =".$task->id; @@ -973,8 +973,12 @@ class doc_generic_project_odt extends ModelePDFProjects // Write new file - $odfHandler->saveToDisk($file); - //$odfHandler->exportAsAttachedPDF($file); + if (!empty($conf->global->MAIN_ODT_AS_PDF)) { + $odfHandler->exportAsAttachedPDF($file); + } + else { + $odfHandler->saveToDisk($file); + } if (! empty($conf->global->MAIN_UMASK)) @chmod($file, octdec($conf->global->MAIN_UMASK)); diff --git a/htdocs/core/modules/propale/doc/doc_generic_proposal_odt.modules.php b/htdocs/core/modules/propale/doc/doc_generic_proposal_odt.modules.php index 26d67f09a32..d4e485562a4 100644 --- a/htdocs/core/modules/propale/doc/doc_generic_proposal_odt.modules.php +++ b/htdocs/core/modules/propale/doc/doc_generic_proposal_odt.modules.php @@ -482,8 +482,12 @@ class doc_generic_proposal_odt extends ModelePDFPropales $reshook=$hookmanager->executeHooks('beforeODTSave',$parameters,$this,$action); // Note that $action and $object may have been modified by some hooks // Write new file - //$result=$odfHandler->exportAsAttachedFile('toto'); - $odfHandler->saveToDisk($file); + if (!empty($conf->global->MAIN_ODT_AS_PDF)) { + $odfHandler->exportAsAttachedPDF($file); + } + else { + $odfHandler->saveToDisk($file); + } if (! empty($conf->global->MAIN_UMASK)) @chmod($file, octdec($conf->global->MAIN_UMASK)); diff --git a/htdocs/core/modules/societe/doc/doc_generic_odt.modules.php b/htdocs/core/modules/societe/doc/doc_generic_odt.modules.php index acf14c67139..e748e45a498 100644 --- a/htdocs/core/modules/societe/doc/doc_generic_odt.modules.php +++ b/htdocs/core/modules/societe/doc/doc_generic_odt.modules.php @@ -109,7 +109,7 @@ class doc_generic_odt extends ModeleThirdPartyDoc if (! is_dir($tmpdir)) $texttitle.=img_warning($langs->trans("ErrorDirNotFound",$tmpdir),0); else { - $tmpfiles=dol_dir_list($tmpdir,'files',0,'\.odt','','name',SORT_ASC,0,true); // Disable hook for the moment + $tmpfiles=dol_dir_list($tmpdir,'files',0,'\.od(s|t)$','','name',SORT_ASC,0,true); // Disable hook for the moment if (count($tmpfiles)) $listoffiles=array_merge($listoffiles,$tmpfiles); } } @@ -210,16 +210,27 @@ class doc_generic_odt extends ModeleThirdPartyDoc { //print "srctemplatepath=".$srctemplatepath; // Src filename $newfile=basename($srctemplatepath); - $newfiletmp=preg_replace('/\.odt/i','',$newfile); + $newfiletmp=preg_replace('/\.od(s|t)/i','',$newfile); $newfiletmp=preg_replace('/template_/i','',$newfiletmp); $newfiletmp=preg_replace('/modele_/i','',$newfiletmp); - $filename=$newfiletmp.'.'.dol_print_date(dol_now(),'%Y%m%d%H%M%S').'.odt'; + // Get extension (ods or odt) + $newfileformat=substr($newfile, strrpos($newfile, '.')+1); + if ( ! empty($conf->global->MAIN_ODT_USE_TIMING)) + { + $filename=$newfiletmp.'.'.dol_print_date(dol_now(),'%Y%m%d%H%M%S').'.'.$newfileformat; + } + else + { + $filename=$newfiletmp.'.'.$newfileformat; + } $file=$dir.'/'.$filename; $object->builddoc_filename=$filename; // For triggers + //print "newfileformat=".$newfileformat; //print "newdir=".$dir; //print "newfile=".$newfile; //print "file=".$file; //print "conf->societe->dir_temp=".$conf->societe->dir_temp; + //exit; dol_mkdir($conf->societe->multidir_temp[$object->entity]); @@ -313,8 +324,12 @@ class doc_generic_odt extends ModeleThirdPartyDoc $reshook=$hookmanager->executeHooks('beforeODTSave',$parameters,$this,$action); // Note that $action and $object may have been modified by some hooks // Write new file - //$result=$odfHandler->exportAsAttachedFile('toto'); - $odfHandler->saveToDisk($file); + if (!empty($conf->global->MAIN_ODT_AS_PDF)) { + $odfHandler->exportAsAttachedPDF($file); + } + else { + $odfHandler->saveToDisk($file); + } if (! empty($conf->global->MAIN_UMASK)) @chmod($file, octdec($conf->global->MAIN_UMASK)); diff --git a/htdocs/core/search_page.php b/htdocs/core/search_page.php index 3cab48155ae..fe21a82c56f 100644 --- a/htdocs/core/search_page.php +++ b/htdocs/core/search_page.php @@ -40,11 +40,6 @@ $langs->load("main"); $right=($langs->trans("DIRECTION")=='rtl'?'left':'right'); $left=($langs->trans("DIRECTION")=='rtl'?'right':'left'); -//var_dump($langs->defaultlang); -//var_dump($conf->format_date_short_java); -//var_dump($langs->trans("FormatDateShortJava")); - - /* * View diff --git a/htdocs/core/tpl/admin_extrafields_add.tpl.php b/htdocs/core/tpl/admin_extrafields_add.tpl.php index 5272c06b31f..44cc7a78bc0 100644 --- a/htdocs/core/tpl/admin_extrafields_add.tpl.php +++ b/htdocs/core/tpl/admin_extrafields_add.tpl.php @@ -27,7 +27,7 @@ var required = jQuery("#required"); var default_value = jQuery("#default_value"); " method="post"> + @@ -85,7 +87,7 @@
+
-textwithpicto('', $langs->trans("ExtrafieldParamHelp"),1,0)?>
textwithpicto('', $langs->trans("ExtrafieldParamHelp".$type),1,0)?>
diff --git a/htdocs/core/tpl/admin_extrafields_edit.tpl.php b/htdocs/core/tpl/admin_extrafields_edit.tpl.php index 181fcd55bbc..d3b06545fa2 100644 --- a/htdocs/core/tpl/admin_extrafields_edit.tpl.php +++ b/htdocs/core/tpl/admin_extrafields_edit.tpl.php @@ -44,6 +44,7 @@ + @@ -80,7 +81,7 @@ if((($type == 'select') || ($type == 'checkbox') ||(($type == 'radio'))) && is_a @@ -88,7 +89,11 @@ if(($type == 'select') || ($type == 'checkbox') ||(($type == 'radio'))) trans("Value"); ?> margin->enabled)) { 'origin_price_ht_cache' => 'price_ht', 'origin_tva_tx_cache' => 'tva_tx', 'origin_price_ttc_cache' => 'price_ttc', - 'qty' => 'qty' - ,'remise_percent' => 'discount' + 'qty' => 'qty', + 'remise_percent' => 'discount' ), 'update_textarea' => array( 'product_desc' => 'desc' @@ -160,7 +160,10 @@ if (! empty($conf->margin->enabled)) { - + margin->enabled)) { @@ -373,6 +376,11 @@ $(document).ready(function() { $('#price_ttc').attr('disabled','disabled'); } + $('#remise_percent').bind('change', function() { + if ($(this).val() < $('#origin_remise_percent').val()) + $('#remise_percent').val($('#origin_remise_percent').val()); + }); + $('#tva_tx').change(function() { if ($(this).val() == 0) { if ($('#idprod').val() == 0) { diff --git a/htdocs/core/triggers/interface_50_modNotification_Notification.class.php b/htdocs/core/triggers/interface_50_modNotification_Notification.class.php index c2785445800..f3b10e7f1f8 100755 --- a/htdocs/core/triggers/interface_50_modNotification_Notification.class.php +++ b/htdocs/core/triggers/interface_50_modNotification_Notification.class.php @@ -1,6 +1,7 @@ * Copyright (C) 2011 Regis Houssin + * Copyright (C) 2013 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 @@ -35,7 +36,8 @@ class InterfaceNotification 'PROPAL_VALIDATE', 'FICHINTER_VALIDATE', 'ORDER_SUPPLIER_APPROVE', - 'ORDER_SUPPLIER_REFUSE' + 'ORDER_SUPPLIER_REFUSE', + 'SHIPPING_VALIDATE' ); /** @@ -196,6 +198,19 @@ class InterfaceNotification $notify = new Notify($this->db); $notify->send($action, $object->socid, $mesg, 'order_supplier', $object->id, $filepdf); } + elseif ($action == 'SHIPPING_VALIDATE') + { + dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id); + + $ref = dol_sanitizeFileName($object->ref); + $filepdf = $conf->expedition->dir_output . '/sending/' . $ref . '/' . $ref . '.pdf'; + if (! file_exists($filepdf)) $filepdf=''; + $mesg = $langs->transnoentitiesnoconv("EMailTextExpeditionValidated",$object->ref); + + + $notify = new Notify($this->db); + $notify->send($action, $object->socid, $mesg, 'expedition', $object->id, $filepdf); + } // If not found /* diff --git a/htdocs/ecm/class/ecmdirectory.class.php b/htdocs/ecm/class/ecmdirectory.class.php index bdb8dd0f366..3c12fe066e9 100644 --- a/htdocs/ecm/class/ecmdirectory.class.php +++ b/htdocs/ecm/class/ecmdirectory.class.php @@ -142,7 +142,8 @@ class EcmDirectory // extends CommonObject $dir=$conf->ecm->dir_output.'/'.$this->getRelativePath(); $result=dol_mkdir($dir); - + if ($result < 0) { $error++; $this->error="ErrorFailedToCreateDir"; } + // Appel des triggers include_once DOL_DOCUMENT_ROOT . '/core/class/interfaces.class.php'; $interface=new Interfaces($this->db); diff --git a/htdocs/ecm/docdir.php b/htdocs/ecm/docdir.php index 8f71bf4ed97..5ab21beed0d 100644 --- a/htdocs/ecm/docdir.php +++ b/htdocs/ecm/docdir.php @@ -118,6 +118,7 @@ if ($action == 'add' && $user->rights->ecm->setup) { $langs->load("errors"); setEventMessage($langs->trans($ecmdir->error), 'errors'); + setEventMessage($ecmdir->errors, 'errors'); $action = 'create'; } } diff --git a/htdocs/expedition/class/expedition.class.php b/htdocs/expedition/class/expedition.class.php index f3db4dafc8b..95b18e1d814 100644 --- a/htdocs/expedition/class/expedition.class.php +++ b/htdocs/expedition/class/expedition.class.php @@ -1199,7 +1199,7 @@ class Expedition extends CommonObject { global $langs; - $listmeths = array(); + $this->listmeths = array(); $i=0; $sql = "SELECT em.rowid, em.code, em.libelle, em.description, em.tracking, em.active"; @@ -1216,29 +1216,11 @@ class Expedition extends CommonObject $label=$langs->trans('SendingMethod'.$obj->code); $this->listmeths[$i]['libelle'] = ($label != 'SendingMethod'.$obj->code?$label:$obj->libelle); $this->listmeths[$i]['description'] = $obj->description; - if ($obj->tracking) - { - $this->listmeths[$i]['tracking'] = $obj->tracking; - } - else - { - if ($obj->code) - { - $classname = "methode_expedition_".strtolower($obj->code); - - if (file_exists(DOL_DOCUMENT_ROOT."/core/modules/expedition/methode_expedition_".strtolower($obj->code).".modules.php") ) - { - require_once DOL_DOCUMENT_ROOT."/core/modules/expedition/methode_expedition_".strtolower($obj->code).'.modules.php'; - $shipmethod = new $classname(); - $this->listmeths[$i]['tracking'] = $shipmethod->provider_url_status('{TRACKID}'); - } - } - } + $this->listmeths[$i]['tracking'] = $obj->tracking; $this->listmeths[$i]['active'] = $obj->active; $i++; } } - else dol_print_error($this->db,''); } /** @@ -1309,8 +1291,6 @@ class Expedition extends CommonObject */ function GetUrlTrackingStatus($value='') { - $code=''; - if (! empty($this->shipping_method_id)) { $sql = "SELECT em.code, em.tracking"; @@ -1322,46 +1302,21 @@ class Expedition extends CommonObject { if ($obj = $this->db->fetch_object($resql)) { - $code = $obj->code; - $tracking = $obj->tracking; + $tracking = $obj->tracking; } } } - if ($tracking) - { - $url = str_replace('{TRACKID}', $value, $tracking); - $this->tracking_url = sprintf(''.($value?$value:'url').'',$url,$url); - } - else - { - if ($code) - { - $classname = "methode_expedition_".strtolower($code); - - $url=''; - if (file_exists(DOL_DOCUMENT_ROOT."/core/modules/expedition/methode_expedition_".strtolower($code).".modules.php") && ! empty($this->tracking_number)) - { - require_once DOL_DOCUMENT_ROOT."/core/modules/expedition/methode_expedition_".strtolower($code).'.modules.php'; - $shipmethod = new $classname(); - $url = $shipmethod->provider_url_status($this->tracking_number); - } - - if ($url) - { - $this->tracking_url = sprintf(''.($value?$value:'url').'',$url,$url); - } - else - { - $this->tracking_url = $value; - } - } - else - { - $this->tracking_url = $value; - } - } - } + if (!empty($tracking) && !empty($value)) + { + $url = str_replace('{TRACKID}', $value, $tracking); + $this->tracking_url = sprintf(''.($value?$value:'url').'',$url,$url); + } + else + { + $this->tracking_url = $value; + } + } /** * Classify the shipping as invoiced diff --git a/htdocs/expedition/fiche.php b/htdocs/expedition/fiche.php index de3107b663f..996e41a649a 100644 --- a/htdocs/expedition/fiche.php +++ b/htdocs/expedition/fiche.php @@ -5,6 +5,7 @@ * Copyright (C) 2005-2012 Regis Houssin * Copyright (C) 2011-2012 Juanjo Menent * Copyright (C) 2013 Florian Henry + * Copyright (C) 2013 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 @@ -698,16 +699,16 @@ if ($action == 'create') //$lines = $object->fetch_lines(1); $numAsked = count($object->lines); - print ''; + }); + '; print '
'; @@ -904,7 +905,7 @@ if ($action == 'create') print '
'; - print ''; + print ''; print '
'; } @@ -974,7 +975,18 @@ else { $numref = $object->ref; } - $ret=$form->form_confirm($_SERVER['PHP_SELF'].'?id='.$object->id,$langs->trans('ValidateSending'),$langs->trans("ConfirmValidateSending",$numref),'confirm_valid','',0,1); + + $text = $langs->trans("ConfirmValidateSending",$numref); + + if (! empty($conf->notification->enabled)) + { + require_once DOL_DOCUMENT_ROOT .'/core/class/notify.class.php'; + $notify=new Notify($db); + $text.='
'; + $text.=$notify->confirmMessage('SHIPPING_VALIDATE',$object->socid); + } + + $ret=$form->form_confirm($_SERVER['PHP_SELF'].'?id='.$object->id,$langs->trans('ValidateSending'),$text,'confirm_valid','',0,1); if ($ret == 'html') print '
'; } /* diff --git a/htdocs/externalsite/frames.php b/htdocs/externalsite/frames.php index e93dc392d93..825398f3636 100644 --- a/htdocs/externalsite/frames.php +++ b/htdocs/externalsite/frames.php @@ -25,12 +25,12 @@ require '../main.inc.php'; -$langs->load("externalsite@externalsite"); +$langs->load("externalsite"); if (empty($conf->global->EXTERNALSITE_URL)) { llxHeader(); - print '
Module ExternalSite was not configured properly.
'; + print '
'.$langs->trans('ExternalSiteModuleNotComplete').'
'; llxFooter(); } diff --git a/htdocs/externalsite/frametop.php b/htdocs/externalsite/frametop.php index 5808c974909..0bf7a259c8f 100644 --- a/htdocs/externalsite/frametop.php +++ b/htdocs/externalsite/frametop.php @@ -24,7 +24,7 @@ require ("../main.inc.php"); -$langs->load("@externalsite"); +$langs->load("externalsite"); top_htmlhead("",""); top_menu("","","_top"); diff --git a/htdocs/fichinter/apercu.php b/htdocs/fichinter/apercu.php index 2bac1eae624..507a48d2dee 100644 --- a/htdocs/fichinter/apercu.php +++ b/htdocs/fichinter/apercu.php @@ -100,7 +100,7 @@ if ($id > 0 || ! empty($ref)) print "
"; - print ''; + print ''; print ''; print ''; print ''; @@ -110,7 +110,7 @@ if ($id > 0 || ! empty($ref)) { print ""; - print ''; + print ''; print ''; print ''; print ''; diff --git a/htdocs/fichinter/fiche.php b/htdocs/fichinter/fiche.php index 70fed335c93..0684c4695ce 100644 --- a/htdocs/fichinter/fiche.php +++ b/htdocs/fichinter/fiche.php @@ -386,7 +386,7 @@ else if ($action == 'setnote_public' && $user->rights->ficheinter->creer) else if ($action == 'setnote_private' && $user->rights->ficheinter->creer) { $object->fetch($id); - $result=$object->update_note(dol_html_entity_decode(GETPOST('note_private'), ENT_QUOTES)); + $result=$object->update_note(dol_html_entity_decode(GETPOST('note_private'), ENT_QUOTES), '_private'); if ($result < 0) dol_print_error($db,$object->error); } diff --git a/htdocs/fourn/class/fournisseur.facture.class.php b/htdocs/fourn/class/fournisseur.facture.class.php index 759258888cf..ac138636b08 100644 --- a/htdocs/fourn/class/fournisseur.facture.class.php +++ b/htdocs/fourn/class/fournisseur.facture.class.php @@ -141,6 +141,7 @@ class FactureFournisseur extends CommonInvoice $sql.= ", fk_soc"; $sql.= ", datec"; $sql.= ", datef"; + $sql.= ", fk_projet"; $sql.= ", note_private"; $sql.= ", note_public"; $sql.= ", fk_user_author"; @@ -154,6 +155,7 @@ class FactureFournisseur extends CommonInvoice $sql.= ", ".$this->socid; $sql.= ", '".$this->db->idate($now)."'"; $sql.= ", '".$this->db->idate($this->date)."'"; + $sql.= ", ".$this->fk_project; $sql.= ", '".$this->db->escape($this->note_private)."'"; $sql.= ", '".$this->db->escape($this->note_public)."'"; $sql.= ", ".$user->id.","; diff --git a/htdocs/fourn/class/fournisseur.product.class.php b/htdocs/fourn/class/fournisseur.product.class.php index 9a86f0e9ee3..8d5a3474bf8 100644 --- a/htdocs/fourn/class/fournisseur.product.class.php +++ b/htdocs/fourn/class/fournisseur.product.class.php @@ -296,7 +296,7 @@ class ProductFournisseur extends Product function fetch_product_fournisseur_price($rowid) { $sql = "SELECT pfp.rowid, pfp.price, pfp.quantity, pfp.unitprice, pfp.remise_percent, pfp.remise, pfp.tva_tx, pfp.fk_availability,"; - $sql.= " pfp.fk_soc, pfp.ref_fourn, pfp.fk_product, pfp.charges, pfp.unitcharges, pfp.recuperableonly as fourn_tva_npr"; + $sql.= " pfp.fk_soc, pfp.ref_fourn, pfp.fk_product, pfp.charges, pfp.unitcharges"; // , pfp.recuperableonly as fourn_tva_npr"; FIXME this field not exist in llx_product_fournisseur_price $sql.= " FROM ".MAIN_DB_PREFIX."product_fournisseur_price as pfp"; $sql.= " WHERE pfp.rowid = ".$rowid; @@ -320,7 +320,7 @@ class ProductFournisseur extends Product $this->product_id = $obj->fk_product; // deprecated $this->fk_product = $obj->fk_product; $this->fk_availability = $obj->fk_availability; - $this->fourn_tva_npr = $obj->fourn_tva_npr; + //$this->fourn_tva_npr = $obj->fourn_tva_npr; // FIXME this field not exist in llx_product_fournisseur_price return 1; } else diff --git a/htdocs/fourn/commande/fiche.php b/htdocs/fourn/commande/fiche.php index 653397cfaf5..cad571686e8 100644 --- a/htdocs/fourn/commande/fiche.php +++ b/htdocs/fourn/commande/fiche.php @@ -1077,7 +1077,7 @@ elseif (! empty($object->id)) require_once DOL_DOCUMENT_ROOT .'/core/class/notify.class.php'; $notify=new Notify($db); $text.='
'; - $text.=$notify->confirmMessage(3,$object->socid); + $text.=$notify->confirmMessage('ORDER_SUPPLIER_APPROVE', $object->socid); } $ret=$form->form_confirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('ValidateOrder'), $text, 'confirm_valid', '', 0, 1); @@ -1762,10 +1762,10 @@ elseif (! empty($object->id)) print ""; } - print "
"; + print "
"; - print '
'; + print '
'; //print '
+ + +
+textwithpicto('', $langs->trans("ExtrafieldParamHelp".$type),1,0)?>
% + % + +
".$langs->trans("Intervention")." PDF'.$object->ref.'.pdf'.$object->ref.'.pdf'.dol_print_size(dol_filesize($file)).''.dol_print_date(dol_filemtime($file),'dayhour').'
Fiche d'intervention detaillee'.$object->ref.'-detail.pdf'.$object->ref.'-detail.pdf'.dol_print_size(dol_filesize($filedetail)).''.dol_print_date(dol_filemtime($filedetail),'dayhour').'
'; + + // Project + if (! empty($conf->projet->enabled)) + { + $langs->load('projects'); + print ''; + } print ''; print ''."\n"; -print ''."\n"; +print ''."\n"; print ''."\n"; print ''."\n"; */ diff --git a/htdocs/holiday/index.php b/htdocs/holiday/index.php index c269a148615..06c75411453 100644 --- a/htdocs/holiday/index.php +++ b/htdocs/holiday/index.php @@ -1,6 +1,6 @@ - * Copyright (C) 2012 Laurent Destailleur + * Copyright (C) 2013 Laurent Destailleur * Copyright (C) 2012 Regis Houssin * * This program is free software; you can redistribute it and/or modify @@ -228,7 +228,6 @@ if ($id > 0) print "\n"; print '
'; //print ''; // ancre diff --git a/htdocs/fourn/commande/note.php b/htdocs/fourn/commande/note.php index 7d4fa0cd496..9e629414b63 100644 --- a/htdocs/fourn/commande/note.php +++ b/htdocs/fourn/commande/note.php @@ -54,9 +54,9 @@ if ($action == 'setnote_public' && $user->rights->fournisseur->commande->creer) $result=$object->update_note(dol_html_entity_decode(GETPOST('note_public'), ENT_QUOTES),'_public'); if ($result < 0) dol_print_error($db,$object->error); } -elseif ($action == 'setnote' && $user->rights->fournisseur->commande->creer) +elseif ($action == 'setnote_private' && $user->rights->fournisseur->commande->creer) { - $result=$object->update_note(dol_html_entity_decode(GETPOST('note'), ENT_QUOTES)); + $result=$object->update_note(dol_html_entity_decode(GETPOST('note_private'), ENT_QUOTES), '_private'); if ($result < 0) dol_print_error($db,$object->error); } diff --git a/htdocs/fourn/facture/fiche.php b/htdocs/fourn/facture/fiche.php index 6ed624b82fa..1ea01631f79 100644 --- a/htdocs/fourn/facture/fiche.php +++ b/htdocs/fourn/facture/fiche.php @@ -41,6 +41,8 @@ if (!empty($conf->produit->enabled)) require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php'; if (!empty($conf->projet->enabled)) require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php'; +if (! empty($conf->projet->enabled)) + require_once DOL_DOCUMENT_ROOT.'/core/lib/project.lib.php'; $langs->load('bills'); @@ -271,6 +273,7 @@ elseif ($action == 'add' && $user->rights->fournisseur->facture->creer) // Creation facture $object->ref = $_POST['ref']; $object->ref_supplier = $_POST['ref_supplier']; + $object->fk_project = GETPOST('projectid'); $object->socid = $_POST['socid']; $object->libelle = $_POST['libelle']; $object->date = $datefacture; @@ -1153,6 +1156,15 @@ if ($action == 'create') print '
'.$langs->trans('DateMaxPayment').''; $form->select_date($datedue,'ech','','','',"add",1,1); print '
'.$langs->trans('Project').''; + select_projects(-1, $projectid, 'projectid'); + print '
'.$langs->trans('NotePublic').''; @@ -1330,12 +1342,12 @@ else } $text=$langs->trans('ConfirmValidateBill',$numref); - /*if (! empty($conf->notification->enabled)) - { - require_once DOL_DOCUMENT_ROOT .'/core/class/notify.class.php'; - $notify=new Notify($db); - $text.='
'; - $text.=$notify->confirmMessage('NOTIFY_VAL_FAC_SUP',$object->socid); + /*if (! empty($conf->notification->enabled)) + { + require_once DOL_DOCUMENT_ROOT .'/core/class/notify.class.php'; + $notify=new Notify($db); + $text.='
'; + $text.=$notify->confirmMessage('BILL_SUPPLIER_VALIDATE',$object->socid); }*/ $formquestion=array(); @@ -2054,7 +2066,7 @@ else print ''.$langs->trans('Delete').''; } print ''; - print '
'; + print '
'; if ($action != 'edit') { diff --git a/htdocs/fourn/facture/index.php b/htdocs/fourn/facture/index.php index 3d55e528daf..5934029aef3 100644 --- a/htdocs/fourn/facture/index.php +++ b/htdocs/fourn/facture/index.php @@ -1,7 +1,7 @@ * Copyright (C) 2004-2013 Laurent Destailleur - * Copyright (C) 2005-2012 Regis Houssin + * Copyright (C) 2005-2013 Regis Houssin * Copyright (C) 2013 Philippe Grand * * This program is free software; you can redistribute it and/or modify @@ -156,12 +156,12 @@ if (GETPOST("search_societe")) if (GETPOST("search_montant_ht")) { - $sql .= " AND fac.total_ht = '".$db->escape(GETPOST("search_montant_ht"))."'"; + $sql .= " AND fac.total_ht = '".$db->escape(price2num(GETPOST("search_montant_ht")))."'"; } if (GETPOST("search_montant_ttc")) { - $sql .= " AND fac.total_ttc = '".$db->escape(GETPOST("search_montant_ttc"))."'"; + $sql .= " AND fac.total_ttc = '".$db->escape(price2num(GETPOST("search_montant_ttc")))."'"; } $sql.= $db->order($sortfield,$sortorder); diff --git a/htdocs/fourn/fiche.php b/htdocs/fourn/fiche.php index 2d9a7a151b3..13ef8ea8523 100644 --- a/htdocs/fourn/fiche.php +++ b/htdocs/fourn/fiche.php @@ -85,8 +85,9 @@ if ($object->fetch($id)) dol_fiche_head($head, 'supplier', $langs->trans("ThirdParty"),0,'company'); - print ''; - print ''; + //print '
'; + print '
'; + //print ''; + //print ''; - print '
'; print ''; print '
'.$langs->trans("ThirdPartyName").''; @@ -216,7 +217,11 @@ if ($object->fetch($id)) print '
'; - print '
'; + + print '
'; + //print '
'; + + $var=true; $MAXLIST=5; @@ -367,9 +372,12 @@ if ($object->fetch($id)) } } - print '
' . "\n"; - print '
'; + print '
'; + print '
'; + //print '
' . "\n"; + + dol_fiche_end(); /* diff --git a/htdocs/holiday/admin/holiday.php b/htdocs/holiday/admin/holiday.php index 583ab228c9a..6e7216332ea 100644 --- a/htdocs/holiday/admin/holiday.php +++ b/htdocs/holiday/admin/holiday.php @@ -278,7 +278,7 @@ $var=true; /*$var=!$var; print '
'.$langs->trans('GroupToValidateCP').''.$langs->trans('GroupToValidateCP').''.$cp->selectUserGroup('userGroup').'

'; - } else { @@ -242,7 +241,15 @@ $nbaquis=$holiday->getCPforUser($user_id); $nbdeduced=$holiday->getConfCP('nbHolidayDeducted'); $nb_holiday = $nbaquis / $nbdeduced; print $langs->trans('SoldeCPUser',round($nb_holiday,2)).($nbdeduced != 1 ? ' ('.$nbaquis.' / '.$nbdeduced.')' : ''); -print ''; + +if ($id > 0) +{ + dol_fiche_end(); + print '
'; +} +else { + print ''; +} print '
'."\n"; print ''; diff --git a/htdocs/imports/import.php b/htdocs/imports/import.php index 85c8410da7e..d6d35335bed 100644 --- a/htdocs/imports/import.php +++ b/htdocs/imports/import.php @@ -569,7 +569,7 @@ if ($step == 3 && $datatoimport) print ''; print ''; print ''; @@ -742,7 +742,7 @@ if ($step == 4 && $datatoimport) print ''; @@ -1172,7 +1172,7 @@ if ($step == 5 && $datatoimport) print ''; @@ -1506,7 +1506,7 @@ if ($step == 6 && $datatoimport) print ''; diff --git a/htdocs/includes/odtphp/odf.php b/htdocs/includes/odtphp/odf.php index 7e72eb6f7e2..4f91157438b 100644 --- a/htdocs/includes/odtphp/odf.php +++ b/htdocs/includes/odtphp/odf.php @@ -18,152 +18,152 @@ class OdfException extends Exception class Odf { protected $config = array( - 'ZIP_PROXY' => 'PclZipProxy', // PclZipProxy, PhpZipProxy - 'DELIMITER_LEFT' => '{', - 'DELIMITER_RIGHT' => '}', - 'PATH_TO_TMP' => '/tmp' - ); - protected $file; - protected $contentXml; // To store content of content.xml file - protected $stylesXml; // To store content of styles.xml file - protected $manifestXml; // To store content of META-INF/manifest.xml file - protected $tmpfile; - protected $tmpdir=''; - protected $images = array(); - protected $vars = array(); - protected $segments = array(); - const PIXEL_TO_CM = 0.026458333; - /** - * Class constructor - * - * @param string $filename the name of the odt file - * @throws OdfException - */ - public function __construct($filename, $config = array()) - { - clearstatcache(); + 'ZIP_PROXY' => 'PclZipProxy', // PclZipProxy, PhpZipProxy + 'DELIMITER_LEFT' => '{', + 'DELIMITER_RIGHT' => '}', + 'PATH_TO_TMP' => '/tmp' + ); + protected $file; + protected $contentXml; // To store content of content.xml file + protected $stylesXml; // To store content of styles.xml file + protected $manifestXml; // To store content of META-INF/manifest.xml file + protected $tmpfile; + protected $tmpdir=''; + protected $images = array(); + protected $vars = array(); + protected $segments = array(); + const PIXEL_TO_CM = 0.026458333; + /** + * Class constructor + * + * @param string $filename the name of the odt file + * @throws OdfException + */ + public function __construct($filename, $config = array()) + { + clearstatcache(); - if (! is_array($config)) { - throw new OdfException('Configuration data must be provided as array'); + if (! is_array($config)) { + throw new OdfException('Configuration data must be provided as array'); + } + foreach ($config as $configKey => $configValue) { + if (array_key_exists($configKey, $this->config)) { + $this->config[$configKey] = $configValue; } - foreach ($config as $configKey => $configValue) { - if (array_key_exists($configKey, $this->config)) { - $this->config[$configKey] = $configValue; - } - } - - $md5uniqid = md5(uniqid()); - if ($this->config['PATH_TO_TMP']) $this->tmpdir = preg_replace('|[\/]$|','',$this->config['PATH_TO_TMP']); // Remove last \ or / - $this->tmpdir .= ($this->tmpdir?'/':'').$md5uniqid; - $this->tmpfile = $this->tmpdir.'/'.$md5uniqid.'.odt'; // We keep .odt extension to allow OpenOffice usage during debug. - - // A working directory is required for some zip proxy like PclZipProxy - if (in_array($this->config['ZIP_PROXY'],array('PclZipProxy')) && ! is_dir($this->config['PATH_TO_TMP'])) { - throw new OdfException('Temporary directory '.$this->config['PATH_TO_TMP'].' must exists'); - } - - // Create tmp direcoty (will be deleted in destructor) - if (!file_exists($this->tmpdir)) { - $result=mkdir($this->tmpdir); - } - - // Load zip proxy - $zipHandler = $this->config['ZIP_PROXY']; - if (!defined('PCLZIP_TEMPORARY_DIR')) define('PCLZIP_TEMPORARY_DIR',$this->tmpdir); - include_once('zip/'.$zipHandler.'.php'); - if (! class_exists($this->config['ZIP_PROXY'])) { - throw new OdfException($this->config['ZIP_PROXY'] . ' class not found - check your php settings'); - } - $this->file = new $zipHandler($this->tmpdir); - - - if ($this->file->open($filename) !== true) { // This also create the tmpdir directory - throw new OdfException("Error while Opening the file '$filename' - Check your odt filename"); - } - if (($this->contentXml = $this->file->getFromName('content.xml')) === false) { - throw new OdfException("Nothing to parse - Check that the content.xml file is correctly formed in source file '$filename'"); - } - if (($this->manifestXml = $this->file->getFromName('META-INF/manifest.xml')) === false) { - throw new OdfException("Something is wrong with META-INF/manifest.xml in source file '$filename'"); - } - if (($this->stylesXml = $this->file->getFromName('styles.xml')) === false) { - throw new OdfException("Nothing to parse - Check that the styles.xml file is correctly formed in source file '$filename'"); - } - $this->file->close(); - - - //print "tmpdir=".$tmpdir; - //print "filename=".$filename; - //print "tmpfile=".$tmpfile; - - copy($filename, $this->tmpfile); - - $this->_moveRowSegments(); } - /** - * Assing a template variable - * - * @param string $key name of the variable within the template - * @param string $value replacement value - * @param bool $encode if true, special XML characters are encoded - * @throws OdfException - * @return odf - */ - public function setVars($key, $value, $encode = true, $charset = 'ISO-8859') - { - $tag = $this->config['DELIMITER_LEFT'] . $key . $this->config['DELIMITER_RIGHT']; - // TODO Warning string may be: - // {aaa} - // instead of {aaa} so we should enhance this function. - //print $key.'-'.$value.'-'.strpos($this->contentXml, $this->config['DELIMITER_LEFT'] . $key . $this->config['DELIMITER_RIGHT']).'
'; - if (strpos($this->contentXml, $tag) === false && strpos($this->stylesXml , $tag) === false) { - //if (strpos($this->contentXml, '">'. $key . '') === false) { - throw new OdfException("var $key not found in the document"); - //} - } - $value = $encode ? htmlspecialchars($value) : $value; - $value = ($charset == 'ISO-8859') ? utf8_encode($value) : $value; - $this->vars[$tag] = str_replace("\n", "", $value); - return $this; + $md5uniqid = md5(uniqid()); + if ($this->config['PATH_TO_TMP']) $this->tmpdir = preg_replace('|[\/]$|','',$this->config['PATH_TO_TMP']); // Remove last \ or / + $this->tmpdir .= ($this->tmpdir?'/':'').$md5uniqid; + $this->tmpfile = $this->tmpdir.'/'.$md5uniqid.'.odt'; // We keep .odt extension to allow OpenOffice usage during debug. + + // A working directory is required for some zip proxy like PclZipProxy + if (in_array($this->config['ZIP_PROXY'],array('PclZipProxy')) && ! is_dir($this->config['PATH_TO_TMP'])) { + throw new OdfException('Temporary directory '.$this->config['PATH_TO_TMP'].' must exists'); } - - /** - * Assing a template variable - * - * @param string $key name of the variable within the template - * @param string $value replacement value - * @param bool $encode if true, special XML characters are encoded - * @throws OdfException - * @return odf - */ - public function setVarsHeadFooter($key, $value, $encode = true, $charset = 'ISO-8859') - { - $tag = $this->config['DELIMITER_LEFT'] . $key . $this->config['DELIMITER_RIGHT']; - // TODO Warning string may be: - // {aaa} - // instead of {aaa} so we should enhance this function. - //print $key.'-'.$value.'-'.strpos($this->contentXml, $this->config['DELIMITER_LEFT'] . $key . $this->config['DELIMITER_RIGHT']).'
'; - if (strpos($this->stylesXml, $tag) === false && strpos($this->stylesXml , $tag) === false) { + + // Create tmp direcoty (will be deleted in destructor) + if (!file_exists($this->tmpdir)) { + $result=mkdir($this->tmpdir); + } + + // Load zip proxy + $zipHandler = $this->config['ZIP_PROXY']; + if (!defined('PCLZIP_TEMPORARY_DIR')) define('PCLZIP_TEMPORARY_DIR',$this->tmpdir); + include_once('zip/'.$zipHandler.'.php'); + if (! class_exists($this->config['ZIP_PROXY'])) { + throw new OdfException($this->config['ZIP_PROXY'] . ' class not found - check your php settings'); + } + $this->file = new $zipHandler($this->tmpdir); + + + if ($this->file->open($filename) !== true) { // This also create the tmpdir directory + throw new OdfException("Error while Opening the file '$filename' - Check your odt filename"); + } + if (($this->contentXml = $this->file->getFromName('content.xml')) === false) { + throw new OdfException("Nothing to parse - Check that the content.xml file is correctly formed in source file '$filename'"); + } + if (($this->manifestXml = $this->file->getFromName('META-INF/manifest.xml')) === false) { + throw new OdfException("Something is wrong with META-INF/manifest.xml in source file '$filename'"); + } + if (($this->stylesXml = $this->file->getFromName('styles.xml')) === false) { + throw new OdfException("Nothing to parse - Check that the styles.xml file is correctly formed in source file '$filename'"); + } + $this->file->close(); + + + //print "tmpdir=".$tmpdir; + //print "filename=".$filename; + //print "tmpfile=".$tmpfile; + + copy($filename, $this->tmpfile); + + $this->_moveRowSegments(); + } + + /** + * Assing a template variable + * + * @param string $key name of the variable within the template + * @param string $value replacement value + * @param bool $encode if true, special XML characters are encoded + * @throws OdfException + * @return odf + */ + public function setVars($key, $value, $encode = true, $charset = 'ISO-8859') + { + $tag = $this->config['DELIMITER_LEFT'] . $key . $this->config['DELIMITER_RIGHT']; + // TODO Warning string may be: + // {aaa} + // instead of {aaa} so we should enhance this function. + //print $key.'-'.$value.'-'.strpos($this->contentXml, $this->config['DELIMITER_LEFT'] . $key . $this->config['DELIMITER_RIGHT']).'
'; + if (strpos($this->contentXml, $tag) === false && strpos($this->stylesXml , $tag) === false) { //if (strpos($this->contentXml, '">'. $key . '') === false) { - throw new OdfException("var $key not found in the document"); - //} - } - $value = $encode ? htmlspecialchars($value) : $value; - $value = ($charset == 'ISO-8859') ? utf8_encode($value) : $value; - $this->vars[$tag] = str_replace("\n", "", $value); - return $this; + throw new OdfException("var $key not found in the document"); + //} } + $value = $encode ? htmlspecialchars($value) : $value; + $value = ($charset == 'ISO-8859') ? utf8_encode($value) : $value; + $this->vars[$tag] = str_replace("\n", "", $value); + return $this; + } - /** - * Evaluating php codes inside the ODT and output the buffer (print, echo) inplace of the code - * - */ - public function phpEval() - { - preg_match_all('/[\{\<]\?(php)?\s+(?P.+)\?[\}\>]/iU',$this->contentXml, $matches); // detecting all {?php code ?} or - for ($i=0;$i < count($matches['content']);$i++) { - try { + /** + * Assing a template variable + * + * @param string $key name of the variable within the template + * @param string $value replacement value + * @param bool $encode if true, special XML characters are encoded + * @throws OdfException + * @return odf + */ + public function setVarsHeadFooter($key, $value, $encode = true, $charset = 'ISO-8859') + { + $tag = $this->config['DELIMITER_LEFT'] . $key . $this->config['DELIMITER_RIGHT']; + // TODO Warning string may be: + // {aaa} + // instead of {aaa} so we should enhance this function. + //print $key.'-'.$value.'-'.strpos($this->contentXml, $this->config['DELIMITER_LEFT'] . $key . $this->config['DELIMITER_RIGHT']).'
'; + if (strpos($this->stylesXml, $tag) === false && strpos($this->stylesXml , $tag) === false) { + //if (strpos($this->contentXml, '">'. $key . '') === false) { + throw new OdfException("var $key not found in the document"); + //} + } + $value = $encode ? htmlspecialchars($value) : $value; + $value = ($charset == 'ISO-8859') ? utf8_encode($value) : $value; + $this->vars[$tag] = str_replace("\n", "", $value); + return $this; + } + + /** + * Evaluating php codes inside the ODT and output the buffer (print, echo) inplace of the code + * + */ + public function phpEval() + { + preg_match_all('/[\{\<]\?(php)?\s+(?P.+)\?[\}\>]/iU',$this->contentXml, $matches); // detecting all {?php code ?} or + for ($i=0;$i < count($matches['content']);$i++) { + try { $ob_output = ''; // flush the output for each code. This var will be filled in by the eval($code) and output buffering : any print or echo or output will be redirected into this variable $code = $matches['content'][$i]; ob_start(); @@ -171,363 +171,400 @@ class Odf $ob_output = ob_get_contents(); // send the content of the buffer into $ob_output $this->contentXml = str_replace($matches[0][$i], $ob_output, $this->contentXml); ob_end_clean(); - } catch (Exception $e) { - ob_end_clean(); - $this->contentXml = str_replace($matches[0][$i], 'ERROR: there was a problem while evaluating this portion of code, please fix it: '.$e, $this->contentXml); - } + } catch (Exception $e) { + ob_end_clean(); + $this->contentXml = str_replace($matches[0][$i], 'ERROR: there was a problem while evaluating this portion of code, please fix it: '.$e, $this->contentXml); } - return 0; } + return 0; + } - /** - * Assign a template variable as a picture - * - * @param string $key name of the variable within the template - * @param string $value path to the picture - * @throws OdfException - * @return odf - */ - public function setImage($key, $value) - { - $filename = strtok(strrchr($value, '/'), '/.'); - $file = substr(strrchr($value, '/'), 1); - $size = @getimagesize($value); - if ($size === false) { - throw new OdfException("Invalid image"); - } - list ($width, $height) = $size; - $width *= self::PIXEL_TO_CM; - $height *= self::PIXEL_TO_CM; - $xml = << IMG; - $this->images[$value] = $file; - $this->setVars($key, $xml, false); - return $this; - } + $this->images[$value] = $file; + $this->setVars($key, $xml, false); + return $this; + } - /** - * Move segment tags for lines of tables - * Called automatically within the constructor - * - * @return void - */ - private function _moveRowSegments() + /** + * Move segment tags for lines of tables + * Called automatically within the constructor + * + * @return void + */ + private function _moveRowSegments() + { + // Search all possible rows in the document + $reg1 = "#]*>(.*)#smU"; + preg_match_all($reg1, $this->contentXml, $matches); + for ($i = 0, $size = count($matches[0]); $i < $size; $i++) { + // Check if the current row contains a segment row.* + $reg2 = '#\[!--\sBEGIN\s(row.[\S]*)\s--\](.*)\[!--\sEND\s\\1\s--\]#sm'; + if (preg_match($reg2, $matches[0][$i], $matches2)) { + $balise = str_replace('row.', '', $matches2[1]); + // Move segment tags around the row + $replace = array( + '[!-- BEGIN ' . $matches2[1] . ' --]' => '', + '[!-- END ' . $matches2[1] . ' --]' => '', + ' '[!-- BEGIN ' . $balise . ' --]' => '[!-- END ' . $balise . ' --]' + ); + $replacedXML = str_replace(array_keys($replace), array_values($replace), $matches[0][$i]); + $this->contentXml = str_replace($matches[0][$i], $replacedXML, $this->contentXml); + } + } + } + + /** + * Merge template variables + * Called automatically for a save + * + * @param string $type 'content' or 'styles' + * @return void + */ + private function _parse($type='content') + { + // Conditionals substitution + // Note: must be done before content substitution, else the variable will be replaced by its value and the conditional won't work anymore + foreach($this->vars as $key => $value) { - // Search all possible rows in the document - $reg1 = "#]*>(.*)#smU"; - preg_match_all($reg1, $this->contentXml, $matches); - for ($i = 0, $size = count($matches[0]); $i < $size; $i++) { - // Check if the current row contains a segment row.* - $reg2 = '#\[!--\sBEGIN\s(row.[\S]*)\s--\](.*)\[!--\sEND\s\\1\s--\]#sm'; - if (preg_match($reg2, $matches[0][$i], $matches2)) { - $balise = str_replace('row.', '', $matches2[1]); - // Move segment tags around the row - $replace = array( - '[!-- BEGIN ' . $matches2[1] . ' --]' => '', - '[!-- END ' . $matches2[1] . ' --]' => '', - ' '[!-- BEGIN ' . $balise . ' --]' => '[!-- END ' . $balise . ' --]' - ); - $replacedXML = str_replace(array_keys($replace), array_values($replace), $matches[0][$i]); - $this->contentXml = str_replace($matches[0][$i], $replacedXML, $this->contentXml); + // If value is true (not 0 nor false nor null nor empty string) + if($value) + { + // Remove the IF tag + $this->contentXml = str_replace('[!-- IF '.$key.' --]', '', $this->contentXml); + // Remove everything between the ELSE tag (if it exists) and the ENDIF tag + $reg = '@(\[!--\sELSE\s' . $key . '\s--\](.*))?\[!--\sENDIF\s' . $key . '\s--\]@smU'; // U modifier = all quantifiers are non-greedy + $this->contentXml = preg_replace($reg, '', $this->contentXml); + } + // Else the value is false, then two cases: no ELSE and we're done, or there is at least one place where there is an ELSE clause, then we replace it + else + { + // Find all conditional blocks for this variable: from IF to ELSE and to ENDIF + $reg = '@\[!--\sIF\s' . $key . '\s--\](.*)(\[!--\sELSE\s' . $key . '\s--\](.*))?\[!--\sENDIF\s' . $key . '\s--\]@smU'; // U modifier = all quantifiers are non-greedy + preg_match_all($reg, $this->contentXml, $matches, PREG_SET_ORDER); + foreach($matches as $match) { // For each match, if there is an ELSE clause, we replace the whole block by the value in the ELSE clause + if (!empty($match[3])) $this->contentXml = str_replace($match[0], $match[3], $this->contentXml); } + // Cleanup the other conditional blocks (all the others where there were no ELSE clause, we can just remove them altogether) + $this->contentXml = preg_replace($reg, '', $this->contentXml); } } - /** - * Merge template variables - * Called automatically for a save - * - * @param string $type 'content' or 'styles' - * @return void - */ - private function _parse($type='content') - { - // Conditionals substitution - // Note: must be done before content substitution, else the variable will be replaced by its value and the conditional won't work anymore - foreach($this->vars as $key => $value) - { - // If value is true (not 0 nor false nor null nor empty string) - if($value) - { - // Remove the IF tag - $this->contentXml = str_replace('[!-- IF '.$key.' --]', '', $this->contentXml); - // Remove everything between the ELSE tag (if it exists) and the ENDIF tag - $reg = '@(\[!--\sELSE\s' . $key . '\s--\](.*))?\[!--\sENDIF\s' . $key . '\s--\]@smU'; // U modifier = all quantifiers are non-greedy - $this->contentXml = preg_replace($reg, '', $this->contentXml); - } - // Else the value is false, then two cases: no ELSE and we're done, or there is at least one place where there is an ELSE clause, then we replace it - else - { - // Find all conditional blocks for this variable: from IF to ELSE and to ENDIF - $reg = '@\[!--\sIF\s' . $key . '\s--\](.*)(\[!--\sELSE\s' . $key . '\s--\](.*))?\[!--\sENDIF\s' . $key . '\s--\]@smU'; // U modifier = all quantifiers are non-greedy - preg_match_all($reg, $this->contentXml, $matches, PREG_SET_ORDER); - foreach($matches as $match) { // For each match, if there is an ELSE clause, we replace the whole block by the value in the ELSE clause - if (!empty($match[3])) $this->contentXml = str_replace($match[0], $match[3], $this->contentXml); - } - // Cleanup the other conditional blocks (all the others where there were no ELSE clause, we can just remove them altogether) - $this->contentXml = preg_replace($reg, '', $this->contentXml); - } - } + // Content (variable) substitution + if ($type == 'content') $this->contentXml = str_replace(array_keys($this->vars), array_values($this->vars), $this->contentXml); + // Styles substitution + if ($type == 'styles') $this->stylesXml = str_replace(array_keys($this->vars), array_values($this->vars), $this->stylesXml); - // Content (variable) substitution - if ($type == 'content') $this->contentXml = str_replace(array_keys($this->vars), array_values($this->vars), $this->contentXml); - // Styles substitution - if ($type == 'styles') $this->stylesXml = str_replace(array_keys($this->vars), array_values($this->vars), $this->stylesXml); + } + /** + * Add the merged segment to the document + * + * @param Segment $segment + * @throws OdfException + * @return odf + */ + public function mergeSegment(Segment $segment) + { + if (! array_key_exists($segment->getName(), $this->segments)) { + throw new OdfException($segment->getName() . 'cannot be parsed, has it been set yet ?'); } + $string = $segment->getName(); + // $reg = '@]*>\[!--\sBEGIN\s' . $string . '\s--\](.*)\[!--.+END\s' . $string . '\s--\]<\/text:p>@smU'; + $reg = '@\[!--\sBEGIN\s' . $string . '\s--\](.*)\[!--.+END\s' . $string . '\s--\]@smU'; + $this->contentXml = preg_replace($reg, $segment->getXmlParsed(), $this->contentXml); + return $this; + } - /** - * Add the merged segment to the document - * - * @param Segment $segment - * @throws OdfException - * @return odf - */ - public function mergeSegment(Segment $segment) - { - if (! array_key_exists($segment->getName(), $this->segments)) { - throw new OdfException($segment->getName() . 'cannot be parsed, has it been set yet ?'); - } - $string = $segment->getName(); - // $reg = '@]*>\[!--\sBEGIN\s' . $string . '\s--\](.*)\[!--.+END\s' . $string . '\s--\]<\/text:p>@smU'; - $reg = '@\[!--\sBEGIN\s' . $string . '\s--\](.*)\[!--.+END\s' . $string . '\s--\]@smU'; - $this->contentXml = preg_replace($reg, $segment->getXmlParsed(), $this->contentXml); - return $this; - } + /** + * Display all the current template variables + * + * @return string + */ + public function printVars() + { + return print_r('
' . print_r($this->vars, true) . '
', true); + } - /** - * Display all the current template variables - * - * @return string - */ - public function printVars() - { - return print_r('
' . print_r($this->vars, true) . '
', true); - } + /** + * Display the XML content of the file from odt document + * as it is at the moment + * + * @return string + */ + public function __toString() + { + return $this->contentXml; + } - /** - * Display the XML content of the file from odt document - * as it is at the moment - * - * @return string - */ - public function __toString() - { - return $this->contentXml; - } + /** + * Display loop segments declared with setSegment() + * + * @return string + */ + public function printDeclaredSegments() + { + return '
' . print_r(implode(' ', array_keys($this->segments)), true) . '
'; + } - /** - * Display loop segments declared with setSegment() - * - * @return string - */ - public function printDeclaredSegments() - { - return '
' . print_r(implode(' ', array_keys($this->segments)), true) . '
'; - } - - /** - * Declare a segment in order to use it in a loop - * - * @param string $segment - * @throws OdfException - * @return Segment - */ - public function setSegment($segment) - { - if (array_key_exists($segment, $this->segments)) { - return $this->segments[$segment]; - } - // $reg = "#\[!--\sBEGIN\s$segment\s--\]<\/text:p>(.*)\[!--\sEND\s$segment\s--\]#sm"; - $reg = "#\[!--\sBEGIN\s$segment\s--\](.*)\[!--\sEND\s$segment\s--\]#sm"; - if (preg_match($reg, html_entity_decode($this->contentXml), $m) == 0) { - throw new OdfException("'$segment' segment not found in the document"); - } - $this->segments[$segment] = new Segment($segment, $m[1], $this); + /** + * Declare a segment in order to use it in a loop + * + * @param string $segment + * @throws OdfException + * @return Segment + */ + public function setSegment($segment) + { + if (array_key_exists($segment, $this->segments)) { return $this->segments[$segment]; } - /** - * Save the odt file on the disk - * - * @param string $file name of the desired file - * @throws OdfException - * @return void - */ - public function saveToDisk($file = null) - { - if ($file !== null && is_string($file)) { - if (file_exists($file) && !(is_file($file) && is_writable($file))) { - throw new OdfException('Permission denied : can\'t create ' . $file); - } - $this->_save(); - copy($this->tmpfile, $file); - } else { - $this->_save(); - } + // $reg = "#\[!--\sBEGIN\s$segment\s--\]<\/text:p>(.*)\[!--\sEND\s$segment\s--\]#sm"; + $reg = "#\[!--\sBEGIN\s$segment\s--\](.*)\[!--\sEND\s$segment\s--\]#sm"; + if (preg_match($reg, html_entity_decode($this->contentXml), $m) == 0) { + throw new OdfException("'$segment' segment not found in the document"); } - - /** - * Write output file onto disk - * - * @throws OdfException - * @return void - */ - private function _save() - { - $res=$this->file->open($this->tmpfile); // tmpfile is odt template - $this->_parse('content'); - $this->_parse('styles'); - - if (! $this->file->addFromString('content.xml', $this->contentXml)) { - throw new OdfException('Error during file export addFromString'); + $this->segments[$segment] = new Segment($segment, $m[1], $this); + return $this->segments[$segment]; + } + /** + * Save the odt file on the disk + * + * @param string $file name of the desired file + * @throws OdfException + * @return void + */ + public function saveToDisk($file = null) + { + if ($file !== null && is_string($file)) { + if (file_exists($file) && !(is_file($file) && is_writable($file))) { + throw new OdfException('Permission denied : can\'t create ' . $file); } - if (! $this->file->addFromString('styles.xml', $this->stylesXml)) { - throw new OdfException('Error during file export addFromString'); - } - foreach ($this->images as $imageKey => $imageValue) { - // Add the image inside the ODT document - $this->file->addFile($imageKey, 'Pictures/' . $imageValue); - // Add the image to the Manifest (which maintains a list of images, necessary to avoid "Corrupt ODT file. Repair?" when opening the file with LibreOffice) - $this->addImageToManifest($imageValue); - } - if (! $this->file->addFromString('./META-INF/manifest.xml', $this->manifestXml)) { - throw new OdfException('Error during file export: manifest.xml'); - } - $this->file->close(); - } - - /** - * Update Manifest file according to added image files - * - * @param string $file Image file to add into manifest content - */ - public function addImageToManifest($file) - { - // Get the file extension - $ext = substr(strrchr($val, '.'), 1); - // Create the correct image XML entry to add to the manifest (this is necessary because ODT format requires that we keep a list of the images in the manifest.xml) - $add = ' '."\n"; - // Append the image to the manifest - $this->manifestXml = str_replace('', $add.'', $this->manifestXml); // we replace the manifest closing tag by the image XML entry + manifest closing tag (this results in appending the data, we do not overwrite anything) - } - - /** - * Export the file as attached file by HTTP - * - * @param string $name (optional) - * @throws OdfException - * @return void - */ - public function exportAsAttachedFile($name="") - { $this->_save(); + copy($this->tmpfile, $file); + } else { + $this->_save(); + } + } + + /** + * Write output file onto disk + * + * @throws OdfException + * @return void + */ + private function _save() + { + $res=$this->file->open($this->tmpfile); // tmpfile is odt template + $this->_parse('content'); + $this->_parse('styles'); + + if (! $this->file->addFromString('content.xml', $this->contentXml)) { + throw new OdfException('Error during file export addFromString'); + } + if (! $this->file->addFromString('styles.xml', $this->stylesXml)) { + throw new OdfException('Error during file export addFromString'); + } + foreach ($this->images as $imageKey => $imageValue) { + // Add the image inside the ODT document + $this->file->addFile($imageKey, 'Pictures/' . $imageValue); + // Add the image to the Manifest (which maintains a list of images, necessary to avoid "Corrupt ODT file. Repair?" when opening the file with LibreOffice) + $this->addImageToManifest($imageValue); + } + if (! $this->file->addFromString('./META-INF/manifest.xml', $this->manifestXml)) { + throw new OdfException('Error during file export: manifest.xml'); + } + $this->file->close(); + } + + /** + * Update Manifest file according to added image files + * + * @param string $file Image file to add into manifest content + */ + public function addImageToManifest($file) + { + // Get the file extension + $ext = substr(strrchr($val, '.'), 1); + // Create the correct image XML entry to add to the manifest (this is necessary because ODT format requires that we keep a list of the images in the manifest.xml) + $add = ' '."\n"; + // Append the image to the manifest + $this->manifestXml = str_replace('', $add.'', $this->manifestXml); // we replace the manifest closing tag by the image XML entry + manifest closing tag (this results in appending the data, we do not overwrite anything) + } + + /** + * Export the file as attached file by HTTP + * + * @param string $name (optional) + * @throws OdfException + * @return void + */ + public function exportAsAttachedFile($name="") + { + $this->_save(); + if (headers_sent($filename, $linenum)) { + throw new OdfException("headers already sent ($filename at $linenum)"); + } + + if( $name == "" ) + { + $name = md5(uniqid()) . ".odt"; + } + + header('Content-type: application/vnd.oasis.opendocument.text'); + header('Content-Disposition: attachment; filename="'.$name.'"'); + header('Content-Length: '.filesize($this->tmpfile)); + readfile($this->tmpfile); + } + + /** + * Convert the ODT file to PDF and export the file as attached file by HTTP + * Note: you need to have JODConverter and OpenOffice or LibreOffice installed and executable on the same system as where this php script will be executed. You also need to chmod +x odt2pdf.sh + * + * @param string $name (optional) + * @throws OdfException + * @return void + */ + public function exportAsAttachedPDF($name="") + { + global $conf; + + if( $name == "" ) $name = md5(uniqid()); + + //dol_syslog(get_class($this).'::exportAsAttachedPDF $name='.$name, LOG_DEBUG); + $this->saveToDisk($name); + + $execmethod=(empty($conf->global->MAIN_EXEC_USE_POPEN)?1:2); // 1 or 2 + + $name=str_replace('.odt', '', $name); + $command = DOL_DOCUMENT_ROOT.'/includes/odtphp/odt2pdf.sh '.$name; + //dol_syslog('$execmethod='.$execmethod.' Run command='.$command); + if ($execmethod == 1) + { + exec($command, $output_arr, $retval); + } + if ($execmethod == 2) + { + $ok=0; + $handle = fopen($outputfile, 'w'); + if ($handle) + { + dol_syslog("Run command ".$command); + $handlein = popen($command, 'r'); + while (!feof($handlein)) + { + $read = fgets($handlein); + fwrite($handle,$read); + $output_arr[]=$read; + } + pclose($handlein); + fclose($handle); + } + if (! empty($conf->global->MAIN_UMASK)) @chmod($outputfile, octdec($conf->global->MAIN_UMASK)); + } + + if($retval == 0) + { + //dol_syslog(get_class($this).'::exportAsAttachedPDF $ret_val='.$retval, LOG_DEBUG); if (headers_sent($filename, $linenum)) { throw new OdfException("headers already sent ($filename at $linenum)"); } - if( $name == "" ) - { - $name = md5(uniqid()) . ".odt"; + if (!empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) { + header('Content-type: application/pdf'); + header('Content-Disposition: attachment; filename="'.$name.'.pdf"'); + readfile("$name.pdf"); } + unlink("$name.odt"); + } else { + //dol_syslog(get_class($this).'::exportAsAttachedPDF $ret_val='.$retval, LOG_DEBUG); + //dol_syslog(get_class($this).'::exportAsAttachedPDF $output_arr='.var_export($output_arr,true), LOG_DEBUG); + echo "Error occured:
"; + foreach($output_arr as $line) + echo $line."
"; + //dol_syslog(get_class($this).'::exportAsAttachedPDF ERROR $line='.$line, LOG_DEBUG); + } + } - header('Content-type: application/vnd.oasis.opendocument.text'); - header('Content-Disposition: attachment; filename="'.$name.'"'); - header('Content-Length: '.filesize($this->tmpfile)); - readfile($this->tmpfile); + /** + * Returns a variable of configuration + * + * @return string The requested variable of configuration + */ + public function getConfig($configKey) + { + if (array_key_exists($configKey, $this->config)) { + return $this->config[$configKey]; + } + return false; + } + /** + * Returns the temporary working file + * + * @return string le chemin vers le fichier temporaire de travail + */ + public function getTmpfile() + { + return $this->tmpfile; + } + + /** + * Delete the temporary file when the object is destroyed + */ + public function __destruct() + { + if (file_exists($this->tmpfile)) { + unlink($this->tmpfile); } - /** - * Convert the ODT file to PDF and export the file as attached file by HTTP - * Note: you need to have JODConverter and OpenOffice or LibreOffice installed and executable on the same system as where this php script will be executed. You also need to chmod +x odt2pdf.sh - * - * @param string $name (optional) - * @throws OdfException - * @return void - */ - public function exportAsAttachedPDF($name="") - { - if( $name == "" ) $name = md5(uniqid()); - - $this->saveToDisk("$name.odt"); - exec("./odt2pdf.sh $name",$output,$ret_val); - if($ret_val == 0) - { - if (headers_sent($filename, $linenum)) { - throw new OdfException("headers already sent ($filename at $linenum)"); - } - - header('Content-type: application/pdf'); - header('Content-Disposition: attachment; filename="'.$name.'.pdf"'); - readfile("$name.pdf"); - unlink("$name.odt"); - unlink("$name.pdf"); - } else { - echo "Error occured:
"; - foreach($output as $line) - echo $line."
"; - } + if (file_exists($this->tmpdir)) { + $this->_rrmdir($this->tmpdir); + rmdir($this->tmpdir); } + } - /** - * Returns a variable of configuration - * - * @return string The requested variable of configuration - */ - public function getConfig($configKey) - { - if (array_key_exists($configKey, $this->config)) { - return $this->config[$configKey]; - } - return false; - } - /** - * Returns the temporary working file - * - * @return string le chemin vers le fichier temporaire de travail - */ - public function getTmpfile() - { - return $this->tmpfile; - } - - /** - * Delete the temporary file when the object is destroyed - */ - public function __destruct() - { - if (file_exists($this->tmpfile)) { - unlink($this->tmpfile); - } - - if (file_exists($this->tmpdir)) { - $this->_rrmdir($this->tmpdir); - rmdir($this->tmpdir); - } - } - - /** - * Empty the temporary working directory recursively - * @param $dir the temporary working directory - * @return void - */ - private function _rrmdir($dir) - { - if ($handle = opendir($dir)) { - while (false !== ($file = readdir($handle))) { - if ($file != '.' && $file != '..') { - if (is_dir($dir . '/' . $file)) { - $this->_rrmdir($dir . '/' . $file); - rmdir($dir . '/' . $file); - } else { - unlink($dir . '/' . $file); - } + /** + * Empty the temporary working directory recursively + * @param $dir the temporary working directory + * @return void + */ + private function _rrmdir($dir) + { + if ($handle = opendir($dir)) { + while (false !== ($file = readdir($handle))) { + if ($file != '.' && $file != '..') { + if (is_dir($dir . '/' . $file)) { + $this->_rrmdir($dir . '/' . $file); + rmdir($dir . '/' . $file); + } else { + unlink($dir . '/' . $file); } } - closedir($handle); } + closedir($handle); } + } } ?> \ No newline at end of file diff --git a/htdocs/includes/odtphp/odt2pdf.sh b/htdocs/includes/odtphp/odt2pdf.sh old mode 100644 new mode 100755 diff --git a/htdocs/install/default.css b/htdocs/install/default.css index b5f8773db75..d6c354e092c 100644 --- a/htdocs/install/default.css +++ b/htdocs/install/default.css @@ -61,10 +61,10 @@ padding: 0px 0px 0px 0px; margin: 0px 0px 0px 0px; } -input[type=text] { +input[type=text], input[type=password] { border: 1px solid #ACBCBB; } -input[type=text]:focus, textarea:focus, select:focus { +input[type=text]:focus, input[type=password]:focus, textarea:focus, select:focus { border: 1px solid #ACBCBB; box-shadow: 0 0 5px #C091AF; } diff --git a/htdocs/install/doctemplates/thirdparties/template_thirdparty.ods b/htdocs/install/doctemplates/thirdparties/template_thirdparty.ods new file mode 100644 index 00000000000..c715d7fb80f Binary files /dev/null and b/htdocs/install/doctemplates/thirdparties/template_thirdparty.ods differ diff --git a/htdocs/install/etape1.php b/htdocs/install/etape1.php index 24e56a7ecf0..53f1aba9e19 100644 --- a/htdocs/install/etape1.php +++ b/htdocs/install/etape1.php @@ -458,7 +458,7 @@ if (! $error && $db->connected && $action == "set") print '
'; - print ''; + print ''; $userroot=isset($_POST["db_user_root"])?$_POST["db_user_root"]:""; @@ -508,7 +508,7 @@ if (! $error && $db->connected && $action == "set") print $langs->trans("UserCreation").' : '; print $dolibarr_main_db_user; print ''; - print ''; + print ''; } else { @@ -542,7 +542,7 @@ if (! $error && $db->connected && $action == "set") print $langs->trans("UserCreation").' : '; print $dolibarr_main_db_user; print ''; - print ''; + print ''; print ''; // Affiche aide diagnostique @@ -576,7 +576,7 @@ if (! $error && $db->connected && $action == "set") print $langs->trans("DatabaseCreation")." (".$langs->trans("User")." ".$userroot.") : "; print $dolibarr_main_db_name; print ''; - print ""; + print ''; $check1=$newdb->getDefaultCharacterSetDatabase(); $check2=$newdb->getDefaultCollationDatabase(); @@ -606,7 +606,7 @@ if (! $error && $db->connected && $action == "set") print $langs->trans("DatabaseCreation")." (".$langs->trans("User")." ".$userroot.") : "; print $dolibarr_main_db_name; print ''; - print ''; + print ''; print ''; // Affiche aide diagnostique @@ -632,43 +632,35 @@ if (! $error && $db->connected && $action == "set") if ($db->connected == 1) { + dolibarr_install_syslog("etape1: connexion to server by user ".$conf->db->user." is ok", LOG_DEBUG); + print ""; + // si acces serveur ok et acces base ok, tout est ok, on ne va pas plus loin, on a meme pas utilise le compte root. if ($db->database_selected == 1) { - dolibarr_install_syslog("etape1: connexion to server by user ".$conf->db->user." is ok", LOG_DEBUG); - print ""; - dolibarr_install_syslog("etape1: connexion to database : ".$conf->db->name.", by user : ".$conf->db->user." is ok", LOG_DEBUG); print ""; $error = 0; } else { - dolibarr_install_syslog("etape1: connexion to server by user ".$conf->db->user." is ok", LOG_DEBUG); - print ""; - dolibarr_install_syslog("etape1: connexion to database ".$conf->db->name.", by user : ".$conf->db->user." has failed", LOG_ERR); print ""; // Affiche aide diagnostique @@ -688,7 +680,7 @@ if (! $error && $db->connected && $action == "set") print $langs->trans("ServerConnection")." (".$langs->trans("User")." ".$conf->db->user.") : "; print $dolibarr_main_db_host; print '"; // Affiche aide diagnostique @@ -938,7 +930,7 @@ function write_conf_file($conffile) print $langs->trans("SaveConfigurationFile"); print ' '.$conffile.''; print ""; } else diff --git a/htdocs/install/etape2.php b/htdocs/install/etape2.php index 9ad310dec9d..92b5f2111b7 100644 --- a/htdocs/install/etape2.php +++ b/htdocs/install/etape2.php @@ -87,12 +87,12 @@ if ($action == "set") if ($db->connected == 1) { print ""; + print $langs->trans("ServerConnection")." : ".$conf->db->host.''; $ok = 1 ; } else { - print ""; + print "'; } if ($ok) @@ -104,7 +104,7 @@ if ($action == "set") else { dolibarr_install_syslog("etape2: Connexion failed to database : ".$conf->db->name); - print ""; + print "'; $ok = 0 ; } } @@ -241,13 +241,13 @@ if ($action == "set") if ($error == 0) { print ''; + print $langs->trans("TablesAndPrimaryKeysCreation").''; $ok = 1; } } else { - print ''; + print ''; dolibarr_install_syslog("Failed to find files to create database in directory ".$dir,LOG_ERR); } } @@ -388,7 +388,7 @@ if ($action == "set") if ($tablefound && $error == 0) { print ''; + print $langs->trans("OtherKeysCreation").''; $okkeys = 1; } } @@ -466,11 +466,11 @@ if ($action == "set") print ""; if ($ok) { - print ""; + print ''; } else { - print ''; + print ''; $ok = 1 ; } @@ -588,11 +588,11 @@ if ($action == "set") print ""; if ($ok) { - print ""; + print ''; } else { - print ''; + print ''; $ok = 1; // Data loading are not blocking errors } } diff --git a/htdocs/install/fileconf.php b/htdocs/install/fileconf.php index 5e58d07d28c..7a8e1ad1ee9 100644 --- a/htdocs/install/fileconf.php +++ b/htdocs/install/fileconf.php @@ -406,7 +406,7 @@ if (! empty($force_install_message)) - - - ", - $desc_pere[0], // Id product -*/ 'id'=>$id, // Id product - 'nb'=>$nb, // Nb of units that compose parent product - 'nb_total'=>$nb*$multiply, // Nb of units for all nb of product - 'stock'=>$this->stock_warehouse[1]->real, // Stock - 'stock_alert'=>$this->seuil_stock_alerte, // Stock alert - 'fullpath' => $compl_path.$nom_pere, // Label - 'type'=>$type // Nb of units that compose parent product - ); - } - else - { - $this->fetch($desc_pere[0]); - $this->load_stock(); - $this->res[]= array( -/* $compl_path.$nom_pere." (".$desc_pere[1].")", - $desc_pere[0], // Id product -*/ 'id'=>$id, // Id product + //print "XXX We add id=".$id." - label=".$label." - nb=".$nb." - multiply=".$multiply." fullpath=".$compl_path.$label."\n"; + $this->fetch($id); + $this->load_stock(); + $this->res[]= array( + 'id'=>$id, // Id product 'nb'=>$nb, // Nb of units that compose parent product - 'nb_total'=>$nb, // Nb of units for all nb of product - 'stock'=>$this->stock_warehouse[1]->real, // Stock + 'nb_total'=>$nb*$multiply, // Nb of units for all nb of product + 'stock'=>$this->stock_warehouse[1]->real, // Stock 'stock_alert'=>$this->seuil_stock_alerte, // Stock alert - 'fullpath' => $compl_path.$nom_pere, // Label - 'type'=>$type // Nb of units that compose parent product - ); - } - } - else if($nom_pere != "0" && $nom_pere != "1") - { - $this->res[]= array($compl_path.$nom_pere,$desc_pere); + 'fullpath' => $compl_path.$label, // Label + 'type'=>$type // Nb of units that compose parent product + ); } // Recursive call if child is an array - if (is_array($desc_pere[0])) + if (is_array($desc_pere['childs'])) { - $this ->fetch_prod_arbo($desc_pere[0], $nom_pere." -> ", $desc_pere[1]*$multiply, $level+1); + //print 'YYY We go down for '.$desc_pere[3]." -> \n"; + $this ->fetch_prod_arbo($desc_pere['childs'], $compl_path.$desc_pere[3]." -> ", $desc_pere[1]*$multiply, $level+1); } } } @@ -2225,11 +2198,12 @@ class Product extends CommonObject $this->res = array(); if (isset($this->sousprods) && is_array($this->sousprods)) { - foreach($this->sousprods as $nom_pere => $desc_pere) + foreach($this->sousprods as $prod_name => $desc_product) { - if (is_array($desc_pere)) $this->fetch_prod_arbo($desc_pere,"",$multiply); + if (is_array($desc_product)) $this->fetch_prod_arbo($desc_product,"",$multiply); } } + //var_dump($this->res); return $this->res; } @@ -2290,7 +2264,7 @@ class Product extends CommonObject /** - * Return all parent products fo current product + * Return all direct parent products fo current product * * @return array prod */ @@ -2321,19 +2295,19 @@ class Product extends CommonObject } /** - * Return childs of product with if fk_parent + * Return childs of product $id * - * @param int $fk_parent Id of product to search childs of + * @param int $id Id of product to search childs of * @return array Prod */ - function getChildsArbo($fk_parent) + function getChildsArbo($id) { $sql = "SELECT p.rowid, p.label as label, pa.qty as qty, pa.fk_product_fils as id, p.fk_product_type"; $sql.= " FROM ".MAIN_DB_PREFIX."product as p"; $sql.= ", ".MAIN_DB_PREFIX."product_association as pa"; $sql.= " WHERE p.rowid = pa.fk_product_fils"; - $sql.= " AND pa.fk_product_pere = ".$fk_parent; - $sql.= " AND pa.fk_product_fils != ".$fk_parent; // This should not happens, it is to avoid invinite loop if it happens + $sql.= " AND pa.fk_product_pere = ".$id; + $sql.= " AND pa.fk_product_fils != ".$id; // This should not happens, it is to avoid infinite loop if it happens dol_syslog(get_class($this).'::getChildsArbo sql='.$sql); $res = $this->db->query($sql); @@ -2348,7 +2322,7 @@ class Product extends CommonObject $listofchilds=$this->getChildsArbo($rec['id']); foreach($listofchilds as $keyChild => $valueChild) { - $prods[$rec['rowid']][$keyChild] = $valueChild; + $prods[$rec['rowid']]['childs'][$keyChild] = $valueChild; } } @@ -2370,14 +2344,14 @@ class Product extends CommonObject function get_sousproduits_arbo() { $parent = $this->getParent(); - foreach($parent as $key => $value) + foreach($parent as $key => $value) // key=label, value[0]=id { foreach($this->getChildsArbo($value[0]) as $keyChild => $valueChild) { $parent[$key][$keyChild] = $valueChild; } } - foreach($parent as $key => $value) + foreach($parent as $key => $value) // key=label, value is array of childs { $this->sousprods[$key] = $value; } @@ -2412,6 +2386,10 @@ class Product extends CommonObject $lien = ''; $lienfin=''; } + else if ($option == 'category') + { + $lien = ''; + } else { $lien = ''; diff --git a/htdocs/product/composition/fiche.php b/htdocs/product/composition/fiche.php index 804759afe3a..71ce35c76e1 100644 --- a/htdocs/product/composition/fiche.php +++ b/htdocs/product/composition/fiche.php @@ -1,6 +1,6 @@ - * Copyright (C) 2004-2011 Laurent Destailleur + * Copyright (C) 2004-2013 Laurent Destailleur * Copyright (C) 2005 Eric Seigne * Copyright (C) 2005-2012 Regis Houssin * Copyright (C) 2006 Andre Cianfarani @@ -72,8 +72,8 @@ $cancel <> $langs->trans("Cancel") && $error=0; for($i=0;$i<$_POST["max_prod"];$i++) { - // print "
: ".$_POST["prod_id_chk".$i]; - if($_POST["prod_id_chk".$i] != "") + print "
: ".$_POST["prod_id_chk".$i]; + if ($_POST["prod_id_chk".$i] > 0) { if($product->add_sousproduit($id, $_POST["prod_id_".$i],$_POST["prod_qty_".$i]) > 0) { @@ -198,15 +198,18 @@ if ($id || $ref) print ''; // Number of subproducts - $prodsfather = $product->getFather(); //Parent Products + $prodsfather = $product->getFather(); // Parent Products $product->get_sousproduits_arbo(); - print '
'; + $prods_arbo=$product->get_arbo_each_prod(); + $nbofsubproducts=count($prods_arbo); + print ''; dol_fiche_end(); - // List of subproducts - $prods_arbo = $product->get_arbo_each_prod(); + // List of products into this virtual product if (count($prods_arbo) > 0) { print ''; + //print ''; print ''; if (! empty($conf->stock->enabled)) print ''; print ''; @@ -231,8 +235,10 @@ if ($id || $ref) print ''; } - // Number of parent products - print ''; + // Number of parent virtual products + print ''; if (count($prodsfather) > 0) { @@ -286,12 +292,14 @@ if ($id || $ref) // Number of subproducts $prodsfather = $product->getFather(); //Parent Products $product->get_sousproduits_arbo(); - print ''; + $prods_arbo=$product->get_arbo_each_prod(); + $nbofsubproducts=count($prods_arbo); + print ''; print ''; // List of subproducts - $prods_arbo = $product->get_arbo_each_prod(); - //var_dump($prods_arbo); if(count($prods_arbo) > 0) { print ''; } - // Number of parent products - print ''; + // Number of parent virtual products + print ''; if (count($prodsfather) > 0) { diff --git a/htdocs/product/fiche.php b/htdocs/product/fiche.php index e8775f44621..143ed6e9551 100644 --- a/htdocs/product/fiche.php +++ b/htdocs/product/fiche.php @@ -693,7 +693,7 @@ else print ''; // Label - print ''; + print ''; // On sell print ''; // Label - print ''; + print ''; // Status print ''; - // Status + // Status print ''."\n"; // Lastname print ''; -print ''; +print ''; print ''."\n"; // Firstname diff --git a/test/phpunit/ModulesTest.php b/test/phpunit/ModulesTest.php index 357413e3be9..8b2a0617275 100755 --- a/test/phpunit/ModulesTest.php +++ b/test/phpunit/ModulesTest.php @@ -138,7 +138,7 @@ class ModulesTest extends PHPUnit_Framework_TestCase $mod=new $class($db); $result=$mod->remove(); $result=$mod->init(); - $this->assertLessThan($result, 0); + $this->assertLessThan($result, 0, $modlabel); print __METHOD__." result=".$result."\n"; }
'.img_mime($file).''; - print ''; + print ''; print $file; print ''; print ''; $modulepart='import'; $relativepath=GETPOST('filetoimport'); - print ''; + print ''; print $filetoimport; print ''; print '
'; $modulepart='import'; $relativepath=GETPOST('filetoimport'); - print ''; + print ''; print $filetoimport; print ''; print '
'; $modulepart='import'; $relativepath=GETPOST('filetoimport'); - print ''; + print ''; print $filetoimport; print ''; print '
'; print $langs->trans("ConfFileReload"); print ''.$langs->trans("OK").'
Ok
'.$langs->trans("OK").'
Ok
'.$langs->trans("Error").'Error
".$langs->trans("OK")."
Ok
'.$langs->trans("Error").'Error
"; + print $langs->trans("ServerConnection")." (".$langs->trans("User")." ".$conf->db->user.") : "; + print $dolibarr_main_db_host; + print ""; + print 'Ok'; + print "
"; - print $langs->trans("ServerConnection")." (".$langs->trans("User")." ".$conf->db->user.") : "; - print $dolibarr_main_db_host; - print ""; - print $langs->trans("OK"); - print "
"; print $langs->trans("DatabaseConnection")." (".$langs->trans("User")." ".$conf->db->user.") : "; print $dolibarr_main_db_name; print ""; - print $langs->trans("OK"); + print 'Ok'; print "
"; - print $langs->trans("ServerConnection")." (".$langs->trans("User")." ".$conf->db->user.") : "; - print $dolibarr_main_db_host; - print ""; - print $langs->trans("OK"); - print "
"; print $langs->trans("DatabaseConnection")." (".$langs->trans("User")." ".$conf->db->user.") : "; print $dolibarr_main_db_name; print ''; - print $langs->trans("Error"); + print 'Error'; print "
'; - print ''.$db->error.''; + print 'Error'; print "
"; - print $langs->trans("OK"); + print 'Ok'; print "
"; - print $langs->trans("ServerConnection")." : ".$conf->db->host."".$langs->trans("OK")."
Ok
Failed to connect to server : ".$conf->db->host."".$langs->trans("Error")."
Failed to connect to server : ".$conf->db->host.'Error
Failed to select database ".$conf->db->name."".$langs->trans("Error")."
Failed to select database ".$conf->db->name.'Error
'; - print $langs->trans("TablesAndPrimaryKeysCreation").''.$langs->trans("OK").'
Ok
'.$langs->trans("ErrorFailedToFindSomeFiles",$dir).''.$langs->trans("Error").'
'.$langs->trans("ErrorFailedToFindSomeFiles",$dir).'Error
'; - print $langs->trans("OtherKeysCreation").''.$langs->trans("OK").'
Ok
".$langs->trans("FunctionsCreation")."".$langs->trans("OK")."
Ok
'.$langs->trans("Error").'
Error
".$langs->trans("ReferenceDataLoading")."".$langs->trans("OK")."
Ok
'.$langs->trans("Error").'
Error
trans("Password"); ?> trans("Password"); ?> llibreria TCPDF , i a continuació comentar o eliminar la línia $dolibarr_pdf_force_fpdf=1, i afegir al seu lloc $dolibarr_lib_TCPDF_PATH='ruta_a_TCPDF' LocalTaxDesc=Alguns països apliquen 2 o 3 taxes a cada línia de factura. Si és el cas, escolliu el tipus de la segona i tercera taxa i el seu valor. Els possibles tipus són:
1: taxa local aplicable a productes i serveis sense IVA (IVA no s'aplica a la taxa local)
2: taxa local s'aplica a productes i serveis abans de l'IVA (IVA es calcula sobre import + taxa local)
3: taxa local s'aplica a productes sense IVA (IVA no s'aplica a la taxa local)
4: taxa local s'aplica a productes abans de l'IVA (IVA es calcula sobre l'import + taxa local)
5: taxa local s'aplica a serveis sense IVA (IVA no s'aplica a la taxa local)
6: taxa local s'aplica a serveis abans de l'IVA (IVA es calcula sobre import + taxa local) diff --git a/htdocs/langs/ca_ES/main.lang b/htdocs/langs/ca_ES/main.lang index 35b4d437e4e..b4689f1537d 100644 --- a/htdocs/langs/ca_ES/main.lang +++ b/htdocs/langs/ca_ES/main.lang @@ -4,8 +4,11 @@ DIRECTION=ltr SeparatorDecimal=, SeparatorThousand= FormatDateShort=%d/%m/%Y +FormatDateShortInput=%d/%m/%Y FormatDateShortJava=dd/MM/yyyy +FormatDateShortJavaInput=dd/MM/yyyy FormatDateShortJQuery=dd/mm/yy +FormatDateShortJQueryInput=dd/mm/yy FormatHourShort=%H:%M FormatHourShortDuration=%H:%M FormatDateTextShort=%d %b %Y diff --git a/htdocs/langs/da_DK/main.lang b/htdocs/langs/da_DK/main.lang index 7dd615bfa86..128bf629fc7 100644 --- a/htdocs/langs/da_DK/main.lang +++ b/htdocs/langs/da_DK/main.lang @@ -14,7 +14,11 @@ CHARSET=UTF-8 SeparatorDecimal=. SeparatorThousand=, FormatDateShort=%d/%m/%Y +FormatDateShortInput=%d/%m/%Y FormatDateShortJava=dd/MM/yyyy +FormatDateShortJavaInput=dd/MM/yyyy +FormatDateShortJQuery=dd/mm/yy +FormatDateShortJQueryInput=dd/mm/yy FormatHourShort=%H:%M FormatDateTextShort=%d %b %Y FormatDateText=%d %B %Y @@ -624,7 +628,6 @@ Prefix=Præfiks // START - Lines generated via autotranslator.php tool (2012-02-29 15:59:19). // Reference language: en_US -> da_DK -FormatDateShortJQuery=dd/mm/yy AddLink=Tilføj link Of=af SearchOf=Søg diff --git a/htdocs/langs/de_AT/main.lang b/htdocs/langs/de_AT/main.lang index ed9d7b27ec2..6a44f3dbfee 100644 --- a/htdocs/langs/de_AT/main.lang +++ b/htdocs/langs/de_AT/main.lang @@ -10,7 +10,11 @@ DIRECTION=ltr SeparatorDecimal=, SeparatorThousand=. FormatDateShort=%d/%m/%Y +FormatDateShortInput=%d/%m/%Y FormatDateShortJava=dd/MM/yyyy +FormatDateShortJavaInput=dd/MM/yyyy +FormatDateShortJQuery=dd/MM/yy +FormatDateShortJQueryInput=dd/MM/yy FormatHourShort=%H:%M FormatDateTextShort=%d %b %Y FormatDateText=%d %B %Y diff --git a/htdocs/langs/de_DE/main.lang b/htdocs/langs/de_DE/main.lang index bac265965cc..88e22f914d8 100644 --- a/htdocs/langs/de_DE/main.lang +++ b/htdocs/langs/de_DE/main.lang @@ -11,8 +11,11 @@ DIRECTION=ltr SeparatorDecimal=, SeparatorThousand=. FormatDateShort=%d/%m/%Y +FormatDateShortInput=%d/%m/%Y FormatDateShortJava=dd/MM/yyyy +FormatDateShortJavaInput=dd/MM/yyyy FormatDateShortJQuery=dd/MM/yy +FormatDateShortJQueryInput=dd/MM/yy FormatHourShort=%I:%M %p FormatHourShortDuration=%H:%M FormatDateTextShort=%d %b %Y diff --git a/htdocs/langs/el_GR/main.lang b/htdocs/langs/el_GR/main.lang index d37b716a9ba..b38a1417ea8 100644 --- a/htdocs/langs/el_GR/main.lang +++ b/htdocs/langs/el_GR/main.lang @@ -7,7 +7,11 @@ FONTSIZEFORPDF=9 SeparatorDecimal=. SeparatorThousand=, FormatDateShort=%d/%m/%Y +FormatDateShortInput=%d/%m/%Y FormatDateShortJava=dd/MM/yyyy +FormatDateShortJavaInput=dd/MM/yyyy +FormatDateShortJQuery=dd/mm/yy +FormatDateShortJQueryInput=dd/mm/yy FormatHourShort=%I:%M %p FormatHourShortDuration=%H:%M FormatDateTextShort=%b %d, %Y @@ -592,7 +596,6 @@ ShortSunday=Κ // START - Lines generated via autotranslator.php tool (2011-06-26 15:35:22). // Reference language: en_US -> el_GR -FormatDateShortJQuery=dd/mm/yy AddLink=Προσθήκη συνδέσμου Of=του AmountByMonth=Ποσό ανά μήνα diff --git a/htdocs/langs/en_AU/main.lang b/htdocs/langs/en_AU/main.lang index 02b689c7c47..e1c3f95b5ea 100644 --- a/htdocs/langs/en_AU/main.lang +++ b/htdocs/langs/en_AU/main.lang @@ -4,7 +4,11 @@ CHARSET=UTF-8 SeparatorDecimal=. SeparatorThousand=, FormatDateShort=%d/%m/%Y +FormatDateShortInput=%d/%m/%Y FormatDateShortJava=dd/MM/yyyy +FormatDateShortJavaInput=dd/MM/yyyy +FormatDateShortJQuery=dd/mm/yy +FormatDateShortJQueryInput=dd/mm/yy FormatHourShort=%H:%M FormatDateTextShort=%d %b %Y FormatDateText=%d %B %Y diff --git a/htdocs/langs/en_GB/main.lang b/htdocs/langs/en_GB/main.lang index 8bd3243e226..6ec5c920232 100644 --- a/htdocs/langs/en_GB/main.lang +++ b/htdocs/langs/en_GB/main.lang @@ -3,7 +3,11 @@ CHARSET=UTF-8 SeparatorDecimal=. SeparatorThousand=, FormatDateShort=%d/%m/%Y +FormatDateShortInput=%d/%m/%Y FormatDateShortJava=dd/MM/yyyy +FormatDateShortJavaInput=dd/MM/yyyy +FormatDateShortJQuery=dd/mm/yy +FormatDateShortJQueryInput=dd/mm/yy FormatHourShort=%H:%M FormatDateTextShort=%d %b %Y FormatDateText=%d %B %Y diff --git a/htdocs/langs/en_IN/main.lang b/htdocs/langs/en_IN/main.lang index 795d89bce4e..8bf5df955b5 100644 --- a/htdocs/langs/en_IN/main.lang +++ b/htdocs/langs/en_IN/main.lang @@ -4,7 +4,11 @@ DIRECTION=ltr SeparatorDecimal=. SeparatorThousand=, FormatDateShort=%d/%m/%Y +FormatDateShortInput=%d/%m/%Y FormatDateShortJava=dd/MM/yyyy +FormatDateShortJavaInput=dd/MM/yyyy +FormatDateShortJQuery=dd/mm/yy +FormatDateShortJQueryInput=dd/mm/yy FormatHourShort=%I:%M %p FormatDateTextShort=%b %d, %Y FormatDateText=%B %d, %Y diff --git a/htdocs/langs/en_NZ/main.lang b/htdocs/langs/en_NZ/main.lang index 1e6ca9a9ddc..d3f11199968 100644 --- a/htdocs/langs/en_NZ/main.lang +++ b/htdocs/langs/en_NZ/main.lang @@ -4,7 +4,11 @@ CHARSET=UTF-8 SeparatorDecimal=. SeparatorThousand=, FormatDateShort=%d/%m/%Y +FormatDateShortInput=%d/%m/%Y FormatDateShortJava=dd/MM/yyyy +FormatDateShortJavaInput=dd/MM/yyyy +FormatDateShortJQuery=dd/mm/yy +FormatDateShortJQueryInput=dd/mm/yy FormatHourShort=%H:%M FormatDateTextShort=%d %b %Y FormatDateText=%d %B %Y diff --git a/htdocs/langs/en_SA/main.lang b/htdocs/langs/en_SA/main.lang index 146ae3fd85e..cb8e3ba6e6d 100644 --- a/htdocs/langs/en_SA/main.lang +++ b/htdocs/langs/en_SA/main.lang @@ -6,8 +6,11 @@ FONTSIZEFORPDF=9 SeparatorDecimal=. SeparatorThousand=, FormatDateShort=%d/%m/%Y +FormatDateShortInput=%d/%m/%Y FormatDateShortJava=dd/MM/yyyy +FormatDateShortJavaInput=dd/MM/yyyy FormatDateShortJQuery=dd/mm/yy +FormatDateShortJQueryInput=dd/mm/yy FormatHourShort=%I:%M %p FormatHourShortDuration=%H:%M FormatDateTextShort=%d %b %Y diff --git a/htdocs/langs/en_US/admin.lang b/htdocs/langs/en_US/admin.lang index e73e752fb21..290707219bb 100644 --- a/htdocs/langs/en_US/admin.lang +++ b/htdocs/langs/en_US/admin.lang @@ -46,6 +46,8 @@ ErrorModuleRequireDolibarrVersion=Error, this module requires Dolibarr version % ErrorDecimalLargerThanAreForbidden=Error, a precision higher than %s is not supported. DictionnarySetup=Dictionary setup Dictionnary=Dictionaries +ErrorReservedTypeSystemSystemAuto=Value 'system' and 'systemauto' for type is reserved. You can use 'user' as value to add your own record +ErrorCodeCantContainZero=Code can't contain value 0 DisableJavascript=Disable JavaScript and Ajax functions ConfirmAjax=Use Ajax confirmation popups UseSearchToSelectCompany=Use autocompletion fields to choose third parties (instead of using a list box).

Also if you have a large number of third parties (> 100 000), you can increase speed by setting constant SOCIETE_DONOTSEARCH_ANYWHERE to 1 in Setup->Other. Search will then be limited to start of string. @@ -360,7 +362,10 @@ ExtrafieldSelect = Select list ExtrafieldSeparator=Separator ExtrafieldCheckBox=Checkbox ExtrafieldRadio=Radio button -ExtrafieldParamHelp=Parameters list have to be like key,value

for exemple :
1,value1
2,value2
3,value3
... +ExtrafieldParamHelpselect=Parameters list have to be like key,value

for exemple :
1,value1
2,value2
3,value3
... +ExtrafieldParamHelpcheckbox=Parameters list have to be like key,value

for exemple :
1,value1
2,value2
3,value3
... +ExtrafieldParamHelpradio=Parameters list have to be like key,value

for exemple :
1,value1
2,value2
3,value3
... +ExtrafieldParamHelpsellist=Parameters list have come from table

for exemple :
c_typent:libelle:id
LibraryToBuildPDF=Library used to build PDF WarningUsingFPDF=Warning: Your conf.php contains directive dolibarr_pdf_force_fpdf=1. This means you use the FPDF library to generate PDF files. This library is old and does not support a lot of features (Unicode, image transparency, cyrillic, arab and asiatic languages, ...), so you may experience errors during PDF generation.
To solve this and have a full support of PDF generation, please download TCPDF library, then comment or remove the line $dolibarr_pdf_force_fpdf=1, and add instead $dolibarr_lib_TCPDF_PATH='path_to_TCPDF_dir' LocalTaxDesc=Some countries apply 2 or 3 taxes on each invoice line. If this is the case, choose type for second and third tax and its rate. Possible type are:
1 : local tax apply on products and services without vat (vat is not applied on local tax)
2 : local tax apply on products and services before vat (vat is calculated on amount + localtax)
3 : local tax apply on products without vat (vat is not applied on local tax)
4 : local tax apply on products before vat (vat is calculated on amount + localtax)
5 : local tax apply on services without vat (vat is not applied on local tax)
6 : local tax apply on services before vat (vat is calculated on amount + localtax) @@ -543,6 +548,7 @@ Permission98=Dispatch invoice accountancy lines Permission101=Read sendings Permission102=Create/modify sendings Permission104=Validate sendings +Permission106=Export sendings Permission109=Delete sendings Permission111=Read financial accounts Permission112=Create/modify/delete and compare transactions diff --git a/htdocs/langs/en_US/agenda.lang b/htdocs/langs/en_US/agenda.lang index 2355c112194..33d52b04c94 100644 --- a/htdocs/langs/en_US/agenda.lang +++ b/htdocs/langs/en_US/agenda.lang @@ -32,7 +32,7 @@ ViewCal=Month view ViewDay=Day view ViewWeek=Week view ViewWithPredefinedFilters= View with predefined filters -AutoActions= Automatic filling of agenda +AutoActions= Automatic filling AgendaAutoActionDesc= Define here events for which you want Dolibarr to create automatically an event in agenda. If nothing is checked (by default), only manual actions will be included in agenda. AgendaSetupOtherDesc= This page provides options to allow export of your Dolibarr events into an external calendar (thunderbird, google calendar, ...) AgendaExtSitesDesc=This page allows to declare external sources of calendars to see their events into Dolibarr agenda. @@ -40,6 +40,7 @@ ActionsEvents= Events for which Dolibarr will create an action in agenda automat PropalValidatedInDolibarr= Proposal %s validated InvoiceValidatedInDolibarr= Invoice %s validated InvoiceBackToDraftInDolibarr=Invoice %s go back to draft status +InvoiceDeleteDolibarr=Invoice %s deleted OrderValidatedInDolibarr= Order %s validated OrderApprovedInDolibarr=Order %s approved OrderBackToDraftInDolibarr=Order %s go back to draft status @@ -66,6 +67,7 @@ AgendaUrlOptions4=logint=%s to restrict output to actions assigned to use AgendaUrlOptions5=logind=%s to restrict output to actions done by user %s. AgendaShowBirthdayEvents=Show birthday's contacts AgendaHideBirthdayEvents=Hide birthday's contacts +Busy=Busy # External Sites ical ExportCal=Export calendar diff --git a/htdocs/langs/en_US/bills.lang b/htdocs/langs/en_US/bills.lang index 41b08dd399f..a76156142d6 100644 --- a/htdocs/langs/en_US/bills.lang +++ b/htdocs/langs/en_US/bills.lang @@ -311,6 +311,8 @@ PaymentConditionShortPT_ORDER=On order PaymentConditionPT_ORDER=On order PaymentConditionShortPT_5050=50-50 PaymentConditionPT_5050=50%% in advance, 50%% on delivery +FixAmount=Fix amount +VarAmount=Variable amount (%% tot.) # PaymentType PaymentTypeVIR=Bank deposit diff --git a/htdocs/langs/en_US/commercial.lang b/htdocs/langs/en_US/commercial.lang index b6bd7c9881a..09fd8e6e300 100644 --- a/htdocs/langs/en_US/commercial.lang +++ b/htdocs/langs/en_US/commercial.lang @@ -81,6 +81,7 @@ ActionAC_SHIP=Send shipping by mail ActionAC_SUP_ORD=Send supplier order by mail ActionAC_SUP_INV=Send supplier invoice by mail ActionAC_OTH=Other +ActionAC_OTH_AUTO=Other (automatically inserted events) ActionAC_MANUAL=Manually inserted events ActionAC_AUTO=Automatically inserted events Stats=Sales statistics @@ -92,4 +93,4 @@ NoData=There is no data StatusProsp=Prospect status DraftPropals=Draft commercial proposals SearchPropal=Search a commercial proposal -CommercialDashboard=Commercial summary \ No newline at end of file +CommercialDashboard=Commercial summary diff --git a/htdocs/langs/en_US/compta.lang b/htdocs/langs/en_US/compta.lang index 5e3a36e5051..a1b3cba5004 100644 --- a/htdocs/langs/en_US/compta.lang +++ b/htdocs/langs/en_US/compta.lang @@ -152,4 +152,5 @@ Pcg_type=Pcg type Pcg_subtype=Pcg subtype InvoiceLinesToDispatch=Invoice lines to dispatch InvoiceDispatched=Dispatched invoices -AccountancyDashboard=Accountancy summary \ No newline at end of file +AccountancyDashboard=Accountancy summary +ByProductsAndServices=By products and services diff --git a/htdocs/langs/en_US/errors.lang b/htdocs/langs/en_US/errors.lang index 48795ba2ce7..3cfee357c81 100644 --- a/htdocs/langs/en_US/errors.lang +++ b/htdocs/langs/en_US/errors.lang @@ -136,4 +136,5 @@ WarningLockFileDoesNotExists=Warning, once setup is finished, you must disable i WarningUntilDirRemoved=All security warnings (visible by admin users only) will remain active as long as the vulnerability is present (or that constant MAIN_REMOVE_INSTALL_WARNING is added in Setup->Other setup). WarningCloseAlways=Warning, closing is done even if amount differs between source and target elements. Enable this feature with caution. WarningUsingThisBoxSlowDown=Warning, using this box slow down seriously all pages showing the box. -WarningClickToDialUserSetupNotComplete=Setup of ClickToDial information for your user are not complete (see tab ClickToDial onto your user card). \ No newline at end of file +WarningClickToDialUserSetupNotComplete=Setup of ClickToDial information for your user are not complete (see tab ClickToDial onto your user card). +WarningNotRelevant=Irrelevant operation for this dataset diff --git a/htdocs/langs/en_US/externalsite.lang b/htdocs/langs/en_US/externalsite.lang index 3ae2098b92a..213fa314ab1 100644 --- a/htdocs/langs/en_US/externalsite.lang +++ b/htdocs/langs/en_US/externalsite.lang @@ -1,4 +1,5 @@ # Dolibarr language file - en_US - externalsite CHARSET=UTF-8 ExternalSiteSetup=Setup link to external website -ExternalSiteURL=External Site URL \ No newline at end of file +ExternalSiteURL=External Site URL +ExternalSiteModuleNotComplete=Module ExternalSite was not configured properly. \ No newline at end of file diff --git a/htdocs/langs/en_US/holiday.lang b/htdocs/langs/en_US/holiday.lang index 24926ae5e53..dc442d7f35f 100644 --- a/htdocs/langs/en_US/holiday.lang +++ b/htdocs/langs/en_US/holiday.lang @@ -132,4 +132,9 @@ NoCPforMonth=No leave this month. Jours=days nbJours=Number days TitleAdminCP=Configuration of Holidays -Permission20001=Read / Modify all requests of holidays +Permission20001=Read/create/modify their holidays +Permission20002=Read/modify all requests of holidays +Permission20003=Delete their holidays requests +Permission20004=Define users holidays +Permission20005=Review log of modified holidays +Permission20006=Access holidays monthly report diff --git a/htdocs/langs/en_US/main.lang b/htdocs/langs/en_US/main.lang index 28de6467cbb..c0e2f94d7f5 100644 --- a/htdocs/langs/en_US/main.lang +++ b/htdocs/langs/en_US/main.lang @@ -4,8 +4,11 @@ DIRECTION=ltr SeparatorDecimal=. SeparatorThousand=, FormatDateShort=%m/%d/%Y +FormatDateShortInput=%m/%d/%Y FormatDateShortJava=MM/dd/yyyy +FormatDateShortJavaInput=MM/dd/yyyy FormatDateShortJQuery=mm/dd/yy +FormatDateShortJQueryInput=mm/dd/yy FormatHourShort=%I:%M %p FormatHourShortDuration=%H:%M FormatDateTextShort=%b %d, %Y @@ -472,6 +475,8 @@ Report=Report Keyword=Mot clé Legend=Legend FillTownFromZip=Fill city from zip +Fill=Fill +Reset=Reset ShowLog=Show log File=File Files=Files diff --git a/htdocs/langs/en_US/other.lang b/htdocs/langs/en_US/other.lang index 6a350078731..bb6c4873c93 100644 --- a/htdocs/langs/en_US/other.lang +++ b/htdocs/langs/en_US/other.lang @@ -152,6 +152,7 @@ EMailTextOrderApproved=The order %s has been approved. EMailTextOrderApprovedBy=The order %s has been approved by %s. EMailTextOrderRefused=The order %s has been refused. EMailTextOrderRefusedBy=The order %s has been refused by %s. +EMailTextExpeditionValidated=The shipping %s has been validated. ImportedWithSet=Importation data set DolibarrNotification=Automatic notification ResizeDesc=Enter new width OR new height. Ratio will be kept during resizing... diff --git a/htdocs/langs/en_US/products.lang b/htdocs/langs/en_US/products.lang index b58dec53dcb..19b1afc3a3f 100644 --- a/htdocs/langs/en_US/products.lang +++ b/htdocs/langs/en_US/products.lang @@ -111,10 +111,12 @@ ServiceLimitedDuration=If product is a service with limited duration: MultiPricesAbility=Activate the multi-prices MultiPricesNumPrices=Number of price MultiPriceLevelsName=Price categories -AssociatedProductsAbility=Activate the sub-products -AssociatedProducts=Sub-products -AssociatedProductsNumber=Number of products composing this product -ParentProductsNumber=Number of parent product +AssociatedProductsAbility=Activate the virtual products feature +AssociatedProducts=Virtual product +AssociatedProductsNumber=Number of products composing this virtual product +ParentProductsNumber=Number of parent virtual product +IfZeroItIsNotAVirtualProduct=If 0, this product is not a virtual product +IfZeroItIsNotUsedByVirtualProduct=If 0, this product is not used by any virtual product EditAssociate=Associate Translation=Translation KeywordFilter=Keyword filter @@ -124,7 +126,7 @@ AddDel=Add/Delete Quantity=Quantity NoMatchFound=No match found ProductAssociationList=List of related products/services: name of product/service (quantity affected) -ProductParentList=List of products/services with this product as a component +ProductParentList=List of virtual products/services with this product as a component ErrorAssociationIsFatherOfThis=One of selected product is parent with current product DeleteProduct=Delete a product/service ConfirmDeleteProduct=Are you sure you want to delete this product/service? @@ -184,4 +186,14 @@ AlwaysUseNewPrice=Always use current price of product/service AlwaysUseFixedPrice=Use the fixed price PriceByQuantity=Price by quantity PriceByQuantityRange=Quantity range -ProductsDashboard=Products/Services summary \ No newline at end of file +ProductsDashboard=Products/Services summary +### composition fabrication +Building=Production and items dispatchment +Build=Produce +BuildIt=Produce & Dispatch +BuildindListInfo=Available quantity for production per warehouse (set it to 0 for no further action) +QtyNeed=Qty +UnitPmp=Net unit VWAP +CostPmpHT=Net total VWAP +ProductUsedForBuild=Auto consumed by production +ProductBuilded=Production completed diff --git a/htdocs/langs/en_US/stocks.lang b/htdocs/langs/en_US/stocks.lang index 35aa3ca537a..8a836c7b3dc 100644 --- a/htdocs/langs/en_US/stocks.lang +++ b/htdocs/langs/en_US/stocks.lang @@ -55,6 +55,7 @@ DeStockOnShipment=Decrease real stocks on shipment validation ReStockOnBill=Increase real stocks on suppliers invoices/credit notes validation ReStockOnValidateOrder=Increase real stocks on suppliers orders approbation ReStockOnDispatchOrder=Increase real stocks on manual dispatching into warehouses, after supplier order receiving +ReStockOnDeleteInvoice=Increase real stocks on invoice deletion OrderStatusNotReadyToDispatch=Order has not yet or no more a status that allows dispatching of products in stock warehouses. StockDiffPhysicTeoric=Reason for difference stock physical and theoretical NoPredefinedProductToDispatch=No predefined products for this object. So no dispatching in stock is required. @@ -86,4 +87,5 @@ PersonalStock=Personal stock %s ThisWarehouseIsPersonalStock=This warehouse represents personal stock of %s %s SelectWarehouseForStockDecrease=Choose warehouse to use for stock decrease SelectWarehouseForStockIncrease=Choose warehouse to use for stock increase +NoStockAction=No stock action LastWaitingSupplierOrders=Orders waiting for receptions \ No newline at end of file diff --git a/htdocs/langs/es_ES/admin.lang b/htdocs/langs/es_ES/admin.lang index c42a026c87f..86b6cba5a97 100644 --- a/htdocs/langs/es_ES/admin.lang +++ b/htdocs/langs/es_ES/admin.lang @@ -45,6 +45,8 @@ ErrorModuleRequireDolibarrVersion=Error, este módulo requiere una versión %s o ErrorDecimalLargerThanAreForbidden=Error, las precisiones superiores a %s no están soportadas. DictionnarySetup=Diccionarios Dictionnary=Diccionarios +ErrorReservedTypeSystemSystemAuto=El uso del tipo 'system' y 'systemauto' está reservado. Puede utilizar 'user' como valor para añadir su propio registro +ErrorCodeCantContainZero=El código no puede contener el valor 0 DisableJavascript=Desactivar las funciones Javascript ConfirmAjax=Utilizar los popups de confirmación Ajax UseSearchToSelectCompany=Utilizar un formulario de búsqueda para buscar terceros (en vez de lista desplegable)

Tenga en cuenta que si tiene un gran número de productos o servicios (>100 000), puede mejorar el rendimiento mediante la constante SOCIETE_DONOTSEARCH_ANYWHERE a 1 en Configuración->Varios. La búsqueda se limitará entonces al inicio de la cadena. @@ -290,7 +292,7 @@ ServerNotAvailableOnIPOrPort=Servidor no disponible en la dirección %s e DoTestServerAvailability=Probar conectividad con el servidor DoTestSend=Probar envío DoTestSendHTML=Probar envío HTML -ErrorCantUseRazInStartedYearIfNoYearMonthInMask=Error, no se puede usar opción @ si la secuencia {yy}{mm} o {yyyy}{mm} no se encuentra en la máscara. +ErrorCantUseRazInStartedYearIfNoYearMonthInMask=Error, no se puede usar la opción @ si la secuencia {yy}{mm} o {yyyy}{mm} no se encuentra en la máscara. UMask=Parámetro UMask de nuevos archivos en Unix/Linux/BSD. UMaskExplanation=Este parámetro determina los derechos de los archivos creados en el servidor Dolibarr (durante la subida, por ejemplo).
Este debe ser el valor octal (por ejemplo, 0666 significa lectura / escritura para todos).
Este parámetro no tiene ningún efecto sobre un servidor Windows. SeeWikiForAllTeam=Vea el wiki para más detalles de todos los actores y de su organización @@ -336,7 +338,7 @@ EnterRefToBuildUrl=Introduzca la referencia del objeto %s GetSecuredUrl=Obtener la URL calculada ButtonHideUnauthorized=Ocultar los botones de acciones no autorizadas en vez de mostrarlos atenuados TotalNumberOfActivatedModules=Número total de módulos activados: %s -YouMustEnableOneModule=Debe activar al menos 1 módulo. +YouMustEnableOneModule=Debe activar al menos un módulo. ProductVatMassChange=Modificar IVA en masa ProductVatMassChangeDesc=Esta página le permite cambiar el tipo de IVA definido en los productos o servicios de un valor a otro. Tenga en cuenta que el cambio se lleva a cabo en masa sobre toda la base de datos. OldVATRates=Tasa de IVA antigua @@ -357,7 +359,10 @@ ExtrafieldSelect=Lista de selección ExtrafieldSeparator=Separador ExtrafieldCheckBox=Casilla de verificación ExtrafieldRadio=Botón de selección excluyente -ExtrafieldParamHelp=La lista debe ser en forma llave,valor

por ejemplo :
1,texto1
2,texto2
3,texto3
... +ExtrafieldParamHelpselect=La llista ha de ser en forma clau, valor

per exemple :
1,text1
2,text2
3,text3
... +ExtrafieldParamHelpcheckbox=La llista ha de ser en forma clau, valor

per exemple :
1,text1
2,text2
3,text3
... +ExtrafieldParamHelpradio=La llista ha de ser en forma clau, valor

per exemple :
1,text1
2,text2
3,text3
... +ExtrafieldParamHelpsellist=La llista ha de ser del table

per exemple :
table:label:(code)
LibraryToBuildPDF=Librería usada para la creación de archivos PDF WarningUsingFPDF=Atención: Su archivo conf.php contiene la directiva dolibarr_pdf_force_fpdf=1. Esto hace que se use la librería FPDF para generar sus archivos PDF. Esta librería es antigua y no cubre algunas funcionalidades (Unicode, transparencia de imágenes, idiomas cirílicos, árabes o asiáticos, etc.), por lo que puede tener problemas en la generación de los PDF.
Para resolverlo, y disponer de un soporte completo de PDF, puede descargar la librería TCPDF , y a continuación comentar o eliminar la línea $dolibarr_pdf_force_fpdf=1, y añadir en su lugar $dolibarr_lib_TCPDF_PATH='ruta_a_TCPDF' LocalTaxDesc=Algunos países aplican 2 o 3 tasas a cada línea de factura. Si es el caso, escoja el tipo de la segunda y tercera tasa y su valor. Los posibles tipos son:
1 : tasa local aplicable a productos y servicios sin IVA (IVA no se aplica en la tasa local)
2 : tasa local se aplica a productos y servicios antes del IVA (IVA se calcula sobre importe+tasa local)
3 : tasa local se aplica a productos sin IVA (IVA no se aplica en la tasa local)
4 : tasa local se aplica a productos antes del IVA (IVA se calcula sobre el importe+tasa local)
5 : tasa local se aplica a servicios sin IVA (IVA no se aplica a la tasa local)
6 : tasa local se aplica a servicios antes del IVA (IVA se calcula sobre importe + tasa local) @@ -478,6 +483,8 @@ Module2900Name=GeoIPMaxmind Module2900Desc=Capacidades de conversión GeoIP Maxmind Module5000Name=Multi-empresa Module5000Desc=Permite gestionar varias empresas +Module6000Name=Workflow +Module6000Desc=Gestión de flujos de trabajo Module20000Name=Días libres Module20000Desc=Gestión de los días libres de los empleados Module50000Name=PayBox @@ -541,6 +548,7 @@ Permission98=Desglosar líneas de facturas Permission101=Consultar expediciones Permission102=Crear/modificar expediciones Permission104=Validar expediciones +Permission106=Exportar expediciones Permission109=Eliminar expediciones Permission111=Consultar cuentas financieras (cuentas bancarias, cajas) Permission112=Crear/modificar cantidad/eliminar registros bancarios @@ -911,7 +919,7 @@ MAIN_ROUNDING_RULE_TOT=Tamaño rango para el redondeo (para algunos países que UnitPriceOfProduct=Precio unitario sin IVA de un producto TotalPriceAfterRounding=Precio total después del redondeo ParameterActiveForNextInputOnly=Parámetro efectivo solamente a partir de las próximas sesiones -NoEventOrNoAuditSetup=No se han registrado eventos de seguridad. Esto puede ser normal si la auditoría no ha sido habilitado en la página "configuración->seguridad->auditoría". +NoEventOrNoAuditSetup=No se han registrado eventos de seguridad. Esto puede ser normal si la auditoría no ha sido habilitada en la página "configuración->seguridad->auditoría". NoEventFoundWithCriteria=No se han encontrado eventos de seguridad para tales criterios de búsqueda. SeeLocalSendMailSetup=Ver la configuración local de sendmail BackupDesc=Para realizar una copia de seguridad completa de Dolibarr, usted debe: diff --git a/htdocs/langs/es_ES/agenda.lang b/htdocs/langs/es_ES/agenda.lang index e0131db59fe..70a768bec15 100644 --- a/htdocs/langs/es_ES/agenda.lang +++ b/htdocs/langs/es_ES/agenda.lang @@ -41,6 +41,7 @@ ActionsEvents=Eventos para que Dolibarr cree una acción de forma automática PropalValidatedInDolibarr=Presupuesto %s validado InvoiceValidatedInDolibarr=Factura %s validada InvoiceBackToDraftInDolibarr=Factura %s devuelta a borrador +InvoiceDeleteDolibarr=Factura %s eliminada OrderValidatedInDolibarr=Pedido %s validado OrderApprovedInDolibarr=Pedido %s aprobado OrderBackToDraftInDolibarr=Pedido %s devuelto a borrador diff --git a/htdocs/langs/es_ES/bills.lang b/htdocs/langs/es_ES/bills.lang index ff1d75eb358..e4a414b8fed 100644 --- a/htdocs/langs/es_ES/bills.lang +++ b/htdocs/langs/es_ES/bills.lang @@ -250,7 +250,7 @@ Deposit=Anticipo Deposits=Anticipos DiscountFromCreditNote=Descuento resultante del abono %s DiscountFromDeposit=Pagos de la factura de anticipo %s -AbsoluteDiscountUse=Este tipo de crédito no puede ser utilizado en una factura antes de su validación +AbsoluteDiscountUse=Este tipo de descuento no puede ser utilizado en una factura antes de su validación CreditNoteDepositUse=La factura debe de estar validada para poder utilizar este tipo de créditos NewGlobalDiscount=Nuevo descuento fijo NewRelativeDiscount=Nuevo descuento @@ -287,6 +287,8 @@ TotalOfTwoDiscountMustEqualsOriginal=La suma del importe de los 2 nuevos descuen ConfirmRemoveDiscount=¿Está seguro de querer eliminar este descuento? RelatedBill=Factura asociada RelatedBills=Facturas asociadas +FixAmount=Importe fijo +VarAmount=Importe variable (%% total) # PaymentConditions PaymentConditionShortRECEP=A la recepción diff --git a/htdocs/langs/es_ES/commercial.lang b/htdocs/langs/es_ES/commercial.lang index 3b5d007aac9..9d774606bf0 100644 --- a/htdocs/langs/es_ES/commercial.lang +++ b/htdocs/langs/es_ES/commercial.lang @@ -81,6 +81,7 @@ ActionAC_SHIP=Envío expedición por correo ActionAC_SUP_ORD=Envío pedido a proveedor por correo ActionAC_SUP_INV=Envío factura de proveedor por correo ActionAC_OTH=Otra +ActionAC_OTH_AUTO=Otra (eventos insertados automáticamente) ActionAC_MANUAL=Eventos creados manualmente ActionAC_AUTO=Eventos creados automáticamente Stats=Estadísticas de venta diff --git a/htdocs/langs/es_ES/externalsite.lang b/htdocs/langs/es_ES/externalsite.lang index 6052639eb4b..131d9f69fc4 100644 --- a/htdocs/langs/es_ES/externalsite.lang +++ b/htdocs/langs/es_ES/externalsite.lang @@ -1,4 +1,5 @@ # Dolibarr language file - es_ES - externalsite CHARSET=UTF-8 ExternalSiteSetup=Configuración del enlace al sitio web externo -ExternalSiteURL=URL del sitio externo \ No newline at end of file +ExternalSiteURL=URL del sitio externo +ExternalSiteModuleNotComplete=El módulo Sitio web externo no ha sido configurado correctamente. \ No newline at end of file diff --git a/htdocs/langs/es_ES/holiday.lang b/htdocs/langs/es_ES/holiday.lang index ebf1a0457d9..93387f29525 100644 --- a/htdocs/langs/es_ES/holiday.lang +++ b/htdocs/langs/es_ES/holiday.lang @@ -132,4 +132,9 @@ NoCPforMonth=Sin vacaciones este mes. Jours=días nbJours=Número de días TitleAdminCP=Configuración de las vacaciones -Permission20001=Leer / Crear / Modificar sus vacaciones \ No newline at end of file +Permission20001=Consultar/crear/modificar sus vacaciones +Permission20002=Consultar/modificar todas las solicitudes de permisos retribuídos +Permission20003=Eliminar las solicitudes de permisos retribuídos +Permission20004=Definir los permisos retribuídos de los usuarios +Permission20005=Consultar el historial de modificaciones de permisos retribuidos +Permission20006=Acceder al informe mensual de permisos retribuidos \ No newline at end of file diff --git a/htdocs/langs/es_ES/main.lang b/htdocs/langs/es_ES/main.lang index b1c231a4a67..aece1ad9d15 100644 --- a/htdocs/langs/es_ES/main.lang +++ b/htdocs/langs/es_ES/main.lang @@ -4,8 +4,11 @@ DIRECTION=ltr SeparatorDecimal=, SeparatorThousand= FormatDateShort=%d/%m/%Y +FormatDateShortInput=%d/%m/%Y FormatDateShortJava=dd/MM/yyyy +FormatDateShortJavaInput=dd/MM/yyyy FormatDateShortJQuery=dd/mm/yy +FormatDateShortJQueryInput=dd/mm/yy FormatHourShort=%H:%M FormatHourShortDuration=%H:%M FormatDateTextShort=%d %b %Y diff --git a/htdocs/langs/es_ES/other.lang b/htdocs/langs/es_ES/other.lang index 60af821e8c1..6d53b9de9cb 100644 --- a/htdocs/langs/es_ES/other.lang +++ b/htdocs/langs/es_ES/other.lang @@ -151,6 +151,7 @@ EMailTextOrderApproved=Pedido %s aprobado EMailTextOrderApprovedBy=Pedido %s aprobado por %s EMailTextOrderRefused=Pedido %s rechazado EMailTextOrderRefusedBy=Pedido %s rechazado por %s +EMailTextExpeditionValidated=El envío %s ha sido validado. ImportedWithSet=Lote de importación (import key) DolibarrNotification=Notificación automática ResizeDesc=Introduzca el nuevo ancho O la nueva altura. La relación se conserva al cambiar el tamaño ... diff --git a/htdocs/langs/es_ES/stocks.lang b/htdocs/langs/es_ES/stocks.lang index fe51937ac65..be0bf800bb8 100644 --- a/htdocs/langs/es_ES/stocks.lang +++ b/htdocs/langs/es_ES/stocks.lang @@ -54,6 +54,7 @@ DeStockOnShipment=Decrementar los stocks físicos sobre los envíos ReStockOnBill=Incrementar los stocks físicos sobre las facturas/abonos de proveedores ReStockOnValidateOrder=Incrementar los stocks físicos sobre los pedidos a proveedores ReStockOnDispatchOrder=Incrementa los stocks físicos en el desglose manual de la recepción de los pedidos a proveedores en los almacenes +ReStockOnDeleteInvoice=Incrementa los stocks físicos en la eliminación de facturas OrderStatusNotReadyToDispatch=El pedido aún no está o no tiene un estado que permita un desglose de stock. StockDiffPhysicTeoric=Motivo de la diferencia entre valores físicos y teóricos NoPredefinedProductToDispatch=No hay productos predefinidos en este objeto. Por lo tanto no se puede realizar un desglose de stock. @@ -85,4 +86,5 @@ PersonalStock=Stock personal %s ThisWarehouseIsPersonalStock=Este almacén representa el stock personal de %s %s SelectWarehouseForStockDecrease=Seleccione el almacén a usar en el decremento de stock SelectWarehouseForStockIncrease=Seleccione el almacén a usar en el incremento de stock +NoStockAction=Sin acciones sobre el stock LastWaitingSupplierOrders=Pedidos en espera de recepción \ No newline at end of file diff --git a/htdocs/langs/es_HN/main.lang b/htdocs/langs/es_HN/main.lang index 390b2055e2f..421e7598de5 100644 --- a/htdocs/langs/es_HN/main.lang +++ b/htdocs/langs/es_HN/main.lang @@ -3,15 +3,6 @@ CHARSET=UTF-8 DIRECTION=ltr SeparatorDecimal=, SeparatorThousand= -FormatDateShort=%d/%m/%Y -FormatDateShortJava=dd/MM/yyyy -FormatHourShort=%H:%M -FormatHourShortDuration=%H:%M -FormatDateTextShort=%d %b %Y -FormatDateText=%d %B %Y -FormatDateHourShort=%d/%m/%Y %H:%M -FormatDateHourTextShort=%d %b %Y %H:%M -FormatDateHourText=%d %B %Y %H:%M AmountVAT=Importe ISV TotalVAT=Total ISV IncludedVAT=ISV incluido diff --git a/htdocs/langs/es_PR/main.lang b/htdocs/langs/es_PR/main.lang index 401b367ff52..5cb39740ada 100644 --- a/htdocs/langs/es_PR/main.lang +++ b/htdocs/langs/es_PR/main.lang @@ -3,15 +3,6 @@ CHARSET=UTF-8 DIRECTION=ltr SeparatorDecimal=, SeparatorThousand= -FormatDateShort=%d/%m/%Y -FormatDateShortJava=dd/MM/yyyy -FormatHourShort=%H:%M -FormatHourShortDuration=%H:%M -FormatDateTextShort=%d %b %Y -FormatDateText=%d %B %Y -FormatDateHourShort=%d/%m/%Y %H:%M -FormatDateHourTextShort=%d %b %Y %H:%M -FormatDateHourText=%d %B %Y %H:%M AmountVAT=Importe IVU TotalVAT=Total IVU IncludedVAT=IVU incluido diff --git a/htdocs/langs/et_EE/main.lang b/htdocs/langs/et_EE/main.lang index f02122fad5b..086bfe8b5b0 100644 --- a/htdocs/langs/et_EE/main.lang +++ b/htdocs/langs/et_EE/main.lang @@ -12,8 +12,11 @@ DIRECTION=ltr SeparatorDecimal=. SeparatorThousand=, FormatDateShort=%m/%d/%Y +FormatDateShortInput=%m/%d/%Y FormatDateShortJava=MM/dd/yyyy +FormatDateShortJavaInput=MM/dd/yyyy FormatDateShortJQuery=dd/mm/yy +FormatDateShortJQueryInput=dd/mm/yy FormatHourShort=%I:%M %p FormatHourShortDuration=%H:%M FormatDateTextShort=%b %d, %Y diff --git a/htdocs/langs/fa_IR/main.lang b/htdocs/langs/fa_IR/main.lang index 4cb4fc7d9f7..6645152d1d2 100644 --- a/htdocs/langs/fa_IR/main.lang +++ b/htdocs/langs/fa_IR/main.lang @@ -15,7 +15,11 @@ FONTSIZEFORPDF=9 SeparatorDecimal=/ SeparatorThousand=, FormatDateShort=%d/%m/%Y +FormatDateShortInput=%d/%m/%Y FormatDateShortJava=dd/MM/yyyy +FormatDateShortJavaInput=dd/MM/yyyy +FormatDateShortJQuery=dd/mm/yy +FormatDateShortJQueryInput=dd/mm/yy FormatHourShort=%H:%M FormatDateTextShort=%d %b %Y FormatDateText=%d %B %Y diff --git a/htdocs/langs/fi_FI/main.lang b/htdocs/langs/fi_FI/main.lang index 734a3356dd9..b451e91e115 100644 --- a/htdocs/langs/fi_FI/main.lang +++ b/htdocs/langs/fi_FI/main.lang @@ -11,7 +11,11 @@ CHARSET=UTF-8 SeparatorDecimal=, SeparatorThousand= FormatDateShort=%d.%m.%Y +FormatDateShortInput=%d.%m.%Y FormatDateShortJava=dd.MM.yyyy +FormatDateShortJavaInput=dd.MM.yyyy +FormatDateShortJQuery=dd.mm.yy +FormatDateShortJQueryInput=dd.mm.yy FormatHourShort=%H.%M FormatDateTextShort=%d. %b %Y FormatDateText=%d. %B %Y @@ -616,7 +620,6 @@ Prefix=Etuliite // START - Lines generated via autotranslator.php tool (2012-02-29 16:10:23). // Reference language: en_US -> fi_FI -FormatDateShortJQuery=dd/mm/yy AddLink=Lisää linkki Of=ja SearchOf=Etsi diff --git a/htdocs/langs/fr_BE/main.lang b/htdocs/langs/fr_BE/main.lang index 3a222bdd6b9..664e394aeba 100644 --- a/htdocs/langs/fr_BE/main.lang +++ b/htdocs/langs/fr_BE/main.lang @@ -3,7 +3,11 @@ CHARSET=UTF-8 SeparatorDecimal=, SeparatorThousand= FormatDateShort=%d/%m/%Y +FormatDateShortInput=%d/%m/%Y FormatDateShortJava=dd/MM/yyyy +FormatDateShortJavaInput=dd/MM/yyyy +FormatDateShortJQuery=dd/mm/yy +FormatDateShortJQueryInput=dd/mm/yy FormatHourShort=%H:%M FormatDateTextShort=%d %b %Y FormatDateText=%d %B %Y diff --git a/htdocs/langs/fr_CA/main.lang b/htdocs/langs/fr_CA/main.lang index 3cd76162e3d..ca4b13b8480 100644 --- a/htdocs/langs/fr_CA/main.lang +++ b/htdocs/langs/fr_CA/main.lang @@ -3,7 +3,11 @@ CHARSET=UTF-8 SeparatorDecimal=, SeparatorThousand= FormatDateShort=%d.%m.%Y +FormatDateShortInput=%d.%m.%Y FormatDateShortJava=dd.MM.yyyy +FormatDateShortJavaInput=dd.MM.yyyy +FormatDateShortJQuery=dd.mm.yy +FormatDateShortJQueryInput=dd.mm.yy FormatHourShort=%H:%M FormatDateTextShort=%d %b %Y FormatDateText=%d %B %Y diff --git a/htdocs/langs/fr_CH/main.lang b/htdocs/langs/fr_CH/main.lang index dbe4956c684..83cc40057ea 100644 --- a/htdocs/langs/fr_CH/main.lang +++ b/htdocs/langs/fr_CH/main.lang @@ -3,7 +3,11 @@ CHARSET=UTF-8 SeparatorDecimal=, SeparatorThousand= FormatDateShort=%d-%m-%Y +FormatDateShortInput=%d-%m-%Y FormatDateShortJava=dd-MM-yyyy +FormatDateShortJavaInput=dd-MM-yyyy +FormatDateShortJQuery=dd-mm-yy +FormatDateShortJQueryInput=dd-mm-yy FormatHourShort=%H:%M FormatDateTextShort=%d %b %Y FormatDateText=%d %B %Y diff --git a/htdocs/langs/fr_FR/admin.lang b/htdocs/langs/fr_FR/admin.lang index d1bc47fb624..cc2ee5b2a4e 100644 --- a/htdocs/langs/fr_FR/admin.lang +++ b/htdocs/langs/fr_FR/admin.lang @@ -45,6 +45,8 @@ ErrorModuleRequireDolibarrVersion= Erreur, ce module requiert une version %s ou ErrorDecimalLargerThanAreForbidden= Erreur, les précisions supérieures à %s ne sont pas supportées. DictionnarySetup= Dictionnaires Dictionnary= Dictionnaires +ErrorReservedTypeSystemSystemAuto= +ErrorCodeCantContainZero= DisableJavascript= Désactiver les fonctions Javascript et Ajax ConfirmAjax= Utiliser les popups de confirmation Ajax UseSearchToSelectCompany= Utiliser un champ avec autocomplétion pour choisir un tiers (plutôt qu'une liste déroulante).

Notez que si vous avez un nombre important de tiers (> 100 000), vous pouvez améliorer les performances en définissant la constante SOCIETE_DONOTSEARCH_ANYWHERE à 1 dans Configuration->Divers. La recherche sera alors limitée au début de la chaine. @@ -357,7 +359,10 @@ ExtrafieldSelect = Liste de sélection ExtrafieldSeparator = Séparateur de champ ExtrafieldCheckBox=Case à cocher ExtrafieldRadio=Case d'option -ExtrafieldParamHelp=La liste doit être de la forme clef,valeur

par exemple :
1,valeur1
2,valeur2
3,valeur3
... +ExtrafieldParamHelpselect=La liste doit être de la forme clef,valeur

par exemple :
1,valeur1
2,valeur2
3,valeur3
... +ExtrafieldParamHelpcheckbox=La liste doit être de la forme clef,valeur

par exemple :
1,valeur1
2,valeur2
3,valeur3
... +ExtrafieldParamHelpradio=La liste doit être de la forme clef,valeur

par exemple :
1,valeur1
2,valeur2
3,valeur3
... +ExtrafieldParamHelpsellist=La liste vient d'une table

par exemple :
c_typent:libelle:id
LibraryToBuildPDF=Bibliothèque utilisée pour la génération des PDF WarningUsingFPDF=Attention: Votre fichier conf.php contient la directive dolibarr_pdf_force_fpdf=1. Cela signifie que vous utilisez la librairie FPDF pour générer vos fichiers PDF. Cette librairie est ancienne et ne couvre pas de nombreuses fonctionnalitée (Unicode, transparence des images, langues cyrillic, arabes ou asiatiques...), aussi vous pouvez rencontrez des problèmes durant la génération des PDF.
Pour résoudre cela et avoir un support complet de PDF, vous pouvez télécharger la librairie TCPDF puis commenter ou supprimer la ligne $dolibarr_pdf_force_fpdf=1, et ajouter à la place $dolibarr_lib_TCPDF_PATH='chemin_vers_TCPDF' LocalTaxDesc=Certains pays appliquent 2 voir 3 taux sur chaque ligne de facture. Si c'est le cas, choisissez le type du deuxième et troisième taux et sa valeur. Les types possibles sont:
1 : taxe locale sur les produits et services hors tva (la tva n'est pas appliquée sur la taxe locale)
2 : taxe locale sur les produits et services avant tva (la tva est appliquée sur le montant + la taxe locale)
3 : taxe locale uniquement sur les produits hors tva (la tva n'est pas appliquée sur la taxe locale)
4 : taxe locale uniquement sur les produits avant tva (la tva est appliquée sur le montant + la taxe locale)
5 : taxe locale uniquement sur les services hors tva (la tva n'est pas appliquée sur la taxe locale)
6 : taxe locale uniquement sur les service avant tva (la tva est appliquée sur le montant + la taxe locale) @@ -542,6 +547,7 @@ Permission98= Ventiler les lignes de factures Permission101= Consulter les expéditions Permission102= Créer/modifier les expéditions Permission104= Valider les expéditions +Permission106= Exporter les expéditions Permission109= Supprimer les expéditions Permission111= Consulter les comptes financiers (comptes bancaires, caisses) Permission112= Créer/modifier montant/supprimer écritures bancaires diff --git a/htdocs/langs/fr_FR/agenda.lang b/htdocs/langs/fr_FR/agenda.lang index 33555be6951..62b09ec39d1 100644 --- a/htdocs/langs/fr_FR/agenda.lang +++ b/htdocs/langs/fr_FR/agenda.lang @@ -32,7 +32,7 @@ ViewCal=Vue mois ViewDay=Vue jour ViewWeek=Vue semaine ViewWithPredefinedFilters=Vues avec filtres prédéfinis -AutoActions=Alimentation automatique de l'agenda +AutoActions=Alimentation automatique AgendaAutoActionDesc=Définissez dans cet onglet les événements pour lesquels dolibarr créera automatiquement une action dans l'agenda. Si aucune case n'est cochée (par défaut), seules les actions manuelles seront incluses dans l'agenda. AgendaSetupOtherDesc=Cette page permet de configurer quelques options permettant d'exporter une vue de votre agenda Dolibarr vers un calendrier externe (thunderbird, google calendar, ...) AgendaExtSitesDesc=Cette page permet d'ajouter des sources de calendriers externes pour les visualiser au sein de l'agenda Dolibarr. @@ -40,6 +40,7 @@ ActionsEvents=Événements pour lesquels Dolibarr doit créer une action dans l' PropalValidatedInDolibarr=Proposition %s validée InvoiceValidatedInDolibarr=Facture %s validée InvoiceBackToDraftInDolibarr=Facture %s repassée en brouillon +InvoiceDeleteDolibarr=Facture %s supprimée OrderValidatedInDolibarr=Commande %s validée OrderApprovedInDolibarr=Commande %s approuvée OrderBackToDraftInDolibarr=Commande %s repassée en brouillon @@ -66,6 +67,7 @@ AgendaUrlOptions4=logint=%s pour limiter l'export aux actions affectées AgendaUrlOptions5=logind=%s pour limiter l'export aux actions réalisées par l'utilisateur %s. AgendaShowBirthdayEvents=Afficher anniversaires contacts AgendaHideBirthdayEvents=Cacher anniversaires contacts +Busy=Occupé # External Sites ical ExportCal=Export calendrier diff --git a/htdocs/langs/fr_FR/bills.lang b/htdocs/langs/fr_FR/bills.lang index 0c87fb93f66..adfa9a34bdc 100644 --- a/htdocs/langs/fr_FR/bills.lang +++ b/htdocs/langs/fr_FR/bills.lang @@ -322,6 +322,8 @@ PaymentTypeVAD=Paiement en ligne PaymentTypeShortVAD=Paiement en ligne PaymentTypeTRA=Paiement par traite PaymentTypeShortTRA=Traite +FixAmount=Montant Fixe +VarAmount=Montant variable (%% tot.) BankDetails=Coordonnées bancaires BankCode=Code banque diff --git a/htdocs/langs/fr_FR/commercial.lang b/htdocs/langs/fr_FR/commercial.lang index 5c5747baa92..c13b1b09ea2 100644 --- a/htdocs/langs/fr_FR/commercial.lang +++ b/htdocs/langs/fr_FR/commercial.lang @@ -81,6 +81,7 @@ ActionAC_SHIP=Envoi bon d'expédition par mail ActionAC_SUP_ORD=Envoi commande fournisseur par mail ActionAC_SUP_INV=Envoi facture fournisseur par mail ActionAC_OTH=Autre +ActionAC_OTH_AUTO=Autre (evênements insérés automatiquement) ActionAC_MANUAL=Evênements insérés manuellement ActionAC_AUTO=Evênements insérés automatiquement Stats=Statistiques de vente diff --git a/htdocs/langs/fr_FR/compta.lang b/htdocs/langs/fr_FR/compta.lang index 1491a7820f4..227b6b734ad 100644 --- a/htdocs/langs/fr_FR/compta.lang +++ b/htdocs/langs/fr_FR/compta.lang @@ -163,4 +163,5 @@ Pcg_type=Classe de compte Pcg_subtype=Sous classe de compte InvoiceLinesToDispatch=Lignes de factures à ventiler InvoiceDispatched=Factures ventilées -AccountancyDashboard=Synthèse compta/tréso \ No newline at end of file +AccountancyDashboard=Synthèse compta/tréso +ByProductsAndServices=Par produits et services diff --git a/htdocs/langs/fr_FR/errors.lang b/htdocs/langs/fr_FR/errors.lang index f1316e03d13..5081f66d5f7 100644 --- a/htdocs/langs/fr_FR/errors.lang +++ b/htdocs/langs/fr_FR/errors.lang @@ -137,4 +137,5 @@ WarningLockFileDoesNotExists=Attention, une fois l'installation terminée, les o WarningUntilDirRemoved=Les alertes de sécurité sont visibles par les administrateurs uniquement et resteront actives tant que la vulnérabilité sera avérée (ou que la constante MAIN_REMOVE_INSTALL_WARNING aura été définie dans Configuration->Divers) WarningCloseAlways=Attention, la fermeture se fait même lorsque le montant diffère. N'activez cette fonctionnalité qu'en connaissance de cause. WarningUsingThisBoxSlowDown=Attention, l'utilisation de cette boite provoque de sérieux ralentissement des pages affichant cette boite. -WarningClickToDialUserSetupNotComplete=La configuration ClickToDial pour votre compte utilisateur n'est pas complète (voir l'onglet ClickToDial sur votre fiche utilisateur) \ No newline at end of file +WarningClickToDialUserSetupNotComplete=La configuration ClickToDial pour votre compte utilisateur n'est pas complète (voir l'onglet ClickToDial sur votre fiche utilisateur) +WarningNotRelevant=Opération non pertinente pour cet ensemble de données diff --git a/htdocs/langs/fr_FR/externalsite.lang b/htdocs/langs/fr_FR/externalsite.lang index ff1fb3112c1..36c8686a3c3 100644 --- a/htdocs/langs/fr_FR/externalsite.lang +++ b/htdocs/langs/fr_FR/externalsite.lang @@ -1,4 +1,5 @@ # Dolibarr language file - fr_FR - externalsite CHARSET=UTF-8 ExternalSiteSetup=Configuration du lien vers le site externe -ExternalSiteURL=URL du site externe \ No newline at end of file +ExternalSiteURL=URL du site externe +ExternalSiteModuleNotComplete= \ No newline at end of file diff --git a/htdocs/langs/fr_FR/holiday.lang b/htdocs/langs/fr_FR/holiday.lang index e6c0d33ad98..a9f4c758d8d 100644 --- a/htdocs/langs/fr_FR/holiday.lang +++ b/htdocs/langs/fr_FR/holiday.lang @@ -130,4 +130,9 @@ NoCPforMonth=Aucun congé ce mois-ci. Jours=jours nbJours=Nombre jours TitleAdminCP=Configuration des Congés -Permission20001=Lire / Créer / modifier ses congés +Permission20001=Lire / Créer / modifier ses congès +Permission20002=Lire / Modifier toutes les demandes de congés payés +Permission20003=Supprimer des demandes de congés payés +Permission20004=Définir les congés payés des utilisateurs +Permission20005=Voir les logs de modification des congés payés +Permission20006=Accéder au rapport mensuel des congés payés diff --git a/htdocs/langs/fr_FR/main.lang b/htdocs/langs/fr_FR/main.lang index b31b711f3a3..bad84a57548 100644 --- a/htdocs/langs/fr_FR/main.lang +++ b/htdocs/langs/fr_FR/main.lang @@ -4,8 +4,11 @@ DIRECTION=ltr SeparatorDecimal=, SeparatorThousand= FormatDateShort=%d/%m/%Y +FormatDateShortInput=%d/%m/%Y FormatDateShortJava=dd/MM/yyyy +FormatDateShortJavaInput=dd/MM/yyyy FormatDateShortJQuery=dd/mm/yy +FormatDateShortJQueryInput=dd/mm/yy FormatHourShort=%H:%M FormatHourShortDuration=%H:%M FormatDateTextShort=%d %b %Y @@ -475,6 +478,8 @@ Report=Rapport Keyword=Mot clé Legend=Légende FillTownFromZip=Renseigner ville +Fill=Remplir +Reset=Vider ShowLog=Afficher historique File=Fichier Files=Fichiers diff --git a/htdocs/langs/fr_FR/other.lang b/htdocs/langs/fr_FR/other.lang index de941e850a6..86218e219be 100644 --- a/htdocs/langs/fr_FR/other.lang +++ b/htdocs/langs/fr_FR/other.lang @@ -151,6 +151,7 @@ EMailTextOrderApproved=La commande %s a été approuvée. EMailTextOrderApprovedBy=La commande %s a été approuvée par %s. EMailTextOrderRefused=La commande %s a été refusée. EMailTextOrderRefusedBy=La commande %s a été refusée par %s. +EMailTextExpeditionValidated= ImportedWithSet=Lot d'importation (Import key) DolibarrNotification=Notification automatique ResizeDesc=Entrer la nouvelle largeur OU la nouvelle hauteur. Le ratio est conservé lors du redimensionnement... diff --git a/htdocs/langs/fr_FR/products.lang b/htdocs/langs/fr_FR/products.lang index 3d27fdd9d6d..bd1c1075e2e 100644 --- a/htdocs/langs/fr_FR/products.lang +++ b/htdocs/langs/fr_FR/products.lang @@ -111,11 +111,13 @@ ServiceLimitedDuration=Si produit de type service à durée limitée : MultiPricesAbility=Prise en charge de prix multiples MultiPricesNumPrices=Nombre de prix MultiPriceLevelsName=Catégorie de prix -AssociatedProductsAbility=Prise en charge des produits composés -AssociatedProducts=Composition -AssociatedProductsNumber=Nbre de sous-produits composant ce produit -ParentProductsNumber=Nbre de produits parent -EditAssociate=Composer +AssociatedProductsAbility=Prise en charge des produits virtuels +AssociatedProducts=Produit virtuel +AssociatedProductsNumber=Nbre de sous-produits constituant ce produit virtuel +ParentProductsNumber=Nbre de produits virtuels parent +IfZeroItIsNotAVirtualProduct=Si 0, ce produit n'est pas un produit virtuel +IfZeroItIsNotUsedByVirtualProduct=Si 0, ce produit n'est pas utilisé par un produit virtuel +EditAssociate=Composer comme produit virtuel Translation=Traduction KeywordFilter=Filtre par mot-clé CategoryFilter=Filtre par catégorie @@ -123,8 +125,8 @@ ProductToAddSearch=Recherche des produits à ajouter AddDel=Ajouter/Retirer Quantity=Quantité NoMatchFound=Aucun résultat n'a été trouvé -ProductAssociationList=Liste des produits/services composant ce produit: Le nombre entre parenthèse est la quantité affectée dans cette composition. -ProductParentList=Liste des produits/services avec ce produit comme composante +ProductAssociationList=Liste des produits/services composant ce produit virtuel: Le nombre entre parenthèse est la quantité affectée dans cette composition. +ProductParentList=Liste des produits/services virtuels avec ce produit comme composante ErrorAssociationIsFatherOfThis=L'un des produits sélectionnés est parent du produit en cours DeleteProduct=Supprimer un produit/service ConfirmDeleteProduct=Êtes-vous sûr de vouloir supprimer ce produit/service ? @@ -184,4 +186,12 @@ AlwaysUseNewPrice=Toujours utiliser le prix du jour AlwaysUseFixedPrice=Utiliser le prix fixé PriceByQuantity=Prix par quantité PriceByQuantityRange=Grille de quantités -ProductsDashboard=Synthèse produits/services \ No newline at end of file +ProductsDashboard=Synthèse produits/services +### composition fabrication +Building=Fabrication +Build=Fabriquer +BuildIt=Lancer la fabrication +BuildindListInfo=Nombre de produit fabricable par entrepot, si saisie à zéro on ne fabrique pas +QtyNeed=Affectée +UnitPmp=Prix Achat Unitaire +CostPmpHT=Cout à l'achat HT diff --git a/htdocs/langs/fr_FR/stocks.lang b/htdocs/langs/fr_FR/stocks.lang index fb016e23ef3..1b2daaf9521 100644 --- a/htdocs/langs/fr_FR/stocks.lang +++ b/htdocs/langs/fr_FR/stocks.lang @@ -55,6 +55,7 @@ DeStockOnShipment=Décrémente les stocks physiques sur validation des expéditi ReStockOnBill=Incrémente les stocks physiques sur validation des factures/avoirs fournisseurs ReStockOnValidateOrder=Incrémente les stocks physiques sur approbation des commandes fournisseurs ReStockOnDispatchOrder=Incrémente les stocks physiques sur ventilation manuelle de la réception des commandes fournisseurs dans les entrepôts +ReStockOnDeleteInvoice=Incrémente les stocks physiques sur la suppression des factures OrderStatusNotReadyToDispatch=La commande n'a pas encore ou n'a plus un statut permettant une ventilation en stock. StockDiffPhysicTeoric=Raison écart stock physique-théorique NoPredefinedProductToDispatch=Pas de produits prédéfinis dans cet objet. Aucune ventilation en stock n'est donc à faire. @@ -86,4 +87,5 @@ PersonalStock=Stock personnel %s ThisWarehouseIsPersonalStock=Cet entrepôt représente le stock personnel de %s %s SelectWarehouseForStockDecrease=Sélectionner l'entrepôt à utiliser pour la décrémentation du stock SelectWarehouseForStockIncrease=Sélectionner l'entrepôt à utiliser pour l'incrémentation du stock +NoStockAction=Pas d'action sur l'entrepot LastWaitingSupplierOrders=Commandes en attente de réception \ No newline at end of file diff --git a/htdocs/langs/he_IL/main.lang b/htdocs/langs/he_IL/main.lang index 1561f468861..03c0061acf1 100644 --- a/htdocs/langs/he_IL/main.lang +++ b/htdocs/langs/he_IL/main.lang @@ -15,8 +15,11 @@ FONTSIZEFORPDF=9 SeparatorDecimal=. SeparatorThousand=, FormatDateShort=%m/%d/%Y +FormatDateShortInput=%m/%d/%Y FormatDateShortJava=MM/dd/yyyy -FormatDateShortJQuery=dd/mm/yy +FormatDateShortJavaInput=MM/dd/yyyy +FormatDateShortJQuery=mm/dd/yy +FormatDateShortJQueryInput=mm/dd/yy FormatHourShort=%I:%M %p FormatHourShortDuration=%H:%M FormatDateTextShort=%b %d, %Y diff --git a/htdocs/langs/hu_HU/main.lang b/htdocs/langs/hu_HU/main.lang index 8ee7c826648..9fb2cf4f61d 100644 --- a/htdocs/langs/hu_HU/main.lang +++ b/htdocs/langs/hu_HU/main.lang @@ -5,7 +5,11 @@ FONTFORPDF=dejavusans SeparatorDecimal=. SeparatorThousand=, FormatDateShort=%d/%m/%Y +FormatDateShortInput=%d/%m/%Y FormatDateShortJava=dd/MM/yyyy +FormatDateShortJavaInput=dd/MM/yyyy +FormatDateShortJQuery=dd/mm/yy +FormatDateShortJQueryInput=dd/mm/yy FormatHourShort=%I:%M %p FormatHourShortDuration=%H:%M FormatDateTextShort=%b %d, %Y @@ -587,7 +591,6 @@ ShortSunday=V // START - Lines generated via autotranslator.php tool (2012-02-29 16:13:31). // Reference language: en_US -> hu_HU -FormatDateShortJQuery=dd/mm/yy AddLink=Link hozzáadása Of=A SearchOf=Keresés diff --git a/htdocs/langs/is_IS/main.lang b/htdocs/langs/is_IS/main.lang index 619f60994d9..c89746ed401 100644 --- a/htdocs/langs/is_IS/main.lang +++ b/htdocs/langs/is_IS/main.lang @@ -12,7 +12,11 @@ DIRECTION=ltr SeparatorDecimal=. SeparatorThousand=, FormatDateShort=%d/%m/%Y +FormatDateShortInput=%d/%m/%Y FormatDateShortJava=dd/MM/yyyy +FormatDateShortJavaInput=dd/MM/yyyy +FormatDateShortJQuery=dd/mm/yy +FormatDateShortJQueryInput=dd/mm/yy FormatHourShort=%H:%M FormatDateTextShort=%d %b %Y FormatDateText=%d %B %Y @@ -604,7 +608,6 @@ Reason=Ástæða // START - Lines generated via autotranslator.php tool (2012-02-29 16:26:19). // Reference language: en_US -> is_IS -FormatDateShortJQuery=dd/mm/yy AddLink=Bæta við tengli Of=á SearchOf=Leita diff --git a/htdocs/langs/it_IT/main.lang b/htdocs/langs/it_IT/main.lang index 43e9b108b78..78664cd01f8 100644 --- a/htdocs/langs/it_IT/main.lang +++ b/htdocs/langs/it_IT/main.lang @@ -270,15 +270,18 @@ FollowingConstantsWillBeSubstituted =Le seguenti costanti saranno sostitute ForCustomer =Per i clienti FormatDateHourShort =%d/%m/%Y %H.%M FormatDateHourText =%d %B %Y %H:%M -FormatDateHourTextShort =%d %b %Y %H.%M +FormatDateHourTextShort =%d %b %Y %H.%M FormatDateShort =%d/%m/%Y +FormatDateShortInput =%d/%m/%Y FormatDateShortJava =dd/MM/yyyy -FormatDateShortJQuery =dd/mm/yy +FormatDateShortJavaInput =dd/MM/yyyy +FormatDateShortJQuery =dd/mm/yy +FormatDateShortJQueryInput =dd/mm/yy FormatDateText =%d %B %Y FormatDateTextShort =%d %b %Y -FormatHourShortDuration =%H:%M -FormatHourShort =%H.%M -For =Per +FormatHourShortDuration =%H:%M +FormatHourShort =%H.%M +For =Per FreeZone =Testo libero Frequency =Frequenza FridayMin =Ven diff --git a/htdocs/langs/ja_JP/main.lang b/htdocs/langs/ja_JP/main.lang index 6f6201cb7ec..d4c93c068e5 100644 --- a/htdocs/langs/ja_JP/main.lang +++ b/htdocs/langs/ja_JP/main.lang @@ -9,9 +9,12 @@ FONTSIZEFORPDF=9 // Reference language: en_US -> ja_JP SeparatorDecimal=. SeparatorThousand=、 -FormatDateShort=%m/%d/%Y -FormatDateShortJava=MM/dd/yyyy -FormatDateShortJQuery=dd/mm/yy +FormatDateShort=%m/%d/%Y +FormatDateShortInput=%m/%d/%Y +FormatDateShortJava=MM/dd/yyyy +FormatDateShortJavaInput=MM/dd/yyyy +FormatDateShortJQuery=mm/dd/yy +FormatDateShortJQueryInput=mm/dd/yy FormatHourShort=%I:%M %p FormatHourShortDuration=%H:%M FormatDateTextShort=%b %d, %Y diff --git a/htdocs/langs/nb_NO/main.lang b/htdocs/langs/nb_NO/main.lang index 203896ba362..123ed5a86ed 100644 --- a/htdocs/langs/nb_NO/main.lang +++ b/htdocs/langs/nb_NO/main.lang @@ -3,7 +3,11 @@ CHARSET=UTF-8 SeparatorDecimal=, SeparatorThousand= FormatDateShort=%d.%m.%Y +FormatDateShortInput=%d.%m.%Y FormatDateShortJava=dd.MM.yyyy +FormatDateShortJavaInput=dd.MM.yyyy +FormatDateShortJQuery=dd.mm.yy +FormatDateShortJQueryInput=dd.mm.yy FormatHourShort=%H.%M FormatDateTextShort=%d. %b %Y FormatDateText=%d. %B %Y @@ -606,7 +610,6 @@ Day0=Søndag // START - Lines generated via autotranslator.php tool (2012-02-29 17:06:43). // Reference language: en_US -> nb_NO -FormatDateShortJQuery=dd/mm/yy AddLink=Legg til link Of=av SearchOf=Søk diff --git a/htdocs/langs/nl_BE/main.lang b/htdocs/langs/nl_BE/main.lang index 3d16e786aed..d4aff86e9c3 100644 --- a/htdocs/langs/nl_BE/main.lang +++ b/htdocs/langs/nl_BE/main.lang @@ -3,7 +3,11 @@ CHARSET=UTF-8 SeparatorDecimal=, SeparatorThousand= FormatDateShort=%d/%m/%Y +FormatDateShortInput=%d/%m/%Y FormatDateShortJava=dd/MM/yyyy +FormatDateShortJavaInput=dd/MM/yyyy +FormatDateShortJQuery=dd/mm/yy +FormatDateShortJQueryInput=dd/mm/yy FormatHourShort=%H:%M FormatDateTextShort=%d %b %Y FormatDateText=%d %B %Y diff --git a/htdocs/langs/nl_NL/main.lang b/htdocs/langs/nl_NL/main.lang index 40947ca565f..100bd776c3a 100644 --- a/htdocs/langs/nl_NL/main.lang +++ b/htdocs/langs/nl_NL/main.lang @@ -4,7 +4,11 @@ DIRECTION = ltr SeparatorDecimal = , SeparatorThousand = . FormatDateShort = %d-%m-%Y +FormatDateShortInput = %d-%m-%Y FormatDateShortJava = dd-MM-yyyy +FormatDateShortJavaInput = dd-MM-yyyy +FormatDateShortJQuery=dd-mm-yy +FormatDateShortJQueryInput=dd-mm-yy FormatHourShort = %H:%M FormatHourShortDuration = %H:%M FormatDateTextShort = %d %b %Y @@ -590,7 +594,6 @@ ShortSunday = Zo // START - Lines generated via autotranslator.php tool (2011-10-10 01:46:39). // Reference language: en_US -> nl_NL -FormatDateShortJQuery=dd/mm/yy JanuaryMin=Jan FebruaryMin=Februari MarchMin=Mar diff --git a/htdocs/langs/pl_PL/main.lang b/htdocs/langs/pl_PL/main.lang index 5f725587178..41236b3456a 100644 --- a/htdocs/langs/pl_PL/main.lang +++ b/htdocs/langs/pl_PL/main.lang @@ -15,7 +15,11 @@ FONTSIZEFORPDF=8 SeparatorDecimal=, SeparatorThousand= FormatDateShort=%d-%m-%Y +FormatDateShortInput=%d-%m-%Y FormatDateShortJava=dd-MM-yyyy +FormatDateShortJavaInput=dd-MM-yyyy +FormatDateShortJQuery=dd-mm-yy +FormatDateShortJQueryInput=dd-mm-yy FormatHourShort=%H:%M FormatDateTextShort=%d %b %Y FormatDateText=%d %B %Y @@ -620,7 +624,6 @@ Prefix=Przedrostek // START - Lines generated via autotranslator.php tool (2012-02-29 17:18:29). // Reference language: en_US -> pl_PL -FormatDateShortJQuery=dd/mm/yy AddLink=Dodaj link Of=z SearchOf=Szukaj diff --git a/htdocs/langs/pt_PT/main.lang b/htdocs/langs/pt_PT/main.lang index 86d60b9b037..4df4d1ea5ec 100644 --- a/htdocs/langs/pt_PT/main.lang +++ b/htdocs/langs/pt_PT/main.lang @@ -3,7 +3,11 @@ CHARSET=UTF-8 SeparatorDecimal=, SeparatorThousand= FormatDateShort=%d/%m/%Y +FormatDateShortInput=%d/%m/%Y FormatDateShortJava=dd/MM/yyyy +FormatDateShortJavaInput=dd/MM/yyyy +FormatDateShortJQuery=dd/mm/yy +FormatDateShortJQueryInput=dd/mm/yy FormatHourShort=%H:%M FormatDateTextShort=%d %b %Y FormatDateText=%d %B %Y @@ -601,7 +605,6 @@ Prefix=Prefixo // START - Lines generated via autotranslator.php tool (2012-02-29 15:45:52). // Reference language: en_US -> pt_PT -FormatDateShortJQuery=dd/mm/yy AddLink=Adicionar link Of=de SearchOf=Pesquisar diff --git a/htdocs/langs/ro_RO/main.lang b/htdocs/langs/ro_RO/main.lang index df4536746d8..8b7530a1702 100644 --- a/htdocs/langs/ro_RO/main.lang +++ b/htdocs/langs/ro_RO/main.lang @@ -13,7 +13,11 @@ FONTSIZEFORPDF=8 SeparatorDecimal=, SeparatorThousand= FormatDateShort=%d.%m.%Y +FormatDateShortInput=%d.%m.%Y FormatDateShortJava=dd.MM.yyyy +FormatDateShortJavaInput=dd.MM.yyyy +FormatDateShortJQuery=dd.mm.yy +FormatDateShortJQueryInput=dd.mm.yy FormatHourShort=%H:%M FormatDateTextShort=%d %b %Y FormatDateText=%d %B %Y @@ -618,7 +622,6 @@ Prefix=Prefix // START - Lines generated via autotranslator.php tool (2012-02-29 17:23:15). // Reference language: en_US -> ro_RO -FormatDateShortJQuery=dd/mm/yy AddLink=Adauga link-ul Of=de SearchOf=Căutare diff --git a/htdocs/langs/ru_RU/main.lang b/htdocs/langs/ru_RU/main.lang index 1d203fb98f0..30be774c29f 100644 --- a/htdocs/langs/ru_RU/main.lang +++ b/htdocs/langs/ru_RU/main.lang @@ -15,7 +15,11 @@ DIRECTION=ltr SeparatorDecimal=, SeparatorThousand= FormatDateShort=%d.%m.%Y +FormatDateShortInput=%d.%m.%Y FormatDateShortJava=dd.MM.yyyy +FormatDateShortJavaInput=dd.MM.yyyy +FormatDateShortJQuery=dd.mm.yy +FormatDateShortJQueryInput=dd.mm.yy FormatHourShort=%H:%M FormatDateTextShort=%d %b %Y FormatDateText=%d %B %Y @@ -628,7 +632,6 @@ Person=Персона // START - Lines generated via autotranslator.php tool (2011-08-18 23:26:41). // Reference language: en_US -> ru_RU -FormatDateShortJQuery=dd/mm/yy AddLink=Добавить ссылку Of=из AmountByMonth=Сумма за месяц diff --git a/htdocs/langs/ru_UA/main.lang b/htdocs/langs/ru_UA/main.lang index cef3a719ae0..cac36234fbf 100644 --- a/htdocs/langs/ru_UA/main.lang +++ b/htdocs/langs/ru_UA/main.lang @@ -10,7 +10,11 @@ DIRECTION=ltr SeparatorDecimal=, SeparatorThousand= FormatDateShort=%d.%m.%Y +FormatDateShortInput=%d.%m.%Y FormatDateShortJava=dd.MM.yyyy +FormatDateShortJavaInput=dd.MM.yyyy +FormatDateShortJQuery=dd.mm.yy +FormatDateShortJQueryInput=dd.mm.yy FormatHourShort=%H:%M FormatDateTextShort=%d %b %Y FormatDateText=%d %B %Y diff --git a/htdocs/langs/sl_SI/main.lang b/htdocs/langs/sl_SI/main.lang index 793d9498587..c79ca0d5dc5 100644 --- a/htdocs/langs/sl_SI/main.lang +++ b/htdocs/langs/sl_SI/main.lang @@ -6,8 +6,11 @@ FONTSIZEFORPDF=8 SeparatorDecimal = , SeparatorThousand = . FormatDateShort = %d/%m/%Y +FormatDateShortInput = %d/%m/%Y FormatDateShortJava = dd/MM/yyyy +FormatDateShortJavaInput = dd/MM/yyyy FormatDateShortJQuery = dd/mm/yy +FormatDateShortJQueryInput = dd/mm/yy FormatHourShort = %I:%M %p FormatHourShortDuration = %H:%M FormatDateTextShort = %d. %b, %Y diff --git a/htdocs/langs/sv_SE/main.lang b/htdocs/langs/sv_SE/main.lang index 55287b657a0..dde9641a208 100644 --- a/htdocs/langs/sv_SE/main.lang +++ b/htdocs/langs/sv_SE/main.lang @@ -12,7 +12,11 @@ DIRECTION=ltr SeparatorDecimal=, SeparatorThousand= FormatDateShort=%Y-%m-%d +FormatDateShortInput=%Y-%m-%d FormatDateShortJava=yyyy-MM-dd +FormatDateShortJavaInput=yyyy-MM-dd +FormatDateShortJQuery=yy-mm-dd +FormatDateShortJQueryInput=yy-mm-dd FormatHourShort=%H:%M FormatHourShortDuration=%H:%M FormatDateTextShort=%b %d %Y @@ -594,7 +598,6 @@ ShortSunday=S // START - Lines generated via autotranslator.php tool (2012-02-29 17:32:03). // Reference language: en_US -> sv_SE -FormatDateShortJQuery=dd/mm/yy AddLink=Tillsätt länk Of=av SearchOf=Sök diff --git a/htdocs/langs/tr_TR/main.lang b/htdocs/langs/tr_TR/main.lang index 7f372bf7dd5..8862e8b7635 100644 --- a/htdocs/langs/tr_TR/main.lang +++ b/htdocs/langs/tr_TR/main.lang @@ -14,8 +14,11 @@ FONTSIZEFORPDF=8 SeparatorDecimal=. SeparatorThousand=, FormatDateShort=%d/%m/%Y +FormatDateShortInput=%d/%m/%Y FormatDateShortJava=dd/MM/yyyy +FormatDateShortJavaInput=dd/MM/yyyy FormatDateShortJQuery=dd/mm/yy +FormatDateShortJQueryInput=dd/mm/yy FormatHourShort=%H:%M FormatHourShortDuration=%H:%M FormatDateTextShort=%d %b %Y diff --git a/htdocs/langs/zh_CN/main.lang b/htdocs/langs/zh_CN/main.lang index 04235a1bd69..04c6ee545bd 100644 --- a/htdocs/langs/zh_CN/main.lang +++ b/htdocs/langs/zh_CN/main.lang @@ -17,7 +17,11 @@ FONTSIZEFORPDF=9 SeparatorDecimal=. SeparatorThousand=None FormatDateShort=%d/%m/%Y +FormatDateShortInput=%d/%m/%Y FormatDateShortJava=dd/MM/yyyy +FormatDateShortJavaInput=dd/MM/yyyy +FormatDateShortJQuery=dd/mm/yy +FormatDateShortJQueryInput=dd/mm/yy FormatHourShort=%I:%M %p FormatDateTextShort=%b %d, %Y FormatDateText=%B %d, %Y @@ -604,7 +608,6 @@ Prefix=字首 // START - Lines generated via autotranslator.php tool (2012-02-29 17:37:09). // Reference language: en_US -> zh_CN -FormatDateShortJQuery=dd/mm/yy AddLink=添加链接 Of=的 SearchOf=搜索 diff --git a/htdocs/langs/zh_TW/main.lang b/htdocs/langs/zh_TW/main.lang index b853fbb6073..aff84edf1ef 100644 --- a/htdocs/langs/zh_TW/main.lang +++ b/htdocs/langs/zh_TW/main.lang @@ -13,7 +13,11 @@ FONTFORPDF=msungstdlight SeparatorDecimal=. SeparatorThousand=None FormatDateShort=%Y/%m/%d +FormatDateShortInput=%Y/%m/%d FormatDateShortJava=yyyy/MM/dd +FormatDateShortJavaInput=yyyy/MM/dd +FormatDateShortJQuery=yy/mm/dd +FormatDateShortJQueryInput=yy/mm/dd FormatHourShort=%I:%M %p FormatDateTextShort=%Y %b %d FormatDateText=%Y %B %d @@ -600,7 +604,6 @@ Prefix=字首 // START - Lines generated via autotranslator.php tool (2012-02-29 17:37:09). // Reference language: en_US -> zh_CN -FormatDateShortJQuery=dd/mm/yy AddLink=添加鏈接 Of=的 SearchOf=搜尋 diff --git a/htdocs/opensurvey/class/opensurveysondage.class.php b/htdocs/opensurvey/class/opensurveysondage.class.php index 0a3f2c571df..188e830be63 100644 --- a/htdocs/opensurvey/class/opensurveysondage.class.php +++ b/htdocs/opensurvey/class/opensurveysondage.class.php @@ -337,7 +337,7 @@ class Opensurveysondage extends CommonObject * * @param User $user User that deletes * @param int $notrigger 0=launch triggers after, 1=disable triggers - * @param string $numsondageadmin Num sondage to delete + * @param string $numsondageadmin Num sondage admin to delete * @return int <0 if KO, >0 if OK */ function delete($user, $notrigger, $numsondageadmin) @@ -345,6 +345,8 @@ class Opensurveysondage extends CommonObject global $conf, $langs; $error=0; + $numsondage=substr($numsondageadmin, 0, 16); + $this->db->begin(); if (! $error) @@ -366,10 +368,10 @@ class Opensurveysondage extends CommonObject if (! $error) { - $sql='DELETE FROM '.MAIN_DB_PREFIX."opensurvey_comments WHERE id_sondage_admin = '".$numsondageadmin."'"; + $sql='DELETE FROM '.MAIN_DB_PREFIX."opensurvey_comments WHERE id_sondage = '".$numsondage."'"; dol_syslog(get_class($this)."::delete sql=".$sql, LOG_DEBUG); $resql=$this->db->query($sql); - $sql='DELETE FROM '.MAIN_DB_PREFIX."opensurvey_user_studs WHERE id_sondage_admin = '".$numsondageadmin."'"; + $sql='DELETE FROM '.MAIN_DB_PREFIX."opensurvey_user_studs WHERE id_sondage = '".$numsondage."'"; dol_syslog(get_class($this)."::delete sql=".$sql, LOG_DEBUG); $resql=$this->db->query($sql); diff --git a/htdocs/opensurvey/list.php b/htdocs/opensurvey/list.php index 506ffecc99e..c87526ce5ca 100755 --- a/htdocs/opensurvey/list.php +++ b/htdocs/opensurvey/list.php @@ -27,6 +27,7 @@ require_once(DOL_DOCUMENT_ROOT."/core/lib/files.lib.php"); $action=GETPOST('action'); $id=GETPOST('id'); +$numsondage=substr($id, 0, 16); if (! $sortorder) $sortorder="ASC"; if (! $sortfield) $sortfield="p.titre"; @@ -45,16 +46,10 @@ if ($action == 'delete_confirm') { $db->begin(); - $sql='DELETE FROM '.MAIN_DB_PREFIX."opensurvey_comments WHERE id_sondage_admin = '".$id."'"; - dol_syslog("Delete poll sql=".$sql, LOG_DEBUG); - $resql=$db->query($sql); - $sql='DELETE FROM '.MAIN_DB_PREFIX."opensurvey_user_studs WHERE id_sondage_admin = '".$id."'"; - dol_syslog("Delete poll sql=".$sql, LOG_DEBUG); - $resql=$db->query($sql); - $sql='DELETE FROM '.MAIN_DB_PREFIX."opensurvey_sondage WHERE id_sondage_admin = '".$id."'"; - dol_syslog("Delete poll sql=".$sql, LOG_DEBUG); - $resql=$db->query($sql); - + $object=new Opensurveysondage($db); + + $result=$object->delete($user,'',$numsondageadmin); + $db->commit(); } diff --git a/htdocs/product/class/html.formproduct.class.php b/htdocs/product/class/html.formproduct.class.php index 422f93eff16..45b0a129808 100644 --- a/htdocs/product/class/html.formproduct.class.php +++ b/htdocs/product/class/html.formproduct.class.php @@ -109,9 +109,10 @@ class FormProduct * @param int $empty 1=Can be empty, 0 if not * @param int $disabled 1=Select is disabled * @param int $fk_product Add quantity of stock in label for product with id fk_product. Nothing if 0. + * @param string $empty_label Empty label if needed (only if $empty=1) * @return string HTML select */ - function selectWarehouses($selected='',$htmlname='idwarehouse',$filtertype='',$empty=0,$disabled=0,$fk_product=0) + function selectWarehouses($selected='',$htmlname='idwarehouse',$filtertype='',$empty=0,$disabled=0,$fk_product=0,$empty_label='') { global $langs,$user; @@ -120,7 +121,7 @@ class FormProduct $this->loadWarehouses($fk_product); $out='
      -> - ".$compl_path.stripslashes($nom_pere)." - (".$desc_pere[1].") ".($desc_pere[1]*$multiply)."  ".$this->stock_entrepot[1]." ".$img."
'.$langs->trans("AssociatedProductsNumber").''.count($product->get_arbo_each_prod()).'
'.$langs->trans("AssociatedProductsNumber").''; + print $form->textwithpicto($nbofsubproducts, $langs->trans('IfZeroItIsNotAVirtualProduct')); + print '
'; @@ -223,6 +226,7 @@ if ($id || $ref) //print $productstatic->getNomUrl(1).'
'; //print $value[0]; // This contains a tr line. print '
'.$productstatic->getNomUrl(1,'composition').' ('.$value['nb'].($value['nb_total'] > $value['nb']?'->'.$value['nb_total']:'').')    '.$productstatic->getNomUrl(1,'composition').' ('.$value['nb'].')    '.$langs->trans("Stock").' : '.$productstatic->stock_reel.'
'.$langs->trans("ParentProductsNumber").''.count($prodsfather).'
'.$langs->trans("ParentProductsNumber").''; + print $form->textwithpicto(count($prodsfather), $langs->trans('IfZeroItIsNotUsedByVirtualProduct')); + print '
'.$langs->trans("AssociatedProductsNumber").''.count($product->get_arbo_each_prod()).'
'.$langs->trans("AssociatedProductsNumber").''; + print $form->textwithpicto($nbofsubproducts, $langs->trans('IfZeroItIsNotAVirtualProduct')); + print '
'; @@ -316,8 +324,10 @@ if ($id || $ref) print '
'.$langs->trans("ParentProductsNumber").''.count($prodsfather).'
'.$langs->trans("ParentProductsNumber").''; + print $form->textwithpicto(count($prodsfather), $langs->trans('IfZeroItIsNotUsedByVirtualProduct')); + print '
'.$langs->trans("Label").'
'.$langs->trans("Label").'
'.$langs->trans("Status").' ('.$langs->trans("Sell").')'; @@ -866,7 +866,7 @@ else print '
'.$langs->trans("Ref").'
'.$langs->trans("Label").'
'.$langs->trans("Label").'
'.$langs->trans("Status").' ('.$langs->trans("Sell").')'; diff --git a/htdocs/projet/class/project.class.php b/htdocs/projet/class/project.class.php index f5af9518de1..321936ad6a9 100644 --- a/htdocs/projet/class/project.class.php +++ b/htdocs/projet/class/project.class.php @@ -1048,7 +1048,7 @@ class Project extends CommonObject } $this->db->begin(); - $res=$clone_project->update_note(dol_html_entity_decode($clone_project->note_private, ENT_QUOTES)); + $res=$clone_project->update_note(dol_html_entity_decode($clone_project->note_private, ENT_QUOTES), '_private'); if ($res < 0) { $this->error.=$clone_project->error; diff --git a/htdocs/projet/class/task.class.php b/htdocs/projet/class/task.class.php index 0adc21eb6cc..ac29870106b 100644 --- a/htdocs/projet/class/task.class.php +++ b/htdocs/projet/class/task.class.php @@ -1064,7 +1064,7 @@ class Task extends CommonObject } $this->db->begin(); - $res=$clone_task->update_note(dol_html_entity_decode($clone_task->note_private, ENT_QUOTES)); + $res=$clone_task->update_note(dol_html_entity_decode($clone_task->note_private, ENT_QUOTES), '_private'); if ($res < 0) { $this->error.=$clone_task->error; diff --git a/htdocs/projet/ganttview.php b/htdocs/projet/ganttview.php index 3a36fd1f591..e19571f9518 100644 --- a/htdocs/projet/ganttview.php +++ b/htdocs/projet/ganttview.php @@ -184,8 +184,8 @@ if (count($tasksarray)>0) // Show Gant diagram from $taskarray using JSGantt - $dateformat=$langs->trans("FormatDateShort"); - $dateformat=strtolower($langs->trans("FormatDateShortJava")); + $dateformat=$langs->trans("FormatDateShort"); // Used by include ganttchart.php later + $dateformat=$langs->trans("FormatDateShortJQuery"); // Used by include ganttchart.php later $array_contacts=array(); $tasks=array(); $project_dependencies=array(); diff --git a/htdocs/projet/note.php b/htdocs/projet/note.php index 26eafbc16d2..dddab2a5e79 100644 --- a/htdocs/projet/note.php +++ b/htdocs/projet/note.php @@ -63,7 +63,7 @@ if ($action == 'setnote_public' && $user->rights->projet->creer) if ($action == 'setnote_private' && $user->rights->projet->creer) { $object->fetch($id); - $result=$object->update_note(dol_html_entity_decode(GETPOST('note_private'), ENT_QUOTES)); + $result=$object->update_note(dol_html_entity_decode(GETPOST('note_private'), ENT_QUOTES), '_private'); if ($result < 0) dol_print_error($db,$object->error); } diff --git a/htdocs/projet/tasks/note.php b/htdocs/projet/tasks/note.php index 9931bde0510..1b6bebeb9d5 100644 --- a/htdocs/projet/tasks/note.php +++ b/htdocs/projet/tasks/note.php @@ -93,7 +93,7 @@ if ($action == 'setnote_public' && ! empty($permission)) else if ($action == 'setnote_private' && ! empty($permission)) { - $result=$object->update_note(dol_html_entity_decode(GETPOST('note_private'), ENT_QUOTES)); + $result=$object->update_note(dol_html_entity_decode(GETPOST('note_private'), ENT_QUOTES), '_private'); if ($result < 0) dol_print_error($db,$object->error); } diff --git a/htdocs/public/demo/index.php b/htdocs/public/demo/index.php index c0e47ea955d..1c03c17c5b5 100644 --- a/htdocs/public/demo/index.php +++ b/htdocs/public/demo/index.php @@ -1,6 +1,6 @@ - * Copyright (C) 2006-2012 Laurent Destailleur + * Copyright (C) 2006-2013 Laurent Destailleur * Copyright (C) 2010 Regis Houssin * * This program is free software; you can redistribute it and/or modify @@ -42,7 +42,7 @@ $hookmanager->initHooks(array('demo')); $demoprofiles=array( array('default'=>'1', 'key'=>'profdemoservonly','label'=>'DemoCompanyServiceOnly', - 'disablemodules'=>'adherent,barcode,boutique,cashdesk,categorie,don,expedition,externalsite,mailmanspip,prelevement,product,stock', + 'disablemodules'=>'adherent,barcode,boutique,cashdesk,categorie,don,expedition,externalsite,mailmanspip,margin,prelevement,product,stock', 'icon'=>DOL_URL_ROOT.'/public/demo/dolibarr_screenshot8.png'), array('default'=>'-1','key'=>'profdemoshopwithdesk','label'=>'DemoCompanyShopWithCashDesk', 'disablemodules'=>'adherent,boutique,categorie,don,externalsite,ficheinter,mailmanspip,prelevement,product,stock', @@ -54,10 +54,10 @@ $demoprofiles=array( 'disablemodules'=>'adherent,boutique,don,externalsite,mailmanspip', 'icon'=>DOL_URL_ROOT.'/public/demo/dolibarr_screenshot9.png'), array('default'=>'-1', 'key'=>'profdemofun','label'=>'DemoFundation', - 'disablemodules'=>'banque,barcode,boutique,cashdesk,commande,commercial,compta,comptabilite,contrat,expedition,externalsite,facture,ficheinter,fournisseur,mailmanspip,prelevement,product,projet,propal,propale,service,societe,stock,tax', + 'disablemodules'=>'banque,barcode,boutique,cashdesk,commande,commercial,compta,comptabilite,contrat,expedition,externalsite,facture,ficheinter,fournisseur,mailmanspip,margin,prelevement,product,projet,propal,propale,service,societe,stock,tax', 'icon'=>DOL_URL_ROOT.'/public/demo/dolibarr_screenshot6.png'), array('default'=>'0', 'key'=>'profdemofun2','label'=>'DemoFundation2', - 'disablemodules'=>'barcode,boutique,cashdesk,commande,commercial,compta,comptabilite,contrat,expedition,externalsite,facture,ficheinter,fournisseur,mailmanspip,prelevement,product,projet,propal,propale,service,societe,stock,tax', + 'disablemodules'=>'barcode,boutique,cashdesk,commande,commercial,compta,comptabilite,contrat,expedition,externalsite,facture,ficheinter,fournisseur,mailmanspip,margin,prelevement,product,projet,propal,propale,service,societe,stock,tax', 'icon'=>DOL_URL_ROOT.'/public/demo/dolibarr_screenshot6.png') ); diff --git a/htdocs/societe/class/societe.class.php b/htdocs/societe/class/societe.class.php index d6666495a14..0c1b8016938 100644 --- a/htdocs/societe/class/societe.class.php +++ b/htdocs/societe/class/societe.class.php @@ -1455,6 +1455,15 @@ class Societe extends CommonObject { $lien = 'canvas)?'&canvas='.$this->canvas:'').'">'; + $lien.=(!empty($this->canvas)?'&canvas='.$this->canvas:'').'">'; $lienfin=''; if ($withpicto) $result.=($lien.img_object($langs->trans("ShowCompany").': '.$name,'company').$lienfin); diff --git a/htdocs/societe/consumption.php b/htdocs/societe/consumption.php index 7c0a4c0332f..aff1fded6d3 100644 --- a/htdocs/societe/consumption.php +++ b/htdocs/societe/consumption.php @@ -295,14 +295,13 @@ if ($sql_select) // Define output language if (! empty($conf->global->MAIN_MULTILANGS) && ! empty($conf->global->PRODUIT_TEXTS_IN_THIRDPARTY_LANGUAGE)) { - $this->fetch_thirdparty(); $prod = new Product($db); $prod->fetch($objp->fk_product); $outputlangs = $langs; $newlang=''; if (empty($newlang) && GETPOST('lang_id')) $newlang=GETPOST('lang_id'); - if (empty($newlang)) $newlang=$this->client->default_lang; + if (empty($newlang)) $newlang=$object->default_lang; if (! empty($newlang)) { $outputlangs = new Translate("",$conf); diff --git a/htdocs/societe/societe.php b/htdocs/societe/societe.php index 26583442b2c..93401eaebf0 100644 --- a/htdocs/societe/societe.php +++ b/htdocs/societe/societe.php @@ -122,7 +122,7 @@ if ($mode == 'search') if ($search_type > 0 && in_array($search_type,array('1,3','2,3'))) $sql .= " AND s.client IN (".$db->escape($search_type).")"; if ($search_type > 0 && in_array($search_type,array('4'))) $sql .= " AND s.fournisseur = 1"; if ($search_type == '0') $sql .= " AND s.client = 0 AND s.fournisseur = 0"; - + $result=$db->query($sql); if ($result) { @@ -365,13 +365,13 @@ if ($resql) print ''; print ''; print ''; print '  '; diff --git a/htdocs/theme/amarok/graph-color.php b/htdocs/theme/amarok/graph-color.php index 96e9894c7fa..1a0d2253a2a 100755 --- a/htdocs/theme/amarok/graph-color.php +++ b/htdocs/theme/amarok/graph-color.php @@ -22,10 +22,10 @@ * \ingroup core */ -global $theme_bordercolor, $theme_datacolor, $theme_bgcolor, $theme_bgcoloronglet; -$theme_bordercolor = array(235,235,224); -$theme_datacolor = array(array(125,135,150), array(200,160,180), array(190,190,220), array(170,140,190), array(190,190,170)); -$theme_bgcolor = array(hexdec('F4'),hexdec('F4'),hexdec('F4')); -$theme_bgcoloronglet = array(hexdec('DE'),hexdec('E7'),hexdec('EC')); +global $theme_bordercolor, $theme_datacolor, $theme_bgcolor, $theme_bgcoloronglet; +$theme_bordercolor = array(235,235,224); +$theme_datacolor = array(array(190,190,220), array(200,160,180), array(125,135,150), array(170,140,190), array(190,190,170)); +$theme_bgcolor = array(hexdec('F4'),hexdec('F4'),hexdec('F4')); +$theme_bgcoloronglet = array(hexdec('DE'),hexdec('E7'),hexdec('EC')); ?> diff --git a/htdocs/theme/amarok/style.css.php b/htdocs/theme/amarok/style.css.php index 6bf44532621..c5e92cdcb1b 100755 --- a/htdocs/theme/amarok/style.css.php +++ b/htdocs/theme/amarok/style.css.php @@ -21,25 +21,28 @@ /** * \file htdocs/theme/amarok/style.css.php - * \brief Fichier de style CSS du theme amarok + * \brief File for CSS style sheet Amarok */ -//if (! defined('NOREQUIREUSER')) define('NOREQUIREUSER','1'); // Not disabled cause need to load personalized language +//if (! defined('NOREQUIREUSER')) define('NOREQUIREUSER','1'); // Not disabled because need to load personalized language //if (! defined('NOREQUIREDB')) define('NOREQUIREDB','1'); // Not disabled to increase speed. Language code is found on url. if (! defined('NOREQUIRESOC')) define('NOREQUIRESOC','1'); -//if (! defined('NOREQUIRETRAN')) define('NOREQUIRETRAN','1'); // Not disabled cause need to do translations +//if (! defined('NOREQUIRETRAN')) define('NOREQUIRETRAN','1'); // Not disabled because need to do translations if (! defined('NOCSRFCHECK')) define('NOCSRFCHECK',1); if (! defined('NOTOKENRENEWAL')) define('NOTOKENRENEWAL',1); -if (! defined('NOLOGIN')) define('NOLOGIN',1); +if (! defined('NOLOGIN')) define('NOLOGIN',1); // File must be accessed by logon page so without login if (! defined('NOREQUIREMENU')) define('NOREQUIREMENU',1); if (! defined('NOREQUIREHTML')) define('NOREQUIREHTML',1); if (! defined('NOREQUIREAJAX')) define('NOREQUIREAJAX','1'); session_cache_limiter(FALSE); -require_once("../../main.inc.php"); +require_once '../../main.inc.php'; + +// Load user to have $user->conf loaded (not done into main because of NOLOGIN constant defined) +if (empty($user->id) && ! empty($_SESSION['dol_login'])) $user->fetch('',$_SESSION['dol_login']); // Define css type header('Content-type: text/css'); @@ -69,12 +72,55 @@ $fontlist='helvetica,arial,tahoma,verdana'; //$fontlist='Verdana,Helvetica,Ar $img_liste_titre=dol_buildpath($path.'/theme/'.$theme.'/img/menus/trtitle.png',1); $img_head=dol_buildpath($path.'/theme/'.$theme.'/img/headbg2.jpg',1); $img_button=dol_buildpath($path.'/theme/'.$theme.'/img/button_bg.png',1); +$dol_hide_topmenu=$conf->dol_hide_topmenu; +$dol_hide_leftmenu=$conf->dol_hide_leftmenu; +$dol_optimize_smallscreen=$conf->dol_optimize_smallscreen; +$dol_no_mouse_hover=$conf->dol_no_mouse_hover; +$dol_use_jmobile=$conf->dol_use_jmobile; + + +// Define reference colors +// Example: Light grey: $colred=235;$colgreen=235;$colblue=235; +// Example: Pink: $colred=230;$colgreen=210;$colblue=230; +// Example: Green: $colred=210;$colgreen=230;$colblue=210; +// Example: Ocean: $colred=220;$colgreen=220;$colblue=240; +//$conf->global->THEME_ELDY_ENABLE_PERSONALIZED=0; +//$user->conf->THEME_ELDY_ENABLE_PERSONALIZED=0; +//var_dump($user->conf->THEME_ELDY_RGB); +$colred =empty($user->conf->THEME_ELDY_ENABLE_PERSONALIZED)?(empty($conf->global->THEME_ELDY_RGB)?235:hexdec(substr($conf->global->THEME_ELDY_RGB,0,2))):(empty($user->conf->THEME_ELDY_RGB)?235:hexdec(substr($user->conf->THEME_ELDY_RGB,0,2))); +$colgreen=empty($user->conf->THEME_ELDY_ENABLE_PERSONALIZED)?(empty($conf->global->THEME_ELDY_RGB)?235:hexdec(substr($conf->global->THEME_ELDY_RGB,2,2))):(empty($user->conf->THEME_ELDY_RGB)?235:hexdec(substr($user->conf->THEME_ELDY_RGB,2,2))); +$colblue =empty($user->conf->THEME_ELDY_ENABLE_PERSONALIZED)?(empty($conf->global->THEME_ELDY_RGB)?235:hexdec(substr($conf->global->THEME_ELDY_RGB,4,2))):(empty($user->conf->THEME_ELDY_RGB)?235:hexdec(substr($user->conf->THEME_ELDY_RGB,4,2))); + +// Colors +$isred=max(0,(2*$colred-$colgreen-$colblue)/2); // 0 - 255 +$isgreen=max(0,(2*$colgreen-$colred-$colblue)/2); // 0 - 255 +$isblue=max(0,(2*$colblue-$colred-$colgreen)/2); // 0 - 255 +$colorback1=($colred-3).','.($colgreen-3).','.($colblue-3); // topmenu +$colorback2=($colred+5).','.($colgreen+5).','.($colblue+5); +$colorbacktab1=($colred+15).','.($colgreen+16).','.($colblue+17); // vmenu +$colorbacktab1b=($colred+5).','.($colgreen+6).','.($colblue+7); // vmenu (not menu) +$colorbacktab2=($colred-15).','.($colgreen-15).','.($colblue-15); +$colorbacktitle1=($colred-5).','.($colgreen-5).','.($colblue-5); // title of array +$colorbacktitle2=($colred-15).','.($colgreen-15).','.($colblue-15); +$colorbacktabcard1=($colred+15).','.($colgreen+16).','.($colblue+17); // card +$colorbacktabcard2=($colred-15).','.($colgreen-15).','.($colblue-15); +$colorbacktabactive=($colred-15).','.($colgreen-15).','.($colblue-15); +$colorbacklineimpair1=(244+round($isred/3)).','.(244+round($isgreen/3)).','.(244+round($isblue/3)); // line impair +$colorbacklineimpair2=(250+round($isred/3)).','.(250+round($isgreen/3)).','.(250+round($isblue/3)); // line impair +$colorbacklineimpairhover=(230+round(($isred+$isgreen+$isblue)/9)).','.(230+round(($isred+$isgreen+$isblue)/9)).','.(230+round(($isred+$isgreen+$isblue)/9)); // line impair +$colorbacklinepair1='255,255,255'; // line pair +$colorbacklinepair2='255,255,255'; // line pair +$colorbacklinepairhover=(230+round(($isred+$isgreen+$isblue)/9)).','.(230+round(($isred+$isgreen+$isblue)/9)).','.(230+round(($isred+$isgreen+$isblue)/9)); +$colorbackbody='#f5f5f5'; +$colortext='40,40,40'; +$fontsize=empty($conf->dol_optimize_smallscreen)?'12':'14'; +$fontsizesmaller=empty($conf->dol_optimize_smallscreen)?'11':'14'; ?> /* ============================================================================== */ -/* Styles par défaut */ +/* Default styles */ /* ============================================================================== */ *, html { @@ -84,31 +130,17 @@ font-size:100%; } body { - background-color:#f5f5f5; - - - background-image:url(); - background-repeat:repeat-y; - margin:0px; - - - background-image:url(); - margin:100px; - +dol_optimize_smallscreen)) { ?> + background-color: #FFFFFF; + + background-color: ; + color:#232323; font-size:px; font-family:; - trans("DIRECTION").";\n"; ?> } -.checkVatPopup { - background-color:#f5f5f5; - background-image:none; - margin:10px; - line-height:16px; -} - a { font-family:; font-weight:bold; @@ -194,6 +226,15 @@ div.inline-block display:inline-block; } +th .button { + -moz-box-shadow: none !important; + -webkit-box-shadow: none !important; + box-shadow: none !important; + -moz-border-radius:0px !important; + -webkit-border-radius:0px !important; + border-radius:0px !important; +} + .valignmiddle { vertical-align: middle; } @@ -211,11 +252,102 @@ div.inline-block } +.blockvmenubookmarks .menu_contenu { + background-color: transparent; +} + +/* ! Message d'erreur lors du login : */ +center .error { padding:8px !important; padding-left:26px !important; padding-right:20px; width:inherit; max-width:450px;color:#552323 !important; font-size:14px; border-radius:8px; text-align: left;} + + + /* ============================================================================== */ -/* Login */ +/* Styles to hide objects */ /* ============================================================================== */ -body.body center{color:white;} +.hideobject { display:none; } + +.hideonsmartphone { display: none; } +.noenlargeonsmartphone { width : 50px !important; display: inline !important; } + +.linkobject { cursor:pointer; } + + +/* ============================================================================== */ +/* Styles for dragging lines */ +/* ============================================================================== */ + +.dragClass { + color: #333333; +} +td.showDragHandle { + cursor: move; +} +.tdlineupdown { + white-space: nowrap; +} + +/* ============================================================================== */ +/* Menu top et 1ere ligne tableau */ +/* ============================================================================== */ + +div.tmenu { + + display:none; + + position:relative; + display:block; + margin:0; + padding:0; + padding-left:1em; + top:0; + left:0; + right:0; + white-space:nowrap; + height:36px; + browser->name != 'ie') echo "line-height:36px; /* disabled for ie9 */ \n"; ?> + background:#333333; + background-image:linear-gradient(top, rgba(255,255,255,.3) 0%, rgba(0,0,0,.3) 100%); + background-image:-o-linear-gradient(top, rgba(255,255,255,.3) 0%, rgba(0,0,0,.3) 100%); + background-image:-moz-linear-gradient(top, rgba(255,255,255,.3) 0%, rgba(0,0,0,.3) 100%); + background-image:-webkit-linear-gradient(top, rgba(255,255,255,.3) 0%, rgba(0,0,0,.3) 100%); + background-image:-ms-linear-gradient(top, rgba(255,255,255,.3) 0%, rgba(0,0,0,.3) 100%); + background-image:-webkit-gradient( + linear, + left top, + left bottom, + color-stop(0, rgba(255,255,255,.3)), + color-stop(1, rgba(0,0,0,.3)) + ); + border-bottom:solid 1px rgba(0,0,0,.8); + box-shadow:0 0 6px rgba(0,0,0,.4) !important; + z-index:100; + +} + +div.tmenu a { + font-weight:normal; +} + +div.tmenu li { + display:inline-table; + margin-right:1em; + text-transform:uppercase; +} + +div.tmenu li a {color:#cccccc;} +div.tmenu li a:hover { color:rgba(255,255,255,1);} + +div.tmenu ul li a.tmenusel {/* texte du menu principal sélectionné */ + color:#ffffff; + font-weight:bold; +} + +.tmenudisabled { color:#808080 !important; cursor: not-allowed; } + + + +/* Login */ form#login { display:block; @@ -329,96 +461,6 @@ table.login_table .vmenu { font-size:120%; } -.blockvmenubookmarks .menu_contenu { - background-color: transparent; -} - -/* ! Message d'erreur lors du login : */ -center .error { padding:8px !important; padding-left:26px !important; padding-right:20px; width:inherit; max-width:450px;color:#552323 !important; font-size:14px; border-radius:8px; text-align: left;} - - - -/* ============================================================================== */ -/* Styles to hide objects */ -/* ============================================================================== */ - -.hideobject { display:none; } - -.hideonsmartphone { display: none; } -.noenlargeonsmartphone { width : 50px !important; display: inline !important; } - -.linkobject { cursor:pointer; } - - -/* For dragging lines */ - -.dragClass {color:#333333;} -td.showDragHandle {cursor:move;} -.tdlineupdown {white-space:nowrap;} - - -/* ============================================================================== */ -/* Menu top et 1ère ligne tableau */ -/* ============================================================================== */ - -div.tmenu { - - display:none; - - position:relative; - display:block; - margin:0; - padding:0; - padding-left:1em; - top:0; - left:0; - right:0; - white-space:nowrap; - height:36px; - browser->name != 'ie') echo "line-height:36px; /* disabled for ie9 */ \n"; ?> - background:#333333; - background-image:linear-gradient(top, rgba(255,255,255,.3) 0%, rgba(0,0,0,.3) 100%); - background-image:-o-linear-gradient(top, rgba(255,255,255,.3) 0%, rgba(0,0,0,.3) 100%); - background-image:-moz-linear-gradient(top, rgba(255,255,255,.3) 0%, rgba(0,0,0,.3) 100%); - background-image:-webkit-linear-gradient(top, rgba(255,255,255,.3) 0%, rgba(0,0,0,.3) 100%); - background-image:-ms-linear-gradient(top, rgba(255,255,255,.3) 0%, rgba(0,0,0,.3) 100%); - background-image:-webkit-gradient( - linear, - left top, - left bottom, - color-stop(0, rgba(255,255,255,.3)), - color-stop(1, rgba(0,0,0,.3)) - ); - border-bottom:solid 1px rgba(0,0,0,.8); - box-shadow:0 0 6px rgba(0,0,0,.4) !important; - z-index:100; - -} - -div.tmenu a { - font-weight:normal; -} - -div.tmenu li { - display:inline-table; - margin-right:1em; - text-transform:uppercase; -} - -div.tmenu li a {color:#cccccc;} -div.tmenu li a:hover {color:rgba(255,255,255,.2);} - -div.tmenu ul li a.tmenusel {/* texte du menu principal sélectionné */ - color:#ffffff; - font-weight:bold; -} - -.tmenudisabled { color:#808080 !important; cursor: not-allowed; } - -/* --- end nav --- */ - -/* Login */ - div.login_block { position:absolute; top:5px; @@ -438,16 +480,16 @@ div.login_block table { div.login { white-space:nowrap; - padding:8px 0px 0px 0px; + padding: dol_optimize_smallscreen?'0':'8')?>px 0px 0px 0px; margin:0px 0px 0px 8px; font-weight:bold; } img.login, img.printer, img.entity { - padding:8px 0px 0px 0px; + padding: dol_optimize_smallscreen?'0':'8')?>px 0px 0px 0px; margin:0px 0px 0px 8px; text-decoration:none; - color:#ffffff; + color: white; font-weight:bold; } @@ -461,6 +503,9 @@ div.vmenu { display:none; width:170px; + -moz-box-shadow: 4px 4px 4px #CCC; + -webkit-box-shadow: 4px 4px 4px #CCC; + box-shadow: 4px 4px 4px #CCC; } @@ -773,8 +818,11 @@ div.tabs { div.tabBar { background-color:#ffffff; padding:6px; - margin:3px 0px 5px; + margin:3px 0px 14px 0px; border:1px solid #bbbbbb; + -moz-box-shadow: 4px 4px 4px #DDD; + -webkit-box-shadow: 4px 4px 4px #DDD; + box-shadow: 4px 4px 4px #DDD; } div.tabBar table.notopnoleftnoright { @@ -1066,7 +1114,7 @@ table.liste { table.liste td {padding:1px 2px 1px 0px;} -tr.liste_titre, tr.box_titre { +div.liste_titre, tr.liste_titre, tr.box_titre { padding:4px; background-color:rgba(0,0,0,.2); background-image:linear-gradient(top, rgba(255,255,255,.3) 0%, rgba(0,0,0,.3) 100%); @@ -1116,13 +1164,13 @@ tr.impair td, tr.pair td {padding:1px 1px 1px 2px;} tr.impair table.nobordernopadding td, tr.pair table.nobordernopadding td {padding:1px 0px;} .impair { - background:#f4f4f4; + background:#fdfdfd; font-family:; border:0px; } .pair { - background:#eaeaea; + background:#f4f4f4; font-family:; border:0px; } @@ -1147,12 +1195,12 @@ tr.impair table.nobordernopadding td, tr.pair table.nobordernopadding td {paddin } tr.box_impair { - background:#f4f4f4; + background:#fdfdfd; font-family:; } tr.box_pair { - background:#eaeaea; + background:#f4f4f4; font-family:; } @@ -1423,7 +1471,7 @@ td.dpHead { /* Jour courant */ .dpSelected { - background-color:#a61111; + background-color:#0B63A2; color:#ffffff; font-weight:bold; } @@ -1468,7 +1516,7 @@ td.dpHead { padding:0px 2px; font-size:9px; border-width:0px; - color:#a61111; + color:#0B63A2; vertical-align:middle; cursor:pointer; } @@ -1499,17 +1547,9 @@ table.cal_month { border-spacing: 0px; } .cal_current_month_right { border-right: solid 1px #E0E0E0; } .cal_other_month_right { border-right: solid 1px #C0C0C0; } -.cal_other_month { - background:#dddddd; -} - -.cal_past_month { - background:#eeeeee; -} - -.cal_current_month { - background:#ffffff; -} +.cal_other_month { opacity: 0.6; background: #EAEAEA; padding-: 2px; padding-: 1px; padding-top: 0px; padding-bottom: 0px; } +.cal_past_month { opacity: 0.6; background: #EEEEEE; padding-: 2px; padding-: 1px; padding-top: 0px; padding-bottom: 0px; } +.cal_current_month { background: #FFFFFF; border-left: solid 1px #E0E0E0; padding-: 2px; padding-: 1px; padding-top: 0px; padding-bottom: 0px; } .cal_today { background:#ffffff; @@ -1518,37 +1558,19 @@ table.cal_month { border-spacing: 0px; } div.dayevent table.nobordernopadding tr td {padding:1px;} -table.cal_event { - border-collapse:collapse; - margin-bottom:1px; -} - -ul.cal_event { padding-right: 2px; padding-top: 1px; border: none; list-style-type: none; margin: 0 auto; padding-left: 0px; padding-start: 0px; -khtml-padding-start: 0px; -o-padding-start: 0px; -webkit-padding-start: 0px; -webkit-padding-start: 0px; } +table.cal_event { border: none; border-collapse: collapse; margin-bottom: 1px; -webkit-border-radius: 6px; border-radius: 6px; + -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.25), 0 1px 2px rgba(0, 0, 0, 0.25); + moz-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.25), 0 1px 2px rgba(0, 0, 0, 0.25); + box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.25), 0 1px 2px rgba(0, 0, 0, 0.25); + background: -webkit-gradient(linear, left top, left bottom, from(#006aac), to(#00438d)); + } +table.cal_event td { border: none; padding-: 2px; padding-: 2px; padding-top: 0px; padding-bottom: 0px; } +ul.cal_event { padding-right: 2px; padding-top: 1px; border: none; list-style-type: none; margin: 0 auto; padding-left: 0px; padding-start: 0px; -khtml-padding-start: 0px; -o-padding-start: 0px; -moz-padding-start: 0px; -webkit-padding-start: 0px; } li.cal_event { border: none; list-style-type: none; } - -.cal_event a:link { - color:#232323; - font-size:11px; - font-weight:normal !important; -} - -.cal_event a:visited { - color:#232323; - font-size:11px; - font-weight:normal !important; -} - -.cal_event a:active { - color:#232323; - font-size:11px; - font-weight:normal !important; -} - -.cal_event a:hover { - color:rgba(255,255,255,.75); - font-size:11px; - font-weight:normal !important; -} +.cal_event a:link { color: #111111; font-size: 11px; font-weight: normal !important; } +.cal_event a:visited { color: #111111; font-size: 11px; font-weight: normal !important; } +.cal_event a:active { color: #111111; font-size: 11px; font-weight: normal !important; } +.cal_event a:hover { color: #111111; font-size: 11px; font-weight: normal !important; color:rgba(255,255,255,.75); } /* ============================================================================== */ diff --git a/htdocs/theme/eldy/style.css.php b/htdocs/theme/eldy/style.css.php index 47e27f3f968..bcfb9a051bd 100644 --- a/htdocs/theme/eldy/style.css.php +++ b/htdocs/theme/eldy/style.css.php @@ -58,6 +58,8 @@ if (GETPOST('theme')) $conf->theme=GETPOST('theme'); // If theme was forced on $langs->load("main",0,1); $right=($langs->trans("DIRECTION")=='rtl'?'left':'right'); $left=($langs->trans("DIRECTION")=='rtl'?'right':'left'); +$fontsize=empty($conf->dol_optimize_smallscreen)?'12':'12'; +$fontsizesmaller=empty($conf->dol_optimize_smallscreen)?'11':'11'; $path=''; // This value may be used in future for external module to overwrite theme $theme='eldy'; // Value of theme @@ -198,7 +200,7 @@ if (! empty($conf->dol_optimize_smallscreen)) $fontsize=11; ?> /* ============================================================================== */ -/* Styles par defaut */ +/* Default styles */ /* ============================================================================== */ body { @@ -304,8 +306,8 @@ input[type=image] { background-color: transparent; border: none; box-shadow: non box-shadow: 4px 4px 4px #CCC; } form { - padding: 0em 0em 0em 0em; - margin: 0em 0em 0em 0em; + padding:0px; + margin:0px; } div.float { @@ -852,9 +854,9 @@ td.vmenu { .vmenu { margin-left: 4px; - + display: none; - + } .menu_contenu { padding-top: 1px; } @@ -1317,11 +1319,14 @@ div.tabsAction { a.tabTitle { - background: #657090; - color: white; +/* background: #657090; + color: white;*/ + color:rgba(0,0,0,.5); + margin-right:10px; + text-shadow:1px 1px 1px #ffffff; font-family: ; font-weight: normal; - padding: 0px 6px 2px 6px; + padding: 4px 6px 2px 6px; margin: 0px 6px; text-decoration: none; white-space: nowrap; @@ -1329,7 +1334,7 @@ a.tabTitle { a.tab:link, a.tab:visited, a.tab:hover, a.tab#active { font-family: ; - padding: 2px 6px 2px 6px; + padding: 4px 6px 2px 6px; margin: 0em 0.2em; text-decoration: none; white-space: nowrap; @@ -1364,6 +1369,7 @@ a.tab#active { a.tab:link, a.tab:visited, a.tab:hover, a.tab#active { color: #; + font-weight: normal !important; } a.tabimage { diff --git a/htdocs/user/note.php b/htdocs/user/note.php index 421d30cbc7a..5ccd23f3042 100644 --- a/htdocs/user/note.php +++ b/htdocs/user/note.php @@ -58,7 +58,7 @@ if ($action == 'update' && $user->rights->user->user->creer && ! $_POST["cancel" { $db->begin(); - $res=$fuser->update_note($_POST["note"],$user); + $res=$fuser->update_note(dol_html_entity_decode(GETPOST('note'), ENT_QUOTES)); if ($res < 0) { $mesg='
'.$adh->error.'
'; diff --git a/htdocs/user/perms.php b/htdocs/user/perms.php index e6836a9b1d4..bca0ba9ee6a 100644 --- a/htdocs/user/perms.php +++ b/htdocs/user/perms.php @@ -260,7 +260,7 @@ print '
'.$langs->trans("Lastname").''.$fuser->lastName.''.$fuser->lastname.'