diff --git a/ChangeLog b/ChangeLog index b11910d25c0..127f2925af8 100644 --- a/ChangeLog +++ b/ChangeLog @@ -2,6 +2,69 @@ English Dolibarr ChangeLog -------------------------------------------------------------- +***** ChangeLog for 11.0.2 compared to 11.0.1 ***** +FIX: #10309 +FIX: #13110 +FIX: #13118 +FIX: #13124 +FIX: #13131 +FIX: #13135 +FIX: #13146 #13198 +FIX: #13175 +FIX: #13182 +FIX: #13183 +FIX: #13184 +FIX: #13263 +FIX: #13267 +FIX: an external user can not approve +FIX: API Get list of documents for supplier_invoice +FIX: API to push an expense report +FIX: API upload/download doc for expensereport +FIX: Avoid to download the export if we just press enter to refresh form +FIX: Bad link to template invoices +FIX: Bad sort link in accounting report +FIX: Bad translation for productlot EatBy and SellBy +FIX: better method to check user rights AND usergroup rights ! +FIX: CA by product list filter +FIX: CSS +FIX: Disable js if no javascript +FIX: duplicate class name into some log lines +FIX: etrafield with visibilty=5 were not in read only. +FIX: excess paid from situation invoices not counted when calculating remain to pay. +FIX: Force FEC export to txt format. +FIX: Free input for email no more visible. +FIX: Keep assigned users in session when loading projects and tasks +FIX: List of viewed projects too large in task widget. +FIX: Menu truncated. Add tooltip to have all content. +FIX: Missing field "billed" in export. +FIX: missing "statut" for getNomUrl() function +FIX: modFournisseur is required by modSupplierProposal +FIX: Multicompany compatibility +FIX: must be == and not = +FIX: option for topbar search and bookmarks +FIX: option MAIN_OPTIMIZEFORTEXTBROWSER +FIX: some responsive troubles +FIX: round MT in accountancy books +FIX: search with '0' +FIX: sort link +FIX: SQL Overload in default contact trigger. +FIX: SQl syntax error. +FIX: Submit of documents for supplier invoices. +FIX: timezone must be tzserver and not tzuser as on contract card +FIX: token in barcode tools page missing +FIX: Bad name of trigger PROPAL_SUPPLIER_TRIGGER, should be PROPOSAL_SUPPLIER_TRIGGER +FIX: Type of contact for event does not exists and not supported +FIX: Type of contact not saved when creating a contact +FIX: typo on ckeck method +FIX: undefined function measuringUnitString in product list +FIX: Usage of project not available in export. +FIX: wrong test +FIX: z-index for moretabsList with constant MAIN_MAXTABS_IN_CARD +FIX: Use GETPOST instead of POST +FIX: HTML Injection +FIX: Visualization rights correction on last modified contacts box. +FIX: Vulnerability in module from modulebuilder. +FIX: Vulnerability reported by code16 ***** ChangeLog for 11.0.1 compared to 11.0.0 ***** FIX: advanced target emailing sql and ergonomy. diff --git a/htdocs/accountancy/index.php b/htdocs/accountancy/index.php index 71fce0be43a..ec193b2922a 100644 --- a/htdocs/accountancy/index.php +++ b/htdocs/accountancy/index.php @@ -66,7 +66,7 @@ if ($conf->accounting->enabled) $resultboxes = FormOther::getBoxesArea($user, "27"); // Load $resultboxes (selectboxlist + boxactivated + boxlista + boxlistb) - $helpisexpanded = empty($resultboxes['boxactivated']); // If there is no widget, the tooltip help is expanded by default. + $helpisexpanded = empty($resultboxes['boxactivated']) || (empty($resultboxes['boxlista']) && empty($resultboxes['boxlistb'])); // If there is no widget, the tooltip help is expanded by default. $showtutorial = ''; if (!$helpisexpanded) @@ -222,10 +222,6 @@ if ($conf->accounting->enabled) $boxlist .= '
'; $boxlist .= '
'; - if (!empty($nbworkboardcount)) - { - $boxlist .= $boxwork; - } $boxlist .= $resultboxes['boxlista']; @@ -233,7 +229,6 @@ if ($conf->accounting->enabled) $boxlist .= '
'; - $boxlist .= $boxstat; $boxlist .= $resultboxes['boxlistb']; $boxlist .= '
'; diff --git a/htdocs/adherents/class/adherent.class.php b/htdocs/adherents/class/adherent.class.php index ec4042cdf88..04c5baa642a 100644 --- a/htdocs/adherents/class/adherent.class.php +++ b/htdocs/adherents/class/adherent.class.php @@ -1376,48 +1376,49 @@ class Adherent extends CommonObject require_once DOL_DOCUMENT_ROOT.'/adherents/class/subscription.class.php'; - $sql = "SELECT c.rowid, c.fk_adherent, c.subscription, c.note, c.fk_bank,"; - $sql.= " c.tms as datem,"; - $sql.= " c.datec as datec,"; - $sql.= " c.dateadh as dateh,"; - $sql.= " c.datef as datef"; - $sql.= " FROM ".MAIN_DB_PREFIX."subscription as c"; - $sql.= " WHERE c.fk_adherent = ".$this->id; - $sql.= " ORDER BY c.dateadh"; + $sql = "SELECT c.rowid, c.fk_adherent, c.fk_type, c.subscription, c.note, c.fk_bank,"; + $sql .= " c.tms as datem,"; + $sql .= " c.datec as datec,"; + $sql .= " c.dateadh as dateh,"; + $sql .= " c.datef as datef"; + $sql .= " FROM ".MAIN_DB_PREFIX."subscription as c"; + $sql .= " WHERE c.fk_adherent = ".$this->id; + $sql .= " ORDER BY c.dateadh"; dol_syslog(get_class($this)."::fetch_subscriptions", LOG_DEBUG); - $resql=$this->db->query($sql); + $resql = $this->db->query($sql); if ($resql) { - $this->subscriptions=array(); + $this->subscriptions = array(); - $i=0; + $i = 0; while ($obj = $this->db->fetch_object($resql)) { - if ($i==0) + if ($i == 0) { - $this->first_subscription_date=$this->db->jdate($obj->datec); - $this->first_subscription_date_start=$this->db->jdate($obj->dateh); - $this->first_subscription_date_end=$this->db->jdate($obj->datef); - $this->first_subscription_amount=$obj->subscription; + $this->first_subscription_date = $this->db->jdate($obj->datec); + $this->first_subscription_date_start = $this->db->jdate($obj->dateh); + $this->first_subscription_date_end = $this->db->jdate($obj->datef); + $this->first_subscription_amount = $obj->subscription; } - $this->last_subscription_date=$this->db->jdate($obj->datec); - $this->last_subscription_date_start=$this->db->jdate($obj->datef); - $this->last_subscription_date_end=$this->db->jdate($obj->datef); - $this->last_subscription_amount=$obj->subscription; + $this->last_subscription_date = $this->db->jdate($obj->datec); + $this->last_subscription_date_start = $this->db->jdate($obj->datef); + $this->last_subscription_date_end = $this->db->jdate($obj->datef); + $this->last_subscription_amount = $obj->subscription; - $subscription=new Subscription($this->db); - $subscription->id=$obj->rowid; - $subscription->fk_adherent=$obj->fk_adherent; - $subscription->amount=$obj->subscription; - $subscription->note=$obj->note; - $subscription->fk_bank=$obj->fk_bank; - $subscription->datem=$this->db->jdate($obj->datem); - $subscription->datec=$this->db->jdate($obj->datec); - $subscription->dateh=$this->db->jdate($obj->dateh); - $subscription->datef=$this->db->jdate($obj->datef); + $subscription = new Subscription($this->db); + $subscription->id = $obj->rowid; + $subscription->fk_adherent = $obj->fk_adherent; + $subscription->fk_type = $obj->fk_type; + $subscription->amount = $obj->subscription; + $subscription->note = $obj->note; + $subscription->fk_bank = $obj->fk_bank; + $subscription->datem = $this->db->jdate($obj->datem); + $subscription->datec = $this->db->jdate($obj->datec); + $subscription->dateh = $this->db->jdate($obj->dateh); + $subscription->datef = $this->db->jdate($obj->datef); - $this->subscriptions[]=$subscription; + $this->subscriptions[] = $subscription; $i++; } @@ -1425,7 +1426,7 @@ class Adherent extends CommonObject } else { - $this->error=$this->db->error().' sql='.$sql; + $this->error = $this->db->error().' sql='.$sql; return -1; } } diff --git a/htdocs/admin/dict.php b/htdocs/admin/dict.php index 314a4e61954..2ad521f79a2 100644 --- a/htdocs/admin/dict.php +++ b/htdocs/admin/dict.php @@ -767,7 +767,7 @@ if (GETPOST('actionadd') || GETPOST('actionmodify')) if ($keycode == 'sortorder') // For column name 'sortorder', we use the field name 'position' { - $sql .= "'".(int) GETPOST('position', 'int'); + $sql .= "'".(int) GETPOST('position', 'int')."'"; } elseif ($_POST[$keycode] == '' && !($keycode == 'code' && $id == 10)) $sql .= "null"; // For vat, we want/accept code = '' elseif ($keycode == 'content') { diff --git a/htdocs/admin/ticket.php b/htdocs/admin/ticket.php index 97d81a3e03c..e10c66a3809 100644 --- a/htdocs/admin/ticket.php +++ b/htdocs/admin/ticket.php @@ -197,6 +197,7 @@ dol_fiche_end(); print load_fiche_titre($langs->trans("TicketNumberingModules")); +print '
'; print ''; print ''; print ''; @@ -287,7 +288,9 @@ foreach ($dirmodels as $reldir) { } } -print '
'.$langs->trans("Name").'

'; +print ''; +print '
'; +print '
'; if (!$conf->use_javascript_ajax) { print '
'; diff --git a/htdocs/admin/ticket_public.php b/htdocs/admin/ticket_public.php index a4098e52247..6b8a23c94fc 100644 --- a/htdocs/admin/ticket_public.php +++ b/htdocs/admin/ticket_public.php @@ -167,7 +167,7 @@ $head = ticketAdminPrepareHead(); dol_fiche_head($head, 'public', $langs->trans("Module56000Name"), -1, "ticket"); -print ''.$langs->trans("TicketPublicAccess").' : '.dol_buildpath('/public/ticket/index.php', 2).''; +print ''.$langs->trans("TicketPublicAccess").' : '.dol_buildpath('/public/ticket/index.php', 2).''; dol_fiche_end(); @@ -176,14 +176,14 @@ $enabledisablehtml = $langs->trans("TicketsActivatePublicInterface").' '; if (empty($conf->global->TICKET_ENABLE_PUBLIC_INTERFACE)) { // Button off, click to enable - $enabledisablehtml .= ''; + $enabledisablehtml .= ''; $enabledisablehtml .= img_picto($langs->trans("Disabled"), 'switch_off'); $enabledisablehtml .= ''; } else { // Button on, click to disable - $enabledisablehtml .= ''; + $enabledisablehtml .= ''; $enabledisablehtml .= img_picto($langs->trans("Activated"), 'switch_on'); $enabledisablehtml .= ''; } @@ -200,6 +200,7 @@ if (!empty($conf->global->TICKET_ENABLE_PUBLIC_INTERFACE)) print ''; } + print '
'; print ''; print ''; print ''; } - print '
'.$langs->trans("Parameters").''; @@ -279,7 +280,9 @@ if (!empty($conf->global->TICKET_ENABLE_PUBLIC_INTERFACE)) print '

