diff --git a/htdocs/accountancy/admin/journaux.php b/htdocs/accountancy/admin/journaux.php index 03fd8684f50..5a305d87f2c 100644 --- a/htdocs/accountancy/admin/journaux.php +++ b/htdocs/accountancy/admin/journaux.php @@ -1,10 +1,10 @@ - * Copyright (C) 2013-2014 Alexandre Spangaro + * Copyright (C) 2013-2015 Alexandre Spangaro * Copyright (C) 2014 Florian Henry * Copyright (C) 2014 Marcos García * Copyright (C) 2014 Juanjo Menent - * Copyright (C) 2015 Jean-François Ferry + * Copyright (C) 2015 Jean-François Ferry * * 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 @@ -48,8 +48,8 @@ $list = array ( 'ACCOUNTING_SELL_JOURNAL', 'ACCOUNTING_PURCHASE_JOURNAL', 'ACCOUNTING_SOCIAL_JOURNAL', - 'ACCOUNTING_CASH_JOURNAL', - 'ACCOUNTING_MISCELLANEOUS_JOURNAL' + 'ACCOUNTING_MISCELLANEOUS_JOURNAL', + 'ACCOUNTING_EXPENSEREPORT_JOURNAL' ); /* diff --git a/htdocs/admin/company.php b/htdocs/admin/company.php index 561e299b937..d5c78761989 100644 --- a/htdocs/admin/company.php +++ b/htdocs/admin/company.php @@ -543,7 +543,7 @@ if ($action == 'edit' || $action == 'updateedit') $var=!$var; print ''; - print $formother->select_month($conf->global->SOCIETE_FISCAL_MONTH_START,'fiscalmonthstart',1) . ''; + print $formother->select_month($conf->global->SOCIETE_FISCAL_MONTH_START,'fiscalmonthstart',0,1) . ''; print ""; diff --git a/htdocs/admin/facture.php b/htdocs/admin/facture.php index 10f6cffc18a..2dca4821727 100644 --- a/htdocs/admin/facture.php +++ b/htdocs/admin/facture.php @@ -294,7 +294,6 @@ $form=new Form($db); $linkback=''.$langs->trans("BackToModuleList").''; print_fiche_titre($langs->trans("BillsSetup"),$linkback,'title_setup'); -print '
'; $head = invoice_admin_prepare_head(); dol_fiche_head($head, 'general', $langs->trans("Invoices"), 0, 'invoice'); diff --git a/htdocs/barcode/printsheet.php b/htdocs/barcode/printsheet.php index fd89390f3db..81af2aafa10 100644 --- a/htdocs/barcode/printsheet.php +++ b/htdocs/barcode/printsheet.php @@ -1,7 +1,7 @@ - * Copyright (C) 2003 Jean-Louis Bergamo - * Copyright (C) 2006-2013 Laurent Destailleur +/* Copyright (C) 2003 Rodolphe Quiedeville + * Copyright (C) 2003 Jean-Louis Bergamo + * Copyright (C) 2006-2013 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 @@ -10,7 +10,7 @@ * * 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 + * 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 @@ -18,9 +18,9 @@ */ /** - * \file htdocs/barcode/printsheet.php - * \ingroup member - * \brief Page to print sheets with barcodes using the document templates into core/modules/printsheets + * \file htdocs/barcode/printsheet.php + * \ingroup member + * \brief Page to print sheets with barcodes using the document templates into core/modules/printsheets */ require '../main.inc.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/format_cards.lib.php'; @@ -96,13 +96,13 @@ if ($action == 'builddoc') if (empty($forbarcode)) // barcode value { - setEventMessage($langs->trans("ErrorFieldRequired",$langs->transnoentitiesnoconv("BarcodeValue")),'errors'); - $error++; + setEventMessage($langs->trans("ErrorFieldRequired",$langs->transnoentitiesnoconv("BarcodeValue")),'errors'); + $error++; } if (empty($fk_barcode_type)) // barcode type = barcode encoding { - setEventMessage($langs->trans("ErrorFieldRequired",$langs->transnoentitiesnoconv("BarcodeType")),'errors'); - $error++; + setEventMessage($langs->trans("ErrorFieldRequired",$langs->transnoentitiesnoconv("BarcodeType")),'errors'); + $error++; } if (! $error) @@ -123,46 +123,54 @@ if ($action == 'builddoc') $code=$forbarcode; $generator=$stdobject->barcode_type_coder; // coder (loaded by fetch_barcode). Engine. $encoding=strtoupper($stdobject->barcode_type_code); // code (loaded by fetch_barcode). Example 'ean', 'isbn', ... - $barcodeimage=$conf->barcode->dir_temp.'/barcode_'.$code.'_'.$encoding.'.png'; $diroutput=$conf->barcode->dir_temp; dol_mkdir($diroutput); // Generate barcode - $dirbarcode=array_merge(array("/core/modules/barcode/doc/"),$conf->modules_parts['barcode']); + $dirbarcode=array_merge(array("/core/modules/barcode/doc/"),$conf->modules_parts['barcode']); - foreach($dirbarcode as $reldir) - { - $dir=dol_buildpath($reldir,0); - $newdir=dol_osencode($dir); - - // Check if directory exists (we do not use dol_is_dir to avoid loading files.lib.php) - if (! is_dir($newdir)) continue; - - $result=@include_once $newdir.$generator.'.modules.php'; - if ($result) break; - } - - // Load barcode class - $classname = "mod".ucfirst($generator); - $module = new $classname($db); - if ($module->encodingIsSupported($encoding)) - { - dol_delete_file($barcodeimage); - // File is created with full name $barcodeimage = $conf->barcode->dir_temp.'/barcode_'.$code.'_'.$encoding.'.png'; - $result=$module->writeBarCode($code,$encoding,'Y',4); - - if ($result <= 0 || ! dol_is_file($barcodeimage)) - { - $error++; - setEventMessage('Failed to generate image file of barcode for code='.$code.' encoding='.$encoding.' file='.basename($barcodeimage), 'errors'); - } - } - else + foreach($dirbarcode as $reldir) { - $error++; - setEventMessage("Error, encoding ".$encoding." is not supported by encoder ".$generator.'. You must choose another barcode type or install a barcode generation engine that support '.$encoding, 'errors'); - } + $dir=dol_buildpath($reldir,0); + $newdir=dol_osencode($dir); + + // Check if directory exists (we do not use dol_is_dir to avoid loading files.lib.php) + if (! is_dir($newdir)) continue; + + $result=@include_once $newdir.$generator.'.modules.php'; + if ($result) break; + } + + // Load barcode class for generating barcode image + $classname = "mod".ucfirst($generator); + $module = new $classname($db); + if ($generator != 'tcpdfbarcode') { + $template = 'standardlabel'; + $is2d = false; + if ($module->encodingIsSupported($encoding)) + { + $barcodeimage=$conf->barcode->dir_temp.'/barcode_'.$code.'_'.$encoding.'.png'; + dol_delete_file($barcodeimage); + // File is created with full name $barcodeimage = $conf->barcode->dir_temp.'/barcode_'.$code.'_'.$encoding.'.png'; + $result=$module->writeBarCode($code,$encoding,'Y',4); + + if ($result <= 0 || ! dol_is_file($barcodeimage)) + { + $error++; + setEventMessage('Failed to generate image file of barcode for code='.$code.' encoding='.$encoding.' file='.basename($barcodeimage), 'errors'); + } + } + else + { + $error++; + setEventMessage("Error, encoding ".$encoding." is not supported by encoder ".$generator.'. You must choose another barcode type or install a barcode generation engine that support '.$encoding, 'errors'); + } + } else { + $template = 'tcpdflabel'; + $encoding = $module->getTcpdfEncodingType($encoding); //convert to TCPDF compatible encoding types + $is2d = $module->is2d; + } } if (! $error) @@ -188,11 +196,12 @@ if ($action == 'builddoc') // For labels if ($mode == 'label') { - $txtforsticker="%PHOTO%"; - $textleft=make_substitutions($txtforsticker, $substitutionarray); - $textheader=''; - $textfooter=''; - $textright=''; + + $txtforsticker="%PHOTO%"; // Photo will be barcode image, %BARCODE% posible when using TCPDF generator + $textleft=make_substitutions((empty($conf->global->BARCODE_LABEL_LEFT_TEXT)?$txtforsticker:$conf->global->BARCODE_LABEL_LEFT_TEXT), $substitutionarray); + $textheader=make_substitutions((empty($conf->global->BARCODE_LABEL_HEADER_TEXT)?'':$conf->global->BARCODE_LABEL_HEADER_TEXT), $substitutionarray); + $textfooter=make_substitutions((empty($conf->global->BARCODE_LABEL_FOOTER_TEXT)?'':$conf->global->BARCODE_LABEL_FOOTER_TEXT), $substitutionarray); + $textright=make_substitutions((empty($conf->global->BARCODE_LABEL_RIGHT_TEXT)?'':$conf->global->BARCODE_LABEL_RIGHT_TEXT), $substitutionarray); $forceimgscalewidth=(empty($conf->global->BARCODE_FORCEIMGSCALEWIDTH)?1:$conf->global->BARCODE_FORCEIMGSCALEWIDTH); $forceimgscaleheight=(empty($conf->global->BARCODE_FORCEIMGSCALEHEIGHT)?1:$conf->global->BARCODE_FORCEIMGSCALEHEIGHT); @@ -203,6 +212,9 @@ if ($action == 'builddoc') 'textheader'=>$textheader, 'textfooter'=>$textfooter, 'textright'=>$textright, + 'code'=>$code, + 'encoding'=>$encoding, + 'is2d'=>$is2d, 'photo'=>$barcodeimage // Photo must be a file that exists with format supported by TCPDF ); } @@ -222,7 +234,7 @@ if ($action == 'builddoc') { $mesg=$langs->trans("ErrorFieldRequired",$langs->transnoentitiesnoconv("DescADHERENT_ETIQUETTE_TYPE")); } - if (! $mesg) $result=members_label_pdf_create($db, $arrayofmembers, $modellabel, $outputlangs, $diroutput); + if (! $mesg) $result=members_label_pdf_create($db, $arrayofmembers, $modellabel, $outputlangs, $diroutput, $template); } if ($result <= 0) @@ -230,11 +242,11 @@ if ($action == 'builddoc') dol_print_error('',$result); } - if (! $mesg) - { - $db->close(); - exit; - } + if (! $mesg) + { + $db->close(); + exit; + } } } diff --git a/htdocs/categories/class/categorie.class.php b/htdocs/categories/class/categorie.class.php index 8e6772dec5d..6ca5b2fad02 100644 --- a/htdocs/categories/class/categorie.class.php +++ b/htdocs/categories/class/categorie.class.php @@ -1064,11 +1064,11 @@ class Categorie extends CommonObject */ function print_all_ways($sep = " >> ", $url='') { - $ways = array (); + $ways = array(); foreach ($this->get_all_ways() as $way) { - $w = array (); + $w = array(); foreach ($way as $cat) { if ($url == '') diff --git a/htdocs/commande/class/commande.class.php b/htdocs/commande/class/commande.class.php index 2f85461887e..ad26b0c409d 100644 --- a/htdocs/commande/class/commande.class.php +++ b/htdocs/commande/class/commande.class.php @@ -1539,7 +1539,7 @@ class Commande extends CommonOrder if ($this->statut == self::STATUS_DRAFT) $this->brouillon = 1; - // Retreive all extrafield for invoice + // Retrieve all extrafields for invoice // fetch optionals attributes and labels require_once DOL_DOCUMENT_ROOT.'/core/class/extrafields.class.php'; $extrafields=new ExtraFields($this->db); diff --git a/htdocs/compta/facture.php b/htdocs/compta/facture.php index 152dde9dee3..5541c726d64 100644 --- a/htdocs/compta/facture.php +++ b/htdocs/compta/facture.php @@ -1414,7 +1414,11 @@ if (empty($reshook)) $model=$object->modelpdf; $ret = $object->fetch($id); // Reload to get new records - $object->generateDocument($model, $outputlangs, $hidedetails, $hidedesc, $hideref); + $result = $object->generateDocument($model, $outputlangs, $hidedetails, $hidedesc, $hideref); + if ($result < 0) + { + setEventMessages($object->error, $object->errors, 'errors'); + } } unset($_POST['prod_entry_mode']); diff --git a/htdocs/compta/facture/class/facture.class.php b/htdocs/compta/facture/class/facture.class.php index 0f90ba6d935..739135b9809 100644 --- a/htdocs/compta/facture/class/facture.class.php +++ b/htdocs/compta/facture/class/facture.class.php @@ -3504,7 +3504,7 @@ class Facture extends CommonInvoice /** * Create a document onto disk according to template module. * - * @param string $modele Force template to use ('' to not force) + * @param string $modele Generator to use. Caller must set it to obj->modelpdf or GETPOST('modelpdf') for example. * @param Translate $outputlangs objet lang a utiliser pour traduction * @param int $hidedetails Hide details of lines * @param int $hidedesc Hide description @@ -3532,22 +3532,24 @@ class Facture extends CommonInvoice $modelpath = "core/modules/facture/doc/"; - return $this->commonGenerateDocument($modelpath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref); + $result=$this->commonGenerateDocument($modelpath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref); + + return $result; } /** * Gets the smallest reference available for a new cycle * * @return int >= 1 if OK, -1 if error - * - * */ function newCycle() { - $sql = 'SELECT max(situation_cycle_ref) FROM ' . MAIN_DB_PREFIX . 'facture'; + $sql = 'SELECT max(situation_cycle_ref) FROM ' . MAIN_DB_PREFIX . 'facture as f'; + $sql.= " WHERE f.entity in (".getEntity('facture').")"; $resql = $this->db->query($sql); if ($resql) { - if ($resql->num_rows > 0) { + if ($resql->num_rows > 0) + { $res = $this->db->fetch_array($resql); $ref = $res['max(situation_cycle_ref)']; $ref++; @@ -3557,7 +3559,7 @@ class Facture extends CommonInvoice $this->db->free($resql); return $ref; } else { - $this->error = $this->db->error(); + $this->error = $this->db->lasterror(); dol_syslog("Error sql=" . $sql . ", error=" . $this->error, LOG_ERR); return -1; } diff --git a/htdocs/contrat/card.php b/htdocs/contrat/card.php index 7193634af54..254185cc63d 100644 --- a/htdocs/contrat/card.php +++ b/htdocs/contrat/card.php @@ -37,8 +37,8 @@ require_once DOL_DOCUMENT_ROOT.'/core/lib/contract.lib.php'; require_once DOL_DOCUMENT_ROOT.'/contrat/class/contrat.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/modules/contract/modules_contract.php'; require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php'; -require_once DOL_DOCUMENT_ROOT . '/core/class/html.formfile.class.php'; -if (! empty($conf->produit->enabled) || ! empty($conf->service->enabled)) require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php'; +require_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php'; +require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php'; if (! empty($conf->propal->enabled)) require_once DOL_DOCUMENT_ROOT.'/comm/propal/class/propal.class.php'; if (! empty($conf->projet->enabled)) { require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php'; @@ -1279,9 +1279,7 @@ else * Lines of contracts */ - if ($conf->product->enabled || $conf->service->enabled) { - $productstatic=new Product($db); - } + $productstatic=new Product($db); $usemargins=0; if (! empty($conf->margin->enabled) && ! empty($object->element) && in_array($object->element,array('facture','propal','commande'))) $usemargins=1; @@ -1343,19 +1341,28 @@ else $productstatic->id=$objp->fk_product; $productstatic->type=$objp->ptype; $productstatic->ref=$objp->pref; - print $productstatic->getNomUrl(1,'',20); + $text = $productstatic->getNomUrl(1,'',20); if ($objp->label) { - print ' - '; + $text .= ' - '; $productstatic->ref=$objp->label; - print $productstatic->getNomUrl(0,'',16); + $text .= $productstatic->getNomUrl(0,'',16); } - if (! empty($conf->global->PRODUIT_DESC_IN_FORM) && !empty($objp->description)) - print '
'.dol_nl2br($objp->description); + $description = $objp->description; + + // Add description in form + if (! empty($conf->global->PRODUIT_DESC_IN_FORM)) + { + $text .= (! empty($objp->description) && $objp->description!=$objp->product_label)?'
'.dol_htmlentitiesbr($objp->description):''; + $description = ''; // Already added into main visible desc + } + + echo $form->textwithtooltip($text,$description,3,'','',$cursorline,0,(!empty($line->fk_parent_line)?img_picto('', 'rightarrow'):'')); + print ''; } else - { + { print ''.dol_htmlentitiesbr($objp->description)."\n"; } // TVA diff --git a/htdocs/contrat/class/contrat.class.php b/htdocs/contrat/class/contrat.class.php index cdf2d789d09..08bc8387387 100644 --- a/htdocs/contrat/class/contrat.class.php +++ b/htdocs/contrat/class/contrat.class.php @@ -237,8 +237,8 @@ class Contrat extends CommonObject /** * Activate a contract line * - * @param User $user Objet User qui active le contrat - * @param int $line_id Id de la ligne de detail a activer + * @param User $user Objet User who activate contract + * @param int $line_id Id of line to activate * @param int $date Date d'ouverture * @param int|string $date_end Date fin prevue * @param string $comment A comment typed by user @@ -284,9 +284,9 @@ class Contrat extends CommonObject /** * Close a contract line * - * @param User $user Objet User qui active le contrat - * @param int $line_id Id de la ligne de detail a activer - * @param int $date_end Date fin + * @param User $user Objet User who close contract + * @param int $line_id Id of line to close + * @param int $date_end Date end * @param string $comment A comment typed by user * @return int <0 if KO, >0 if OK */ @@ -576,7 +576,7 @@ class Contrat extends CommonObject $result=$this->fetch_lines(); if ($result < 0) { - $this->error=$this->db->error(); + $this->error=$this->db->lasterror(); return -3; } @@ -599,7 +599,7 @@ class Contrat extends CommonObject } /** - * Load lignes array into this->lines + * Load lines array into this->lines * * @return ContratLigne[] Return array of contract lines */ @@ -624,7 +624,7 @@ class Contrat extends CommonObject $this->lines=array(); // Selectionne les lignes contrats liees a un produit - $sql = "SELECT p.label, p.description as product_desc, p.ref,"; + $sql = "SELECT p.label as product_label, p.description as product_desc, p.ref as product_ref,"; $sql.= " d.rowid, d.fk_contrat, d.statut, d.description, d.price_ht, d.tva_tx, d.localtax1_tx, d.localtax2_tx, d.qty, d.remise_percent, d.subprice, d.fk_product_fournisseur_price as fk_fournprice, d.buy_price_ht as pa_ht,"; $sql.= " d.total_ht,"; $sql.= " d.total_tva,"; @@ -684,10 +684,12 @@ class Contrat extends CommonObject $line->fk_user_cloture = $objp->fk_user_cloture; $line->fk_unit = $objp->fk_unit; - $line->ref = $objp->ref; - $line->libelle = $objp->label; // Label produit - $line->label = $objp->label; // For backward compatibility - $line->product_desc = $objp->product_desc; // Description produit + $line->ref = $objp->product_ref; // deprecated + $line->label = $objp->product_label; // deprecated + $line->libelle = $objp->product_label; // deprecated + $line->product_ref = $objp->product_ref; // Ref product + $line->product_desc = $objp->product_desc; // Description product + $line->product_label = $objp->product_label; // Label product $line->description = $objp->description; @@ -2339,7 +2341,10 @@ class ContratLigne extends CommonObjectLine $sql.= " t.fk_contrat,"; $sql.= " t.fk_product,"; $sql.= " t.statut,"; - $sql.= " t.label,"; + $sql.= " t.label,"; // This field is not used. Only label of product + $sql.= " p.ref as product_ref,"; + $sql.= " p.label as product_label,"; + $sql.= " p.description as product_desc,"; $sql.= " t.description,"; $sql.= " t.date_commande,"; $sql.= " t.date_ouverture_prevue as date_ouverture_prevue,"; @@ -2368,7 +2373,7 @@ class ContratLigne extends CommonObjectLine $sql.= " t.fk_user_cloture,"; $sql.= " t.commentaire,"; $sql.= " t.fk_unit"; - $sql.= " FROM ".MAIN_DB_PREFIX."contratdet as t"; + $sql.= " FROM ".MAIN_DB_PREFIX."contratdet as t LEFT JOIN ".MAIN_DB_PREFIX."product as p ON p.rowid = t.fk_product"; if ($id) $sql.= " WHERE t.rowid = ".$id; if ($ref) $sql.= " WHERE t.rowid = '".$this->db->escape($ref)."'"; @@ -2387,7 +2392,10 @@ class ContratLigne extends CommonObjectLine $this->fk_contrat = $obj->fk_contrat; $this->fk_product = $obj->fk_product; $this->statut = $obj->statut; - $this->label = $obj->label; + $this->product_ref = $obj->product_ref; + $this->product_label = $obj->product_label; + $this->product_description = $obj->product_description; + $this->label = $obj->label; // deprecated. We do not use this field. Only ref and label of product, and description of contract line $this->description = $obj->description; $this->date_commande = $this->db->jdate($obj->date_commande); $this->date_ouverture_prevue = $this->db->jdate($obj->date_ouverture_prevue); diff --git a/htdocs/core/class/commonobject.class.php b/htdocs/core/class/commonobject.class.php index 566f887ba52..77877a37cb2 100644 --- a/htdocs/core/class/commonobject.class.php +++ b/htdocs/core/class/commonobject.class.php @@ -3406,13 +3406,13 @@ abstract class CommonObject /** * Common function for all objects extending CommonObject for generating documents * - * @param string $modelspath Relative folder where models are placed - * @param string $modele Model to use - * @param Translate $outputlangs Language to use - * @param int $hidedetails 1 to hide details. 0 by default - * @param int $hidedesc 1 to hide product description. 0 by default - * @param int $hideref 1 to hide product reference. 0 by default - * @return int 1 if OK -1 if not OK + * @param string $modelspath Relative folder where generators are placed + * @param string $modele Generator to use. Caller must set it to obj->modelpdf or GETPOST('modelpdf') for example. + * @param Translate $outputlangs Language to use + * @param int $hidedetails 1 to hide details. 0 by default + * @param int $hidedesc 1 to hide product description. 0 by default + * @param int $hideref 1 to hide product reference. 0 by default + * @return int >0 if OK, <0 if KO */ protected function commonGenerateDocument($modelspath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref) { @@ -3426,7 +3426,7 @@ abstract class CommonObject @set_time_limit(120); error_reporting($err); - // If selected modele is a filename template (then $modele="modelname:filename") + // If selected model is a filename template (then $modele="modelname" or "modelname:filename") $tmp=explode(':',$modele,2); if (! empty($tmp[1])) { @@ -3456,7 +3456,7 @@ abstract class CommonObject if ($filefound) break; } - // Charge le modele + // If generator was found if ($filefound) { require_once $file; @@ -3464,6 +3464,47 @@ abstract class CommonObject $obj = new $classname($this->db); //$obj->message = $message; + // If generator is ODT, we must have srctemplatepath defined, if not we set it. + if ($obj->type == 'odt' && empty($srctemplatepath)) + { + $varfortemplatedir=$obj->scandir; + if ($varfortemplatedir && ! empty($conf->global->$varfortemplatedir)) + { + $dirtoscan=$conf->global->$varfortemplatedir; + + $listoffiles=array(); + + // Now we add first model found in directories scanned + $listofdir=explode(',',$dirtoscan); + foreach($listofdir as $key=>$tmpdir) + { + $tmpdir=trim($tmpdir); + $tmpdir=preg_replace('/DOL_DATA_ROOT/',DOL_DATA_ROOT,$tmpdir); + if (! $tmpdir) { unset($listofdir[$key]); continue; } + if (is_dir($tmpdir)) + { + $tmpfiles=dol_dir_list($tmpdir,'files',0,'\.od(s|t)$','','name',SORT_ASC,0); + if (count($tmpfiles)) $listoffiles=array_merge($listoffiles,$tmpfiles); + } + } + + if (count($listoffiles)) + { + foreach($listoffiles as $record) + { + $srctemplatepath=$record['fullname']; + break; + } + } + } + + if (empty($srctemplatepath)) + { + $this->error='ErrorGenerationAskedForOdtTemplateWithNoSrcFileFound'; + return -1; + } + } + // We save charset_output to restore it because write_file can change it if needed for // output format that does not support UTF8. $sav_charset_output=$outputlangs->charset_output; @@ -3483,14 +3524,15 @@ abstract class CommonObject else { $outputlangs->charset_output=$sav_charset_output; - dol_print_error($this->db,"Error generating document for ".__CLASS__.". Error: ".$obj->error); + dol_print_error($this->db, "Error generating document for ".__CLASS__.". Error: ".$obj->error, $obj->errors); return -1; } } else { - dol_print_error('',$langs->trans("Error")." ".$langs->trans("ErrorFileDoesNotExists",$file)); + $this->error=$langs->trans("Error")." ".$langs->trans("ErrorFileDoesNotExists",$file); + dol_print_error('',$this->error); return -1; } } diff --git a/htdocs/core/class/commonstickergenerator.class.php b/htdocs/core/class/commonstickergenerator.class.php new file mode 100644 index 00000000000..1091962f6ea --- /dev/null +++ b/htdocs/core/class/commonstickergenerator.class.php @@ -0,0 +1,270 @@ + + * Copyright (C) 2002-2003 Jean-Louis Bergamo + * Copyright (C) 2006-2013 Laurent Destailleur + * Copyright (C) 2015 Francis Appels + * + * 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 . + */ + +/* Inspire de PDF_Label + * PDF_Label - PDF label editing + * @package PDF_Label + * @author Laurent PASSEBECQ + * @copyright 2003 Laurent PASSEBECQ + * disponible ici : http://www.fpdf.org/fr/script/script29.php + */ + +//------------------------------------------------------------------- +// VERSIONS : +// 1.0 : Initial release +// 1.1 : + : Added unit in the constructor +// + : Now Positions start @ (1,1).. then the first image @top-left of a page is (1,1) +// + : Added in the description of a label : +// font-size : defaut char size (can be changed by calling Set_Char_Size(xx); +// paper-size : Size of the paper for this sheet (thanx to Al Canton) +// metric : type of unit used in this description +// You can define your label properties in inches by setting metric to 'in' +// and printing in millimiter by setting unit to 'mm' in constructor. +// Added some labels : +// 5160, 5161, 5162, 5163,5164 : thanx to Al Canton : acanton@adams-blake.com +// 8600 : thanx to Kunal Walia : kunal@u.washington.edu +// + : Added 3mm to the position of labels to avoid errors +//////////////////////////////////////////////////// + +/** + * \file htdocs/core/class/commonstickergenerator.class.php + * \ingroup core + * \brief generate pdf document with labels or cards in Avery or custom format + */ + +require_once DOL_DOCUMENT_ROOT.'/core/lib/pdf.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/images.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/format_cards.lib.php'; + + +/** + * Class to generate stick sheet with format Avery or other personalised + */ +abstract class CommonStickerGenerator +{ + + public $code; // Code of format + public $format; // Array with informations + + // protected + var $_Avery_Name = ''; // Nom du format de l'etiquette + var $_Margin_Left = 0; // Marge de gauche de l'etiquette + var $_Margin_Top = 0; // marge en haut de la page avant la premiere etiquette + var $_X_Space = 0; // Espace horizontal entre 2 bandes d'etiquettes + var $_Y_Space = 0; // Espace vertical entre 2 bandes d'etiquettes + var $_X_Number = 0; // NX Nombre d'etiquettes sur la largeur de la page + var $_Y_Number = 0; // NY Nombre d'etiquettes sur la hauteur de la page + var $_Width = 0; // Largeur de chaque etiquette + var $_Height = 0; // Hauteur de chaque etiquette + var $_Char_Size = 10; // Hauteur des caracteres + var $_Line_Height = 10; // Hauteur par defaut d'une ligne + var $_Metric = 'mm'; // Type of metric.. Will help to calculate good values + var $_Metric_Doc = 'mm'; // Type of metric for the doc.. + var $_COUNTX = 1; + var $_COUNTY = 1; + var $_First = 1; + var $Tformat; + + /** + * Constructor + * + * @param DoliDB $db Database handler + */ + function __construct($db) + { + $this->db = $db; + } + + /** + * Function to build PDF on disk, then output on HTTP strem. + * + * @param array $arrayofrecords Array of record informations (array('textleft'=>,'textheader'=>, ..., 'id'=>,'photo'=>) + * @param Translate $outputlangs Lang object for output language + * @param string $srctemplatepath Full path of source filename for generator using a template file + * @param string $outputdir Output directory for pdf file + * @return int 1=OK, 0=KO + */ + abstract function write_file($arrayofrecords,$outputlangs,$srctemplatepath,$outputdir=''); + + /** + * Output a sticker on page at position _COUNTX, _COUNTY (_COUNTX and _COUNTY start from 0) + * + * @param PDF $pdf PDF reference + * @param Translate $outputlangs Output langs + * @param array $param Associative array containing label content and optional parameters + * @return void + */ + abstract function addSticker(&$pdf,$outputlangs,$param); + + /** + * Methode qui permet de modifier la taille des caracteres + * Cela modiera aussi l'espace entre chaque ligne + * + * @param PDF $pdf PDF reference + * @param int $pt point + * @return void + */ + function Set_Char_Size(&$pdf,$pt) + { + if ($pt > 3) { + $this->_Char_Size = $pt; + $this->_Line_Height = $this->_Get_Height_Chars($pt); + $pdf->SetFont('','',$pt); + } + } + + /** + * protected Print dot line + * + * @param PDF $pdf PDF reference + * @param int $x1 X1 + * @param int $y1 Y1 + * @param int $x2 X2 + * @param int $y2 Y2 + * @param int $epaisseur Epaisseur + * @param int $nbPointilles Nb pointilles + * @return void + */ + function _Pointille(&$pdf,$x1=0,$y1=0,$x2=210,$y2=297,$epaisseur=1,$nbPointilles=15) + { + $pdf->SetLineWidth($epaisseur); + $length=abs($x1-$x2); + $hauteur=abs($y1-$y2); + if($length>$hauteur) { + $Pointilles=($length/$nbPointilles)/2; // taille des pointilles + } + else { + $Pointilles=($hauteur/$nbPointilles)/2; + } + for($i=$x1;$i<=$x2;$i+=$Pointilles+$Pointilles) { + for($j=$i;$j<=($i+$Pointilles);$j++) { + if($j<=($x2-1)) { + $pdf->Line($j,$y1,$j+1,$y1); // on trace le pointill? du haut, point par point + $pdf->Line($j,$y2,$j+1,$y2); // on trace le pointill? du bas, point par point + } + } + } + for($i=$y1;$i<=$y2;$i+=$Pointilles+$Pointilles) { + for($j=$i;$j<=($i+$Pointilles);$j++) { + if($j<=($y2-1)) { + $pdf->Line($x1,$j,$x1,$j+1); // on trace le pointill? du haut, point par point + $pdf->Line($x2,$j,$x2,$j+1); // on trace le pointill? du bas, point par point + } + } + } + } + + /** + * protected Function realisant une croix aux 4 coins des cartes + * + * @param PDF $pdf PDF reference + * @param int $x1 X1 + * @param int $y1 Y1 + * @param int $x2 X2 + * @param int $y2 Y2 + * @param int $epaisseur Epaisseur + * @param int $taille Size + * @return void + */ + function _Croix(&$pdf,$x1=0,$y1=0,$x2=210,$y2=297,$epaisseur=1,$taille=4) + { + $pdf->SetDrawColor(192,192,192); + + $pdf->SetLineWidth($epaisseur); + $lg=$taille/2; + // croix haut gauche + $pdf->Line($x1,$y1-$lg,$x1,$y1+$lg); + $pdf->Line($x1-$lg,$y1,$x1+$lg,$y1); + // croix bas gauche + $pdf->Line($x1,$y2-$lg,$x1,$y2+$lg); + $pdf->Line($x1-$lg,$y2,$x1+$lg,$y2); + // croix haut droit + $pdf->Line($x2,$y1-$lg,$x2,$y1+$lg); + $pdf->Line($x2-$lg,$y1,$x2+$lg,$y1); + // croix bas droit + $pdf->Line($x2,$y2-$lg,$x2,$y2+$lg); + $pdf->Line($x2-$lg,$y2,$x2+$lg,$y2); + + $pdf->SetDrawColor(0,0,0); + } + + /** + * protected Convert units (in to mm, mm to in) + * $src and $dest must be 'in' or 'mm' + * + * @param int $value value + * @param string $src from + * @param string $dest to + * @return float value value after conversion + */ + function _Convert_Metric ($value, $src, $dest) + { + if ($src != $dest) { + $tab['in'] = 39.37008; + $tab['mm'] = 1000; + return $value * $tab[$dest] / $tab[$src]; + } else { + return $value; + } + } + + /** + * protected Give the height for a char size given. + * + * @param int $pt Point + * @return int Height chars + */ + function _Get_Height_Chars($pt) + { + // Tableau de concordance entre la hauteur des caracteres et de l'espacement entre les lignes + $_Table_Hauteur_Chars = array(6=>2, 7=>2.5, 8=>3, 9=>3.5, 10=>4, 11=>6, 12=>7, 13=>8, 14=>9, 15=>10); + if (in_array($pt, array_keys($_Table_Hauteur_Chars))) { + return $_Table_Hauteur_Chars[$pt]; + } else { + return 100; // There is a prob.. + } + } + + /** + * protected Set format + * + * @param PDF $pdf PDF reference + * @param string $format Format + * @return void + */ + function _Set_Format(&$pdf, $format) + { + $this->_Metric = $format['metric']; + $this->_Avery_Name = $format['name']; + $this->_Avery_Code = $format['code']; + $this->_Margin_Left = $this->_Convert_Metric($format['marginLeft'], $this->_Metric, $this->_Metric_Doc); + $this->_Margin_Top = $this->_Convert_Metric($format['marginTop'], $this->_Metric, $this->_Metric_Doc); + $this->_X_Space = $this->_Convert_Metric($format['SpaceX'], $this->_Metric, $this->_Metric_Doc); + $this->_Y_Space = $this->_Convert_Metric($format['SpaceY'], $this->_Metric, $this->_Metric_Doc); + $this->_X_Number = $format['NX']; + $this->_Y_Number = $format['NY']; + $this->_Width = $this->_Convert_Metric($format['width'], $this->_Metric, $this->_Metric_Doc); + $this->_Height = $this->_Convert_Metric($format['height'], $this->_Metric, $this->_Metric_Doc); + $this->Set_Char_Size($pdf, $format['font-size']); + } + +} diff --git a/htdocs/core/class/doleditor.class.php b/htdocs/core/class/doleditor.class.php index 0839639217f..f95924929bb 100644 --- a/htdocs/core/class/doleditor.class.php +++ b/htdocs/core/class/doleditor.class.php @@ -160,7 +160,7 @@ class DolEditor { $found=1; //$out.= ''; diff --git a/htdocs/core/class/extrafields.class.php b/htdocs/core/class/extrafields.class.php index 71cf0c6577d..a6cac8a5276 100644 --- a/htdocs/core/class/extrafields.class.php +++ b/htdocs/core/class/extrafields.class.php @@ -107,7 +107,7 @@ class ExtraFields * @param string $label label of attribute * @param int $type Type of attribute ('int', 'text', 'varchar', 'date', 'datehour') * @param int $pos Position of attribute - * @param int $size Size/length of attribute + * @param string $size Size/length of attribute * @param string $elementtype Element type ('member', 'product', 'thirdparty', ...) * @param int $unique Is field unique or not * @param int $required Is field required or not @@ -128,7 +128,7 @@ class ExtraFields // Create field into database except for separator type which is not stored in database if ($type != 'separate') { - $result=$this->create($attrname,$type,$size,$elementtype, $unique, $required, $default_value, $param, $perms, $list); + $result=$this->create($attrname, $type, $size, $elementtype, $unique, $required, $default_value, $param, $perms, $list); } $err1=$this->errno; if ($result > 0 || $err1 == 'DB_ERROR_COLUMN_ALREADY_EXISTS' || $type == 'separate') @@ -156,7 +156,7 @@ class ExtraFields * * @param string $attrname code of attribute * @param int $type Type of attribute ('int', 'text', 'varchar', 'date', 'datehour') - * @param int $length Size/length of attribute + * @param string $length Size/length of attribute ('5', '24,8', ...) * @param string $elementtype Element type ('member', 'product', 'thirdparty', 'contact', ...) * @param int $unique Is field unique or not * @param int $required Is field required or not @@ -233,7 +233,7 @@ class ExtraFields * @param string $label label of attribute * @param int $type Type of attribute ('int', 'text', 'varchar', 'date', 'datehour', 'float') * @param int $pos Position of attribute - * @param int $size Size/length of attribute + * @param string $size Size/length of attribute ('5', '24,8', ...) * @param string $elementtype Element type ('member', 'product', 'thirdparty', ...) * @param int $unique Is field unique or not * @param int $required Is field required or not diff --git a/htdocs/core/class/html.form.class.php b/htdocs/core/class/html.form.class.php index 28f81fc490a..82364874cfe 100644 --- a/htdocs/core/class/html.form.class.php +++ b/htdocs/core/class/html.form.class.php @@ -4407,13 +4407,15 @@ class Form * @param array $selected Array with key+value preselected * @param int $key_in_label 1 pour afficher la key dans la valeur "[key] value" * @param int $value_as_key 1 to use value as key - * @param string $option Valeur de l'option en fonction du type choisi + * @param string $morecss Add more css style * @param int $translate Translate and encode value - * @param int $width Force width of select box. May be used only when using jquery couch. + * @param int $width Force width of select box. May be used only when using jquery couch. Example: 250, 95% + * @param string $moreattrib Add more options on select component. Example: 'disabled="disabled"' + * @param string $elemtype Type of element we show ('category', ...) * @return string HTML multiselect string * @see selectarray */ - static function multiselectarray($htmlname, $array, $selected=array(), $key_in_label=0, $value_as_key=0, $option='', $translate=0, $width=0) + static function multiselectarray($htmlname, $array, $selected=array(), $key_in_label=0, $value_as_key=0, $morecss='', $translate=0, $width=0, $moreattrib='',$elemtype='') { global $conf, $langs; @@ -4423,8 +4425,36 @@ class Form $tmpplugin=empty($conf->global->MAIN_USE_JQUERY_MULTISELECT)?constant('REQUIRE_JQUERY_MULTISELECT'):$conf->global->MAIN_USE_JQUERY_MULTISELECT; print ' '; @@ -4433,7 +4463,7 @@ class Form // Try also magic suggest // Add data-role="none" to disable jmobile decoration - $out = ''."\n"; if (is_array($array) && ! empty($array)) { if ($value_as_key) $array=array_combine($array, $array); @@ -4462,6 +4492,49 @@ class Form } + /** + * Render list of categories linked to object with id $id and type $type + * + * @param int $id Id of object + * @param string $type Type of category ('member', 'customer', 'supplier', 'product', 'contact'). Old mode (0, 1, 2, ...) is deprecated. + * @param int $rendermode 0=Default, use multiselect. 1=Use text with link + * @return mixed Array of category objects or < 0 if KO + */ + function showCategories($id, $type, $rendermode=0) + { + global $db; + + $cat = new Categorie($db); + $categories = $cat->containing($id, $type); + + if ($rendermode == 1) + { + $toprint = array(); + foreach($categories as $c) + { + $ways = $c->print_all_ways(); + foreach($ways as $way) + { + $toprint[] = img_object('','category').' '.$way; + } + } + return implode('
', $toprint); + } + + if ($rendermode == 0) + { + $cate_arbo = $this->select_all_categories(0, '', 'parent', 64, 0, 1); + foreach($categories as $c) { + $arrayselected[] = $c->id; + } + + return $this->multiselectarray('categories', $cate_arbo, $arrayselected, '', 0, '', 0, '100%', 'disabled="disabled"', 'category'); + } + + return 'ErrorBadValueForParameterRenderMode'; // Should not happened + } + + /** * Return an html string with a select combo box to choose yes or no * diff --git a/htdocs/core/class/html.formother.class.php b/htdocs/core/class/html.formother.class.php index 3233b479b6c..9266b8aa3a6 100644 --- a/htdocs/core/class/html.formother.class.php +++ b/htdocs/core/class/html.formother.class.php @@ -773,20 +773,22 @@ class FormOther } /** - * Return HTML combo list of month + * Return HTML combo list of month * - * @param string $selected Preselected value - * @param string $htmlname Nom de la zone select - * @param int $useempty Affiche valeur vide dans liste - * @return string + * @param string $selected Preselected value + * @param string $htmlname Name of HTML select object + * @param int $useempty Show empty in list + * @param int $longlabel Show long label + * @return string */ - function select_month($selected='',$htmlname='monthid',$useempty=0) + function select_month($selected='',$htmlname='monthid',$useempty=0,$longlabel=0) { global $langs; require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php'; - $montharray = monthArray($langs, 1); // Get array + if ($longlabel) $montharray = monthArray($langs, 0); // Get array + else $montharray = monthArray($langs, 1); $select_month = ''; + print ' '; - print ' '; - print ' '; + + // Amount with all taxes + print ''; // Status print ''; @@ -249,9 +278,9 @@ if ($resql) print ''; print ''.$langs->trans("Total").''; - print ''.$total_total_ht.''; - print ''.$total_total_tva.''; - print ''.$total_total_ttc.''; + print ''.price($total_total_ht).''; + print ''.price($total_total_tva).''; + print ''.price($total_total_ttc).''; print ''; print ''; print ''; diff --git a/htdocs/langs/en_US/accountancy.lang b/htdocs/langs/en_US/accountancy.lang index b09dab7f764..c119a002641 100644 --- a/htdocs/langs/en_US/accountancy.lang +++ b/htdocs/langs/en_US/accountancy.lang @@ -1,6 +1,13 @@ # Dolibarr language file - en_US - Accounting Expert CHARSET=UTF-8 - +ACCOUNTING_EXPORT_SEPARATORCSV=Column separator for export file +ACCOUNTING_EXPORT_DATE=Date format for export file +ACCOUNTING_EXPORT_PIECE=Export the number of piece ? +ACCOUNTING_EXPORT_GLOBAL_ACCOUNT=Export with global account ? +ACCOUNTING_EXPORT_LABEL=Export the label ? +ACCOUNTING_EXPORT_AMOUNT=Export the amount ? +ACCOUNTING_EXPORT_DEVISE=Export the devise ? + Accounting=Accounting Globalparameters=Global parameters Chartofaccounts=Chart of accounts @@ -81,9 +88,8 @@ ACCOUNTING_LENGTH_AACCOUNT=Length of the third party accounts ACCOUNTING_SELL_JOURNAL=Sell journal ACCOUNTING_PURCHASE_JOURNAL=Purchase journal -ACCOUNTING_BANK_JOURNAL=Bank journal -ACCOUNTING_CASH_JOURNAL=Cash journal ACCOUNTING_MISCELLANEOUS_JOURNAL=Miscellaneous journal +ACCOUNTING_EXPENSEREPORT_JOURNAL=Expense report journal ACCOUNTING_SOCIAL_JOURNAL=Social journal ACCOUNTING_ACCOUNT_TRANSFER_CASH=Account of transfer diff --git a/htdocs/langs/en_US/admin.lang b/htdocs/langs/en_US/admin.lang index 973390d7994..8c4baf3d8d3 100755 --- a/htdocs/langs/en_US/admin.lang +++ b/htdocs/langs/en_US/admin.lang @@ -1424,6 +1424,8 @@ BarcodeDescUPC=Barcode of type UPC BarcodeDescISBN=Barcode of type ISBN BarcodeDescC39=Barcode of type C39 BarcodeDescC128=Barcode of type C128 +BarcodeDescDATAMATRIX=Barcode of type Datamatrix +BarcodeDescQRCODE=Barcode of type QR code GenbarcodeLocation=Bar code generation command line tool (used by internal engine for some bar code types). Must be compatible with "genbarcode".
For example: /usr/local/bin/genbarcode BarcodeInternalEngine=Internal engine BarCodeNumberManager=Manager to auto define barcode numbers diff --git a/htdocs/langs/en_US/products.lang b/htdocs/langs/en_US/products.lang index 8ad095f4169..9ceef0033c0 100644 --- a/htdocs/langs/en_US/products.lang +++ b/htdocs/langs/en_US/products.lang @@ -131,7 +131,7 @@ ProductToAddSearch=Search product to add AddDel=Add/Delete Quantity=Quantity NoMatchFound=No match found -ProductAssociationList=List of related products/services: name of product/service (quantity affected) +ProductAssociationList=List of products/services that are component of this virtual product/package ProductParentList=List of package products/services with this product as a component ErrorAssociationIsFatherOfThis=One of selected product is parent with current product DeleteProduct=Delete a product/service diff --git a/htdocs/langs/fr_FR/other.lang b/htdocs/langs/fr_FR/other.lang index fd87446570e..b8087ff18c8 100644 --- a/htdocs/langs/fr_FR/other.lang +++ b/htdocs/langs/fr_FR/other.lang @@ -12,7 +12,6 @@ Notify_FICHINTER_VALIDATE=Validation fiche intervention Notify_FICHINTER_SENTBYMAIL=Envoi fiche d'intervention par email Notify_BILL_VALIDATE=Validation facture client Notify_BILL_UNVALIDATE=Dévalidation facture client -Notify_ORDER_SUPPLIER_VALIDATE=Commande fournisseur enregistrée Notify_ORDER_SUPPLIER_APPROVE=Approbation commande fournisseur Notify_ORDER_SUPPLIER_REFUSE=Refus commande fournisseur Notify_ORDER_VALIDATE=Validation commande client diff --git a/htdocs/product/card.php b/htdocs/product/card.php index 33edc83dd85..21c12e6d31d 100644 --- a/htdocs/product/card.php +++ b/htdocs/product/card.php @@ -58,6 +58,7 @@ $id=GETPOST('id', 'int'); $ref=GETPOST('ref', 'alpha'); $type=GETPOST('type','int'); $action=(GETPOST('action','alpha') ? GETPOST('action','alpha') : 'view'); +$cancel=GETPOST('cancel'); $confirm=GETPOST('confirm','alpha'); $socid=GETPOST('socid','int'); if (! empty($user->societe_id)) $socid=$user->societe_id; @@ -98,6 +99,8 @@ $hookmanager->initHooks(array('productcard','globalcard')); * Actions */ +if ($cancel) $action = ''; + $createbarcode=empty($conf->barcode->enabled)?0:1; if (! empty($conf->global->MAIN_USE_ADVANCED_PERMS) && empty($user->rights->barcode->creer_advance)) $createbarcode=0; @@ -520,19 +523,45 @@ if (empty($reshook)) } - // Add product into proposal - if ($object->id > 0 && $action == 'addinpropal') + // Add product into object + if ($object->id > 0 && $action == 'addin') { - $propal = new Propal($db); - $result=$propal->fetch(GETPOST('propalid')); - if ($result <= 0) + if (GETPOST('propalid') > 0) { - dol_print_error($db,$propal->error); - exit; + $propal = new Propal($db); + $result=$propal->fetch(GETPOST('propalid')); + if ($result <= 0) + { + dol_print_error($db,$propal->error); + exit; + } + $thirpdartyid = $propal->socid; + } + elseif (GETPOST('commandeid') > 0) + { + $commande = new Commande($db); + $result=$commande->fetch(GETPOST('commandeid')); + if ($result <= 0) + { + dol_print_error($db,$commande->error); + exit; + } + $thirpdartyid = $commande->socid; + } + elseif (GETPOST('factureid') > 0) + { + $facture = new Facture($db); + $result=$facture->fetch(GETPOST('factureid')); + if ($result <= 0) + { + dol_print_error($db,$facture->error); + exit; + } + $thirpdartyid = $facture->socid; } $soc = new Societe($db); - $result=$soc->fetch($propal->socid); + $result=$soc->fetch($thirpdartyid); if ($result <= 0) { dol_print_error($db,$soc->error); @@ -589,254 +618,116 @@ if (empty($reshook)) } } - $result = $propal->addline( - $desc, - $pu_ht, - GETPOST('qty'), - $tva_tx, - $localtax1_tx, // localtax1 - $localtax2_tx, // localtax2 - $object->id, - GETPOST('remise_percent'), - $price_base_type, - $pu_ttc, - 0, - 0, - -1, - 0, - 0, - 0, - 0, - '', - '', - '', - 0, - $object->fk_unit - ); - if ($result > 0) + if (GETPOST('propalid') > 0) { - header("Location: ".DOL_URL_ROOT."/comm/propal.php?id=".$propal->id); - return; + $result = $propal->addline( + $desc, + $pu_ht, + GETPOST('qty'), + $tva_tx, + $localtax1_tx, // localtax1 + $localtax2_tx, // localtax2 + $object->id, + GETPOST('remise_percent'), + $price_base_type, + $pu_ttc, + 0, + 0, + -1, + 0, + 0, + 0, + 0, + '', + '', + '', + 0, + $object->fk_unit + ); + if ($result > 0) + { + header("Location: ".DOL_URL_ROOT."/comm/propal.php?id=".$propal->id); + return; + } + + setEventMessage($langs->trans("ErrorUnknown").": $result", 'errors'); } - - setEventMessage($langs->trans("ErrorUnknown").": $result", 'errors'); - } - - // Add product into order - if ($object->id > 0 && $action == 'addincommande') - { - $commande = new Commande($db); - $result=$commande->fetch(GETPOST('commandeid')); - if ($result <= 0) + elseif (GETPOST('commandeid') > 0) { - dol_print_error($db,$commande->error); - exit; + $result = $commande->addline( + $desc, + $pu_ht, + GETPOST('qty'), + $tva_tx, + $localtax1_tx, // localtax1 + $localtax2_tx, // localtax2 + $object->id, + GETPOST('remise_percent'), + '', + '', + $price_base_type, + $pu_ttc, + '', + '', + 0, + -1, + 0, + 0, + null, + 0, + '', + 0, + $object->fk_unit + ); + + if ($result > 0) + { + header("Location: ".DOL_URL_ROOT."/commande/card.php?id=".$commande->id); + exit; + } } - - $soc = new Societe($db); - $result=$soc->fetch($commande->socid); - if ($result <= 0) - { - dol_print_error($db,$soc->error); - exit; - } - - $desc = $object->description; - - $tva_tx = get_default_tva($mysoc, $soc, $object->id); - $localtax1_tx= get_localtax($tva_tx, 1, $soc); - $localtax2_tx= get_localtax($tva_tx, 2, $soc); - - - $pu_ht = $object->price; - $pu_ttc = $object->price_ttc; - $price_base_type = $object->price_base_type; - - // If multiprice - if ($conf->global->PRODUIT_MULTIPRICES && $soc->price_level) - { - $pu_ht = $object->multiprices[$soc->price_level]; - $pu_ttc = $object->multiprices_ttc[$soc->price_level]; - $price_base_type = $object->multiprices_base_type[$soc->price_level]; - } - elseif (! empty($conf->global->PRODUIT_CUSTOMER_PRICES)) + elseif (GETPOST('factureid') > 0) { - require_once DOL_DOCUMENT_ROOT . '/product/class/productcustomerprice.class.php'; + $result = $facture->addline( + $desc, + $pu_ht, + GETPOST('qty'), + $tva_tx, + $localtax1_tx, + $localtax2_tx, + $object->id, + GETPOST('remise_percent'), + '', + '', + '', + '', + '', + $price_base_type, + $pu_ttc, + Facture::TYPE_STANDARD, + -1, + 0, + '', + 0, + 0, + null, + 0, + '', + 0, + 100, + '', + $object->fk_unit + ); - $prodcustprice = new Productcustomerprice($db); - - $filter = array('t.fk_product' => $object->id,'t.fk_soc' => $soc->id); - - $result = $prodcustprice->fetch_all('', '', 0, 0, $filter); - if ($result) { - if (count($prodcustprice->lines) > 0) { - $pu_ht = price($prodcustprice->lines [0]->price); - $pu_ttc = price($prodcustprice->lines [0]->price_ttc); - $price_base_type = $prodcustprice->lines [0]->price_base_type; - $prod->tva_tx = $prodcustprice->lines [0]->tva_tx; - } - } + if ($result > 0) + { + header("Location: ".DOL_URL_ROOT."/compta/facture.php?facid=".$facture->id); + exit; + } } - // On reevalue prix selon taux tva car taux tva transaction peut etre different - // de ceux du produit par defaut (par exemple si pays different entre vendeur et acheteur). - if ($tva_tx != $object->tva_tx) - { - if ($price_base_type != 'HT') - { - $pu_ht = price2num($pu_ttc / (1 + ($tva_tx/100)), 'MU'); - } - else - { - $pu_ttc = price2num($pu_ht * (1 + ($tva_tx/100)), 'MU'); - } - } - - $result = $commande->addline( - $desc, - $pu_ht, - GETPOST('qty'), - $tva_tx, - $localtax1_tx, // localtax1 - $localtax2_tx, // localtax2 - $object->id, - GETPOST('remise_percent'), - '', - '', - $price_base_type, - $pu_ttc, - '', - '', - 0, - -1, - 0, - 0, - null, - 0, - '', - 0, - $object->fk_unit - ); - - if ($result > 0) - { - header("Location: ".DOL_URL_ROOT."/commande/card.php?id=".$commande->id); - exit; - } - } - - // Add product into invoice - if ($object->id > 0 && $action == 'addinfacture' && $user->rights->facture->creer) - { - $facture = New Facture($db); - $result=$facture->fetch(GETPOST('factureid')); - if ($result <= 0) - { - dol_print_error($db,$facture->error); - exit; - } - - $soc = new Societe($db); - $soc->fetch($facture->socid); - if ($result <= 0) - { - dol_print_error($db,$soc->error); - exit; - } - - $desc = $object->description; - - $tva_tx = get_default_tva($mysoc, $soc, $object->id); - $localtax1_tx= get_localtax($tva_tx, 1, $soc); - $localtax2_tx= get_localtax($tva_tx, 2, $soc); - - $pu_ht = $object->price; - $pu_ttc = $object->price_ttc; - $price_base_type = $object->price_base_type; - - // If multiprice - if ($conf->global->PRODUIT_MULTIPRICES && $soc->price_level) - { - $pu_ht = $object->multiprices[$soc->price_level]; - $pu_ttc = $object->multiprices_ttc[$soc->price_level]; - $price_base_type = $object->multiprices_base_type[$soc->price_level]; - } - elseif (! empty($conf->global->PRODUIT_CUSTOMER_PRICES)) - { - require_once DOL_DOCUMENT_ROOT . '/product/class/productcustomerprice.class.php'; - - $prodcustprice = new Productcustomerprice($db); - - $filter = array('t.fk_product' => $object->id,'t.fk_soc' => $soc->id); - - $result = $prodcustprice->fetch_all('', '', 0, 0, $filter); - if ($result) { - if (count($prodcustprice->lines) > 0) { - $pu_ht = price($prodcustprice->lines [0]->price); - $pu_ttc = price($prodcustprice->lines [0]->price_ttc); - $price_base_type = $prodcustprice->lines [0]->price_base_type; - $prod->tva_tx = $prodcustprice->lines [0]->tva_tx; - } - } - } - // On reevalue prix selon taux tva car taux tva transaction peut etre different - // de ceux du produit par defaut (par exemple si pays different entre vendeur et acheteur). - if ($tva_tx != $object->tva_tx) - { - if ($price_base_type != 'HT') - { - $pu_ht = price2num($pu_ttc / (1 + ($tva_tx/100)), 'MU'); - } - else - { - $pu_ttc = price2num($pu_ht * (1 + ($tva_tx/100)), 'MU'); - } - } - - $result = $facture->addline( - $desc, - $pu_ht, - GETPOST('qty'), - $tva_tx, - $localtax1_tx, - $localtax2_tx, - $object->id, - GETPOST('remise_percent'), - '', - '', - '', - '', - '', - $price_base_type, - $pu_ttc, - Facture::TYPE_STANDARD, - -1, - 0, - '', - 0, - 0, - null, - 0, - '', - 0, - 100, - '', - $object->fk_unit - ); - - if ($result > 0) - { - header("Location: ".DOL_URL_ROOT."/compta/facture.php?facid=".$facture->id); - exit; - } } } -if (GETPOST("cancel") == $langs->trans("Cancel")) -{ - $action = ''; - header("Location: ".$_SERVER["PHP_SELF"]."?id=".$object->id); - exit; -} /* @@ -1174,7 +1065,7 @@ else $type = $langs->trans('Product'); if ($object->isservice()) $type = $langs->trans('Service'); - print_fiche_titre($langs->trans('Modify').' '.$type.' : '.(is_object($object->oldcopy)?$object->oldcopy->ref:$object->ref), ""); + //print_fiche_titre($langs->trans('Modify').' '.$type.' : '.(is_object($object->oldcopy)?$object->oldcopy->ref:$object->ref), ""); // Main official, simple, and not duplicated code print '
'."\n"; @@ -1182,6 +1073,12 @@ else print ''; print ''; print ''; + + $head=product_prepare_head($object); + $titre=$langs->trans("CardProduct".$object->type); + $picto=($object->type== Product::TYPE_SERVICE?'service':'product'); + dol_fiche_head($head, 'card', $titre, 0, $picto); + print ''; // Ref @@ -1374,7 +1271,7 @@ else foreach($cats as $cat) { $arrayselected[] = $cat->id; } - print $form->multiselectarray('categories', $cate_arbo, $arrayselected, '', 0, '', 0, 250); + print $form->multiselectarray('categories', $cate_arbo, $arrayselected, '', 0, '', 0, '100%'); print ""; // Units @@ -1409,10 +1306,10 @@ else print ''; print '
'; - - print '
'; //} + dol_fiche_end(); + print '
'; print ''; print '     '; @@ -1688,16 +1585,8 @@ else print ' '."\n"; // Categories - print ''.$langs->trans("Categories").''; - $cat = new Categorie($db); - $categories = $cat->containing($object->id,0); - $catarray = $form->select_all_categories(0, '', 'parent', 64, 0, 1); - - $toprint = array(); - foreach($categories as $c) { - $toprint[] = $catarray[$c->id]; - } - print implode('
', $toprint); + print ''.$langs->trans("Categories").''; + print $form->showCategories($object->id,'product'); print ""; print "\n"; @@ -1817,42 +1706,24 @@ if ($object->id && ($action == '' || $action == 'view') && $object->status) $langs->load("propal"); - $html .= ''; - $html .= ''.$langs->trans("AddToDraftProposals").''; - $html .= ''; - $html .= ''; - $var=true; $otherprop = $propal->liste_array(2,1,0); - $html .= ''; - $html .= ''; - $html .= ''; + if (is_array($otherprop) && count($otherprop)) { $var=!$var; - $html .= ''; - $html .= ''; } else - { - $html .= "'; } - $html .= '
'; - $html .= ''; - $html .= $langs->trans("Proposals").''; + $html .= '
'; + $html .= $langs->trans("AddToDraftProposals").''; $html .= $form->selectarray("propalid", $otherprop, 0, 1); $html .= '
'.$langs->trans("Quantity").' '; - $html .= ''.$langs->trans("ReductionShort").'(%) '; - $html .= ''; - $html .= ''; - $html .= ''; - $html .= '
"; + { + $html .= '
'; + $html .= $langs->trans("AddToDraftProposals").''; $html .= $langs->trans("NoDraftProposals"); $html .= '
'; - $html .= ''; - - $html .= ''; - $html .= ''; } // Commande @@ -1862,42 +1733,23 @@ if ($object->id && ($action == '' || $action == 'view') && $object->status) $langs->load("orders"); - $html .= ''; - $html .= ''.$langs->trans("AddToDraftOrders").''; - $html .= ''; - $html .= ''; - $var=true; $othercom = $commande->liste_array(2, 1, null); - $html .= '
'; - $html .= ''; - $html .= ''; if (is_array($othercom) && count($othercom)) { $var=!$var; - $html .= ''; - $html .= ''; } else { - $html .= "'; } - $html .= '
'; - $html .= ''; - $html .= $langs->trans("Orders").''; + $html .= '
'; + $html .= $langs->trans("AddToDraftOrders").''; $html .= $form->selectarray("commandeid", $othercom, 0, 1); $html .= '
'.$langs->trans("Quantity").' '; - $html .= ''.$langs->trans("ReductionShort").'(%) '; - $html .= ''; - $html .= ''; - $html .= ''; - $html .= '
"; + $html .= '
'; + $html .= $langs->trans("AddToDraftOrders").''; $html .= $langs->trans("NoDraftOrders"); $html .= '
'; - $html .= '
'; - - $html .= ''; - $html .= ''; } // Factures @@ -1907,51 +1759,48 @@ if ($object->id && ($action == '' || $action == 'view') && $object->status) $langs->load("bills"); - $html .= ''; - $html .= ''.$langs->trans("AddToDraftInvoices").''; - $html .= ''; - $html .= ''; - $var=true; $otherinvoice = $invoice->liste_array(2, 1, null); - $html .= '
'; - $html .= ''; - $html .= ''; if (is_array($otherinvoice) && count($otherinvoice)) { $var=!$var; - $html .= ''; - $html .= ''; } else { - $html .= "'; } - $html .= '
'; - $html .= ''; - $html .= $langs->trans("Invoice").''; + $html .= '
'; + $html .= $langs->trans("AddToDraftInvoices").''; $html .= $form->selectarray("factureid", $otherinvoice, 0, 1); $html .= '
'.$langs->trans("Quantity").' '; - $html .= ''.$langs->trans("ReductionShort").'(%) '; - $html .= ''; - $html .= ''; - $html .= ''; - $html .= '
"; + $html .= '
'; + $html .= $langs->trans("AddToDraftInvoices").''; $html .= $langs->trans("NoDraftInvoices"); $html .= '
'; - $html .= '
'; - - $html .= ''; - $html .= ''; } //If any text is going to be printed, then we show the table if (!empty($html)) { - print ''; + print ''; + print ''; + print ''; + + print load_fiche_titre($langs->trans("Add"),'',''); + + $html .= ''; + + print '
'.$langs->trans("Quantity").' '; + $html .= ''.$langs->trans("ReductionShort").'(%) '; + $html .= ''; + $html .= '
'; print $html; print '
'; - print '
'; + + print '
'; + print ''; + print '
'; + + print ''; } } diff --git a/htdocs/product/class/product.class.php b/htdocs/product/class/product.class.php index bfb1a660b55..c1046af1216 100755 --- a/htdocs/product/class/product.class.php +++ b/htdocs/product/class/product.class.php @@ -2815,16 +2815,16 @@ class Product extends CommonObject /** * Return all Father products fo current product * - * @return array prod + * @return array Array of product * @see getParent */ function getFather() { - $sql = "SELECT p.label as label,p.rowid,pa.fk_product_pere as id,p.fk_product_type"; + $sql = "SELECT p.rowid, p.label as label, p.ref as ref, pa.fk_product_pere as id, p.fk_product_type, pa.qty, pa.incdec"; $sql.= " FROM ".MAIN_DB_PREFIX."product_association as pa,"; $sql.= " ".MAIN_DB_PREFIX."product as p"; $sql.= " WHERE p.rowid = pa.fk_product_pere"; - $sql.= " AND pa.fk_product_fils=".$this->id; + $sql.= " AND pa.fk_product_fils = ".$this->id; $res = $this->db->query($sql); if ($res) @@ -2832,8 +2832,11 @@ class Product extends CommonObject $prods = array (); while ($record = $this->db->fetch_array($res)) { - $prods[$record['id']]['id'] = $record['rowid']; - $prods[$record['id']]['label'] = $this->db->escape($record['label']); + $prods[$record['id']]['id'] = $record['rowid']; + $prods[$record['id']]['ref'] = $record['ref']; + $prods[$record['id']]['label'] = $record['label']; + $prods[$record['id']]['qty'] = $record['qty']; + $prods[$record['id']]['incdec'] = $record['incdec']; $prods[$record['id']]['fk_product_type'] = $record['fk_product_type']; } return $prods; @@ -2854,7 +2857,7 @@ class Product extends CommonObject */ function getParent() { - $sql = "SELECT p.label as label,p.rowid,pa.fk_product_pere as id,p.fk_product_type"; + $sql = "SELECT p.rowid, p.label as label, p.ref as ref, pa.fk_product_pere as id, p.fk_product_type, pa.qty"; $sql.= " FROM ".MAIN_DB_PREFIX."product_association as pa,"; $sql.= " ".MAIN_DB_PREFIX."product as p"; $sql.= " WHERE p.rowid = pa.fk_product_pere"; @@ -3409,7 +3412,7 @@ class Product extends CommonObject function is_photo_available($sdir) { include_once DOL_DOCUMENT_ROOT .'/core/lib/files.lib.php'; - + global $conf; $dir = $sdir; diff --git a/htdocs/product/composition/card.php b/htdocs/product/composition/card.php index 773d08fae72..0a427741919 100644 --- a/htdocs/product/composition/card.php +++ b/htdocs/product/composition/card.php @@ -255,37 +255,59 @@ if ($id > 0 || ! empty($ref)) // Number of parent virtual products - print $form->textwithpicto($langs->trans("ParentProductsNumber").': '.count($prodsfather), $langs->trans('IfZeroItIsNotUsedByVirtualProduct')); + //print $form->textwithpicto($langs->trans("ParentProductsNumber").': '.count($prodsfather), $langs->trans('IfZeroItIsNotUsedByVirtualProduct')); - if (count($prodsfather) > 0) - { - print $langs->trans("ProductParentList").'
'; - print ''; - foreach($prodsfather as $value) + //if (count($prodsfather) > 0) + //{ + print_fiche_titre($langs->trans("ProductParentList"),'','').'
'; + print '
'; + print ''; + print ''; + print ''; + print ''; + print ''; + if (count($prodsfather) > 0) + { + $class='pair'; + + foreach($prodsfather as $value) + { + $idprod= $value["id"]; + $productstatic->id=$idprod;// $value["id"]; + $productstatic->type=$value["fk_product_type"]; + $productstatic->ref=$value['ref']; + $productstatic->label=$value['label']; + + $class=($class=='impair')?'pair':'impair'; + print ''; + + print ''; + print ''; + print ''; + print ''; + } + } + else { - $idprod= $value["id"]; - $productstatic->id=$idprod;// $value["id"]; - $productstatic->type=$value["fk_product_type"]; - $productstatic->ref=$value['label']; print ''; - print ''; + print ''; print ''; } print '
'.$langs->trans('ParentProduct').''.$langs->trans('Label').''.$langs->trans('Qty').'
'.$productstatic->getNomUrl(1,'composition').''.$productstatic->label.''.$value['qty'].'
'.$productstatic->getNomUrl(1,'composition').''.$langs->trans("None").'
'; - } + //} print '
'."\n"; // Number of subproducts - print $form->textwithpicto($langs->trans("AssociatedProductsNumber").': '.(empty($conf->global->PRODUCT_SHOW_SUB_SUB_PRODUCTS)?$nbofsubproducts:$nbofsubsubproducts), $langs->trans('IfZeroItIsNotAVirtualProduct')); + //print $form->textwithpicto($langs->trans("AssociatedProductsNumber").': '.(empty($conf->global->PRODUCT_SHOW_SUB_SUB_PRODUCTS)?$nbofsubproducts:$nbofsubsubproducts), $langs->trans('IfZeroItIsNotAVirtualProduct')); // List of subproducts - if (count($prods_arbo) > 0) - { + //if (count($prods_arbo) > 0) + //{ $atleastonenotdefined=0; - print $langs->trans("ProductAssociationList").'
'; + print_fiche_titre($langs->trans("ProductAssociationList"),'','').'
'; print '
'; print ''; @@ -302,6 +324,8 @@ if ($id > 0 || ! empty($ref)) print ''.$langs->trans('ComposedProductIncDecStock').''; print ''."\n"; + $class='pair'; + foreach($prods_arbo as $value) { $productstatic->id=$value['id']; @@ -409,7 +433,7 @@ if ($id > 0 || ! empty($ref)) }*/ print '
'; - } + //} // Form with product to add if ((empty($action) || $action == 'view' || $action == 'edit' || $action == 'search' || $action == 're-edit') && ($user->rights->produit->creer || $user->rights->service->creer)) diff --git a/htdocs/product/fournisseurs.php b/htdocs/product/fournisseurs.php index 9d7a9215ef1..abeb8fdf995 100644 --- a/htdocs/product/fournisseurs.php +++ b/htdocs/product/fournisseurs.php @@ -523,20 +523,20 @@ if ($id || $ref) $param="&id=".$product->id; print ''; print_liste_field_titre($langs->trans("Suppliers"),$_SERVER["PHP_SELF"],"s.nom","",$param,"",$sortfield,$sortorder); - print ''.$langs->trans("SupplierRef").''; + print_liste_field_titre($langs->trans("SupplierRef")); if (!empty($conf->global->FOURN_PRODUCT_AVAILABILITY)) print_liste_field_titre($langs->trans("Availability"),$_SERVER["PHP_SELF"],"pfp.fk_availability","",$param,"",$sortfield,$sortorder); print_liste_field_titre($langs->trans("QtyMin"),$_SERVER["PHP_SELF"],"pfp.quantity","",$param,'align="right"',$sortfield,$sortorder); - print ''.$langs->trans("VATRate").''; - print ''.$langs->trans("PriceQtyMinHT").''; + print_liste_field_titre($langs->trans("VATRate")); + print_liste_field_titre($langs->trans("PriceQtyMinHT")); print_liste_field_titre($langs->trans("UnitPriceHT"),$_SERVER["PHP_SELF"],"pfp.unitprice","",$param,'align="right"',$sortfield,$sortorder); - print ''.$langs->trans("DiscountQtyMin").''; + print_liste_field_titre($langs->trans("DiscountQtyMin")); print_liste_field_titre($langs->trans("NbDaysToDelivery"),$_SERVER["PHP_SELF"],"pfp.delivery_time_days","",$param,'align="right"',$sortfield,$sortorder); // Charges ???? if ($conf->global->PRODUCT_CHARGES) { - if (! empty($conf->margin->enabled)) print ''.$langs->trans("UnitCharges").''; + if (! empty($conf->margin->enabled)) print_liste_field_titre($langs->trans("UnitCharges")); } - print ''; + print_liste_field_titre(''); print "\n"; $product_fourn = new ProductFournisseur($db); diff --git a/htdocs/public/test/test_arrays.php b/htdocs/public/test/test_arrays.php index 7cbd9898204..2f0e903b8c5 100644 --- a/htdocs/public/test/test_arrays.php +++ b/htdocs/public/test/test_arrays.php @@ -65,7 +65,7 @@ else

