diff --git a/ChangeLog b/ChangeLog index e70169095be..98339d3874a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -41,6 +41,7 @@ Dolibarr better: - Hooks 'printLeftBlock' and 'formConfirm' are now compliant with hook development rules. They are "addreplace" hooks, so you must return content with "->resprints='mycontent'" and not with "return 'mycontent'" - All fields "fk_societe" were renamed into "fk_soc". +- Method select_PriceBaseType and load_PriceBaseType were merged into selectPriceBaseType ***** ChangeLog for 3.7.1 compared to 3.7.* ***** FIX Bug in the new photo system diff --git a/dev/skeletons/skeleton_page.php b/dev/skeletons/skeleton_page.php index ac329318ae5..9e6d76ee6d8 100644 --- a/dev/skeletons/skeleton_page.php +++ b/dev/skeletons/skeleton_page.php @@ -352,8 +352,9 @@ if ($id && (empty($action) || $action == 'view')) // Example 2 : Adding links to objects - // The class must extends CommonObject class to have this method available - //$somethingshown=$object->showLinkedObjectBlock(); + //$somethingshown=$form->showLinkedObjectBlock($object); + //$linktoelem = $form->showLinkToObjectBlock($object); + //if ($linktoelem) print '
'.$linktoelem; } diff --git a/htdocs/admin/company.php b/htdocs/admin/company.php index 1a75a199dc6..db4c1dff209 100644 --- a/htdocs/admin/company.php +++ b/htdocs/admin/company.php @@ -385,7 +385,7 @@ if ($action == 'edit' || $action == 'updateedit') } else { - print ''; + print ''; } print ''; print ''; @@ -777,7 +777,7 @@ else } else { - print ''; + print ''; } print ''; diff --git a/htdocs/api/class/api_access.class.php b/htdocs/api/class/api_access.class.php index f4aba956817..9cd40f56498 100644 --- a/htdocs/api/class/api_access.class.php +++ b/htdocs/api/class/api_access.class.php @@ -44,6 +44,8 @@ class DolibarrApiAccess implements iAuthenticate */ public static $user = ''; + // @codingStandardsIgnoreStart + /** * Check access * @@ -106,7 +108,6 @@ class DolibarrApiAccess implements iAuthenticate return in_array(static::$role, (array) static::$requires) || static::$role == 'admin'; } - // @codingStandardsIgnoreStart /** * @return string string to be used with WWW-Authenticate header * @example Basic diff --git a/htdocs/cashdesk/admin/cashdesk.php b/htdocs/cashdesk/admin/cashdesk.php index a8ef98b0b0b..48804958b20 100644 --- a/htdocs/cashdesk/admin/cashdesk.php +++ b/htdocs/cashdesk/admin/cashdesk.php @@ -102,7 +102,7 @@ print "\n"; $var=!$var; print ''.$langs->trans("CashDeskThirdPartyForSell").''; print ''; -print $form->select_thirdparty($conf->global->CASHDESK_ID_THIRDPARTY,'socid','s.client in (1,3)',0,array(),1); +print $form->select_company($conf->global->CASHDESK_ID_THIRDPARTY,'socid','s.client in (1,3)',1,0,1,array(),0); print ''; if (! empty($conf->banque->enabled)) { @@ -133,17 +133,17 @@ if (! empty($conf->stock->enabled)) if (empty($conf->productbatch->enabled)) { print $form->selectyesno('CASHDESK_NO_DECREASE_STOCK',$conf->global->CASHDESK_NO_DECREASE_STOCK,1); } - else + else { if (!$conf->global->CASHDESK_NO_DECREASE_STOCK) { $res = dolibarr_set_const($db,"CASHDESK_NO_DECREASE_STOCK",1,'chaine',0,'',$conf->entity); } - print $langs->trans('StockDecreaseForPointOfSaleDisabledbyBatch'); + print $langs->trans('StockDecreaseForPointOfSaleDisabledbyBatch'); } print ''; $disabled=$conf->global->CASHDESK_NO_DECREASE_STOCK; - + $var=!$var; print ''.$langs->trans("CashDeskIdWareHouse").''; // Force warehouse (this is not a default value) print ''; diff --git a/htdocs/categories/class/categorie.class.php b/htdocs/categories/class/categorie.class.php index 36251073028..190f58d9388 100644 --- a/htdocs/categories/class/categorie.class.php +++ b/htdocs/categories/class/categorie.class.php @@ -1215,7 +1215,7 @@ class Categorie extends CommonObject } /** - * Return list of categories (id or instances) linked to element of id $id and type $type + * Return list of categories (object instances or labels) linked to element of id $id and type $type * Should be named getListOfCategForObject * * @param int $id Id of element @@ -1228,20 +1228,15 @@ class Categorie extends CommonObject */ function containing($id,$type,$mode='object') { - // Deprecation warning - if (is_numeric($type)) { - dol_syslog(__METHOD__ . ': using numeric types is deprecated.', LOG_WARNING); - } - $cats = array(); // For backward compatibility - if (is_numeric( $type )) { + if (is_numeric($type)) + { + dol_syslog(__METHOD__ . ': using numeric value for parameter type is deprecated. Use string code instead.', LOG_WARNING); // We want to reverse lookup - $map_type = array_flip( $this->MAP_ID ); + $map_type = array_flip($this->MAP_ID); $type = $map_type[$type]; - dol_syslog( get_class( $this ) . "::containing(): numeric types are deprecated, please use string instead", - LOG_WARNING ); } $sql = "SELECT ct.fk_categorie, c.label"; @@ -1249,7 +1244,6 @@ class Categorie extends CommonObject $sql .= " WHERE ct.fk_categorie = c.rowid AND ct.fk_" . $this->MAP_CAT_FK[$type] . " = " . $id . " AND c.type = " . $this->MAP_ID[$type]; $sql .= " AND c.entity IN (" . getEntity( 'category', 1 ) . ")"; - dol_syslog(get_class($this).'::containing', LOG_DEBUG); $res = $this->db->query($sql); if ($res) { diff --git a/htdocs/comm/action/card.php b/htdocs/comm/action/card.php index 0b75ea73e98..044cf9908ea 100644 --- a/htdocs/comm/action/card.php +++ b/htdocs/comm/action/card.php @@ -215,7 +215,7 @@ if ($action == 'add') $object->duree=((float) (GETPOST('dureehour') * 60) + (float) GETPOST('dureemin')) * 60; $listofuserid=array(); - if (! empty($_SESSION['assignedtouser'])) $listofuserid=json_decode($_SESSION['assignedtouser']); + if (! empty($_SESSION['assignedtouser'])) $listofuserid=json_decode($_SESSION['assignedtouser'], true); $i=0; foreach($listofuserid as $key => $value) { diff --git a/htdocs/comm/askpricesupplier/card.php b/htdocs/comm/askpricesupplier/card.php index 6759ae22196..72654ac3da4 100644 --- a/htdocs/comm/askpricesupplier/card.php +++ b/htdocs/comm/askpricesupplier/card.php @@ -1709,10 +1709,12 @@ if ($action == 'create') $somethingshown = $formfile->show_documents('askpricesupplier', $filename, $filedir, $urlsource, $genallowed, $delallowed, $object->modelpdf, 1, 0, 0, 28, 0, '', 0, '', $soc->default_lang); - /* - * Linked object block - */ - $somethingshown = $object->showLinkedObjectBlock(); + // Linked object block + $somethingshown = $form->showLinkedObjectBlock($object); + + // Show links to link elements + //$linktoelem = $form->showLinkToObjectBlock($object); + //if ($linktoelem) print '
'.$linktoelem; print '
'; diff --git a/htdocs/comm/propal.php b/htdocs/comm/propal.php index ce22d192f81..55b6543c195 100644 --- a/htdocs/comm/propal.php +++ b/htdocs/comm/propal.php @@ -2307,10 +2307,13 @@ if ($action == 'create') $somethingshown = $formfile->show_documents('propal', $filename, $filedir, $urlsource, $genallowed, $delallowed, $object->modelpdf, 1, 0, 0, 28, 0, '', 0, '', $soc->default_lang); - /* - * Linked object block - */ - $somethingshown = $object->showLinkedObjectBlock(); + // Linked object block + $somethingshown = $form->showLinkedObjectBlock($object); + + // Show links to link elements + $linktoelem = $form->showLinkToObjectBlock($object); + if ($linktoelem) print '
'.$linktoelem; + print '
'; // print ''; @@ -2337,7 +2340,7 @@ if ($action == 'create') $ref = dol_sanitizeFileName($object->ref); include_once DOL_DOCUMENT_ROOT . '/core/lib/files.lib.php'; - $fileparams = dol_most_recent_file($conf->propal->dir_output . '/' . $ref, preg_quote($ref, '/')); + $fileparams = dol_most_recent_file($conf->propal->dir_output . '/' . $ref, preg_quote($ref, '/').'([^\-])+'); $file = $fileparams['fullname']; // Define output language @@ -2362,7 +2365,7 @@ if ($action == 'create') dol_print_error($db, $result); exit(); } - $fileparams = dol_most_recent_file($conf->propal->dir_output . '/' . $ref, preg_quote($ref, '/')); + $fileparams = dol_most_recent_file($conf->propal->dir_output . '/' . $ref, preg_quote($ref, '/').'([^\-])+'); $file = $fileparams['fullname']; } diff --git a/htdocs/comm/propal/list.php b/htdocs/comm/propal/list.php index 9fbdb2ffd7e..c8e96919f84 100644 --- a/htdocs/comm/propal/list.php +++ b/htdocs/comm/propal/list.php @@ -56,6 +56,7 @@ $search_refcustomer=GETPOST('search_refcustomer','alpha'); $search_societe=GETPOST('search_societe','alpha'); $search_montant_ht=GETPOST('search_montant_ht','alpha'); $search_author=GETPOST('search_author','alpha'); +$search_product_category=GETPOST('search_product_category','int'); $search_town=GETPOST('search_town','alpha'); $viewstatut=$db->escape(GETPOST('viewstatut')); $object_statut=$db->escape(GETPOST('propal_statut')); @@ -91,6 +92,7 @@ if (GETPOST("button_removefilter") || GETPOST("button_removefilter_x")) // Both $search_societe=''; $search_montant_ht=''; $search_author=''; + $search_product_category=''; $search_town=''; $year=''; $month=''; @@ -145,14 +147,15 @@ if (! $sortorder) $sortorder='DESC'; $limit = $conf->liste_limit; -if (! $sall) $sql = 'SELECT'; -else $sql = 'SELECT DISTINCT'; +$sql = 'SELECT'; +if ($sall || $search_product_category > 0) $sql = 'SELECT DISTINCT'; $sql.= ' s.rowid, s.nom as name, s.town, s.client, s.code_client,'; $sql.= ' p.rowid as propalid, p.note_private, p.total_ht, p.ref, p.ref_client, p.fk_statut, p.fk_user_author, p.datep as dp, p.fin_validite as dfv,'; if (! $user->rights->societe->client->voir && ! $socid) $sql .= " sc.fk_soc, sc.fk_user,"; $sql.= ' u.login'; $sql.= ' FROM '.MAIN_DB_PREFIX.'societe as s, '.MAIN_DB_PREFIX.'propal as p'; -if ($sall) $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'propaldet as pd ON p.rowid=pd.fk_propal'; +if ($sall || $search_product_category > 0) $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'propaldet as pd ON p.rowid=pd.fk_propal'; +if ($search_product_category > 0) $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'categorie_product as cp ON cp.fk_product=pd.fk_product'; $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'user as u ON p.fk_user_author = u.rowid'; // We'll need this table joined to the select in order to filter by sale if ($search_sale > 0 || (! $user->rights->societe->client->voir && ! $socid)) $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; @@ -190,7 +193,8 @@ if ($search_montant_ht != '') if ($sall) { $sql .= natural_search(array('s.nom', 'p.note_private', 'p.note_public', 'pd.description'), $sall); } -if ($socid) $sql.= ' AND s.rowid = '.$socid; +if ($search_product_category > 0) $sql.=" AND cp.fk_categorie = ".$search_product_category; +if ($socid > 0) $sql.= ' AND s.rowid = '.$socid; if ($viewstatut <> '') { $sql.= ' AND p.fk_statut IN ('.$viewstatut.')'; @@ -223,7 +227,7 @@ if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST)) $result = $db->query($sql); $nbtotalofrecords = $db->num_rows($result); } - +//print $sql; $sql.= $db->plimit($limit + 1,$offset); $result=$db->query($sql); @@ -265,15 +269,28 @@ if ($result) if ($user->rights->societe->client->voir || $socid) { $langs->load("commercial"); - $moreforfilter.=$langs->trans('ThirdPartiesOfSaleRepresentative'). ': '; + $moreforfilter.='
'; + $moreforfilter.=$langs->trans('ThirdPartiesOfSaleRepresentative'). ': '; $moreforfilter.=$formother->select_salesrepresentatives($search_sale,'search_sale',$user); - $moreforfilter.='       '; + $moreforfilter.='
'; } // If the user can view prospects other than his' if ($user->rights->societe->client->voir || $socid) { - $moreforfilter.=$langs->trans('LinkedToSpecificUsers'). ': '; + $moreforfilter.='
'; + $moreforfilter.=$langs->trans('LinkedToSpecificUsers'). ': '; $moreforfilter.=$form->select_dolusers($search_user,'search_user',1); + $moreforfilter.='
'; + } + // If the user can view prospects other than his' + if ($conf->categorie->enabled && $user->rights->produit->lire) + { + include_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php'; + $moreforfilter.='
'; + $moreforfilter.=$langs->trans('IncludingProductWithTag'). ': '; + $cate_arbo = $form->select_all_categories(Categorie::TYPE_PRODUCT, null, 'parent', null, null, 1); + $moreforfilter.=$form->selectarray('search_product_category', $cate_arbo, $search_product_category, 1, 0, 0, '', 0, 0, 0, 0, '', 1); + $moreforfilter.='
'; } if (! empty($moreforfilter)) { diff --git a/htdocs/commande/card.php b/htdocs/commande/card.php index fcd96f8c898..cc5251e6592 100644 --- a/htdocs/commande/card.php +++ b/htdocs/commande/card.php @@ -2,7 +2,7 @@ /* Copyright (C) 2003-2006 Rodolphe Quiedeville * Copyright (C) 2004-2014 Laurent Destailleur * Copyright (C) 2005 Marc Barilley / Ocebo - * Copyright (C) 2005-2013 Regis Houssin + * Copyright (C) 2005-2015 Regis Houssin * Copyright (C) 2006 Andre Cianfarani * Copyright (C) 2010-2013 Juanjo Menent * Copyright (C) 2011 Philippe Grand @@ -2305,10 +2305,13 @@ if ($action == 'create' && $user->rights->commande->creer) $delallowed = $user->rights->commande->supprimer; $somethingshown = $formfile->show_documents('commande', $comref, $filedir, $urlsource, $genallowed, $delallowed, $object->modelpdf, 1, 0, 0, 28, 0, '', '', '', $soc->default_lang); - /* - * Linked object block - */ - $somethingshown = $object->showLinkedObjectBlock(); + // Linked object block + $somethingshown = $form->showLinkedObjectBlock($object); + + // Show links to link elements + //$linktoelem = $form->showLinkToObjectBlock($object); + //if ($linktoelem) print '
'.$linktoelem; + print '
'; // print ''; @@ -2331,7 +2334,6 @@ if ($action == 'create' && $user->rights->commande->creer) $ref = dol_sanitizeFileName($object->ref); include_once DOL_DOCUMENT_ROOT . '/core/lib/files.lib.php'; - $fileparams = dol_most_recent_file($conf->commande->dir_output . '/' . $ref, preg_quote($ref, '/')); $file = $fileparams['fullname']; // Define output language @@ -2356,7 +2358,7 @@ if ($action == 'create' && $user->rights->commande->creer) dol_print_error($db, $result); exit(); } - $fileparams = dol_most_recent_file($conf->commande->dir_output . '/' . $ref, preg_quote($ref, '/')); + $fileparams = dol_most_recent_file($conf->commande->dir_output . '/' . $ref, preg_quote($ref, '/').'([^\-])+'); $file = $fileparams['fullname']; } diff --git a/htdocs/compta/facture.php b/htdocs/compta/facture.php index 379d2d2ee5d..6b145ffd4f2 100644 --- a/htdocs/compta/facture.php +++ b/htdocs/compta/facture.php @@ -3,7 +3,7 @@ * Copyright (C) 2004 Eric Seigne * Copyright (C) 2004-2014 Laurent Destailleur * Copyright (C) 2005 Marc Barilley / Ocebo - * Copyright (C) 2005-2012 Regis Houssin + * Copyright (C) 2005-2015 Regis Houssin * Copyright (C) 2006 Andre Cianfarani * Copyright (C) 2010-2015 Juanjo Menent * Copyright (C) 2012-2013 Christophe Battarel @@ -2134,7 +2134,7 @@ if ($action == 'create') print '
'; // Next situation invoice - $opt = $form->load_situation_invoices(GETPOST('originid'), $socid); + $opt = $form->selectSituationInvoices(GETPOST('originid'), $socid); print '
'; $tmp='' . $langs->trans('NoSituations') . '') || (GETPOST('origin') && GETPOST('origin') != 'facture')) $tmp.=' disabled'; @@ -3776,77 +3776,10 @@ if ($action == 'create') $somethingshown = $formfile->numoffiles; // Linked object block - $somethingshown = $object->showLinkedObjectBlock(); + $somethingshown = $form->showLinkedObjectBlock($object); - $linktoelem=''; - - if (! empty($conf->commande->enabled)) - { - $linktoelem.=($linktoelem?'   ':'').'' . $langs->trans('LinkedOrder') . ''; - - print ' - - '; - - print ''; - } - - // Show link to elements + // Show links to link elements + $linktoelem = $form->showLinkToObjectBlock($object,array('order')); if ($linktoelem) print '
'.$linktoelem; // Link for paypal payment @@ -3888,7 +3821,7 @@ if ($action == 'create') $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, '/')); + $fileparams = dol_most_recent_file($conf->facture->dir_output . '/' . $ref, preg_quote($ref, '/').'([^\-])+'); $file = $fileparams['fullname']; // Define output language @@ -3913,7 +3846,7 @@ if ($action == 'create') dol_print_error($db, $result); exit(); } - $fileparams = dol_most_recent_file($conf->facture->dir_output . '/' . $ref, preg_quote($ref, '/')); + $fileparams = dol_most_recent_file($conf->facture->dir_output . '/' . $ref, preg_quote($ref, '/').'([^\-])+'); $file = $fileparams['fullname']; } diff --git a/htdocs/contrat/card.php b/htdocs/contrat/card.php index 192a2d16b17..6bf7dcaeacc 100644 --- a/htdocs/contrat/card.php +++ b/htdocs/contrat/card.php @@ -1871,10 +1871,13 @@ else $somethingshown = $formfile->show_documents('contract', $filename, $filedir, $urlsource, $genallowed, $delallowed, $object->modelpdf, 1, 0, 0, 28, 0, '', 0, '', $soc->default_lang); - /* - * Linked object block - */ - $somethingshown=$object->showLinkedObjectBlock(); + // Linked object block + $somethingshown = $form->showLinkedObjectBlock($object); + + // Show links to link elements + $linktoelem = $form->showLinkToObjectBlock($object); + if ($linktoelem) print '
'.$linktoelem; + print '
'; diff --git a/htdocs/core/actions_extrafields.inc.php b/htdocs/core/actions_extrafields.inc.php index 03d724b9bba..4c5f0b512d2 100644 --- a/htdocs/core/actions_extrafields.inc.php +++ b/htdocs/core/actions_extrafields.inc.php @@ -1,5 +1,5 @@ +/* Copyright (C) 2011-2015 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 @@ -148,7 +148,21 @@ if ($action == 'add') } } - $result=$extrafields->addExtraField($_POST['attrname'],$_POST['label'],$_POST['type'],$_POST['pos'],$extrasize,$elementtype,(GETPOST('unique')?1:0),(GETPOST('required')?1:0),$default_value,$params,(GETPOST('alwayseditable')?1:0)); + $result=$extrafields->addExtraField( + GETPOST('attrname'), + GETPOST('label'), + GETPOST('type'), + GETPOST('pos'), + $extrasize, + $elementtype, + (GETPOST('unique')?1:0), + (GETPOST('required')?1:0), + $default_value, + $params, + (GETPOST('alwayseditable')?1:0), + (GETPOST('perms')?GETPOST('perms'):''), + (GETPOST('list')?1:0) + ); if ($result > 0) { setEventMessage($langs->trans('SetupSaved')); @@ -285,7 +299,20 @@ if ($action == 'update') $params['options'][$key] = $value; } } - $result=$extrafields->update($_POST['attrname'],$_POST['label'],$_POST['type'],$extrasize,$elementtype,(GETPOST('unique')?1:0),(GETPOST('required')?1:0),$pos,$params,(GETPOST('alwayseditable')?1:0)); + $result=$extrafields->update( + GETPOST('attrname'), + GETPOST('label'), + GETPOST('type'), + $extrasize, + $elementtype, + (GETPOST('unique')?1:0), + (GETPOST('required')?1:0), + $pos, + $params, + (GETPOST('alwayseditable')?1:0), + (GETPOST('perms')?GETPOST('perms'):''), + (GETPOST('list')?1:0) + ); if ($result > 0) { setEventMessage($langs->trans('SetupSaved')); diff --git a/htdocs/core/class/CMailFile.class.php b/htdocs/core/class/CMailFile.class.php index 6e41384dbce..1aadc47b79e 100644 --- a/htdocs/core/class/CMailFile.class.php +++ b/htdocs/core/class/CMailFile.class.php @@ -37,7 +37,7 @@ class CMailFile { var $subject; // Topic: Subject of email - var $addr_from; // From: Label and EMail of sender (must include '<>'). For example '' or 'John Doe ' or '') + var $addr_from; // From: Label and EMail of sender (must include '<>'). For example '' or 'John Doe ' or '') // Sender: Who send the email ("Sender" has sent emails on behalf of "From"). // Use it when the "From" is an email of a domain that is a SPF protected domain, and sending smtp server is not this domain. In such case, use for Sender an email of the protected domain. // Return-Path: Email where to send bounds. @@ -387,7 +387,7 @@ class CMailFile // If Windows, sendmail_from must be defined if (isset($_SERVER["WINDIR"])) { - if (empty($this->addr_from)) $this->addr_from = 'robot@mydomain.com'; + if (empty($this->addr_from)) $this->addr_from = 'robot@example.com'; @ini_set('sendmail_from',$this->getValidAddress($this->addr_from,2)); } diff --git a/htdocs/core/class/commonobject.class.php b/htdocs/core/class/commonobject.class.php index 4c511726979..8ae7332fc6e 100644 --- a/htdocs/core/class/commonobject.class.php +++ b/htdocs/core/class/commonobject.class.php @@ -135,8 +135,8 @@ abstract class CommonObject $sql = "SELECT rowid, ref, ref_ext"; $sql.= " FROM ".MAIN_DB_PREFIX.$element; - $sql.= " WHERE entity IN (".getEntity($element).")" ; - + $sql.= " WHERE entity IN (".getEntity($element).")" ; + if ($id > 0) $sql.= " AND rowid = ".$db->escape($id); else if ($ref) $sql.= " AND ref = '".$db->escape($ref)."'"; else if ($ref_ext) $sql.= " AND ref_ext = '".$db->escape($ref_ext)."'"; @@ -2580,88 +2580,19 @@ abstract class CommonObject // TODO: All functions here must be redesigned and moved as they are not business functions but output functions // -------------------- - /* This is to show linked object block */ - /** - * Show linked object block - * TODO Move this into html.class.php - * But for the moment we don't know if it's possible as we keep a method available on overloaded objects. + * Show linked object block. * - * @return int + * @return int <0 if KO, >0 if OK + * @deprecated 3.8 Use instead $form->shoLinkedObjectBlock($object) */ function showLinkedObjectBlock() { - global $conf,$langs,$hookmanager; - global $bc; - - $this->fetchObjectLinked(); - - // Bypass the default method - $hookmanager->initHooks(array('commonobject')); - $parameters=array(); - $reshook=$hookmanager->executeHooks('showLinkedObjectBlock',$parameters,$this,$action); // Note that $action and $object may have been modified by hook - - if (empty($reshook)) - { - $num = count($this->linkedObjects); - - foreach($this->linkedObjects as $objecttype => $objects) - { - $tplpath = $element = $subelement = $objecttype; - - if (preg_match('/^([^_]+)_([^_]+)/i',$objecttype,$regs)) - { - $element = $regs[1]; - $subelement = $regs[2]; - $tplpath = $element.'/'.$subelement; - } - - // To work with non standard path - if ($objecttype == 'facture') { - $tplpath = 'compta/'.$element; - if (empty($conf->facture->enabled)) continue; // Do not show if module disabled - } - else if ($objecttype == 'propal') { - $tplpath = 'comm/'.$element; - if (empty($conf->propal->enabled)) continue; // Do not show if module disabled - } - else if ($objecttype == 'askpricesupplier') { - $tplpath = 'comm/'.$element; - if (empty($conf->askpricesupplier->enabled)) continue; // Do not show if module disabled - } - else if ($objecttype == 'shipping' || $objecttype == 'shipment') { - $tplpath = 'expedition'; - if (empty($conf->expedition->enabled)) continue; // Do not show if module disabled - } - else if ($objecttype == 'delivery') { - $tplpath = 'livraison'; - if (empty($conf->expedition->enabled)) continue; // Do not show if module disabled - } - else if ($objecttype == 'invoice_supplier') { - $tplpath = 'fourn/facture'; - } - else if ($objecttype == 'order_supplier') { - $tplpath = 'fourn/commande'; - } - - global $linkedObjectBlock; - $linkedObjectBlock = $objects; - - // Output template part (modules that overwrite templates must declare this into descriptor) - $dirtpls=array_merge($conf->modules_parts['tpl'],array('/'.$tplpath.'/tpl')); - foreach($dirtpls as $reldir) - { - $res=@include dol_buildpath($reldir.'/linkedobjectblock.tpl.php'); - if ($res) break; - } - } - - return $num; - } + global $form; + return $form->showLinkedObjectBlock($this); } - /* This is to show add lines */ /** @@ -3108,222 +3039,18 @@ abstract class CommonObject } - /** - * get Margin info - * - * @param boolean $force_price True of not - * @return mixed Array with info - */ - 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 (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 * (1 - $product->fourn_remise_percent / 100); - 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 - $pa = $line->qty * $line->pa_ht; - $pv = $line->qty * $line->subprice * (1 - $line->remise_percent / 100); - if ($conf->global->MARGIN_METHODE_FOR_DISCOUNT == '1') { // remise globale considérée comme produit - $marginInfos['pa_products'] += $pa; - $marginInfos['pv_products'] += $pv; - $marginInfos['pa_total'] += $pa; - $marginInfos['pv_total'] += $pv; - // if credit note, margin = -1 * (abs(selling_price) - buying_price) - if ($pv < 0) - $marginInfos['margin_on_products'] += -1 * (abs($pv) - $pa); - else - $marginInfos['margin_on_products'] += $pv - $pa; - } - elseif ($conf->global->MARGIN_METHODE_FOR_DISCOUNT == '2') { // remise globale considérée comme service - $marginInfos['pa_services'] += $pa; - $marginInfos['pv_services'] += $pv; - $marginInfos['pa_total'] += $pa; - $marginInfos['pv_total'] += $pv; - // if credit note, margin = -1 * (abs(selling_price) - buying_price) - if ($pv < 0) - $marginInfos['margin_on_services'] += -1 * (abs($pv) - $pa); - else - $marginInfos['margin_on_services'] += $pv - $pa; - } - elseif ($conf->global->MARGIN_METHODE_FOR_DISCOUNT == '3') { // remise globale prise en compte uniqt sur total - $marginInfos['pa_total'] += $pa; - $marginInfos['pv_total'] += $pv; - } - } - else { - $type=$line->product_type?$line->product_type:$line->fk_product_type; - if ($type == 0) { // product - $pa = $line->qty * $line->pa_ht; - $pv = $line->qty * $line->subprice * (1 - $line->remise_percent / 100); - $marginInfos['pa_products'] += $pa; - $marginInfos['pv_products'] += $pv; - $marginInfos['pa_total'] += $pa; - $marginInfos['pv_total'] += $pv; - // if credit note, margin = -1 * (abs(selling_price) - buying_price) - if ($pv < 0) - $marginInfos['margin_on_products'] += -1 * (abs($pv) - $pa); - else - $marginInfos['margin_on_products'] += $pv - $pa; - } - elseif ($type == 1) { // service - $pa = $line->qty * $line->pa_ht; - $pv = $line->qty * $line->subprice * (1 - $line->remise_percent / 100); - $marginInfos['pa_services'] += $pa; - $marginInfos['pv_services'] += $pv; - $marginInfos['pa_total'] += $pa; - $marginInfos['pv_total'] += $pv; - // if credit note, margin = -1 * (abs(selling_price) - buying_price) - if ($pv < 0) - $marginInfos['margin_on_services'] += -1 * (abs($pv) - $pa); - else - $marginInfos['margin_on_services'] += $pv - $pa; - } - } - } - if ($marginInfos['pa_products'] > 0) - $marginInfos['margin_rate_products'] = 100 * $marginInfos['margin_on_products'] / $marginInfos['pa_products']; - if ($marginInfos['pv_products'] > 0) - $marginInfos['mark_rate_products'] = 100 * $marginInfos['margin_on_products'] / $marginInfos['pv_products']; - - if ($marginInfos['pa_services'] > 0) - $marginInfos['margin_rate_services'] = 100 * $marginInfos['margin_on_services'] / $marginInfos['pa_services']; - if ($marginInfos['pv_services'] > 0) - $marginInfos['mark_rate_services'] = 100 * $marginInfos['margin_on_services'] / $marginInfos['pv_services']; - - // if credit note, margin = -1 * (abs(selling_price) - buying_price) - if ($marginInfos['pv_total'] < 0) - $marginInfos['total_margin'] = -1 * (abs($marginInfos['pv_total']) - $marginInfos['pa_total']); - else - $marginInfos['total_margin'] = $marginInfos['pv_total'] - $marginInfos['pa_total']; - if ($marginInfos['pa_total'] > 0) - $marginInfos['total_margin_rate'] = 100 * $marginInfos['total_margin'] / $marginInfos['pa_total']; - if ($marginInfos['pv_total'] > 0) - $marginInfos['total_mark_rate'] = 100 * $marginInfos['total_margin'] / $marginInfos['pv_total']; - - return $marginInfos; - } - /** * Show the array with all margin infos * - * @param boolean $force_price Force price - * @return void + * @param boolean $force_price Force price + * @return void + * @deprecated 3.8 Load FormMargin class and make a direct call to displayMarginInfos */ function displayMarginInfos($force_price=false) { - global $langs, $conf, $user; - - if (! empty($user->societe_id)) return; - - if (! $user->rights->margins->liretous) return; - - $rounding = min($conf->global->MAIN_MAX_DECIMALS_UNIT, $conf->global->MAIN_MAX_DECIMALS_TOT); - - $marginInfo = $this->getMarginInfos($force_price); - - if (! empty($conf->global->MARGIN_ADD_SHOWHIDE_BUTTON)) // TODO Warning this feature rely on an external js file that may be removed. Using native js function document.cookie should be better - { - print $langs->trans('ShowMarginInfos').' : '; - $hidemargininfos = $_COOKIE['DOLUSER_MARGININFO_HIDE_SHOW']; - print ''.img_picto($langs->trans("Disabled"),'switch_off').''; - print ''.img_picto($langs->trans("Enabled"),'switch_on').''; - - print ''; - if (!empty($hidemargininfos)) print ''; - } - - 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 (! empty($conf->product->enabled)) - { - //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 ''; - } - - if (! empty($conf->service->enabled)) - { - print ''; - print ''; - print ''; - print ''; - print ''; - if (! empty($conf->global->DISPLAY_MARGIN_RATES)) - print ''; - if (! empty($conf->global->DISPLAY_MARK_RATES)) - print ''; - print ''; - } - - if (! empty($conf->product->enabled) && ! empty($conf->service->enabled)) - { - 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'], null, null, null, null, $rounding).''.price($marginInfo['pa_products'], null, null, null, null, $rounding).''.price($marginInfo['margin_on_products'], null, null, null, null, $rounding).''.(($marginInfo['margin_rate_products'] == '')?'':price($marginInfo['margin_rate_products'], null, null, null, null, $rounding).'%').''.(($marginInfo['mark_rate_products'] == '')?'':price($marginInfo['mark_rate_products'], null, null, null, null, $rounding).'%').'
'.$langs->trans('MarginOnServices').''.price($marginInfo['pv_services'], null, null, null, null, $rounding).''.price($marginInfo['pa_services'], null, null, null, null, $rounding).''.price($marginInfo['margin_on_services'], null, null, null, null, $rounding).''.(($marginInfo['margin_rate_services'] == '')?'':price($marginInfo['margin_rate_services'], null, null, null, null, $rounding).'%').''.(($marginInfo['mark_rate_services'] == '')?'':price($marginInfo['mark_rate_services'], null, null, null, null, $rounding).'%').'
'.$langs->trans('TotalMargin').''.price($marginInfo['pv_total'], null, null, null, null, $rounding).''.price($marginInfo['pa_total'], null, null, null, null, $rounding).''.price($marginInfo['total_margin'], null, null, null, null, $rounding).''.(($marginInfo['total_margin_rate'] == '')?'':price($marginInfo['total_margin_rate'], null, null, null, null, $rounding).'%').''.(($marginInfo['total_mark_rate'] == '')?'':price($marginInfo['total_mark_rate'], null, null, null, null, $rounding).'%').'
'; + include_once DOL_DOCUMENT_ROOT.'/core/class/html.formmargin.class.php'; + $formmargin=new FormMargin($this->db); + $formmargin->displayMarginInfos($this, $force_price); } diff --git a/htdocs/core/class/conf.class.php b/htdocs/core/class/conf.class.php index 6370062a6a9..13d2881563f 100644 --- a/htdocs/core/class/conf.class.php +++ b/htdocs/core/class/conf.class.php @@ -404,7 +404,7 @@ class Conf $this->css = "/theme/".$this->theme."/style.css.php"; // conf->email_from = email pour envoi par dolibarr des mails automatiques - $this->email_from = "robot@domain.com"; + $this->email_from = "robot@example.com"; if (! empty($this->global->MAIN_MAIL_EMAIL_FROM)) $this->email_from = $this->global->MAIN_MAIL_EMAIL_FROM; // conf->notification->email_from = email pour envoi par Dolibarr des notifications diff --git a/htdocs/core/class/html.form.class.php b/htdocs/core/class/html.form.class.php index bdb4f57a4cc..c236df18199 100644 --- a/htdocs/core/class/html.form.class.php +++ b/htdocs/core/class/html.form.class.php @@ -41,6 +41,8 @@ /** * Class to manage generation of HTML components * Only common components must be here. + * + * TODO Merge all function load_cache_* and loadCache* (except load_cache_vatrates) into one generic function loadCacheTable */ class Form { @@ -101,7 +103,7 @@ class Form } } else - { + { $ret.=''; @@ -497,7 +499,7 @@ class Form $sql = "SELECT rowid, code as code_iso, code_iso as code_iso3, label, favorite"; $sql.= " FROM ".MAIN_DB_PREFIX."c_country"; - $sql.= " WHERE active = 1"; + $sql.= " WHERE active > 0"; //$sql.= " ORDER BY code ASC"; dol_syslog(get_class($this)."::select_country", LOG_DEBUG); @@ -585,7 +587,7 @@ class Form $sql = "SELECT rowid, code"; $sql.= " FROM ".MAIN_DB_PREFIX."c_incoterms"; - $sql.= " WHERE active = 1"; + $sql.= " WHERE active > 0"; $sql.= " ORDER BY code ASC"; dol_syslog(get_class($this)."::select_incoterm", LOG_DEBUG); @@ -712,22 +714,23 @@ class Form /** * Load into cache cache_types_fees, array of types of fees * - * @return int Nb of lines loaded, 0 if already loaded, <0 if ko - * TODO move in DAO class + * @return int Nb of lines loaded, <0 if KO */ function load_cache_types_fees() { global $langs; - $langs->load("trips"); + $num = count($this->cache_types_fees); + if ($num > 0) return 0; // Cache already loaded - if (count($this->cache_types_fees)) return 0; // Cache already load + dol_syslog(__METHOD__, LOG_DEBUG); + + $langs->load("trips"); $sql = "SELECT c.code, c.label"; $sql.= " FROM ".MAIN_DB_PREFIX."c_type_fees as c"; - //$sql.= " ORDER BY c.label ASC"; // No sort here, sort must be done after translation + $sql.= " WHERE active > 0"; - dol_syslog(get_class($this).'::load_cache_types_fees', LOG_DEBUG); $resql=$this->db->query($sql); if ($resql) { @@ -749,7 +752,7 @@ class Form return $num; } else - { + { dol_print_error($this->db); return -1; } @@ -767,7 +770,7 @@ class Form { global $user, $langs; - dol_syslog(get_class($this)."::select_type_fees ".$selected.", ".$htmlname, LOG_DEBUG); + dol_syslog(__METHOD__." selected=".$selected.", htmlname=".$htmlname, LOG_DEBUG); $this->load_cache_types_fees(); @@ -803,11 +806,28 @@ class Form * @param array $ajaxoptions Options for ajax_autocompleter * @param int $forcecombo Force to use combo box * @return string Return select box for thirdparty. + * @deprecated 3.8 Use select_company instead. For exemple $form->select_thirdparty(GETPOST('socid'),'socid','',0) => $form->select_company(GETPOST('socid'),'socid','',1,0,0,array(),0) */ function select_thirdparty($selected='', $htmlname='socid', $filter='', $limit=20, $ajaxoptions=array(), $forcecombo=0) { - global $langs,$conf; + return $this->select_thirdparty_list($selected,$htmlname,$filter,1,0,$forcecombo,array(),'',0,$limit); + } + /** + * Output html form to select a third party + * + * @param string $selected Preselected type + * @param string $htmlname Name of field in form + * @param string $filter optional filters criteras (example: 's.rowid <> x') + * @param int $showempty Add an empty field + * @param int $showtype Show third party type in combolist (customer, prospect or supplier) + * @param int $forcecombo Force to use combo box + * @param array $events Ajax event options to run on change. Example: array(array('method'=>'getContacts', 'url'=>dol_buildpath('/core/ajax/contacts.php',1), 'htmlname'=>'contactid', 'params'=>array('add-customer-contact'=>'disabled'))) + * @param int $limit Maximum number of elements + * @return string HTML string with select box for thirdparty. + */ + function select_company($selected='', $htmlname='socid', $filter='', $showempty=0, $showtype=0, $forcecombo=0, $events=array(), $limit=0) + { $out=''; /* TODO Use ajax_autocompleter like for products (not finished) @@ -840,32 +860,12 @@ class Form } else {*/ - $out.=$this->select_thirdparty_list($selected,$htmlname,$filter,1,0,$forcecombo,array(),'',0,$limit); + $out.=$this->select_thirdparty_list($selected, $htmlname, $filter, $showempty, $showtype, $forcecombo, $events, '', 0, $limit); //} return $out; } - /** - * Output html form to select a third party - * - * @param string $selected Preselected type - * @param string $htmlname Name of field in form - * @param string $filter optional filters criteras (example: 's.rowid <> x') - * @param int $showempty Add an empty field - * @param int $showtype Show third party type in combolist (customer, prospect or supplier) - * @param int $forcecombo Force to use combo box - * @param array $events Event options to run on change. Example: array(array('method'=>'getContacts', 'url'=>dol_buildpath('/core/ajax/contacts.php',1), 'htmlname'=>'contactid', 'params'=>array('add-customer-contact'=>'disabled'))) - * @param int $limit Maximum number of elements - * @return string HTML string with - * @deprecated Use select_thirdparty instead - * @see select_thirdparty() - */ - function select_company($selected='', $htmlname='socid', $filter='', $showempty=0, $showtype=0, $forcecombo=0, $events=array(), $limit=0) - { - return $this->select_thirdparty_list($selected, $htmlname, $filter, $showempty, $showtype, $forcecombo, $events, '', 0, $limit); - } - /** * Output html form to select a third party * @@ -896,7 +896,7 @@ class Form if (! empty($user->societe_id)) $sql.= " AND s.rowid = ".$user->societe_id; if ($filter) $sql.= " AND (".$filter.")"; if (!$user->rights->societe->client->voir && !$user->societe_id) $sql.= " AND s.rowid = sc.fk_soc AND sc.fk_user = " .$user->id; - if (! empty($conf->global->COMPANY_HIDE_INACTIVE_IN_COMBOBOX)) $sql.= " AND s.status<>0 "; + if (! empty($conf->global->COMPANY_HIDE_INACTIVE_IN_COMBOBOX)) $sql.= " AND s.status <> 0"; // Add criteria if ($filterkey && $filterkey != '') { @@ -1123,7 +1123,7 @@ class Form if ($showsoc > 0) $sql.= " LEFT OUTER JOIN ".MAIN_DB_PREFIX ."societe as s ON s.rowid=sp.fk_soc"; $sql.= " WHERE sp.entity IN (".getEntity('societe', 1).")"; if ($socid > 0) $sql.= " AND sp.fk_soc=".$socid; - if (! empty($conf->global->CONTACT_HIDE_INACTIVE_IN_COMBOBOX)) $sql.= " AND sp.statut<>0"; + if (! empty($conf->global->CONTACT_HIDE_INACTIVE_IN_COMBOBOX)) $sql.= " AND sp.statut <> 0"; $sql.= " ORDER BY sp.lastname ASC"; dol_syslog(get_class($this)."::select_contacts", LOG_DEBUG); @@ -2324,19 +2324,22 @@ class Form /** * Charge dans cache la liste des conditions de paiements possibles * - * @return int Nb lignes chargees, 0 si deja chargees, <0 si ko + * @return int Nb of lines loaded, <0 if KO */ function load_cache_conditions_paiements() { global $langs; - if (count($this->cache_conditions_paiements)) return 0; // Cache deja charge + $num = count($this->cache_conditions_paiements); + if ($num > 0) return 0; // Cache already loaded - $sql = "SELECT rowid, code, libelle"; + dol_syslog(__METHOD__, LOG_DEBUG); + + $sql = "SELECT rowid, code, libelle as label"; $sql.= " FROM ".MAIN_DB_PREFIX.'c_payment_term'; - $sql.= " WHERE active=1"; + $sql.= " WHERE active > 0"; $sql.= " ORDER BY sortorder"; - dol_syslog(get_class($this).'::load_cache_conditions_paiements', LOG_DEBUG); + $resql = $this->db->query($sql); if ($resql) { @@ -2347,14 +2350,18 @@ class Form $obj = $this->db->fetch_object($resql); // Si traduction existe, on l'utilise, sinon on prend le libelle par defaut - $libelle=($langs->trans("PaymentConditionShort".$obj->code)!=("PaymentConditionShort".$obj->code)?$langs->trans("PaymentConditionShort".$obj->code):($obj->libelle!='-'?$obj->libelle:'')); + $label=($langs->trans("PaymentConditionShort".$obj->code)!=("PaymentConditionShort".$obj->code)?$langs->trans("PaymentConditionShort".$obj->code):($obj->label!='-'?$obj->label:'')); $this->cache_conditions_paiements[$obj->rowid]['code'] =$obj->code; - $this->cache_conditions_paiements[$obj->rowid]['label']=$libelle; + $this->cache_conditions_paiements[$obj->rowid]['label']=$label; $i++; } - return 1; + + //$this->cache_conditions_paiements=dol_sort_array($this->cache_conditions_paiements, 'label'); // We use the sortorder + + return $num; } - else { + else + { dol_print_error($this->db); return -1; } @@ -2363,19 +2370,21 @@ class Form /** * Charge dans cache la liste des délais de livraison possibles * - * @return int Nb lignes chargees, 0 si deja chargees, <0 si ko + * @return int Nb of lines loaded, <0 if KO */ function load_cache_availability() { global $langs; - if (count($this->cache_availability)) return 0; // Cache deja charge + $num = count($this->cache_availability); + if ($num > 0) return 0; // Cache already loaded + + dol_syslog(__METHOD__, LOG_DEBUG); $sql = "SELECT rowid, code, label"; $sql.= " FROM ".MAIN_DB_PREFIX.'c_availability'; - $sql.= " WHERE active=1"; - $sql.= " ORDER BY rowid"; - dol_syslog(get_class($this).'::load_cache_availability', LOG_DEBUG); + $sql.= " WHERE active > 0"; + $resql = $this->db->query($sql); if ($resql) { @@ -2391,9 +2400,13 @@ class Form $this->cache_availability[$obj->rowid]['label']=$label; $i++; } - return 1; + + $this->cache_availability = dol_sort_array($this->cache_availability, 'label'); + + return $num; } - else { + else + { dol_print_error($this->db); return -1; } @@ -2414,6 +2427,8 @@ class Form $this->load_cache_availability(); + dol_syslog(__METHOD__." selected=".$selected.", htmlname=".$htmlname, LOG_DEBUG); + print ''; @@ -2607,7 +2631,7 @@ class Form { global $langs,$user; - dol_syslog(get_class($this)."::select_type_paiements ".$selected.", ".$htmlname.", ".$filtertype.", ".$format,LOG_DEBUG); + dol_syslog(__METHOD__." ".$selected.", ".$htmlname.", ".$filtertype.", ".$format, LOG_DEBUG); $filterarray=array(); if ($filtertype == 'CRDT') $filterarray=array(0,2,3); @@ -2647,26 +2671,13 @@ class Form /** - * Selection HT or TTC + * Selection HT or TTC * - * @param string $selected Id pre-selectionne - * @param string $htmlname Nom de la zone select - * @return void + * @param string $selected Id pre-selectionne + * @param string $htmlname Nom de la zone select + * @return string Code of HTML select to chose tax or not */ - function select_PriceBaseType($selected='',$htmlname='price_base_type') - { - print $this->load_PriceBaseType($selected,$htmlname); - } - - - /** - * Selection HT or TTC - * - * @param string $selected Id pre-selectionne - * @param string $htmlname Nom de la zone select - * @return void - */ - function load_PriceBaseType($selected='',$htmlname='price_base_type') + function selectPriceBaseType($selected='',$htmlname='price_base_type') { global $langs; @@ -2711,9 +2722,9 @@ class Form $langs->load("admin"); $langs->load("deliveries"); - $sql = "SELECT rowid, code, libelle"; + $sql = "SELECT rowid, code, libelle as label"; $sql.= " FROM ".MAIN_DB_PREFIX."c_shipment_mode"; - $sql.= " WHERE active = 1"; + $sql.= " WHERE active > 0"; if ($filtre) $sql.=" AND ".$filtre; $sql.= " ORDER BY libelle ASC"; @@ -2734,7 +2745,7 @@ class Form } else { print ''; $i++; } @@ -2786,12 +2797,12 @@ class Form /** * Creates HTML last in cycle situation invoices selector * - * @param string $selected Preselected ID - * @param int $socid Company ID + * @param string $selected Preselected ID + * @param int $socid Company ID * * @return string HTML select */ - function load_situation_invoices($selected = '', $socid = '') + function selectSituationInvoices($selected = '', $socid = 0) { global $langs; @@ -2799,7 +2810,7 @@ class Form $opt = ''; $sql = 'SELECT rowid, facnumber, situation_cycle_ref, situation_counter, situation_final, fk_soc FROM ' . MAIN_DB_PREFIX . 'facture WHERE situation_counter>=1'; - $sql .= ' order by situation_cycle_ref, situation_counter desc'; + $sql.= ' ORDER by situation_cycle_ref, situation_counter desc'; $resql = $this->db->query($sql); if ($resql && $this->db->num_rows($resql) > 0) { // Last seen cycle @@ -2825,10 +2836,13 @@ class Form } } } - } else { + } + else + { dol_syslog("Error sql=" . $sql . ", error=" . $this->error, LOG_ERR); } - if ($opt == '') { + if ($opt == '') + { $opt = ''; } return $opt; @@ -2850,7 +2864,9 @@ class Form $return= '
'; $ret.=$langs->trans($text); $ret.='
'; } else - { + { if ($selected) { require_once DOL_DOCUMENT_ROOT .'/user/class/user.class.php'; - //$this->load_cache_contacts(); - //print $this->cache_contacts[$selected]; $theuser=new User($this->db); $theuser->fetch($selected); print $theuser->getNomUrl(1); @@ -3659,12 +3673,12 @@ class Form /** - * Affiche formulaire de selection des contacts + * Show forms to select a contact * - * @param string $page Page - * @param Societe $societe Third party - * @param int $selected Id contact pre-selectionne - * @param string $htmlname Nom du formulaire select + * @param string $page Page + * @param Societe $societe Filter on third party + * @param int $selected Id contact pre-selectionne + * @param string $htmlname Name of HTML select. If 'none', we just show contact link. * @return void */ function form_contacts($page, $societe, $selected='', $htmlname='contactid') @@ -3694,8 +3708,6 @@ class Form if ($selected) { require_once DOL_DOCUMENT_ROOT .'/contact/class/contact.class.php'; - //$this->load_cache_contacts(); - //print $this->cache_contacts[$selected]; $contact=new Contact($this->db); $contact->fetch($selected); print $contact->getFullName($langs); @@ -3811,12 +3823,14 @@ class Form global $langs; $num = count($this->cache_vatrates); - if ($num > 0) return $num; // Cache deja charge + if ($num > 0) return $num; // Cache already loaded - $sql = "SELECT DISTINCT t.taux, t.recuperableonly"; + dol_syslog(__METHOD__, LOG_DEBUG); + + $sql = "SELECT DISTINCT t.taux, t.recuperableonly"; $sql.= " FROM ".MAIN_DB_PREFIX."c_tva as t, ".MAIN_DB_PREFIX."c_country as c"; $sql.= " WHERE t.fk_pays = c.rowid"; - $sql.= " AND t.active = 1"; + $sql.= " AND t.active > 0"; $sql.= " AND c.code IN (".$country_code.")"; $sql.= " ORDER BY t.taux ASC, t.recuperableonly ASC"; @@ -3850,7 +3864,8 @@ class Form } /** - * Output an HTML select vat rate + * Output an HTML select vat rate. + * The name of this function should be selectVat. We keep bad name for compatibility purpose. * * @param string $htmlname Name of html select field * @param float $selectedrate Force preselected vat rate. Use '' for no forcing. @@ -4342,16 +4357,18 @@ class Form global $conf, $langs; // Do we want a multiselect ? - $multiselect = 0; - if (preg_match('/^multi/',$htmlname)) $multiselect = 1; + //$jsbeautify = 0; + //if (preg_match('/^multi/',$htmlname)) $jsbeautify = 1; + $jsbeautify = 1; if ($value_as_key) $array=array_combine($array, $array); $out=''; // Add code for jquery to use multiselect - if ($addjscombo && empty($conf->dol_use_jmobile) && $multiselect) + if ($addjscombo && empty($conf->dol_use_jmobile) && $jsbeautify) { + $minLengthToAutocomplete=0; $tmpplugin=empty($conf->global->MAIN_USE_JQUERY_MULTISELECT)?constant('REQUIRE_JQUERY_MULTISELECT')?constant('REQUIRE_JQUERY_MULTISELECT'):'select2':$conf->global->MAIN_USE_JQUERY_MULTISELECT; $out.=' + '; + + print '
global->MAIN_OPTIMIZEFORTEXTBROWSER)?' style="display:none"':'').'>'; + + $sql = "SELECT s.rowid as socid, s.nom as name, s.client, c.rowid, c.ref, c.ref_client, c.total_ht"; + $sql .= " FROM " . MAIN_DB_PREFIX . "societe as s"; + $sql .= ", " . MAIN_DB_PREFIX . "commande as c"; + $sql .= ' WHERE c.fk_soc = s.rowid AND c.fk_soc = ' . $object->thirdparty->id . ''; + + $resqlorderlist = $this->db->query($sql); + if ($resqlorderlist) + { + $num = $this->db->num_rows($resqlorderlist); + $i = 0; + + print '
'; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + while ($i < $num) + { + $objp = $this->db->fetch_object($resqlorderlist); + + $var = ! $var; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + + $i ++; + } + print '
' . $langs->trans("Ref") . '' . $langs->trans("RefCustomer") . '' . $langs->trans("AmountHTShort") . '' . $langs->trans("Company") . '
'; + print ''; + print '' . $objp->ref . '' . $objp->ref_client . '' . price($objp->total_ht) . '' . $objp->name . '
'; + print '
     
'; + print '
'; + $this->db->free($resqlorderlist); + } else { + dol_print_error($this->db); + } + + print '
'; + } + + if (((! is_array($restrictlinksto)) || in_array('supplier_order',$restrictlinksto)) + && ! empty($conf->fournisseur->enabled)) + { + $linktoelem.=($linktoelem?'   ':'').'' . $langs->trans('LinkedOrder') . ''; + + print ' + + '; + + print '
global->MAIN_OPTIMIZEFORTEXTBROWSER)?' style="display:none"':'').'>'; + + $sql = "SELECT s.rowid as socid, s.nom as name, s.client, c.rowid, c.ref, c.ref_supplier, c.total_ht"; + $sql .= " FROM " . MAIN_DB_PREFIX . "societe as s"; + $sql .= ", " . MAIN_DB_PREFIX . "commande_fournisseur as c"; + $sql .= ' WHERE c.fk_soc = s.rowid AND c.fk_soc = ' . $object->thirdparty->id; + + $resqlorderlist = $this->db->query($sql); + if ($resqlorderlist) + { + $num = $this->db->num_rows($resqlorderlist); + $i = 0; + + print '
'; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + while ($i < $num) { + $objp = $this->db->fetch_object($resqlorderlist); + if ($objp->socid == $societe->id) { + $var = ! $var; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + } + + $i ++; + } + print '
' . $langs->trans("Ref") . '' . $langs->trans("RefSupplier") . '' . $langs->trans("AmountHTShort") . '' . $langs->trans("Company") . '
'; + print ''; + print '' . $objp->ref . '' . $objp->ref_supplier . '' . price($objp->total_ht) . '' . $objp->name . '
'; + print '
 
'; + print '
'; + $this->db->free($resqlorderlist); + } else { + dol_print_error($this->db); + } + + print '
'; + } + + + return $linktoelem; + } + /** * Return an html string with a select combo box to choose yes or no * @@ -4719,7 +4966,7 @@ class Form * @param string $paramid Name of parameter to use to name the id into the URL link * @param string $morehtml More html content to output just before the nav bar * @param int $shownav Show Condition (navigation is shown if value is 1) - * @param string $fieldid Nom du champ en base a utiliser pour select next et previous + * @param string $fieldid Nom du champ en base a utiliser pour select next et previous (we make the select max and min on this field) * @param string $fieldref Nom du champ objet ref (object->ref) a utiliser pour select next et previous * @param string $morehtmlref Code html supplementaire a afficher apres ref * @param string $moreparam More param to add in nav link url. @@ -4745,7 +4992,7 @@ class Form //print "xx".$previous_ref."x".$next_ref; //if ($previous_ref || $next_ref || $morehtml) { //$ret.='\n"; diff --git a/htdocs/core/lib/agenda.lib.php b/htdocs/core/lib/agenda.lib.php index 8ebdc547cc8..fd2a3cd4099 100644 --- a/htdocs/core/lib/agenda.lib.php +++ b/htdocs/core/lib/agenda.lib.php @@ -103,7 +103,7 @@ function print_actions_filter($form, $canedit, $status, $year, $month, $day, $sh print ''; } diff --git a/htdocs/core/lib/ajax.lib.php b/htdocs/core/lib/ajax.lib.php index 47c4773cf62..db47ad041e2 100644 --- a/htdocs/core/lib/ajax.lib.php +++ b/htdocs/core/lib/ajax.lib.php @@ -1,6 +1,6 @@ - * Copyright (C) 2007-2014 Regis Houssin + * Copyright (C) 2007-2015 Regis Houssin * Copyright (C) 2012 Christophe Battarel * * This program is free software; you can redistribute it and/or modify @@ -340,7 +340,7 @@ function ajax_combobox($htmlname, $events=array(), $minLengthToAutocomplete=0, $ if ($forcefocus) $msg.= '.select2(\'focus\')'; $msg.= ';'."\n"; - if (count($event)) + if (count($events)) { $msg.= ' jQuery("#'.$htmlname.'").change(function () { diff --git a/htdocs/core/lib/company.lib.php b/htdocs/core/lib/company.lib.php index 9c93fa8fe89..7d4ce9ceebf 100644 --- a/htdocs/core/lib/company.lib.php +++ b/htdocs/core/lib/company.lib.php @@ -364,7 +364,7 @@ function getState($id,$withcode='',$dbtouse=0) } else { - return $langs->trans("NotDefined"); + return $langs->transnoentitiesnoconv("NotDefined"); } } else dol_print_error($dbtouse,''); diff --git a/htdocs/core/lib/donation.lib.php b/htdocs/core/lib/donation.lib.php index c9362425459..5cc5c2d6785 100644 --- a/htdocs/core/lib/donation.lib.php +++ b/htdocs/core/lib/donation.lib.php @@ -78,6 +78,15 @@ function donation_prepare_head($object) // $this->tabs = array('entity:-tabname); to remove a tab complete_head_from_modules($conf, $langs, $object, $head, $h, 'donation'); + require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; + $upload_dir = $conf->don->dir_output . '/' . get_exdir($filename,2,0,1,$object,'donation'). '/'. dol_sanitizeFileName($object->ref); + $nbFiles = count(dol_dir_list($upload_dir,'files',0,'','(\.meta|_preview\.png)$')); + $head[$h][0] = DOL_URL_ROOT.'/don/document.php?id='.$object->id; + $head[$h][1] = $langs->trans('Documents'); + if($nbFiles > 0) $head[$h][1].= ' '.$nbFiles.''; + $head[$h][2] = 'documents'; + $h++; + $head[$h][0] = DOL_URL_ROOT . '/don/info.php?id=' . $object->id; $head[$h][1] = $langs->trans("Info"); $head[$h][2] = 'info'; diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index b164636ceb7..48bbe2ace8d 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -1645,7 +1645,7 @@ function dol_print_address($address, $htmlid, $mode, $id) /** * Return true if email syntax is ok * - * @param string $address email (Ex: "toto@titi.com", "John Do ") + * @param string $address email (Ex: "toto@examle.com", "John Do ") * @param int $acceptsupervisorkey If 1, the special string '__SUPERVISOREMAIL__' is also accepted as valid * @return boolean true if email syntax is OK, false if KO or empty string */ @@ -2637,11 +2637,12 @@ function dol_print_error_email($prefixcode) * @param string $td Options of attribute td ("" by defaut, example: 'align="center"') * @param string $sortfield Current field used to sort * @param string $sortorder Current sort order + * @param string $prefix Prefix for css * @return void */ -function print_liste_field_titre($name, $file="", $field="", $begin="", $moreparam="", $td="", $sortfield="", $sortorder="") +function print_liste_field_titre($name, $file="", $field="", $begin="", $moreparam="", $td="", $sortfield="", $sortorder="", $prefix="") { - print getTitleFieldOfList($name, 0, $file, $field, $begin, $moreparam, $td, $sortfield, $sortorder); + print getTitleFieldOfList($name, 0, $file, $field, $begin, $moreparam, $td, $sortfield, $sortorder, $prefix); } /** @@ -2656,9 +2657,10 @@ function print_liste_field_titre($name, $file="", $field="", $begin="", $morepar * @param string $moreattrib Add more attributes on th ("" by defaut) * @param string $sortfield Current field used to sort * @param string $sortorder Current sort order + * @param string $prefix Prefix for css * @return string */ -function getTitleFieldOfList($name, $thead=0, $file="", $field="", $begin="", $moreparam="", $moreattrib="", $sortfield="", $sortorder="") +function getTitleFieldOfList($name, $thead=0, $file="", $field="", $begin="", $moreparam="", $moreattrib="", $sortfield="", $sortorder="", $prefix="") { global $conf; //print "$name, $file, $field, $begin, $options, $moreattrib, $sortfield, $sortorder
\n"; @@ -2672,7 +2674,7 @@ function getTitleFieldOfList($name, $thead=0, $file="", $field="", $begin="", $m // If field is used as sort criteria we use a specific class // Example if (sortfield,field)=("nom","xxx.nom") or (sortfield,field)=("nom","nom") if ($field && ($sortfield == $field || $sortfield == preg_replace("/^[^\.]+\./","",$field))) $out.= '<'.$tag.' class="liste_titre_sel" '. $moreattrib.'>'; - else $out.= '<'.$tag.' class="liste_titre" '. $moreattrib.'>'; + else $out.= '<'.$tag.' class="'.$prefix.'liste_titre" '. $moreattrib.'>'; if (! empty($conf->dol_optimize_smallscreen) && empty($thead) && $field) // If this is a sort field { @@ -4127,8 +4129,8 @@ function dol_textishtml($msg,$option=0) elseif (preg_match('/<(br|div|font|li|span|strong|table)>/i',$msg)) return true; elseif (preg_match('/<(br|div|font|li|span|strong|table)\s+[^<>\/]*>/i',$msg)) return true; elseif (preg_match('/<(br|div|font|li|span|strong|table)\s+[^<>\/]*\/>/i',$msg)) return true; - elseif (preg_match('/]*src[^<>]*>/i',$msg)) return true; // must accept - elseif (preg_match('/]*href[^<>]*>/i',$msg)) return true; // must accept + elseif (preg_match('/]*src[^<>]*>/i',$msg)) return true; // must accept + elseif (preg_match('/]*href[^<>]*>/i',$msg)) return true; // must accept elseif (preg_match('//i',$msg)) return true; elseif (preg_match('/&[A-Z0-9]{1,6};/i',$msg)) return true; // Html entities names (http://www.w3schools.com/tags/ref_entities.asp) elseif (preg_match('/&#[0-9]{2,3};/i',$msg)) return true; // Html entities numbers (http://www.w3schools.com/tags/ref_entities.asp) @@ -4867,7 +4869,7 @@ function complete_head_from_modules($conf,$langs,$object,&$head,&$h,$type,$mode= * Print common footer : * conf->global->MAIN_HTML_FOOTER * conf->global->MAIN_GOOGLE_AN_ID - * DOL_TUNING + * conf->global->MAIN_SHOW_TUNING_INFO or $_SERVER["MAIN_SHOW_TUNING_INFO"] * conf->logbuffer * * @param string $zone 'private' (for private pages) or 'public' (for public pages) @@ -4904,7 +4906,7 @@ function printCommonFooter($zone='private') } // End of tuning - if (! empty($_SERVER['DOL_TUNING']) || ! empty($conf->global->MAIN_SHOW_TUNING_INFO)) + if (! empty($_SERVER['MAIN_SHOW_TUNING_INFO']) || ! empty($conf->global->MAIN_SHOW_TUNING_INFO)) { print "\n".' - '; - - print '
'; - $ret.='
'; + $ret.='
'; //} $ret.=dol_htmlentities($object->$fieldref); @@ -4863,7 +5110,6 @@ class Form $cache='0'; if ($file && file_exists($dir."/".$file)) { - // TODO Link to large image $ret.=''; $ret.='Photo'; $ret.=''; @@ -4876,19 +5122,22 @@ class Form } else { - $nophoto='/theme/common/nophoto.jpg'; + $nophoto='/public/theme/common/nophoto.jpg'; if (in_array($modulepart,array('userphoto','contact'))) // For module thar are "physical" users { - $nophoto='/theme/common/user_anonymous.png'; - if ($object->gender == 'man') $nophoto='/theme/common/user_man.png'; - if ($object->gender == 'woman') $nophoto='/theme/common/user_woman.png'; + $nophoto='/public/theme/common/user_anonymous.png'; + if ($object->gender == 'man') $nophoto='/public/theme/common/user_man.png'; + if ($object->gender == 'woman') $nophoto='/public/theme/common/user_woman.png'; } if (! empty($conf->gravatar->enabled) && $email) { + /** + * @see https://gravatar.com/site/implement/images/php/ + */ global $dolibarr_main_url_root; $ret.=''; - $ret.='Photo found on Gravatar'; // gravatar need md5 hash + $ret.='Gravatar avatar'; // gravatar need md5 hash } else { diff --git a/htdocs/core/class/html.formmargin.class.php b/htdocs/core/class/html.formmargin.class.php new file mode 100644 index 00000000000..a52238be1b9 --- /dev/null +++ b/htdocs/core/class/html.formmargin.class.php @@ -0,0 +1,273 @@ + + * + * 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/html.formmargin.class.php + * \ingroup core + * \brief Fichier de la classe des fonctions predefinie de composants html autre + */ + + +/** + * Classe permettant la generation de composants html autre + * Only common components are here. + */ +class FormMargin +{ + var $db; + var $error; + + + /** + * Constructor + * + * @param DoliDB $db Database handler + */ + function __construct($db) + { + $this->db = $db; + + return 1; + } + + + + /** + * get array with margin information from lines of object + * + * @param CommonObject $object Object we want to get margin information for + * @param boolean $force_price True of not + * @return array Array with info + */ + function getMarginInfosArray($object, $force_price=false) + { + global $conf, $db; + + // Default returned array + $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($object->lines as $line) + { + if (empty($line->pa_ht) && isset($line->fk_fournprice) && !$force_price) + { + require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.product.class.php'; + $product = new ProductFournisseur($db); + if ($product->fetch_product_fournisseur_price($line->fk_fournprice)) + $line->pa_ht = $product->fourn_unitprice * (1 - $product->fourn_remise_percent / 100); + 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 + $pa = $line->qty * $line->pa_ht; + $pv = $line->qty * $line->subprice * (1 - $line->remise_percent / 100); + if ($conf->global->MARGIN_METHODE_FOR_DISCOUNT == '1') { // remise globale considérée comme produit + $marginInfos['pa_products'] += $pa; + $marginInfos['pv_products'] += $pv; + $marginInfos['pa_total'] += $pa; + $marginInfos['pv_total'] += $pv; + // if credit note, margin = -1 * (abs(selling_price) - buying_price) + if ($pv < 0) + $marginInfos['margin_on_products'] += -1 * (abs($pv) - $pa); + else + $marginInfos['margin_on_products'] += $pv - $pa; + } + elseif ($conf->global->MARGIN_METHODE_FOR_DISCOUNT == '2') { // remise globale considérée comme service + $marginInfos['pa_services'] += $pa; + $marginInfos['pv_services'] += $pv; + $marginInfos['pa_total'] += $pa; + $marginInfos['pv_total'] += $pv; + // if credit note, margin = -1 * (abs(selling_price) - buying_price) + if ($pv < 0) + $marginInfos['margin_on_services'] += -1 * (abs($pv) - $pa); + else + $marginInfos['margin_on_services'] += $pv - $pa; + } + elseif ($conf->global->MARGIN_METHODE_FOR_DISCOUNT == '3') { // remise globale prise en compte uniqt sur total + $marginInfos['pa_total'] += $pa; + $marginInfos['pv_total'] += $pv; + } + } + else { + $type=$line->product_type?$line->product_type:$line->fk_product_type; + if ($type == 0) { // product + $pa = $line->qty * $line->pa_ht; + $pv = $line->qty * $line->subprice * (1 - $line->remise_percent / 100); + $marginInfos['pa_products'] += $pa; + $marginInfos['pv_products'] += $pv; + $marginInfos['pa_total'] += $pa; + $marginInfos['pv_total'] += $pv; + // if credit note, margin = -1 * (abs(selling_price) - buying_price) + if ($pv < 0) + $marginInfos['margin_on_products'] += -1 * (abs($pv) - $pa); + else + $marginInfos['margin_on_products'] += $pv - $pa; + } + elseif ($type == 1) { // service + $pa = $line->qty * $line->pa_ht; + $pv = $line->qty * $line->subprice * (1 - $line->remise_percent / 100); + $marginInfos['pa_services'] += $pa; + $marginInfos['pv_services'] += $pv; + $marginInfos['pa_total'] += $pa; + $marginInfos['pv_total'] += $pv; + // if credit note, margin = -1 * (abs(selling_price) - buying_price) + if ($pv < 0) + $marginInfos['margin_on_services'] += -1 * (abs($pv) - $pa); + else + $marginInfos['margin_on_services'] += $pv - $pa; + } + } + } + if ($marginInfos['pa_products'] > 0) + $marginInfos['margin_rate_products'] = 100 * $marginInfos['margin_on_products'] / $marginInfos['pa_products']; + if ($marginInfos['pv_products'] > 0) + $marginInfos['mark_rate_products'] = 100 * $marginInfos['margin_on_products'] / $marginInfos['pv_products']; + + if ($marginInfos['pa_services'] > 0) + $marginInfos['margin_rate_services'] = 100 * $marginInfos['margin_on_services'] / $marginInfos['pa_services']; + if ($marginInfos['pv_services'] > 0) + $marginInfos['mark_rate_services'] = 100 * $marginInfos['margin_on_services'] / $marginInfos['pv_services']; + + // if credit note, margin = -1 * (abs(selling_price) - buying_price) + if ($marginInfos['pv_total'] < 0) + $marginInfos['total_margin'] = -1 * (abs($marginInfos['pv_total']) - $marginInfos['pa_total']); + else + $marginInfos['total_margin'] = $marginInfos['pv_total'] - $marginInfos['pa_total']; + if ($marginInfos['pa_total'] > 0) + $marginInfos['total_margin_rate'] = 100 * $marginInfos['total_margin'] / $marginInfos['pa_total']; + if ($marginInfos['pv_total'] > 0) + $marginInfos['total_mark_rate'] = 100 * $marginInfos['total_margin'] / $marginInfos['pv_total']; + + return $marginInfos; + } + + /** + * Show the array with all margin infos + * + * @param CommonObject $object Object we want to get margin information for + * @param boolean $force_price Force price + * @return void + */ + function displayMarginInfos($object, $force_price=false) + { + global $langs, $conf, $user; + + if (! empty($user->societe_id)) return; + + if (! $user->rights->margins->liretous) return; + + $rounding = min($conf->global->MAIN_MAX_DECIMALS_UNIT, $conf->global->MAIN_MAX_DECIMALS_TOT); + + $marginInfo = $this->getMarginInfosArray($object, $force_price); + + if (! empty($conf->global->MARGIN_ADD_SHOWHIDE_BUTTON)) // TODO Warning this feature rely on an external js file that may be removed. Using native js function document.cookie should be better + { + print $langs->trans('ShowMarginInfos').' : '; + $hidemargininfos = $_COOKIE['DOLUSER_MARGININFO_HIDE_SHOW']; + print ''.img_picto($langs->trans("Disabled"),'switch_off').''; + print ''.img_picto($langs->trans("Enabled"),'switch_on').''; + + print ''; + if (!empty($hidemargininfos)) print ''; + } + + 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 (! empty($conf->product->enabled)) + { + //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 ''; + } + + if (! empty($conf->service->enabled)) + { + print ''; + print ''; + print ''; + print ''; + print ''; + if (! empty($conf->global->DISPLAY_MARGIN_RATES)) + print ''; + if (! empty($conf->global->DISPLAY_MARK_RATES)) + print ''; + print ''; + } + + if (! empty($conf->product->enabled) && ! empty($conf->service->enabled)) + { + 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'], null, null, null, null, $rounding).''.price($marginInfo['pa_products'], null, null, null, null, $rounding).''.price($marginInfo['margin_on_products'], null, null, null, null, $rounding).''.(($marginInfo['margin_rate_products'] == '')?'':price($marginInfo['margin_rate_products'], null, null, null, null, $rounding).'%').''.(($marginInfo['mark_rate_products'] == '')?'':price($marginInfo['mark_rate_products'], null, null, null, null, $rounding).'%').'
'.$langs->trans('MarginOnServices').''.price($marginInfo['pv_services'], null, null, null, null, $rounding).''.price($marginInfo['pa_services'], null, null, null, null, $rounding).''.price($marginInfo['margin_on_services'], null, null, null, null, $rounding).''.(($marginInfo['margin_rate_services'] == '')?'':price($marginInfo['margin_rate_services'], null, null, null, null, $rounding).'%').''.(($marginInfo['mark_rate_services'] == '')?'':price($marginInfo['mark_rate_services'], null, null, null, null, $rounding).'%').'
'.$langs->trans('TotalMargin').''.price($marginInfo['pv_total'], null, null, null, null, $rounding).''.price($marginInfo['pa_total'], null, null, null, null, $rounding).''.price($marginInfo['total_margin'], null, null, null, null, $rounding).''.(($marginInfo['total_margin_rate'] == '')?'':price($marginInfo['total_margin_rate'], null, null, null, null, $rounding).'%').''.(($marginInfo['total_mark_rate'] == '')?'':price($marginInfo['total_mark_rate'], null, null, null, null, $rounding).'%').'
'; + } + +} + diff --git a/htdocs/core/db/DoliDB.class.php b/htdocs/core/db/DoliDB.class.php index 6a7c5276025..c4908595493 100644 --- a/htdocs/core/db/DoliDB.class.php +++ b/htdocs/core/db/DoliDB.class.php @@ -55,7 +55,7 @@ abstract class DoliDB implements Database public $transaction_opened; /** @var string Last successful query */ public $lastquery; - /** @ar string Last failed query */ + /** @var string Last failed query */ public $lastqueryerror; /** @var string Last error message */ public $lasterror; diff --git a/htdocs/core/lib/admin.lib.php b/htdocs/core/lib/admin.lib.php index 3a35c961905..05204885c9c 100644 --- a/htdocs/core/lib/admin.lib.php +++ b/htdocs/core/lib/admin.lib.php @@ -1084,18 +1084,18 @@ function form_constantes($tableau,$strictw3c=0) if ($const == 'ADHERENT_MAILMAN_URL') { print '. '.$langs->trans("Example").': '.img_down().'
'; - //print 'http://lists.domain.com/cgi-bin/mailman/admin/%LISTE%/members?adminpw=%MAILMAN_ADMINPW%&subscribees=%EMAIL%&send_welcome_msg_to_this_batch=1'; + //print 'http://lists.exampe.com/cgi-bin/mailman/admin/%LISTE%/members?adminpw=%MAILMAN_ADMINPW%&subscribees=%EMAIL%&send_welcome_msg_to_this_batch=1'; print ''; } if ($const == 'ADHERENT_MAILMAN_UNSUB_URL') { print '. '.$langs->trans("Example").': '.img_down().'
'; print ''; - //print 'http://lists.domain.com/cgi-bin/mailman/admin/%LISTE%/members/remove?adminpw=%MAILMAN_ADMINPW%&unsubscribees=%EMAIL%'; + //print 'http://lists.example.com/cgi-bin/mailman/admin/%LISTE%/members/remove?adminpw=%MAILMAN_ADMINPW%&unsubscribees=%EMAIL%'; } if ($const == 'ADHERENT_MAILMAN_LISTS') { @@ -1106,7 +1106,7 @@ function form_constantes($tableau,$strictw3c=0) print 'TYPE:Type1:mymailmanlist1,TYPE:Type2:mymailmanlist2
'; if ($conf->categorie->enabled) print 'CATEG:Categ1:mymailmanlist1,CATEG:Categ2:mymailmanlist2
'; print '
'; - //print 'http://lists.domain.com/cgi-bin/mailman/admin/%LISTE%/members/remove?adminpw=%MAILMAN_ADMINPW%&unsubscribees=%EMAIL%'; + //print 'http://lists.example.com/cgi-bin/mailman/admin/%LISTE%/members/remove?adminpw=%MAILMAN_ADMINPW%&unsubscribees=%EMAIL%'; } print "
'; print $langs->trans("ThirdParty").'   '; print ''; - print $form->select_thirdparty($socid, 'socid'); + print $form->select_company($socid, 'socid'); print '
'; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - while ($i < $num) { - $objp = $db->fetch_object($resqlorderlist); - if ($objp->socid == $societe->id) { - $var = ! $var; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - } - - $i ++; - } - print '
' . $langs->trans("Ref") . '' . $langs->trans("RefSupplier") . '' . $langs->trans("AmountHTShort") . '' . $langs->trans("Company") . '
'; - print ''; - print '' . $objp->ref . '' . $objp->ref_supplier . '' . price($objp->total_ht) . '' . $objp->name . '
'; - print '
 
'; - print ''; - $db->free($resqlorderlist); - } else { - dol_print_error($db); - } - - print '
'; - } - - // Show link to elements + // Show links to link elements + $linktoelem = $form->showLinkToObjectBlock($object,array('supplier_order')); if ($linktoelem) print '
'.$linktoelem; + print '
'; //print ''; //print '
'; @@ -2509,7 +2443,7 @@ else { $ref = dol_sanitizeFileName($object->ref); include_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; - $fileparams = dol_most_recent_file($conf->fournisseur->facture->dir_output.'/'.get_exdir($object->id,2,0,0,$object,'invoice_supplier').$ref, preg_quote($ref,'/')); + $fileparams = dol_most_recent_file($conf->fournisseur->facture->dir_output.'/'.get_exdir($object->id,2,0,0,$object,'invoice_supplier').$ref, preg_quote($ref,'/').'([^\-])+'); $file=$fileparams['fullname']; // Define output language @@ -2536,7 +2470,7 @@ else dol_print_error($db,$result); exit; } - $fileparams = dol_most_recent_file($conf->fournisseur->facture->dir_output.'/'.get_exdir($object->id,2,0,0,$object,'invoice_supplier').$ref, preg_quote($ref,'/')); + $fileparams = dol_most_recent_file($conf->fournisseur->facture->dir_output.'/'.get_exdir($object->id,2,0,0,$object,'invoice_supplier').$ref, preg_quote($ref,'/').'([^\-])+'); $file=$fileparams['fullname']; } diff --git a/htdocs/index.php b/htdocs/index.php index eaebe195fd4..8c37688c0f8 100644 --- a/htdocs/index.php +++ b/htdocs/index.php @@ -1,7 +1,7 @@ * Copyright (C) 2004-2013 Laurent Destailleur - * Copyright (C) 2005-2012 Regis Houssin + * Copyright (C) 2005-2015 Regis Houssin * Copyright (C) 2011-2012 Juanjo Menent * Copyright (C) 2015 Marcos García * @@ -268,7 +268,7 @@ if (empty($user->societe_id)) else $board=$boardloaded[$classe]; $var=!$var; - if ($langfile[$key]) $langs->load($langfile[$key]); + if (!empty($langfile[$key])) $langs->load($langfile[$key]); $text=$langs->trans($titres[$key]); print '
'; print '
'; diff --git a/htdocs/install/mysql/migration/3.6.0-3.7.0.sql b/htdocs/install/mysql/migration/3.6.0-3.7.0.sql index 399f8099ca6..dd0aba11632 100755 --- a/htdocs/install/mysql/migration/3.6.0-3.7.0.sql +++ b/htdocs/install/mysql/migration/3.6.0-3.7.0.sql @@ -208,10 +208,14 @@ UPDATE llx_product SET fk_barcode_type = NULL WHERE fk_barcode_type NOT IN (SELE ALTER TABLE llx_product_price ADD INDEX idx_product_price_fk_user_author (fk_user_author); UPDATE llx_product_price set fk_user_author = null where fk_user_author = 0; UPDATE llx_product_price set fk_user_author = null where fk_user_author not in (select rowid from llx_user); +-- drop foreign key for avoid a mysql crash +ALTER TABLE llx_product_price DROP FOREIGN KEY fk_product_price_user_author; ALTER TABLE llx_product_price ADD CONSTRAINT fk_product_price_user_author FOREIGN KEY (fk_user_author) REFERENCES llx_user (rowid); -- fk_product ALTER TABLE llx_product_price ADD INDEX idx_product_price_fk_product (fk_product); DELETE from llx_product_price where fk_product NOT IN (SELECT rowid from llx_product); +-- drop foreign key for avoid a mysql crash +ALTER TABLE llx_product_price DROP FOREIGN KEY fk_product_price_product; ALTER TABLE llx_product_price ADD CONSTRAINT fk_product_price_product FOREIGN KEY (fk_product) REFERENCES llx_product (rowid); ALTER TABLE llx_commande_fournisseur MODIFY COLUMN date_livraison datetime; diff --git a/htdocs/install/mysql/migration/3.7.0-3.8.0.sql b/htdocs/install/mysql/migration/3.7.0-3.8.0.sql index 140475ed5df..1b3633c9ae5 100755 --- a/htdocs/install/mysql/migration/3.7.0-3.8.0.sql +++ b/htdocs/install/mysql/migration/3.7.0-3.8.0.sql @@ -647,12 +647,12 @@ ALTER TABLE llx_actioncomm ADD COLUMN email_sender varchar(256); ALTER TABLE llx_actioncomm ADD COLUMN email_to varchar(256); ALTER TABLE llx_actioncomm ADD COLUMN errors_to varchar(256); --- Recuring events +-- Recurring events ALTER TABLE llx_actioncomm ADD COLUMN recurid varchar(128); ALTER TABLE llx_actioncomm ADD COLUMN recurrule varchar(128); ALTER TABLE llx_actioncomm ADD COLUMN recurdateend datetime; -ALTER TABLE llx_stcomm ADD COLUMN picto varchar(128); +ALTER TABLE llx_c_stcomm ADD COLUMN picto varchar(128); -- New trigger for Supplier invoice unvalidation INSERT INTO llx_c_action_trigger (code, label, description, elementtype, rang) VALUES ('BILL_SUPPLIER_UNVALIDATE','Supplier invoice unvalidated','Executed when a supplier invoice status is set back to draft','invoice_supplier',15); diff --git a/htdocs/langs/en_US/products.lang b/htdocs/langs/en_US/products.lang index d7fba120cb3..1d7ece0c98d 100644 --- a/htdocs/langs/en_US/products.lang +++ b/htdocs/langs/en_US/products.lang @@ -294,3 +294,4 @@ LastUpdated=Last updated CorrectlyUpdated=Correctly updated PropalMergePdfProductActualFile=Files use to add into PDF Azur are/is PropalMergePdfProductChooseFile=Select PDF files +IncludingProductWithTag=Including product with tag \ No newline at end of file diff --git a/htdocs/livraison/card.php b/htdocs/livraison/card.php index fb087e71800..7ea9920d65b 100644 --- a/htdocs/livraison/card.php +++ b/htdocs/livraison/card.php @@ -788,10 +788,14 @@ else $shipment = new Expedition($db); $shipment->fetch($object->origin_id); - $somethingshown=$shipment->showLinkedObjectBlock(); + // Linked object block + $somethingshown = $form->showLinkedObjectBlock($shipment); + + // Show links to link elements + //$linktoelem = $form->showLinkToObjectBlock($shipment); + //if ($linktoelem) print '
'.$linktoelem; } - if ($genallowed && ! $somethingshown) $somethingshown=1; print ''; diff --git a/htdocs/main.inc.php b/htdocs/main.inc.php index 7a390ab7d9d..bb574a68b77 100644 --- a/htdocs/main.inc.php +++ b/htdocs/main.inc.php @@ -4,7 +4,7 @@ * Copyright (C) 2004-2015 Laurent Destailleur * Copyright (C) 2004 Sebastien Di Cintio * Copyright (C) 2004 Benoit Mortier - * Copyright (C) 2005-2012 Regis Houssin + * Copyright (C) 2005-2015 Regis Houssin * Copyright (C) 2011-2014 Philippe Grand * Copyright (C) 2008 Matteli * Copyright (C) 2011-2013 Juanjo Menent @@ -34,10 +34,10 @@ //@ini_set('memory_limit', '64M'); // This may be useless if memory is hard limited by your PHP -// For optional tuning. Enabled if environment variable DOL_TUNING is defined. +// For optional tuning. Enabled if environment variable MAIN_SHOW_TUNING_INFO is defined. // A call first. Is the equivalent function dol_microtime_float not yet loaded. $micro_start_time=0; -if (! empty($_SERVER['DOL_TUNING'])) +if (! empty($_SERVER['MAIN_SHOW_TUNING_INFO'])) { list($usec, $sec) = explode(" ", microtime()); $micro_start_time=((float) $usec + (float) $sec); @@ -110,7 +110,7 @@ function test_sql_and_script_inject($val, $type) } /** - * Security: Return true if OK, false otherwise. + * Return true if security check on parameters are OK, false otherwise. * * @param string $var Variable name * @param string $type 1=GET, 0=POST, 2=PHP_SELF @@ -1803,7 +1803,7 @@ function printSearchForm($urlaction,$urlobject,$title,$htmlmodesearch,$htmlinput { global $conf,$langs; - if (!$htmlinputid) { + if (empty($htmlinputid)) { $htmlinputid = $htmlinputname; } diff --git a/htdocs/product/admin/product_tools.php b/htdocs/product/admin/product_tools.php index 26ad4dba807..ec5f575a552 100644 --- a/htdocs/product/admin/product_tools.php +++ b/htdocs/product/admin/product_tools.php @@ -292,7 +292,7 @@ else print ''."\n"; print ''.$langs->trans("PriceBaseTypeToChange").''."\n"; print ''."\n"; - print $form->load_PriceBaseType($price_base_type); + print $form->selectPriceBaseType($price_base_type); print ''."\n"; print ''."\n"; */ diff --git a/htdocs/product/canvas/product/actions_card_product.class.php b/htdocs/product/canvas/product/actions_card_product.class.php index 260c8996fc4..aba6325d234 100644 --- a/htdocs/product/canvas/product/actions_card_product.class.php +++ b/htdocs/product/canvas/product/actions_card_product.class.php @@ -116,7 +116,7 @@ class ActionsCardProduct // Price $this->tpl['price'] = $this->price; $this->tpl['price_min'] = $this->price_min; - $this->tpl['price_base_type'] = $form->load_PriceBaseType($this->price_base_type, "price_base_type"); + $this->tpl['price_base_type'] = $form->selectPriceBaseType($this->price_base_type, "price_base_type"); // VAT $this->tpl['tva_tx'] = $form->load_tva("tva_tx",-1,$mysoc,''); diff --git a/htdocs/product/canvas/service/actions_card_service.class.php b/htdocs/product/canvas/service/actions_card_service.class.php index f7de783cd99..7bc04ecb42a 100644 --- a/htdocs/product/canvas/service/actions_card_service.class.php +++ b/htdocs/product/canvas/service/actions_card_service.class.php @@ -115,7 +115,7 @@ class ActionsCardService // Price $this->tpl['price'] = $this->price; $this->tpl['price_min'] = $this->price_min; - $this->tpl['price_base_type'] = $form->load_PriceBaseType($this->price_base_type, "price_base_type"); + $this->tpl['price_base_type'] = $form->selectPriceBaseType($this->price_base_type, "price_base_type"); // VAT $this->tpl['tva_tx'] = $form->load_tva("tva_tx",-1,$mysoc,''); diff --git a/htdocs/product/card.php b/htdocs/product/card.php index 7780bb560a5..65845a5dd2c 100644 --- a/htdocs/product/card.php +++ b/htdocs/product/card.php @@ -2,7 +2,7 @@ /* Copyright (C) 2001-2007 Rodolphe Quiedeville * Copyright (C) 2004-2015 Laurent Destailleur * Copyright (C) 2005 Eric Seigne - * Copyright (C) 2005-2014 Regis Houssin + * Copyright (C) 2005-2015 Regis Houssin * Copyright (C) 2006 Andre Cianfarani * Copyright (C) 2006 Auguria SARL * Copyright (C) 2010-2014 Juanjo Menent @@ -1004,7 +1004,7 @@ else // PRIX print ''.$langs->trans("SellingPrice").''; print ''; - print $form->select_PriceBaseType($object->price_base_type, "price_base_type"); + print $form->selectPriceBaseType($object->price_base_type, "price_base_type"); print ''; // MIN PRICE @@ -1385,7 +1385,7 @@ else print ''; + if (($action != 'editbarcodetype') && ! empty($user->rights->barcode->creer)) print ''; print '
'; print $langs->trans("BarcodeType"); print ''; - if (($action != 'editbarcodetype') && $user->rights->barcode->creer) print 'id.'">'.img_edit($langs->trans('Edit'),1).'id.'">'.img_edit($langs->trans('Edit'),1).'
'; print ''; if ($action == 'editbarcodetype') @@ -1406,7 +1406,7 @@ else print ''; + if (($action != 'editbarcode') && ! empty($user->rights->barcode->creer)) print ''; print '
'; print $langs->trans("BarcodeValue"); print ''; - if (($action != 'editbarcode') && $user->rights->barcode->creer) print 'id.'">'.img_edit($langs->trans('Edit'),1).'id.'">'.img_edit($langs->trans('Edit'),1).'
'; print ''; if ($action == 'editbarcode') @@ -1461,7 +1461,7 @@ else print ''; // Batch number management (to batch) - if ($conf->productbatch->enabled) { + if (! empty($conf->productbatch->enabled)) { print ''.$langs->trans("ManageLotSerial").''; if (! empty($conf->use_javascript_ajax) && $user->rights->produit->creer && ! empty($conf->global->MAIN_DIRECT_STATUS_UPDATE)) { print ajax_object_onoff($object, 'status_batch', 'tobatch', 'ProductStatusOnBatch', 'ProductStatusNotOnBatch'); @@ -1552,7 +1552,7 @@ else } // Unit - if($conf->global->PRODUCT_USE_UNITS) + if (! empty($conf->global->PRODUCT_USE_UNITS)) { $unit = $object->getLabelOfUnit(); diff --git a/htdocs/product/fournisseurs.php b/htdocs/product/fournisseurs.php index f23ac3d1e95..fe715801f11 100644 --- a/htdocs/product/fournisseurs.php +++ b/htdocs/product/fournisseurs.php @@ -450,7 +450,7 @@ if ($id || $ref) print ''.$langs->trans("PriceQtyMin").''; print ''; print ' '; - print $form->select_PriceBaseType((GETPOST('price_base_type')?GETPOST('price_base_type'):$product->price_base_type), "price_base_type"); + print $form->selectPriceBaseType((GETPOST('price_base_type')?GETPOST('price_base_type'):$product->price_base_type), "price_base_type"); print ''; // Discount qty min diff --git a/htdocs/product/price.php b/htdocs/product/price.php index ce8ad104a1f..b744d37ea06 100644 --- a/htdocs/product/price.php +++ b/htdocs/product/price.php @@ -2,7 +2,7 @@ /* Copyright (C) 2001-2007 Rodolphe Quiedeville * Copyright (C) 2004-2014 Laurent Destailleur * Copyright (C) 2005 Eric Seigne - * Copyright (C) 2005-2013 Regis Houssin + * Copyright (C) 2005-2015 Regis Houssin * Copyright (C) 2006 Andre Cianfarani * Copyright (C) 2014 Florian Henry * Copyright (C) 2014 Juanjo Menent @@ -43,9 +43,12 @@ if (! empty($conf->global->PRODUIT_CUSTOMER_PRICES)) { $langs->load("products"); $langs->load("bills"); +$mesg=''; $error=0; $errors=array(); $_error=0; + $id = GETPOST('id', 'int'); $ref = GETPOST('ref', 'alpha'); $action = GETPOST('action', 'alpha'); +$cancel = GETPOST('cancel', 'alpha'); $eid = GETPOST('eid', 'int'); // Security check @@ -54,303 +57,302 @@ $fieldtype = (! empty($ref) ? 'ref' : 'rowid'); if ($user->societe_id) $socid = $user->societe_id; $result = restrictedArea($user, 'produit|service', $fieldvalue, 'product&product', '', '', $fieldtype); -$object = new Product($db); +if ($id > 0 || ! empty($ref)) +{ + $object = new Product($db); + $object->fetch($id, $ref); +} // Clean param if (! empty($conf->global->PRODUIT_MULTIPRICES) && empty($conf->global->PRODUIT_MULTIPRICES_LIMIT)) $conf->global->PRODUIT_MULTIPRICES_LIMIT = 5; -$error=0; +// Initialize technical object to manage hooks of thirdparties. Note that conf->hooks_modules contains array array +$hookmanager->initHooks(array('productpricecard','globalcard')); /* * Actions */ -if (GETPOST("cancel")) $action=''; +if ($cancel) $action=''; -if ($action == 'update_price' && ! GETPOST("cancel") && ($user->rights->produit->creer || $user->rights->service->creer)) +$parameters=array('id'=>$id, 'ref'=>$ref); +$reshook=$hookmanager->executeHooks('doActions',$parameters,$object,$action); // Note that $action and $object may have been modified by some hooks +if ($reshook < 0) setEventMessages($hookmanager->error, $hookmanager->errors, 'errors'); + +if (empty($reshook)) { - $result = $object->fetch($id); - - $error=0; - $maxpricesupplier = $object->min_recommended_price(); - $object->fk_price_expression = empty($eid) ? 0 : $eid; //0 discards expression - - // MultiPrix - if (! empty($conf->global->PRODUIT_MULTIPRICES)) + if ($action == 'update_price' && !$cancel && ($user->rights->produit->creer || $user->rights->service->creer)) { - $newprice = ''; - $newprice_min = ''; - $newpricebase = ''; - $newvat = ''; + $maxpricesupplier = $object->min_recommended_price(); + $object->fk_price_expression = empty($eid) ? 0 : $eid; //0 discards expression - for ($i = 1; $i <= $conf->global->PRODUIT_MULTIPRICES_LIMIT; $i ++) + // MultiPrix + if (! empty($conf->global->PRODUIT_MULTIPRICES)) { - if (isset($_POST ["price_" . $i])) + $newprice = ''; + $newprice_min = ''; + $newpricebase = ''; + $newvat = ''; + + for ($i = 1; $i <= $conf->global->PRODUIT_MULTIPRICES_LIMIT; $i ++) { - $level = $i; - $newprice = price2num($_POST ["price_" . $i], 'MU'); - $newprice_min = price2num($_POST ["price_min_" . $i], 'MU'); - $newpricebase = $_POST ["multiprices_base_type_" . $i]; - $newnpr = (preg_match('/\*/', $_POST ["tva_tx_" . $i]) ? 1 : 0); - $newvat = str_replace('*', '', $_POST ["tva_tx_" . $i]); - $newpsq = GETPOST('psqflag'); - $newpsq = empty($newpsq) ? 0 : $newpsq; - break; // We found submited price + if (isset($_POST ["price_" . $i])) + { + $level = $i; + $newprice = price2num($_POST ["price_" . $i], 'MU'); + $newprice_min = price2num($_POST ["price_min_" . $i], 'MU'); + $newpricebase = $_POST ["multiprices_base_type_" . $i]; + $newnpr = (preg_match('/\*/', $_POST ["tva_tx_" . $i]) ? 1 : 0); + $newvat = str_replace('*', '', $_POST ["tva_tx_" . $i]); + $newpsq = GETPOST('psqflag'); + $newpsq = empty($newpsq) ? 0 : $newpsq; + break; // We found submited price + } } + } else { + $level = 0; + $newprice = price2num($_POST ["price"], 'MU'); + $newprice_min = price2num($_POST ["price_min"], 'MU'); + $newpricebase = $_POST ["price_base_type"]; + $newnpr = (preg_match('/\*/', $_POST ["tva_tx"]) ? 1 : 0); + $newvat = str_replace('*', '', $_POST ["tva_tx"]); + $newpsq = GETPOST('psqflag'); + $newpsq = empty($newpsq) ? 0 : $newpsq; } - } else { - $level = 0; - $newprice = price2num($_POST ["price"], 'MU'); - $newprice_min = price2num($_POST ["price_min"], 'MU'); - $newpricebase = $_POST ["price_base_type"]; - $newnpr = (preg_match('/\*/', $_POST ["tva_tx"]) ? 1 : 0); - $newvat = str_replace('*', '', $_POST ["tva_tx"]); - $newpsq = GETPOST('psqflag'); - $newpsq = empty($newpsq) ? 0 : $newpsq; - } - if (! empty($conf->global->PRODUCT_MINIMUM_RECOMMENDED_PRICE) && $newprice_min < $maxpricesupplier) - { - setEventMessage($langs->trans("MinimumPriceLimit",price($maxpricesupplier,0,'',1,-1,-1,'auto')),'errors'); - $error++; - $action='edit_price'; - } - - if ($newprice < $newprice_min && ! empty($object->fk_price_expression)) { - $newprice = $newprice_min; //Set price same as min, the user will not see the - } - - if ($object->updatePrice($newprice, $newpricebase, $user, $newvat, $newprice_min, $level, $newnpr, $newpsq) > 0) - { - if ($object->fk_price_expression != 0) { - //Check the expression validity by parsing it - $priceparser = new PriceParser($db); - $price_result = $priceparser->parseProduct($object); - if ($price_result < 0) { //Expression is not valid - $error++; - $action='edit_price'; - setEventMessage($priceparser->translatedError(), 'errors'); - } - } - if (empty($error) && ! empty($conf->dynamicprices->enabled)) + if (! empty($conf->global->PRODUCT_MINIMUM_RECOMMENDED_PRICE) && $newprice_min < $maxpricesupplier) { - $ret=$object->setPriceExpression($object->fk_price_expression); - if ($ret < 0) + setEventMessage($langs->trans("MinimumPriceLimit",price($maxpricesupplier,0,'',1,-1,-1,'auto')),'errors'); + $error++; + $action='edit_price'; + } + + if ($newprice < $newprice_min && ! empty($object->fk_price_expression)) { + $newprice = $newprice_min; //Set price same as min, the user will not see the + } + + if ($object->updatePrice($newprice, $newpricebase, $user, $newvat, $newprice_min, $level, $newnpr, $newpsq) > 0) + { + if ($object->fk_price_expression != 0) { + //Check the expression validity by parsing it + $priceparser = new PriceParser($db); + $price_result = $priceparser->parseProduct($object); + if ($price_result < 0) { //Expression is not valid + $error++; + $action='edit_price'; + setEventMessage($priceparser->translatedError(), 'errors'); + } + } + if (empty($error) && ! empty($conf->dynamicprices->enabled)) { - $error++; - $action='edit_price'; - setEventMessage($object->error, 'errors'); + $ret=$object->setPriceExpression($object->fk_price_expression); + if ($ret < 0) + { + $error++; + $action='edit_price'; + setEventMessage($object->error, 'errors'); + } + } + if (empty($error)) + { + $action = ''; + setEventMessage($langs->trans("RecordSaved")); + } + } else { + $action = 'edit_price'; + setEventMessage($object->error, 'errors'); + } + } + + if ($action == 'delete' && $user->rights->produit->supprimer) + { + $result = $object->log_price_delete($user, $_GET ["lineid"]); + if ($result < 0) { + setEventMessage($object->error, 'errors'); + } + } + + /** + * *************************************************** + * Price by quantity + * *************************************************** + */ + if ($action == 'activate_price_by_qty') { // Activating product price by quantity add a new price, specified as by quantity + + $level = GETPOST('level'); + + $object->updatePrice(0, $object->price_base_type, $user, $object->tva_tx, 0, $level, $object->tva_npr, 1); + } + + if ($action == 'edit_price_by_qty') { // Edition d'un prix par quantité + $rowid = GETPOST('rowid'); + } + + if ($action == 'update_price_by_qty') { // Ajout / Mise à jour d'un prix par quantité + + // Récupération des variables + $rowid = GETPOST('rowid'); + $priceid = GETPOST('priceid'); + $newprice = price2num(GETPOST("price"), 'MU'); + // $newminprice=price2num(GETPOST("price_min"),'MU'); // TODO : Add min price management + $quantity = GETPOST('quantity'); + $remise_percent = price2num(GETPOST('remise_percent')); + $remise = 0; // TODO : allow discount by amount when available on documents + + if (empty($quantity)) { + $error ++; + setEventMessage($langs->trans("ErrorFieldRequired", $langs->transnoentities("Qty")), 'errors'); + } + if (empty($newprice)) { + $error ++; + setEventMessage($langs->trans("ErrorFieldRequired", $langs->transnoentities("Price")), 'errors'); + } + if (! $error) { + // Calcul du prix HT et du prix unitaire + if ($object->price_base_type == 'TTC') { + $price = price2num($newprice) / (1 + ($object->tva_tx / 100)); + } + + $price = price2num($newprice, 'MU'); + $unitPrice = price2num($price / $quantity, 'MU'); + + // Ajout / mise à jour + if ($rowid > 0) { + $sql = "UPDATE " . MAIN_DB_PREFIX . "product_price_by_qty SET"; + $sql .= " price='" . $price . "',"; + $sql .= " unitprice=" . $unitPrice . ","; + $sql .= " quantity=" . $quantity . ","; + $sql .= " remise_percent=" . $remise_percent . ","; + $sql .= " remise=" . $remise; + $sql .= " WHERE rowid = " . GETPOST('rowid'); + + $result = $db->query($sql); + } else { + $sql = "INSERT INTO " . MAIN_DB_PREFIX . "product_price_by_qty (fk_product_price,price,unitprice,quantity,remise_percent,remise) values ("; + $sql .= $priceid . ',' . $price . ',' . $unitPrice . ',' . $quantity . ',' . $remise_percent . ',' . $remise . ')'; + + $result = $db->query($sql); } } - if (empty($error)) + } + + if ($action == 'delete_price_by_qty') { + $rowid = GETPOST('rowid'); + + $sql = "DELETE FROM " . MAIN_DB_PREFIX . "product_price_by_qty"; + $sql .= " WHERE rowid = " . GETPOST('rowid'); + + $result = $db->query($sql); + } + + if ($action == 'delete_all_price_by_qty') { + $priceid = GETPOST('priceid'); + + $sql = "DELETE FROM " . MAIN_DB_PREFIX . "product_price_by_qty"; + $sql .= " WHERE fk_product_price = " . $priceid; + + $result = $db->query($sql); + } + + /** + * *************************************************** + * Price by customer + * **************************************************** + */ + if ($action == 'add_customer_price_confirm' && !$cancel && ($user->rights->produit->creer || $user->rights->service->creer)) { + + $maxpricesupplier = $object->min_recommended_price(); + + $update_child_soc = GETPOST('updatechildprice'); + + // add price by customer + $prodcustprice->fk_soc = GETPOST('socid', 'int'); + $prodcustprice->fk_product = $object->id; + $prodcustprice->price = price2num(GETPOST("price"), 'MU'); + $prodcustprice->price_min = price2num(GETPOST("price_min"), 'MU'); + $prodcustprice->price_base_type = GETPOST("price_base_type", 'alpha'); + $prodcustprice->tva_tx = str_replace('*', '', GETPOST("tva_tx")); + $prodcustprice->recuperableonly = (preg_match('/\*/', GETPOST("tva_tx")) ? 1 : 0); + + if (! empty($conf->global->PRODUCT_MINIMUM_RECOMMENDED_PRICE) && $prodcustprice->price_min<$maxpricesupplier) { + setEventMessage($langs->trans("MinimumPriceLimit",price($maxpricesupplier,0,'',1,-1,-1,'auto')),'errors'); + $error++; + $action='add_customer_price'; + } + + if (! $error) + { + $result = $prodcustprice->create($user, 0, $update_child_soc); + + if ($result < 0) { + setEventMessage($prodcustprice->error, 'errors'); + } else { + setEventMessage($langs->trans('Save'), 'mesgs'); + } + $action = ''; - setEventMessage($langs->trans("RecordSaved")); - } - } else { - $action = 'edit_price'; - setEventMessage($object->error, 'errors'); - } -} - -if ($action == 'delete' && $user->rights->produit->supprimer) -{ - $result = $object->log_price_delete($user, $_GET ["lineid"]); - if ($result < 0) { - setEventMessage($object->error, 'errors'); - } -} - -/** - * *************************************************** - * Price by quantity - * *************************************************** - */ -$error = 0; -if ($action == 'activate_price_by_qty') { // Activating product price by quantity add a new price, specified as by quantity - $result = $object->fetch($id); - $level = GETPOST('level'); - - $object->updatePrice(0, $object->price_base_type, $user, $object->tva_tx, 0, $level, $object->tva_npr, 1); -} - -if ($action == 'edit_price_by_qty') { // Edition d'un prix par quantité - $rowid = GETPOST('rowid'); -} - -if ($action == 'update_price_by_qty') { // Ajout / Mise à jour d'un prix par quantité - $result = $object->fetch($id); - - // Récupération des variables - $rowid = GETPOST('rowid'); - $priceid = GETPOST('priceid'); - $newprice = price2num(GETPOST("price"), 'MU'); - // $newminprice=price2num(GETPOST("price_min"),'MU'); // TODO : Add min price management - $quantity = GETPOST('quantity'); - $remise_percent = price2num(GETPOST('remise_percent')); - $remise = 0; // TODO : allow discount by amount when available on documents - - if (empty($quantity)) { - $error ++; - setEventMessage($langs->trans("ErrorFieldRequired", $langs->transnoentities("Qty")), 'errors'); - } - if (empty($newprice)) { - $error ++; - setEventMessage($langs->trans("ErrorFieldRequired", $langs->transnoentities("Price")), 'errors'); - } - if (! $error) { - // Calcul du prix HT et du prix unitaire - if ($object->price_base_type == 'TTC') { - $price = price2num($newprice) / (1 + ($object->tva_tx / 100)); - } - - $price = price2num($newprice, 'MU'); - $unitPrice = price2num($price / $quantity, 'MU'); - - // Ajout / mise à jour - if ($rowid > 0) { - $sql = "UPDATE " . MAIN_DB_PREFIX . "product_price_by_qty SET"; - $sql .= " price='" . $price . "',"; - $sql .= " unitprice=" . $unitPrice . ","; - $sql .= " quantity=" . $quantity . ","; - $sql .= " remise_percent=" . $remise_percent . ","; - $sql .= " remise=" . $remise; - $sql .= " WHERE rowid = " . GETPOST('rowid'); - - $result = $db->query($sql); - } else { - $sql = "INSERT INTO " . MAIN_DB_PREFIX . "product_price_by_qty (fk_product_price,price,unitprice,quantity,remise_percent,remise) values ("; - $sql .= $priceid . ',' . $price . ',' . $unitPrice . ',' . $quantity . ',' . $remise_percent . ',' . $remise . ')'; - - $result = $db->query($sql); } } -} -if ($action == 'delete_price_by_qty') { - $rowid = GETPOST('rowid'); - - $sql = "DELETE FROM " . MAIN_DB_PREFIX . "product_price_by_qty"; - $sql .= " WHERE rowid = " . GETPOST('rowid'); - - $result = $db->query($sql); -} - -if ($action == 'delete_all_price_by_qty') { - $priceid = GETPOST('priceid'); - - $sql = "DELETE FROM " . MAIN_DB_PREFIX . "product_price_by_qty"; - $sql .= " WHERE fk_product_price = " . $priceid; - - $result = $db->query($sql); -} - -/** - * *************************************************** - * Price by customer - * **************************************************** - */ -if ($action == 'add_customer_price_confirm' && ! $_POST ["cancel"] && ($user->rights->produit->creer || $user->rights->service->creer)) { - - $error=0; - $maxpricesupplier = $object->min_recommended_price(); - - $update_child_soc = GETPOST('updatechildprice'); - - $result = $object->fetch($id); - - // add price by customer - $prodcustprice->fk_soc = GETPOST('socid', 'int'); - $prodcustprice->fk_product = $object->id; - $prodcustprice->price = price2num(GETPOST("price"), 'MU'); - $prodcustprice->price_min = price2num(GETPOST("price_min"), 'MU'); - $prodcustprice->price_base_type = GETPOST("price_base_type", 'alpha'); - $prodcustprice->tva_tx = str_replace('*', '', GETPOST("tva_tx")); - $prodcustprice->recuperableonly = (preg_match('/\*/', GETPOST("tva_tx")) ? 1 : 0); - - if (! empty($conf->global->PRODUCT_MINIMUM_RECOMMENDED_PRICE) && $prodcustprice->price_min<$maxpricesupplier) - { - setEventMessage($langs->trans("MinimumPriceLimit",price($maxpricesupplier,0,'',1,-1,-1,'auto')),'errors'); - $error++; - $action='add_customer_price'; - } - - if (! $error) - { - $result = $prodcustprice->create($user, 0, $update_child_soc); + if ($action == 'delete_customer_price' && ($user->rights->produit->supprimer || $user->rights->service->supprimer)) { + // Delete price by customer + $prodcustprice->id = GETPOST('lineid'); + $result = $prodcustprice->delete($user); if ($result < 0) { - setEventMessage($prodcustprice->error, 'errors'); + setEventMessage($prodcustprice->error, 'mesgs'); } else { - setEventMessage($langs->trans('Save'), 'mesgs'); + setEventMessage($langs->trans('Delete'), 'errors'); } - $action = ''; } -} -if ($action == 'delete_customer_price' && ($user->rights->produit->supprimer || $user->rights->service->supprimer)) { - // Delete price by customer - $prodcustprice->id = GETPOST('lineid'); - $result = $prodcustprice->delete($user); + if ($action == 'update_customer_price_confirm' && !$cancel && ($user->rights->produit->creer || $user->rights->service->creer)) { - if ($result < 0) { - setEventMessage($prodcustprice->error, 'mesgs'); - } else { - setEventMessage($langs->trans('Delete'), 'errors'); - } - $action = ''; -} + $maxpricesupplier = $object->min_recommended_price(); -if ($action == 'update_customer_price_confirm' && ! $_POST ["cancel"] && ($user->rights->produit->creer || $user->rights->service->creer)) { + $update_child_soc = GETPOST('updatechildprice'); - $result = $object->fetch($id); + $prodcustprice->fetch(GETPOST('lineid', 'int')); - $error=0; - $maxpricesupplier = $object->min_recommended_price(); + // update price by customer + $prodcustprice->price = price2num(GETPOST("price"), 'MU'); + $prodcustprice->price_min = price2num(GETPOST("price_min"), 'MU'); + $prodcustprice->price_base_type = GETPOST("price_base_type", 'alpha'); + $prodcustprice->tva_tx = str_replace('*', '', GETPOST("tva_tx")); + $prodcustprice->recuperableonly = (preg_match('/\*/', GETPOST("tva_tx")) ? 1 : 0); - $update_child_soc = GETPOST('updatechildprice'); - - $prodcustprice->fetch(GETPOST('lineid', 'int')); - - // update price by customer - $prodcustprice->price = price2num(GETPOST("price"), 'MU'); - $prodcustprice->price_min = price2num(GETPOST("price_min"), 'MU'); - $prodcustprice->price_base_type = GETPOST("price_base_type", 'alpha'); - $prodcustprice->tva_tx = str_replace('*', '', GETPOST("tva_tx")); - $prodcustprice->recuperableonly = (preg_match('/\*/', GETPOST("tva_tx")) ? 1 : 0); - - if ($prodcustprice->price_min<$maxpricesupplier && !empty($conf->global->PRODUCT_MINIMUM_RECOMMENDED_PRICE)) - { - setEventMessage($langs->trans("MinimumPriceLimit",price($maxpricesupplier,0,'',1,-1,-1,'auto')),'errors'); - $error++; - $action='update_customer_price'; - } - - if ( ! $error) - { - $result = $prodcustprice->update($user, 0, $update_child_soc); - - if ($result < 0) { - setEventMessage($prodcustprice->error, 'errors'); - } else { - setEventMessage($langs->trans('Save'), 'mesgs'); + if ($prodcustprice->price_min<$maxpricesupplier && !empty($conf->global->PRODUCT_MINIMUM_RECOMMENDED_PRICE)) + { + setEventMessage($langs->trans("MinimumPriceLimit",price($maxpricesupplier,0,'',1,-1,-1,'auto')),'errors'); + $error++; + $action='update_customer_price'; } - $action = ''; + if ( ! $error) + { + $result = $prodcustprice->update($user, 0, $update_child_soc); + + if ($result < 0) { + setEventMessage($prodcustprice->error, 'errors'); + } else { + setEventMessage($langs->trans('Save'), 'mesgs'); + } + + $action = ''; + } } } + /* * View */ $form = new Form($db); -if (! empty($id) || ! empty($ref)) - $result = $object->fetch($id, $ref); - llxHeader("", "", $langs->trans("CardProduct" . $object->type)); $head = product_prepare_head($object); @@ -687,7 +689,7 @@ if ($action == 'edit_price' && ($user->rights->produit->creer || $user->rights-> print $langs->trans('PriceBase'); print ''; print ''; - print $form->select_PriceBaseType($object->price_base_type, "price_base_type"); + print $form->selectPriceBaseType($object->price_base_type, "price_base_type"); print ''; print ''; @@ -793,7 +795,7 @@ if ($action == 'edit_price' && ($user->rights->produit->creer || $user->rights-> } else { print ''; } - print $form->select_PriceBaseType($object->multiprices_base_type ["$i"], "multiprices_base_type_" . $i); + print $form->selectPriceBaseType($object->multiprices_base_type ["$i"], "multiprices_base_type_" . $i); print ''; // Min price @@ -1010,7 +1012,7 @@ if (! empty($conf->global->PRODUIT_CUSTOMER_PRICES)) print $langs->trans('PriceBase'); print ''; print ''; - print $form->select_PriceBaseType($object->price_base_type, "price_base_type"); + print $form->selectPriceBaseType($object->price_base_type, "price_base_type"); print ''; print ''; @@ -1094,7 +1096,7 @@ if (! empty($conf->global->PRODUIT_CUSTOMER_PRICES)) print $langs->trans('PriceBase'); print ''; print ''; - print $form->select_PriceBaseType($prodcustprice->price_base_type, "price_base_type"); + print $form->selectPriceBaseType($prodcustprice->price_base_type, "price_base_type"); print ''; print ''; diff --git a/htdocs/projet/list.php b/htdocs/projet/list.php index ef80873d03e..4464c9cb8ef 100644 --- a/htdocs/projet/list.php +++ b/htdocs/projet/list.php @@ -258,7 +258,7 @@ if ($resql) print_liste_field_titre($langs->trans("DateEnd"),$_SERVER["PHP_SELF"],"p.datee","",$param,'align="center"',$sortfield,$sortorder); print_liste_field_titre($langs->trans("Visibility"),$_SERVER["PHP_SELF"],"p.public","",$param,"",$sortfield,$sortorder); print_liste_field_titre($langs->trans("Status"),$_SERVER["PHP_SELF"],'p.fk_statut',"",$param,'align="right"',$sortfield,$sortorder); - print ' '; + print_liste_field_titre(''); print "\n"; print ''; diff --git a/htdocs/public/demo/index.php b/htdocs/public/demo/index.php index 956bcac8b75..4b0c0526174 100644 --- a/htdocs/public/demo/index.php +++ b/htdocs/public/demo/index.php @@ -41,7 +41,7 @@ $conf->dol_use_jmobile=GETPOST('dol_use_jmobile','int'); // Security check global $dolibarr_main_demo; -if (empty($dolibarr_main_demo)) accessforbidden('Parameter dolibarr_main_demo must be defined in conf file with value "default login,default pass" to enable the demo entry page',1,1,1); +if (empty($dolibarr_main_demo)) accessforbidden('Parameter dolibarr_main_demo must be defined in conf file with value "default login,default pass" to enable the demo entry page',0,0,1); // Initialize technical object to manage hooks of thirdparties. Note that conf->hooks_modules contains array array $res=$hookmanager->initHooks(array('demo')); diff --git a/htdocs/public/donations/therm.php b/htdocs/public/donations/therm.php deleted file mode 100644 index 7c24253dd71..00000000000 --- a/htdocs/public/donations/therm.php +++ /dev/null @@ -1,54 +0,0 @@ - - * Copyright (C) 2008 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 . - */ - -/** - * \file htdocs/public/donations/therm.php - * \ingroup donation - * \brief Screen with thermometer - */ - -define("NOLOGIN",1); // This means this output page does not require to be logged. -define("NOCSRFCHECK",1); // We accept to go on this page from external web site. - -require '../../main.inc.php'; -require_once DOL_DOCUMENT_ROOT.'/core/lib/images.lib.php'; -require_once DOL_DOCUMENT_ROOT.'/don/class/don.class.php'; - -// Security check -if (empty($conf->don->enabled)) accessforbidden('',1,1,1); - - - -/* - * View (output an image) - */ - -$dontherm = new Don($db); - -$intentValue = $dontherm->sum_donations(1); -$pendingValue = $dontherm->sum_donations(2); -$actualValue = $dontherm->sum_donations(3); - -$db->close(); - - -/* - * Graph thermometer - */ -print moneyMeter($actualValue, $pendingValue, $intentValue); - diff --git a/htdocs/public/members/public_card.php b/htdocs/public/members/public_card.php index fd745e523c9..fc96ffed01c 100644 --- a/htdocs/public/members/public_card.php +++ b/htdocs/public/members/public_card.php @@ -65,7 +65,11 @@ $extrafields = new ExtraFields($db); * View */ -llxHeaderVierge($langs->trans("MemberCard")); +$morehead=''; +if (! empty($conf->global->MEMBER_PUBLIC_CSS)) $morehead=''; +else $morehead=''; + +llxHeaderVierge($langs->trans("MemberCard"), $morehead); // fetch optionals attributes and labels $extralabels=$extrafields->fetch_name_optionals_label('adherent'); @@ -75,7 +79,7 @@ if ($id > 0) if ($res < 0) { dol_print_error($db,$object->error); exit; } $res=$object->fetch_optionals($object->id,$extralabels); - print_titre($langs->trans("MemberCard")); + print_fiche_titre($langs->trans("MemberCard"), '', ''); if (empty($object->public)) { @@ -83,7 +87,7 @@ if ($id > 0) } else { - print ''; + print '
'; print '\n"; print ''; @@ -138,7 +142,7 @@ function llxHeaderVierge($title, $head = "") print "".$title."\n"; if ($head) print $head."\n"; print "\n"; - print "\n"; + print ''."\n"; } /** diff --git a/htdocs/public/members/public_list.php b/htdocs/public/members/public_list.php index e672a6d59d3..9064dd52879 100644 --- a/htdocs/public/members/public_list.php +++ b/htdocs/public/members/public_list.php @@ -62,7 +62,7 @@ function llxHeaderVierge($title, $head = "") print "".$title."\n"; if ($head) print $head."\n"; print "\n"; - print "\n"; + print ''."\n"; } /** @@ -98,7 +98,13 @@ if (! $sortfield) { $sortfield="lastname"; } * View */ -llxHeaderVierge($langs->trans("ListOfValidatedPublicMembers")); +$form = new Form($db); + +$morehead=''; +if (! empty($conf->global->MEMBER_PUBLIC_CSS)) $morehead=''; +else $morehead=''; + +llxHeaderVierge($langs->trans("ListOfValidatedPublicMembers"), $morehead); $sql = "SELECT rowid, firstname, lastname, societe, zip, town, email, birth, photo"; $sql.= " FROM ".MAIN_DB_PREFIX."adherent"; @@ -120,17 +126,16 @@ if ($result) $param="&statut=$statut&sortorder=$sortorder&sortfield=$sortfield"; print_barre_liste($langs->trans("ListOfValidatedPublicMembers"), $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, '', $num, 0, ''); - print '
'.$langs->trans("Type").''.$object->type."
'.$langs->trans("Person").''.$object->morphy.'
'; + print '
'; - print ''; - print ''."\n"; + print ''; + print ''; + print ''."\n"; //print_liste_field_titre($langs->trans("DateToBirth"), $_SERVER["PHP_SELF"],"birth",'',$param,$sortfield,$sortorder); // est-ce nécessaire ?? - print_liste_field_titre($langs->trans("EMail"), $_SERVER["PHP_SELF"],"email",'',$param,$sortfield,$sortorder); - print_liste_field_titre($langs->trans("Zip"), $_SERVER["PHP_SELF"],"zip","",$param,$sortfield,$sortorder); - print_liste_field_titre($langs->trans("Town"), $_SERVER["PHP_SELF"],"town","",$param,$sortfield,$sortorder); - print "\n"; + print_liste_field_titre($langs->trans("EMail"), $_SERVER["PHP_SELF"],"email",'',$param,'',$sortfield,$sortorder,'public_'); + print_liste_field_titre($langs->trans("Zip"), $_SERVER["PHP_SELF"],"zip","",$param,'',$sortfield,$sortorder,'public_'); + print_liste_field_titre($langs->trans("Town"), $_SERVER["PHP_SELF"],"town","",$param,'',$sortfield,$sortorder,'public_'); + print_liste_field_titre($langs->trans("Photo"), $_SERVER["PHP_SELF"],"","",$param,'',$sortfield,$sortorder,'public_'); print "\n"; $var=True; @@ -139,13 +144,13 @@ if ($result) $objp = $db->fetch_object($result); $var=!$var; print ""; - print ''."\n"; + print ''."\n"; + print ''."\n"; print ''."\n"; print ''."\n"; print ''."\n"; if (isset($objp->photo) && $objp->photo != '') { - $form = new Form($db); print ''."\n"; @@ -165,6 +170,6 @@ else } -$db->close(); - llxFooterVierge(); + +$db->close(); diff --git a/htdocs/public/test/test_arrays.php b/htdocs/public/test/test_arrays.php index 9f0cec70e62..698046cf708 100644 --- a/htdocs/public/test/test_arrays.php +++ b/htdocs/public/test/test_arrays.php @@ -148,6 +148,39 @@ print_barre_liste('Title of my list', 3, $_SERVER["PHP_SELF"], '', '', '', 'Text ?>
'.$langs->trans("Firstname").''; - print ' '.$langs->trans("Lastname").''; - print ' / '.$langs->trans("Company").'
'.dolGetFirstLastname($langs->trans("Firstname"),$langs->trans("Lastname")).''.$langs->trans("Company").'".$langs->trans("Photo")."
'.dolGetFirstLastname($obj->firstname, $obj->lastname).($objp->societe?' / '.$objp->societe:'').''.dolGetFirstLastname($objp->firstname, $objp->lastname).''.$objp->societe.''.$objp->email.''.$objp->zip.''.$objp->town.''; print $form->showphoto('memberphoto', $objp, 64); print '
+'; +$moreforfilter.=$langs->trans('This is a select list for a filter A'). ': '; +$cate_arbo = array('field1'=>'value1a into the select list A','field2'=>'value2a'); +$moreforfilter.=$form->selectarray('search_aaa', $cate_arbo, '', 1); // List without js combo +$moreforfilter.=''; + +$moreforfilter.='
'; +$moreforfilter.=$langs->trans('This is a select list for a filter B'). ': '; +$cate_arbo = array('field1'=>'value1b into the select list B','field2'=>'value2b'); +$moreforfilter.=$form->selectarray('search_bbb', $cate_arbo, '', 1, 0, 0, '', 0, 0, 0, 0, '', 1); // List with js combo +$moreforfilter.='
'; + +$moreforfilter.='
'; +$moreforfilter.=$langs->trans('This is a select list for a filter C'). ': '; +$cate_arbo = array('field1'=>'value1c into the select list C','field2'=>'value2c'); +$moreforfilter.=$form->selectarray('search_ccc', $cate_arbo, '', 1, 0, 0, '', 0, 0, 0, 0, '', 1); // List with js combo +$moreforfilter.='
'; + +$moreforfilter.='
'; +$moreforfilter.=$langs->trans('This is a select list for a filter D'). ': '; +$cate_arbo = array('field1'=>'value1d into the select list D','field2'=>'value2d'); +$moreforfilter.=$form->selectarray('search_ddd', $cate_arbo, '', 1, 0, 0, '', 0, 0, 0, 0, '', 1); // List with js combo +$moreforfilter.='
'; + +if (! empty($moreforfilter)) +{ + print ''; + print ''; +} +?> trans('title1'),0,$_SERVER["PHP_SELF"],'aaa','','','align="left"',$sortfield,$sortorder); ?> trans('title2'),0,$_SERVER["PHP_SELF"],'bbb','','','align="right"',$sortfield,$sortorder); ?> diff --git a/htdocs/public/test/test_forms.php b/htdocs/public/test/test_forms.php index 0a99b11e3aa..a6a361620e9 100644 --- a/htdocs/public/test/test_forms.php +++ b/htdocs/public/test/test_forms.php @@ -75,7 +75,7 @@ print '

'."\n"; // Test4d: form->select_thirdparty print "Test 4d: Select thirdparty
\n"; -print $form->select_thirdparty(0,'thirdpartytest'); +print $form->select_company(0,'thirdpartytest'); print '

'."\n"; diff --git a/htdocs/public/theme/common/index.php b/htdocs/public/theme/common/index.php new file mode 100644 index 00000000000..0d25c726b33 --- /dev/null +++ b/htdocs/public/theme/common/index.php @@ -0,0 +1,29 @@ + + * Copyright (C) 2015 Raphaël Doursenaud + * + * 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/public/theme/common/index.php + * \ingroup core + * \brief A redirect page to an error + * \author Laurent Destailleur + */ + +require '../../../master.inc.php'; + +header("Location: ".DOL_URL_ROOT.'/public/error-404.php'); + diff --git a/htdocs/theme/common/nophoto.jpg b/htdocs/public/theme/common/nophoto.jpg similarity index 100% rename from htdocs/theme/common/nophoto.jpg rename to htdocs/public/theme/common/nophoto.jpg diff --git a/htdocs/theme/common/user_anonymous.png b/htdocs/public/theme/common/user_anonymous.png similarity index 100% rename from htdocs/theme/common/user_anonymous.png rename to htdocs/public/theme/common/user_anonymous.png diff --git a/htdocs/theme/common/user_man.png b/htdocs/public/theme/common/user_man.png similarity index 100% rename from htdocs/theme/common/user_man.png rename to htdocs/public/theme/common/user_man.png diff --git a/htdocs/theme/common/user_woman.png b/htdocs/public/theme/common/user_woman.png similarity index 100% rename from htdocs/theme/common/user_woman.png rename to htdocs/public/theme/common/user_woman.png diff --git a/htdocs/public/theme/index.php b/htdocs/public/theme/index.php new file mode 100644 index 00000000000..1d8c522741d --- /dev/null +++ b/htdocs/public/theme/index.php @@ -0,0 +1,29 @@ + + * Copyright (C) 2015 Raphaël Doursenaud + * + * 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/public/theme/index.php + * \ingroup core + * \brief A redirect page to an error + * \author Laurent Destailleur + */ + +require '../../master.inc.php'; + +header("Location: ".DOL_URL_ROOT.'/public/error-404.php'); + diff --git a/htdocs/societe/class/societe.class.php b/htdocs/societe/class/societe.class.php index bce15b081bb..4d55732b801 100644 --- a/htdocs/societe/class/societe.class.php +++ b/htdocs/societe/class/societe.class.php @@ -317,6 +317,7 @@ class Societe extends CommonObject * @var string */ var $note_public; + //! code statut prospect var $stcomm_id; var $statut_commercial; @@ -1044,7 +1045,7 @@ class Societe extends CommonObject $num=$this->db->num_rows($resql); if ($num > 1) { - $this->error='Fetch several records found for ref='.$ref; + $this->error='Fetch several records found request'; dol_syslog($this->error, LOG_ERR); $result = -2; } @@ -1301,13 +1302,15 @@ class Societe extends CommonObject * Delete a third party from database and all its dependencies (contacts, rib...) * * @param int $id Id of third party to delete - * @param User $user User who ask to delete thirparty + * @param User $fuser User who ask to delete thirparty * @param int $call_trigger 0=No, 1=yes - * @return int <0 if KO, 0 if nothing done, >0 if OK + * @return int <0 if KO, 0 if nothing done, >0 if OK */ - function delete($id, $user='', $call_trigger=1) + function delete($id, User $fuser=null, $call_trigger=1) { - global $langs, $conf; + global $langs, $conf, $user; + + if (empty($fuser)) $fuser=$user; require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; @@ -1323,10 +1326,10 @@ class Societe extends CommonObject $this->db->begin(); // User is mandatory for trigger call - if ($user && $call_trigger) + if ($call_trigger) { // Call trigger - $result=$this->call_trigger('COMPANY_DELETE',$user); + $result=$this->call_trigger('COMPANY_DELETE',$fuser); if ($result < 0) $error++; // End call triggers } @@ -1451,7 +1454,8 @@ class Societe extends CommonObject return 1; } else - { + { + dol_syslog($this->error, LOG_ERR); $this->db->rollback(); return -1; } diff --git a/htdocs/societe/price.php b/htdocs/societe/price.php index 0932144a860..500612d48ed 100644 --- a/htdocs/societe/price.php +++ b/htdocs/societe/price.php @@ -254,7 +254,7 @@ if (! empty($conf->global->PRODUIT_CUSTOMER_PRICES)) { print $langs->trans('PriceBase'); print ''; print ''; print ''; @@ -332,7 +332,7 @@ if (! empty($conf->global->PRODUIT_CUSTOMER_PRICES)) { print $langs->trans('PriceBase'); print ''; print ''; print ''; diff --git a/htdocs/societe/soc.php b/htdocs/societe/soc.php index ec9a63f64d4..70ec2a08a49 100644 --- a/htdocs/societe/soc.php +++ b/htdocs/societe/soc.php @@ -1849,7 +1849,7 @@ else 'name' => 'soc_origin', 'label' => $langs->trans('MergeOriginThirdparty'), 'type' => 'other', - 'value' => $form->select_thirdparty('', 'soc_origin', 's.rowid != '.$object->id) + 'value' => $form->select_company('', 'soc_origin', 's.rowid != '.$object->id) ) ); diff --git a/htdocs/societe/societe.php b/htdocs/societe/societe.php index 0a8ec08da1d..9ab7e921faa 100644 --- a/htdocs/societe/societe.php +++ b/htdocs/societe/societe.php @@ -338,7 +338,7 @@ if ($resql) print_liste_field_titre($form->textwithpicto($langs->trans("ProfId2Short"),$textprofid[2],1,0),$_SERVER["PHP_SELF"],"s.siret","",$params,'class="nowrap"',$sortfield,$sortorder); print_liste_field_titre($form->textwithpicto($langs->trans("ProfId3Short"),$textprofid[3],1,0),$_SERVER["PHP_SELF"],"s.ape","",$params,'class="nowrap"',$sortfield,$sortorder); print_liste_field_titre($form->textwithpicto($langs->trans("ProfId4Short"),$textprofid[4],1,0),$_SERVER["PHP_SELF"],"s.idprof4","",$params,'class="nowrap"',$sortfield,$sortorder); - print ''; + print_liste_field_titre(''); print_liste_field_titre($langs->trans("Status"),$_SERVER["PHP_SELF"],"s.status","",$params,'align="right"',$sortfield,$sortorder); print "\n"; diff --git a/htdocs/theme/eldy/style.css.php b/htdocs/theme/eldy/style.css.php index 15730ff89fb..03f4006a06b 100644 --- a/htdocs/theme/eldy/style.css.php +++ b/htdocs/theme/eldy/style.css.php @@ -453,6 +453,10 @@ textarea.centpercent { height: 28px; vertical-align: middle; } +div.divsearchfield { + float: ; + margin-: 12px; +} /* Style to move picto into left of button */ /* @@ -1976,9 +1980,12 @@ table.liste td { /* Pagination */ -div.refid { +div.refidpadding { padding-top: dol_use_jmobile)?'8':'12'; ?>px; - font-weight: bold; +} +div.refid { + padding-top: dol_use_jmobile)?'5':'12'; ?>px; + font-weight: bold; color: #766; font-size: 120%; } @@ -3542,6 +3549,18 @@ border-top-right-radius: 6px; } + +/* The theme for public pages */ +.public_body { + margin: 20px; +} +.public_border { + border: 1px solid #888; +} +.public_liste_titre { + + + /* CSS style used for small screen */ .imgopensurveywizard @@ -3553,5 +3572,7 @@ border-top-right-radius: 6px; .imgopensurveywizard { width:95%; height: auto; } } + + close(); diff --git a/htdocs/user/class/user.class.php b/htdocs/user/class/user.class.php index 4d7a3d18a5c..b55723d3735 100644 --- a/htdocs/user/class/user.class.php +++ b/htdocs/user/class/user.class.php @@ -4,7 +4,7 @@ * Copyright (c) 2004-2012 Laurent Destailleur * Copyright (C) 2004 Sebastien Di Cintio * Copyright (C) 2004 Benoit Mortier - * Copyright (C) 2005-2012 Regis Houssin + * Copyright (C) 2005-2015 Regis Houssin * Copyright (C) 2005 Lionel Cousteix * Copyright (C) 2011 Herve Prot * Copyright (C) 2013-2014 Philippe Grand @@ -1823,6 +1823,7 @@ class User extends CommonObject { global $langs, $conf, $db; global $dolibarr_main_authentication, $dolibarr_main_demo; + global $menumanager; $result = ''; @@ -1833,7 +1834,6 @@ class User extends CommonObject $label.= '' . $langs->trans('Name') . ': ' . $this->getFullName($langs,'',''); if (! empty($this->login)) $label.= '
' . $langs->trans('Login') . ': ' . $this->login; - if (! empty($this->email)) $label.= '
' . $langs->trans("EMail").': '.$this->email; if (! empty($this->admin)) $label.= '
' . $langs->trans("Administrator").': '.yn($this->admin); diff --git a/htdocs/viewimage.php b/htdocs/viewimage.php index 9e22bb94cc2..f9f2b54b292 100644 --- a/htdocs/viewimage.php +++ b/htdocs/viewimage.php @@ -173,7 +173,7 @@ else // Open and return file // This test is to avoid error images when image is not available (for example thumbs). if (! dol_is_file($original_file)) { - $original_file=DOL_DOCUMENT_ROOT.'/theme/common/nophoto.jpg'; + $original_file=DOL_DOCUMENT_ROOT.'/public/theme/common/nophoto.jpg'; /*$error='Error: File '.$_GET["file"].' does not exists or filesystems permissions are not allowed'; dol_print_error(0,$error); print $error; diff --git a/htdocs/webservices/server_contact.php b/htdocs/webservices/server_contact.php index 066c9f38b6c..f439e791cb4 100644 --- a/htdocs/webservices/server_contact.php +++ b/htdocs/webservices/server_contact.php @@ -272,7 +272,7 @@ function getContact($authentication,$id,$ref_ext) ){ $contact_result_fields =array( 'id' => $contact->id, - 'ref_ext' => $contact->ref_ext, + 'ref_ext' => $contact->ref_ext, 'lastname' => $contact->lastname, 'firstname' => $contact->firstname, 'address' => $contact->address, @@ -334,7 +334,7 @@ function getContact($authentication,$id,$ref_ext) else { $error++; - $errorcode='NOT_FOUND'; $errorlabel='Object not found for id='.$id.' nor ref='.$ref.' nor ref_ext='.$ref_ext; + $errorcode='NOT_FOUND'; $errorlabel='Object not found for id='.$id.' nor ref_ext='.$ref_ext; } } @@ -615,9 +615,15 @@ function updateContact($authentication,$contact) $error=0; $fuser=check_authentication($authentication,$error,$errorcode,$errorlabel); // Check parameters - if (empty($contact['id'])) { - $error++; $errorcode='KO'; $errorlabel="Contact id is mandatory."; + if (empty($contact['id']) && empty($contact['ref_ext'])) { + $error++; $errorcode='KO'; $errorlabel="Contact id or ref_ext is mandatory."; } + // Check parameters + if (! $error && ($id && $ref_ext)) + { + $error++; + $errorcode='BAD_PARAMETERS'; $errorlabel="Parameter id and ref_ext can't be all provided. You must choose one of them."; + } if (! $error) { @@ -626,7 +632,7 @@ function updateContact($authentication,$contact) include_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php'; $object=new Contact($db); - $result=$object->fetch($contact['id']); + $result=$object->fetch($contact['id'],0,$contact['ref_ext']); if (!empty($object->id)) { diff --git a/htdocs/webservices/server_invoice.php b/htdocs/webservices/server_invoice.php index 3c1a122fa6f..4a495607a29 100644 --- a/htdocs/webservices/server_invoice.php +++ b/htdocs/webservices/server_invoice.php @@ -102,7 +102,6 @@ $server->wsdl->addComplexType( 'total' => array('name'=>'total','type'=>'xsd:double'), 'date_start' => array('name'=>'date_start','type'=>'xsd:date'), 'date_end' => array('name'=>'date_end','type'=>'xsd:date'), - 'payment_mode_id' => array('name'=>'payment_mode_id','type'=>'xsd:string'), // From product 'product_id' => array('name'=>'product_id','type'=>'xsd:int'), 'product_ref' => array('name'=>'product_ref','type'=>'xsd:string'), @@ -160,6 +159,7 @@ $server->wsdl->addComplexType( 'date_creation' => array('name'=>'date_creation','type'=>'xsd:dateTime'), 'date_validation' => array('name'=>'date_validation','type'=>'xsd:dateTime'), 'date_modification' => array('name'=>'date_modification','type'=>'xsd:dateTime'), + 'payment_mode_id' => array('name'=>'payment_mode_id','type'=>'xsd:string'), 'type' => array('name'=>'type','type'=>'xsd:int'), 'total_net' => array('name'=>'type','type'=>'xsd:double'), 'total_vat' => array('name'=>'type','type'=>'xsd:double'), @@ -243,13 +243,37 @@ $server->register( // Entry values array('authentication'=>'tns:authentication','invoice'=>'tns:invoice'), // Exit values - array('result'=>'tns:result','id'=>'xsd:string','ref'=>'xsd:string'), + array('result'=>'tns:result','id'=>'xsd:string','ref'=>'xsd:string','ref_ext'=>'xsd:string'), $ns, $ns.'#createInvoice', $styledoc, $styleuse, 'WS to create an invoice' ); +$server->register( + 'createInvoiceFromOrder', + // Entry values + array('authentication'=>'tns:authentication','invoice'=>'tns:invoice'), + // Exit values + array('result'=>'tns:result','invoice'=>'tns:invoice'), + $ns, + $ns.'#createInvoiceFromOrder', + $styledoc, + $styleuse, + 'WS to create an invoice from an order' +); +$server->register( + 'updateInvoice', + // Entry values + array('authentication'=>'tns:authentication','invoice'=>'tns:invoice'), + // Exit values + array('result'=>'tns:result','id'=>'xsd:string','ref'=>'xsd:string','ref_ext'=>'xsd:string'), + $ns, + $ns.'#updateInvoice', + $styledoc, + $styleuse, + 'WS to update an invoice' +); /** @@ -299,15 +323,19 @@ function getInvoice($authentication,$id='',$ref='',$ref_ext='') $linesresp[]=array( 'id'=>$line->rowid, 'type'=>$line->product_type, - 'desc'=>dol_htmlcleanlastbr($line->desc), - 'total_net'=>$line->total_ht, - 'total_vat'=>$line->total_tva, - 'total'=>$line->total_ttc, - 'vat_rate'=>$line->tva_tx, - 'qty'=>$line->qty, - 'product_ref'=>$line->product_ref, - 'product_label'=>$line->product_label, - 'product_desc'=>$line->product_desc, + 'desc'=>dol_htmlcleanlastbr($line->desc), + 'total_net'=>$line->total_ht, + 'total_vat'=>$line->total_tva, + 'total'=>$line->total_ttc, + 'vat_rate'=>$line->tva_tx, + 'qty'=>$line->qty, + 'unitprice'=> $line->subprice, + 'date_start'=> $line->date_start?dol_print_date($line->date_start,'dayrfc'):'', + 'date_end'=> $line->date_end?dol_print_date($line->date_end,'dayrfc'):'', + 'product_id'=>$line->fk_product, + 'product_ref'=>$line->product_ref, + 'product_label'=>$line->product_label, + 'product_desc'=>$line->product_desc, ); $i++; } @@ -319,9 +347,11 @@ function getInvoice($authentication,$id='',$ref='',$ref_ext='') 'id' => $invoice->id, 'ref' => $invoice->ref, 'ref_ext' => $invoice->ref_ext?$invoice->ref_ext:'', // If not defined, field is not added into soap + 'thirdparty_id' => $invoice->socid, 'fk_user_author' => $invoice->user_author?$invoice->user_author:'', 'fk_user_valid' => $invoice->user_valid?$invoice->user_valid:'', 'date' => $invoice->date?dol_print_date($invoice->date,'dayrfc'):'', + 'date_due' => $invoice->date_lim_reglement?dol_print_date($invoice->date_lim_reglement,'dayrfc'):'', 'date_creation' => $invoice->date_creation?dol_print_date($invoice->date_creation,'dayhourrfc'):'', 'date_validation' => $invoice->date_validation?dol_print_date($invoice->date_creation,'dayhourrfc'):'', 'date_modification' => $invoice->datem?dol_print_date($invoice->datem,'dayhourrfc'):'', @@ -331,7 +361,8 @@ function getInvoice($authentication,$id='',$ref='',$ref_ext='') 'total' => $invoice->total_ttc, 'note_private' => $invoice->note_private?$invoice->note_private:'', 'note_public' => $invoice->note_public?$invoice->note_public:'', - 'status'=> $invoice->statut, + 'status' => $invoice->statut, + 'project_id' => $invoic->fk_project, 'close_code' => $invoice->close_code?$invoice->close_code:'', 'close_note' => $invoice->close_note?$invoice->close_note:'', 'payment_mode_id' => $invoice->mode_reglement_id?$invoice->mode_reglement_id:'', @@ -387,7 +418,7 @@ function getInvoicesForThirdParty($authentication,$idthirdparty) if (! $error && empty($idthirdparty)) { $error++; - $errorcode='BAD_PARAMETERS'; $errorlabel='Parameter id is not provided'; + $errorcode='BAD_PARAMETERS'; $errorlabel='Parameter idthirdparty is not provided'; } if (! $error) @@ -433,6 +464,10 @@ function getInvoicesForThirdParty($authentication,$idthirdparty) 'total'=>$line->total_ttc, 'vat_rate'=>$line->tva_tx, 'qty'=>$line->qty, + 'unitprice'=> $line->subprice, + 'date_start'=> $line->date_start?dol_print_date($line->date_start,'dayrfc'):'', + 'date_end'=> $line->date_end?dol_print_date($line->date_end,'dayrfc'):'', + 'product_id'=>$line->fk_product, 'product_ref'=>$line->product_ref, 'product_label'=>$line->product_label, 'product_desc'=>$line->product_desc, @@ -448,7 +483,7 @@ function getInvoicesForThirdParty($authentication,$idthirdparty) 'fk_user_valid' => $invoice->user_valid?$invoice->user_valid:'', 'date' => $invoice->date?dol_print_date($invoice->date,'dayrfc'):'', 'date_due' => $invoice->date_lim_reglement?dol_print_date($invoice->date_lim_reglement,'dayrfc'):'', - 'date_creation' => $invoice->date_creation?dol_print_date($invoice->date_creation,'dayhourrfc'):'', + 'date_creation' => $invoice->date_creation?dol_print_date($invoice->date_creation,'dayhourrfc'):'', 'date_validation' => $invoice->date_validation?dol_print_date($invoice->date_creation,'dayhourrfc'):'', 'date_modification' => $invoice->datem?dol_print_date($invoice->datem,'dayhourrfc'):'', 'type' => $invoice->type, @@ -458,9 +493,10 @@ function getInvoicesForThirdParty($authentication,$idthirdparty) 'note_private' => $invoice->note_private?$invoice->note_private:'', 'note_public' => $invoice->note_public?$invoice->note_public:'', 'status'=> $invoice->statut, + 'project_id' => $invoic->fk_project, 'close_code' => $invoice->close_code?$invoice->close_code:'', 'close_note' => $invoice->close_note?$invoice->close_note:'', - 'payment_mode_id' => $invoice->mode_reglement_id?$invoice->mode_reglement_id:'', + 'payment_mode_id' => $invoice->mode_reglement_id?$invoice->mode_reglement_id:'', 'lines' => $linesresp ); } @@ -503,7 +539,8 @@ function createInvoice($authentication,$invoice) $now=dol_now(); - dol_syslog("Function: createInvoiceForThirdParty login=".$authentication['login']); + dol_syslog("Function: createInvoice login=".$authentication['login']." id=".$invoice->id. + ", ref=".$invoice->ref.", ref_ext=".$invoice->ref_ext); if ($authentication['entity']) $conf->entity=$authentication['entity']; @@ -513,27 +550,32 @@ function createInvoice($authentication,$invoice) $error=0; $fuser=check_authentication($authentication,$error,$errorcode,$errorlabel); + // Check parameters + if (empty($invoice['id']) && empty($invoice['ref']) && empty($invoice['ref_ext'])) { + $error++; $errorcode='KO'; $errorlabel="Invoice id or ref or ref_ext is mandatory."; + } + if (! $error) { - $newobject=new Facture($db); - $newobject->socid=$invoice['thirdparty_id']; - $newobject->type=$invoice['type']; - $newobject->ref_ext=$invoice['ref_ext']; - $newobject->date=dol_stringtotime($invoice['date'],'dayrfc'); - $newobject->note_private=$invoice['note_private']; - $newobject->note_public=$invoice['note_public']; - $newobject->statut= Facture::STATUS_DRAFT; // We start with status draft - $newobject->fk_project=$invoice['project_id']; - $newobject->date_creation=$now; + $new_invoice=new Facture($db); + $new_invoice->socid=$invoice['thirdparty_id']; + $new_invoice->type=$invoice['type']; + $new_invoice->ref_ext=$invoice['ref_ext']; + $new_invoice->date=dol_stringtotime($invoice['date'],'dayrfc'); + $new_invoice->note_private=$invoice['note_private']; + $new_invoice->note_public=$invoice['note_public']; + $new_invoice->statut= Facture::STATUS_DRAFT; // We start with status draft + $new_invoice->fk_project=$invoice['project_id']; + $new_invoice->date_creation=$now; //take mode_reglement and cond_reglement from thirdparty $soc = new Societe($db); - $res=$soc->fetch($newobject->socid); + $res=$soc->fetch($new_invoice->socid); if ($res > 0) { - $newobject->mode_reglement_id = ! empty($invoice['payment_mode_id'])?$invoice['payment_mode_id']:$soc->mode_reglement_id; - $newobject->cond_reglement_id = $soc->cond_reglement_id; + $new_invoice->mode_reglement_id = ! empty($invoice['payment_mode_id'])?$invoice['payment_mode_id']:$soc->mode_reglement_id; + $new_invoice->cond_reglement_id = $soc->cond_reglement_id; } - else $newobject->mode_reglement_id = $invoice['payment_mode_id']; + else $new_invoice->mode_reglement_id = $invoice['payment_mode_id']; // Trick because nusoap does not store data with same structure if there is one or several lines $arrayoflines=array(); @@ -556,22 +598,22 @@ function createInvoice($authentication,$invoice) $newline->date_start=dol_stringtotime($line['date_start']); $newline->date_end=dol_stringtotime($line['date_end']); $newline->fk_product=$line['product_id']; - $newobject->lines[]=$newline; + $new_invoice->lines[]=$newline; } //var_dump($newobject->date_lim_reglement); exit; //var_dump($invoice['lines'][0]['type']); $db->begin(); - $result=$newobject->create($fuser,0,dol_stringtotime($invoice['date_due'],'dayrfc')); + $result=$new_invoice->create($fuser,0,dol_stringtotime($invoice['date_due'],'dayrfc')); if ($result < 0) { $error++; } - if ($invoice['status'] == 1) // We want invoice to have status validated + if (!$error && $invoice['status'] == Facture::STATUS_VALIDATED) // We want invoice to have status validated { - $result=$newobject->validate($fuser); + $result=$new_invoice->validate($fuser); if ($result < 0) { $error++; @@ -581,14 +623,16 @@ function createInvoice($authentication,$invoice) if (! $error) { $db->commit(); - $objectresp=array('result'=>array('result_code'=>'OK', 'result_label'=>''),'id'=>$newobject->id,'ref'=>$newobject->ref); + $objectresp=array('result'=>array('result_code'=>'OK', 'result_label'=>''),'id'=>$new_invoice->id, + 'ref'=>$new_invoice->ref,'ref_ext'=>$new_invoice->ref_ext); } else { $db->rollback(); $error++; $errorcode='KO'; - $errorlabel=$newobject->error; + $errorlabel=$new_invoice->error; + dol_syslog("Function: createInvoice error while creating".$errorlabel); } } @@ -601,5 +645,197 @@ function createInvoice($authentication,$invoice) return $objectresp; } +/** + * Create an invoice from an order + * + * @param array $authentication Array of authentication information + * @param string $id_order id of order to copy invoice from + * @param string $ref_order ref of order to copy invoice from + * @param string $ref_ext_order ref_ext of order to copy invoice from + * @param string $id_invoice invoice id + * @param string $ref_invoice invoice ref + * @param string $ref_ext_invoice invoice ref_ext + * @return array Array result + */ +function createInvoiceFromOrder($authentication,$id_order='', $ref_order='', $ref_ext_order='', + $id_invoice='', $ref_invoice='', $ref_ext_invoice='') +{ + global $db,$conf,$langs; + + $now=dol_now(); + + dol_syslog("Function: createInvoiceFromOrder login=".$authentication['login']." id=".$id_order. + ", ref=".$ref_order.", ref_ext=".$ref_ext_order); + + if ($authentication['entity']) $conf->entity=$authentication['entity']; + + // Init and check authentication + $objectresp=array(); + $errorcode='';$errorlabel=''; + $error=0; + $fuser=check_authentication($authentication,$error,$errorcode,$errorlabel); + + // Check parameters + if (empty($id_order) && empty($ref_order) && empty($ref_ext_order)) { + $error++; $errorcode='KO'; $errorlabel="order id or ref or ref_ext is mandatory."; + } else if (empty($id_invoice) && empty($ref_invoice) && empty($ref_ext_invoice)) { + $error++; $errorcode='KO'; $errorlabel="invoice id or ref or ref_ext is mandatory."; + } + + ////////////////////// + if (! $error) + { + $fuser->getrights(); + + if ($fuser->rights->commande->lire) + { + $order=new Commande($db); + $result=$order->fetch($id,$ref,$ref_ext); + if ($result > 0) + { + // Security for external user + if( $socid && ( $socid != $order->socid) ) + { + $error++; + $errorcode='PERMISSION_DENIED'; $errorlabel=$order->socid.'User does not have permission for this request'; + } + + if(!$error) + { + + $newobject=new Facture($db); + $result = $newobject->createFromOrder($order); + + if ($result < 0) + { + $error++; + dol_syslog("Webservice server_invoice:: invoice creation from order failed", LOG_ERR); + } + + } + } + else + { + $error++; + $errorcode='NOT_FOUND'; $errorlabel='Object not found for id='.$id_order.' nor ref='.$ref_order.' nor ref_ext='.$ref_ext_order; + } + } + else + { + $error++; + $errorcode='PERMISSION_DENIED'; $errorlabel='User does not have permission for this request'; + } + } + + if ($error) + { + $objectresp = array('result'=>array('result_code' => $errorcode, 'result_label' => $errorlabel)); + } + else + { + $objectresp = array('result'=>array('result_code'=>'OK', 'result_label'=>''),'invoice'=>$newobject); + + } + + return $objectresp; +} + +/** + * Uddate an invoice, only change the state of an invoice + * + * @param array $authentication Array of authentication information + * @param Facture $invoice Invoice + * @return array Array result + */ +function updateInvoice($authentication,$invoice) +{ + global $db,$conf,$langs; + + dol_syslog("Function: updateInvoice login=".$authentication['login']." id=".$invoice['id']. + ", ref=".$invoice['ref'].", ref_ext=".$invoice['ref_ext']); + + if ($authentication['entity']) $conf->entity=$authentication['entity']; + + // Init and check authentication + $objectresp=array(); + $errorcode='';$errorlabel=''; + $error=0; + $fuser=check_authentication($authentication,$error,$errorcode,$errorlabel); + + // Check parameters + if (empty($invoice['id']) && empty($invoice['ref']) && empty($invoice['ref_ext'])) { + $error++; $errorcode='KO'; $errorlabel="Invoice id or ref or ref_ext is mandatory."; + } + + if (! $error) + { + $objectfound=false; + + $object=new Facture($db); + $result=$object->fetch($invoice['id'],$invoice['ref'],$invoice['ref_ext'], ''); + + if (!empty($object->id)) { + + $objectfound=true; + + $db->begin(); + + if (isset($invoice['status'])) + { + if ($invoice['status'] == Facture::STATUS_DRAFT) + { + $result = $object->set_draft($fuser); + } + if ($invoice['status'] == Facture::STATUS_VALIDATED) + { + $result = $object->validate($fuser); + + if ($result >= 0) + { + // Define output language + $outputlangs = $langs; + $order->generateDocument($invoice->modelpdf, $outputlangs); + } + } + if ($invoice['status'] == Facture::STATUS_CLOSED) + { + $result = $object->set_paid($fuser,$invoice->close_code,$invoice->close_note); + } + if ($invoice['status'] == Facture::STATUS_ABANDONED) + $result = $object->set_canceled($fuser,$invoice->close_code,$invoice->close_note); + } + } + + if ((! $error) && ($objectfound)) + { + $db->commit(); + $objectresp=array( + 'result'=>array('result_code'=>'OK', 'result_label'=>''), + 'id'=>$object->id, + 'ref'=>$object->ref, + 'ref_ext'=>$object->ref_ext + ); + } + elseif ($objectfound) + { + $db->rollback(); + $error++; + $errorcode='KO'; + $errorlabel=$object->error; + } else { + $error++; + $errorcode='NOT_FOUND'; + $errorlabel='Invoice id='.$invoice['id'].' ref='.$invoice['ref'].' ref_ext='.$invoice['ref_ext'].' cannot be found'; + } + } + + if ($error) + { + $objectresp = array('result'=>array('result_code' => $errorcode, 'result_label' => $errorlabel)); + } + + return $objectresp; +} + // Return the results. $server->service(file_get_contents("php://input")); diff --git a/htdocs/webservices/server_order.php b/htdocs/webservices/server_order.php index 2f5955d8ec1..28518d24763 100644 --- a/htdocs/webservices/server_order.php +++ b/htdocs/webservices/server_order.php @@ -917,7 +917,17 @@ function updateOrder($authentication,$order) if (isset($order['status'])) { if ($order['status'] == -1) $result=$object->cancel($fuser); - if ($order['status'] == 1) $result=$object->valid($fuser); + if ($order['status'] == 1) + { + $result=$object->valid($fuser); + if ($result >= 0) + { + // Define output language + $outputlangs = $langs; + $order->generateDocument($order->modelpdf, $outputlangs); + + } + } if ($order['status'] == 0) $result=$object->set_reopen($fuser); if ($order['status'] == 3) $result=$object->cloture($fuser); } @@ -951,7 +961,9 @@ function updateOrder($authentication,$order) $db->commit(); $objectresp=array( 'result'=>array('result_code'=>'OK', 'result_label'=>''), - 'id'=>$object->id + 'id'=>$object->id, + 'ref'=>$object->ref, + 'ref_ext'=>$object->ref_ext ); } elseif ($objectfound) diff --git a/htdocs/webservices/server_thirdparty.php b/htdocs/webservices/server_thirdparty.php index c7ca5911d62..542e2980c45 100644 --- a/htdocs/webservices/server_thirdparty.php +++ b/htdocs/webservices/server_thirdparty.php @@ -258,8 +258,31 @@ $server->register( 'WS to get list of thirdparties id and ref' ); +// Register WSDL +$server->register( + 'deleteThirdParty', + // Entry values + array('authentication'=>'tns:authentication','id'=>'xsd:string','ref'=>'xsd:string','ref_ext'=>'xsd:string'), + // Exit values + array('result'=>'tns:result','id'=>'xsd:string'), + $ns, + $ns.'#deleteThirdParty', + $styledoc, + $styleuse, + 'WS to delete a thirdparty from its id, ref or ref_ext' +); + // Full methods code +/** + * Get a thirdparty + * + * @param array $authentication Array of authentication information + * @param string $id internal id + * @param string $ref internal reference + * @param string $ref_ext external reference + * @return array Array result + */ function getThirdParty($authentication,$id='',$ref='',$ref_ext='') { global $db,$conf,$langs; @@ -728,5 +751,88 @@ function getListOfThirdParties($authentication,$filterthirdparty) return $objectresp; } +/** + * Delete a thirdparty + * + * @param array $authentication Array of authentication information + * @param string $id internal id + * @param string $ref internal reference + * @param string $ref_ext external reference + * @return array Array result + */ +function deleteThirdParty($authentication,$id='',$ref='',$ref_ext='') +{ + global $db,$conf,$langs; + + dol_syslog("Function: deleteThirdParty login=".$authentication['login']." id=".$id." ref=".$ref." ref_ext=".$ref_ext); + + if ($authentication['entity']) $conf->entity=$authentication['entity']; + + // Init and check authentication + $objectresp=array(); + $errorcode='';$errorlabel=''; + $error=0; + $fuser=check_authentication($authentication,$error,$errorcode,$errorlabel); + // Check parameters + if (! $error && (($id && $ref) || ($id && $ref_ext) || ($ref && $ref_ext))) + { + dol_syslog("Function: deleteThirdParty checkparam"); + $error++; + $errorcode='BAD_PARAMETERS'; $errorlabel="Parameter id, ref and ref_ext can't be both provided. You must choose one or other but not both."; + } + dol_syslog("Function: deleteThirdParty 1"); + + if (! $error) + { + $fuser->getrights(); + + if ($fuser->rights->societe->lire && $fuser->rights->societe->supprimer) + { + $thirdparty=new Societe($db); + $result=$thirdparty->fetch($id,$ref,$ref_ext); + + if ($result > 0) + { + $db->begin(); + + $result=$thirdparty->delete($thirdparty->id, $fuser); + + if ($result > 0) + { + $db->commit(); + + $objectresp = array('result'=>array('result_code'=>'OK', 'result_label'=>'')); + } + else + { + $db->rollback(); + $error++; + $errorcode='KO'; + $errorlabel=$thirdparty->error; + dol_syslog("Function: deleteThirdParty cant delete"); + } + } + else + { + $error++; + $errorcode='NOT_FOUND'; $errorlabel='Object not found for id='.$id.' nor ref='.$ref.' nor ref_ext='.$ref_ext; + + } + } + else + { + $error++; + $errorcode='PERMISSION_DENIED'; $errorlabel='User does not have permission for this request'; + } + } + + if ($error) + { + $objectresp = array('result'=>array('result_code' => $errorcode, 'result_label' => $errorlabel)); + } + + return $objectresp; +} + // Return the results. $server->service(file_get_contents("php://input")); diff --git a/test/phpunit/WebservicesInvoicesTest.php b/test/phpunit/WebservicesInvoicesTest.php index 202f260bc84..bbfde0a66e5 100755 --- a/test/phpunit/WebservicesInvoicesTest.php +++ b/test/phpunit/WebservicesInvoicesTest.php @@ -18,9 +18,9 @@ /** * \file test/phpunit/WebservicesInvoicesTest.php - * \ingroup test + * \ingroup test * \brief PHPUnit test - * \remarks To run this script as CLI: phpunit filename.php + * \remarks To run this script as CLI: phpunit filename.php */ global $conf,$user,$langs,$db; @@ -31,10 +31,11 @@ require_once dirname(__FILE__).'/../../htdocs/core/lib/date.lib.php'; require_once(NUSOAP_PATH.'/nusoap.php'); // Include SOAP -if (empty($user->id)) { - print "Load permissions for admin user nb 1\n"; - $user->fetch(1); - $user->getrights(); +if (empty($user->id)) +{ + print "Load permissions for admin user nb 1\n"; + $user->fetch(1); + $user->getrights(); } $conf->global->MAIN_DISABLE_ALL_MAILS=1; @@ -44,138 +45,369 @@ $conf->global->MAIN_DISABLE_ALL_MAILS=1; * * @backupGlobals disabled * @backupStaticAttributes enabled - * @remarks backupGlobals must be disabled to have db,conf,user and lang not erased. + * @remarks backupGlobals must be disabled to have db,conf,user and lang not erased. */ class WebservicesInvoicesTest extends PHPUnit_Framework_TestCase { - protected $savconf; - protected $savuser; - protected $savlangs; - protected $savdb; + protected $savconf; + protected $savuser; + protected $savlangs; + protected $savdb; + protected $soapclient; + protected $socid; + + protected $ns = 'http://www.dolibarr.org/ns/'; + + /** + * Constructor + * We save global variables into local variables + * + * @return DateLibTest + */ + function __construct() + { + //$this->sharedFixture + global $conf,$user,$langs,$db; + $this->savconf=$conf; + $this->savuser=$user; + $this->savlangs=$langs; + $this->savdb=$db; + $WS_DOL_URL = DOL_MAIN_URL_ROOT.'/webservices/server_invoice.php'; + + + // Set the WebService URL + print __METHOD__." create nusoap_client for URL=".$WS_DOL_URL."\n"; + $this->soapclient = new nusoap_client($WS_DOL_URL); + if ($this->soapclient) + { + $this->soapclient->soap_defencoding='UTF-8'; + $this->soapclient->decodeUTF8(false); + } + + // create a third_party, needed to create an invoice + $societe=new Societe($db); + $societe->ref=''; + $societe->name='name'; + $societe->ref_ext='209'; + $societe->status=1; + $societe->client=1; + $societe->fournisseur=0; + $societe->date_creation=$now; + $societe->tva_assuj=0; + $societe->particulier=0; + + $societe->create($user); + + $this->socid = $societe->id; + + print __METHOD__." societe created id=".$societe->id."\n"; - /** - * Constructor - * We save global variables into local variables - * - * @return DateLibTest - */ - function __construct() + print __METHOD__." db->type=".$db->type." user->id=".$user->id; + //print " - db ".$db->db; + print "\n"; + } + + // Static methods + public static function setUpBeforeClass() { - //$this->sharedFixture - global $conf,$user,$langs,$db; - $this->savconf=$conf; - $this->savuser=$user; - $this->savlangs=$langs; - $this->savdb=$db; + global $conf,$user,$langs,$db; + $db->begin(); // This is to have all actions inside a transaction even if test launched without suite. - print __METHOD__." db->type=".$db->type." user->id=".$user->id; - //print " - db ".$db->db; - print "\n"; + print __METHOD__."\n"; } - - // Static methods - public static function setUpBeforeClass() - { - global $conf,$user,$langs,$db; - $db->begin(); // This is to have all actions inside a transaction even if test launched without suite. - - print __METHOD__."\n"; - } - - // tear down after class public static function tearDownAfterClass() { - global $conf,$user,$langs,$db; - $db->rollback(); + global $conf,$user,$langs,$db; + $db->rollback(); - print __METHOD__."\n"; + print __METHOD__."\n"; } - /** - * Init phpunit tests - * - * @return void - */ + /** + * Init phpunit tests + * + * @return void + */ protected function setUp() { - global $conf,$user,$langs,$db; - $conf=$this->savconf; - $user=$this->savuser; - $langs=$this->savlangs; - $db=$this->savdb; - - print __METHOD__."\n"; + global $conf,$user,$langs,$db; + $conf=$this->savconf; + $user=$this->savuser; + $langs=$this->savlangs; + $db=$this->savdb; + + print __METHOD__."\n"; + } - /** - * End phpunit tests - * - * @return void - */ + /** + * End phpunit tests + * + * @return void + */ protected function tearDown() { - print __METHOD__."\n"; + print __METHOD__."\n"; } /** - * testWSInvoicesXxx + * testWSInvoicesCreateInvoice * - * @return int + * @return int invoice created */ - public function testWSInvoicesXxx() + public function testWSInvoicesCreateInvoice() { - global $conf,$user,$langs,$db; - $conf=$this->savconf; - $user=$this->savuser; - $langs=$this->savlangs; - $db=$this->savdb; + global $conf,$user,$langs,$db; + $conf=$this->savconf; + $user=$this->savuser; + $langs=$this->savlangs; + $db=$this->savdb; - $WS_DOL_URL = DOL_MAIN_URL_ROOT.'/webservices/server_invoice.php'; - $WS_METHOD = 'getInvoice'; - $ns='http://www.dolibarr.org/ns/'; + $WS_METHOD = 'createInvoice'; - // Set the WebService URL - print __METHOD__." create nusoap_client for URL=".$WS_DOL_URL."\n"; - $soapclient = new nusoap_client($WS_DOL_URL); - if ($soapclient) { - $soapclient->soap_defencoding='UTF-8'; - $soapclient->decodeUTF8(false); - } + // load societe first + $societe=new Societe($db); + $societe->fetch('', '', '209'); + print __METHOD__." societe loaded id=".$societe->id."\n"; + + + $body = array ( + "id" => NULL, + "ref" => NULL, + "ref_ext" => "165", + "thirdparty_id" => $societe->id, + "fk_user_author" => NULL, + "fk_user_valid" => NULL, + "date" => "2015-04-19 20:16:53", + "date_due" => "", + "date_creation" => "", + "date_validation" => "", + "date_modification" => "", + "type" => "", + "total_net" => "36.30", + "total_vat" => "6.00", + "total" => "42.30", + "payment_mode_id" => 50, + "note_private" => "Synchronised from Prestashop", + "note_public" => "", + "status" => "1", + "close_code" => NULL , + "close_note" => NULL, + "project_id" => NULL, + "lines" => array( + array("id" => NULL, + "type" => 0, + "desc" => "Horloge Vinyle Serge", + "vat_rate" => 20, + "qty" => 1, + "unitprice" => "30.000000", + "total_net" => "30.000000", + "total_vat" => "6.00", + "total" => "36.000000", + "date_start" => "", + "date_end" => "", + "payment_mode_id" => "", + "product_id" => "", + "product_ref" => "", + "product_label" => "", + "product_desc" => "" )) + ); - // Call the WebService method and store its result in $result. - $authentication=array( - 'dolibarrkey'=>$conf->global->WEBSERVICES_KEY, - 'sourceapplication'=>'DEMO', - 'login'=>'admin', - 'password'=>'admin', - 'entity'=>'' - ); + // Call the WebService method and store its result in $result. + $authentication=array( + 'dolibarrkey'=>$conf->global->WEBSERVICES_KEY, + 'sourceapplication'=>'DEMO', + 'login'=>'admin', + 'password'=>'admin', + 'entity'=>''); - // Test URL - $result=''; - $parameters = array('authentication'=>$authentication,'id'=>1); - print __METHOD__." call method ".$WS_METHOD."\n"; - try { - $result = $soapclient->call($WS_METHOD,$parameters,$ns,''); - } catch(SoapFault $exception) { - echo $exception; - $result=0; - } - if (! $result || ! empty($result['faultstring'])) { - //var_dump($soapclient); - print $soapclient->error_str; - print "\n
\n"; - print $soapclient->request; - print "\n
\n"; - print $soapclient->response; - print "\n"; - } + // Test URL + $result=''; + $parameters = array('authentication'=>$authentication,'invoice'=>$body); + print __METHOD__." call method ".$WS_METHOD."\n"; + try { + $result = $this->soapclient->call($WS_METHOD,$parameters,$this->ns,''); + } + catch(SoapFault $exception) + { + echo $exception; + $result=0; + } + if (! $result || ! empty($result['faultstring'])) + { + //var_dump($soapclient); + print $this->soapclient->error_str; + print "\n
\n"; + print $this->soapclient->request; + print "\n
\n"; + print $this->soapclient->response; + print "\n"; + } - print __METHOD__." result=".$result."\n"; - $this->assertEquals('OK',$result['result']['result_code']); + print __METHOD__." result=".$result['result']['result_code']."\n"; + $this->assertEquals('OK',$result['result']['result_code']); + $this->assertEquals('165', $result['ref_ext']); - return $result; + + return $result; + } + + /** + * testWSInvoicesGetInvoiceByRefExt + * + * Retrieve an invoice using ref_ext + * @depends testWSInvoicesCreateInvoice + * + * @param array $result Invoice created by create method + * @return array Invoice + */ + public function testWSInvoicesGetInvoiceByRefExt($result) + { + global $conf,$user,$langs,$db; + $conf=$this->savconf; + $user=$this->savuser; + $langs=$this->savlangs; + $db=$this->savdb; + + $WS_METHOD = 'getInvoice'; + + // Call the WebService method and store its result in $result. + $authentication=array( + 'dolibarrkey'=>$conf->global->WEBSERVICES_KEY, + 'sourceapplication'=>'DEMO', + 'login'=>'admin', + 'password'=>'admin', + 'entity'=>''); + + // Test URL + $result=''; + $parameters = array('authentication'=>$authentication,'id'=>NULL,'ref'=>NULL,'ref_ext'=>165); + print __METHOD__." call method ".$WS_METHOD."\n"; + try { + $result = $this->soapclient->call($WS_METHOD,$parameters,$this->ns,''); + } + catch(SoapFault $exception) + { + echo $exception; + $result=0; + } + if (! $result || ! empty($result['faultstring'])) + { + print $this->soapclient->error_str; + print "\n
\n"; + print $this->soapclient->request; + print "\n
\n"; + print $this->soapclient->response; + print "\n"; + } + print __METHOD__." result=".$result['result']['result_code']."\n"; + $this->assertEquals('OK',$result['result']['result_code']); + $this->assertEquals('165', $result['invoice']['ref_ext']); + + + return $result; + } + + /** + * testWSInvoicesUpdateInvoiceByRefExt + * + * Update an invoice using ref_ext + * @depends testWSInvoicesCreateInvoice + * + * @param array $result invoice created by create method + * @return array Invoice + */ + public function testWSInvoicesUpdateInvoiceByRefExt($result) + { + global $conf,$user,$langs,$db; + $conf=$this->savconf; + $user=$this->savuser; + $langs=$this->savlangs; + $db=$this->savdb; + + $WS_METHOD = 'updateInvoice'; + + // update status to 2 + $body = array ( + "id" => NULL, + "ref" => NULL, + "ref_ext" => "165", + "thirdparty_id" => "209", + "fk_user_author" => NULL, + "fk_user_valid" => NULL, + "date" => "2015-04-19 20:16:53", + "date_due" => "", + "date_creation" => "", + "date_validation" => "", + "date_modification" => "", + "type" => "", + "total_net" => "36.30", + "total_vat" => "6.00", + "total" => "42.30", + "payment_mode_id" => 50, + "note_private" => "Synchronised from Prestashop", + "note_public" => "", + "status" => "2", + "close_code" => NULL , + "close_note" => NULL, + "project_id" => NULL, + "lines" => array( + array( + "id" => NULL, + "type" => 0, + "desc" => "Horloge Vinyle Serge", + "vat_rate" => 20, + "qty" => "1", + "unitprice" => "30.000000", + "total_net" => "30.000000", + "total_vat" => "6.00", + "total" => "36.000000", + "date_start" => "", + "date_end" => "", + "payment_mode_id" => "", + "product_id" => "", + "product_ref" => "", + "product_label" => "", + "product_desc" => "" )) + ); + + // Call the WebService method and store its result in $result. + $authentication=array( + 'dolibarrkey'=>$conf->global->WEBSERVICES_KEY, + 'sourceapplication'=>'DEMO', + 'login'=>'admin', + 'password'=>'admin', + 'entity'=>''); + + // Test URL + $result=''; + $parameters = array('authentication'=>$authentication,'invoice'=>$body); + print __METHOD__." call method ".$WS_METHOD."\n"; + try { + $result = $this->soapclient->call($WS_METHOD,$parameters,$this->ns,''); + } + catch(SoapFault $exception) + { + echo $exception; + $result=0; + } + if (! $result || ! empty($result['faultstring'])) + { + print $this->soapclient->error_str; + print "\n
\n"; + print $this->soapclient->request; + print "\n
\n"; + print $this->soapclient->response; + print "\n"; + } + + print __METHOD__." result=".$result['result']['result_code'].$result['result']['result_label']."\n"; + $this->assertEquals('OK',$result['result']['result_code']); + $this->assertEquals('165', $result['ref_ext']); + + + return $result; } } diff --git a/test/phpunit/WebservicesThirdpartyTest.php b/test/phpunit/WebservicesThirdpartyTest.php index 0c99d7d362a..2888c432e73 100755 --- a/test/phpunit/WebservicesThirdpartyTest.php +++ b/test/phpunit/WebservicesThirdpartyTest.php @@ -52,6 +52,13 @@ class WebservicesThirdpartyTest extends PHPUnit_Framework_TestCase protected $savuser; protected $savlangs; protected $savdb; + protected $soapclient; + + private $_WS_DOL_URL; + private $_ns='http://www.dolibarr.org/ns/'; + + + /** * Constructor @@ -67,6 +74,16 @@ class WebservicesThirdpartyTest extends PHPUnit_Framework_TestCase $this->savuser=$user; $this->savlangs=$langs; $this->savdb=$db; + + $this->_WS_DOL_URL = DOL_MAIN_URL_ROOT.'/webservices/server_thirdparty.php'; + + // Set the WebService URL + print __METHOD__." create nusoap_client for URL=".$this->_WS_DOL_URL."\n"; + $this->soapclient = new nusoap_client($this->_WS_DOL_URL); + if ($this->soapclient) { + $this->soapclient->soap_defencoding='UTF-8'; + $this->soapclient->decodeUTF8(false); + } print __METHOD__." db->type=".$db->type." user->id=".$user->id; //print " - db ".$db->db; @@ -117,31 +134,114 @@ class WebservicesThirdpartyTest extends PHPUnit_Framework_TestCase print __METHOD__."\n"; } + /** + * testWSThirdpartycreateThirdParty + * + * @return array thirdparty created + */ + public function testWSThirdpartycreateThirdParty() + { + global $conf,$user,$langs,$db; + $conf=$this->savconf; + $user=$this->savuser; + $langs=$this->savlangs; + $db=$this->savdb; + + $WS_METHOD = 'createThirdParty'; + + + // Call the WebService method and store its result in $result. + $authentication=array( + 'dolibarrkey'=>$conf->global->WEBSERVICES_KEY, + 'sourceapplication'=>'DEMO', + 'login'=>'admin', + 'password'=>'admin', + 'entity'=>''); + + $body = array ( + "id" => NULL, + "ref" => "name", + "ref_ext" => "12", + "fk_user_author" => NULL, + "status" => NULL, + "client" => 1, + "supplier" => 0, + "customer_code" => "", + "supplier_code" => "", + "customer_code_accountancy" => "", + "supplier_code_accountancy" => "", + "date_creation" => "", // dateTime + "date_modification" => "", // dateTime + "note_private" => "", + "note_public" => "", + "address" => "", + "zip" => "", + "town" => "", + "province_id" => "", + "country_id" => "", + "country_code" => "", + "country" => "", + "phone" => "", + "fax" => "", + "email" => "", + "url" => "", + "profid1" => "", + "profid2" => "", + "profid3" => "", + "profid4" => "", + "profid5" => "", + "profid6" => "", + "capital" => "", + "vat_used" => "", + "vat_number" => "" + ); + + // Test URL + $result=''; + $parameters = array('authentication'=>$authentication, 'thirdparty'=>$body); + print __METHOD__." call method ".$WS_METHOD."\n"; + try { + $result = $this->soapclient->call($WS_METHOD,$parameters,$thid->ns,''); + } catch(SoapFault $exception) { + echo $exception; + $result=0; + } + if (! $result || ! empty($result['faultstring'])) { + //var_dump($soapclient); + print $this->soapclient->error_str; + print "\n
\n"; + print $this->soapclient->request; + print "\n
\n"; + print $this->soapclient->response; + print "\n"; + } + + print __METHOD__." result=".$result['result']['result_code']."\n"; + $this->assertEquals('OK',$result['result']['result_code']); + $this->assertEquals('name',$result['ref']); + + return $result; + } /** - * testWSThirdpartygetThirdParty - * - * @return int + * testWSThirdpartygetThirdPartyById + * + * Use id to retrieve thirdparty + * @depends testWSThirdpartycreateThirdParty + * + * @param array $result thirdparty created by create method + * @return array thirpdarty updated */ - public function testWSThirdpartygetThirdParty() + public function testWSThirdpartygetThirdPartyById($result) { global $conf,$user,$langs,$db; $conf=$this->savconf; $user=$this->savuser; $langs=$this->savlangs; $db=$this->savdb; + $id = $result['id']; - $WS_DOL_URL = DOL_MAIN_URL_ROOT.'/webservices/server_thirdparty.php'; $WS_METHOD = 'getThirdParty'; - $ns='http://www.dolibarr.org/ns/'; - - // Set the WebService URL - print __METHOD__." create nusoap_client for URL=".$WS_DOL_URL."\n"; - $soapclient = new nusoap_client($WS_DOL_URL); - if ($soapclient) { - $soapclient->soap_defencoding='UTF-8'; - $soapclient->decodeUTF8(false); - } // Call the WebService method and store its result in $result. $authentication=array( @@ -151,30 +251,150 @@ class WebservicesThirdpartyTest extends PHPUnit_Framework_TestCase 'password'=>'admin', 'entity'=>''); - // Test URL $result=''; - $parameters = array('authentication'=>$authentication, 'id'=>1); + $parameters = array('authentication'=>$authentication, 'id'=>$id); print __METHOD__." call method ".$WS_METHOD."\n"; try { - $result = $soapclient->call($WS_METHOD,$parameters,$ns,''); + $result = $this->soapclient->call($WS_METHOD,$parameters,$this->_ns,''); } catch(SoapFault $exception) { echo $exception; $result=0; } if (! $result || ! empty($result['faultstring'])) { //var_dump($soapclient); - print $soapclient->error_str; + print $this->soapclient->error_str; print "\n
\n"; - print $soapclient->request; + print $this->soapclient->request; print "\n
\n"; - print $soapclient->response; + print $this->soapclient->response; print "\n"; } - print __METHOD__." result=".$result."\n"; + print __METHOD__." result=".$result['result']['result_code']."\n"; $this->assertEquals('OK',$result['result']['result_code']); - + $this->assertEquals($id, $result['thirdparty']['id']); + $this->assertEquals('name', $result['thirdparty']['ref']); + $this->assertEquals('12', $result['thirdparty']['ref_ext']); + $this->assertEquals('0', $result['thirdparty']['status']); + $this->assertEquals('1', $result['thirdparty']['client']); + $this->assertEquals('0', $result['thirdparty']['supplier']); + + return $result; } + + /** + * testWSThirdpartygetThirdPartyByRefExt + * + * Use ref_ext to retrieve thirdparty + * + * @depends testWSThirdpartycreateThirdParty + * + * @param array $result thirdparty created by create method + * @return array thirdparty + */ + public function testWSThirdpartygetThirdPartyByRefExt($result) + { + global $conf,$user,$langs,$db; + $conf=$this->savconf; + $user=$this->savuser; + $langs=$this->savlangs; + $db=$this->savdb; + $id = $result['id']; + + $WS_METHOD = 'getThirdParty'; + + // Call the WebService method and store its result in $result. + $authentication=array( + 'dolibarrkey'=>$conf->global->WEBSERVICES_KEY, + 'sourceapplication'=>'DEMO', + 'login'=>'admin', + 'password'=>'admin', + 'entity'=>''); + + // Test URL + $result=''; + $parameters = array('authentication'=>$authentication, 'id'=>'', 'ref'=>'', 'ref_ext'=>'12'); + print __METHOD__." call method ".$WS_METHOD."\n"; + try { + $result = $this->soapclient->call($WS_METHOD,$parameters,$this->_ns,''); + } catch(SoapFault $exception) { + echo $exception; + $result=0; + } + print $this->soapclient->response; + if (! $result || ! empty($result['faultstring'])) { + //var_dump($soapclient); + print $this->soapclient->error_str; + print "\n
\n"; + print $this->soapclient->request; + print "\n
\n"; + print $this->soapclient->response; + print "\n"; + } + + print __METHOD__." result=".$result['result']['result_code']."\n"; + $this->assertEquals('OK',$result['result']['result_code']); + $this->assertEquals($id, $result['thirdparty']['id']); + $this->assertEquals('name', $result['thirdparty']['ref']); + $this->assertEquals('12', $result['thirdparty']['ref_ext']); + $this->assertEquals('0', $result['thirdparty']['status']); + $this->assertEquals('1', $result['thirdparty']['client']); + $this->assertEquals('0', $result['thirdparty']['supplier']); + + + return $result; + } + + /** + * testWSThirdpartydeleteThirdParty + * + * @depends testWSThirdpartycreateThirdParty + * + * @param array $result thirdparty created by create method + * @return array thirdparty + */ + public function testWSThirdpartydeleteThirdPartyById($result) + { + global $conf,$user,$langs,$db; + $conf=$this->savconf; + $user=$this->savuser; + $langs=$this->savlangs; + $db=$this->savdb; + $id = $result['id']; + + $WS_METHOD = 'deleteThirdParty'; + + // Call the WebService method and store its result in $result. + $authentication=array( + 'dolibarrkey'=>$conf->global->WEBSERVICES_KEY, + 'sourceapplication'=>'DEMO', + 'login'=>'admin', + 'password'=>'admin', + 'entity'=>''); + + $result=''; + $parameters = array('authentication'=>$authentication, 'id'=>$id, 'ref'=>'', 'ref_ext'=>''); + print __METHOD__." call method ".$WS_METHOD."\n"; + try { + $result = $this->soapclient->call($WS_METHOD,$parameters,$this->_ns,''); + } catch(SoapFault $exception) { + echo $exception; + $result=0; + } + if (! $result || ! empty($result['faultstring'])) { + print $this->soapclient->error_str; + print "\n
\n"; + print $this->soapclient->request; + print "\n
\n"; + print $this->soapclient->response; + print "\n"; + } + + print __METHOD__." result=".$result['result']['result_code']."\n"; + $this->assertEquals('OK',$result['result']['result_code']); + + return $result; + } }
'; + print $moreforfilter; + print '
'; - print $form->select_PriceBaseType($object->price_base_type, "price_base_type"); + print $form->selectPriceBaseType($object->price_base_type, "price_base_type"); print '
'; - print $form->select_PriceBaseType($prodcustprice->price_base_type, "price_base_type"); + print $form->selectPriceBaseType($prodcustprice->price_base_type, "price_base_type"); print '