'; + print ''; + print '
'; + print '
'; if (!$conf->use_javascript_ajax) { print '
'; @@ -288,6 +291,7 @@ if (!empty($conf->global->TICKET_ENABLE_PUBLIC_INTERFACE)) // Admin var of module print load_fiche_titre($langs->trans("TicketParamMail")); + print '
'; print ''; print ''; @@ -369,13 +373,14 @@ if (!empty($conf->global->TICKET_ENABLE_PUBLIC_INTERFACE)) $url_interface = $conf->global->TICKET_URL_PUBLIC_INTERFACE; print ''; + print ''; print ''; print ''; print '
'.$langs->trans("TicketUrlPublicInterfaceLabelAdmin").''; print ''; - print ''; print $form->textwithpicto('', $langs->trans("TicketUrlPublicInterfaceHelpAdmin"), 1, 'help'); print '
'; + print '
'; print '
'; diff --git a/htdocs/comm/propal/class/propal.class.php b/htdocs/comm/propal/class/propal.class.php index 778f00fbf31..c16fdf1679c 100644 --- a/htdocs/comm/propal/class/propal.class.php +++ b/htdocs/comm/propal/class/propal.class.php @@ -223,6 +223,90 @@ class Propal extends CommonObject public $oldcopy; + + /** + * 'type' if the field format ('integer', 'integer:ObjectClass:PathToClass[:AddCreateButtonOrNot[:Filter]]', 'varchar(x)', 'double(24,8)', 'real', 'price', 'text', 'html', 'date', 'datetime', 'timestamp', 'duration', 'mail', 'phone', 'url', 'password') + * Note: Filter can be a string like "(t.ref:like:'SO-%') or (t.date_creation:<:'20160101') or (t.nature:is:NULL)" + * 'label' the translation key. + * 'enabled' is a condition when the field must be managed. + * 'position' is the sort order of field. + * 'notnull' is set to 1 if not null in database. Set to -1 if we must set data to null if empty ('' or 0). + * 'visible' says if field is visible in list (Examples: 0=Not visible, 1=Visible on list and create/update/view forms, 2=Visible on list only, 3=Visible on create/update/view form only (not list), 4=Visible on list and update/view form only (not create). 5=Visible on list and view only (not create/not update). Using a negative value means field is not shown by default on list but can be selected for viewing) + * 'noteditable' says if field is not editable (1 or 0) + * 'default' is a default value for creation (can still be overwrote by the Setup of Default Values if field is editable in creation form). Note: If default is set to '(PROV)' and field is 'ref', the default value will be set to '(PROVid)' where id is rowid when a new record is created. + * 'index' if we want an index in database. + * 'foreignkey'=>'tablename.field' if the field is a foreign key (it is recommanded to name the field fk_...). + * 'searchall' is 1 if we want to search in this field when making a search from the quick search button. + * 'isameasure' must be set to 1 if you want to have a total on list for this field. Field type must be summable like integer or double(24,8). + * 'css' is the CSS style to use on field. For example: 'maxwidth200' + * 'help' is a string visible as a tooltip on field + * 'showoncombobox' if value of the field must be visible into the label of the combobox that list record + * 'disabled' is 1 if we want to have the field locked by a 'disabled' attribute. In most cases, this is never set into the definition of $fields into class, but is set dynamically by some part of code. + * 'arraykeyval' to set list of value if type is a list of predefined values. For example: array("0"=>"Draft","1"=>"Active","-1"=>"Cancel") + * 'comment' is not used. You can store here any text of your choice. It is not used by application. + * + * Note: To have value dynamic, you can set value to 0 in definition and edit the value on the fly into the constructor. + */ + + // BEGIN MODULEBUILDER PROPERTIES + /** + * @var array Array with all fields and their property. Do not use it as a static var. It may be modified by constructor. + */ + public $fields=array( + 'rowid' =>array('type'=>'integer', 'label'=>'TechnicalID', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>10), + 'fk_soc' =>array('type'=>'integer:Societe:societe/class/societe.class.php', 'label'=>'ThirdParty', 'enabled'=>1, 'visible'=>-1, 'position'=>15), + 'fk_projet' =>array('type'=>'integer:Project:projet/class/project.class.php:1:fk_statut=1', 'label'=>'Fk projet', 'enabled'=>1, 'visible'=>-1, 'position'=>20), + 'tms' =>array('type'=>'timestamp', 'label'=>'DateModification', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>25), + 'ref' =>array('type'=>'varchar(30)', 'label'=>'Ref', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'showoncombobox'=>1, 'position'=>30), + 'entity' =>array('type'=>'integer', 'label'=>'Entity', 'default'=>1, 'enabled'=>1, 'visible'=>-2, 'notnull'=>1, 'position'=>35, 'index'=>1), + 'ref_ext' =>array('type'=>'varchar(255)', 'label'=>'Ref ext', 'enabled'=>1, 'visible'=>0, 'position'=>40), + 'ref_int' =>array('type'=>'varchar(255)', 'label'=>'Ref int', 'enabled'=>1, 'visible'=>-1, 'position'=>45), + 'ref_client' =>array('type'=>'varchar(255)', 'label'=>'Ref client', 'enabled'=>1, 'visible'=>-1, 'position'=>50), + 'datec' =>array('type'=>'datetime', 'label'=>'DateCreation', 'enabled'=>1, 'visible'=>-1, 'position'=>55), + 'datep' =>array('type'=>'date', 'label'=>'Datep', 'enabled'=>1, 'visible'=>-1, 'position'=>60), + 'fin_validite' =>array('type'=>'datetime', 'label'=>'Fin validite', 'enabled'=>1, 'visible'=>-1, 'position'=>65), + 'date_valid' =>array('type'=>'datetime', 'label'=>'DateValidation', 'enabled'=>1, 'visible'=>-1, 'position'=>70), + 'date_cloture' =>array('type'=>'datetime', 'label'=>'Date cloture', 'enabled'=>1, 'visible'=>-1, 'position'=>75), + 'fk_user_author' =>array('type'=>'integer:User:user/class/user.class.php', 'label'=>'Fk user author', 'enabled'=>1, 'visible'=>-1, 'position'=>80), + 'fk_user_modif' =>array('type'=>'integer:User:user/class/user.class.php', 'label'=>'UserModif', 'enabled'=>1, 'visible'=>-2, 'notnull'=>-1, 'position'=>85), + 'fk_user_valid' =>array('type'=>'integer:User:user/class/user.class.php', 'label'=>'UserValidation', 'enabled'=>1, 'visible'=>-1, 'position'=>90), + 'fk_user_cloture' =>array('type'=>'integer:User:user/class/user.class.php', 'label'=>'Fk user cloture', 'enabled'=>1, 'visible'=>-1, 'position'=>95), + 'fk_statut' =>array('type'=>'smallint(6)', 'label'=>'Fk statut', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>500), + 'price' =>array('type'=>'double', 'label'=>'Price', 'enabled'=>1, 'visible'=>-1, 'position'=>105), + 'remise_percent' =>array('type'=>'double', 'label'=>'Remise percent', 'enabled'=>1, 'visible'=>-1, 'position'=>110), + 'remise_absolue' =>array('type'=>'double', 'label'=>'Remise absolue', 'enabled'=>1, 'visible'=>-1, 'position'=>115), + 'remise' =>array('type'=>'double', 'label'=>'Remise', 'enabled'=>1, 'visible'=>-1, 'position'=>120), + 'total_ht' =>array('type'=>'double(24,8)', 'label'=>'Total ht', 'enabled'=>1, 'visible'=>-1, 'position'=>125), + 'tva' =>array('type'=>'double(24,8)', 'label'=>'Tva', 'enabled'=>1, 'visible'=>-1, 'position'=>130), + 'localtax1' =>array('type'=>'double(24,8)', 'label'=>'Localtax1', 'enabled'=>1, 'visible'=>-1, 'position'=>135), + 'localtax2' =>array('type'=>'double(24,8)', 'label'=>'Localtax2', 'enabled'=>1, 'visible'=>-1, 'position'=>140), + 'total' =>array('type'=>'double(24,8)', 'label'=>'Total', 'enabled'=>1, 'visible'=>-1, 'position'=>145), + 'fk_account' =>array('type'=>'integer', 'label'=>'Fk account', 'enabled'=>1, 'visible'=>-1, 'position'=>150), + 'fk_currency' =>array('type'=>'varchar(3)', 'label'=>'Fk currency', 'enabled'=>1, 'visible'=>-1, 'position'=>155), + 'fk_cond_reglement' =>array('type'=>'integer', 'label'=>'Fk cond reglement', 'enabled'=>1, 'visible'=>-1, 'position'=>160), + 'fk_mode_reglement' =>array('type'=>'integer', 'label'=>'Fk mode reglement', 'enabled'=>1, 'visible'=>-1, 'position'=>165), + 'note_private' =>array('type'=>'text', 'label'=>'NotePublic', 'enabled'=>1, 'visible'=>0, 'position'=>170), + 'note_public' =>array('type'=>'text', 'label'=>'NotePrivate', 'enabled'=>1, 'visible'=>0, 'position'=>175), + 'model_pdf' =>array('type'=>'varchar(255)', 'label'=>'Model pdf', 'enabled'=>1, 'visible'=>0, 'position'=>180), + 'date_livraison' =>array('type'=>'date', 'label'=>'Date livraison', 'enabled'=>1, 'visible'=>-1, 'position'=>185), + 'fk_shipping_method' =>array('type'=>'integer', 'label'=>'Fk shipping method', 'enabled'=>1, 'visible'=>-1, 'position'=>190), + 'fk_availability' =>array('type'=>'integer', 'label'=>'Fk availability', 'enabled'=>1, 'visible'=>-1, 'position'=>195), + 'fk_delivery_address' =>array('type'=>'integer', 'label'=>'Fk delivery address', 'enabled'=>1, 'visible'=>-1, 'position'=>200), + 'fk_input_reason' =>array('type'=>'integer', 'label'=>'Fk input reason', 'enabled'=>1, 'visible'=>-1, 'position'=>205), + 'import_key' =>array('type'=>'varchar(14)', 'label'=>'ImportId', 'enabled'=>1, 'visible'=>-2, 'position'=>900), + 'extraparams' =>array('type'=>'varchar(255)', 'label'=>'Extraparams', 'enabled'=>1, 'visible'=>-1, 'position'=>215), + 'fk_incoterms' =>array('type'=>'integer', 'label'=>'Fk incoterms', 'enabled'=>1, 'visible'=>-1, 'position'=>220), + 'location_incoterms' =>array('type'=>'varchar(255)', 'label'=>'Location incoterms', 'enabled'=>1, 'visible'=>-1, 'position'=>225), + 'fk_multicurrency' =>array('type'=>'integer', 'label'=>'Fk multicurrency', 'enabled'=>1, 'visible'=>-1, 'position'=>230), + 'multicurrency_code' =>array('type'=>'varchar(255)', 'label'=>'Multicurrency code', 'enabled'=>1, 'visible'=>-1, 'position'=>235), + 'multicurrency_tx' =>array('type'=>'double(24,8)', 'label'=>'Multicurrency tx', 'enabled'=>1, 'visible'=>-1, 'position'=>240), + 'multicurrency_total_ht' =>array('type'=>'double(24,8)', 'label'=>'Multicurrency total ht', 'enabled'=>1, 'visible'=>-1, 'position'=>245), + 'multicurrency_total_tva' =>array('type'=>'double(24,8)', 'label'=>'Multicurrency total tva', 'enabled'=>1, 'visible'=>-1, 'position'=>250), + 'multicurrency_total_ttc' =>array('type'=>'double(24,8)', 'label'=>'Multicurrency total ttc', 'enabled'=>1, 'visible'=>-1, 'position'=>255), + 'last_main_doc' =>array('type'=>'varchar(255)', 'label'=>'Last main doc', 'enabled'=>1, 'visible'=>-1, 'position'=>260), + ); + // END MODULEBUILDER PROPERTIES + /** * Draft status */ diff --git a/htdocs/comm/propal/list.php b/htdocs/comm/propal/list.php index d4d227f8b7c..8551e17d08a 100644 --- a/htdocs/comm/propal/list.php +++ b/htdocs/comm/propal/list.php @@ -1029,9 +1029,7 @@ if ($resql) $nbofsalesrepresentative = count($listsalesrepresentatives); if ($nbofsalesrepresentative > 3) // We print only number { - print ''; print $nbofsalesrepresentative; - print ''; } elseif ($nbofsalesrepresentative > 0) { diff --git a/htdocs/commande/class/commande.class.php b/htdocs/commande/class/commande.class.php index 1d8c5bb0f30..6e4d2efc742 100644 --- a/htdocs/commande/class/commande.class.php +++ b/htdocs/commande/class/commande.class.php @@ -232,6 +232,94 @@ class Commande extends CommonOrder //! key of pos source ('0', '1', ...) public $pos_source; + + /** + * 'type' if the field format ('integer', 'integer:ObjectClass:PathToClass[:AddCreateButtonOrNot[:Filter]]', 'varchar(x)', 'double(24,8)', 'real', 'price', 'text', 'html', 'date', 'datetime', 'timestamp', 'duration', 'mail', 'phone', 'url', 'password') + * Note: Filter can be a string like "(t.ref:like:'SO-%') or (t.date_creation:<:'20160101') or (t.nature:is:NULL)" + * 'label' the translation key. + * 'enabled' is a condition when the field must be managed. + * 'position' is the sort order of field. + * 'notnull' is set to 1 if not null in database. Set to -1 if we must set data to null if empty ('' or 0). + * 'visible' says if field is visible in list (Examples: 0=Not visible, 1=Visible on list and create/update/view forms, 2=Visible on list only, 3=Visible on create/update/view form only (not list), 4=Visible on list and update/view form only (not create). 5=Visible on list and view only (not create/not update). Using a negative value means field is not shown by default on list but can be selected for viewing) + * 'noteditable' says if field is not editable (1 or 0) + * 'default' is a default value for creation (can still be overwrote by the Setup of Default Values if field is editable in creation form). Note: If default is set to '(PROV)' and field is 'ref', the default value will be set to '(PROVid)' where id is rowid when a new record is created. + * 'index' if we want an index in database. + * 'foreignkey'=>'tablename.field' if the field is a foreign key (it is recommanded to name the field fk_...). + * 'searchall' is 1 if we want to search in this field when making a search from the quick search button. + * 'isameasure' must be set to 1 if you want to have a total on list for this field. Field type must be summable like integer or double(24,8). + * 'css' is the CSS style to use on field. For example: 'maxwidth200' + * 'help' is a string visible as a tooltip on field + * 'showoncombobox' if value of the field must be visible into the label of the combobox that list record + * 'disabled' is 1 if we want to have the field locked by a 'disabled' attribute. In most cases, this is never set into the definition of $fields into class, but is set dynamically by some part of code. + * 'arraykeyval' to set list of value if type is a list of predefined values. For example: array("0"=>"Draft","1"=>"Active","-1"=>"Cancel") + * 'comment' is not used. You can store here any text of your choice. It is not used by application. + * + * Note: To have value dynamic, you can set value to 0 in definition and edit the value on the fly into the constructor. + */ + + // BEGIN MODULEBUILDER PROPERTIES + /** + * @var array Array with all fields and their property. Do not use it as a static var. It may be modified by constructor. + */ + public $fields=array( + 'rowid' =>array('type'=>'integer', 'label'=>'TechnicalID', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>10), + 'tms' =>array('type'=>'timestamp', 'label'=>'DateModification', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>15), + 'fk_soc' =>array('type'=>'integer:Societe:societe/class/societe.class.php', 'label'=>'ThirdParty', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>20), + 'fk_projet' =>array('type'=>'integer:Project:projet/class/project.class.php:1:fk_statut=1', 'label'=>'Fk projet', 'enabled'=>1, 'visible'=>-1, 'position'=>25), + 'ref' =>array('type'=>'varchar(30)', 'label'=>'Ref', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'showoncombobox'=>1, 'position'=>30), + 'entity' =>array('type'=>'integer', 'label'=>'Entity', 'default'=>1, 'enabled'=>1, 'visible'=>-2, 'notnull'=>1, 'position'=>35, 'index'=>1), + 'ref_ext' =>array('type'=>'varchar(255)', 'label'=>'Ref ext', 'enabled'=>1, 'visible'=>0, 'position'=>40), + 'ref_int' =>array('type'=>'varchar(255)', 'label'=>'Ref int', 'enabled'=>1, 'visible'=>-1, 'position'=>45), + 'ref_client' =>array('type'=>'varchar(255)', 'label'=>'Ref client', 'enabled'=>1, 'visible'=>-1, 'position'=>50), + 'date_creation' =>array('type'=>'datetime', 'label'=>'Date creation', 'enabled'=>1, 'visible'=>-1, 'position'=>55), + 'date_valid' =>array('type'=>'datetime', 'label'=>'DateValidation', 'enabled'=>1, 'visible'=>-1, 'position'=>60), + 'date_cloture' =>array('type'=>'datetime', 'label'=>'Date cloture', 'enabled'=>1, 'visible'=>-1, 'position'=>65), + 'date_commande' =>array('type'=>'date', 'label'=>'Date commande', 'enabled'=>1, 'visible'=>-1, 'position'=>70), + 'fk_user_author' =>array('type'=>'integer:User:user/class/user.class.php', 'label'=>'Fk user author', 'enabled'=>1, 'visible'=>-1, 'position'=>75), + 'fk_user_modif' =>array('type'=>'integer:User:user/class/user.class.php', 'label'=>'UserModif', 'enabled'=>1, 'visible'=>-2, 'notnull'=>-1, 'position'=>80), + 'fk_user_valid' =>array('type'=>'integer:User:user/class/user.class.php', 'label'=>'UserValidation', 'enabled'=>1, 'visible'=>-1, 'position'=>85), + 'fk_user_cloture' =>array('type'=>'integer:User:user/class/user.class.php', 'label'=>'Fk user cloture', 'enabled'=>1, 'visible'=>-1, 'position'=>90), + 'source' =>array('type'=>'smallint(6)', 'label'=>'Source', 'enabled'=>1, 'visible'=>-1, 'position'=>95), + 'fk_statut' =>array('type'=>'smallint(6)', 'label'=>'Fk statut', 'enabled'=>1, 'visible'=>-1, 'position'=>500), + 'amount_ht' =>array('type'=>'double(24,8)', 'label'=>'Amount ht', 'enabled'=>1, 'visible'=>-1, 'position'=>105), + 'remise_percent' =>array('type'=>'double', 'label'=>'Remise percent', 'enabled'=>1, 'visible'=>-1, 'position'=>110), + 'remise_absolue' =>array('type'=>'double', 'label'=>'Remise absolue', 'enabled'=>1, 'visible'=>-1, 'position'=>115), + 'remise' =>array('type'=>'double', 'label'=>'Remise', 'enabled'=>1, 'visible'=>-1, 'position'=>120), + 'tva' =>array('type'=>'double(24,8)', 'label'=>'Tva', 'enabled'=>1, 'visible'=>-1, 'position'=>125), + 'localtax1' =>array('type'=>'double(24,8)', 'label'=>'Localtax1', 'enabled'=>1, 'visible'=>-1, 'position'=>130), + 'localtax2' =>array('type'=>'double(24,8)', 'label'=>'Localtax2', 'enabled'=>1, 'visible'=>-1, 'position'=>135), + 'total_ht' =>array('type'=>'double(24,8)', 'label'=>'Total ht', 'enabled'=>1, 'visible'=>-1, 'position'=>140), + 'total_ttc' =>array('type'=>'double(24,8)', 'label'=>'Total ttc', 'enabled'=>1, 'visible'=>-1, 'position'=>145), + 'note_private' =>array('type'=>'text', 'label'=>'NotePublic', 'enabled'=>1, 'visible'=>0, 'position'=>150), + 'note_public' =>array('type'=>'text', 'label'=>'NotePrivate', 'enabled'=>1, 'visible'=>0, 'position'=>155), + 'model_pdf' =>array('type'=>'varchar(255)', 'label'=>'Model pdf', 'enabled'=>1, 'visible'=>0, 'position'=>160), + 'facture' =>array('type'=>'tinyint(4)', 'label'=>'Facture', 'enabled'=>1, 'visible'=>-1, 'position'=>165), + 'fk_account' =>array('type'=>'integer', 'label'=>'Fk account', 'enabled'=>1, 'visible'=>-1, 'position'=>170), + 'fk_currency' =>array('type'=>'varchar(3)', 'label'=>'Fk currency', 'enabled'=>1, 'visible'=>-1, 'position'=>175), + 'fk_cond_reglement' =>array('type'=>'integer', 'label'=>'Fk cond reglement', 'enabled'=>1, 'visible'=>-1, 'position'=>180), + 'fk_mode_reglement' =>array('type'=>'integer', 'label'=>'Fk mode reglement', 'enabled'=>1, 'visible'=>-1, 'position'=>185), + 'date_livraison' =>array('type'=>'date', 'label'=>'Date livraison', 'enabled'=>1, 'visible'=>-1, 'position'=>190), + 'fk_shipping_method' =>array('type'=>'integer', 'label'=>'Fk shipping method', 'enabled'=>1, 'visible'=>-1, 'position'=>195), + 'fk_warehouse' =>array('type'=>'integer:Entrepot:product/stock/class/entrepot.class.php', 'label'=>'Fk warehouse', 'enabled'=>1, 'visible'=>-1, 'position'=>200), + 'fk_availability' =>array('type'=>'integer', 'label'=>'Fk availability', 'enabled'=>1, 'visible'=>-1, 'position'=>205), + 'fk_input_reason' =>array('type'=>'integer', 'label'=>'Fk input reason', 'enabled'=>1, 'visible'=>-1, 'position'=>210), + 'fk_delivery_address' =>array('type'=>'integer', 'label'=>'Fk delivery address', 'enabled'=>1, 'visible'=>-1, 'position'=>215), + 'import_key' =>array('type'=>'varchar(14)', 'label'=>'ImportId', 'enabled'=>1, 'visible'=>-2, 'position'=>900), + 'extraparams' =>array('type'=>'varchar(255)', 'label'=>'Extraparams', 'enabled'=>1, 'visible'=>-1, 'position'=>225), + 'fk_incoterms' =>array('type'=>'integer', 'label'=>'Fk incoterms', 'enabled'=>1, 'visible'=>-1, 'position'=>230), + 'location_incoterms' =>array('type'=>'varchar(255)', 'label'=>'Location incoterms', 'enabled'=>1, 'visible'=>-1, 'position'=>235), + 'fk_multicurrency' =>array('type'=>'integer', 'label'=>'Fk multicurrency', 'enabled'=>1, 'visible'=>-1, 'position'=>240), + 'multicurrency_code' =>array('type'=>'varchar(255)', 'label'=>'Multicurrency code', 'enabled'=>1, 'visible'=>-1, 'position'=>245), + 'multicurrency_tx' =>array('type'=>'double(24,8)', 'label'=>'Multicurrency tx', 'enabled'=>1, 'visible'=>-1, 'position'=>250), + 'multicurrency_total_ht' =>array('type'=>'double(24,8)', 'label'=>'Multicurrency total ht', 'enabled'=>1, 'visible'=>-1, 'position'=>255), + 'multicurrency_total_tva' =>array('type'=>'double(24,8)', 'label'=>'Multicurrency total tva', 'enabled'=>1, 'visible'=>-1, 'position'=>260), + 'multicurrency_total_ttc' =>array('type'=>'double(24,8)', 'label'=>'Multicurrency total ttc', 'enabled'=>1, 'visible'=>-1, 'position'=>265), + 'last_main_doc' =>array('type'=>'varchar(255)', 'label'=>'Last main doc', 'enabled'=>1, 'visible'=>-1, 'position'=>270), + 'module_source' =>array('type'=>'varchar(32)', 'label'=>'Module source', 'enabled'=>1, 'visible'=>-1, 'position'=>275), + 'pos_source' =>array('type'=>'varchar(32)', 'label'=>'Pos source', 'enabled'=>1, 'visible'=>-1, 'position'=>280), + ); + // END MODULEBUILDER PROPERTIES + /** * ERR Not enough stock */ diff --git a/htdocs/compta/facture/card.php b/htdocs/compta/facture/card.php index 2f1941ff836..3363548095f 100644 --- a/htdocs/compta/facture/card.php +++ b/htdocs/compta/facture/card.php @@ -297,31 +297,32 @@ if (empty($reshook)) // Also negative lines should not be allowed on 'non Credit notes' invoices. A test is done when adding or updating lines but we must // do it again in validation to avoid cases where invoice is created from another object that allow negative lines. - // Note that we can accept the negative line if sum with other lines with same vat is positivie: Because all the lines will be merged together + // Note that we can accept the negative line if sum with other lines with same vat makes total positive: Because all the lines will be merged together // when converted into 'available credit' and we will get a positive available credit line. // Note: Other solution if you want to add a negative line on invoice, is to create a discount for customer and consumme it (but this is possible on standard invoice only). - $array_of_pu_ht_per_vat_rate = array(); - $array_of_pu_ht_devise_per_vat_rate = array(); + $array_of_total_ht_per_vat_rate = array(); + $array_of_total_ht_devise_per_vat_rate = array(); foreach($object->lines as $line) { - if (empty($array_of_pu_ht_per_vat_rate[$line->tva_tx.'_'.$line->vat_src_code])) $array_of_pu_ht_per_vat_rate[$line->tva_tx.'_'.$line->vat_src_code] = 0; - if (empty($array_of_pu_ht_devise_per_vat_rate[$line->tva_tx.'_'.$line->vat_src_code])) $array_of_pu_ht_devise_per_vat_rate[$line->tva_tx.'_'.$line->vat_src_code] = 0; - $array_of_pu_ht_per_vat_rate[$line->tva_tx.'_'.$line->vat_src_code] += $line->subprice; - $array_of_pu_ht_devise_per_vat_rate[$line->tva_tx.'_'.$line->vat_src_code] += $line->multicurrency_subprice; + if (empty($array_of_total_ht_per_vat_rate[$line->tva_tx.'_'.$line->vat_src_code])) $array_of_total_ht_per_vat_rate[$line->tva_tx.'_'.$line->vat_src_code] = 0; + if (empty($array_of_total_ht_devise_per_vat_rate[$line->tva_tx.'_'.$line->vat_src_code])) $array_of_total_ht_devise_per_vat_rate[$line->tva_tx.'_'.$line->vat_src_code] = 0; + $array_of_total_ht_per_vat_rate[$line->tva_tx.'_'.$line->vat_src_code] += $line->total_ht; + $array_of_total_ht_devise_per_vat_rate[$line->tva_tx.'_'.$line->vat_src_code] += $line->multicurrency_subprice; } - //var_dump($array_of_pu_ht_per_vat_rate);exit; - foreach($array_of_pu_ht_per_vat_rate as $vatrate => $tmpvalue) - { - $pu_ht = $array_of_pu_ht_per_vat_rate[$vatrate]; - $pu_ht_devise = $array_of_pu_ht_devise_per_vat_rate[$vatrate]; - if (($pu_ht < 0 || $pu_ht_devise < 0) && empty($conf->global->FACTURE_ENABLE_NEGATIVE_LINES)) + //var_dump($array_of_total_ht_per_vat_rate);exit; + foreach($array_of_total_ht_per_vat_rate as $vatrate => $tmpvalue) + { + $tmp_total_ht = $array_of_total_ht_per_vat_rate[$vatrate]; + $tmp_total_ht_devise = $array_of_total_ht_devise_per_vat_rate[$vatrate]; + + if (($tmp_total_ht < 0 || $tmp_total_ht_devise < 0) && empty($conf->global->FACTURE_ENABLE_NEGATIVE_LINES)) { $langs->load("errors"); if ($object->type == $object::TYPE_DEPOSIT) { // Using negative lines on deposit lead to headach and blocking problems when you want to consume them. setEventMessages($langs->trans("ErrorLinesCantBeNegativeOnDeposits"), null, 'errors'); } else { - setEventMessages($langs->trans("ErrorFieldCantBeNegativeOnInvoice", $langs->transnoentitiesnoconv("UnitPriceHT"), $langs->transnoentitiesnoconv("CustomerAbsoluteDiscountShort")), null, 'errors'); + setEventMessages($langs->trans("ErrorLinesCantBeNegativeForOneVATRate"), null, 'errors'); } $error++; $action = ''; @@ -5080,7 +5081,7 @@ elseif ($id > 0 || !empty($ref)) // Reverse back money or convert to reduction if ($object->type == Facture::TYPE_CREDIT_NOTE || $object->type == Facture::TYPE_DEPOSIT || $object->type == Facture::TYPE_STANDARD || $object->type == Facture::TYPE_SITUATION) { // For credit note only - if ($object->type == Facture::TYPE_CREDIT_NOTE && $object->statut == 1 && $object->paye == 0 && $usercanissuepayment) + if ($object->type == Facture::TYPE_CREDIT_NOTE && $object->statut == Facture::STATUS_VALIDATED && $object->paye == 0 && $usercanissuepayment) { if ($resteapayer == 0) { @@ -5093,12 +5094,12 @@ elseif ($id > 0 || !empty($ref)) } // For standard invoice with excess received - if (($object->type == Facture::TYPE_STANDARD || $object->type == Facture::TYPE_SITUATION) && empty($object->paye) && $resteapayer < 0 && $usercancreate && empty($discount->id)) + if (($object->type == Facture::TYPE_STANDARD || $object->type == Facture::TYPE_SITUATION) && $object->statut == Facture::STATUS_VALIDATED && empty($object->paye) && $resteapayer < 0 && $usercancreate && empty($discount->id)) { print ''.$langs->trans('ConvertExcessReceivedToReduc').''; } // For credit note - if ($object->type == Facture::TYPE_CREDIT_NOTE && $object->statut == 1 && $object->paye == 0 && $usercancreate + if ($object->type == Facture::TYPE_CREDIT_NOTE && $object->statut == Facture::STATUS_VALIDATED && $object->paye == 0 && $usercancreate && (! empty($conf->global->INVOICE_ALLOW_REUSE_OF_CREDIT_WHEN_PARTIALLY_REFUNDED) || $object->getSommePaiement() == 0) ) { print ''.$langs->trans('ConvertToReduc').''; @@ -5111,7 +5112,7 @@ elseif ($id > 0 || !empty($ref)) } // Classify paid - if (($object->statut == 1 && $object->paye == 0 && $usercanissuepayment && (($object->type != Facture::TYPE_CREDIT_NOTE && $object->type != Facture::TYPE_DEPOSIT && $resteapayer <= 0) || ($object->type == Facture::TYPE_CREDIT_NOTE && $resteapayer >= 0))) + if (($object->statut == Facture::STATUS_VALIDATED && $object->paye == 0 && $usercanissuepayment && (($object->type != Facture::TYPE_CREDIT_NOTE && $object->type != Facture::TYPE_DEPOSIT && $resteapayer <= 0) || ($object->type == Facture::TYPE_CREDIT_NOTE && $resteapayer >= 0))) || ($object->type == Facture::TYPE_DEPOSIT && $object->paye == 0 && $object->total_ttc > 0 && $resteapayer == 0 && $usercanissuepayment && empty($discount->id)) ) { @@ -5120,7 +5121,7 @@ elseif ($id > 0 || !empty($ref)) // Classify 'closed not completely paid' (possible si validee et pas encore classee payee) - if ($object->statut == 1 && $object->paye == 0 && $resteapayer > 0 && $usercanissuepayment) + if ($object->statut == Facture::STATUS_VALIDATED && $object->paye == 0 && $resteapayer > 0 && $usercanissuepayment) { if ($totalpaye > 0 || $totalcreditnotes > 0) { diff --git a/htdocs/compta/facture/class/facture.class.php b/htdocs/compta/facture/class/facture.class.php index b123bf5cab4..8c198b58a3e 100644 --- a/htdocs/compta/facture/class/facture.class.php +++ b/htdocs/compta/facture/class/facture.class.php @@ -221,6 +221,102 @@ class Facture extends CommonInvoice */ public $retained_warranty_fk_cond_reglement; + + /** + * 'type' if the field format ('integer', 'integer:ObjectClass:PathToClass[:AddCreateButtonOrNot[:Filter]]', 'varchar(x)', 'double(24,8)', 'real', 'price', 'text', 'html', 'date', 'datetime', 'timestamp', 'duration', 'mail', 'phone', 'url', 'password') + * Note: Filter can be a string like "(t.ref:like:'SO-%') or (t.date_creation:<:'20160101') or (t.nature:is:NULL)" + * 'label' the translation key. + * 'enabled' is a condition when the field must be managed. + * 'position' is the sort order of field. + * 'notnull' is set to 1 if not null in database. Set to -1 if we must set data to null if empty ('' or 0). + * 'visible' says if field is visible in list (Examples: 0=Not visible, 1=Visible on list and create/update/view forms, 2=Visible on list only, 3=Visible on create/update/view form only (not list), 4=Visible on list and update/view form only (not create). 5=Visible on list and view only (not create/not update). Using a negative value means field is not shown by default on list but can be selected for viewing) + * 'noteditable' says if field is not editable (1 or 0) + * 'default' is a default value for creation (can still be overwrote by the Setup of Default Values if field is editable in creation form). Note: If default is set to '(PROV)' and field is 'ref', the default value will be set to '(PROVid)' where id is rowid when a new record is created. + * 'index' if we want an index in database. + * 'foreignkey'=>'tablename.field' if the field is a foreign key (it is recommanded to name the field fk_...). + * 'searchall' is 1 if we want to search in this field when making a search from the quick search button. + * 'isameasure' must be set to 1 if you want to have a total on list for this field. Field type must be summable like integer or double(24,8). + * 'css' is the CSS style to use on field. For example: 'maxwidth200' + * 'help' is a string visible as a tooltip on field + * 'showoncombobox' if value of the field must be visible into the label of the combobox that list record + * 'disabled' is 1 if we want to have the field locked by a 'disabled' attribute. In most cases, this is never set into the definition of $fields into class, but is set dynamically by some part of code. + * 'arraykeyval' to set list of value if type is a list of predefined values. For example: array("0"=>"Draft","1"=>"Active","-1"=>"Cancel") + * 'comment' is not used. You can store here any text of your choice. It is not used by application. + * + * Note: To have value dynamic, you can set value to 0 in definition and edit the value on the fly into the constructor. + */ + + // BEGIN MODULEBUILDER PROPERTIES + /** + * @var array Array with all fields and their property. Do not use it as a static var. It may be modified by constructor. + */ + public $fields = array( + 'rowid' =>array('type'=>'integer', 'label'=>'TechnicalID', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>10), + 'ref' =>array('type'=>'varchar(30)', 'label'=>'Ref', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'showoncombobox'=>1, 'position'=>15), + 'entity' =>array('type'=>'integer', 'label'=>'Entity', 'default'=>1, 'enabled'=>1, 'visible'=>-2, 'notnull'=>1, 'position'=>20, 'index'=>1), + 'ref_ext' =>array('type'=>'varchar(255)', 'label'=>'Ref ext', 'enabled'=>1, 'visible'=>0, 'position'=>25), + 'ref_int' =>array('type'=>'varchar(255)', 'label'=>'Ref int', 'enabled'=>1, 'visible'=>0, 'position'=>30), + 'type' =>array('type'=>'smallint(6)', 'label'=>'Type', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>35), + 'ref_client' =>array('type'=>'varchar(255)', 'label'=>'Ref client', 'enabled'=>1, 'visible'=>-1, 'position'=>40), + 'increment' =>array('type'=>'varchar(10)', 'label'=>'Increment', 'enabled'=>1, 'visible'=>-1, 'position'=>45), + 'fk_soc' =>array('type'=>'integer:Societe:societe/class/societe.class.php', 'label'=>'ThirdParty', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>50), + 'datec' =>array('type'=>'datetime', 'label'=>'DateCreation', 'enabled'=>1, 'visible'=>-1, 'position'=>55), + 'datef' =>array('type'=>'date', 'label'=>'DateInvoice', 'enabled'=>1, 'visible'=>-1, 'position'=>60), + 'date_valid' =>array('type'=>'date', 'label'=>'DateValidation', 'enabled'=>1, 'visible'=>-1, 'position'=>65), + 'date_closing' =>array('type'=>'datetime', 'label'=>'Date closing', 'enabled'=>1, 'visible'=>-1, 'position'=>70), + 'tms' =>array('type'=>'timestamp', 'label'=>'DateModification', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>75), + 'paye' =>array('type'=>'smallint(6)', 'label'=>'InvoicePaidCompletely', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>80), + //'amount' =>array('type'=>'double(24,8)', 'label'=>'Amount', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>85), + 'remise_percent' =>array('type'=>'double', 'label'=>'Remise percent', 'enabled'=>1, 'visible'=>-1, 'position'=>90), + 'remise_absolue' =>array('type'=>'double', 'label'=>'Remise absolue', 'enabled'=>1, 'visible'=>-1, 'position'=>95), + 'remise' =>array('type'=>'double', 'label'=>'Remise', 'enabled'=>1, 'visible'=>-1, 'position'=>100), + 'close_code' =>array('type'=>'varchar(16)', 'label'=>'EarlyClosingReason', 'enabled'=>1, 'visible'=>-1, 'position'=>105), + 'close_note' =>array('type'=>'varchar(128)', 'label'=>'EarlyClosingComment', 'enabled'=>1, 'visible'=>-1, 'position'=>110), + 'tva' =>array('type'=>'double(24,8)', 'label'=>'TotalVAT', 'enabled'=>1, 'visible'=>-1, 'position'=>115, 'isameasure'=>1), + 'localtax1' =>array('type'=>'double(24,8)', 'label'=>'Localtax1', 'enabled'=>1, 'visible'=>-1, 'position'=>120, 'isameasure'=>1), + 'localtax2' =>array('type'=>'double(24,8)', 'label'=>'Localtax2', 'enabled'=>1, 'visible'=>-1, 'position'=>125, 'isameasure'=>1), + 'revenuestamp' =>array('type'=>'double(24,8)', 'label'=>'RevenueStamp', 'enabled'=>1, 'visible'=>-1, 'position'=>130, 'isameasure'=>1), + 'total' =>array('type'=>'double(24,8)', 'label'=>'TotalHT', 'enabled'=>1, 'visible'=>-1, 'position'=>135, 'isameasure'=>1), + 'total_ttc' =>array('type'=>'double(24,8)', 'label'=>'TotalTTC', 'enabled'=>1, 'visible'=>-1, 'position'=>140, 'isameasure'=>1), + 'fk_statut' =>array('type'=>'smallint(6)', 'label'=>'Status', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>500, 'arrayofkeyval'=>array(0=>'Draft', 1=>'Validated', 2=>'Paid', 3=>'Abandonned')), + 'fk_user_author' =>array('type'=>'integer:User:user/class/user.class.php', 'label'=>'UserAuthor', 'enabled'=>1, 'visible'=>-1, 'position'=>150), + 'fk_user_modif' =>array('type'=>'integer:User:user/class/user.class.php', 'label'=>'UserModif', 'enabled'=>1, 'visible'=>-2, 'notnull'=>-1, 'position'=>155), + 'fk_user_valid' =>array('type'=>'integer:User:user/class/user.class.php', 'label'=>'UserValidation', 'enabled'=>1, 'visible'=>-1, 'position'=>160), + 'fk_user_closing' =>array('type'=>'integer:User:user/class/user.class.php', 'label'=>'UserClosing', 'enabled'=>1, 'visible'=>-1, 'position'=>165), + 'fk_facture_source' =>array('type'=>'integer', 'label'=>'SourceInvoice', 'enabled'=>1, 'visible'=>-1, 'position'=>170), + 'fk_projet' =>array('type'=>'integer:Project:projet/class/project.class.php:1:fk_statut=1', 'label'=>'Project', 'enabled'=>1, 'visible'=>-1, 'position'=>175), + 'fk_account' =>array('type'=>'integer', 'label'=>'Fk account', 'enabled'=>1, 'visible'=>-1, 'position'=>180), + 'fk_currency' =>array('type'=>'varchar(3)', 'label'=>'CurrencyCode', 'enabled'=>1, 'visible'=>-1, 'position'=>185), + 'fk_cond_reglement' =>array('type'=>'integer', 'label'=>'PaymentTerm', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>190), + 'fk_mode_reglement' =>array('type'=>'integer', 'label'=>'PaymentMode', 'enabled'=>1, 'visible'=>-1, 'position'=>195), + 'date_lim_reglement' =>array('type'=>'date', 'label'=>'DateDue', 'enabled'=>1, 'visible'=>-1, 'position'=>200), + 'note_private' =>array('type'=>'text', 'label'=>'NotePublic', 'enabled'=>1, 'visible'=>0, 'position'=>205), + 'note_public' =>array('type'=>'text', 'label'=>'NotePrivate', 'enabled'=>1, 'visible'=>0, 'position'=>210), + 'model_pdf' =>array('type'=>'varchar(255)', 'label'=>'Model pdf', 'enabled'=>1, 'visible'=>0, 'position'=>215), + 'extraparams' =>array('type'=>'varchar(255)', 'label'=>'Extraparams', 'enabled'=>1, 'visible'=>-1, 'position'=>225), + 'situation_cycle_ref' =>array('type'=>'smallint(6)', 'label'=>'Situation cycle ref', 'enabled'=>'$conf->global->INVOICE_USE_SITUATION', 'visible'=>-1, 'position'=>230), + 'situation_counter' =>array('type'=>'smallint(6)', 'label'=>'Situation counter', 'enabled'=>'$conf->global->INVOICE_USE_SITUATION', 'visible'=>-1, 'position'=>235), + 'situation_final' =>array('type'=>'smallint(6)', 'label'=>'Situation final', 'enabled'=>'empty($conf->global->INVOICE_USE_SITUATION) ? 0 : 1', 'visible'=>-1, 'position'=>240), + 'retained_warranty' =>array('type'=>'double', 'label'=>'Retained warranty', 'enabled'=>'$conf->global->INVOICE_USE_SITUATION_RETAINED_WARRANTY', 'visible'=>-1, 'position'=>245), + 'retained_warranty_date_limit' =>array('type'=>'date', 'label'=>'Retained warranty date limit', 'enabled'=>'$conf->global->INVOICE_USE_SITUATION_RETAINED_WARRANTY', 'visible'=>-1, 'position'=>250), + 'retained_warranty_fk_cond_reglement' =>array('type'=>'integer', 'label'=>'Retained warranty fk cond reglement', 'enabled'=>'$conf->global->INVOICE_USE_SITUATION_RETAINED_WARRANTY', 'visible'=>-1, 'position'=>255), + 'fk_incoterms' =>array('type'=>'integer', 'label'=>'IncotermsCode', 'enabled'=>'$conf->incoterm->enabled', 'visible'=>-1, 'position'=>260), + 'location_incoterms' =>array('type'=>'varchar(255)', 'label'=>'IncotermsLocation', 'enabled'=>'$conf->incoterm->enabled', 'visible'=>-1, 'position'=>265), + 'date_pointoftax' =>array('type'=>'date', 'label'=>'DatePointOfTax', 'enabled'=>'$conf->global->INVOICE_POINTOFTAX_DATE', 'visible'=>-1, 'position'=>270), + 'fk_multicurrency' =>array('type'=>'integer', 'label'=>'MulticurrencyID', 'enabled'=>'$conf->multicurrency->enabled', 'visible'=>-1, 'position'=>275), + 'multicurrency_code' =>array('type'=>'varchar(255)', 'label'=>'MulticurrencyCode', 'enabled'=>'$conf->multicurrency->enabled', 'visible'=>-1, 'position'=>280), + 'multicurrency_tx' =>array('type'=>'double(24,8)', 'label'=>'MulticurrencyRate', 'enabled'=>'$conf->multicurrency->enabled', 'visible'=>-1, 'position'=>285), + 'multicurrency_total_ht' =>array('type'=>'double(24,8)', 'label'=>'Multicurrency total ht', 'enabled'=>'$conf->multicurrency->enabled', 'visible'=>-1, 'position'=>290), + 'multicurrency_total_tva' =>array('type'=>'double(24,8)', 'label'=>'Multicurrency total tva', 'enabled'=>'$conf->multicurrency->enabled', 'visible'=>-1, 'position'=>295), + 'multicurrency_total_ttc' =>array('type'=>'double(24,8)', 'label'=>'Multicurrency total ttc', 'enabled'=>'$conf->multicurrency->enabled', 'visible'=>-1, 'position'=>300), + 'fk_fac_rec_source' =>array('type'=>'integer', 'label'=>'RecurringInvoiceSource', 'enabled'=>1, 'visible'=>-1, 'position'=>305), + 'last_main_doc' =>array('type'=>'varchar(255)', 'label'=>'Last main doc', 'enabled'=>1, 'visible'=>-1, 'position'=>310), + 'module_source' =>array('type'=>'varchar(32)', 'label'=>'POSModule', 'enabled'=>1, 'visible'=>-1, 'position'=>315), + 'pos_source' =>array('type'=>'varchar(32)', 'label'=>'POSTerminal', 'enabled'=>1, 'visible'=>-1, 'position'=>320), + 'import_key' =>array('type'=>'varchar(14)', 'label'=>'ImportId', 'enabled'=>1, 'visible'=>-2, 'position'=>220), + ); + // END MODULEBUILDER PROPERTIES + /** * Standard invoice */ diff --git a/htdocs/contrat/list.php b/htdocs/contrat/list.php index 41834b8d0f6..c32e45c1b42 100644 --- a/htdocs/contrat/list.php +++ b/htdocs/contrat/list.php @@ -705,9 +705,7 @@ while ($i < min($num, $limit)) $nbofsalesrepresentative = count($listsalesrepresentatives); if ($nbofsalesrepresentative > 3) { // We print only number - print ''; print $nbofsalesrepresentative; - print ''; } elseif ($nbofsalesrepresentative > 0) { diff --git a/htdocs/core/actions_massactions.inc.php b/htdocs/core/actions_massactions.inc.php index 4a00412f800..c3f046431b0 100644 --- a/htdocs/core/actions_massactions.inc.php +++ b/htdocs/core/actions_massactions.inc.php @@ -691,11 +691,11 @@ if ($massaction == 'confirm_createbills') // Create bills from orders for ($i = 0; $i < $num; $i++) { - $desc = ($lines[$i]->desc ? $lines[$i]->desc : $lines[$i]->libelle); + $desc = ($lines[$i]->desc ? $lines[$i]->desc : ''); // If we build one invoice for several order, we must put the invoice of order on the line if (!empty($createbills_onebythird)) { - $desc = dol_concatdesc($desc, $langs->trans("Order").' '.$cmd->ref.' - '.dol_print_date($cmd->date, 'day', $langs)); + $desc = dol_concatdesc($desc, $langs->trans("Order").' '.$cmd->ref.' - '.dol_print_date($cmd->date, 'day')); } if ($lines[$i]->subprice < 0) diff --git a/htdocs/core/boxes/box_graph_product_distribution.php b/htdocs/core/boxes/box_graph_product_distribution.php index c61bc2569be..96f0a5ecb78 100644 --- a/htdocs/core/boxes/box_graph_product_distribution.php +++ b/htdocs/core/boxes/box_graph_product_distribution.php @@ -146,6 +146,7 @@ class box_graph_product_distribution extends ModeleBoxes $mode = 'customer'; $stats_invoice = new FactureStats($this->db, $socid, $mode, ($userid > 0 ? $userid : 0)); $data1 = $stats_invoice->getAllByProductEntry($year, (GETPOST('action', 'aZ09') == $refreshaction ?-1 : (3600 * 24))); + if (empty($data1)) { $showpointvalue = 0; @@ -160,7 +161,7 @@ class box_graph_product_distribution extends ModeleBoxes if (!$mesg) { $i = 0; $tot = count($data1); $legend = array(); - while ($i <= $tot) + while ($i < $tot) { $data1[$i][0] = dol_trunc($data1[$i][0], 5); // Required to avoid error "Could not draw pie with labels contained inside canvas" $legend[] = $data1[$i][0]; @@ -218,7 +219,7 @@ class box_graph_product_distribution extends ModeleBoxes if (!$mesg) { $i = 0; $tot = count($data2); $legend = array(); - while ($i <= $tot) + while ($i < $tot) { $data2[$i][0] = dol_trunc($data2[$i][0], 5); // Required to avoid error "Could not draw pie with labels contained inside canvas" $legend[] = $data2[$i][0]; @@ -277,7 +278,7 @@ class box_graph_product_distribution extends ModeleBoxes if (!$mesg) { $i = 0; $tot = count($data3); $legend = array(); - while ($i <= $tot) + while ($i < $tot) { $data3[$i][0] = dol_trunc($data3[$i][0], 5); // Required to avoid error "Could not draw pie with labels contained inside canvas" $legend[] = $data3[$i][0]; diff --git a/htdocs/core/class/commondocgenerator.class.php b/htdocs/core/class/commondocgenerator.class.php index d09bfbade6b..56910b43e4a 100644 --- a/htdocs/core/class/commondocgenerator.class.php +++ b/htdocs/core/class/commondocgenerator.class.php @@ -562,12 +562,12 @@ abstract class CommonDocGenerator 'line_price_ttc_locale'=>price($line->total_ttc, 0, $outputlangs), 'line_price_vat_locale'=>price($line->total_tva, 0, $outputlangs), // Dates - 'line_date_start'=>dol_print_date($line->date_start, 'day', 'tzuser'), - 'line_date_start_locale'=>dol_print_date($line->date_start, 'day', 'tzuser', $outputlangs), - 'line_date_start_rfc'=>dol_print_date($line->date_start, 'dayrfc', 'tzuser'), - 'line_date_end'=>dol_print_date($line->date_end, 'day', 'tzuser'), - 'line_date_end_locale'=>dol_print_date($line->date_end, 'day', 'tzuser', $outputlangs), - 'line_date_end_rfc'=>dol_print_date($line->date_end, 'dayrfc', 'tzuser'), + 'line_date_start'=>dol_print_date($line->date_start, 'day'), + 'line_date_start_locale'=>dol_print_date($line->date_start, 'day', 'tzserver', $outputlangs), + 'line_date_start_rfc'=>dol_print_date($line->date_start, 'dayrfc'), + 'line_date_end'=>dol_print_date($line->date_end, 'day'), + 'line_date_end_locale'=>dol_print_date($line->date_end, 'day', 'tzserver', $outputlangs), + 'line_date_end_rfc'=>dol_print_date($line->date_end, 'dayrfc'), 'line_multicurrency_code' => price2num($line->multicurrency_code), 'line_multicurrency_subprice' => price2num($line->multicurrency_subprice), diff --git a/htdocs/core/class/commonobject.class.php b/htdocs/core/class/commonobject.class.php index 3a7375f7950..f4ae126f096 100644 --- a/htdocs/core/class/commonobject.class.php +++ b/htdocs/core/class/commonobject.class.php @@ -5380,7 +5380,7 @@ abstract class CommonObject // Add field of attribute if ($extrafields->attributes[$this->table_element]['type'][$attributeKey] != 'separate') // Only for other type than separator) { - if ($new_array_options[$key] != '') + if ($new_array_options[$key] != '' || $new_array_options[$key] == '0') { $sql .= ",'".$this->db->escape($new_array_options[$key])."'"; } @@ -5482,7 +5482,7 @@ abstract class CommonObject $this->errors[] = $langs->trans("ExtraFieldHasWrongValue", $attributeLabel); return -1; } - elseif ($value == '') + elseif ($value === '') { $this->array_options["options_".$key] = null; } @@ -5495,7 +5495,7 @@ abstract class CommonObject $this->errors[] = $langs->trans("ExtraFieldHasWrongValue", $attributeLabel); return -1; } - elseif ($value == '') + elseif ($value === '') { $this->array_options["options_".$key] = null; } diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index 7cbcc5f49a7..72f7070588e 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -1882,6 +1882,7 @@ function dol_print_date($time, $format = '', $tzoutput = 'tzserver', $outputlang $format = str_replace('%A', '__A__', $format); } + // Analyze date $reg = array(); if (preg_match('/^([0-9][0-9][0-9][0-9])([0-9][0-9])([0-9][0-9])([0-9][0-9])([0-9][0-9])([0-9][0-9])$/i', $time, $reg)) // Deprecated. Ex: 1970-01-01, 1970-01-01 01:00:00, 19700101010000 diff --git a/htdocs/core/menus/standard/eldy.lib.php b/htdocs/core/menus/standard/eldy.lib.php index f66768b7ffb..298b19c7147 100644 --- a/htdocs/core/menus/standard/eldy.lib.php +++ b/htdocs/core/menus/standard/eldy.lib.php @@ -984,7 +984,7 @@ function print_left_eldy_menu($db, $menu_array_before, $menu_array_after, &$tabM $newmenu->add("/fichinter/card.php?action=create&leftmenu=ficheinter", $langs->trans("NewIntervention"), 1, $user->rights->ficheinter->creer, '', '', '', 201); $newmenu->add("/fichinter/list.php?leftmenu=ficheinter", $langs->trans("List"), 1, $user->rights->ficheinter->lire, '', '', '', 202); if ($conf->global->MAIN_FEATURES_LEVEL >= 2) $newmenu->add("/fichinter/card-rec.php?leftmenu=ficheinter", $langs->trans("ListOfTemplates"), 1, $user->rights->ficheinter->lire, '', '', '', 203); - $newmenu->add("/fichinter/stats/index.php?leftmenu=ficheinter", $langs->trans("Statistics"), 1, $user->rights->fournisseur->commande->lire); + $newmenu->add("/fichinter/stats/index.php?leftmenu=ficheinter", $langs->trans("Statistics"), 1, $user->rights->ficheinter->lire); } } diff --git a/htdocs/core/tpl/objectline_create.tpl.php b/htdocs/core/tpl/objectline_create.tpl.php index 6fd135af821..2fffe30276a 100644 --- a/htdocs/core/tpl/objectline_create.tpl.php +++ b/htdocs/core/tpl/objectline_create.tpl.php @@ -636,11 +636,15 @@ if (!empty($usemargins) && $user->rights->margins->creer) { console.log("We are in a price per qty context, we do not call ajax/product"); } else { + global->PRODUIT_CUSTOMER_PRICES_BY_QTY) || ! empty($conf->global->PRODUIT_CUSTOMER_PRICES_BY_QTY_MULTIPRICES)) { ?> + if (isNaN(pbq)) { console.log("We use experimental option PRODUIT_CUSTOMER_PRICES_BY_QTY or PRODUIT_CUSTOMER_PRICES_BY_QTY but we are not yet able to get the id of pbq from product combo list, so load of price may be 0 if product has differet prices"); } + // Get the HT price for the product and display it - console.log("Load price without tax and set it into #price_ht for id="+$(this).val()+" socid=socid; ?>"); + console.log("Load unit price without tax and set it into #price_ht for product id="+$(this).val()+" socid=socid; ?>"); $.post('/product/ajax/products.php?action=fetch', { 'id': $(this).val(), 'socid': socid; ?> }, function(data) { + console.log("Load unit price end, we got value "+data.price_ht); jQuery("#price_ht").val(data.price_ht); }, 'json' @@ -658,95 +662,96 @@ if (!empty($usemargins) && $user->rights->margins->creer) $("#fournprice_predef").find("option").remove(); $("#fournprice_predef").hide(); $("#buying_price").val("").show(); + /* Call post to load content of combo list fournprice_predef */ $.post('/fourn/ajax/getSupplierPrices.php?bestpricefirst=1', { 'idprod': $(this).val() }, function(data) { - if (data && data.length > 0) - { - var options = ''; var defaultkey = ''; var defaultprice = ''; var bestpricefound = 0; - - var bestpriceid = 0; var bestpricevalue = 0; - var pmppriceid = 0; var pmppricevalue = 0; - var costpriceid = 0; var costpricevalue = 0; - - /* setup of margin calculation */ - var defaultbuyprice = 'global->MARGIN_TYPE)) - { - if ($conf->global->MARGIN_TYPE == '1') print 'bestsupplierprice'; - if ($conf->global->MARGIN_TYPE == 'pmp') print 'pmp'; - if ($conf->global->MARGIN_TYPE == 'costprice') print 'costprice'; - } ?>'; - console.log("we will set the field for margin. defaultbuyprice="+defaultbuyprice); - - var i = 0; - $(data).each(function() { - /* Warning: Lines must be processed in order: best supplier price, then pmpprice line then costprice */ - if (this.id != 'pmpprice' && this.id != 'costprice') + if (data && data.length > 0) { - i++; - this.price = parseFloat(this.price); // to fix when this.price >0 - // If margin is calculated on best supplier price, we set it by defaut (but only if value is not 0) - //console.log("id="+this.id+"-price="+this.price+"-"+(this.price > 0)); - if (bestpricefound == 0 && this.price > 0) { defaultkey = this.id; defaultprice = this.price; bestpriceid = this.id; bestpricevalue = this.price; bestpricefound=1; } // bestpricefound is used to take the first price > 0 - } - if (this.id == 'pmpprice') - { - // If margin is calculated on PMP, we set it by defaut (but only if value is not 0) - console.log("id="+this.id+"-price="+this.price); - if ('pmp' == defaultbuyprice || 'costprice' == defaultbuyprice) + var options = ''; var defaultkey = ''; var defaultprice = ''; var bestpricefound = 0; + + var bestpriceid = 0; var bestpricevalue = 0; + var pmppriceid = 0; var pmppricevalue = 0; + var costpriceid = 0; var costpricevalue = 0; + + /* setup of margin calculation */ + var defaultbuyprice = 'global->MARGIN_TYPE)) { - if (this.price > 0) { - defaultkey = this.id; defaultprice = this.price; pmppriceid = this.id; pmppricevalue = this.price; - //console.log("pmppricevalue="+pmppricevalue); + if ($conf->global->MARGIN_TYPE == '1') print 'bestsupplierprice'; + if ($conf->global->MARGIN_TYPE == 'pmp') print 'pmp'; + if ($conf->global->MARGIN_TYPE == 'costprice') print 'costprice'; + } ?>'; + console.log("we will set the field for margin. defaultbuyprice="+defaultbuyprice); + + var i = 0; + $(data).each(function() { + /* Warning: Lines must be processed in order: best supplier price, then pmpprice line then costprice */ + if (this.id != 'pmpprice' && this.id != 'costprice') + { + i++; + this.price = parseFloat(this.price); // to fix when this.price >0 + // If margin is calculated on best supplier price, we set it by defaut (but only if value is not 0) + //console.log("id="+this.id+"-price="+this.price+"-"+(this.price > 0)); + if (bestpricefound == 0 && this.price > 0) { defaultkey = this.id; defaultprice = this.price; bestpriceid = this.id; bestpricevalue = this.price; bestpricefound=1; } // bestpricefound is used to take the first price > 0 } - } - } - if (this.id == 'costprice') - { - // If margin is calculated on Cost price, we set it by defaut (but only if value is not 0) - console.log("id="+this.id+"-price="+this.price+"-pmppricevalue="+pmppricevalue); - if ('costprice' == defaultbuyprice) + if (this.id == 'pmpprice') + { + // If margin is calculated on PMP, we set it by defaut (but only if value is not 0) + console.log("id="+this.id+"-price="+this.price); + if ('pmp' == defaultbuyprice || 'costprice' == defaultbuyprice) + { + if (this.price > 0) { + defaultkey = this.id; defaultprice = this.price; pmppriceid = this.id; pmppricevalue = this.price; + //console.log("pmppricevalue="+pmppricevalue); + } + } + } + if (this.id == 'costprice') + { + // If margin is calculated on Cost price, we set it by defaut (but only if value is not 0) + console.log("id="+this.id+"-price="+this.price+"-pmppricevalue="+pmppricevalue); + if ('costprice' == defaultbuyprice) + { + if (this.price > 0) { defaultkey = this.id; defaultprice = this.price; costpriceid = this.id; costpricevalue = this.price; } + else if (pmppricevalue > 0) { defaultkey = 'pmpprice'; defaultprice = pmppricevalue; } + } + } + options += ''; + }); + options += ''; + + console.log("finally selected defaultkey="+defaultkey+" defaultprice for buying price="+defaultprice); + + $("#fournprice_predef").html(options).show(); + if (defaultkey != '') { - if (this.price > 0) { defaultkey = this.id; defaultprice = this.price; costpriceid = this.id; costpricevalue = this.price; } - else if (pmppricevalue > 0) { defaultkey = 'pmpprice'; defaultprice = pmppricevalue; } + $("#fournprice_predef").val(defaultkey); } + + /* At loading, no product are yet selected, so we hide field of buying_price */ + $("#buying_price").hide(); + + /* Define default price at loading */ + var defaultprice = $("#fournprice_predef").find('option:selected').attr("price"); + $("#buying_price").val(defaultprice); + + $("#fournprice_predef").change(function() { + console.log("change on fournprice_predef"); + /* Hide field buying_price according to choice into list (if 'inputprice' or not) */ + var linevalue=$(this).find('option:selected').val(); + var pricevalue = $(this).find('option:selected').attr("price"); + if (linevalue != 'inputprice' && linevalue != 'pmpprice') { + $("#buying_price").val(pricevalue).hide(); /* We set value then hide field */ + } + if (linevalue == 'inputprice') { + $('#buying_price').show(); + } + if (linevalue == 'pmpprice') { + $("#buying_price").val(pricevalue); + $('#buying_price').hide(); + } + }); } - options += ''; - }); - options += ''; - - console.log("finally selected defaultkey="+defaultkey+" defaultprice="+defaultprice); - - $("#fournprice_predef").html(options).show(); - if (defaultkey != '') - { - $("#fournprice_predef").val(defaultkey); - } - - /* At loading, no product are yet selected, so we hide field of buying_price */ - $("#buying_price").hide(); - - /* Define default price at loading */ - var defaultprice = $("#fournprice_predef").find('option:selected').attr("price"); - $("#buying_price").val(defaultprice); - - $("#fournprice_predef").change(function() { - console.log("change on fournprice_predef"); - /* Hide field buying_price according to choice into list (if 'inputprice' or not) */ - var linevalue=$(this).find('option:selected').val(); - var pricevalue = $(this).find('option:selected').attr("price"); - if (linevalue != 'inputprice' && linevalue != 'pmpprice') { - $("#buying_price").val(pricevalue).hide(); /* We set value then hide field */ - } - if (linevalue == 'inputprice') { - $('#buying_price').show(); - } - if (linevalue == 'pmpprice') { - $("#buying_price").val(pricevalue); - $('#buying_price').hide(); - } - }); - } }, 'json'); diff --git a/htdocs/expensereport/class/expensereport.class.php b/htdocs/expensereport/class/expensereport.class.php index 869e1b84e90..db46d591816 100644 --- a/htdocs/expensereport/class/expensereport.class.php +++ b/htdocs/expensereport/class/expensereport.class.php @@ -1015,7 +1015,9 @@ class ExpenseReport extends CommonObject public function fetch_lines() { // phpcs:enable - $this->lines = array(); + global $conf; + + $this->lines = array(); $sql = ' SELECT de.rowid, de.comments, de.qty, de.value_unit, de.date, de.rang,'; $sql .= ' de.'.$this->fk_element.', de.fk_c_type_fees, de.fk_c_exp_tax_cat, de.fk_projet as fk_project, de.tva_tx, de.fk_ecm_files,'; diff --git a/htdocs/filefunc.inc.php b/htdocs/filefunc.inc.php index 01245a466cc..e453ef34991 100644 --- a/htdocs/filefunc.inc.php +++ b/htdocs/filefunc.inc.php @@ -31,7 +31,7 @@ */ if (! defined('DOL_APPLICATION_TITLE')) define('DOL_APPLICATION_TITLE', 'Dolibarr'); -if (! defined('DOL_VERSION')) define('DOL_VERSION', '11.0.1'); // a.b.c-alpha, a.b.c-beta, a.b.c-rcX or a.b.c +if (! defined('DOL_VERSION')) define('DOL_VERSION', '11.0.2'); // a.b.c-alpha, a.b.c-beta, a.b.c-rcX or a.b.c if (! defined('EURO')) define('EURO', chr(128)); diff --git a/htdocs/fourn/card.php b/htdocs/fourn/card.php index 9056d1217ca..162a8363917 100644 --- a/htdocs/fourn/card.php +++ b/htdocs/fourn/card.php @@ -808,16 +808,6 @@ if ($object->id > 0) } } - if ($user->rights->fournisseur->facture->creer) - { - $langs->load("bills"); - if ($object->status == 1) { - print ''.$langs->trans("AddBill").''; - } else { - print ''.$langs->trans("AddBill").''; - } - } - if ($user->rights->fournisseur->facture->creer) { if (!empty($orders2invoice) && $orders2invoice > 0) @@ -835,6 +825,16 @@ if ($object->id > 0) else print ''; } + if ($user->rights->fournisseur->facture->creer) + { + $langs->load("bills"); + if ($object->status == 1) { + print ''.$langs->trans("AddBill").''; + } else { + print ''.$langs->trans("AddBill").''; + } + } + // Add action if (!empty($conf->agenda->enabled) && !empty($conf->global->MAIN_REPEATTASKONEACHTAB) && $object->status == 1) { diff --git a/htdocs/install/upgrade2.php b/htdocs/install/upgrade2.php index b5cf6e4c9dd..05eeaba2d5f 100644 --- a/htdocs/install/upgrade2.php +++ b/htdocs/install/upgrade2.php @@ -5070,15 +5070,15 @@ function migrate_members_socialnetworks() print ''; $sql = 'SELECT rowid, socialnetworks'; $sql .= ', skype, twitter, facebook, linkedin, instagram, snapchat, googleplus, youtube, whatsapp FROM '.MAIN_DB_PREFIX.'adherent WHERE '; - $sql .= ' skype IS NOT NULL OR skype!=""'; - $sql .= ' OR twitter IS NOT NULL OR twitter!=""'; - $sql .= ' OR facebook IS NOT NULL OR facebook!=""'; - $sql .= ' OR linkedin IS NOT NULL OR linkedin!=""'; - $sql .= ' OR instagram IS NOT NULL OR instagram!=""'; - $sql .= ' OR snapchat IS NOT NULL OR snapchat!=""'; - $sql .= ' OR googleplus IS NOT NULL OR googleplus!=""'; - $sql .= ' OR youtube IS NOT NULL OR youtube!=""'; - $sql .= ' OR whatsapp IS NOT NULL OR whatsapp!=""'; + $sql .= " skype IS NOT NULL OR skype <> ''"; + $sql .= " OR twitter IS NOT NULL OR twitter <> ''"; + $sql .= " OR facebook IS NOT NULL OR facebook <> ''"; + $sql .= " OR linkedin IS NOT NULL OR linkedin <> ''"; + $sql .= " OR instagram IS NOT NULL OR instagram <> ''"; + $sql .= " OR snapchat IS NOT NULL OR snapchat <> ''"; + $sql .= " OR googleplus IS NOT NULL OR googleplus <> ''"; + $sql .= " OR youtube IS NOT NULL OR youtube <> ''"; + $sql .= " OR whatsapp IS NOT NULL OR whatsapp <> ''"; //print $sql; $resql = $db->query($sql); if ($resql) { @@ -5160,16 +5160,16 @@ function migrate_contacts_socialnetworks() print ''; $sql = 'SELECT rowid, socialnetworks'; $sql .= ', jabberid, skype, twitter, facebook, linkedin, instagram, snapchat, googleplus, youtube, whatsapp FROM '.MAIN_DB_PREFIX.'socpeople WHERE '; - $sql .= ' jabberid IS NOT NULL OR jabberid!=""'; - $sql .= ' OR skype IS NOT NULL OR skype!=""'; - $sql .= ' OR twitter IS NOT NULL OR twitter!=""'; - $sql .= ' OR facebook IS NOT NULL OR facebook!=""'; - $sql .= ' OR linkedin IS NOT NULL OR linkedin!=""'; - $sql .= ' OR instagram IS NOT NULL OR instagram!=""'; - $sql .= ' OR snapchat IS NOT NULL OR snapchat!=""'; - $sql .= ' OR googleplus IS NOT NULL OR googleplus!=""'; - $sql .= ' OR youtube IS NOT NULL OR youtube!=""'; - $sql .= ' OR whatsapp IS NOT NULL OR whatsapp!=""'; + $sql .= " jabberid IS NOT NULL OR jabberid <> ''"; + $sql .= " OR skype IS NOT NULL OR skype <> ''"; + $sql .= " OR twitter IS NOT NULL OR twitter <> ''"; + $sql .= " OR facebook IS NOT NULL OR facebook <> ''"; + $sql .= " OR linkedin IS NOT NULL OR linkedin <> ''"; + $sql .= " OR instagram IS NOT NULL OR instagram <> ''"; + $sql .= " OR snapchat IS NOT NULL OR snapchat <> ''"; + $sql .= " OR googleplus IS NOT NULL OR googleplus <> ''"; + $sql .= " OR youtube IS NOT NULL OR youtube <> ''"; + $sql .= " OR whatsapp IS NOT NULL OR whatsapp <> ''"; //print $sql; $resql = $db->query($sql); if ($resql) { @@ -5255,15 +5255,15 @@ function migrate_thirdparties_socialnetworks() print ''; $sql = 'SELECT rowid, socialnetworks'; $sql .= ', skype, twitter, facebook, linkedin, instagram, snapchat, googleplus, youtube, whatsapp FROM '.MAIN_DB_PREFIX.'societe WHERE '; - $sql .= ' skype IS NOT NULL OR skype!=""'; - $sql .= ' OR twitter IS NOT NULL OR twitter!=""'; - $sql .= ' OR facebook IS NOT NULL OR facebook!=""'; - $sql .= ' OR linkedin IS NOT NULL OR linkedin!=""'; - $sql .= ' OR instagram IS NOT NULL OR instagram!=""'; - $sql .= ' OR snapchat IS NOT NULL OR snapchat!=""'; - $sql .= ' OR googleplus IS NOT NULL OR googleplus!=""'; - $sql .= ' OR youtube IS NOT NULL OR youtube!=""'; - $sql .= ' OR whatsapp IS NOT NULL OR whatsapp!=""'; + $sql .= " skype IS NOT NULL OR skype <> ''"; + $sql .= " OR twitter IS NOT NULL OR twitter <> ''"; + $sql .= " OR facebook IS NOT NULL OR facebook <> ''"; + $sql .= " OR linkedin IS NOT NULL OR linkedin <> ''"; + $sql .= " OR instagram IS NOT NULL OR instagram <> ''"; + $sql .= " OR snapchat IS NOT NULL OR snapchat <> ''"; + $sql .= " OR googleplus IS NOT NULL OR googleplus <> ''"; + $sql .= " OR youtube IS NOT NULL OR youtube <> ''"; + $sql .= " OR whatsapp IS NOT NULL OR whatsapp <> ''"; //print $sql; $resql = $db->query($sql); if ($resql) { diff --git a/htdocs/langs/en_US/errors.lang b/htdocs/langs/en_US/errors.lang index 525131b2a61..c5b61e50ed6 100644 --- a/htdocs/langs/en_US/errors.lang +++ b/htdocs/langs/en_US/errors.lang @@ -117,7 +117,8 @@ ErrorLoginDoesNotExists=User with login %s could not be found. ErrorLoginHasNoEmail=This user has no email address. Process aborted. ErrorBadValueForCode=Bad value for security code. Try again with new value... ErrorBothFieldCantBeNegative=Fields %s and %s can't be both negative -ErrorFieldCantBeNegativeOnInvoice=Field %s cannot be negative on this type of invoice. If you need to add a discount line, just create the discount first (from field '%s' in thirdparty card) and apply it to the invoice. You can also ask your admin to set option FACTURE_ENABLE_NEGATIVE_LINES to 1 to allow the old behaviour. +ErrorFieldCantBeNegativeOnInvoice=Field %s cannot be negative on this type of invoice. If you need to add a discount line, just create the discount first (from field '%s' in thirdparty card) and apply it to the invoice. +ErrorLinesCantBeNegativeForOneVATRate=Total of lines can't be negative for a given VAT rate. ErrorLinesCantBeNegativeOnDeposits=Lines can't be negative in a deposit. You will face problems when you will need to consume the deposit in final invoice if you do so. ErrorQtyForCustomerInvoiceCantBeNegative=Quantity for line into customer invoices can't be negative ErrorWebServerUserHasNotPermission=User account %s used to execute web server has no permission for that diff --git a/htdocs/projet/card.php b/htdocs/projet/card.php index bd14d527c9f..48777ceb1e4 100644 --- a/htdocs/projet/card.php +++ b/htdocs/projet/card.php @@ -545,7 +545,7 @@ if ($action == 'create' && $user->rights->projet->creer) print ''; // Label - print ''.$langs->trans("Label").''; + print ''.$langs->trans("Label").''; // Usage (opp, task, bill time, ...) print ''; @@ -784,7 +784,7 @@ elseif ($object->id > 0) array('type' => 'checkbox', 'name' => 'clone_task_files', 'label' => $langs->trans("CloneTaskFiles"), 'value' => false) ); - print $form->formconfirm($_SERVER["PHP_SELF"]."?id=".$object->id, $langs->trans("CloneProject"), $langs->trans("ConfirmCloneProject"), "confirm_clone", $formquestion, '', 1, 300, 590); + print $form->formconfirm($_SERVER["PHP_SELF"]."?id=".$object->id, $langs->trans("ToClone"), $langs->trans("ConfirmCloneProject"), "confirm_clone", $formquestion, '', 1, 300, 590); } diff --git a/htdocs/projet/contact.php b/htdocs/projet/contact.php index cf94b1a5354..a724a88c7c4 100644 --- a/htdocs/projet/contact.php +++ b/htdocs/projet/contact.php @@ -19,7 +19,7 @@ /** * \file htdocs/projet/contact.php * \ingroup project - * \brief Onglet de gestion des contacts du projet + * \brief List of all contacts of a project */ require '../main.inc.php'; @@ -27,6 +27,7 @@ require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php'; require_once DOL_DOCUMENT_ROOT.'/contact/class/contact.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/project.lib.php'; require_once DOL_DOCUMENT_ROOT.'/core/class/html.formcompany.class.php'; +if ($conf->categorie->enabled) { require_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php'; } // Load translation files required by the page $langs->loadLangs(array('projects', 'companies')); diff --git a/htdocs/projet/list.php b/htdocs/projet/list.php index ef09ade1b91..650c14c5ee2 100644 --- a/htdocs/projet/list.php +++ b/htdocs/projet/list.php @@ -761,9 +761,7 @@ while ($i < min($num, $limit)) $nbofsalesrepresentative = count($listsalesrepresentatives); if ($nbofsalesrepresentative > 3) // We print only number { - print ''; print $nbofsalesrepresentative; - print ''; } elseif ($nbofsalesrepresentative > 0) { diff --git a/htdocs/public/ticket/create_ticket.php b/htdocs/public/ticket/create_ticket.php index 181973912e5..16978e06ee2 100644 --- a/htdocs/public/ticket/create_ticket.php +++ b/htdocs/public/ticket/create_ticket.php @@ -68,11 +68,12 @@ if (GETPOST('addfile', 'alpha') && !GETPOST('add', 'alpha')) { // Set tmp directory TODO Use a dedicated directory for temp mails files $vardir = $conf->ticket->dir_output; - $upload_dir_tmp = $vardir.'/temp'; + $upload_dir_tmp = $vardir.'/temp/'.session_id(); if (!dol_is_dir($upload_dir_tmp)) { dol_mkdir($upload_dir_tmp); } - dol_add_file_process($upload_dir_tmp, 0, 0, 'addedfile'); + + dol_add_file_process($upload_dir_tmp, 0, 0, 'addedfile', '', null, '', 0); $action = 'create_ticket'; ////} } @@ -83,7 +84,7 @@ if (GETPOST('removedfile', 'alpha') && !GETPOST('add', 'alpha')) { // Set tmp directory $vardir = $conf->ticket->dir_output.'/'; - $upload_dir_tmp = $vardir.'/temp'; + $upload_dir_tmp = $vardir.'/temp/'.session_id(); // TODO Delete only files that was uploaded from email form dol_remove_file_process($_POST['removedfile'], 0, 0); @@ -170,7 +171,7 @@ if ($action == 'create_ticket' && GETPOST('add', 'alpha')) { if (!$error && $id > 0) { if ($usertoassign > 0) { - $object->add_contact($usertoassign, "SUPPORTCLI", 'external', $notrigger = 0); + $object->add_contact($usertoassign, "SUPPORTCLI", 'external', 0); } } @@ -304,7 +305,7 @@ if ($action == 'create_ticket' && GETPOST('add', 'alpha')) { } // Copy files into ticket directory - $destdir = $conf->ticket->dir_output.'/'.$object->track_id; + $destdir = $conf->ticket->dir_output.'/'.$object->ref; if (!dol_is_dir($destdir)) { dol_mkdir($destdir); } diff --git a/htdocs/societe/canvas/actions_card_common.class.php b/htdocs/societe/canvas/actions_card_common.class.php index a76e9aa34cb..10cc427afcf 100644 --- a/htdocs/societe/canvas/actions_card_common.class.php +++ b/htdocs/societe/canvas/actions_card_common.class.php @@ -306,9 +306,7 @@ abstract class ActionsCardCommon $nbofsalesrepresentative=count($listsalesrepresentatives); if ($nbofsalesrepresentative > 3) // We print only number { - $this->tpl['sales_representatives'].= ''; $this->tpl['sales_representatives'].= $nbofsalesrepresentative; - $this->tpl['sales_representatives'].= ''; } elseif ($nbofsalesrepresentative > 0) { diff --git a/test/test_serialize.php b/test/test_serialize.php new file mode 100644 index 00000000000..873698e95c2 --- /dev/null +++ b/test/test_serialize.php @@ -0,0 +1,50 @@ +#!/usr/bin/env php +aaa = 'aaa'; +$object->bbb = 'bbb'; +$object->thirdparty = new stdClass(); +$tmp = new Societe($db); +$tmp->name = 'MyBigCompany'; +foreach ($tmp as $key=>$value) +{ + if (!in_array($key, array( + 'name', 'name_alias', 'ref_ext', 'address', 'zip', 'town', 'state_code', 'country_code' + ))) continue; // Discard if not into a dedicated list + if (!is_object($value)) $object->thirdparty->{$key} = $value; +} + + +// Show information +print "\n"; +print "*** PHP Version : ".PHP_VERSION." - Dolibarr Version : ".DOL_VERSION."\n"; + +print "*** print_r() of object used to generate the key to hash for blockedlog on the object sample:\n"; +print print_r($object, true); +print "*** We build hash(256) of this string:\n"; +print hash('sha256', print_r($object, true)); +print "\n"; + +print "*** When it is serialized() to store in db, we got:\n"; +print serialize($object); +print "\n"; + +print "*** And when it is print_r(unserialized()) to reuse it:\n"; +print print_r(unserialize(serialize($object)), true); +print "*** We build hash(256) of this string:\n"; +print hash('sha256', print_r(unserialize(serialize($object)), true)); +print "\n"; + +print "\n"; + +//print print_r(unserialize(serialize($object)));