This page is a sample of page using tables. It is designed to make test with
-- css (edit page to change to test another css)
+- css (add parameter &theme=newthem to test another theme or edit css of current theme)
- jmobile (add parameter dol_use_jmobile=1&dol_optimize_smallscreen=1 to enable view with jmobile)
- dataTables
- tablednd
@@ -115,9 +115,13 @@ This page is a sample of page using tables. It is designed to make test with
-


Example 1 : Standard table => Use this if you need the drag and drop for lines
+


Example 1 : Standard table/thead/tbody/tr/th-td (no class pair/impair on td) => Use this if you need the drag and drop for lines
initAsSpecimen(); + $sortfield='aaa'; $sortorder='ASC'; $tasksarray=array(1,2,3); // To force having several lines @@ -130,14 +134,14 @@ if (! empty($conf->use_javascript_ajax)) include DOL_DOCUMENT_ROOT.'/core/tpl/aj trans('title2'),0,$_SERVER["PHP_SELF"],'bbb','','','align="right"',$sortfield,$sortorder); ?> trans('title3'),0,$_SERVER["PHP_SELF"],'ccc','','','align="center"',$sortfield,$sortorder); ?> -a1b1c1 -a2b2c2 +getNomUrl(1); ?>b1c1 +a2b2c2
-


Example 2 : Table using tags: table/thead/tbody/tr/td + dataTable => Use this for long result tables
+


Example 2 : Table using tags: table/thead/tbody/tr/th-td + dataTable => Use this for long result tables
@@ -221,9 +225,11 @@ $('xxxth').replaceWith( - - - trans('zzz'),1,$_SERVER["PHP_SELF"],'','','','align="center" class="tagtd"',$sortfield,$sortorder); ?> + + + trans('Column C'),1,$_SERVER["PHP_SELF"],'','','','align="center" class="tagtd"',$sortfield,$sortorder); + ?> @@ -292,7 +298,7 @@ $('xxxth').replaceWith(
-


Example 3 : Table using tags: div.tagtable+div.tagtr+div or div.tagtable+div.tagtr+div.tagtd => Use this, but AVOID IT if possible, for tables that need to have a different form for each line (drag and drop of lines does not work for this case, also height of title can't be forced to a minimum)

+


Example 3 : Table using tags: div.tagtable+div.tagtr+div or div.tagtable+div.tagtr+div.tagtd => Use this for tables that need to have a different form for each line, but AVOID IT if possible (drag and drop of lines does not work for this case, also height of title can't be forced to a minimum)

-
line3
-
dfsdf
-
ffdsfsd
-
aaaa
+
Title A
+
title B
+
title C
+
title D
-
+
line4
dfsdf
bbbb
-
+
line5
dfsdf
bbbb
+
+
line6
+
jghjgh
+
5
+
lll
+
snakeColumn A