diff --git a/ChangeLog b/ChangeLog index a009533f07a..21d3ebc66b3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -6,8 +6,8 @@ WARNING: Do not try to make any Dolibarr upgrade if you are running Mysql version 5.5.40. Mysql version 5.5.40 has a very critical bug making your data beeing definitely lost. -You may also experience troubles with Mysql 5.5.41/42/43 with error "Lost connection" -during migration. +You may also experience troubles with Mysql 5.5.41/42/43 with error "Lost connection" during +migration. Upgrading to any other version or any other database system is abolutely required BEFORE trying make a Dolibarr upgrade. @@ -25,6 +25,8 @@ Dolibarr 4.0 should be compatible with PHP 7 but more feedbacks are still expect Following changes may create regression for some external modules, but were necessary to make Dolibarr better: - Function log() of class CommandeFournisseur has been removed. Using it is no more required. +- Class Resource was renamed into DolResource to avoid conflict with a reserved PHP word. +- Method commonobject->add_thumb() has been renamed into commonobject->addThumbs(). - Method select_type_comptes_financiers() has been renamed into selectTypeOfBankAccount() - Property ->client that was deprecated 6 years ago, is replaced in all core code with ->thirdparty. - File '/core/tpl/document_actions_pre_headers.tpl.php' were renamed into '/core/actions_linkedfiles.inc.php'. @@ -33,7 +35,6 @@ So if you included it into your module, change your code like this to be compati if (! $res) include_once DOL_DOCUMENT_ROOT . '/core/tpl/document_actions_pre_headers.tpl.php'; - ***** ChangeLog for 3.9.1 compared to 3.9.* ***** FIX: #3815 Call to undefined function local_by_date() FIX: #4424 Missing email of user popup in supplier orders area diff --git a/build/exe/doliwamp/doliwamp.bmp b/build/exe/doliwamp/doliwamp.bmp index 52b1320d111..87191204d8c 100644 Binary files a/build/exe/doliwamp/doliwamp.bmp and b/build/exe/doliwamp/doliwamp.bmp differ diff --git a/build/makepack-dolibarr.pl b/build/makepack-dolibarr.pl index b8c4f2fb475..8a70ea73f2c 100755 --- a/build/makepack-dolibarr.pl +++ b/build/makepack-dolibarr.pl @@ -379,7 +379,7 @@ if ($nboftargetok) { print 'Run git tag -a -m "'.$MAJOR.'.'.$MINOR.'.'.$BUILD.'" "'.$MAJOR.'.'.$MINOR.'.'.$BUILD.'"'."\n"; $ret=`git tag -a -m "$MAJOR.$MINOR.$BUILD" "$MAJOR.$MINOR.$BUILD" 2>&1`; - if ($ret =~ /already exists/) + if ($ret =~ /(already exists|existe déjà)/) { print "WARNING: Tag ".$MAJOR.'.'.$MINOR.'.'.$BUILD." already exists. Overwrite (y/N) ? "; $QUESTIONOVERWRITETAG=; diff --git a/doc/images/dolibarr_screenshot1_1280x800.png b/doc/images/dolibarr_screenshot1_1280x800.png index 9aa799a10a7..684feb62390 100644 Binary files a/doc/images/dolibarr_screenshot1_1280x800.png and b/doc/images/dolibarr_screenshot1_1280x800.png differ diff --git a/doc/images/dolibarr_screenshot1_300x188.png b/doc/images/dolibarr_screenshot1_300x188.png index 9fab4daa8ef..b849e202206 100644 Binary files a/doc/images/dolibarr_screenshot1_300x188.png and b/doc/images/dolibarr_screenshot1_300x188.png differ diff --git a/doc/images/dolibarr_screenshot1_640x400.png b/doc/images/dolibarr_screenshot1_640x400.png index 3f0d38832e1..9efefcc2405 100644 Binary files a/doc/images/dolibarr_screenshot1_640x400.png and b/doc/images/dolibarr_screenshot1_640x400.png differ diff --git a/htdocs/accountancy/journal/bankjournal.php b/htdocs/accountancy/journal/bankjournal.php index c32846ae22e..c990465bacf 100644 --- a/htdocs/accountancy/journal/bankjournal.php +++ b/htdocs/accountancy/journal/bankjournal.php @@ -238,7 +238,7 @@ if ($result) { $paymentsalstatic->ref = $links[$key]['url_id']; $paymentsalstatic->label = $links[$key]['label']; $tabpay[$obj->rowid]["lib"] .= ' ' . $paymentsalstatic->getNomUrl(2); - $tabtp[$obj->rowid][$account_employee ] += $obj->amount; + $tabtp[$obj->rowid][$account_employee] += $obj->amount; } else if ($links[$key]['type'] == 'banktransfert') { $tabpay[$obj->rowid]["lib"] .= ' ' . $langs->trans("BankTransfer"); $tabtp[$obj->rowid][$account_transfer] += $obj->amount; @@ -418,12 +418,27 @@ if ($action == 'export_csv') { foreach ( $tabpay as $key => $val ) { $date = dol_print_date($db->jdate($val["date"]), '%d%m%Y'); + $reflabel = $val["ref"]; + if ($reflabel == '(SupplierInvoicePayment)') { + $reflabel = $langs->trans('Supplier'); + } + if ($reflabel == '(CustomerInvoicePayment)') { + $reflabel = $langs->trans('Customer'); + } + if ($reflabel == '(SocialContributionPayment)') { + $reflabel = $langs->trans('SocialContribution'); + } + if ($reflabel == '(DonationPayment)') { + $reflabel = $langs->trans('Donation'); + } + if ($reflabel == '(SubscriptionPayment)') { + $reflabel = $langs->trans('Donation'); + } + $companystatic->id = $tabcompany[$key]['id']; $companystatic->name = $tabcompany[$key]['name']; $companystatic->client = $tabcompany[$key]['code_client']; - $date = dol_print_date($db->jdate($val["date"]), '%d%m%Y'); - // Bank foreach ( $tabbq[$key] as $k => $mt ) { print $date . $sep; @@ -432,8 +447,12 @@ if ($action == 'export_csv') { print $sep; print ($mt < 0 ? 'C' : 'D') . $sep; print ($mt <= 0 ? price(- $mt) : $mt) . $sep; - print $val["type_payment"] . $sep; - print utf8_decode($val["ref"]) . $sep; + if ($companystatic->name == '') { + print $langs->trans('Bank')." - ". utf8_decode($val["ref"]) . $sep; + } else { + print $langs->trans("Bank") .' - '.utf8_decode($companystatic->name) . $sep; + } + print utf8_decode($reflabel) . $sep; print "\n"; } @@ -443,33 +462,45 @@ if ($action == 'export_csv') { if ($mt) { print $date . $sep; print $journal . $sep; - if ($val["lib"] == '(SupplierInvoicePayment)') { - print length_accountg($conf->global->ACCOUNTING_ACCOUNT_SUPPLIER) . $sep; - } else { + if ($tabtype[$key] == 'payment') { print length_accountg($conf->global->ACCOUNTING_ACCOUNT_CUSTOMER) . $sep; + print length_accounta(html_entity_decode($k)) . $sep; + } else if ($tabtype[$key] == 'payment_supplier') { + print length_accountg($conf->global->ACCOUNTING_ACCOUNT_SUPPLIER) . $sep; + print length_accounta(html_entity_decode($k)) . $sep; + } else { + print length_accountg(html_entity_decode($k)) . $sep; + print $sep; } - print length_accounta(html_entity_decode($k)) . $sep; print ($mt < 0 ? 'D' : 'C') . $sep; print ($mt <= 0 ? price(- $mt) : $mt) . $sep; - print $val["type_payment"] . $sep; - print utf8_decode($val["ref"]) . $sep; + if ($companystatic->name == '') { + print $langs->trans('ThirdParty')." - ". utf8_decode($val["ref"]) . $sep; + } else { + print $langs->trans('ThirdParty')." - ". utf8_decode($companystatic->name) . $sep; + } + print utf8_decode($reflabel) . $sep; print "\n"; } } } else { foreach ( $tabbq[$key] as $k => $mt ) { - print $date . $sep; - print $journal . $sep; - print length_accountg($conf->global->ACCOUNTING_ACCOUNT_SUSPENSE) . $sep; - print $sep; - print ($mt < 0 ? 'D' : 'C') . $sep; - print ($mt <= 0 ? price(- $mt) : $mt) . $sep; - print $val["type_payment"] . $sep; - print utf8_decode($val["ref"]) . $sep; - print "\n"; + print $date . $sep; + print $journal . $sep; + print length_accountg($conf->global->ACCOUNTING_ACCOUNT_SUSPENSE) . $sep; + print $sep; + print ($mt < 0 ? 'D' : 'C') . $sep; + print ($mt <= 0 ? price(- $mt) : $mt) . $sep; + if ($companystatic->name == '') { + print $langs->trans('ThirdParty')." - ". utf8_decode($val["ref"]) . $sep; + } else { + print $langs->trans('ThirdParty')." - ". utf8_decode($companystatic->name) . $sep; } + print utf8_decode($reflabel) . $sep; + print "\n"; } } + } } else { // Model Classic Export foreach ( $tabpay as $key => $val ) { @@ -480,6 +511,7 @@ if ($action == 'export_csv') { // Bank foreach ( $tabbq[$key] as $k => $mt ) { + print '"' . $journal . '"' . $sep; print '"' . $date . '"' . $sep; print '"' . $val["type_payment"] . '"' . $sep; print '"' . length_accountg(html_entity_decode($k)) . '"' . $sep; @@ -488,7 +520,6 @@ if ($action == 'export_csv') { } else { print '"' . $langs->trans("Bank") . ' - ' . utf8_decode($companystatic->name) . '"' . $sep; } - // print '"' . $langs->trans("Bank") . '"' . $sep; print '"' . ($mt >= 0 ? price($mt) : '') . '"' . $sep; print '"' . ($mt < 0 ? price(- $mt) : '') . '"'; print "\n"; @@ -498,10 +529,10 @@ if ($action == 'export_csv') { if (is_array($tabtp[$key])) { foreach ( $tabtp[$key] as $k => $mt ) { if ($mt) { + print '"' . $journal . '"' . $sep; print '"' . $date . '"' . $sep; print '"' . $val["type_payment"] . '"' . $sep; print '"' . length_accounta(html_entity_decode($k)) . '"' . $sep; - // print '"' . $companystatic->name . '"' . $sep; if ($companystatic->name == '') { print '"' . $langs->trans('ThirdParty') . " - " . utf8_decode($val["ref"]) . '"' . $sep; } else { @@ -514,10 +545,10 @@ if ($action == 'export_csv') { } } else { foreach ( $tabbq[$key] as $k => $mt ) { + print '"' . $journal . '"' . $sep; print '"' . $date . '"' . $sep; print '"' . $val["ref"] . '"' . $sep; print '"' . length_accountg($conf->global->ACCOUNTING_ACCOUNT_SUSPENSE) . '"' . $sep; - // print '"' . $langs->trans("Bank") . '"' . $sep; if ($companystatic->name == '') { print '"' . $langs->trans("Bank") . ' - ' . utf8_decode($val["ref"]) . '"' . $sep; } else { @@ -599,6 +630,9 @@ else { if ($reflabel == '(DonationPayment)') { $reflabel = $langs->trans('Donation'); } + if ($reflabel == '(SubscriptionPayment)') { + $reflabel = $langs->trans('SubscriptionPayment'); + } // Bank foreach ( $tabbq[$key] as $k => $mt ) { diff --git a/htdocs/admin/company.php b/htdocs/admin/company.php index c9e07677512..ee6cbac057f 100644 --- a/htdocs/admin/company.php +++ b/htdocs/admin/company.php @@ -731,7 +731,9 @@ else $var=!$var; print ''.$langs->trans("CompanyCurrency").''; print currency_name($conf->currency,1); - print ' ('.$langs->getCurrencySymbol($conf->currency).')'; + print ' ('.$conf->currency; + print ($conf->currency != $langs->getCurrencySymbol($conf->currency) ? ' - '.$langs->getCurrencySymbol($conf->currency) : ''); + print ')'; print ''; $var=!$var; diff --git a/htdocs/admin/dict.php b/htdocs/admin/dict.php index ea745e45df7..f51a2994c60 100644 --- a/htdocs/admin/dict.php +++ b/htdocs/admin/dict.php @@ -189,7 +189,7 @@ $tabsql[28]= "SELECT h.rowid as rowid, h.code, h.label, h.affect, h.delay, h.new $tabsql[29]= "SELECT rowid as rowid, code, label, percent, position, active FROM ".MAIN_DB_PREFIX."c_lead_status"; $tabsql[30]= "SELECT rowid, code, name, paper_size, orientation, metric, leftmargin, topmargin, nx, ny, spacex, spacey, width, height, font_size, custom_x, custom_y, active FROM ".MAIN_DB_PREFIX."c_format_cards"; $tabsql[31]= "SELECT s.rowid as rowid, pcg_version, s.fk_pays as country_id, c.code as country_code, c.label as country, s.label, s.active FROM ".MAIN_DB_PREFIX."accounting_system as s, ".MAIN_DB_PREFIX."c_country as c WHERE s.fk_pays=c.rowid and c.active=1"; -$tabsql[32]= "SELECT a.rowid as rowid, a.code as code, a.label, a.range_account, a.position, a.fk_country as country_id, c.code as country_code, c.label as country, a.active FROM ".MAIN_DB_PREFIX."c_accounting_category as a, ".MAIN_DB_PREFIX."c_country as c WHERE a.fk_country=c.rowid and c.active=1"; +$tabsql[32]= "SELECT a.rowid as rowid, a.code as code, a.label, a.range_account, a.sens, a.category_type, a.formula, a.position as position, a.fk_country as country_id, c.code as country_code, c.label as country, a.active FROM ".MAIN_DB_PREFIX."c_accounting_category as a, ".MAIN_DB_PREFIX."c_country as c WHERE a.fk_country=c.rowid and c.active=1"; $tabsql[33]= "SELECT rowid, pos, code, label, active FROM ".MAIN_DB_PREFIX."c_hrm_department"; $tabsql[34]= "SELECT rowid, pos, code, label, c_level, active FROM ".MAIN_DB_PREFIX."c_hrm_function"; @@ -226,7 +226,7 @@ $tabsqlsort[28]="country ASC, code ASC"; $tabsqlsort[29]="position ASC"; $tabsqlsort[30]="code ASC"; $tabsqlsort[31]="pcg_version ASC"; -$tabsqlsort[32]="code ASC, label ASC"; +$tabsqlsort[32]="position ASC"; $tabsqlsort[33]="code ASC"; $tabsqlsort[34]="code ASC"; @@ -263,7 +263,7 @@ $tabfield[28]= "code,label,affect,delay,newbymonth,country_id,country"; $tabfield[29]= "code,label,percent,position"; $tabfield[30]= "code,name,paper_size,orientation,metric,leftmargin,topmargin,nx,ny,spacex,spacey,width,height,font_size,custom_x,custom_y"; $tabfield[31]= "pcg_version,country_id,country,label"; -$tabfield[32]= "code,label,range,position,country_id,country"; +$tabfield[32]= "code,label,range_account,sens,category_type,formula,position,country_id,country"; $tabfield[33]= "code,label"; $tabfield[34]= "code,label"; @@ -300,7 +300,7 @@ $tabfieldvalue[28]= "code,label,affect,delay,newbymonth,country"; $tabfieldvalue[29]= "code,label,percent,position"; $tabfieldvalue[30]= "code,name,paper_size,orientation,metric,leftmargin,topmargin,nx,ny,spacex,spacey,width,height,font_size,custom_x,custom_y"; $tabfieldvalue[31]= "pcg_version,country,label"; -$tabfieldvalue[32]= "code,label,range_account,position,country"; +$tabfieldvalue[32]= "code,label,range_account,sens,category_type,formula,position,country"; $tabfieldvalue[33]= "code,label"; $tabfieldvalue[34]= "code,label"; @@ -337,7 +337,7 @@ $tabfieldinsert[28]= "code,label,affect,delay,newbymonth,fk_country"; $tabfieldinsert[29]= "code,label,percent,position"; $tabfieldinsert[30]= "code,name,paper_size,orientation,metric,leftmargin,topmargin,nx,ny,spacex,spacey,width,height,font_size,custom_x,custom_y"; $tabfieldinsert[31]= "pcg_version,fk_pays,label"; -$tabfieldinsert[32]= "code,label,range_account,position,fk_country"; +$tabfieldinsert[32]= "code,label,range_account,sens,category_type,formula,position,fk_country"; $tabfieldinsert[33]= "code,label"; $tabfieldinsert[34]= "code,label"; @@ -524,6 +524,7 @@ if ($id == 11) 'propal' => $langs->trans('Proposal'), 'commande' => $langs->trans('Order'), 'facture' => $langs->trans('Bill'), + 'resource' => $langs->trans('Resource'), // 'facture_fourn' => $langs->trans('SupplierBill'), 'fichinter' => $langs->trans('InterventionCard') ); @@ -585,6 +586,7 @@ if (GETPOST('actionadd') || GETPOST('actionmodify')) if ($value == 'localtax1' && empty($_POST['localtax1_type'])) continue; if ($value == 'localtax2' && empty($_POST['localtax2_type'])) continue; if ($value == 'color' && empty($_POST['color'])) continue; + if ($value == 'formula' && empty($_POST['formula'])) continue; if ((! isset($_POST[$value]) || $_POST[$value]=='') && (! in_array($listfield[$f], array('decalage','module','accountancy_code','accountancy_code_sell','accountancy_code_buy'))) // Fields that are not mandatory ) @@ -605,6 +607,7 @@ if (GETPOST('actionadd') || GETPOST('actionmodify')) if ($fieldnamekey == 'unicode') $fieldnamekey = 'Unicode'; if ($fieldnamekey == 'deductible') $fieldnamekey = 'Deductible'; if ($fieldnamekey == 'sortorder') $fieldnamekey = 'SortOrder'; + if ($fieldnamekey == 'category_type') $fieldnamekey = 'Calculated'; setEventMessages($langs->transnoentities("ErrorFieldRequired", $langs->transnoentities($fieldnamekey)), null, 'errors'); } @@ -999,6 +1002,9 @@ if ($id) if ($fieldlist[$field]=='short_label') { $valuetoshow=$langs->trans("ShortLabel"); } if ($fieldlist[$field]=='type_template') { $valuetoshow=$langs->trans("TypeOfTemplate"); } if ($fieldlist[$field]=='range_account') { $valuetoshow=$langs->trans("Range"); } + if ($fieldlist[$field]=='sens') { $valuetoshow=$langs->trans("Sens"); } + if ($fieldlist[$field]=='category_type') { $valuetoshow=$langs->trans("Calculated"); } + if ($fieldlist[$field]=='formula') { $valuetoshow=$langs->trans("Formula"); } if ($id == 2) // Special cas for state page { @@ -1167,6 +1173,9 @@ if ($id) if ($fieldlist[$field]=='short_label') { $valuetoshow=$langs->trans("ShortLabel"); } if ($fieldlist[$field]=='type_template') { $valuetoshow=$langs->trans("TypeOfTemplate"); } if ($fieldlist[$field]=='range_account') { $valuetoshow=$langs->trans("Range"); } + if ($fieldlist[$field]=='sens') { $valuetoshow=$langs->trans("Sens"); } + if ($fieldlist[$field]=='category_type') { $valuetoshow=$langs->trans("Calculated"); } + if ($fieldlist[$field]=='formula') { $valuetoshow=$langs->trans("Formula"); } // Affiche nom du champ if ($showfield) @@ -1248,7 +1257,7 @@ if ($id) $valuetoshow=($key != "Country".strtoupper($obj->country_code)?$obj->country_code." - ".$key:$obj->country); } } - else if ($fieldlist[$field]=='recuperableonly' || $fieldlist[$field]=='fdm' || $fieldlist[$field] == 'deductible') { + else if ($fieldlist[$field]=='recuperableonly' || $fieldlist[$field]=='fdm' || $fieldlist[$field] == 'deductible' || $fieldlist[$field] == 'category_type') { $valuetoshow=yn($valuetoshow); $align="center"; } @@ -1618,7 +1627,7 @@ function fieldList($fieldlist, $obj='', $tabname='', $context='') print 'user'; print ''; } - elseif ($fieldlist[$field] == 'recuperableonly' || $fieldlist[$field] == 'fdm' || $fieldlist[$field] == 'deductible') { + elseif ($fieldlist[$field] == 'recuperableonly' || $fieldlist[$field] == 'fdm' || $fieldlist[$field] == 'deductible' || $fieldlist[$field] == 'category_type') { print ''; print $form->selectyesno($fieldlist[$field],(! empty($obj->{$fieldlist[$field]})?$obj->{$fieldlist[$field]}:''),1); print ''; @@ -1697,7 +1706,7 @@ function fieldList($fieldlist, $obj='', $tabname='', $context='') if ($fieldlist[$field]=='position') $size='size="4" '; if ($fieldlist[$field]=='libelle') $size='centpercent'; if ($fieldlist[$field]=='tracking') $class='centpercent'; - if ($fieldlist[$field]=='sortorder') $size='size="2" '; + if ($fieldlist[$field]=='sortorder' || $fieldlist[$field]=='sens' || $fieldlist[$field]=='category_type') $size='size="2" '; print ''; print ''; } diff --git a/htdocs/admin/fckeditor.php b/htdocs/admin/fckeditor.php index b5bd4d045f6..e244941ff58 100644 --- a/htdocs/admin/fckeditor.php +++ b/htdocs/admin/fckeditor.php @@ -189,7 +189,19 @@ else show_skin(null,1); print '
'."\n"; - print load_fiche_titre($langs->trans("TestSubmitForm"),'(mode='.$mode.')',''); + $listofmodes=array('dolibarr_mailings','dolibarr_notes','dolibarr_details','Full'); + $linkstomode=''; + foreach($listofmodes as $newmode) + { + if ($linkstomode) $linkstomode.=' - '; + $linkstomode.=''; + if ($mode == $newmode) $linkstomode.=''; + $linkstomode.=$newmode; + if ($mode == $newmode) $linkstomode.=''; + $linkstomode.=''; + } + $linkstomode.=''; + print load_fiche_titre($langs->trans("TestSubmitForm"),$linkstomode,''); print ''; $uselocalbrowser=true; $readonly=($mode=='dolibarr_readonly'?1:0); diff --git a/htdocs/admin/loan.php b/htdocs/admin/loan.php index 1cc55bd5a36..3213503835d 100644 --- a/htdocs/admin/loan.php +++ b/htdocs/admin/loan.php @@ -1,5 +1,5 @@ +/* Copyright (C) 2014-2016 Alexandre Spangaro * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -26,6 +26,7 @@ require '../main.inc.php'; // Class require_once DOL_DOCUMENT_ROOT.'/core/lib/admin.lib.php'; +if (! empty($conf->accounting->enabled)) require_once DOL_DOCUMENT_ROOT . '/accountancy/class/html.formventilation.class.php'; $langs->load("admin"); $langs->load("loan"); @@ -76,6 +77,7 @@ if ($action == 'update') llxHeader(); $form = new Form($db); +if (! empty($conf->accounting->enabled)) $formaccountancy = New FormVentilation($db); $linkback=''.$langs->trans("BackToModuleList").''; print load_fiche_titre($langs->trans('ConfigLoan'),$linkback,'title_setup'); @@ -104,7 +106,14 @@ foreach ($list as $key) // Value print ''; - print ''; + if (! empty($conf->accounting->enabled)) + { + print $formaccountancy->select_account($conf->global->$key, $key, 1, '', 1, 1); + } + else + { + print ''; + } print ''; } diff --git a/htdocs/admin/menus/edit.php b/htdocs/admin/menus/edit.php index f4f1bbb96bf..5fc39432c8e 100644 --- a/htdocs/admin/menus/edit.php +++ b/htdocs/admin/menus/edit.php @@ -75,6 +75,7 @@ if ($action == 'update') $menu->perms=$_POST['perms']; $menu->target=$_POST['target']; $menu->user=$_POST['user']; + $menu->fk_menu=$_POST['fk_menu']; $result=$menu->update($user); if ($result > 0) { @@ -275,6 +276,8 @@ if ($action == 'create') print '
'; print ''; + dol_fiche_head(); + print ''; // Id @@ -368,8 +371,10 @@ if ($action == 'create') print '
'; + dol_fiche_end(); + // Boutons - print '
'; + print '
'; print ''; print '     '; print ''; @@ -387,6 +392,8 @@ elseif ($action == 'edit') print ''; print ''; + dol_fiche_head(); + print ''; $menu = new Menubase($db); @@ -416,9 +423,9 @@ elseif ($action == 'edit') // MenuId Parent print ''; + print ''; //$menu_handler //print ''; - print ''; print ''; // Niveau @@ -454,8 +461,10 @@ elseif ($action == 'edit') print '
'.$langs->trans('MenuIdParent').''.$menu->fk_menu.''.$langs->trans('DetailMenuIdParent').'
'; + dol_fiche_end(); + // Bouton - print '
'; + print '
'; print ''; print '     '; print ''; diff --git a/htdocs/api/admin/explorer.php b/htdocs/api/admin/explorer.php index 44a14f99675..66d06e91679 100644 --- a/htdocs/api/admin/explorer.php +++ b/htdocs/api/admin/explorer.php @@ -150,12 +150,30 @@ $linkback=''.$langs->trans("BackToM print load_fiche_titre($langs->trans("ApiSetup"),$linkback,'title_setup'); +// Define $urlwithroot +$urlwithouturlroot=preg_replace('/'.preg_quote(DOL_URL_ROOT,'/').'$/i','',trim($dolibarr_main_url_root)); +$urlwithroot=$urlwithouturlroot.DOL_URL_ROOT; // This is to use external domain name found into config file +//$urlwithroot=DOL_MAIN_URL_ROOT; // This is to use same domain name than current + +// Show message +print '
'; +$message=''; +$url='
'.$urlwithroot.'/api/index.php/login?login='.urlencode($user->login).'&password=yourpassword'; +$message.=$langs->trans("UrlToGetKeyToUseAPIs").':
'; +$message.=img_picto('','object_globe.png').' '.$url; +print $message; +print '
'; +print '
'; + +print $langs->trans("ListOfAvailableAPIs").':
'; foreach($listofapis['v1'] as $key => $val) { + if ($key == 'login') continue; if ($key) { //print $key.' - '.$val['classname'].' - '.$val['fullpath']." - ".DOL_MAIN_URL_ROOT.'/api/index.php/'.strtolower(preg_replace('/Api$/','',$val['classname']))."/xxx
\n"; - $url=DOL_MAIN_URL_ROOT.'/api/index.php/'.$key; + $url=$urlwithroot.'/api/index.php/'.$key; + $url.='?api_key=token'; print img_picto('','object_globe.png').' '.$url."
\n"; } diff --git a/htdocs/api/class/api_access.class.php b/htdocs/api/class/api_access.class.php index 9d29c60e26a..67f8c710bb7 100644 --- a/htdocs/api/class/api_access.class.php +++ b/htdocs/api/class/api_access.class.php @@ -116,16 +116,13 @@ class DolibarrApiAccess implements iAuthenticate else { throw new RestException(401, "Failed to login to API. No parameter 'api_key' provided"); - //dol_syslog("Failed to login to API. No parameter key provided", LOG_DEBUG); - //return false; } - $userClass::setCacheIdentifier(static::$role); - Resources::$accessControlFunction = 'DolibarrApiAccess::verifyAccess'; - - $requirefortest = static::$requires; - if (! is_array($requirefortest)) $requirefortest=explode(',',$requirefortest); - return in_array(static::$role, (array) static::$requirefortest) || static::$role == 'admin'; + $userClass::setCacheIdentifier(static::$role); + Resources::$accessControlFunction = 'DolibarrApiAccess::verifyAccess'; + $requirefortest = static::$requires; + if (! is_array($requirefortest)) $requirefortest=explode(',',$requirefortest); + return in_array(static::$role, (array) $requirefortest) || static::$role == 'admin'; } /** diff --git a/htdocs/api/index.php b/htdocs/api/index.php index d7bcedb5fd7..55a45aea4b9 100644 --- a/htdocs/api/index.php +++ b/htdocs/api/index.php @@ -141,6 +141,8 @@ foreach ($modulesdir as $dir) // TODO If not found, redirect to explorer + +// Call API (we suppose we found it) $api->r->handle(); diff --git a/htdocs/comm/index.php b/htdocs/comm/index.php index 5265f73e595..f1bf108f14c 100644 --- a/htdocs/comm/index.php +++ b/htdocs/comm/index.php @@ -87,6 +87,11 @@ if (! empty($conf->commande->enabled) && $user->rights->commande->lire) { $listofsearchfields['search_customer_order']=array('text'=>'CustomerOrder'); } +// Search supplier proposal +if (! empty($conf->supplier_proposal->enabled) && $user->rights->supplier_proposal->lire) +{ + $listofsearchfields['search_supplier_proposal']=array('text'=>'SupplierProposalShort'); +} // Search supplier order if (! empty($conf->fournisseur->enabled) && $user->rights->fournisseur->commande->lire) { @@ -100,12 +105,7 @@ if (! empty($conf->ficheinter->enabled) && $user->rights->ficheinter->lire) // Search contract if (! empty($conf->contrat->enabled) && $user->rights->contrat->lire) { - $listofsearchfields['search_contract']=array('text'=>'Contrat'); -} -// Search supplier proposal -if (! empty($conf->supplier_proposal->enabled) && $user->rights->supplier_proposal->lire) -{ - $listofsearchfields['search_supplier_proposal']=array('text'=>'SupplierProposalShort'); + $listofsearchfields['search_contract']=array('text'=>'Contract'); } if (count($listofsearchfields)) diff --git a/htdocs/commande/class/api_commande.class.php b/htdocs/commande/class/api_commande.class.php index 04d78f30a1d..d6a2a3d0f82 100644 --- a/htdocs/commande/class/api_commande.class.php +++ b/htdocs/commande/class/api_commande.class.php @@ -207,9 +207,9 @@ class CommandeApi extends DolibarrApi */ function post($request_data = NULL) { - if(! DolibarrApiAccess::$user->rights->commande->creer) { - throw new RestException(401); - } + if(! DolibarrApiAccess::$user->rights->commande->creer) { + throw new RestException(401, "Insuffisant rights"); + } // Check mandatory fields $result = $this->_validate($request_data); @@ -224,7 +224,7 @@ class CommandeApi extends DolibarrApi $this->commande->lines = $lines; } if(! $this->commande->create(DolibarrApiAccess::$user) ) { - throw new RestException(401); + throw new RestException(500, "Error while creating order"); } return $this->commande->id; diff --git a/htdocs/commande/class/commande.class.php b/htdocs/commande/class/commande.class.php index c4569418968..a0babc4d972 100644 --- a/htdocs/commande/class/commande.class.php +++ b/htdocs/commande/class/commande.class.php @@ -9,6 +9,7 @@ * Copyright (C) 2012 Cedric Salvador * Copyright (C) 2013 Florian Henry * Copyright (C) 2014-2015 Marcos García + * Copyright (C) 2016 Ferran Marcet * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -2516,7 +2517,7 @@ class Commande extends CommonOrder */ function updateline($rowid, $desc, $pu, $qty, $remise_percent, $txtva, $txlocaltax1=0.0,$txlocaltax2=0.0, $price_base_type='HT', $info_bits=0, $date_start='', $date_end='', $type=0, $fk_parent_line=0, $skip_update_total=0, $fk_fournprice=null, $pa_ht=0, $label='', $special_code=0, $array_options=0, $fk_unit=null) { - global $conf, $mysoc; + global $conf, $mysoc, $langs; dol_syslog(get_class($this)."::updateline id=$rowid, desc=$desc, pu=$pu, qty=$qty, remise_percent=$remise_percent, txtva=$txtva, txlocaltax1=$txlocaltax1, txlocaltax2=$txlocaltax2, price_base_type=$price_base_type, info_bits=$info_bits, date_start=$date_start, date_end=$date_end, type=$type, fk_parent_line=$fk_parent_line, pa_ht=$pa_ht, special_code=$special_code"); include_once DOL_DOCUMENT_ROOT.'/core/lib/price.lib.php'; @@ -2585,6 +2586,26 @@ class Commande extends CommonOrder $line = new OrderLine($this->db); $line->fetch($rowid); + if (!empty($line->fk_product)) + { + $product=new Product($this->db); + $result=$product->fetch($line->fk_product); + $product_type=$product->type; + + if (! empty($conf->global->STOCK_MUST_BE_ENOUGH_FOR_ORDER) && $product_type == 0 && $product->stock_reel < $qty) + { + $this->error=$langs->trans('ErrorStockIsNotEnough'); + dol_syslog(get_class($this)."::addline error=Product ".$product->ref.": ".$this->error, LOG_ERR); + $this->db->rollback(); + unset($_POST['productid']); + unset($_POST['tva_tx']); + unset($_POST['price_ht']); + unset($_POST['qty']); + unset($_POST['buying_price']); + return self::STOCK_NOT_ENOUGH_FOR_ORDER; + } + } + $staticline = clone $line; $line->oldline = $staticline; diff --git a/htdocs/commande/list.php b/htdocs/commande/list.php index 7aa1dc481e9..bad7fdbd4bf 100644 --- a/htdocs/commande/list.php +++ b/htdocs/commande/list.php @@ -673,6 +673,12 @@ if ($resql) $var=!$var; print ''; + $notshippable=0; + $warning = 0; + $text_info=''; + $text_warning=''; + $nbprod=0; + if (! empty($arrayfields['c.ref']['checked'])) { print ''; @@ -694,17 +700,11 @@ if ($resql) print ''; // Show shippable Icon (create subloop, so may be slow) - if ($conf->stock->enabled) + if ($conf->stock->enabled) { - $langs->load("stocks"); - if (($obj->fk_statut > 0) && ($obj->fk_statut < 3)) - { - $notshippable=0; - $warning = 0; - $text_info=''; - $text_warning=''; - $nbprod=0; - + $langs->load("stocks"); + if (($obj->fk_statut > 0) && ($obj->fk_statut < 3)) + { $numlines = count($generic_commande->lines); // Loop on each line of order for ($lig=0; $lig < $numlines; $lig++) { @@ -712,17 +712,19 @@ if ($resql) { $nbprod++; // order contains real products $generic_product->id = $generic_commande->lines[$lig]->fk_product; + + // Get local and virtual stock and store it into cache if (empty($productstat_cache[$generic_commande->lines[$lig]->fk_product])) { - $generic_product->load_stock(); - $generic_product->load_virtual_stock(); + $generic_product->load_stock('nobatch'); + //$generic_product->load_virtual_stock(); Already included into load_stock $productstat_cache[$generic_commande->lines[$lig]->fk_product]['stock_reel'] = $generic_product->stock_reel; $productstat_cachevirtual[$generic_commande->lines[$lig]->fk_product]['stock_reel'] = $generic_product->stock_theorique; } else { $generic_product->stock_reel = $productstat_cache[$generic_commande->lines[$lig]->fk_product]['stock_reel']; $generic_product->stock_theorique = $productstat_cachevirtual[$generic_commande->lines[$lig]->fk_product]['stock_reel'] = $generic_product->stock_theorique; } - - if (empty($conf->global->SHIPPABLE_ORDER_ICON_IN_LIST)) // Default code is when this option is not set, setting it create strange result + + if (empty($conf->global->SHIPPABLE_ORDER_ICON_IN_LIST)) // Default code. Default is when this option is not set, setting it create strange result { $text_info .= $generic_commande->lines[$lig]->qty.' X '.$generic_commande->lines[$lig]->ref.' '.dol_trunc($generic_commande->lines[$lig]->product_label, 25); $text_info .= ' - '.$langs->trans("Stock").': '.$generic_product->stock_reel; @@ -795,7 +797,7 @@ if ($resql) { print $form->textwithtooltip('',$text_info,2,1,$text_icon,'',2); } - if ($warning) { + if ($warning) { // Always false in default mode print $form->textwithtooltip('', $langs->trans('NotEnoughForAllOrders').'
'.$text_warning, 2, 1, img_picto('', 'error'),'',2); } print ''; diff --git a/htdocs/compta/bank/card.php b/htdocs/compta/bank/card.php index e2cecacb83c..102e6a6861a 100644 --- a/htdocs/compta/bank/card.php +++ b/htdocs/compta/bank/card.php @@ -3,7 +3,7 @@ * Copyright (C) 2003 Jean-Louis Bergamo * Copyright (C) 2004-2015 Laurent Destailleur * Copyright (C) 2005-2009 Regis Houssin - * Copyright (C) 2014-2015 Alexandre Spangaro + * Copyright (C) 2014-2016 Alexandre Spangaro * Copyright (C) 2015 Jean-François Ferry * Copyright (C) 2016 Marcos García * @@ -34,8 +34,8 @@ require_once DOL_DOCUMENT_ROOT . '/core/class/html.formcompany.class.php'; require_once DOL_DOCUMENT_ROOT . '/core/class/html.formbank.class.php'; require_once DOL_DOCUMENT_ROOT . '/compta/bank/class/account.class.php'; require_once DOL_DOCUMENT_ROOT . '/core/class/extrafields.class.php'; -require_once DOL_DOCUMENT_ROOT . '/core/lib/accounting.lib.php'; -if (! empty($conf->accounting->enabled)) require_once DOL_DOCUMENT_ROOT.'/accountancy/class/html.formventilation.class.php'; +if (! empty($conf->accounting->enabled)) require_once DOL_DOCUMENT_ROOT . '/core/lib/accounting.lib.php'; +if (! empty($conf->accounting->enabled)) require_once DOL_DOCUMENT_ROOT . '/accountancy/class/html.formventilation.class.php'; $langs->load("banks"); $langs->load("bills"); @@ -675,7 +675,13 @@ else print ''; // Accountancy code print ''; - print ''; + print ''; + } else { + print $account->account_number; + } + print ''; // Accountancy journal if (! empty($conf->accounting->enabled)) diff --git a/htdocs/compta/bank/class/account.class.php b/htdocs/compta/bank/class/account.class.php index 123f4537a58..478633490f8 100644 --- a/htdocs/compta/bank/class/account.class.php +++ b/htdocs/compta/bank/class/account.class.php @@ -7,6 +7,7 @@ * Copyright (C) 2013 Florian Henry * Copyright (C) 2015-2016 Marcos García * Copyright (C) 2015 Alexandre Spangaro + * Copyright (C) 2016 Ferran Marcet * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -588,7 +589,7 @@ class Account extends CommonObject { $this->id = $this->db->last_insert_id(MAIN_DB_PREFIX."bank_account"); - $result=$this->update(); + $result=$this->update($user); if ($result > 0) { $accline = new AccountLine($this->db); @@ -1100,15 +1101,19 @@ class Account extends CommonObject */ public static function countAccountToReconcile() { - global $db, $conf, $langs; - - if ($user->societe_id) return 0; // protection pour eviter appel par utilisateur externe + global $db, $conf, $user; + + //Protection against external users + if ($user->societe_id) { + return 0; + } $nb=0; $sql = "SELECT COUNT(ba.rowid) as nb"; $sql.= " FROM ".MAIN_DB_PREFIX."bank_account as ba"; $sql.= " WHERE ba.rappro > 0 and ba.clos = 0"; + $sql.= " AND ba.entity IN (".getEntity('bank_account', 1).")"; if (empty($conf->global->BANK_CAN_RECONCILIATE_CASHACCOUNT)) $sql.= " AND ba.courant != 2"; $resql=$db->query($sql); if ($resql) diff --git a/htdocs/compta/bank/treso.php b/htdocs/compta/bank/treso.php index db7f37cb3e5..0cee6211b49 100644 --- a/htdocs/compta/bank/treso.php +++ b/htdocs/compta/bank/treso.php @@ -136,7 +136,7 @@ if ($_REQUEST["account"] || $_REQUEST["ref"]) print ''; $var=!$var; - print ''; + print ''; print ''; print ''; print ''; diff --git a/htdocs/compta/facture.php b/htdocs/compta/facture.php index 55f259aa2fe..27ba03499c8 100644 --- a/htdocs/compta/facture.php +++ b/htdocs/compta/facture.php @@ -1,7 +1,7 @@ * Copyright (C) 2004 Eric Seigne - * Copyright (C) 2004-2014 Laurent Destailleur + * Copyright (C) 2004-2016 Laurent Destailleur * Copyright (C) 2005 Marc Barilley / Ocebo * Copyright (C) 2005-2015 Regis Houssin * Copyright (C) 2006 Andre Cianfarani @@ -83,6 +83,7 @@ $search_montant_ht = GETPOST('search_montant_ht', 'alpha'); $search_montant_ttc = GETPOST('search_montant_ttc', 'alpha'); $origin = GETPOST('origin', 'alpha'); $originid = (GETPOST('originid', 'int') ? GETPOST('originid', 'int') : GETPOST('origin_id', 'int')); // For backward compatibility +$fac_rec=GETPOST('fac_rec','int'); // PDF $hidedetails = (GETPOST('hidedetails', 'int') ? GETPOST('hidedetails', 'int') : (! empty($conf->global->MAIN_GENERATE_DOCUMENTS_HIDE_DETAILS) ? 1 : 0)); @@ -2082,8 +2083,9 @@ if ($action == 'create') $(document).ready(function() { $("#socid").change(function() { var socid = $(this).val(); + var fac_rec = $(\'#fac_rec\').val(); // reload page - window.location.href = "'.$_SERVER["PHP_SELF"].'?action=create&socid="+socid; + window.location.href = "'.$_SERVER["PHP_SELF"].'?action=create&socid="+socid+"&fac_rec="+fac_rec; }); }); '; @@ -2098,6 +2100,8 @@ if ($action == 'create') $invoice_predefined = new FactureRec($db); $invoice_predefined->fetch(GETPOST('fac_rec','int')); + $dateinvoice = $invoice_predefined->date_when; // To use next gen date by default later + $sql = 'SELECT r.rowid, r.titre, r.total_ttc'; $sql .= ' FROM ' . MAIN_DB_PREFIX . 'facture_rec as r'; $sql .= ' WHERE r.fk_soc = ' . $invoice_predefined->socid; @@ -2111,7 +2115,7 @@ if ($action == 'create') if ($num > 0) { print ''; + print ''; + // Option to reload page to retrieve customer informations. Note, this clear other input + if (!empty($conf->global->RELOAD_PAGE_ON_TEMPLATE_CHANGE)) + { + print ''; + } + print ''; } $db->free($resql); } else { @@ -2402,7 +2421,7 @@ if ($action == 'create') $langs->load('projects'); print ''; } @@ -3548,7 +3567,7 @@ else if ($id > 0 || ! empty($ref)) print '
'.$langs->trans("AccountancyCode").''.length_accountg($account->account_number).'
'; + if (! empty($conf->accounting->enabled)) { + print length_accountg($account->account_number).'
'.$langs->trans("RemainderToPay").' 
' . $langs->trans('CreateFromRepeatableInvoice') . ''; - print ''; print ''; while ($i < $num) { @@ -2122,7 +2126,22 @@ if ($action == 'create') print '>' . $objp->titre . ' (' . price($objp->total_ttc) . ' ' . $langs->trans("TTC") . ')'; $i ++; } - print '
' . $langs->trans('Project') . ''; $numprojet = $formproject->select_projects($socid, $projectid, 'projectid', 0); - print '   id).'">' . $langs->trans("AddProject") . ''; + print '   id.($fac_rec?'&fac_rec='.$fac_rec:'')).'">' . $langs->trans("AddProject") . ''; print '
'; print '
'; print $langs->trans('BankAccount'); print ''; - if (($action != 'editbankaccount') && $user->rights->commande->creer && ! empty($object->brouillon)) + if (($action != 'editbankaccount') && $user->rights->facture->creer && ! empty($object->brouillon)) print 'id.'">'.img_edit($langs->trans('SetBankAccount'),1).'
'; print ''; diff --git a/htdocs/compta/facture/class/facture-rec.class.php b/htdocs/compta/facture/class/facture-rec.class.php index 0acd58f0202..cddd511dbe4 100644 --- a/htdocs/compta/facture/class/facture-rec.class.php +++ b/htdocs/compta/facture/class/facture-rec.class.php @@ -53,7 +53,7 @@ class FactureRec extends CommonInvoice var $propalid; var $date_last_gen; - var $next_gen; + var $date_when; var $nb_gen_done; var $nb_gen_max; @@ -341,6 +341,17 @@ class FactureRec extends CommonInvoice } + /** + * Create an array of invoice lines + * + * @return int >0 if OK, <0 if KO + */ + function getLinesArray() + { + return $this->fetch_lines(); + } + + /** * Recupere les lignes de factures predefinies dans this->lines * @@ -348,16 +359,23 @@ class FactureRec extends CommonInvoice */ function fetch_lines() { + $this->lines=array(); + $sql = 'SELECT l.rowid, l.fk_product, l.product_type, l.label as custom_label, l.description, l.product_type, l.price, l.qty, l.tva_tx, '; $sql.= ' l.remise, l.remise_percent, l.subprice,'; - $sql.= ' l.total_ht, l.total_tva, l.total_ttc,'; + $sql.= ' l.info_bits, l.total_ht, l.total_tva, l.total_ttc,'; + //$sql.= ' l.situation_percent, l.fk_prev_id,'; + //$sql.= ' l.localtax1_tx, l.localtax2_tx, l.localtax1_type, l.localtax2_type, l.remise_percent, l.fk_remise_except, l.subprice,'; $sql.= ' l.rang, l.special_code,'; + //$sql.= ' l.info_bits, l.total_ht, l.total_tva, l.total_localtax1, l.total_localtax2, l.total_ttc, l.fk_code_ventilation, l.fk_product_fournisseur_price as fk_fournprice, l.buy_price_ht as pa_ht,'; $sql.= ' l.fk_unit, l.fk_contract_line,'; + //$sql.= ' l.fk_multicurrency, l.multicurrency_code, l.multicurrency_subprice, l.multicurrency_total_ht, l.multicurrency_total_tva, l.multicurrency_total_ttc,'; $sql.= ' p.ref as product_ref, p.fk_product_type as fk_product_type, p.label as product_label, p.description as product_desc'; $sql.= ' FROM '.MAIN_DB_PREFIX.'facturedet_rec as l'; $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'product as p ON l.fk_product = p.rowid'; $sql.= ' WHERE l.fk_facture = '.$this->id; - + $sql.= ' ORDER BY l.rang'; + dol_syslog('FactureRec::fetch_lines', LOG_DEBUG); $result = $this->db->query($sql); if ($result) @@ -387,10 +405,6 @@ class FactureRec extends CommonInvoice $line->remise_percent = $objp->remise_percent; $line->fk_remise_except = $objp->fk_remise_except; $line->fk_product = $objp->fk_product; - $line->date_start = $objp->date_start; - $line->date_end = $objp->date_end; - $line->date_start = $objp->date_start; - $line->date_end = $objp->date_end; $line->info_bits = $objp->info_bits; $line->total_ht = $objp->total_ht; $line->total_tva = $objp->total_tva; @@ -415,7 +429,7 @@ class FactureRec extends CommonInvoice } else { - $this->error=$this->db->error(); + $this->error=$this->db-lasterror(); return -3; } } diff --git a/htdocs/compta/facture/class/facture.class.php b/htdocs/compta/facture/class/facture.class.php index 4dbf4b9020a..8fee9cc5758 100644 --- a/htdocs/compta/facture/class/facture.class.php +++ b/htdocs/compta/facture/class/facture.class.php @@ -14,6 +14,7 @@ * Copyright (C) 2012-2014 Raphaël Doursenaud * Copyright (C) 2013 Cedric Gross * Copyright (C) 2013 Florian Henry + * Copyright (C) 2016 Ferran Marcet * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -280,24 +281,27 @@ class Facture extends CommonInvoice $this->socid = $_facrec->socid; + // Fields coming from GUI (priority on template). TODO Value of template should be used as default value on GUI so we can use here always value from GUI $this->fk_project = GETPOST('projectid','int') > 0 ? GETPOST('projectid','int') : $_facrec->fk_project; - $this->fk_account = $_facrec->fk_account; - $this->cond_reglement_id = $_facrec->cond_reglement_id; - $this->mode_reglement_id = $_facrec->mode_reglement_id; + $this->note_public = GETPOST('note_public') ? GETPOST('note_public') : $_facrec->note_public; + $this->note_private = GETPOST('note_private') ? GETPOST('note_private') : $_facrec->note_private; + $this->modelpdf = GETPOST('model') ? GETPOST('model') : $_facrec->modelpdf; + $this->cond_reglement_id = GETPOST('cond_reglement_id') > 0 ? GETPOST('cond_reglement_id') : $_facrec->cond_reglement_id; + $this->mode_reglement_id = GETPOST('mode_reglement_id') > 0 ? GETPOST('mode_reglement_id') : $_facrec->mode_reglement_id; + $this->fk_account = GETPOST('fk_account') > 0 ? GETPOST('fk_account') : $_facrec->fk_account; + + // Fields always coming from template $this->remise_absolue = $_facrec->remise_absolue; $this->remise_percent = $_facrec->remise_percent; $this->fk_incoterms = $_facrec->fk_incoterms; $this->location_incoterms= $_facrec->location_incoterms; - $this->note_public = $_facrec->note_public; - $this->note_private = $_facrec->note_private; - // Clean parameters if (! $this->type) $this->type = self::TYPE_STANDARD; $this->ref_client=trim($this->ref_client); $this->note_public=trim($this->note_public); $this->note_private=trim($this->note_private); - $this->note_private=dol_concatdesc($facture->note_private, $langs->trans("GeneratedFromRecurringInvoice", $_facrec->ref)); + $this->note_private=dol_concatdesc($this->note_private, $langs->trans("GeneratedFromRecurringInvoice", $_facrec->ref)); //if (! $this->remise) $this->remise = 0; if (! $this->mode_reglement_id) $this->mode_reglement_id = 0; @@ -2537,6 +2541,19 @@ class Facture extends CommonInvoice $line = new FactureLigne($this->db); $line->fetch($rowid); + if (!empty($line->fk_product)) + { + $product=new Product($this->db); + $result=$product->fetch($line->fk_product); + $product_type=$product->type; + + if (! empty($conf->global->STOCK_MUST_BE_ENOUGH_FOR_INVOICE) && $product_type == 0 && $product->stock_reel < $qty) { + $this->error=$langs->trans('ErrorStockIsNotEnough'); + $this->db->rollback(); + return -3; + } + } + $staticline = clone $line; $line->oldline = $staticline; @@ -2589,7 +2606,7 @@ class Facture extends CommonInvoice $this->line->array_options=$array_options; } - $result=$this->line->update(); + $result=$this->line->update($user); if ($result > 0) { // Reorder if child line @@ -2663,7 +2680,7 @@ class Facture extends CommonInvoice $line->total_ttc = $tabprice[2]; $line->total_localtax1 = $tabprice[9]; $line->total_localtax2 = $tabprice[10]; - $line->update(); + $line->update($user); $this->update_price(1); $this->db->commit(); } diff --git a/htdocs/compta/facture/fiche-rec.php b/htdocs/compta/facture/fiche-rec.php index ad9626718c6..b826e4f266d 100644 --- a/htdocs/compta/facture/fiche-rec.php +++ b/htdocs/compta/facture/fiche-rec.php @@ -33,6 +33,7 @@ require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture-rec.class.php'; require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php'; require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/class/html.formprojet.class.php'; +require_once DOL_DOCUMENT_ROOT.'/core/class/html.formother.class.php'; $langs->load('bills'); $langs->load('compta'); @@ -50,18 +51,29 @@ if ($action == "create" || $action == "add") $objecttype = ''; $result = restrictedArea($user, 'facture', $id, $objecttype); $projectid = GETPOST('projectid','int'); -if ($page == -1) -{ - $page = 0 ; -} +$search_ref=GETPOST('search_ref'); +$search_societe=GETPOST('search_societe'); +$search_montant_ht=GETPOST('search_montant_ht'); +$search_montant_vat=GETPOST('search_montant_vat'); +$search_montant_ttc=GETPOST('search_montant_ttc'); +$day=GETPOST('day'); +$year=GETPOST('year'); +$month=GETPOST('month'); +$day_date_when=GETPOST('day_date_when'); +$year_date_when=GETPOST('year_date_when'); +$month_date_when=GETPOST('month_date_when'); +$search_frequency=GETPOST('search_frequency'); + $limit = GETPOST('limit')?GETPOST('limit','int'):$conf->liste_limit; -$offset = $limit * $page ; - -if ($sortorder == "") -$sortorder="DESC"; - -if ($sortfield == "") -$sortfield="f.datef"; +$sortfield = GETPOST("sortfield",'alpha'); +$sortorder = GETPOST("sortorder",'alpha'); +$page = GETPOST("page",'int'); +if ($page == -1) { $page = 0; } +$offset = $limit * $page; +if (! $sortorder) $sortorder='DESC'; +if (! $sortfield) $sortfield='f.titre'; +$pageprev = $page - 1; +$pagenext = $page + 1; $object = new FactureRec($db); if (($id > 0 || $ref) && $action != 'create' && $action != 'add') @@ -73,13 +85,45 @@ if (($id > 0 || $ref) && $action != 'create' && $action != 'add') } } +// Initialize technical object to manage hooks of thirdparties. Note that conf->hooks_modules contains array array +$hookmanager->initHooks(array('invoicecard','globalcard')); +$extrafields = new ExtraFields($db); + +// fetch optionals attributes and labels +$extralabels = $extrafields->fetch_name_optionals_label('facturerec'); +$search_array_options=$extrafields->getOptionalsFromPost($extralabels,'','search_'); + +$permissionnote = $user->rights->facture->creer; // Used by the include of actions_setnotes.inc.php +$permissiondellink=$user->rights->facture->creer; // Used by the include of actions_dellink.inc.php +$permissiontoedit = $user->rights->facture->creer; // Used by the include of actions_lineupdonw.inc.php + +$arrayfields=array( + 'f.titre'=>array('label'=>$langs->trans("Ref"), 'checked'=>1), + 's.nom'=>array('label'=>$langs->trans("ThirdParty"), 'checked'=>1), + 'f.total'=>array('label'=>$langs->trans("AmountHT"), 'checked'=>1), + 'f.tva'=>array('label'=>$langs->trans("AmountVAT"), 'checked'=>1), + 'f.total_ttc'=>array('label'=>$langs->trans("AmountTTC"), 'checked'=>1), + 'f.frequency'=>array('label'=>$langs->trans("RecurringInvoiceTemplate"), 'checked'=>1), + 'f.date_last_gen'=>array('label'=>$langs->trans("DateLastGeneration"), 'checked'=>1), + 'f.date_when'=>array('label'=>$langs->trans("NextDateToExecution"), 'checked'=>1), + 'f.datec'=>array('label'=>$langs->trans("DateCreation"), 'checked'=>0, 'position'=>500), + 'f.tms'=>array('label'=>$langs->trans("DateModificationShort"), 'checked'=>0, 'position'=>500), +); +// Extra fields +if (is_array($extrafields->attribute_label) && count($extrafields->attribute_label)) +{ + foreach($extrafields->attribute_label as $key => $val) + { + $arrayfields["ef.".$key]=array('label'=>$extrafields->attribute_label[$key], 'checked'=>$extrafields->attribute_list[$key], 'position'=>$extrafields->attribute_pos[$key], 'enabled'=>$extrafields->attribute_perms[$key]); + } +} + /* * Actions */ // Set note -$permissionnote=$user->rights->facture->creer; // Used by the include of actions_setnotes.inc.php include DOL_DOCUMENT_ROOT.'/core/actions_setnotes.inc.php'; // Must be include, not include_once include DOL_DOCUMENT_ROOT.'/core/actions_lineupdown.inc.php'; // Must be include, not include_once @@ -101,7 +145,7 @@ if ($action == 'add') $rehour=GETPOST('rehour'); $remin=GETPOST('remin'); $nb_gen_max=GETPOST('nb_gen_max', 'int'); - if (empty($nb_gen_max)) $nb_gen_max =0; + //if (empty($nb_gen_max)) $nb_gen_max =0; if (GETPOST('frequency')) { @@ -111,7 +155,7 @@ if ($action == 'add') $action = "create"; $error++; } - if ($nb_gen_max == '') + if ($nb_gen_max === '') { setEventMessages($langs->transnoentities("ErrorFieldRequired",$langs->trans("MaxPeriodNumber")), null, 'errors'); $action = "create"; @@ -122,7 +166,8 @@ if ($action == 'add') if (! $error) { $object->titre = GETPOST('titre', 'alpha'); - $object->note_private = GETPOST('note_private'); + $object->note_private = GETPOST('note_private'); + $object->note_public = GETPOST('note_public'); $object->usenewprice = GETPOST('usenewprice'); $object->frequency = $frequency; @@ -570,6 +615,24 @@ if ($action == 'addline' && $user->rights->facture->creer) } } +// Do we click on purge search criteria ? +if (GETPOST("button_removefilter_x") || GETPOST("button_removefilter")) // Both test are required to be compatible with all browsers +{ + $search_ref=''; + $search_societe=''; + $search_montant_ht=''; + $search_montant_vat=''; + $search_montant_ttc=''; + $day=''; + $year=''; + $month=''; + $day_date_when=''; + $year_date_when=''; + $month_date_when=''; + $search_frequency=''; + $search_array_options=array(); +} + /* @@ -579,6 +642,7 @@ if ($action == 'addline' && $user->rights->facture->creer) llxHeader('',$langs->trans("RepeatableInvoices"),'ch-facture.html#s-fac-facture-rec'); $form = new Form($db); +$formother = new FormOther($db); $companystatic = new Societe($db); $now = dol_now(); @@ -599,7 +663,9 @@ if ($action == 'create') if ($object->fetch($id, $ref) > 0) { - print ''; + $result = $object->getLinesArray(); + + print ''; print ''; print ''; print ''; @@ -616,20 +682,23 @@ if ($action == 'create') // Third party print ''.$langs->trans("Customer").''.$object->thirdparty->getNomUrl(1,'customer').''; - print ''; - print $langs->trans("Comment"); - print ''; + print ''; // Title print ''.$langs->trans("Title").''; print ''; - print ''; - - // Note - print ''; - print ''; print ''; + // Note public + print ''.$langs->trans("NotePublic").''; + print ''; + print ''; + + // Note private + print ''.$langs->trans("NotePrivate").''; + print ''; + print ''; + // Author print "".$langs->trans("Author")."".$user->getFullName($langs).""; @@ -648,7 +717,7 @@ if ($action == 'create') { $projectid = $object->fk_project; $langs->load('projects'); - print '' . $langs->trans('Project') . ''; + print '' . $langs->trans('Project') . ''; $numprojet = $formproject->select_projects($socid, $projectid, 'projectid', 0); print '   id).'">' . $langs->trans("AddProject") . ''; print ''; @@ -707,10 +776,22 @@ if ($action == 'create') print load_fiche_titre($title, '', ''); - /* * Invoice lines */ + print ''; + // Show object lines + if (! empty($object->lines)) + { + $disableedit=1; + $disablemove=1; + $disableremove=1; + $ret = $object->printObjectLines('', $mysoc, $soc, $lineid, 0); // No date selector for template invoice + } + + print "
\n"; + + /* print ''; print '
'; @@ -877,7 +958,8 @@ if ($action == 'create') print $db->error(); } print "
"; - + */ + print ''; if ($flag_price_may_change) @@ -1007,7 +1089,15 @@ else } print ''; + // Note public + print ''; + print $form->editfieldkey($langs->trans("NotePublic"), 'note_public', $object->note_public, $object, $user->rights->facture->creer); + print ''; + print $form->editfieldval($langs->trans("NotePublic"), 'note_public', $object->note_public, $object, $user->rights->facture->creer, 'textarea:'.ROWS_4.':60'); + print ''; + print ''; + // Note private print ''; print $form->editfieldkey($langs->trans("NotePrivate"), 'note_private', $object->note_private, $object, $user->rights->facture->creer); print ''; @@ -1208,7 +1298,7 @@ else if (! empty($object->lines)) { $disableedit=1; - $disablemove=1; + //$disablemove=1; $ret = $object->printObjectLines($action, $mysoc, $soc, $lineid, 0); // No date selector for template invoice } @@ -1287,15 +1377,47 @@ else $sql.= " FROM ".MAIN_DB_PREFIX."societe as s,".MAIN_DB_PREFIX."facture_rec as f"; $sql.= " WHERE f.fk_soc = s.rowid"; $sql.= " AND f.entity = ".$conf->entity; - if ($socid) $sql .= " AND s.rowid = ".$socid; + if ($search_ref) $sql .= natural_search('f.titre', $search_ref); + if ($search_societe) $sql .= natural_search('s.nom', $search_societe); + if ($search_frequency) $sql .= natural_search('f.frequency', $search_frequency); + if ($search_montant_ht != '') $sql.= natural_search('f.total', $search_montant_ht, 1); + if ($search_montant_vat != '') $sql.= natural_search('f.tva', $search_montant_vat, 1); + if ($search_montant_ttc != '') $sql.= natural_search('f.total_ttc', $search_montant_ttc, 1); + if ($month > 0) + { + if ($year > 0 && empty($day)) + $sql.= " AND f.date_last_gen BETWEEN '".$db->idate(dol_get_first_day($year,$month,false))."' AND '".$db->idate(dol_get_last_day($year,$month,false))."'"; + else if ($year > 0 && ! empty($day)) + $sql.= " AND f.date_last_gen BETWEEN '".$db->idate(dol_mktime(0, 0, 0, $month, $day, $year))."' AND '".$db->idate(dol_mktime(23, 59, 59, $month, $day, $year))."'"; + else + $sql.= " AND date_format(f.date_last_gen, '%m') = '".$month."'"; + } + else if ($year > 0) + { + $sql.= " AND f.date_last_gen BETWEEN '".$db->idate(dol_get_first_day($year,1,false))."' AND '".$db->idate(dol_get_last_day($year,12,false))."'"; + } + if ($month_date_when > 0) + { + if ($year_date_when > 0 && empty($day_date_when)) + $sql.= " AND f.date_when BETWEEN '".$db->idate(dol_get_first_day($year_date_when,$month_date_when,false))."' AND '".$db->idate(dol_get_last_day($year_date_when,$month_date_when,false))."'"; + else if ($year_date_when > 0 && ! empty($day_date_when)) + $sql.= " AND f.date_date_when_reglement BETWEEN '".$db->idate(dol_mktime(0, 0, 0, $month_date_when, $day_date_when, $year_date_when))."' AND '".$db->idate(dol_mktime(23, 59, 59, $month_date_when, $day_date_when, $year_date_when))."'"; + else + $sql.= " AND date_format(f.date_when, '%m') = '".$month_date_when."'"; + } + else if ($year_date_when > 0) + { + $sql.= " AND f.date_when BETWEEN '".$db->idate(dol_get_first_day($year_date_when,1,false))."' AND '".$db->idate(dol_get_last_day($year_date_when,12,false))."'"; + } - $nbtotalofrecords = 0; + $nbtotalofrecords = 0; if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST)) { $result = $db->query($sql); $nbtotalofrecords = $db->num_rows($result); } - + + $sql.= $db->order($sortfield, $sortorder); $sql.= $db->plimit($limit+1,$offset); $resql = $db->query($sql); @@ -1305,6 +1427,29 @@ else $param='&socid='.$socid; if ($limit > 0 && $limit != $conf->liste_limit) $param.='&limit='.$limit; + if ($day) $param.='&day='.$day; + if ($month) $param.='&month='.$month; + if ($year) $param.='&year=' .$year; + if ($day_date_when) $param.='&day_date_when='.$day_date_when; + if ($month_date_when) $param.='&month_date_when='.$month_date_when; + if ($year_date_when) $param.='&year_date_when=' .$year_date_when; + if ($search_ref) $param.='&search_ref=' .$search_ref; + if ($search_societe) $param.='&search_societe=' .$search_societe; + if ($search_montant_ht != '') $param.='&search_montant_ht='.$search_montant_ht; + if ($search_montant_vat != '') $param.='&search_montant_vat='.$search_montant_vat; + if ($search_montant_ttc != '') $param.='&search_montant_ttc='.$search_montant_ttc; + if ($search_frequency) $param.='&search_frequency=' .$search_frequency; + if ($option) $param.="&option=".$option; + if ($optioncss != '') $param.='&optioncss='.$optioncss; + // Add $param from extra fields + foreach ($search_array_options as $key => $val) + { + $crit=$val; + $tmpkey=preg_replace('/search_options_/','',$key); + if ($val != '') $param.='&search_options_'.$tmpkey.'='.urlencode($val); + } + + $massactionbutton=$form->selectMassAction('', $massaction == 'presend' ? array() : array('presend'=>$langs->trans("SendByMail"), 'builddoc'=>$langs->trans("PDFMerge"))); print ''."\n"; if ($optioncss != '') print ''; @@ -1313,25 +1458,133 @@ else print ''; print ''; print ''; - - print_barre_liste($langs->trans("RepeatableInvoices"),$page,$_SERVER['PHP_SELF'],$param,$sortfield,$sortorder,'',$num,$nbtotalofrecord,'title_accountancy.png',0,'','',$limit); + + print_barre_liste($langs->trans("RepeatableInvoices"),$page,$_SERVER['PHP_SELF'],$param,$sortfield,$sortorder,'',$num,$nbtotalofrecords,'title_accountancy.png',0,'','',$limit); print $langs->trans("ToCreateAPredefinedInvoice", $langs->transnoentitiesnoconv("ChangeIntoRepeatableInvoice")).'

'; $i = 0; print ''; print ''; - print_liste_field_titre($langs->trans("Ref")); - print_liste_field_titre($langs->trans("Company"),$_SERVER['PHP_SELF'],"s.nom","","&socid=$socid","",$sortfiled,$sortorder); - print_liste_field_titre($langs->trans("AmountHT"),'','','','','align="right"'); - print_liste_field_titre($langs->trans("AmountVAT"),'','','','','align="right"'); - print_liste_field_titre($langs->trans("AmountTTC"),'','','','','align="right"'); - print_liste_field_titre($langs->trans("RecurringInvoiceTemplate"),'','','','','align="center"'); - print_liste_field_titre($langs->trans("DateLastGeneration"),'','','','','align="center"'); - print_liste_field_titre($langs->trans("NextDateToExecution"),'','','','','align="center"'); + print_liste_field_titre($langs->trans("Ref"),$_SERVER['PHP_SELF'],"f.titre","",$param,"",$sortfield,$sortorder); + print_liste_field_titre($langs->trans("ThirdParty"),$_SERVER['PHP_SELF'],"s.nom","",$param,"",$sortfield,$sortorder); + print_liste_field_titre($langs->trans("AmountHT"),$_SERVER['PHP_SELF'],"f.total","",$param,'align="right"',$sortfield,$sortorder); + print_liste_field_titre($langs->trans("AmountVAT"),$_SERVER['PHP_SELF'],"f.tva","",$param,'align="right"',$sortfield,$sortorder); + print_liste_field_titre($langs->trans("AmountTTC"),$_SERVER['PHP_SELF'],"f.total_ttc","",$param,'align="right"',$sortfield,$sortorder); + print_liste_field_titre($langs->trans("RecurringInvoiceTemplate"),$_SERVER['PHP_SELF'],"f.frequency","",$param,'align="center"',$sortfield,$sortorder); + print_liste_field_titre($langs->trans("DateLastGeneration"),$_SERVER['PHP_SELF'],"f.date_last_gen","",$param,'align="center"',$sortfield,$sortorder); + print_liste_field_titre($langs->trans("NextDateToExecution"),$_SERVER['PHP_SELF'],"f.date_when","",$param,'align="center"',$sortfield,$sortorder); print_liste_field_titre(''); // Field may contains ling text print "\n"; + + // Filters lines + print ''; + // Ref + if (! empty($arrayfields['f.titre']['checked'])) + { + print ''; + } + // Thirpdarty + if (! empty($arrayfields['s.nom']['checked'])) + { + print ''; + } + if (! empty($arrayfields['f.total']['checked'])) + { + // Amount + print ''; + } + if (! empty($arrayfields['f.tva']['checked'])) + { + // Amount + print ''; + } + if (! empty($arrayfields['f.total_ttc']['checked'])) + { + // Amount + print ''; + } + if (! empty($arrayfields['f.frequency']['checked'])) + { + // Amount + print ''; + } + // Date invoice + if (! empty($arrayfields['f.date_last_gen']['checked'])) + { + print ''; + } + // Date due + if (! empty($arrayfields['f.date_when']['checked'])) + { + print ''; + } + // Extra fields + if (is_array($extrafields->attribute_label) && count($extrafields->attribute_label)) + { + foreach($extrafields->attribute_label as $key => $val) + { + if (! empty($arrayfields["ef.".$key]['checked'])) + { + $align=$extrafields->getAlignFlag($key); + $typeofextrafield=$extrafields->attribute_type[$key]; + print ''; + } + } + } + // Fields from hook + $parameters=array('arrayfields'=>$arrayfields); + $reshook=$hookmanager->executeHooks('printFieldListOption',$parameters); // Note that $action and $object may have been modified by hook + print $hookmanager->resPrint; + // Date creation + if (! empty($arrayfields['f.datec']['checked'])) + { + print ''; + } + // Date modification + if (! empty($arrayfields['f.tms']['checked'])) + { + print ''; + } + // Action column + print ''; + print "\n"; + + if ($num > 0) { $var=true; diff --git a/htdocs/compta/facture/list.php b/htdocs/compta/facture/list.php index e2883081452..68eb4240226 100644 --- a/htdocs/compta/facture/list.php +++ b/htdocs/compta/facture/list.php @@ -153,6 +153,7 @@ $arrayfields=array( 'f.total_vat'=>array('label'=>$langs->trans("AmountVAT"), 'checked'=>0), 'f.total_ttc'=>array('label'=>$langs->trans("AmountTTC"), 'checked'=>0), 'am'=>array('label'=>$langs->trans("Received"), 'checked'=>0), + 'rtp'=>array('label'=>$langs->trans("Rest"), 'checked'=>0), 'f.datec'=>array('label'=>$langs->trans("DateCreation"), 'checked'=>0, 'position'=>500), 'f.tms'=>array('label'=>$langs->trans("DateModificationShort"), 'checked'=>0, 'position'=>500), 'f.fk_statut'=>array('label'=>$langs->trans("Status"), 'checked'=>1, 'position'=>1000), @@ -694,7 +695,7 @@ if ($search_country) $sql .= " AND s.fk_pays IN (".$search_country.')'; if ($search_type_thirdparty) $sql .= " AND s.fk_typent IN (".$search_type_thirdparty.')'; if ($search_company) $sql .= natural_search('s.nom', $search_company); if ($search_montant_ht != '') $sql.= natural_search('f.total', $search_montant_ht, 1); -if ($search_montant_vat != '') $sql.= natural_search('f.total', $search_montant_vat, 1); +if ($search_montant_vat != '') $sql.= natural_search('f.total_vat', $search_montant_vat, 1); if ($search_montant_ttc != '') $sql.= natural_search('f.total_ttc', $search_montant_ttc, 1); if ($search_status != '' && $search_status >= 0) $sql.= " AND f.fk_statut = ".$db->escape($search_status); if ($search_paymentmode > 0) $sql .= " AND f.fk_mode_reglement = ".$search_paymentmode.""; @@ -997,6 +998,7 @@ if ($resql) if (! empty($arrayfields['f.total_vat']['checked'])) print_liste_field_titre($arrayfields['f.total_vat']['label'],$_SERVER['PHP_SELF'],'f.tva','',$param,'align="right"',$sortfield,$sortorder); if (! empty($arrayfields['f.total_ttc']['checked'])) print_liste_field_titre($arrayfields['f.total_ttc']['label'],$_SERVER['PHP_SELF'],'f.total_ttc','',$param,'align="right"',$sortfield,$sortorder); if (! empty($arrayfields['am']['checked'])) print_liste_field_titre($arrayfields['am']['label'],$_SERVER['PHP_SELF'],'am','',$param,'align="right"',$sortfield,$sortorder); + if (! empty($arrayfields['rtp']['checked'])) print_liste_field_titre($arrayfields['rtp']['label'],$_SERVER['PHP_SELF'],'rtp','',$param,'align="right"',$sortfield,$sortorder); // Extra fields if (is_array($extrafields->attribute_label) && count($extrafields->attribute_label)) { @@ -1117,6 +1119,11 @@ if ($resql) print ''; } + if (! empty($arrayfields['rtp']['checked'])) + { + print ''; + } // Extra fields if (is_array($extrafields->attribute_label) && count($extrafields->attribute_label)) { @@ -1195,6 +1202,7 @@ if ($resql) $facturestatic->date_lim_reglement=$db->jdate($obj->datelimite); $notetoshow=dol_string_nohtmltag(($user->societe_id>0?$obj->note_public:$obj->note_private),1); $paiement = $facturestatic->getSommePaiement(); + $remaintopay = $obj->total_ttc - $paiement; print '
'; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + //print ''; + print ''; + if (! empty($conf->global->MAIN_LIST_FILTER_ON_DAY)) print ''; + print ''; + $formother->select_year($year?$year:-1,'year',1, 20, 5); + print ''; + if (! empty($conf->global->MAIN_LIST_FILTER_ON_DAY)) print ''; + print ''; + $formother->select_year($year_date_when?$year_date_when:-1,'year_date_when',1, 20, 5); + print ''; + if (in_array($typeofextrafield, array('varchar', 'int', 'double', 'select'))) + { + $crit=$val; + $tmpkey=preg_replace('/search_options_/','',$key); + $searchclass=''; + if (in_array($typeofextrafield, array('varchar', 'select'))) $searchclass='searchstring'; + if (in_array($typeofextrafield, array('int', 'double'))) $searchclass='searchnum'; + print ''; + } + print ''; + print ''; + print ''; + $searchpitco=$form->showFilterAndCheckAddButtons(0, 'checkforselect', 1); + print $searchpitco; + print '
'; print ''; + print '
'; @@ -1347,6 +1355,14 @@ if ($resql) if (! $i) $totalarray['totalamfield']=$totalarray['nbfield']; $totalarray['totalam'] += $paiement; } + + if (! empty($arrayfields['rtp']['checked'])) + { + print ''; + if (! $i) $totalarray['nbfield']++; + if (! $i) $totalarray['totalrtpfield']=$totalarray['nbfield']; + $totalarray['totalrtp'] += $remaintopay; + } // Extra fields if (is_array($extrafields->attribute_label) && count($extrafields->attribute_label)) @@ -1425,6 +1441,7 @@ if ($resql) elseif ($totalarray['totalvatfield'] == $i) print ''; elseif ($totalarray['totalttcfield'] == $i) print ''; elseif ($totalarray['totalamfield'] == $i) print ''; + elseif ($totalarray['totalrtpfield'] == $i) print ''; else print ''; } print ''; diff --git a/htdocs/compta/resultat/clientfourn.php b/htdocs/compta/resultat/clientfourn.php index 6a31fc02b4c..2d9241301a6 100644 --- a/htdocs/compta/resultat/clientfourn.php +++ b/htdocs/compta/resultat/clientfourn.php @@ -382,7 +382,7 @@ print ''; * Charges sociales non deductibles */ -print ''; +print ''; if ($modecompta == 'CREANCES-DETTES') { @@ -456,7 +456,7 @@ print ''; * Charges sociales deductibles */ -print ''; +print ''; if ($modecompta == 'CREANCES-DETTES') { diff --git a/htdocs/compta/stats/cabyprodserv.php b/htdocs/compta/stats/cabyprodserv.php index ca58ff334b5..8e4aabd9339 100644 --- a/htdocs/compta/stats/cabyprodserv.php +++ b/htdocs/compta/stats/cabyprodserv.php @@ -181,6 +181,8 @@ report_header($nom,$nomlink,$period,$periodlink,$description,$builddate,$exportl // SQL request $catotal=0; +$catotal_ht=0; +$qtytotal=0; if ($modecompta == 'CREANCES-DETTES') { @@ -401,6 +403,8 @@ if ($modecompta == 'CREANCES-DETTES') // Total print ''; print ''; + print ''; + print ''; print ''; print ''; print ''; diff --git a/htdocs/contact/class/contact.class.php b/htdocs/contact/class/contact.class.php index 88cd24af359..259918c5aa9 100644 --- a/htdocs/contact/class/contact.class.php +++ b/htdocs/contact/class/contact.class.php @@ -107,6 +107,47 @@ class Contact extends CommonObject $this->db = $db; $this->statut = 1; // By default, status is enabled } + + /** + * Load indicators into this->nb for board + * + * @return int <0 if KO, >0 if OK + */ + function load_state_board() + { + global $user; + + $this->nb=array(); + $clause = "WHERE"; + + $sql = "SELECT count(sp.rowid) as nb"; + $sql.= " FROM ".MAIN_DB_PREFIX."socpeople as sp"; + $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."societe as s ON (sp.fk_soc = s.rowid)"; + if (!$user->rights->societe->client->voir && !$user->societe_id) + { + $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."societe_commerciaux as sc ON s.rowid = sc.fk_soc"; + $sql.= " WHERE sc.fk_user = " .$user->id; + $clause = "AND"; + } + $sql.= ' '.$clause.' s.entity IN ('.getEntity($this->element, 1).')'; + + $resql=$this->db->query($sql); + if ($resql) + { + while ($obj=$this->db->fetch_object($resql)) + { + $this->nb["contacts"]=$obj->nb; + } + $this->db->free($resql); + return 1; + } + else + { + dol_print_error($this->db); + $this->error=$this->db->lasterror(); + return -1; + } + } /** * Add a contact into database diff --git a/htdocs/core/class/commonobject.class.php b/htdocs/core/class/commonobject.class.php index ec02fce3dae..049ccbd1bc9 100644 --- a/htdocs/core/class/commonobject.class.php +++ b/htdocs/core/class/commonobject.class.php @@ -3236,8 +3236,9 @@ abstract class CommonObject */ function printObjectLines($action, $seller, $buyer, $selected=0, $dateSelector=0) { - global $conf, $hookmanager, $inputalsopricewithtax, $usemargins, $disableedit, $disablemove, $langs, $user; - + global $conf, $hookmanager, $langs, $user; + global $inputalsopricewithtax, $usemargins, $disableedit, $disablemove, $disableremove; // TODO We should not use global var for this ! + // Define usemargins $usemargins=0; if (! empty($conf->margin->enabled) && ! empty($this->element) && in_array($this->element,array('facture','propal','commande'))) $usemargins=1; @@ -3366,7 +3367,7 @@ abstract class CommonObject { global $conf,$langs,$user,$object,$hookmanager; global $form,$bc,$bcdd; - global $object_rights, $disableedit, $disablemove; // TODO We should not use global var for this ! + global $object_rights, $disableedit, $disablemove, $disableremove; // TODO We should not use global var for this ! $object_rights = $this->getRights(); @@ -4559,7 +4560,7 @@ abstract class CommonObject $productFournisseur = new ProductFournisseur($this->db); if (($result = $productFournisseur->find_min_price_product_fournisseur($fk_product)) > 0) { - $buyPrice = $productFournisseur->fourn_price; + $buyPrice = $productFournisseur->fourn_unitprice; } else if ($result < 0) { diff --git a/htdocs/core/class/doleditor.class.php b/htdocs/core/class/doleditor.class.php index 8564a18822e..ff31823976e 100644 --- a/htdocs/core/class/doleditor.class.php +++ b/htdocs/core/class/doleditor.class.php @@ -52,7 +52,7 @@ class DolEditor * @param string $content Content of WYSIWIG field * @param int $width Width in pixel of edit area (auto by default) * @param int $height Height in pixel of edit area (200px by default) - * @param string $toolbarname Name of bar set to use ('Full', 'dolibarr_notes[_encoded]', 'dolibarr_details[_encoded]'=the less featured, 'dolibarr_mailings[_encoded]', ') + * @param string $toolbarname Name of bar set to use ('Full', 'dolibarr_notes[_encoded]', 'dolibarr_details[_encoded]'=the less featured, 'dolibarr_mailings[_encoded]', 'dolibarr_readonly') * @param string $toolbarlocation Where bar is stored : * 'In' each window has its own toolbar * 'Out:name' share toolbar into the div called 'name' @@ -148,7 +148,10 @@ class DolEditor { global $conf,$langs; - $found=0; + $fullpage=False; + $disallowAnyContent=empty($conf->global->FCKEDITOR_ALLOW_ANY_CONTENT); // Only predefined list of html tags are allowed + + $found=0; $out=''; if ($this->tool == 'fckeditor') @@ -186,7 +189,8 @@ class DolEditor customConfig : ckeditorConfig, readOnly : '.($this->readonly?'true':'false').', htmlEncodeOutput :'.$htmlencode_force.', - allowedContent :'.(empty($conf->global->FCKEDITOR_ALLOW_ANY_CONTENT)?'false':'true').', + allowedContent :'.($disallowAnyContent?'false':'true').', + fullPage : '.($fullpage?'true':'false').', toolbar: \''.$this->toolbarname.'\', toolbarStartupExpanded: '.($this->toolbarstartexpanded ? 'true' : 'false').', width: '.($this->width ? '\''.$this->width.'\'' : '\'\'').', diff --git a/htdocs/core/class/html.form.class.php b/htdocs/core/class/html.form.class.php index 697e5e8bdeb..c65fcb1bdc5 100644 --- a/htdocs/core/class/html.form.class.php +++ b/htdocs/core/class/html.form.class.php @@ -390,6 +390,7 @@ class Form * @param int $noencodehtmltext Do not encode into html entity the htmltext * @return string Code html du tooltip (texte+picto) * @see Use function textwithpicto if you can. + * TODO Move this as static as soon as everybody use textwithpicto or @Form::textwithtooltip */ function textwithtooltip($text, $htmltext, $tooltipon = 1, $direction = 0, $img = '', $extracss = '', $notabs = 2, $incbefore = '', $noencodehtmltext = 0) { @@ -2057,17 +2058,27 @@ class Form { global $langs,$conf; global $price_level, $status, $finished; - + + $selected_input_value=''; if (! empty($conf->use_javascript_ajax) && ! empty($conf->global->PRODUIT_USE_SEARCH_TO_SELECT)) { + if ($selected > 0) + { + require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php'; + $producttmpselect = new Product($this->db); + $producttmpselect->fetch($selected); + $selected_input_value=$producttmpselect->ref; + unset($producttmpselect); + } + if (!empty($conf->global->SUPPLIER_ORDER_WITH_NOPRICEDEFINED)) { print ''; } // mode=2 means suppliers products $urloption=($socid > 0?'socid='.$socid.'&':'').'htmlname='.$htmlname.'&outjson=1&price_level='.$price_level.'&type='.$filtertype.'&mode=2&status='.$status.'&finished='.$finished; - print ajax_autocompleter('', $htmlname, DOL_URL_ROOT.'/product/ajax/products.php', $urloption, $conf->global->PRODUIT_USE_SEARCH_TO_SELECT, 0, $ajaxoptions); - print ($hidelabel?'':$langs->trans("RefOrLabel").' : ').''; + print ajax_autocompleter($selected, $htmlname, DOL_URL_ROOT.'/product/ajax/products.php', $urloption, $conf->global->PRODUIT_USE_SEARCH_TO_SELECT, 0, $ajaxoptions); + print ($hidelabel?'':$langs->trans("RefOrLabel").' : ').''; } else { @@ -2089,7 +2100,7 @@ class Form * @param string $filtertype Filter on product type (''=nofilter, 0=product, 1=service) * @param string $filtre Pour filtre sql * @param string $filterkey Filtre des produits - * @param int $statut -1=Return all products, 0=Products not on sell, 1=Products on sell + * @param int $statut -1=Return all products, 0=Products not on sell, 1=Products on sell (not used here, a filter on tobuy is already hard coded in request) * @param int $outputmode 0=HTML select string, 1=Array * @param int $limit Limit of line number * @return array Array of keys for json @@ -2106,7 +2117,7 @@ class Form $sql = "SELECT p.rowid, p.label, p.ref, p.price, p.duration, p.fk_product_type,"; $sql.= " pfp.ref_fourn, pfp.rowid as idprodfournprice, pfp.price as fprice, pfp.quantity, pfp.remise_percent, pfp.remise, pfp.unitprice,"; $sql.= " pfp.fk_supplier_price_expression, pfp.fk_product, pfp.tva_tx, pfp.fk_soc, s.nom as name,"; - $sql.= " pfp.supplier_reputation"; + $sql.= " pfp.supplier_reputation"; $sql.= " FROM ".MAIN_DB_PREFIX."product as p"; $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."product_fournisseur_price as pfp ON p.rowid = pfp.fk_product"; if ($socid) $sql.= " AND pfp.fk_soc = ".$socid; @@ -2390,10 +2401,10 @@ class Form $form.= $opt; $i++; } - $form.= ''; - - $this->db->free($result); } + + $form.= ''; + $this->db->free($result); return $form; } else diff --git a/htdocs/core/class/html.formother.class.php b/htdocs/core/class/html.formother.class.php index 5af984ba659..f446caa12a2 100644 --- a/htdocs/core/class/html.formother.class.php +++ b/htdocs/core/class/html.formother.class.php @@ -805,6 +805,7 @@ class FormOther $select_week .= ''; } $select_week .= ''; return $select_week; @@ -844,6 +845,7 @@ class FormOther $select_month .= ''; } $select_month .= ''; return $select_month; diff --git a/htdocs/core/class/translate.class.php b/htdocs/core/class/translate.class.php index 866b746362b..34858bc3234 100644 --- a/htdocs/core/class/translate.class.php +++ b/htdocs/core/class/translate.class.php @@ -908,7 +908,8 @@ class Translate } /** - * Return a currency code into its symbol + * Return a currency code into its symbol. + * If mb_convert_encoding is not available, return currency code. * * @param string $currency_code Currency code * @param integer $forceloadall 1=Force to load all currencies into cache. We know we need to use all of them. By default read and cache only required currency. diff --git a/htdocs/core/filemanagerdol/browser/default/browser.php b/htdocs/core/filemanagerdol/browser/default/browser.php index f542bdf59b6..15e44621bcf 100644 --- a/htdocs/core/filemanagerdol/browser/default/browser.php +++ b/htdocs/core/filemanagerdol/browser/default/browser.php @@ -19,15 +19,20 @@ * along with this program. If not, see . */ -define('NOTOKENRENEWAL',1); // Disables token renewal +//define('NOTOKENRENEWAL',1); // Disables token renewal +//require '../../../../main.inc.php'; +require '../../connectors/php/config.php'; // This include the define('NOTOKENRENEWAL',1) and the require main.in.php + +global $Config; + + -require '../../../../main.inc.php'; ?> - FCKeditor - Resources Browser + <?php echo $langs->trans("MediaBrowser").' - '.$Config['UserFilesAbsolutePathRelative']; ?> diff --git a/htdocs/core/tpl/objectline_view.tpl.php b/htdocs/core/tpl/objectline_view.tpl.php index 967d9f81970..559cae91464 100644 --- a/htdocs/core/tpl/objectline_view.tpl.php +++ b/htdocs/core/tpl/objectline_view.tpl.php @@ -31,7 +31,7 @@ * $inputalsopricewithtax (0 by default, 1 to also show column with unit price including tax) * $usemargins (0 to disable all margins columns, 1 to show according to margin setup) * $object_rights->creer initialized from = $object->getRights() - * $disableedit, $disablemove + * $disableedit, $disablemove, $disableremove * * $type, $text, $description, $line */ @@ -46,7 +46,6 @@ if (empty($forceall)) $forceall=0; if (empty($senderissupplier)) $senderissupplier=0; if (empty($inputalsopricewithtax)) $inputalsopricewithtax=0; if (empty($usemargins)) $usemargins=0; - ?> @@ -216,7 +215,7 @@ if (empty($usemargins)) $usemargins=0; '; } - print ''; + print ''; print ''; print ''; print ''; diff --git a/htdocs/expensereport/class/expensereport.class.php b/htdocs/expensereport/class/expensereport.class.php index 2a281bda595..07c3e598818 100644 --- a/htdocs/expensereport/class/expensereport.class.php +++ b/htdocs/expensereport/class/expensereport.class.php @@ -746,7 +746,7 @@ class ExpenseReport extends CommonObject $sql.= ' ctf.code as code_type_fees, ctf.label as libelle_type_fees,'; $sql.= ' p.ref as ref_projet, p.title as title_projet'; $sql.= ' FROM '.MAIN_DB_PREFIX.$this->table_element_line.' as de'; - $sql.= ' INNER JOIN '.MAIN_DB_PREFIX.'c_type_fees as ctf ON de.fk_c_type_fees = ctf.id'; + $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_type_fees as ctf ON de.fk_c_type_fees = ctf.id'; $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'projet as p ON de.fk_projet = p.rowid'; $sql.= ' WHERE de.'.$this->fk_element.' = '.$this->id; @@ -776,7 +776,7 @@ class ExpenseReport extends CommonObject $deplig->total_tva = $objp->total_tva; $deplig->total_ttc = $objp->total_ttc; - $deplig->type_fees_code = $objp->code_type_fees; + $deplig->type_fees_code = empty($objp->code_type_fees)?'TF_OTHER':$objp->code_type_fees; $deplig->type_fees_libelle = $objp->libelle_type_fees; $deplig->tva_tx = $objp->tva_tx; $deplig->vatrate = $objp->tva_tx; @@ -850,12 +850,9 @@ class ExpenseReport extends CommonObject { global $conf,$langs; + $this->oldref = $this->ref; $expld_car = (empty($conf->global->NDF_EXPLODE_CHAR))?"-":$conf->global->NDF_EXPLODE_CHAR; - // Sélection du numéro de ref suivant - $ref_next = $this->getNextNumRef(); - $ref_number_int = ($this->ref+1)-1; - // Sélection de la date de début de la NDF $sql = 'SELECT date_debut'; $sql.= ' FROM '.MAIN_DB_PREFIX.$this->table_element; @@ -864,21 +861,59 @@ class ExpenseReport extends CommonObject $objp = $this->db->fetch_object($result); $this->date_debut = $this->db->jdate($objp->date_debut); - // Création du ref_number suivant - if($ref_next) + $update_number_int = false; + + // Create next ref if ref is PROVxx + // Rename directory if dir was a temporary ref + if (preg_match('/^[\(]?PROV/i', $this->ref)) { - $prefix="ER"; - if (! empty($conf->global->EXPENSE_REPORT_PREFIX)) $prefix=$conf->global->EXPENSE_REPORT_PREFIX; - $this->ref = strtoupper($fuser->login).$expld_car.$prefix.$this->ref.$expld_car.dol_print_date($this->date_debut,'%y%m%d'); + // Sélection du numéro de ref suivant + $ref_next = $this->getNextNumRef(); + $ref_number_int = ($this->ref+1)-1; + $update_number_int = true; + // Création du ref_number suivant + if($ref_next) + { + $prefix="ER"; + if (! empty($conf->global->EXPENSE_REPORT_PREFIX)) $prefix=$conf->global->EXPENSE_REPORT_PREFIX; + $this->ref = strtoupper($fuser->login).$expld_car.$prefix.$this->ref.$expld_car.dol_print_date($this->date_debut,'%y%m%d'); + } + require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; + // We rename directory in order to avoid losing the attachments + $oldref = dol_sanitizeFileName($this->oldref); + $newref = dol_sanitizeFileName($this->ref); + $dirsource = $conf->expensereport->dir_output.'/'.$oldref; + $dirdest = $conf->expensereport->dir_output.'/'.$newref; + if (file_exists($dirsource)) + { + dol_syslog(get_class($this)."::valid() rename dir ".$dirsource." into ".$dirdest); + + if (@rename($dirsource, $dirdest)) + { + dol_syslog("Rename ok"); + // Rename docs starting with $oldref with $newref + $listoffiles=dol_dir_list($conf->expensereport->dir_output.'/'.$newref, 'files', 1, '^'.preg_quote($oldref,'/')); + foreach($listoffiles as $fileentry) + { + $dirsource=$fileentry['name']; + $dirdest=preg_replace('/^'.preg_quote($oldref,'/').'/',$newref, $dirsource); + $dirsource=$fileentry['path'].'/'.$dirsource; + $dirdest=$fileentry['path'].'/'.$dirdest; + @rename($dirsource, $dirdest); + } + } + } } if ($this->fk_statut != 2) { $now = dol_now(); - + $sql = 'UPDATE '.MAIN_DB_PREFIX.$this->table_element; - $sql.= " SET ref = '".$this->ref."', fk_statut = 2, fk_user_valid = ".$fuser->id.", date_valid='".$this->db->idate($now)."',"; - $sql.= " ref_number_int = ".$ref_number_int; + $sql.= " SET ref = '".$this->ref."', fk_statut = 2, fk_user_valid = ".$fuser->id.", date_valid='".$this->db->idate($now)."'"; + if ($update_number_int) { + $sql.= ", ref_number_int = ".$ref_number_int; + } $sql.= ' WHERE rowid = '.$this->id; $resql=$this->db->query($sql); @@ -1265,7 +1300,9 @@ class ExpenseReport extends CommonObject $sql.= " FROM ".MAIN_DB_PREFIX."projet as p"; $sql.= " WHERE p.rowid = ".$projet_id; $result = $this->db->query($sql); - $objp_projet = $this->db->fetch_object($result); + if ($result) { + $objp_projet = $this->db->fetch_object($result); + } $ligne->projet_ref = $objp_projet->ref_projet; $ligne->projet_title = $objp_projet->title_projet; diff --git a/htdocs/exports/class/export.class.php b/htdocs/exports/class/export.class.php index 7912b4f189f..6632f050550 100644 --- a/htdocs/exports/class/export.class.php +++ b/htdocs/exports/class/export.class.php @@ -225,7 +225,7 @@ class Export else $i++; if (strpos($key, ' as ')===false) { - $newfield=$key.' as '.str_replace(array('.', '-'),'_',$key); + $newfield=$key.' as '.str_replace(array('.', '-','(',')'),'_',$key); } else { $newfield=$key; } @@ -587,14 +587,14 @@ class Export if ($this->array_export_special[$indice][$key]=='NULLIFNEG') { //$alias=$this->array_export_alias[$indice][$key]; - $alias=str_replace(array('.', '-'),'_',$key); + $alias=str_replace(array('.', '-','(',')'),'_',$key); if ($objp->$alias < 0) $objp->$alias=''; } // Operation ZEROIFNEG if ($this->array_export_special[$indice][$key]=='ZEROIFNEG') { //$alias=$this->array_export_alias[$indice][$key]; - $alias=str_replace(array('.', '-'),'_',$key); + $alias=str_replace(array('.', '-','(',')'),'_',$key); if ($objp->$alias < 0) $objp->$alias='0'; } } diff --git a/htdocs/exports/export.php b/htdocs/exports/export.php index d78a2564e7c..50ca1e09a91 100644 --- a/htdocs/exports/export.php +++ b/htdocs/exports/export.php @@ -35,6 +35,7 @@ require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; $langs->load("exports"); $langs->load("users"); $langs->load("companies"); +$langs->load("projects"); // Everybody should be able to go on this page //if (! $user->admin) diff --git a/htdocs/fichinter/class/fichinter.class.php b/htdocs/fichinter/class/fichinter.class.php index 69f01613f50..66fb1031d6e 100644 --- a/htdocs/fichinter/class/fichinter.class.php +++ b/htdocs/fichinter/class/fichinter.class.php @@ -89,6 +89,46 @@ class Fichinter extends CommonObject $this->statuts_logo[3]='statut4'; } + /** + * Load indicators into this->nb for board + * + * @return int <0 if KO, >0 if OK + */ + function load_state_board() + { + global $user; + + $this->nb=array(); + $clause = "WHERE"; + + $sql = "SELECT count(fi.rowid) as nb"; + $sql.= " FROM ".MAIN_DB_PREFIX."fichinter as fi"; + $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."societe as s ON fi.fk_soc = s.rowid"; + if (!$user->rights->societe->client->voir && !$user->societe_id) + { + $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."societe_commerciaux as sc ON s.rowid = sc.fk_soc"; + $sql.= " WHERE sc.fk_user = " .$user->id; + $clause = "AND"; + } + $sql.= " ".$clause." fi.entity IN (".getEntity($this->element, 1).")"; + + $resql=$this->db->query($sql); + if ($resql) + { + while ($obj=$this->db->fetch_object($resql)) + { + $this->nb["fichinters"]=$obj->nb; + } + $this->db->free($resql); + return 1; + } + else + { + dol_print_error($this->db); + $this->error=$this->db->error(); + return -1; + } + } /** * Create an intervention into data base diff --git a/htdocs/fourn/class/fournisseur.facture.class.php b/htdocs/fourn/class/fournisseur.facture.class.php index e209dd741d6..30296bc2e22 100644 --- a/htdocs/fourn/class/fournisseur.facture.class.php +++ b/htdocs/fourn/class/fournisseur.facture.class.php @@ -7,7 +7,7 @@ * Copyright (C) 2010-2015 Juanjo Menent * Copyright (C) 2013 Philippe Grand * Copyright (C) 2013 Florian Henry - * Copyright (C) 2014-2015 Marcos García + * Copyright (C) 2014-2016 Marcos García * Copyright (C) 2015 Bahfir Abbes * Copyright (C) 2015 Ferran Marcet * @@ -694,7 +694,16 @@ class FactureFournisseur extends CommonInvoice dol_syslog(get_class($this)."::update", LOG_DEBUG); $resql = $this->db->query($sql); - if (! $resql) { $error++; $this->errors[]="Error ".$this->db->lasterror(); } + + if (!$resql) { + $error++; + + if ($this->db->errno() == 'DB_ERROR_RECORD_ALREADY_EXISTS') { + $this->errors[] = $langs->trans('ErrorRefAlreadyExists'); + } else { + $this->errors[] = "Error ".$this->db->lasterror(); + } + } if (! $error) { diff --git a/htdocs/fourn/facture/card.php b/htdocs/fourn/facture/card.php index c1346c357d5..eb6392eba06 100644 --- a/htdocs/fourn/facture/card.php +++ b/htdocs/fourn/facture/card.php @@ -247,8 +247,11 @@ if (empty($reshook)) // Set supplier ref if ($action == 'setref_supplier' && $user->rights->fournisseur->commande->creer) { - $result=$object->setValueFrom('ref_supplier',GETPOST('ref_supplier','alpha')); - if ($result < 0) dol_print_error($db, $object->error); + $object->ref_supplier = GETPOST('ref_supplier', 'alpha'); + + if ($object->update($user) < 0) { + setEventMessages($object->error, $object->errors, 'errors'); + } } // payments conditions diff --git a/htdocs/fourn/facture/list.php b/htdocs/fourn/facture/list.php index dafe95e419d..42810962275 100644 --- a/htdocs/fourn/facture/list.php +++ b/htdocs/fourn/facture/list.php @@ -225,10 +225,19 @@ if ($search_amount_all_tax != '') $sql .= natural_search('fac.total_ttc', $search_amount_all_tax, 1); } -if ($search_status != '') +if ($search_status != '' && $search_status>=0) { $sql.= " AND fac.fk_statut = ".$search_status; } +if ($filter && $filter != -1) +{ + $aFilter = explode(',', $filter); + foreach ($aFilter as $fil) + { + $filt = explode(':', $fil); + $sql .= ' AND ' . trim($filt[0]) . ' = ' . trim($filt[1]); + } +} $nbtotalofrecords = 0; if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST)) @@ -265,7 +274,7 @@ if ($resql) if ($search_amount_no_tax) $param.='&search_amount_no_tax='.urlencode($search_amount_no_tax); if ($search_amount_all_tax) $param.='&search_amount_all_tax='.urlencode($search_amount_all_tax); if ($filter && $filter != -1) $param.='&filtre='.urlencode($filter); - if ($optioncss != '') $param.='&optioncss='.$optioncss; + if ($optioncss != '') $param.='&optioncss='.$optioncss; if ($search_status >= 0) $param.="&search_status=".$search_status; print ''; diff --git a/htdocs/hrm/establishment/card.php b/htdocs/hrm/establishment/card.php index fb6f41f4f39..11179d218f8 100644 --- a/htdocs/hrm/establishment/card.php +++ b/htdocs/hrm/establishment/card.php @@ -136,7 +136,7 @@ else if ($action == 'update') $object->country_id = $_POST["country_id"]; $object->fk_user_mod = $user->id; - $result = $object->update(); + $result = $object->update($user); if ($result > 0) { diff --git a/htdocs/index.php b/htdocs/index.php index 332e2ea4483..5e9492d9b50 100644 --- a/htdocs/index.php +++ b/htdocs/index.php @@ -162,6 +162,7 @@ if (empty($user->societe_id)) ! empty($conf->societe->enabled) && $user->rights->societe->lire && empty($conf->global->SOCIETE_DISABLE_CUSTOMERS) && empty($conf->global->SOCIETE_DISABLE_CUSTOMERS_STATS), ! empty($conf->societe->enabled) && $user->rights->societe->lire && empty($conf->global->SOCIETE_DISABLE_PROSPECTS) && empty($conf->global->SOCIETE_DISABLE_PROSPECTS_STATS), ! empty($conf->fournisseur->enabled) && $user->rights->fournisseur->lire && empty($conf->global->SOCIETE_DISABLE_SUPPLIERS_STATS), + ! empty($conf->societe->enabled) && $user->rights->societe->contact->lire, ! empty($conf->adherent->enabled) && $user->rights->adherent->lire, ! empty($conf->product->enabled) && $user->rights->produit->lire, ! empty($conf->service->enabled) && $user->rights->service->lire, @@ -169,6 +170,7 @@ if (empty($user->societe_id)) ! empty($conf->commande->enabled) && $user->rights->commande->lire, ! empty($conf->facture->enabled) && $user->rights->facture->lire, ! empty($conf->contrat->enabled) && $user->rights->contrat->activer, + ! empty($conf->ficheinter->enabled) && $user->rights->ficheinter->lire, ! empty($conf->supplier_order->enabled) && $user->rights->fournisseur->commande->lire && empty($conf->global->SOCIETE_DISABLE_SUPPLIERS_ORDERS_STATS), ! empty($conf->supplier_invoice->enabled) && $user->rights->fournisseur->facture->lire && empty($conf->global->SOCIETE_DISABLE_SUPPLIERS_INVOICES_STATS), ! empty($conf->supplier_proposal->enabled) && $user->rights->supplier_proposal->lire && empty($conf->global->SOCIETE_DISABLE_SUPPLIERS_PROPOSAL_STATS), @@ -181,6 +183,7 @@ if (empty($user->societe_id)) DOL_DOCUMENT_ROOT."/societe/class/client.class.php", DOL_DOCUMENT_ROOT."/societe/class/client.class.php", DOL_DOCUMENT_ROOT."/fourn/class/fournisseur.class.php", + DOL_DOCUMENT_ROOT."/contact/class/contact.class.php", DOL_DOCUMENT_ROOT."/adherents/class/adherent.class.php", DOL_DOCUMENT_ROOT."/product/class/product.class.php", DOL_DOCUMENT_ROOT."/product/class/service.class.php", @@ -188,6 +191,7 @@ if (empty($user->societe_id)) DOL_DOCUMENT_ROOT."/commande/class/commande.class.php", DOL_DOCUMENT_ROOT."/compta/facture/class/facture.class.php", DOL_DOCUMENT_ROOT."/contrat/class/contrat.class.php", + DOL_DOCUMENT_ROOT."/fichinter/class/fichinter.class.php", DOL_DOCUMENT_ROOT."/fourn/class/fournisseur.commande.class.php", DOL_DOCUMENT_ROOT."/fourn/class/fournisseur.facture.class.php", DOL_DOCUMENT_ROOT."/supplier_proposal/class/supplier_proposal.class.php", @@ -199,6 +203,7 @@ if (empty($user->societe_id)) 'Client', 'Client', 'Fournisseur', + 'Contact', 'Adherent', 'Product', 'Service', @@ -206,6 +211,7 @@ if (empty($user->societe_id)) 'Commande', 'Facture', 'Contrat', + 'Fichinter', 'CommandeFournisseur', 'FactureFournisseur', 'SupplierProposal', @@ -217,6 +223,7 @@ if (empty($user->societe_id)) 'customers', 'prospects', 'suppliers', + 'contacts', 'members', 'products', 'services', @@ -224,6 +231,7 @@ if (empty($user->societe_id)) 'orders', 'invoices', 'Contracts', + 'fichinters', 'supplier_orders', 'supplier_invoices', 'askprice', @@ -235,6 +243,7 @@ if (empty($user->societe_id)) 'company', 'company', 'company', + 'contact', 'user', 'product', 'service', @@ -243,6 +252,7 @@ if (empty($user->societe_id)) 'bill', 'order', 'order', + 'order', 'bill', 'propal', 'trip', @@ -253,6 +263,7 @@ if (empty($user->societe_id)) "ThirdPartyCustomersStats", "ThirdPartyProspectsStats", "Suppliers", + "Contacts", "Members", "Products", "Services", @@ -260,6 +271,7 @@ if (empty($user->societe_id)) "CustomersOrders", "BillsCustomers", "Contracts", + "Interventions", "SuppliersOrders", "SuppliersInvoices", "SupplierProposalShort", @@ -272,6 +284,7 @@ if (empty($user->societe_id)) DOL_URL_ROOT.'/societe/list.php?type=c', DOL_URL_ROOT.'/societe/list.php?type=p', DOL_URL_ROOT.'/societe/list.php?type=f', + DOL_URL_ROOT.'/contact/list.php', DOL_URL_ROOT.'/adherents/list.php?statut=1&mainmenu=members', DOL_URL_ROOT.'/product/list.php?type=0&mainmenu=products', DOL_URL_ROOT.'/product/list.php?type=1&mainmenu=products', @@ -279,6 +292,7 @@ if (empty($user->societe_id)) DOL_URL_ROOT.'/commande/list.php?mainmenu=commercial', DOL_URL_ROOT.'/compta/facture/list.php?mainmenu=accountancy', DOL_URL_ROOT.'/contrat/list.php', + DOL_URL_ROOT.'/fichinter/list.php', DOL_URL_ROOT.'/fourn/commande/list.php', DOL_URL_ROOT.'/fourn/facture/list.php', DOL_URL_ROOT.'/supplier_proposal/list.php', @@ -290,6 +304,7 @@ if (empty($user->societe_id)) "companies", "prospects", "suppliers", + "companies", "members", "products", "produts", @@ -298,6 +313,7 @@ if (empty($user->societe_id)) "bills", "supplier_proposal", "contracts", + "interventions", "trips", "projects" ); diff --git a/htdocs/install/mysql/data/llx_accounting_category.sql b/htdocs/install/mysql/data/llx_accounting_category.sql new file mode 100644 index 00000000000..5769d291563 --- /dev/null +++ b/htdocs/install/mysql/data/llx_accounting_category.sql @@ -0,0 +1,29 @@ +-- Copyright (C) 2016 Alexandre Spangaro +-- +-- This program is free software; you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- 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 . +-- +-- + +-- +-- Ne pas placer de commentaire en fin de ligne, ce fichier est parsé lors +-- de l'install et tous les sigles '--' sont supprimés. +-- + +-- +-- Categories compte de résultat Français +-- + +INSERT INTO llx_c_accounting_category (rowid, code, label, range_account, sens, category_type, formula, position, fk_country, active) VALUES ( 1,'VTE','Ventes de marchandises', '707xxx', 0, 0, '', '10', 1, 1); +INSERT INTO llx_c_accounting_category (rowid, code, label, range_account, sens, category_type, formula, position, fk_country, active) VALUES ( 2,'MAR','Coût d\'achats marchandises vendues', '603xxx | 607xxx | 609xxx', 0, 0, '', '20', 1, 1); +INSERT INTO llx_c_accounting_category (rowid, code, label, range_account, sens, category_type, formula, position, fk_country, active) VALUES ( 3,'MARGE','Marge commerciale', '', 0, 1, '1 + 2', '30', 1, 1); \ No newline at end of file diff --git a/htdocs/install/mysql/migration/3.9.0-4.0.0.sql b/htdocs/install/mysql/migration/3.9.0-4.0.0.sql index 002930c276c..a429ef5c7cf 100644 --- a/htdocs/install/mysql/migration/3.9.0-4.0.0.sql +++ b/htdocs/install/mysql/migration/3.9.0-4.0.0.sql @@ -36,6 +36,8 @@ ALTER TABLE llx_product_customer_price_log ADD COLUMN localtax1_type varchar(10) ALTER TABLE llx_product_customer_price_log ADD COLUMN localtax2_type varchar(10) NOT NULL DEFAULT '0' after localtax2_tx; +ALTER TABLE llx_expedition ADD COLUMN billed smallint DEFAULT 0; + CREATE TABLE llx_product_lot ( rowid integer AUTO_INCREMENT PRIMARY KEY, tms timestamp, @@ -64,6 +66,8 @@ ALTER TABLE llx_product ADD COLUMN height_units tinyint DEFAULT NULL; ALTER TABLE llx_product ADD COLUMN default_vat_code varchar(10) after cost_price; +ALTER TABLE llx_product MODIFY COLUMN stock real; + CREATE TABLE llx_categorie_user ( fk_categorie integer NOT NULL, @@ -301,19 +305,15 @@ ALTER TABLE llx_contratdet ADD COLUMN multicurrency_total_ht double(24,8) DEFAUL ALTER TABLE llx_contratdet ADD COLUMN multicurrency_total_tva double(24,8) DEFAULT 0; ALTER TABLE llx_contratdet ADD COLUMN multicurrency_total_ttc double(24,8) DEFAULT 0; - - ALTER TABLE llx_paiement ADD COLUMN multicurrency_amount double(24,8) DEFAULT 0; ALTER TABLE llx_paiement_facture ADD COLUMN multicurrency_amount double(24,8) DEFAULT 0; ALTER TABLE llx_paiementfourn ADD COLUMN multicurrency_amount double(24,8) DEFAULT 0; ALTER TABLE llx_paiementfourn_facturefourn ADD COLUMN multicurrency_amount double(24,8) DEFAULT 0; -ALTER TABLE llx_societe_remise_except ADD COLUMN multicurrency_amount_ht double(24,8) NOT NULL; +ALTER TABLE llx_societe_remise_except ADD COLUMN multicurrency_amount_ht double(24,8) DEFAULT 0 NOT NULL; ALTER TABLE llx_societe_remise_except ADD COLUMN multicurrency_amount_tva double(24,8) DEFAULT 0 NOT NULL; ALTER TABLE llx_societe_remise_except ADD COLUMN multicurrency_amount_ttc double(24,8) DEFAULT 0 NOT NULL; - - ALTER TABLE llx_supplier_proposal ADD COLUMN fk_multicurrency integer; ALTER TABLE llx_supplier_proposal ADD COLUMN multicurrency_code varchar(255); ALTER TABLE llx_supplier_proposal ADD COLUMN multicurrency_tx double(24,8) DEFAULT 1; @@ -364,11 +364,18 @@ CREATE TABLE llx_c_accounting_category ( ) ENGINE=innodb; ALTER TABLE llx_c_accounting_category ADD UNIQUE INDEX uk_c_accounting_category(code); + +INSERT INTO llx_c_accounting_category (rowid, code, label, range_account, sens, category_type, formula, position, fk_country, active) VALUES ( 1,'VTE',"Ventes de marchandises", '707xxx', 0, 0, '', '10', 1, 1); +INSERT INTO llx_c_accounting_category (rowid, code, label, range_account, sens, category_type, formula, position, fk_country, active) VALUES ( 2,'MAR',"Coût d'achats marchandises vendues", '603xxx | 607xxx | 609xxx', 0, 0, '', '20', 1, 1); +INSERT INTO llx_c_accounting_category (rowid, code, label, range_account, sens, category_type, formula, position, fk_country, active) VALUES ( 3,'MARGE',"Marge commerciale", '', 0, 1, '1 + 2', '30', 1, 1); + UPDATE llx_accounting_account SET account_parent = '0' WHERE account_parent = ''; -ALTER TABLE llx_accounting_account MODIFY COLUMN account_parent integer DEFAULT 0; +-- VMYSQL4.1 ALTER TABLE llx_accounting_account MODIFY COLUMN account_parent integer DEFAULT 0; +-- VPGSQL8.2 ALTER TABLE llx_accounting_account ALTER COLUMN account_parent TYPE integer USING account_parent::integer; -DROP INDEX uk_bordereau_cheque ON llx_bordereau_cheque; +-- VMYSQL4.1 DROP INDEX uk_bordereau_cheque ON llx_bordereau_cheque; +-- VPGSQL8.2 DROP INDEX uk_bordereau_cheque; ALTER TABLE llx_bordereau_cheque CHANGE COLUMN number ref VARCHAR(30) NOT NULL; CREATE UNIQUE INDEX uk_bordereau_cheque ON llx_bordereau_cheque (ref, entity); @@ -389,3 +396,18 @@ ALTER TABLE llx_product ADD COLUMN default_vat_code varchar(10) after cost_price -- Delete old deprecated field ALTER TABLE llx_product_stock DROP COLUMN pmp; + +-- VMYSQL4.1 ALTER TABLE llx_c_type_resource CHANGE COLUMN rowid rowid integer NOT NULL AUTO_INCREMENT; + +ALTER TABLE llx_resource ADD COLUMN asset_number varchar(255) after ref; +ALTER TABLE llx_resource ADD COLUMN datec datetime DEFAULT NULL; +ALTER TABLE llx_resource ADD COLUMN date_valid datetime DEFAULT NULL; +ALTER TABLE llx_resource ADD COLUMN fk_user_author integer DEFAULT NULL; +ALTER TABLE llx_resource ADD COLUMN fk_user_modif integer DEFAULT NULL; +ALTER TABLE llx_resource ADD COLUMN fk_user_valid integer DEFAULT NULL; +ALTER TABLE llx_resource ADD COLUMN fk_statut smallint NOT NULL DEFAULT '0'; +ALTER TABLE llx_resource ADD COLUMN import_key varchar(14); +ALTER TABLE llx_resource ADD COLUMN extraparams varchar(255); + +ALTER TABLE llx_element_resources ADD COLUMN duree real; -- total duration of using ressource + diff --git a/htdocs/install/mysql/tables/llx_accounting_account.sql b/htdocs/install/mysql/tables/llx_accounting_account.sql index d74c1b75105..51346cc63f6 100644 --- a/htdocs/install/mysql/tables/llx_accounting_account.sql +++ b/htdocs/install/mysql/tables/llx_accounting_account.sql @@ -29,7 +29,7 @@ create table llx_accounting_account pcg_type varchar(20) NOT NULL, pcg_subtype varchar(20) NOT NULL, account_number varchar(32) NOT NULL, - account_parent integer, -- Hierarchic parent + account_parent integer DEFAULT 0, -- Hierarchic parent label varchar(255) NOT NULL, fk_accounting_category integer DEFAULT 0, fk_user_author integer DEFAULT NULL, diff --git a/htdocs/install/mysql/tables/llx_element_resources.sql b/htdocs/install/mysql/tables/llx_element_resources.sql index 9c67a0d52af..d619626d3d7 100644 --- a/htdocs/install/mysql/tables/llx_element_resources.sql +++ b/htdocs/install/mysql/tables/llx_element_resources.sql @@ -26,6 +26,7 @@ CREATE TABLE llx_element_resources resource_type varchar(64), -- resource or user busy integer, mandatory integer, + duree real, -- total duration of using ressource fk_user_create integer, tms timestamp )ENGINE=innodb; diff --git a/htdocs/install/mysql/tables/llx_expedition.sql b/htdocs/install/mysql/tables/llx_expedition.sql index 8421bb1649c..12dba35f89d 100644 --- a/htdocs/install/mysql/tables/llx_expedition.sql +++ b/htdocs/install/mysql/tables/llx_expedition.sql @@ -40,8 +40,9 @@ create table llx_expedition fk_address integer DEFAULT NULL, -- delivery address (deprecated) fk_shipping_method integer, tracking_number varchar(50), - fk_statut smallint DEFAULT 0, - + fk_statut smallint DEFAULT 0, -- 0 = draft, 1 = validated, 2 = billed or closed depending on WORKFLOW_BILL_ON_SHIPMENT option + billed smallint DEFAULT 0, + height float, -- height width float, -- with size_units integer, -- unit of all sizes (height, width, depth) diff --git a/htdocs/install/mysql/tables/llx_product.sql b/htdocs/install/mysql/tables/llx_product.sql index 9d3446d696d..8b43844498e 100755 --- a/htdocs/install/mysql/tables/llx_product.sql +++ b/htdocs/install/mysql/tables/llx_product.sql @@ -79,7 +79,7 @@ create table llx_product surface_units tinyint DEFAULT NULL, volume float DEFAULT NULL, volume_units tinyint DEFAULT NULL, - stock integer, -- Current physical stock (dernormalized field) + stock real, -- Current physical stock (dernormalized field) pmp double(24,8) DEFAULT 0 NOT NULL, -- To store valuation of stock calculated using average price method, for this product fifo double(24,8), -- To store valuation of stock calculated using fifo method, for this product lifo double(24,8), -- To store valuation of stock calculated using lifo method, for this product diff --git a/htdocs/install/mysql/tables/llx_resource.sql b/htdocs/install/mysql/tables/llx_resource.sql index 0d67075f1ea..afb73e9fd5f 100755 --- a/htdocs/install/mysql/tables/llx_resource.sql +++ b/htdocs/install/mysql/tables/llx_resource.sql @@ -1,5 +1,6 @@ -- Module to manage resources into Dolibarr ERP/CRM --- Copyright (C) 2013 Jean-François Ferry +-- Copyright (C) 2013 Jean-François Ferry +-- Copyright (C) 2016 Gilles Poirier -- -- 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 @@ -16,12 +17,21 @@ CREATE TABLE llx_resource ( - rowid integer AUTO_INCREMENT PRIMARY KEY, - entity integer DEFAULT 1 NOT NULL, - ref varchar(255), - description text, + rowid integer AUTO_INCREMENT PRIMARY KEY, + entity integer DEFAULT 1 NOT NULL, + ref varchar(255), + asset_number varchar(255), + description text, fk_code_type_resource varchar(32), - note_public text, - note_private text, - tms timestamp -)ENGINE=innodb; \ No newline at end of file + datec datetime DEFAULT NULL, + date_valid datetime DEFAULT NULL, + fk_user_author integer DEFAULT NULL, + fk_user_modif integer DEFAULT NULL, + fk_user_valid integer DEFAULT NULL, + fk_statut smallint NOT NULL DEFAULT '0', + note_public text, + note_private text, + import_key varchar(14), + extraparams varchar(255), -- for stock other parameters with json format + tms timestamp +)ENGINE=innodb; diff --git a/htdocs/install/mysql/tables/llx_societe_remise_except.sql b/htdocs/install/mysql/tables/llx_societe_remise_except.sql index ef84e0081d6..f17d17670d2 100644 --- a/htdocs/install/mysql/tables/llx_societe_remise_except.sql +++ b/htdocs/install/mysql/tables/llx_societe_remise_except.sql @@ -33,7 +33,7 @@ create table llx_societe_remise_except fk_facture integer, fk_facture_source integer, description text NOT NULL, - multicurrency_amount_ht double(24,8) NOT NULL, + multicurrency_amount_ht double(24,8) DEFAULT 0 NOT NULL, multicurrency_amount_tva double(24,8) DEFAULT 0 NOT NULL, multicurrency_amount_ttc double(24,8) DEFAULT 0 NOT NULL )ENGINE=innodb; diff --git a/htdocs/install/mysql/tables/llx_stock_mouvement.sql b/htdocs/install/mysql/tables/llx_stock_mouvement.sql index 3db9a4475cd..3ac42c0c852 100644 --- a/htdocs/install/mysql/tables/llx_stock_mouvement.sql +++ b/htdocs/install/mysql/tables/llx_stock_mouvement.sql @@ -24,8 +24,8 @@ create table llx_stock_mouvement datem datetime, -- Date and hour of movement fk_product integer NOT NULL, -- Id of product batch varchar(30) DEFAULT NULL, -- Lot or serial number - eatby date DEFAULT NULL, -- Eatby date - sellby date DEFAULT NULL, -- Sellby date + eatby date DEFAULT NULL, -- Eatby date (deprecated, we should get value from batch number in table llx_product_lot) + sellby date DEFAULT NULL, -- Sellby date (deprecated, we should get value from batch number in table llx_product_lot) fk_entrepot integer NOT NULL, -- Id warehouse value real, -- Qty of movement price double(24,8) DEFAULT 0, -- Entry price (used to calculate PMP, FIFO or LIFO value) diff --git a/htdocs/install/upgrade2.php b/htdocs/install/upgrade2.php index c9fa2ba39a6..9ee3d842e51 100644 --- a/htdocs/install/upgrade2.php +++ b/htdocs/install/upgrade2.php @@ -401,6 +401,8 @@ if (! GETPOST("action") || preg_match('/upgrade/i',GETPOST('action'))) $beforeversionarray=explode('.','4.0.9'); if (versioncompare($versiontoarray,$afterversionarray) >= 0 && versioncompare($versiontoarray,$beforeversionarray) <= 0) { + migrate_directories($db,$langs,$conf,'/fckeditor','/medias'); + // Reload modules (this must be always and only into last targeted version) $listofmodule=array( 'MAIN_MODULE_BARCODE'=>'newboxdefonly', diff --git a/htdocs/langs/ar_SA/projects.lang b/htdocs/langs/ar_SA/projects.lang index bdd7967374a..ab322a4bd05 100644 --- a/htdocs/langs/ar_SA/projects.lang +++ b/htdocs/langs/ar_SA/projects.lang @@ -199,6 +199,6 @@ OppStatusQUAL=المؤهل العلمى OppStatusPROPO=مقترح OppStatusNEGO=Negociation OppStatusPENDING=بانتظار -OppStatusWIN=فاز +OppStatusWON=فاز OppStatusLOST=ضائع Budget=Budget diff --git a/htdocs/langs/bn_BD/projects.lang b/htdocs/langs/bn_BD/projects.lang index b4a21befd80..982ec36b26b 100644 --- a/htdocs/langs/bn_BD/projects.lang +++ b/htdocs/langs/bn_BD/projects.lang @@ -199,6 +199,6 @@ OppStatusQUAL=Qualification OppStatusPROPO=Proposal OppStatusNEGO=Negociation OppStatusPENDING=Pending -OppStatusWIN=Won +OppStatusWON=Won OppStatusLOST=Lost Budget=Budget diff --git a/htdocs/langs/bs_BA/projects.lang b/htdocs/langs/bs_BA/projects.lang index 0b25f6ea67a..fdfcbd408e5 100644 --- a/htdocs/langs/bs_BA/projects.lang +++ b/htdocs/langs/bs_BA/projects.lang @@ -199,6 +199,6 @@ OppStatusQUAL=Qualification OppStatusPROPO=Proposal OppStatusNEGO=Negociation OppStatusPENDING=Pending -OppStatusWIN=Won +OppStatusWON=Won OppStatusLOST=Lost Budget=Budget diff --git a/htdocs/langs/ca_ES/projects.lang b/htdocs/langs/ca_ES/projects.lang index 5c2f18593cb..91c1a7cc9db 100644 --- a/htdocs/langs/ca_ES/projects.lang +++ b/htdocs/langs/ca_ES/projects.lang @@ -199,6 +199,6 @@ OppStatusQUAL=Qualificació OppStatusPROPO=Pressupost OppStatusNEGO=Negociació OppStatusPENDING=Pendent -OppStatusWIN=Guanyat +OppStatusWON=Guanyat OppStatusLOST=Perdut Budget=Budget diff --git a/htdocs/langs/cs_CZ/projects.lang b/htdocs/langs/cs_CZ/projects.lang index 14b67dbb918..cdc3743aee4 100644 --- a/htdocs/langs/cs_CZ/projects.lang +++ b/htdocs/langs/cs_CZ/projects.lang @@ -199,6 +199,6 @@ OppStatusQUAL=Qualification OppStatusPROPO=Proposal OppStatusNEGO=Negociation OppStatusPENDING=Pending -OppStatusWIN=Won +OppStatusWON=Won OppStatusLOST=Lost Budget=Budget diff --git a/htdocs/langs/da_DK/projects.lang b/htdocs/langs/da_DK/projects.lang index 0c7ed16673b..618a6e5dc47 100644 --- a/htdocs/langs/da_DK/projects.lang +++ b/htdocs/langs/da_DK/projects.lang @@ -199,6 +199,6 @@ OppStatusQUAL=Qualification OppStatusPROPO=Proposal OppStatusNEGO=Negociation OppStatusPENDING=Pending -OppStatusWIN=Won +OppStatusWON=Won OppStatusLOST=Lost Budget=Budget diff --git a/htdocs/langs/de_DE/projects.lang b/htdocs/langs/de_DE/projects.lang index 15fc4080190..c1d58f6d3d6 100644 --- a/htdocs/langs/de_DE/projects.lang +++ b/htdocs/langs/de_DE/projects.lang @@ -199,6 +199,6 @@ OppStatusQUAL=Qualifikation OppStatusPROPO=Angebot OppStatusNEGO=Verhandlung OppStatusPENDING=Anstehend -OppStatusWIN=Gewonnen +OppStatusWON=Gewonnen OppStatusLOST=Verloren Budget=Budget diff --git a/htdocs/langs/en_US/accountancy.lang b/htdocs/langs/en_US/accountancy.lang index 9fe7c6544fb..64c0d88df48 100644 --- a/htdocs/langs/en_US/accountancy.lang +++ b/htdocs/langs/en_US/accountancy.lang @@ -174,6 +174,9 @@ OptionModeProductBuyDesc=Show all products with no accounting account defined fo ## Dictionary Range=Range of accounting account +Sens=Sens +Calculated=Calculated +Formula=Formula ## Error ErrorNoAccountingCategoryForThisCountry=No accounting category are available for this country \ No newline at end of file diff --git a/htdocs/langs/en_US/admin.lang b/htdocs/langs/en_US/admin.lang index b37083ca091..9122546a1f3 100755 --- a/htdocs/langs/en_US/admin.lang +++ b/htdocs/langs/en_US/admin.lang @@ -521,7 +521,7 @@ Module1520Desc=Mass mail document generation Module1780Name=Tags/Categories Module1780Desc=Create tags/category (products, customers, suppliers, contacts or members) Module2000Name=WYSIWYG editor -Module2000Desc=Allow to edit some text area using an advanced editor +Module2000Desc=Allow to edit some text area using an advanced editor (Based on CKEditor) Module2200Name=Dynamic Prices Module2200Desc=Enable the usage of math expressions for prices Module2300Name=Cron @@ -1602,7 +1602,7 @@ ApiDesc=By enabling this module, Dolibarr become a REST server to provide miscel KeyForApiAccess=Key to use API (parameter "api_key") ApiProductionMode=Enable production mode (this will activate use of a caches for services management) ApiEndPointIs=You can access to the API at url -ApiExporerIs=You can explore the API at url +ApiExporerIs=You can explore the APIs at url OnlyActiveElementsAreExposed=Only elements from enabled modules are exposed ApiKey=Key for API ##### Bank ##### @@ -1740,3 +1740,5 @@ AddOtherPagesOrServices=Add other pages or services AddModels=Add document or numbering templates AddSubstitutions=Add keys substitutions DetectionNotPossible=Detection not possible +UrlToGetKeyToUseAPIs=Url to get token to use API (once token has been received it is saved on database user table and will be checked on each future access) +ListOfAvailableAPIs=List of available APIs \ No newline at end of file diff --git a/htdocs/langs/en_US/compta.lang b/htdocs/langs/en_US/compta.lang index e3c0b5108fc..c6526b51d28 100644 --- a/htdocs/langs/en_US/compta.lang +++ b/htdocs/langs/en_US/compta.lang @@ -59,6 +59,8 @@ SpecialExpensesArea=Area for all special payments TaxAndDividendsArea=Sale taxes, social/fiscal taxes contributions and dividends area SocialContribution=Social or fiscal tax SocialContributions=Social or fiscal taxes +SocialContributionsDeductibles=Deductible social or fiscal taxes +SocialContributionsNondeductibles=Nondeductible social or fiscal taxes MenuSpecialExpenses=Special expenses MenuTaxAndDividends=Taxes and dividends MenuSalaries=Salaries diff --git a/htdocs/langs/en_US/main.lang b/htdocs/langs/en_US/main.lang index 4b69e2c0dde..90ccde2474a 100644 --- a/htdocs/langs/en_US/main.lang +++ b/htdocs/langs/en_US/main.lang @@ -120,6 +120,7 @@ Home=Home Help=Help OnlineHelp=Online help PageWiki=Wiki page +MediaBrowser=Media browser Always=Always Never=Never Under=under diff --git a/htdocs/langs/en_US/projects.lang b/htdocs/langs/en_US/projects.lang index 607b28d9f06..42c05d0cd07 100644 --- a/htdocs/langs/en_US/projects.lang +++ b/htdocs/langs/en_US/projects.lang @@ -199,6 +199,6 @@ OppStatusQUAL=Qualification OppStatusPROPO=Proposal OppStatusNEGO=Negociation OppStatusPENDING=Pending -OppStatusWIN=Won +OppStatusWON=Won OppStatusLOST=Lost Budget=Budget \ No newline at end of file diff --git a/htdocs/langs/en_US/supplier_proposal.lang b/htdocs/langs/en_US/supplier_proposal.lang index 3d12ad57612..a1ede43437d 100644 --- a/htdocs/langs/en_US/supplier_proposal.lang +++ b/htdocs/langs/en_US/supplier_proposal.lang @@ -1,7 +1,6 @@ # Dolibarr language file - Source file is en_US - supplier_proposal SupplierProposal=Supplier commercial proposals supplier_proposalDESC=Manage price requests to suppliers -SupplierProposalShort=Supplier proposals SupplierProposalNew=New request CommRequest=Price request CommRequests=Price requests diff --git a/htdocs/langs/en_US/website.lang b/htdocs/langs/en_US/website.lang index 13659bc5954..a0b2106ac63 100644 --- a/htdocs/langs/en_US/website.lang +++ b/htdocs/langs/en_US/website.lang @@ -4,11 +4,17 @@ WebsiteSetupDesc=Create here as much entry as number of different websites you n DeleteWebsite=Delete website ConfirmDeleteWebsite=Are you sure you want to delete this web site. All its pages and content will also be removed. WEBSITE_PAGENAME=Page name/alias -WEBSITE_URL=Page real URL +WEBSITE_URL=Web site URL +WEBSITE_CSS_URL=URL of external CSS file +WEBSITE_CSS_INLINE=CSS content +MediaFiles=Media library +EditCss=Edit Style/CSS EditMenu=Edit menu EditPageMeta=Edit Meta EditPageContent=Edit Content Website=Web site AddPage=Add page Page=Page -PreviewOfSiteNotYetAvailable=Preview of your website %s not yet available. You must first add a page. \ No newline at end of file +PreviewOfSiteNotYetAvailable=Preview of your website %s not yet available. You must first add a page. +PageDeleted=Page %s of website %s deleted +ViewInNewTab=View in new tab \ No newline at end of file diff --git a/htdocs/langs/es_ES/projects.lang b/htdocs/langs/es_ES/projects.lang index b0965bd080c..3a9fd407875 100644 --- a/htdocs/langs/es_ES/projects.lang +++ b/htdocs/langs/es_ES/projects.lang @@ -199,6 +199,6 @@ OppStatusQUAL=Cualificación OppStatusPROPO=Presupuesto OppStatusNEGO=Negociación OppStatusPENDING=Pendiente -OppStatusWIN=Ganado +OppStatusWON=Ganado OppStatusLOST=Perdido Budget=Budget diff --git a/htdocs/langs/et_EE/projects.lang b/htdocs/langs/et_EE/projects.lang index 7c53e51f80d..31f516ada14 100644 --- a/htdocs/langs/et_EE/projects.lang +++ b/htdocs/langs/et_EE/projects.lang @@ -199,6 +199,6 @@ OppStatusQUAL=Qualification OppStatusPROPO=Proposal OppStatusNEGO=Negociation OppStatusPENDING=Pending -OppStatusWIN=Won +OppStatusWON=Won OppStatusLOST=Lost Budget=Budget diff --git a/htdocs/langs/eu_ES/projects.lang b/htdocs/langs/eu_ES/projects.lang index b4a21befd80..982ec36b26b 100644 --- a/htdocs/langs/eu_ES/projects.lang +++ b/htdocs/langs/eu_ES/projects.lang @@ -199,6 +199,6 @@ OppStatusQUAL=Qualification OppStatusPROPO=Proposal OppStatusNEGO=Negociation OppStatusPENDING=Pending -OppStatusWIN=Won +OppStatusWON=Won OppStatusLOST=Lost Budget=Budget diff --git a/htdocs/langs/fi_FI/projects.lang b/htdocs/langs/fi_FI/projects.lang index fea93953f69..50177fda449 100644 --- a/htdocs/langs/fi_FI/projects.lang +++ b/htdocs/langs/fi_FI/projects.lang @@ -199,6 +199,6 @@ OppStatusQUAL=Qualification OppStatusPROPO=Proposal OppStatusNEGO=Negociation OppStatusPENDING=Pending -OppStatusWIN=Won +OppStatusWON=Won OppStatusLOST=Lost Budget=Budget diff --git a/htdocs/langs/fr_FR/projects.lang b/htdocs/langs/fr_FR/projects.lang index b95fbb3cd56..6389d10abbf 100644 --- a/htdocs/langs/fr_FR/projects.lang +++ b/htdocs/langs/fr_FR/projects.lang @@ -199,6 +199,6 @@ OppStatusQUAL=Qualification OppStatusPROPO=Proposition OppStatusNEGO=Négociation OppStatusPENDING=En attente -OppStatusWIN=Gagné +OppStatusWON=Gagné OppStatusLOST=Perdu Budget=Budget diff --git a/htdocs/langs/he_IL/projects.lang b/htdocs/langs/he_IL/projects.lang index fb939aef169..ee8785e6397 100644 --- a/htdocs/langs/he_IL/projects.lang +++ b/htdocs/langs/he_IL/projects.lang @@ -199,6 +199,6 @@ OppStatusQUAL=Qualification OppStatusPROPO=Proposal OppStatusNEGO=Negociation OppStatusPENDING=Pending -OppStatusWIN=Won +OppStatusWON=Won OppStatusLOST=Lost Budget=Budget diff --git a/htdocs/langs/hr_HR/projects.lang b/htdocs/langs/hr_HR/projects.lang index 7dae3662584..bd83a40224d 100644 --- a/htdocs/langs/hr_HR/projects.lang +++ b/htdocs/langs/hr_HR/projects.lang @@ -199,6 +199,6 @@ OppStatusQUAL=Qualification OppStatusPROPO=Proposal OppStatusNEGO=Negociation OppStatusPENDING=Pending -OppStatusWIN=Won +OppStatusWON=Won OppStatusLOST=Lost Budget=Budget diff --git a/htdocs/langs/hu_HU/projects.lang b/htdocs/langs/hu_HU/projects.lang index 9ab8ab13b05..20a6f143d2a 100644 --- a/htdocs/langs/hu_HU/projects.lang +++ b/htdocs/langs/hu_HU/projects.lang @@ -199,6 +199,6 @@ OppStatusQUAL=Qualification OppStatusPROPO=Proposal OppStatusNEGO=Negociation OppStatusPENDING=Pending -OppStatusWIN=Won +OppStatusWON=Won OppStatusLOST=Lost Budget=Budget diff --git a/htdocs/langs/id_ID/projects.lang b/htdocs/langs/id_ID/projects.lang index 83a284cc58c..13798a28b3c 100644 --- a/htdocs/langs/id_ID/projects.lang +++ b/htdocs/langs/id_ID/projects.lang @@ -199,6 +199,6 @@ OppStatusQUAL=Qualification OppStatusPROPO=Proposal OppStatusNEGO=Negociation OppStatusPENDING=Pending -OppStatusWIN=Won +OppStatusWON=Won OppStatusLOST=Lost Budget=Budget diff --git a/htdocs/langs/is_IS/projects.lang b/htdocs/langs/is_IS/projects.lang index d41a345caf3..517ab7e2e84 100644 --- a/htdocs/langs/is_IS/projects.lang +++ b/htdocs/langs/is_IS/projects.lang @@ -199,6 +199,6 @@ OppStatusQUAL=Qualification OppStatusPROPO=Proposal OppStatusNEGO=Negociation OppStatusPENDING=Pending -OppStatusWIN=Won +OppStatusWON=Won OppStatusLOST=Lost Budget=Budget diff --git a/htdocs/langs/it_IT/projects.lang b/htdocs/langs/it_IT/projects.lang index 9954fb68fd2..8599f5089b5 100644 --- a/htdocs/langs/it_IT/projects.lang +++ b/htdocs/langs/it_IT/projects.lang @@ -199,6 +199,6 @@ OppStatusQUAL=Qualificazione OppStatusPROPO=Proposta OppStatusNEGO=Negoziazione OppStatusPENDING=In attesa -OppStatusWIN=Vinto +OppStatusWON=Vinto OppStatusLOST=Perso Budget=Budget diff --git a/htdocs/langs/ka_GE/projects.lang b/htdocs/langs/ka_GE/projects.lang index b4a21befd80..982ec36b26b 100644 --- a/htdocs/langs/ka_GE/projects.lang +++ b/htdocs/langs/ka_GE/projects.lang @@ -199,6 +199,6 @@ OppStatusQUAL=Qualification OppStatusPROPO=Proposal OppStatusNEGO=Negociation OppStatusPENDING=Pending -OppStatusWIN=Won +OppStatusWON=Won OppStatusLOST=Lost Budget=Budget diff --git a/htdocs/langs/kn_IN/projects.lang b/htdocs/langs/kn_IN/projects.lang index b4a21befd80..982ec36b26b 100644 --- a/htdocs/langs/kn_IN/projects.lang +++ b/htdocs/langs/kn_IN/projects.lang @@ -199,6 +199,6 @@ OppStatusQUAL=Qualification OppStatusPROPO=Proposal OppStatusNEGO=Negociation OppStatusPENDING=Pending -OppStatusWIN=Won +OppStatusWON=Won OppStatusLOST=Lost Budget=Budget diff --git a/htdocs/langs/ko_KR/projects.lang b/htdocs/langs/ko_KR/projects.lang index b4a21befd80..982ec36b26b 100644 --- a/htdocs/langs/ko_KR/projects.lang +++ b/htdocs/langs/ko_KR/projects.lang @@ -199,6 +199,6 @@ OppStatusQUAL=Qualification OppStatusPROPO=Proposal OppStatusNEGO=Negociation OppStatusPENDING=Pending -OppStatusWIN=Won +OppStatusWON=Won OppStatusLOST=Lost Budget=Budget diff --git a/htdocs/langs/lo_LA/projects.lang b/htdocs/langs/lo_LA/projects.lang index 56cc02c9e82..52ca66a2763 100644 --- a/htdocs/langs/lo_LA/projects.lang +++ b/htdocs/langs/lo_LA/projects.lang @@ -199,6 +199,6 @@ OppStatusQUAL=Qualification OppStatusPROPO=Proposal OppStatusNEGO=Negociation OppStatusPENDING=Pending -OppStatusWIN=Won +OppStatusWON=Won OppStatusLOST=Lost Budget=Budget diff --git a/htdocs/langs/lt_LT/projects.lang b/htdocs/langs/lt_LT/projects.lang index 6398f58b129..bc9adc0ef7f 100644 --- a/htdocs/langs/lt_LT/projects.lang +++ b/htdocs/langs/lt_LT/projects.lang @@ -199,6 +199,6 @@ OppStatusQUAL=Qualification OppStatusPROPO=Proposal OppStatusNEGO=Negociation OppStatusPENDING=Pending -OppStatusWIN=Won +OppStatusWON=Won OppStatusLOST=Lost Budget=Budget diff --git a/htdocs/langs/lv_LV/projects.lang b/htdocs/langs/lv_LV/projects.lang index d04ece7b84f..000139e853c 100644 --- a/htdocs/langs/lv_LV/projects.lang +++ b/htdocs/langs/lv_LV/projects.lang @@ -199,6 +199,6 @@ OppStatusQUAL=Kvalifikācija OppStatusPROPO=Proposal OppStatusNEGO=Negociation OppStatusPENDING=Pending -OppStatusWIN=Won +OppStatusWON=Won OppStatusLOST=Lost Budget=Budget diff --git a/htdocs/langs/mk_MK/projects.lang b/htdocs/langs/mk_MK/projects.lang index b4a21befd80..982ec36b26b 100644 --- a/htdocs/langs/mk_MK/projects.lang +++ b/htdocs/langs/mk_MK/projects.lang @@ -199,6 +199,6 @@ OppStatusQUAL=Qualification OppStatusPROPO=Proposal OppStatusNEGO=Negociation OppStatusPENDING=Pending -OppStatusWIN=Won +OppStatusWON=Won OppStatusLOST=Lost Budget=Budget diff --git a/htdocs/langs/nb_NO/projects.lang b/htdocs/langs/nb_NO/projects.lang index c57648d77d1..c69d3c47ee4 100644 --- a/htdocs/langs/nb_NO/projects.lang +++ b/htdocs/langs/nb_NO/projects.lang @@ -199,6 +199,6 @@ OppStatusQUAL=Kvalifikasjon OppStatusPROPO=Tilbud OppStatusNEGO=Forhandling OppStatusPENDING=Venter -OppStatusWIN=Vunnet +OppStatusWON=Vunnet OppStatusLOST=Tapt Budget=Budget diff --git a/htdocs/langs/nl_NL/projects.lang b/htdocs/langs/nl_NL/projects.lang index 93514bd4108..8cf1a0d4684 100644 --- a/htdocs/langs/nl_NL/projects.lang +++ b/htdocs/langs/nl_NL/projects.lang @@ -199,6 +199,6 @@ OppStatusQUAL=Qualification OppStatusPROPO=Proposal OppStatusNEGO=Negociation OppStatusPENDING=Pending -OppStatusWIN=Won +OppStatusWON=Won OppStatusLOST=Lost Budget=Budget diff --git a/htdocs/langs/pl_PL/projects.lang b/htdocs/langs/pl_PL/projects.lang index 1479193a7cc..429a664d293 100644 --- a/htdocs/langs/pl_PL/projects.lang +++ b/htdocs/langs/pl_PL/projects.lang @@ -199,6 +199,6 @@ OppStatusQUAL=Kwalifikacja OppStatusPROPO=Wniosek OppStatusNEGO=Negocjacje OppStatusPENDING=W oczekiwaniu -OppStatusWIN=Won +OppStatusWON=Won OppStatusLOST=Zagubiony Budget=Budget diff --git a/htdocs/langs/pt_BR/projects.lang b/htdocs/langs/pt_BR/projects.lang index f8ae458330b..ab92118d1e4 100644 --- a/htdocs/langs/pt_BR/projects.lang +++ b/htdocs/langs/pt_BR/projects.lang @@ -125,5 +125,5 @@ OppStatusQUAL=Qualificação OppStatusPROPO=Proposta OppStatusNEGO=Negociação OppStatusPENDING=Pendente -OppStatusWIN=Ganhou +OppStatusWON=Ganhou OppStatusLOST=Perdido diff --git a/htdocs/langs/pt_PT/projects.lang b/htdocs/langs/pt_PT/projects.lang index c6bc715fada..2df744a5013 100644 --- a/htdocs/langs/pt_PT/projects.lang +++ b/htdocs/langs/pt_PT/projects.lang @@ -199,6 +199,6 @@ OppStatusQUAL=Qualification OppStatusPROPO=Proposal OppStatusNEGO=Negociation OppStatusPENDING=Pending -OppStatusWIN=Won +OppStatusWON=Won OppStatusLOST=Lost Budget=Budget diff --git a/htdocs/langs/ro_RO/projects.lang b/htdocs/langs/ro_RO/projects.lang index 301c6242d24..c6fc6cb74e0 100644 --- a/htdocs/langs/ro_RO/projects.lang +++ b/htdocs/langs/ro_RO/projects.lang @@ -199,6 +199,6 @@ OppStatusQUAL=Calificare OppStatusPROPO=Ofertă OppStatusNEGO=Negociere OppStatusPENDING=In asteptarea -OppStatusWIN=Castigat +OppStatusWON=Castigat OppStatusLOST=Pierdut Budget=Budget diff --git a/htdocs/langs/ru_RU/projects.lang b/htdocs/langs/ru_RU/projects.lang index 27c4995d20d..bdee2d2d019 100644 --- a/htdocs/langs/ru_RU/projects.lang +++ b/htdocs/langs/ru_RU/projects.lang @@ -199,6 +199,6 @@ OppStatusQUAL=Qualification OppStatusPROPO=Proposal OppStatusNEGO=Negociation OppStatusPENDING=Pending -OppStatusWIN=Won +OppStatusWON=Won OppStatusLOST=Lost Budget=Budget diff --git a/htdocs/langs/sk_SK/projects.lang b/htdocs/langs/sk_SK/projects.lang index 6453fec2772..579d69f1323 100644 --- a/htdocs/langs/sk_SK/projects.lang +++ b/htdocs/langs/sk_SK/projects.lang @@ -199,6 +199,6 @@ OppStatusQUAL=Qualification OppStatusPROPO=Proposal OppStatusNEGO=Negociation OppStatusPENDING=Pending -OppStatusWIN=Won +OppStatusWON=Won OppStatusLOST=Lost Budget=Budget diff --git a/htdocs/langs/sl_SI/projects.lang b/htdocs/langs/sl_SI/projects.lang index 81c1c01c46d..38c773a95bb 100644 --- a/htdocs/langs/sl_SI/projects.lang +++ b/htdocs/langs/sl_SI/projects.lang @@ -199,6 +199,6 @@ OppStatusQUAL=Qualification OppStatusPROPO=Proposal OppStatusNEGO=Negociation OppStatusPENDING=Pending -OppStatusWIN=Won +OppStatusWON=Won OppStatusLOST=Lost Budget=Budget diff --git a/htdocs/langs/sq_AL/projects.lang b/htdocs/langs/sq_AL/projects.lang index b4a21befd80..982ec36b26b 100644 --- a/htdocs/langs/sq_AL/projects.lang +++ b/htdocs/langs/sq_AL/projects.lang @@ -199,6 +199,6 @@ OppStatusQUAL=Qualification OppStatusPROPO=Proposal OppStatusNEGO=Negociation OppStatusPENDING=Pending -OppStatusWIN=Won +OppStatusWON=Won OppStatusLOST=Lost Budget=Budget diff --git a/htdocs/langs/sr_RS/projects.lang b/htdocs/langs/sr_RS/projects.lang index 8ba6046454e..553b7ec80af 100644 --- a/htdocs/langs/sr_RS/projects.lang +++ b/htdocs/langs/sr_RS/projects.lang @@ -199,6 +199,6 @@ OppStatusQUAL=Kvalifikacija OppStatusPROPO=Ponuda OppStatusNEGO=Pregovaranje OppStatusPENDING=Na čekanju -OppStatusWIN=Dobijeno +OppStatusWON=Dobijeno OppStatusLOST=Izgubljeno Budget=Budget diff --git a/htdocs/langs/sv_SE/projects.lang b/htdocs/langs/sv_SE/projects.lang index 77be1874eb2..a75da531dd3 100644 --- a/htdocs/langs/sv_SE/projects.lang +++ b/htdocs/langs/sv_SE/projects.lang @@ -199,6 +199,6 @@ OppStatusQUAL=Qualification OppStatusPROPO=Proposal OppStatusNEGO=Negociation OppStatusPENDING=Pending -OppStatusWIN=Won +OppStatusWON=Won OppStatusLOST=Lost Budget=Budget diff --git a/htdocs/langs/sw_SW/projects.lang b/htdocs/langs/sw_SW/projects.lang index b4a21befd80..982ec36b26b 100644 --- a/htdocs/langs/sw_SW/projects.lang +++ b/htdocs/langs/sw_SW/projects.lang @@ -199,6 +199,6 @@ OppStatusQUAL=Qualification OppStatusPROPO=Proposal OppStatusNEGO=Negociation OppStatusPENDING=Pending -OppStatusWIN=Won +OppStatusWON=Won OppStatusLOST=Lost Budget=Budget diff --git a/htdocs/langs/tr_TR/projects.lang b/htdocs/langs/tr_TR/projects.lang index dbdfcadfce7..b4a54871c5a 100644 --- a/htdocs/langs/tr_TR/projects.lang +++ b/htdocs/langs/tr_TR/projects.lang @@ -199,6 +199,6 @@ OppStatusQUAL=Nitelendirme OppStatusPROPO=Teklif OppStatusNEGO=Pazarlık OppStatusPENDING=Beklemede -OppStatusWIN=Kazanç +OppStatusWON=Kazanç OppStatusLOST=Kayıp Budget=Budget diff --git a/htdocs/langs/uk_UA/projects.lang b/htdocs/langs/uk_UA/projects.lang index b4a21befd80..982ec36b26b 100644 --- a/htdocs/langs/uk_UA/projects.lang +++ b/htdocs/langs/uk_UA/projects.lang @@ -199,6 +199,6 @@ OppStatusQUAL=Qualification OppStatusPROPO=Proposal OppStatusNEGO=Negociation OppStatusPENDING=Pending -OppStatusWIN=Won +OppStatusWON=Won OppStatusLOST=Lost Budget=Budget diff --git a/htdocs/langs/uz_UZ/projects.lang b/htdocs/langs/uz_UZ/projects.lang index b4a21befd80..982ec36b26b 100644 --- a/htdocs/langs/uz_UZ/projects.lang +++ b/htdocs/langs/uz_UZ/projects.lang @@ -199,6 +199,6 @@ OppStatusQUAL=Qualification OppStatusPROPO=Proposal OppStatusNEGO=Negociation OppStatusPENDING=Pending -OppStatusWIN=Won +OppStatusWON=Won OppStatusLOST=Lost Budget=Budget diff --git a/htdocs/langs/vi_VN/projects.lang b/htdocs/langs/vi_VN/projects.lang index 174b4a88dc1..7af08a9a5bc 100644 --- a/htdocs/langs/vi_VN/projects.lang +++ b/htdocs/langs/vi_VN/projects.lang @@ -199,6 +199,6 @@ OppStatusQUAL=Qualification OppStatusPROPO=Proposal OppStatusNEGO=Negociation OppStatusPENDING=Pending -OppStatusWIN=Won +OppStatusWON=Won OppStatusLOST=Lost Budget=Budget diff --git a/htdocs/langs/zh_CN/projects.lang b/htdocs/langs/zh_CN/projects.lang index bbd8b5cf27d..070c15647e6 100644 --- a/htdocs/langs/zh_CN/projects.lang +++ b/htdocs/langs/zh_CN/projects.lang @@ -199,6 +199,6 @@ OppStatusQUAL=Qualification OppStatusPROPO=Proposal OppStatusNEGO=Negociation OppStatusPENDING=Pending -OppStatusWIN=Won +OppStatusWON=Won OppStatusLOST=Lost Budget=Budget diff --git a/htdocs/langs/zh_TW/projects.lang b/htdocs/langs/zh_TW/projects.lang index 2599ab48413..2519f38c954 100644 --- a/htdocs/langs/zh_TW/projects.lang +++ b/htdocs/langs/zh_TW/projects.lang @@ -199,6 +199,6 @@ OppStatusQUAL=Qualification OppStatusPROPO=Proposal OppStatusNEGO=Negociation OppStatusPENDING=Pending -OppStatusWIN=Won +OppStatusWON=Won OppStatusLOST=Lost Budget=Budget diff --git a/htdocs/main.inc.php b/htdocs/main.inc.php index b0f4585d888..bea4a20afcd 100644 --- a/htdocs/main.inc.php +++ b/htdocs/main.inc.php @@ -866,7 +866,7 @@ else define('ROWS_9',8); } -$heightforframes=52; +$heightforframes=48; // Init menu manager if (! defined('NOREQUIREMENU')) @@ -1464,7 +1464,7 @@ function top_menu($head, $title='', $target='', $disablejs=0, $disablehead=0, $a $text =''; $text.= img_picto(":".$langs->trans("PrintContentArea"), 'printer_top.png', 'class="printer"'); $text.=''; - $toprightmenu.=Form::textwithtooltip('',$langs->trans("PrintContentArea"),2,1,$text,'login_block_elem',2); + $toprightmenu.=@Form::textwithtooltip('',$langs->trans("PrintContentArea"),2,1,$text,'login_block_elem',2); } // Link to Dolibarr wiki pages @@ -1501,12 +1501,12 @@ function top_menu($head, $title='', $target='', $disablejs=0, $disablehead=0, $a //if ($mode == 'wiki') $text.=' ('.dol_trunc(strtr($helppage,'_',' '),8).')'; $text.=''; //$toprightmenu.=''."\n"; - $toprightmenu.=Form::textwithtooltip('',$title,2,1,$text,'login_block_elem',2); + $toprightmenu.=@Form::textwithtooltip('',$title,2,1,$text,'login_block_elem',2); } } // Logout link - $toprightmenu.=Form::textwithtooltip('',$logouthtmltext,2,1,$logouttext,'login_block_elem',2); + $toprightmenu.=@Form::textwithtooltip('',$logouthtmltext,2,1,$logouttext,'login_block_elem',2); $toprightmenu.=''; diff --git a/htdocs/product/card.php b/htdocs/product/card.php index 841d1b1b73a..92d8a7f4288 100644 --- a/htdocs/product/card.php +++ b/htdocs/product/card.php @@ -8,12 +8,12 @@ * Copyright (C) 2010-2015 Juanjo Menent * Copyright (C) 2013-2014 Marcos García * Copyright (C) 2012-2013 Cédric Salvador - * Copyright (C) 2011-2015 Alexandre Spangaro + * Copyright (C) 2011-2016 Alexandre Spangaro * Copyright (C) 2014 Cédric Gross * Copyright (C) 2014-2015 Ferran Marcet * Copyright (C) 2015 Jean-François Ferry * Copyright (C) 2015 Raphaël Doursenaud - * Copyright (C) 2016 Charlie Benke + * Copyright (C) 2016 Charlie Benke * * 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 @@ -1477,22 +1477,24 @@ else // Accountancy sell code print ''; + if (! empty($conf->accounting->enabled)) { + print length_accountg($object->accountancy_code_sell); + } else { + print $object->accountancy_code_sell; + } + print ''; // Accountancy buy code print ''; // Status (to sell) diff --git a/htdocs/product/class/api_product.class.php b/htdocs/product/class/api_product.class.php index 1ce63411cd3..1e485fd6733 100644 --- a/htdocs/product/class/api_product.class.php +++ b/htdocs/product/class/api_product.class.php @@ -18,6 +18,7 @@ use Luracast\Restler\RestException; require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php'; + require_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php'; /** * API class for product object @@ -165,6 +166,91 @@ class ProductApi extends DolibarrApi } return $obj_ret; } + + + /** + * List products in a category + * + * Get a list of products + * + * @param int $mode Use this param to filter list (0 for all, 1 for only product, 2 for only service) + * @param int $category Use this param to filter list by category + * @param mixed $to_sell Filter products to sell (1) or not to sell (0) + * @param mixed $to_buy Filter products to nuy (1) or not to buy (0) + * @param string $sortfield Sort field + * @param string $sortorder Sort order + * @param int $limit Limit for list + * @param int $page Page number + * + * @return array Array of product objects + * + * @url GET /product/list/category/{category} + */ + function getByCategory($mode=0, $category=0, $to_sell='', $to_buy='', $sortfield = "p.ref", $sortorder = 'ASC', $limit = 0, $page = 0) { + global $db, $conf; + + $obj_ret = array(); + + $socid = DolibarrApiAccess::$user->societe_id ? DolibarrApiAccess::$user->societe_id : ''; + + $sql = "SELECT rowid, ref, ref_ext"; + $sql.= " FROM ".MAIN_DB_PREFIX."product as p, "; + $sql.= MAIN_DB_PREFIX."categorie_product as c"; + $sql.= ' WHERE p.entity IN ('.getEntity('product', 1).')'; + + // Select products of given category + $sql.= " AND c.fk_categorie = ".$db->escape($category); + $sql.= " AND c.fk_product = p.rowid "; + + // Show products + if ($mode == 1) $sql.= " AND p.fk_product_type = 0"; + // Show services + if ($mode == 2) $sql.= " AND p.fk_product_type = 1"; + // Show product on sell + if ($to_sell) $sql.= " AND p.to_sell = ".$db->escape($to_sell); + // Show product on buy + if ($to_buy) $sql.= " AND p.to_nuy = ".$db->escape($to_nuy); + + $nbtotalofrecords = 0; + if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST)) + { + $result = $db->query($sql); + $nbtotalofrecords = $db->num_rows($result); + } + + $sql.= $db->order($sortfield, $sortorder); + if ($limit) { + if ($page < 0) + { + $page = 0; + } + $offset = $limit * $page; + + $sql.= $db->plimit($limit + 1, $offset); + } + + $result = $db->query($sql); + if ($result) + { + $num = $db->num_rows($result); + while ($i < $num) + { + $obj = $db->fetch_object($result); + $product_static = new Product($db); + if($product_static->fetch($obj->rowid)) { + $obj_ret[] = parent::_cleanObjectDatas($product_static); + } + $i++; + } + } + else { + throw new RestException(503, 'Error when retrieve product list'); + } + if( ! count($obj_ret)) { + throw new RestException(404, 'No product found'); + } + return $obj_ret; + } /** * Create product object diff --git a/htdocs/product/class/product.class.php b/htdocs/product/class/product.class.php index 819a5438eda..6919d722ceb 100644 --- a/htdocs/product/class/product.class.php +++ b/htdocs/product/class/product.class.php @@ -109,8 +109,10 @@ class Product extends CommonObject var $localtax1_type; var $localtax2_type; - //! Stock + //! Stock real var $stock_reel; + //! Stock virtual + var $stock_theorique; //! Cost price var $cost_price; //! Average price value for product entry into stock (PMP) @@ -1416,7 +1418,7 @@ class Product extends CommonObject $id=$this->id; - dol_syslog(get_class($this)."::update_price id=".$id." newprice=".$newprice." newpricebase=".$newpricebase." newminprice=".$newminprice." level=".$level." npr=".$newnpr," newdefaultvatcode=".$newdefaultvatcode); + dol_syslog(get_class($this)."::update_price id=".$id." newprice=".$newprice." newpricebase=".$newpricebase." newminprice=".$newminprice." level=".$level." npr=".$newnpr." newdefaultvatcode=".$newdefaultvatcode); // Clean parameters if (empty($this->tva_tx)) $this->tva_tx=0; @@ -1848,7 +1850,7 @@ class Product extends CommonObject } } - // We should not load stock at each fetch. If someone need stock, he must call load_stock after fetch. + // We should not load stock during the fetch. If someone need stock of product, he must call load_stock after fetching product. //$res=$this->load_stock(); // instead we just init the stock_warehouse array $this->stock_warehouse = array(); @@ -2845,7 +2847,7 @@ class Product extends CommonObject //print "XXX We add id=".$id." - label=".$label." - nb=".$nb." - multiply=".$multiply." fullpath=".$compl_path.$label."\n"; $this->fetch($id); // Load product - $this->load_stock(); // Load stock + $this->load_stock('nobatch,novirtual'); // Load stock to get true this->stock_reel $this->res[]= array( 'id'=>$id, // Id product 'id_parent'=>$id_parent, @@ -3339,15 +3341,18 @@ class Product extends CommonObject /** * Load information about stock of a product into stock_reel, stock_warehouse[] (including stock_warehouse[idwarehouse]->detail_batch for batch products) + * This function need a lot of load. If you use it on list, use a cache to execute it one for each product id. * - * @return int < 0 if KO, > 0 if OK - * @see load_virtual_stock, getBatchInfo + * @param string $option '', 'nobatch' = Do not load batch information, 'novirtual' = Do not load virtual stock + * @return int < 0 if KO, > 0 if OK + * @see load_virtual_stock, getBatchInfo */ - function load_stock() + function load_stock($option='') { $this->stock_reel = 0; $this->stock_warehouse = array(); - + $this->stock_theorique = 0; + $sql = "SELECT ps.rowid, ps.reel, ps.fk_entrepot"; $sql.= " FROM ".MAIN_DB_PREFIX."product_stock as ps"; $sql.= ", ".MAIN_DB_PREFIX."entrepot as w"; @@ -3369,14 +3374,17 @@ class Product extends CommonObject $this->stock_warehouse[$row->fk_entrepot] = new stdClass(); $this->stock_warehouse[$row->fk_entrepot]->real = $row->reel; $this->stock_warehouse[$row->fk_entrepot]->id = $row->rowid; - if ($this->hasbatch()) $this->stock_warehouse[$row->fk_entrepot]->detail_batch=Productbatch::findAll($this->db,$row->rowid,1); + if ((! preg_match('/nobatch/', $option)) && $this->hasbatch()) $this->stock_warehouse[$row->fk_entrepot]->detail_batch=Productbatch::findAll($this->db,$row->rowid,1); $this->stock_reel+=$row->reel; $i++; } } $this->db->free($result); - $this->load_virtual_stock(); // This also load stats_commande_fournisseur, ... + if (! preg_match('/novirtual/', $option)) + { + $this->load_virtual_stock(); // This also load stats_commande_fournisseur, ... + } return 1; } @@ -3388,7 +3396,8 @@ class Product extends CommonObject } /** - * Load information about objects that are delat between physical and virtual stock of a product + * Load value ->stock_theorique of a product. Property this->id must be defined. + * This function need a lot of load. If you use it on list, use a cache to execute it one for each product id. * * @return int < 0 if KO, > 0 if OK * @see load_stock, getBatchInfo @@ -3712,7 +3721,7 @@ class Product extends CommonObject } } - if ($size==1 || $size='small') + if ($size==1 || $size=='small') { if ($nbbyrow > 0) { diff --git a/htdocs/product/class/productbatch.class.php b/htdocs/product/class/productbatch.class.php index d0554309539..749da6d86e2 100644 --- a/htdocs/product/class/productbatch.class.php +++ b/htdocs/product/class/productbatch.class.php @@ -408,8 +408,8 @@ class Productbatch extends CommonObject * Find first detail record that match eather eat-by or sell-by or batch within given warehouse * * @param int $fk_product_stock id product_stock for objet - * @param date $eatby eat-by date for objet - * @param date $sellby sell-by date for objet + * @param date $eatby eat-by date for objet - deprecated: a search must be done on batch number + * @param date $sellby sell-by date for objet - deprecated: a search must be done on batch number * @param string $batch_number batch number for objet * @return int <0 if KO, >0 if OK */ diff --git a/htdocs/product/list.php b/htdocs/product/list.php index 51e453393a0..1d63964be1c 100644 --- a/htdocs/product/list.php +++ b/htdocs/product/list.php @@ -103,6 +103,13 @@ if ($type=='0') $result=restrictedArea($user,'produit','','','','','',$objcanvas else if ($type=='1') $result=restrictedArea($user,'service','','','','','',$objcanvas); else $result=restrictedArea($user,'produit|service','','','','','',$objcanvas); +// Define virtualdiffersfromphysical +$virtualdiffersfromphysical=0; +if (! empty($conf->global->STOCK_CALCULATE_ON_SHIPMENT) || ! empty($conf->global->STOCK_CALCULATE_ON_SUPPLIER_DISPATCH_ORDER)) +{ + $virtualdiffersfromphysical=1; // According to increase/decrease stock options, virtual and physical stock may differs. +} + // List of fields to search into when doing a "search in all" $fieldstosearchall = array( 'p.ref'=>"Ref", @@ -140,9 +147,11 @@ $arrayfields=array( 'p.duration'=>array('label'=>$langs->trans("Duration"), 'checked'=>($contextpage != 'productlist'), 'enabled'=>(! empty($conf->service->enabled))), 'p.sellprice'=>array('label'=>$titlesellprice, 'checked'=>1, 'enabled'=>empty($conf->global->PRODUIT_MULTIPRICES)), 'p.minbuyprice'=>array('label'=>$langs->trans("BuyingPriceMinShort"), 'checked'=>1, 'enabled'=>(! empty($user->rights->fournisseur->lire))), - 'p.desiredstock'=>array('label'=>$langs->trans("DesiredStock"), 'checked'=>1, 'enabled'=>(! empty($conf->stock->enabled) && $user->rights->stock->lire && $contextpage != 'service')), - 'p.tobatch'=>array('label'=>$langs->trans("ManageLotSerial"), 'checked'=>0, 'enabled'=>(! empty($conf->productbatch->enabled))), + 'p.seuil_stock_alerte'=>array('label'=>$langs->trans("StockLimit"), 'checked'=>0, 'enabled'=>(! empty($conf->stock->enabled) && $user->rights->stock->lire && $contextpage != 'service')), + 'p.desiredstock'=>array('label'=>$langs->trans("DesiredStock"), 'checked'=>1, 'enabled'=>(! empty($conf->stock->enabled) && $user->rights->stock->lire && $contextpage != 'service')), 'p.stock'=>array('label'=>$langs->trans("PhysicalStock"), 'checked'=>1, 'enabled'=>(! empty($conf->stock->enabled) && $user->rights->stock->lire && $contextpage != 'service')), + 'stock_virtual'=>array('label'=>$langs->trans("VirtualStock"), 'checked'=>1, 'enabled'=>(! empty($conf->stock->enabled) && $user->rights->stock->lire && $contextpage != 'service' && $virtualdiffersfromphysical)), + 'p.tobatch'=>array('label'=>$langs->trans("ManageLotSerial"), 'checked'=>0, 'enabled'=>(! empty($conf->productbatch->enabled))), 'p.accountancy_code_sell'=>array('label'=>$langs->trans("ProductAccountancySellCode"), 'checked'=>0), 'p.accountancy_code_buy'=>array('label'=>$langs->trans("ProductAccountancyBuyCode"), 'checked'=>0), 'p.datec'=>array('label'=>$langs->trans("DateCreation"), 'checked'=>0, 'position'=>500), @@ -159,6 +168,7 @@ if (is_array($extrafields->attribute_label) && count($extrafields->attribute_lab } } + /* * Actions @@ -425,9 +435,11 @@ else if (! empty($arrayfields['p.duration']['checked'])) print_liste_field_titre($arrayfields['p.duration']['label'], $_SERVER["PHP_SELF"],"p.duration","",$param,"",$sortfield,$sortorder); if (! empty($arrayfields['p.sellprice']['checked'])) print_liste_field_titre($arrayfields['p.sellprice']['label'], $_SERVER["PHP_SELF"],"","",$param,'align="right"',$sortfield,$sortorder); if (! empty($arrayfields['p.minbuyprice']['checked'])) print_liste_field_titre($arrayfields['p.minbuyprice']['label'], $_SERVER["PHP_SELF"],"","",$param,'align="right"',$sortfield,$sortorder); + if (! empty($arrayfields['p.seuil_stock_alerte']['checked'])) print_liste_field_titre($arrayfields['p.seuil_stock_alerte']['label'], $_SERVER["PHP_SELF"],"p.seuil_stock_alerte","",$param,'align="right"',$sortfield,$sortorder); if (! empty($arrayfields['p.desiredstock']['checked'])) print_liste_field_titre($arrayfields['p.desiredstock']['label'], $_SERVER["PHP_SELF"],"p.desiredstock","",$param,'align="right"',$sortfield,$sortorder); - if (! empty($arrayfields['p.tobatch']['checked'])) print_liste_field_titre($arrayfields['p.tobatch']['label'], $_SERVER["PHP_SELF"],"p.tobatch","",$param,'align="center"',$sortfield,$sortorder); if (! empty($arrayfields['p.stock']['checked'])) print_liste_field_titre($arrayfields['p.stock']['label'], $_SERVER["PHP_SELF"],"p.stock","",$param,'align="right"',$sortfield,$sortorder); + if (! empty($arrayfields['stock_virtual']['checked'])) print_liste_field_titre($arrayfields['stock_virtual']['label'], $_SERVER["PHP_SELF"],"","",$param,'align="right"',$sortfield,$sortorder); + if (! empty($arrayfields['p.tobatch']['checked'])) print_liste_field_titre($arrayfields['p.tobatch']['label'], $_SERVER["PHP_SELF"],"p.tobatch","",$param,'align="center"',$sortfield,$sortorder); if (! empty($arrayfields['p.accountancy_code_sell']['checked'])) print_liste_field_titre($arrayfields['p.accountancy_code_sell']['label'], $_SERVER["PHP_SELF"],"p.accountancy_code_sell","",$param,'',$sortfield,$sortorder); if (! empty($arrayfields['p.accountancy_code_buy']['checked'])) print_liste_field_titre($arrayfields['p.accountancy_code_buy']['label'], $_SERVER["PHP_SELF"],"p.accountancy_code_buy","",$param,'',$sortfield,$sortorder); if (is_array($extrafields->attribute_label) && count($extrafields->attribute_label)) @@ -499,6 +511,13 @@ else print ' '; print ''; } + // Limit for alert + if (! empty($arrayfields['p.seuil_stock_alerte']['checked'])) + { + print ''; + } // Desired stock if (! empty($arrayfields['p.desiredstock']['checked'])) { @@ -506,11 +525,13 @@ else print ' '; print ''; } - // To batch - if (! empty($arrayfields['p.tobatch']['checked'])) print ''; // Stock if (! empty($arrayfields['p.stock']['checked'])) print ''; - // Accountancy code sell + // Stock + if (! empty($arrayfields['stock_virtual']['checked'])) print ''; + // To batch + if (! empty($arrayfields['p.tobatch']['checked'])) print ''; + // Accountancy code sell if (! empty($arrayfields['p.accountancy_code_sell']['checked'])) print ''; // Accountancy code sell if (! empty($arrayfields['p.accountancy_code_buy']['checked'])) print ''; @@ -591,7 +612,16 @@ else $product_static->status_buy = $objp->tobuy; $product_static->status = $objp->tosell; $product_static->entity = $objp->entity; - + + if (! empty($conf->stock->enabled) && $user->rights->stock->lire && $type != 1) // To optimize call of load_stock + { + if ($objp->fk_product_type != 1) // Not a service + { + $product_static->load_stock('nobatch'); // Load stock_reel + stock_warehouse. This also call load_virtual_stock() + } + } + + $var=!$var; print ''; @@ -672,15 +702,16 @@ else print ''; } - if (! empty($conf->stock->enabled) && $user->rights->stock->lire && $type != 1) // To optimize call of load_stock - { + // Limit alert + if (! empty($arrayfields['p.seuil_stock_alerte']['checked'])) + { + print ''; + } // Desired stock if (! empty($arrayfields['p.desiredstock']['checked'])) { @@ -691,24 +722,35 @@ else } print ''; } - // Desired stock - if (! empty($arrayfields['p.tobatch']['checked'])) - { - print ''; - } // Stock if (! empty($arrayfields['p.stock']['checked'])) { print ''; } + // Stock + if (! empty($arrayfields['stock_virtual']['checked'])) + { + print ''; + } + // Lot/Serial + if (! empty($arrayfields['p.tobatch']['checked'])) + { + print ''; + } // Accountancy code sell if (! empty($arrayfields['p.accountancy_code_sell']['checked'])) print ''; // Accountancy code sell diff --git a/htdocs/product/reassort.php b/htdocs/product/reassort.php index 6642c1e3550..15a93d8070c 100644 --- a/htdocs/product/reassort.php +++ b/htdocs/product/reassort.php @@ -85,6 +85,13 @@ if (! empty($_POST["button_removefilter_x"])) $toolowstock=''; } +// Define virtualdiffersfromphysical +$virtualdiffersfromphysical=0; +if (! empty($conf->global->STOCK_CALCULATE_ON_SHIPMENT) || ! empty($conf->global->STOCK_CALCULATE_ON_SUPPLIER_DISPATCH_ORDER)) +{ + $virtualdiffersfromphysical=1; // According to increase/decrease stock options, virtual and physical stock may differs. +} + /* @@ -193,11 +200,11 @@ if ($resql) if ($sref || $snom || $sall || GETPOST('search')) { - print_barre_liste($texte, $page, $_SERVER["PHP_SELF"], "&sref=".$sref."&snom=".$snom."&sall=".$sall."&tosell=".$tosell."&tobuy=".$tobuy.(!empty($search_categ) ? '&search_categ='.$search_categ : '').(!empty($toolowstock) ? '&toolowstock='.$toolowstock : ''), $sortfield, $sortorder,'',$num); + print_barre_liste($texte, $page, $_SERVER["PHP_SELF"], "&sref=".$sref."&snom=".$snom."&sall=".$sall."&tosell=".$tosell."&tobuy=".$tobuy.(!empty($search_categ) ? '&search_categ='.$search_categ : '').(!empty($toolowstock) ? '&toolowstock='.$toolowstock : ''), $sortfield, $sortorder,'',$num, 0, 'title_products'); } else { - print_barre_liste($texte, $page, $_SERVER["PHP_SELF"], "&sref=$sref&snom=$snom&fourn_id=$fourn_id".(isset($type)?"&type=$type":"").(!empty($search_categ) ? '&search_categ='.$search_categ : '').(!empty($toolowstock) ? '&toolowstock='.$toolowstock : ''), $sortfield, $sortorder,'',$num); + print_barre_liste($texte, $page, $_SERVER["PHP_SELF"], "&sref=$sref&snom=$snom&fourn_id=$fourn_id".(isset($type)?"&type=$type":"").(!empty($search_categ) ? '&search_categ='.$search_categ : '').(!empty($toolowstock) ? '&toolowstock='.$toolowstock : ''), $sortfield, $sortorder,'',$num, 0, 'title_products'); } if (! empty($catid)) @@ -272,8 +279,7 @@ if ($resql) } - // TODO Add info of running suppliers/customers orders - //print_liste_field_titre($langs->trans("TheoreticalStock"),$_SERVER["PHP_SELF"], "stock_theorique",$param,"",'align="right"',$sortfield,$sortorder); + if ($virtualdiffersfromphysical) print_liste_field_titre($langs->trans("VirtualStock"),$_SERVER["PHP_SELF"], "stock_theorique",$param,"",'align="right"',$sortfield,$sortorder); print_liste_field_titre(''); print_liste_field_titre($langs->trans("Status").' ('.$langs->trans("Sell").')',$_SERVER["PHP_SELF"], "p.tosell",$param,"",'align="right"',$sortfield,$sortorder); print_liste_field_titre($langs->trans("Status").' ('.$langs->trans("Buy").')',$_SERVER["PHP_SELF"], "p.tobuy",$param,"",'align="right"',$sortfield,$sortorder); @@ -287,16 +293,18 @@ if ($resql) print ''; + // Duration if (! empty($conf->service->enabled) && $type == 1) { print ''; } - // Lot/Serial + // Stock limit print ''; print ''; print ''; + if ($virtualdiffersfromphysical) print ''; print ''; print ''; print ''; print ''; print ''; + // Real stock print ''; /* @@ -356,7 +365,14 @@ if ($resql) - + // Virtual stock + if ($virtualdiffersfromphysical) + { + print ''; + } print ''; print ''; print ''; diff --git a/htdocs/product/reassortlot.php b/htdocs/product/reassortlot.php index 3b77f9c5ba7..b0e4904715e 100644 --- a/htdocs/product/reassortlot.php +++ b/htdocs/product/reassortlot.php @@ -204,11 +204,11 @@ if ($resql) if ($sref || $snom || $sall || GETPOST('search')) { - print_barre_liste($texte, $page, $_SERVER["PHP_SELF"], "&sref=".$sref."&snom=".$snom."&sall=".$sall."&tosell=".$tosell."&tobuy=".$tobuy, $sortfield, $sortorder,'',$num); + print_barre_liste($texte, $page, $_SERVER["PHP_SELF"], "&sref=".$sref."&snom=".$snom."&sall=".$sall."&tosell=".$tosell."&tobuy=".$tobuy, $sortfield, $sortorder,'',$num, 0, 'title_products'); } else { - print_barre_liste($texte, $page, $_SERVER["PHP_SELF"], "&sref=$sref&snom=$snom&fourn_id=$fourn_id".(isset($type)?"&type=$type":""), $sortfield, $sortorder,'',$num); + print_barre_liste($texte, $page, $_SERVER["PHP_SELF"], "&sref=$sref&snom=$snom&fourn_id=$fourn_id".(isset($type)?"&type=$type":""), $sortfield, $sortorder,'',$num, 0, 'title_products'); } if (! empty($catid)) diff --git a/htdocs/product/stock/class/mouvementstock.class.php b/htdocs/product/stock/class/mouvementstock.class.php index 652c6d9dc36..944fb3f8dfb 100644 --- a/htdocs/product/stock/class/mouvementstock.class.php +++ b/htdocs/product/stock/class/mouvementstock.class.php @@ -220,10 +220,9 @@ class MouvementStock extends CommonObject $oldqty=$product->stock_reel; $oldpmp=$product->pmp; $oldqtywarehouse=0; - //$oldpmpwarehouse=0; // Test if there is already a record for couple (warehouse / product) - $num = 0; + $alreadyarecord = 0; if (! $error) { $sql = "SELECT rowid, reel FROM ".MAIN_DB_PREFIX."product_stock"; @@ -236,9 +235,8 @@ class MouvementStock extends CommonObject $obj = $this->db->fetch_object($resql); if ($obj) { - $num = 1; + $alreadyarecord = 1; $oldqtywarehouse = $obj->reel; - //$oldpmpwarehouse = $obj->pmp; $fk_product_stock = $obj->rowid; } $this->db->free($resql); @@ -252,25 +250,12 @@ class MouvementStock extends CommonObject // Calculate new PMP. $newpmp=0; - //$newpmpwarehouse=0; if (! $error) { // Note: PMP is calculated on stock input only (type of movement = 0 or 3). If type == 0 or 3, qty should be > 0. // Note: Price should always be >0 or 0. PMP should be always >0 (calculated on input) if (($type == 0 || $type == 3) && $price > 0) { - // If we will change PMP for the warehouse we edit and the product, we must first check/clean that PMP is defined - // on every stock entry with old value (so global updated value will match recalculated value from product_stock) - /* $sql = "UPDATE ".MAIN_DB_PREFIX."product_stock SET pmp = ".($oldpmp?$oldpmp:'0'); - $sql.= " WHERE pmp = 0 AND fk_product = ".$fk_product; - dol_syslog(get_class($this)."::_create", LOG_DEBUG); - $resql=$this->db->query($sql); - if (! $resql) - { - $this->errors[]=$this->db->lasterror(); - $error = -4; - } - */ $oldqtytouse=($oldqty >= 0?$oldqty:0); // We make a test on oldpmp>0 to avoid to use normal rule on old data with no pmp field defined if ($oldpmp > 0) $newpmp=price2num((($oldqtytouse * $oldpmp) + ($qty * $price)) / ($oldqtytouse + $qty), 'MU'); @@ -278,13 +263,8 @@ class MouvementStock extends CommonObject { $newpmp=$price; // For this product, PMP was not yet set. We set it to input price. } - /* - $oldqtywarehousetouse=$oldqtywarehouse; - if ($oldpmpwarehouse > 0) $newpmpwarehouse=price2num((($oldqtywarehousetouse * $oldpmpwarehouse) + ($qty * $price)) / ($oldqtywarehousetouse + $qty), 'MU'); - else $newpmpwarehouse=$price; - */ - //print "oldqtytouse=".$oldqtytouse." oldpmp=".$oldpmp." oldqtywarehousetouse=".$oldqtywarehousetouse." oldpmpwarehouse=".$oldpmpwarehouse." "; - //print "qty=".$qty." newpmp=".$newpmp." newpmpwarehouse=".$newpmpwarehouse; + //print "oldqtytouse=".$oldqtytouse." oldpmp=".$oldpmp." oldqtywarehousetouse=".$oldqtywarehousetouse." "; + //print "qty=".$qty." newpmp=".$newpmp; //exit; } else if ($type == 1 || $type == 2) @@ -295,14 +275,13 @@ class MouvementStock extends CommonObject else { $newpmp = $oldpmp; - //$newpmpwarehouse = $oldpmpwarehouse; } } // Update stock quantity if (! $error) { - if ($num > 0) + if ($alreadyarecord > 0) { $sql = "UPDATE ".MAIN_DB_PREFIX."product_stock SET reel = reel + ".$qty; $sql.= " WHERE fk_entrepot = ".$entrepot_id." AND fk_product = ".$fk_product; @@ -339,11 +318,13 @@ class MouvementStock extends CommonObject // Update PMP and denormalized value of stock qty at product level if (! $error) { - $sql = "UPDATE ".MAIN_DB_PREFIX."product SET pmp = ".$newpmp.", stock = ".$this->db->ifsql("stock IS NULL", 0, "stock") . " + ".$qty; + // $sql = "UPDATE ".MAIN_DB_PREFIX."product SET pmp = ".$newpmp.", stock = ".$this->db->ifsql("stock IS NULL", 0, "stock") . " + ".$qty; + // $sql.= " WHERE rowid = ".$fk_product; + // Update pmp + denormalized fields because we change content of produt_stock. Warning: Do not use "SET p.stock", does not works with pgsql + $sql = "UPDATE ".MAIN_DB_PREFIX."product as p SET p.pmp = ".$newpmp.", "; + $sql.= " stock=(SELECT SUM(ps.reel) FROM ".MAIN_DB_PREFIX."product_stock ps WHERE ps.fk_product = p.rowid)"; $sql.= " WHERE rowid = ".$fk_product; - // May be this request is better: - // UPDATE llx_product p SET p.stock= (SELECT SUM(ps.reel) FROM llx_product_stock ps WHERE ps.fk_product = p.rowid); - + print $sql; dol_syslog(get_class($this)."::_create", LOG_DEBUG); $resql=$this->db->query($sql); if (! $resql) @@ -352,6 +333,12 @@ class MouvementStock extends CommonObject $error = -4; } } + + // If stock is now 0, we can remove entry into llx_stock_product, but only if there is no child lines into llx_product_batch (detail of batch, because we can imagine + // having a lot1/qty=X and lot2/qty=-X, so 0 but we must not loose repartition of different lot. + $sql="DELETE FROM ".MAIN_DB_PREFIX."product_stock WHERE reel = 0 AND rowid NOT IN (SELECT fk_product_stock FROM ".MAIN_DB_PREFIX."product_batch as pb)"; + $resql=$this->db->query($sql); + // We do not test error, it can fails if there is child in batch details } // Add movement for sub products (recursive call) @@ -543,7 +530,7 @@ class MouvementStock extends CommonObject * Create or update batch record (update table llx_product_batch) * * @param array|int $dluo Could be either - * - int if id of product_batch + * - int if row id of product_batch table * - or complete array('fk_product_stock'=>, 'eatby'=>, 'sellby'=> , 'batchnumber'=>) * @param int $qty Quantity of product with batch number. May be a negative amount. * @return int <0 if KO, else return productbatch id diff --git a/htdocs/product/stock/massstockmove.php b/htdocs/product/stock/massstockmove.php index 7d62699b425..c7b7ed41034 100644 --- a/htdocs/product/stock/massstockmove.php +++ b/htdocs/product/stock/massstockmove.php @@ -185,7 +185,7 @@ if ($action == 'createmovements') { $result=$product->fetch($id_product); - $product->load_stock(); // Load array product->stock_warehouse + $product->load_stock('novirtual'); // Load array product->stock_warehouse // Define value of products moved $pricesrc=0; diff --git a/htdocs/product/stock/mouvement.php b/htdocs/product/stock/mouvement.php index 190bf676c8a..29ee33c56eb 100644 --- a/htdocs/product/stock/mouvement.php +++ b/htdocs/product/stock/mouvement.php @@ -207,11 +207,10 @@ if ($action == "transfert_stock" && ! $cancel) $db->begin(); - $product->load_stock(); // Load array product->stock_warehouse + $product->load_stock('novirtual'); // Load array product->stock_warehouse // Define value of products moved $pricesrc=0; - //if (isset($product->stock_warehouse[GETPOST("id_entrepot_source")]->pmp)) $pricesrc=$product->stock_warehouse[GETPOST("id_entrepot_source")]->pmp; if (isset($product->pmp)) $pricesrc=$product->pmp; $pricedest=$pricesrc; diff --git a/htdocs/product/stock/product.php b/htdocs/product/stock/product.php index de30bc3d0b6..05b0aecf5b6 100644 --- a/htdocs/product/stock/product.php +++ b/htdocs/product/stock/product.php @@ -185,7 +185,7 @@ if ($action == "correct_stock" && ! $cancel) // Transfer stock from a warehouse to another warehouse if ($action == "transfert_stock" && ! $cancel) { - if (! (GETPOST("id_entrepot_source",'int') > 0) || ! (GETPOST("id_entrepot_destination",'int') > 0)) + if (! (GETPOST("id_entrepot",'int') > 0) || ! (GETPOST("id_entrepot_destination",'int') > 0)) { setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Warehouse")), null, 'errors'); $error++; @@ -197,7 +197,7 @@ if ($action == "transfert_stock" && ! $cancel) $error++; $action='transfert'; } - if (GETPOST("id_entrepot_source",'int') == GETPOST("id_entrepot_destination",'int')) + if (GETPOST("id_entrepot",'int') == GETPOST("id_entrepot_destination",'int')) { setEventMessages($langs->trans("ErrorSrcAndTargetWarehouseMustDiffers"), null, 'errors'); $error++; @@ -225,7 +225,7 @@ if ($action == "transfert_stock" && ! $cancel) $db->begin(); - $object->load_stock(); // Load array product->stock_warehouse + $object->load_stock('novirtual'); // Load array product->stock_warehouse // Define value of products moved $pricesrc=0; @@ -254,7 +254,7 @@ if ($action == "transfert_stock" && ! $cancel) } else { - $srcwarehouseid=GETPOST('id_entrepot_source','int'); + $srcwarehouseid=GETPOST('id_entrepot','int'); $batch=GETPOST('batch_number'); $eatby=$d_eatby; $sellby=$d_sellby; @@ -291,7 +291,7 @@ if ($action == "transfert_stock" && ! $cancel) // Remove stock $result1=$object->correct_stock( $user, - GETPOST("id_entrepot_source"), + GETPOST("id_entrepot"), GETPOST("nbpiece"), 1, GETPOST("label"), @@ -390,6 +390,7 @@ if ($id > 0 || $ref) { $object = new Product($db); $result = $object->fetch($id,$ref); + $object->load_stock(); $help_url='EN:Module_Stocks_En|FR:Module_Stock|ES:Módulo_Stocks'; @@ -480,7 +481,6 @@ if ($id > 0 || $ref) print ''; // Real stock - $object->load_stock(); $text_stock_options = ''; $text_stock_options.= (! empty($conf->global->STOCK_CALCULATE_ON_SHIPMENT)?$langs->trans("DeStockOnShipment").'
':''); $text_stock_options.= (! empty($conf->global->STOCK_CALCULATE_ON_VALIDATE_ORDER)?$langs->trans("DeStockOnValidateOrder").'
':''); @@ -702,9 +702,10 @@ if ($resql) $entrepotstatic->id=$obj->rowid; $entrepotstatic->libelle=$obj->label; $entrepotstatic->lieu=$obj->lieu; + $stock_real = round($obj->reel, 10); print ''; print ''; - print ''; + print ''; // PMP print ''; // Value purchase diff --git a/htdocs/product/stock/replenish.php b/htdocs/product/stock/replenish.php index c31699a12ef..7af08ee6575 100644 --- a/htdocs/product/stock/replenish.php +++ b/htdocs/product/stock/replenish.php @@ -69,6 +69,13 @@ if (!$sortorder) { $sortorder = 'ASC'; } +// Define virtualdiffersfromphysical +$virtualdiffersfromphysical=0; +if (! empty($conf->global->STOCK_CALCULATE_ON_SHIPMENT) || ! empty($conf->global->STOCK_CALCULATE_ON_SUPPLIER_DISPATCH_ORDER)) +{ + $virtualdiffersfromphysical=1; // According to increase/decrease stock options, virtual and physical stock may differs. +} + /* * Actions @@ -227,20 +234,6 @@ if ($action == 'order' && isset($_POST['valid'])) $form = new Form($db); -$virtualdiffersfromphysical=0; -if (! empty($conf->global->STOCK_CALCULATE_ON_SHIPMENT) || ! empty($conf->global->STOCK_CALCULATE_ON_SUPPLIER_DISPATCH_ORDER)) -{ - $virtualdiffersfromphysical=1; // According to increase/decrease stock options, virtual and physical stock may differs. -} - -$usevirtualstock=-1; -if ($virtualdiffersfromphysical) -{ - $usevirtualstock=(! empty($conf->global->STOCK_USE_VIRTUAL_STOCK)?1:0); - if ($mode=='virtual') $usevirtualstock=1; - if ($mode=='physical') $usevirtualstock=0; -} - $title = $langs->trans('Status'); $sql = 'SELECT p.rowid, p.ref, p.label, p.price,'; @@ -557,7 +550,7 @@ while ($i < ($limit ? min($num, $limit) : $num)) //print ''; print ''; - print ''; + print ''; print ''; diff --git a/htdocs/public/websites/index.php b/htdocs/public/websites/index.php index fb3133df7cc..b54a69e90f9 100644 --- a/htdocs/public/websites/index.php +++ b/htdocs/public/websites/index.php @@ -1,5 +1,5 @@ +/* Copyright (C) 2016 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 @@ -16,16 +16,122 @@ */ /** - * \file htdocs/public/paypal/index.php + * \file htdocs/public/websites/index.php * \ingroup core * \brief A redirect page to an error * \author Laurent Destailleur */ +define('NOTOKENRENEWAL',1); // Disables token renewal +define("NOLOGIN",1); +define("NOCSRFCHECK",1); // We accept to go on this page from external web site. +if (! defined('NOREQUIREMENU')) define('NOREQUIREMENU','1'); +if (! defined('NOREQUIREHTML')) define('NOREQUIREHTML','1'); +if (! defined('NOREQUIREAJAX')) define('NOREQUIREAJAX','1'); + +/** + * Header empty + * + * @return void + */ +function llxHeader() { } +/** + * Footer empty + * + * @return void + */ +function llxFooter() { } + require '../../master.inc.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; + + +$error=0; +$website=GETPOST('website', 'alpha'); +$page=GETPOST('page', 'alpha'); +$pageid=GETPOST('pageid', 'alpha'); + +$accessallowed = 1; +$type=''; + + +/* + * View + */ $appli=constant('DOL_APPLICATION_TITLE'); if (!empty($conf->global->MAIN_APPLICATION_TITLE)) $appli=$conf->global->MAIN_APPLICATION_TITLE; -print 'Directory with '.$appli.' websites.
'; +//print 'Directory with '.$appli.' websites.
'; + +if (empty($pageid)) +{ + require_once DOL_DOCUMENT_ROOT.'/websites/class/website.class.php'; + require_once DOL_DOCUMENT_ROOT.'/websites/class/websitepage.class.php'; + + $object=new Website($db); + $object->fetch(0, $website); + + $objectpage=new WebsitePage($db); + $array=$objectpage->fetchAll($object->id); + + if (count($array) > 0) + { + $firstrep=reset($array); + $pageid=$firstrep->id; + } +} + + +// Security: Delete string ../ into $original_file +global $dolibarr_main_data_root; + +if ($pageid == 'css') +{ + $original_file=$dolibarr_main_data_root.'/websites/'.$website.'/styles.css'; +} +else +{ + $original_file=$dolibarr_main_data_root.'/websites/'.$website.'/page'.$pageid.'.tpl.php'; +} + +// Find the subdirectory name as the reference +$refname=basename(dirname($original_file)."/"); + +// Security: +// Limite acces si droits non corrects +if (! $accessallowed) +{ + accessforbidden(); +} + +// Security: +// On interdit les remontees de repertoire ainsi que les pipe dans +// les noms de fichiers. +if (preg_match('/\.\./',$original_file) || preg_match('/[<>|]/',$original_file)) +{ + dol_syslog("Refused to deliver file ".$original_file); + $file=basename($original_file); // Do no show plain path of original_file in shown error message + dol_print_error(0,$langs->trans("ErrorFileNameInvalid",$file)); + exit; +} + +clearstatcache(); + +$filename = basename($original_file); + +// Output file on browser +dol_syslog("index.php include $original_file $filename content-type=$type"); +$original_file_osencoded=dol_osencode($original_file); // New file name encoded in OS encoding charset + +// This test if file exists should be useless. We keep it to find bug more easily +if (! file_exists($original_file_osencoded)) +{ + dol_print_error(0,$langs->trans("ErrorFileDoesNotExists",$original_file)); + exit; +} + +include_once $original_file_osencoded; + +if (is_object($db)) $db->close(); diff --git a/htdocs/resource/add.php b/htdocs/resource/add.php index 679ef545442..cf13c79560f 100644 --- a/htdocs/resource/add.php +++ b/htdocs/resource/add.php @@ -1,7 +1,7 @@ - * Copyright (C) 2015 Alexandre Spangaro - * Copyright (C) 2015 Laurent Destailleur +/* Copyright (C) 2013 Jean-François Ferry + * Copyright (C) 2015 Alexandre Spangaro + * Copyright (C) 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 @@ -18,15 +18,14 @@ */ /** - * \file resource/add.php - * \ingroup resource - * \brief Page to manage resource object - * Initialy built by build_class_from_table on 2013-07-24 16:03 + * \file resource/add.php + * \ingroup resource + * \brief Page to manage resource object */ require '../main.inc.php'; -require_once DOL_DOCUMENT_ROOT.'/resource/class/resource.class.php'; +require_once DOL_DOCUMENT_ROOT.'/resource/class/dolresource.class.php'; require_once DOL_DOCUMENT_ROOT.'/resource/class/html.formresource.class.php'; // Load traductions files required by page @@ -36,15 +35,15 @@ $langs->load("other"); $langs->load("resource"); // Get parameters -$id = GETPOST('id','int'); -$action = GETPOST('action','alpha'); -$cancel = GETPOST('cancel','alpha'); +$id = GETPOST('id','int'); +$action = GETPOST('action','alpha'); +$cancel = GETPOST('cancel','alpha'); if (empty($sortorder)) $sortorder="DESC"; if (empty($sortfield)) $sortfield="t.rowid"; if (empty($arch)) $arch = 0; if ($page == -1) { - $page = 0 ; + $page = 0 ; } $limit = $conf->global->limit; @@ -56,60 +55,60 @@ $pagenext = $page + 1; // Protection if external user if ($user->societe_id > 0) { - accessforbidden(); + accessforbidden(); } -$object = new Resource($db); +$object = new DolResource($db); if ($action == 'confirm_add_resource') { - if (! $cancel) - { - $error=''; + if (! $cancel) + { + $error=''; - $ref=GETPOST('ref','alpha'); - $description=GETPOST('description','alpha'); - $fk_code_type_resource=GETPOST('fk_code_type_resource','alpha'); + $ref=GETPOST('ref','alpha'); + $description=GETPOST('description','alpha'); + $fk_code_type_resource=GETPOST('fk_code_type_resource','alpha'); - if (empty($ref)) - { - $mesg=$langs->trans("ErrorFieldRequired",$langs->transnoentities("Ref")); - setEventMessages($mesg, null, 'errors'); - $error++; - } + if (empty($ref)) + { + $mesg=$langs->trans("ErrorFieldRequired",$langs->transnoentities("Ref")); + setEventMessages($mesg, null, 'errors'); + $error++; + } - if (! $error) - { - $object=new Resource($db); - $object->ref=$ref; - $object->description=$description; - $object->fk_code_type_resource=$fk_code_type_resource; + if (! $error) + { + $object=new Dolresource($db); + $object->ref=$ref; + $object->description=$description; + $object->fk_code_type_resource=$fk_code_type_resource; - $result=$object->create($user); - if ($result > 0) - { - // Creation OK - $db->commit(); - setEventMessages($langs->trans('ResourceCreatedWithSuccess'), null, 'mesgs'); - Header("Location: card.php?id=" . $object->id); - return; - } - else - { - // Creation KO - setEventMessages($object->error, $object->errors, 'errors'); - $action = ''; - } - } - else - { - $action = ''; - } - } - else - { - Header("Location: list.php"); - } + $result=$object->create($user); + if ($result > 0) + { + // Creation OK + $db->commit(); + setEventMessages($langs->trans('ResourceCreatedWithSuccess'), null, 'mesgs'); + Header("Location: card.php?id=" . $object->id); + return; + } + else + { + // Creation KO + setEventMessages($object->error, $object->errors, 'errors'); + $action = ''; + } + } + else + { + $action = ''; + } + } + else + { + Header("Location: list.php"); + } } @@ -122,58 +121,58 @@ $formresource = new FormResource($db); if (! $action) { - $pagetitle=$langs->trans('AddResource'); - llxHeader('',$pagetitle,''); - print load_fiche_titre($pagetitle,'','title_generic'); + $pagetitle=$langs->trans('AddResource'); + llxHeader('',$pagetitle,''); + print load_fiche_titre($pagetitle,'','title_generic'); - print ''; - print ''; + print ''; + print ''; - dol_fiche_head(''); + dol_fiche_head(''); - print '
'.(! empty($remaintopay)?price($remaintopay,0,$langs):' ').''.price($totalarray['totalvat']).''.price($totalarray['totalttc']).''.price($totalarray['totalam']).''.price($totalarray['totalrtp']).'
'.$langs->trans("SocialContributions").' ('.$langs->trans("Type").' 0)
'.$langs->trans("SocialContributionsNondeductibles").'
'.$langs->trans("SocialContributions").' ('.$langs->trans("Type").' 1)
'.$langs->trans("SocialContributionsDeductibles").'
'.$langs->trans("Total").''.price($qtytotal).' '.price($catotal_ht).''.price($catotal).'  situation_counter == 1 || !$this->situation_cycle_ref) { + if (($this->situation_counter == 1 || !$this->situation_cycle_ref) && empty($disableremove)) { print 'id . '">'; print img_delete(); print ''; diff --git a/htdocs/core/tpl/resource_add.tpl.php b/htdocs/core/tpl/resource_add.tpl.php index e2add5fb266..482dad50085 100644 --- a/htdocs/core/tpl/resource_add.tpl.php +++ b/htdocs/core/tpl/resource_add.tpl.php @@ -13,7 +13,7 @@ $out .= ''; $out .= ''; $out .= ''; $out .= ''; -$out .= ''; +$out .= ''; // Place diff --git a/htdocs/custom/README.md b/htdocs/custom/README.md index 5f15148f685..82f92dfbeff 100644 --- a/htdocs/custom/README.md +++ b/htdocs/custom/README.md @@ -14,11 +14,9 @@ Then create the symbolic link ln -fs ~/git/newmodule/htdocs /path_to_dolibarr/htdocs/custom/newmodule WARNING !!! -You must also enable the custom directory into dolibarr conf/conf.php file by adding the following +Check also that the custom directory into dolibarr conf/conf.php file by adding the following two lines, so dolibarr will also scan this directories to find external external modules: $dolibarr_main_url_root_alt='/custom'; $dolibarr_main_document_root_alt='/path_to_dolibarr/htdocs/custom/'; -(This is not enabled by default because enabling external module may slow down application) - diff --git a/htdocs/document.php b/htdocs/document.php index 1b3d494d1a1..52b1584e7af 100644 --- a/htdocs/document.php +++ b/htdocs/document.php @@ -65,6 +65,7 @@ $entity=GETPOST('entity')?GETPOST('entity','int'):$conf->entity; // Security check if (empty($modulepart)) accessforbidden('Bad value for parameter modulepart'); +if ($modulepart == 'fckeditor') $modulepart='medias'; // For backward compatibility $socid=0; if ($user->societe_id > 0) $socid = $user->societe_id; @@ -97,7 +98,7 @@ if (preg_match('/\.(html|htm)$/i',$original_file)) $attachment = false; if (isset($_GET["attachment"])) $attachment = GETPOST("attachment")?true:false; if (! empty($conf->global->MAIN_DISABLE_FORCE_SAVEAS)) $attachment=false; -// Suppression de la chaine de caractere ../ dans $original_file +// Security: Delete string ../ into $original_file $original_file = str_replace("../","/", $original_file); // Find the subdirectory name as the reference @@ -169,7 +170,6 @@ if (! file_exists($original_file_osencoded)) } // Permissions are ok and file found, so we return it - header('Content-Description: File Transfer'); if ($encoding) header('Content-Encoding: '.$encoding); if ($type) header('Content-Type: '.$type.(preg_match('/text/',$type)?'; charset="'.$conf->file->character_set_client:'')); @@ -183,7 +183,7 @@ header('Pragma: public'); //ob_clean(); //flush(); - + readfile($original_file_osencoded); if (is_object($db)) $db->close(); diff --git a/htdocs/expedition/card.php b/htdocs/expedition/card.php index 4547a94566a..c52c72ff509 100644 --- a/htdocs/expedition/card.php +++ b/htdocs/expedition/card.php @@ -533,6 +533,12 @@ if (empty($reshook)) $object->set_billed(); } + elseif ($action == 'classifyclosed') + { + $object->fetch($id); + $object->setClosed(); + } + include DOL_DOCUMENT_ROOT.'/core/actions_printing.inc.php'; // Actions to send emails @@ -885,6 +891,7 @@ if ($action == 'create') //ship from preselected location $stock = + $product->stock_warehouse[$warehouse_id]->real; // Convert to number $deliverableQty=min($quantityToBeDelivered, $stock); + if ($deliverableQty < 0) $deliverableQty = 0; if (empty($conf->productbatch->enabled) || ! ($product->hasbatch() && is_object($product->stock_warehouse[$warehouse_id]))) { // Quantity to send @@ -1774,16 +1781,19 @@ else if ($id || $ref) { print ''.$langs->trans("CreateDeliveryOrder").''; } - // Close if (! empty($conf->facture->enabled) && $object->statut > 0) { if ($user->rights->expedition->creer && $object->statut > 0 && ! $object->billed) { - $label="Close"; + $label="Close"; $paramaction='classifyclosed'; // = Transferred/Received // Label here should be "Close" or "ClassifyBilled" if we decided to make bill on shipments instead of orders - if (! empty($conf->global->WORKFLOW_BILL_ON_SHIPMENT)) $label="ClassifyBilled"; - print ''.$langs->trans($label).''; + if (! empty($conf->global->WORKFLOW_BILL_ON_SHIPMENT)) // TODO Quand l'option est on, il faut avoir le bouton en plus et non en remplacement du Close. + { + $label="ClassifyBilled"; + $paramaction='classifybilled'; + } + print ''.$langs->trans($label).''; } } diff --git a/htdocs/expedition/class/expedition.class.php b/htdocs/expedition/class/expedition.class.php index a0ba1567c24..18b3d4d7ebc 100644 --- a/htdocs/expedition/class/expedition.class.php +++ b/htdocs/expedition/class/expedition.class.php @@ -664,7 +664,7 @@ class Expedition extends CommonObject $langs->load("agenda"); // Loop on each product line to add a stock movement - // TODO possibilite d'expedier a partir d'une propale ou autre origine + // TODO in future, shipment lines may not be linked to order line $sql = "SELECT cd.fk_product, cd.subprice,"; $sql.= " ed.rowid, ed.qty, ed.fk_entrepot,"; $sql.= " edb.rowid as edbrowid, edb.eatby, edb.sellby, edb.batch, edb.qty as edbqty, edb.fk_origin_stock"; @@ -738,7 +738,7 @@ class Expedition extends CommonObject if (! $error && ! $notrigger) { // Call trigger - $result=$this->call_trigger('SHIPPING_VALIDATE',$user); + $result=$this->call_trigger('SHIPPING_VALIDATE',$user); // TODO Add option in workflow module on this trigger to close order if sum of shipment = product to ship of order if ($result < 0) { $error++; } // End call triggers } @@ -878,16 +878,14 @@ class Expedition extends CommonObject $product=new Product($this->db); $result=$product->fetch($fk_product); - $product_type=$product->type; if ($entrepot_id > 0) { - $product->load_stock(); - $product_stock = $product->stock_warehouse[$entrepot_id]->real; + $product->load_stock(); + $product_stock = $product->stock_warehouse[$entrepot_id]->real; } - else - { - $product_stock = $product->stock_reel; - } - + else + $product_stock = $product->stock_reel; + + $product_type=$product->type; if ($product_type == 0 && $product_stock < $qty) { $this->error=$langs->trans('ErrorStockIsNotEnough'); @@ -1795,11 +1793,11 @@ class Expedition extends CommonObject } /** - * Classify the shipping as invoiced + * Classify the shipping as closed * * @return int <0 if ko, >0 if ok */ - function set_billed() + function setClosed() { global $conf; @@ -1809,7 +1807,32 @@ class Expedition extends CommonObject $resql=$this->db->query($sql); if ($resql) { - //TODO: Add option/checkbox to set order billed if 100% of order is shipped + // TODO: Add option/checkbox to set order billed if 100% of order is shipped + $this->statut=2; + return 1; + } + else + { + dol_print_error($this->db); + return -1; + } + } + + /** + * Classify the shipping as invoiced (used when WORKFLOW_BILL_ON_SHIPMENT is on) + * + * @return int <0 if ko, >0 if ok + */ + function set_billed() + { + global $conf; + + $sql = 'UPDATE '.MAIN_DB_PREFIX.'expedition SET fk_statut=2, billed=1'; // TODO Update only billed + $sql .= ' WHERE rowid = '.$this->id.' AND fk_statut > 0'; + + $resql=$this->db->query($sql); + if ($resql) + { $this->statut=2; $this->billed=1; return 1; diff --git a/htdocs/expensereport/card.php b/htdocs/expensereport/card.php index be9d8ab49bd..a946649592a 100644 --- a/htdocs/expensereport/card.php +++ b/htdocs/expensereport/card.php @@ -1625,7 +1625,7 @@ else $sql.= ' ctf.code as type_fees_code, ctf.label as type_fees_libelle,'; $sql.= ' pjt.rowid as projet_id, pjt.title as projet_title, pjt.ref as projet_ref'; $sql.= ' FROM '.MAIN_DB_PREFIX.'expensereport_det as fde'; - $sql.= ' INNER JOIN '.MAIN_DB_PREFIX.'c_type_fees as ctf ON fde.fk_c_type_fees=ctf.id'; + $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_type_fees as ctf ON fde.fk_c_type_fees=ctf.id'; $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'projet as pjt ON fde.fk_projet=pjt.rowid'; $sql.= ' WHERE fde.fk_expensereport = '.$object->id; @@ -1691,7 +1691,7 @@ else } print ''.$langs->trans("TF_".strtoupper($objp->type_fees_libelle)).''.$langs->trans("TF_".strtoupper(empty($objp->type_fees_libelle)?'OTHER':$objp->type_fees_libelle)).''.$objp->comments.''.vatrate($objp->vatrate,true).''.price($objp->value_unit).'
'; - print ''; - print '
'; print $langs->trans("ProductAccountancySellCode"); - print '
'; print '
'; - print length_accountg($object->accountancy_code_sell); - print '
'; - print ''; - print '
'; print $langs->trans("ProductAccountancyBuyCode"); - print '
'; print '
'; - print length_accountg($object->accountancy_code_buy); + if (! empty($conf->accounting->enabled)) { + print length_accountg($object->accountancy_code_buy); + } else { + print $object->accountancy_code_buy; + } print '
'; + print ' '; + print ''.$form->selectyesno($search_tobatch, '', '', '', 1).'  '.$form->selectyesno($search_tobatch, '', '', '', 1).'
'; if ($objp->fk_product_type != 1) { - $product_static->id = $objp->rowid; - $product_static->load_stock(); + print $objp->seuil_stock_alerte; } - } - + print ''; - print yn($objp->tobatch); - print ''; if ($objp->fk_product_type != 1) { - if ($product_static->stock_reel < $objp->seuil_stock_alerte) print img_warning($langs->trans("StockTooLow")).' '; + if ($objp->seuil_stock_alerte != '' && $product_static->stock_reel < (float) $objp->seuil_stock_alerte) print img_warning($langs->trans("StockTooLow")).' '; print $product_static->stock_reel; } print ''; + if ($objp->fk_product_type != 1) + { + if ($objp->seuil_stock_alerte != '' && $product_static->stock_theorique < (float) $objp->seuil_stock_alerte) print img_warning($langs->trans("StockTooLow")).' '; + print $product_static->stock_theorique; + } + print ''; + print yn($objp->tobatch); + print ''.$objp->accountancy_code_sell.''; print ''; print ''; print ' '; print '      '; @@ -334,9 +342,10 @@ if ($resql) //print ''.$objp->stock_theorique.''.$objp->seuil_stock_alerte.''.$objp->desiredstock.''; - if ($objp->seuil_stock_alerte && ($objp->stock_physique < $objp->seuil_stock_alerte)) print img_warning($langs->trans("StockTooLow")).' '; - print $product->stock_reel; + if ($objp->seuil_stock_alerte != '' && ($objp->stock_physique < $objp->seuil_stock_alerte)) print img_warning($langs->trans("StockTooLow")).' '; + print $objp->stock_physique; print ''; + if ($objp->seuil_stock_alerte != '' && ($product->stock_theorique < $objp->seuil_stock_alerte)) print img_warning($langs->trans("StockTooLow")).' '; + print $product->stock_theorique; + print ''.$langs->trans("Movements").''.$product->LibStatut($objp->statut,5,0).''.$product->LibStatut($objp->tobuy,5,1).'
'.$entrepotstatic->getNomUrl(1).''.$obj->reel.($obj->reel<0?' '.img_warning():'').''.$stock_real.($stock_real < 0 ?' '.img_warning():'').''.(price2num($object->pmp)?price2num($object->pmp,'MU'):'').''.$prod->getNomUrl(1, '', 16).''.$prod->getNomUrl(1, '').'' . $objp->label . '
'; + print '
'; - // Ref / label - $field = 'ref'; - print ''; - print ''; - print ''; - print ''; + // Ref / label + $field = 'ref'; + print ''; + print ''; + print ''; + print ''; - // Type - print ''; - print ''; + // Type + print ''; + print ''; - // Description - $field = 'description'; - print ''; - print ''; - print ''; - print ''; + // Description + $field = 'description'; + print ''; + print ''; + print ''; + print ''; - print '
'; - print $langs->trans('ResourceFormLabel_'.$field); - print ''; - print ''; - print '
'; + print $langs->trans('ResourceFormLabel_'.$field); + print ''; + print ''; + print '
'.$langs->trans("ResourceType").''; - $ret = $formresource->select_types_resource($object->fk_code_type_resource, 'fk_code_type_resource', '', 2, 1); - print '
'.$langs->trans("ResourceType").''; + $ret = $formresource->select_types_resource($object->fk_code_type_resource, 'fk_code_type_resource', '', 2, 1); + print '
'; - print $langs->trans('ResourceFormLabel_'.$field); - print ''; - require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php'; - $doleditor = new DolEditor($field, $$field, 160, '', '', false); - $doleditor->Create(); - print '
'; + print $langs->trans('ResourceFormLabel_'.$field); + print ''; + require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php'; + $doleditor = new DolEditor($field, $$field, 160, '', '', false); + $doleditor->Create(); + print '
'; + print ''; - dol_fiche_end(''); + dol_fiche_end(''); - echo '
', - '', - '   ', - '', - '
'; + echo '
', + '', + '   ', + '', + '
'; - print ''; + print ''; } diff --git a/htdocs/resource/card.php b/htdocs/resource/card.php index 31fb6a955b1..163eeab13ce 100644 --- a/htdocs/resource/card.php +++ b/htdocs/resource/card.php @@ -29,7 +29,7 @@ if (! $res) $res=@include("../../main.inc.php"); // For "custom" directory if (! $res) die("Include of main fails"); require_once DOL_DOCUMENT_ROOT.'/contact/class/contact.class.php'; -require_once 'class/resource.class.php'; +require_once 'class/dolresource.class.php'; require_once 'class/html.formresource.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/resource.lib.php'; @@ -56,7 +56,7 @@ if ($user->societe_id > 0) if( ! $user->rights->resource->read) accessforbidden(); -$object = new Resource($db); +$object = new Dolresource($db); $hookmanager->initHooks(array('resource_card','globalcard')); $parameters=array('resource_id'=>$id); @@ -152,7 +152,7 @@ $formresource = new FormResource($db); if ( $object->fetch($id) > 0 ) { - $head=resourcePrepareHead($object); + $head=resource_prepare_head($object); if ($action == 'edit' ) diff --git a/htdocs/resource/class/resource.class.php b/htdocs/resource/class/dolresource.class.php similarity index 99% rename from htdocs/resource/class/resource.class.php rename to htdocs/resource/class/dolresource.class.php index bfd4f04c3e5..b6b4eec8be2 100644 --- a/htdocs/resource/class/resource.class.php +++ b/htdocs/resource/class/dolresource.class.php @@ -1,5 +1,5 @@ +/* Copyright (C) 2013-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 @@ -28,7 +28,7 @@ require_once DOL_DOCUMENT_ROOT."/core/lib/functions2.lib.php"; /** * DAO Resource object */ -class Resource extends CommonObject +class Dolresource extends CommonObject { var $element='resource'; //!< Id that identify managed objects var $table_element='resource'; //!< Name of table without prefix where object is stored @@ -414,7 +414,7 @@ class Resource extends CommonObject while ($i < $num) { $obj = $this->db->fetch_object($resql); - $line = new Resource($this->db); + $line = new Dolresource($this->db); $line->id = $obj->rowid; $line->ref = $obj->ref; $line->description = $obj->description; @@ -488,7 +488,7 @@ class Resource extends CommonObject while ($i < $num) { $obj = $this->db->fetch_object($resql); - $line = new Resource($this->db); + $line = new Dolresource($this->db); $line->id = $obj->rowid; $line->resource_id = $obj->resource_id; $line->resource_type = $obj->resource_type; @@ -574,7 +574,7 @@ class Resource extends CommonObject while ($i < $num) { $obj = $this->db->fetch_object($resql); - $line = new Resource($this->db); + $line = new Dolresource($this->db); $line->id = $obj->rowid; $line->resource_id = $obj->resource_id; $line->resource_type = $obj->resource_type; diff --git a/htdocs/resource/class/html.formresource.class.php b/htdocs/resource/class/html.formresource.class.php index 4128de6fead..82b0ebe7d1a 100644 --- a/htdocs/resource/class/html.formresource.class.php +++ b/htdocs/resource/class/html.formresource.class.php @@ -1,5 +1,5 @@ +/* Copyright (C) - 2013-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 @@ -17,7 +17,7 @@ */ /** - * \file place/class/html.place.class.php + * \file place/class/html.formresource.class.php * \ingroup core * \brief Class file to manage forms into resource module */ @@ -75,7 +75,7 @@ class FormResource $out=''; $outarray=array(); - $resourcestat = new Resource($this->db); + $resourcestat = new Dolresource($this->db); $resources_used = $resourcestat->fetch_all('ASC', 't.rowid', $limit, $offset, $filter=''); @@ -159,7 +159,7 @@ class FormResource { global $langs,$user; - $resourcestat = new Resource($this->db); + $resourcestat = new Dolresource($this->db); dol_syslog(get_class($this)."::select_types_resource ".$selected.", ".$htmlname.", ".$filtertype.", ".$format,LOG_DEBUG); diff --git a/htdocs/resource/contact.php b/htdocs/resource/contact.php new file mode 100644 index 00000000000..d635ee2e1e6 --- /dev/null +++ b/htdocs/resource/contact.php @@ -0,0 +1,159 @@ + + * Copyright (C) 2007-2009 Laurent Destailleur + * Copyright (C) 2012 Juanjo Menent + * Copyright (C) 2016 Gilles Poirier + + * + * 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/resource/contact.php + * \ingroup resource + * \brief Onglet de gestion des contacts des resources + */ + +require '../main.inc.php'; +require_once DOL_DOCUMENT_ROOT.'/resource/class/dolresource.class.php'; +require_once DOL_DOCUMENT_ROOT.'/contact/class/contact.class.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/resource.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/core/class/html.formcompany.class.php'; + +$langs->load("resource"); +$langs->load("sendings"); +$langs->load("companies"); + +$id = GETPOST('id','int'); +$ref = GETPOST('ref', 'alpha'); +$action = GETPOST('action','alpha'); + +// Security check +if ($user->societe_id) $socid=$user->societe_id; +$result = restrictedArea($user, 'resource', $id, 'resource'); + +$object = new DolResource($db); +$result = $object->fetch($id,$ref); + + +/* + * Ajout d'un nouveau contact + */ + +if ($action == 'addcontact' && $user->rights->resource->write) +{ + if ($result > 0 && $id > 0) + { + $contactid = (GETPOST('userid','int') ? GETPOST('userid','int') : GETPOST('contactid','int')); + $result = $object->add_contact($contactid, GETPOST('type','int'), GETPOST('source','alpha')); + } + + if ($result >= 0) + { + header("Location: ".$_SERVER['PHP_SELF']."?id=".$object->id); + exit; + } + else + { + if ($object->error == 'DB_ERROR_RECORD_ALREADY_EXISTS') { + $langs->load("errors"); + $mesg = $langs->trans("ErrorThisContactIsAlreadyDefinedAsThisType"); + } else { + $mesg = $object->error; + } + + setEventMessage($mesg, 'errors'); + } +} + +// bascule du statut d'un contact +else if ($action == 'swapstatut' && $user->rights->resource->write) +{ + $result=$object->swapContactStatus(GETPOST('ligne','int')); +} + +// Efface un contact +else if ($action == 'deletecontact' && $user->rights->resource->write) +{ + $result = $object->delete_contact(GETPOST('lineid','int')); + + if ($result >= 0) + { + header("Location: ".$_SERVER['PHP_SELF']."?id=".$object->id); + exit; + } + else { + dol_print_error($db); + } +} + + +/* + * View + */ + +$form = new Form($db); +$formcompany = new FormCompany($db); +$contactstatic=new Contact($db); +$userstatic=new User($db); + +llxHeader('',$langs->trans("Resource")); + +// Mode vue et edition + +if ($id > 0 || ! empty($ref)) +{ + $soc = new Societe($db); + $soc->fetch($object->socid); + + + $head = resource_prepare_head($object); + dol_fiche_head($head, 'contact', $langs->trans("ResourceSingular"), 0, 'resource@resource'); + + + /* + * Resource synthese pour rappel + */ + print ''; + + print ''; + print ''; + + // Resource type + print ''; + print ''; + print ''; + print ''; + + print '
'.$langs->trans("ResourceFormLabel_ref").''; + $linkback = $objet->ref.' '.$langs->trans("BackToList").''; + print $form->showrefnav($object, 'id', $linkback,1,"rowid"); + print '
' . $langs->trans("ResourceType") . ''; + print $object->type_label; + print '
'; + print '
'; + + print '
'; + + if (! empty($conf->global->RESOURCE_HIDE_ADD_CONTACT_USER)) $hideaddcontactforuser=1; + if (! empty($conf->global->RESOURCE_HIDE_ADD_CONTACT_THIPARTY)) $hideaddcontactforthirdparty=1; + + $permission=1; + // Contacts lines + include DOL_DOCUMENT_ROOT.'/core/tpl/contacts.tpl.php'; +} + + +llxFooter(); +$db->close(); diff --git a/htdocs/resource/document.php b/htdocs/resource/document.php new file mode 100644 index 00000000000..a21bc88c319 --- /dev/null +++ b/htdocs/resource/document.php @@ -0,0 +1,141 @@ + + * Copyright (C) 2004-2010 Laurent Destailleur + * Copyright (C) 2005 Marc Barilley / Ocebo + * Copyright (C) 2005-2009 Regis Houssin + * Copyright (C) 2005 Simon TOSSER + * Copyright (C) 2011-2012 Juanjo Menent + * Copyright (C) 2013 Cédric Salvador + * Copyright (C) 2016 Gilles Poirier + * + * 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/resource/document.php + * \ingroup resource + * \brief Page des documents joints sur les resources + */ + +require '../main.inc.php'; +require_once DOL_DOCUMENT_ROOT.'/resource/class/dolresource.class.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/images.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/resource.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php'; + +$langs->load("other"); +$langs->load("resource"); +$langs->load("companies"); + +$id = GETPOST('id','int'); +$ref = GETPOST('ref', 'alpha'); +$action = GETPOST('action','alpha'); +$confirm = GETPOST('confirm','alpha'); + +// Security check +if ($user->societe_id) $socid=$user->societe_id; +$result = restrictedArea($user, 'resource', $id, 'resource'); + + +// Get parameters +$sortfield = GETPOST('sortfield','alpha'); +$sortorder = GETPOST('sortorder','alpha'); +$page = GETPOST('page','int'); +if ($page == -1) { $page = 0; } +$offset = $conf->liste_limit * $page; +$pageprev = $page - 1; +$pagenext = $page + 1; +if (! $sortorder) $sortorder="ASC"; +if (! $sortfield) $sortfield="name"; + + +$object = new DolResource($db); +$object->fetch($id, $ref); + +$upload_dir = $conf->resource->dir_output.'/'.dol_sanitizeFileName($object->ref); +$modulepart='resource'; + + +/* + * Actions + */ + +include_once DOL_DOCUMENT_ROOT . '/core/actions_linkedfiles.inc.php'; + + +/* + * View + */ + +$form = new Form($db); + +llxHeader('',$langs->trans("Resource")); + +if ($object->id) +{ + $object->fetch_thirdparty(); + + $head=resource_prepare_head($object); + + dol_fiche_head($head, 'documents', $langs->trans("ResourceSingular"), 0, 'resource'); + + + // Construit liste des fichiers + $filearray=dol_dir_list($upload_dir,"files",0,'','(\.meta|_preview\.png)$',$sortfield,(strtolower($sortorder)=='desc'?SORT_DESC:SORT_ASC),1); + $totalsize=0; + foreach($filearray as $key => $file) + { + $totalsize+=$file['size']; + } + + + print ''; + + + print ''; + print ''; + + // Resource type + print ''; + print ''; + print ''; + print ''; + + print ''; + print ''; + print '
'.$langs->trans("ResourceFormLabel_ref").''; + $linkback = $objet->ref.' '.$langs->trans("BackToList").''; + print $form->showrefnav($object, 'id', $linkback,1,"rowid"); + print '
' . $langs->trans("ResourceType") . ''; + print $object->type_label; + print '
'.$langs->trans("NbOfAttachedFiles").''.count($filearray).'
'.$langs->trans("TotalSizeOfAttachedFiles").''.$totalsize.' '.$langs->trans("bytes").'
'; + + print '
'; + + $modulepart = 'dolresource'; + $permission = $user->rights->resource->write; + $param = '&id=' . $object->id; + include_once DOL_DOCUMENT_ROOT . '/core/tpl/document_actions_post_headers.tpl.php'; + +} +else +{ + print $langs->trans("ErrorUnknown"); +} + + +llxFooter(); + +$db->close(); diff --git a/htdocs/resource/element_resource.php b/htdocs/resource/element_resource.php index e4477e1674a..59a95f6f57a 100644 --- a/htdocs/resource/element_resource.php +++ b/htdocs/resource/element_resource.php @@ -1,5 +1,6 @@ +/* Copyright (C) 2013 Jean-François Ferry + * Copyright (C) 2016 Gilles Poirier * * 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 @@ -16,18 +17,18 @@ */ /** - * \file resource/element_resource.php - * \ingroup resource - * \brief Page to show and manage linked resources to an element + * \file resource/element_resource.php + * \ingroup resource + * \brief Page to show and manage linked resources to an element */ $res=0; -$res=@include("../main.inc.php"); // For root directory -if (! $res) $res=@include("../../main.inc.php"); // For "custom" directory +$res=@include("../main.inc.php"); // For root directory +if (! $res) $res=@include("../../main.inc.php"); // For "custom" directory if (! $res) die("Include of main fails"); -require 'class/resource.class.php'; +require 'class/dolresource.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php'; // Load traductions files requiredby by page @@ -35,92 +36,92 @@ $langs->load("resource"); $langs->load("other"); /* -$sortorder = GETPOST('sortorder','alpha'); -$sortfield = GETPOST('sortfield','alpha'); -$page = GETPOST('page','int'); +$sortorder = GETPOST('sortorder','alpha'); +$sortfield = GETPOST('sortfield','alpha'); +$page = GETPOST('page','int'); */ if( ! $user->rights->resource->read) - accessforbidden(); + accessforbidden(); -$object=new Resource($db); +$object=new Dolresource($db); $hookmanager->initHooks(array('element_resource')); -$object->available_resources = array('resource'); +$object->available_resources = array('dolresource'); // Get parameters -$id = GETPOST('id','int'); -$action = GETPOST('action','alpha'); -$mode = GETPOST('mode','alpha'); -$lineid = GETPOST('lineid','int'); -$element = GETPOST('element','alpha'); // element_type -$element_id = GETPOST('element_id','int'); -$resource_id = GETPOST('fk_resource','int'); -$resource_type = GETPOST('resource_type','alpha'); -$busy = GETPOST('busy','int'); -$mandatory = GETPOST('mandatory','int'); -$cancel = GETPOST('cancel','alpha'); -$confirm = GETPOST('confirm','alpha'); -$socid = GETPOST('socid','int'); +$id = GETPOST('id','int'); +$action = GETPOST('action','alpha'); +$mode = GETPOST('mode','alpha'); +$lineid = GETPOST('lineid','int'); +$element = GETPOST('element','alpha'); // element_type +$element_id = GETPOST('element_id','int'); +$resource_id = GETPOST('fk_resource','int'); +$resource_type = GETPOST('resource_type','alpha'); +$busy = GETPOST('busy','int'); +$mandatory = GETPOST('mandatory','int'); +$cancel = GETPOST('cancel','alpha'); +$confirm = GETPOST('confirm','alpha'); +$socid = GETPOST('socid','int'); -if ($socid > 0) +if ($socid > 0) { $element_id = $socid; $element = 'societe'; } - - + + /* * Actions */ if ($action == 'add_element_resource' && ! $cancel) { - $error++; - $res = 0; - if (! ($resource_id > 0)) - { - $error++; + $error++; + $res = 0; + if (! ($resource_id > 0)) + { + $error++; setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Resource")), null, 'errors'); $action=''; - } - else - { + } + else + { $objstat = fetchObjectByElement($element_id, $element); - + $res = $objstat->add_element_resource($resource_id, $resource_type, $busy, $mandatory); - } - if (! $error && $res > 0) - { - setEventMessages($langs->trans('ResourceLinkedWithSuccess'), null, 'mesgs'); - header("Location: ".$_SERVER['PHP_SELF'].'?element='.$element.'&element_id='.$element_id); - exit; - } + } + if (! $error && $res > 0) + { + setEventMessages($langs->trans('ResourceLinkedWithSuccess'), null, 'mesgs'); + header("Location: ".$_SERVER['PHP_SELF'].'?element='.$element.'&element_id='.$element_id); + exit; + } } // Update ressource if ($action == 'update_linked_resource' && $user->rights->resource->write && !GETPOST('cancel') ) { - $res = $object->fetch_element_resource($lineid); - if($res) - { - $object->busy = $busy; - $object->mandatory = $mandatory; + $res = $object->fetch_element_resource($lineid); + if($res) + { + $object->busy = $busy; + $object->mandatory = $mandatory; - $result = $object->update_element_resource($user); + $result = $object->update_element_resource($user); - if ($result >= 0) - { - setEventMessages($langs->trans('RessourceLineSuccessfullyUpdated'), null, 'mesgs'); - header("Location: ".$_SERVER['PHP_SELF']."?element=".$element."&element_id=".$element_id); - exit; - } - else - { - setEventMessages($object->error, $object->errors, 'errors'); - } - } + if ($result >= 0) + { + setEventMessages($langs->trans('RessourceLineSuccessfullyUpdated'), null, 'mesgs'); + header("Location: ".$_SERVER['PHP_SELF']."?element=".$element."&element_id=".$element_id); + exit; + } + else + { + setEventMessages($object->error, $object->errors, 'errors'); + } + } } // Delete a resource linked to an element @@ -134,7 +135,7 @@ if ($action == 'confirm_delete_linked_resource' && $user->rights->resource->dele header("Location: ".$_SERVER['PHP_SELF']."?element=".$element."&element_id=".$element_id); exit; } - else + else { setEventMessages($object->error, $object->errors, 'errors'); } @@ -164,149 +165,190 @@ llxHeader('',$pagetitle,''); // Load available resource, declared by modules $ret = count($object->available_resources); if($ret == -1) { - dol_print_error($db,$object->error); - exit; + dol_print_error($db,$object->error); + exit; } if(!$ret) { - print '
'.$langs->trans('NoResourceInDatabase').'
'; + print '
'.$langs->trans('NoResourceInDatabase').'
'; } else { - // Confirmation suppression resource line - if ($action == 'delete_resource') - { - print $form->formconfirm("element_resource.php?element=".$element."&element_id=".$element_id."&id=".$id."&lineid=".$lineid,$langs->trans("DeleteResource"),$langs->trans("ConfirmDeleteResourceElement"),"confirm_delete_linked_resource",'','',1); - } + // Confirmation suppression resource line + if ($action == 'delete_resource') + { + print $form->formconfirm("element_resource.php?element=".$element."&element_id=".$element_id."&id=".$id."&lineid=".$lineid,$langs->trans("DeleteResource"),$langs->trans("ConfirmDeleteResourceElement"),"confirm_delete_linked_resource",'','',1); + } + /* + * Specific to agenda module + */ + if ($element_id && $element == 'action') + { + require_once DOL_DOCUMENT_ROOT.'/core/lib/agenda.lib.php'; + + $act = fetchObjectByElement($element_id,$element); + if (is_object($act)) + { + + $head=actions_prepare_head($act); + + dol_fiche_head($head, 'resources', $langs->trans("Action"),0,'action'); + + // Affichage fiche action en mode visu + print ''; + + $linkback = ''.$langs->trans("BackToList").''; + + // Ref + print ''; + + // Type + if (! empty($conf->global->AGENDA_USE_EVENT_TYPE)) + { + print ''; + } + + // Title + print ''; + print '
'.$langs->trans("Ref").''; + print $form->showrefnav($act, 'id', $linkback, ($user->societe_id?0:1), 'id', 'ref', ''); + print '
'.$langs->trans("Type").''.$act->type.'
'.$langs->trans("Title").''.$act->label.'
'; + + dol_fiche_end(); + } + } + + /* + * Specific to thirdparty module + */ + if ($element_id && $element == 'societe') + { + $socstatic = fetchObjectByElement($element_id,$element); + if (is_object($socstatic)) + { + $savobject = $object; + + $object = $socstatic; + + require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php'; + $head = societe_prepare_head($socstatic); + + dol_fiche_head($head, 'resources', $langs->trans("ThirdParty"),0,'company'); + + dol_banner_tab($socstatic, 'socid', '', ($user->societe_id?0:1), 'rowid', 'nom'); + + print '
'; + + print '
'; + print ''; + + // Alias name (commercial, trademark or alias name) + print '"; + + print '
'.$langs->trans('AliasNames').''; + print $socstatic->name_alias; + print "
'; + + print '
'; + + dol_fiche_end(); + + $object = $savobject; + } + } + /* - * Specific to agenda module + * Specific to fichinter module */ - if ($element_id && $element == 'action') + if ($element_id && $element == 'fichinter') { - require_once DOL_DOCUMENT_ROOT.'/core/lib/agenda.lib.php'; + require_once DOL_DOCUMENT_ROOT.'/core/lib/fichinter.lib.php'; - $act = fetchObjectByElement($element_id,$element); - if (is_object($act)) + $fichinter = fetchObjectByElement($element_id, $element); + if (is_object($fichinter)) { - - $head=actions_prepare_head($act); - - dol_fiche_head($head, 'resources', $langs->trans("Action"),0,'action'); + $head=fichinter_prepare_head($fichinter); + dol_fiche_head($head, 'resource', $langs->trans("InterventionCard"),0,'intervention'); // Affichage fiche action en mode visu print ''; - - $linkback = ''.$langs->trans("BackToList").''; + + $linkback = ''.$langs->trans("BackToList").''; // Ref print ''; - // Type - if (! empty($conf->global->AGENDA_USE_EVENT_TYPE)) - { - print ''; - } - // Title - print ''; - print '
'.$langs->trans("Ref").''; - print $form->showrefnav($act, 'id', $linkback, ($user->societe_id?0:1), 'id', 'ref', ''); + print $form->showrefnav($fichinter, 'id', $linkback, ($user->societe_id?0:1), 'ref', 'ref', ''); print '
'.$langs->trans("Type").''.$act->type.'
'.$langs->trans("Title").''.$act->label.'
'; + // Customer + if ( is_null($fichinter->client) ) + $fichinter->fetch_thirdparty(); + + print "".$langs->trans("Company").""; + print ''.$fichinter->client->getNomUrl(1).''; + print ""; dol_fiche_end(); } } - /* - * Specific to thirdparty module - */ - if ($element_id && $element == 'societe') - { - $socstatic = fetchObjectByElement($element_id,$element); - if (is_object($socstatic)) - { - $savobject = $object; - - $object = $socstatic; - - require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php'; - $head = societe_prepare_head($socstatic); - dol_fiche_head($head, 'resources', $langs->trans("ThirdParty"),0,'company'); + // hook for other elements linked + $parameters=array('element'=>$element, 'element_id'=>$element_id ); + $reshook=$hookmanager->executeHooks('printElementTab',$parameters,$object,$action); // Note that $action and $object may have been modified by some hooks + if ($reshook < 0) setEventMessages($hookmanager->error, $hookmanager->errors, 'errors'); - dol_banner_tab($socstatic, 'socid', '', ($user->societe_id?0:1), 'rowid', 'nom'); - - print '
'; - - print '
'; - print ''; - - // Alias name (commercial, trademark or alias name) - print '"; - - print '
'.$langs->trans('AliasNames').''; - print $socstatic->name_alias; - print "
'; - print '
'; - - dol_fiche_end(); - - $object = $savobject; - } - } + //print load_fiche_titre($langs->trans('ResourcesLinkedToElement'),'',''); - //print load_fiche_titre($langs->trans('ResourcesLinkedToElement'),'',''); + foreach ($object->available_resources as $modresources => $resources) + { + $resources=(array) $resources; // To be sure $resources is an array + foreach($resources as $resource_obj) + { + $element_prop = getElementProperties($resource_obj); + + //print '/'.$modresources.'/class/'.$resource_obj.'.class.php
'; + + $path = ''; + if(strpos($resource_obj,'@')) + $path .= '/'.$element_prop['module']; + + $linked_resources = $object->getElementResources($element,$element_id,$resource_obj); - - foreach ($object->available_resources as $modresources => $resources) - { - $resources=(array) $resources; // To be sure $resources is an array - foreach($resources as $resource_obj) - { - $element_prop = getElementProperties($resource_obj); - - //print '/'.$modresources.'/class/'.$resource_obj.'.class.php
'; - - $path = ''; - if(strpos($resource_obj,'@')) - $path .= '/'.$element_prop['module']; - - $linked_resources = $object->getElementResources($element,$element_id,$resource_obj); - - - // If we have a specific template we use it - if(file_exists(dol_buildpath($path.'/core/tpl/resource_'.$element_prop['element'].'_add.tpl.php'))) - { - $res=include dol_buildpath($path.'/core/tpl/resource_'.$element_prop['element'].'_add.tpl.php'); - } - else - { - $res=include DOL_DOCUMENT_ROOT . '/core/tpl/resource_add.tpl.php'; - } + // If we have a specific template we use it + if(file_exists(dol_buildpath($path.'/core/tpl/resource_'.$element_prop['element'].'_add.tpl.php'))) + { + $res=include dol_buildpath($path.'/core/tpl/resource_'.$element_prop['element'].'_add.tpl.php'); + } + else + { + $res=include DOL_DOCUMENT_ROOT . '/core/tpl/resource_add.tpl.php'; + } //var_dump($element_id); - if ($mode != 'add' || $resource_obj != $resource_type) - { - //print load_fiche_titre($langs->trans(ucfirst($element_prop['element']).'Singular')); + if ($mode != 'add' || $resource_obj != $resource_type) + { + //print load_fiche_titre($langs->trans(ucfirst($element_prop['element']).'Singular')); - // If we have a specific template we use it - if(file_exists(dol_buildpath($path.'/core/tpl/resource_'.$element_prop['element'].'_view.tpl.php'))) - { - $res=@include dol_buildpath($path.'/core/tpl/resource_'.$element_prop['element'].'_view.tpl.php'); + // If we have a specific template we use it + if(file_exists(dol_buildpath($path.'/core/tpl/resource_'.$element_prop['element'].'_view.tpl.php'))) + { + $res=@include dol_buildpath($path.'/core/tpl/resource_'.$element_prop['element'].'_view.tpl.php'); - } - else - { - $res=include DOL_DOCUMENT_ROOT . '/core/tpl/resource_view.tpl.php'; - } - } - } - } + } + else + { + $res=include DOL_DOCUMENT_ROOT . '/core/tpl/resource_view.tpl.php'; + } + } + } + } } llxFooter(); diff --git a/htdocs/resource/list.php b/htdocs/resource/list.php index 9bfa7309167..b33bbec259e 100644 --- a/htdocs/resource/list.php +++ b/htdocs/resource/list.php @@ -1,5 +1,5 @@ +/* Copyright (C) 2013-2014 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 @@ -16,34 +16,34 @@ */ /** - * \file resource/index.php - * \ingroup resource - * \brief Page to manage resource objects + * \file resource/index.php + * \ingroup resource + * \brief Page to manage resource objects */ require '../main.inc.php'; -require_once DOL_DOCUMENT_ROOT.'/resource/class/resource.class.php'; +require_once DOL_DOCUMENT_ROOT.'/resource/class/dolresource.class.php'; -// Load translations files requiredby by page +// Load translations files required by page $langs->load("resource"); $langs->load("companies"); $langs->load("other"); // Get parameters -$id = GETPOST('id','int'); -$action = GETPOST('action','alpha'); +$id = GETPOST('id','int'); +$action = GETPOST('action','alpha'); -$lineid = GETPOST('lineid','int'); -$element = GETPOST('element','alpha'); -$element_id = GETPOST('element_id','int'); -$resource_id = GETPOST('resource_id','int'); +$lineid = GETPOST('lineid','int'); +$element = GETPOST('element','alpha'); +$element_id = GETPOST('element_id','int'); +$resource_id = GETPOST('resource_id','int'); -$sortorder = GETPOST('sortorder','alpha'); -$sortfield = GETPOST('sortfield','alpha'); -$page = GETPOST('page','int'); +$sortorder = GETPOST('sortorder','alpha'); +$sortfield = GETPOST('sortfield','alpha'); +$page = GETPOST('page','int'); -$object = new Resource($db); +$object = new Dolresource($db); $hookmanager->initHooks(array('resource_list')); @@ -52,7 +52,7 @@ if (empty($sortfield)) $sortfield="t.rowid"; if (empty($arch)) $arch = 0; if ($page == -1) { - $page = 0 ; + $page = 0 ; } $limit = GETPOST('limit')?GETPOST('limit','int'):$conf->liste_limit; @@ -61,7 +61,7 @@ $pageprev = $page - 1; $pagenext = $page + 1; if( ! $user->rights->resource->read) - accessforbidden(); + accessforbidden(); /* @@ -86,72 +86,69 @@ llxHeader('',$pagetitle,''); // Confirmation suppression resource line if ($action == 'delete_resource') { - print $form->formconfirm($_SERVER['PHP_SELF']."?element=".$element."&element_id=".$element_id."&lineid=".$lineid,$langs->trans("DeleteResource"),$langs->trans("ConfirmDeleteResourceElement"),"confirm_delete_resource",'','',1); + print $form->formconfirm($_SERVER['PHP_SELF']."?element=".$element."&element_id=".$element_id."&lineid=".$lineid,$langs->trans("DeleteResource"),$langs->trans("ConfirmDeleteResourceElement"),"confirm_delete_resource",'','',1); } // Load object list $ret = $object->fetch_all($sortorder, $sortfield, $limit, $offset); if($ret == -1) { - dol_print_error($db,$object->error); - exit; + dol_print_error($db,$object->error); + exit; } else { print_barre_liste($pagetitle, $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, '', $ret+1, $object->num_all,'title_generic.png'); } if(!$ret) { - print '
'.$langs->trans('NoResourceInDatabase').'
'; + print '
'.$langs->trans('NoResourceInDatabase').'
'; } else { - $var=true; + $var=true; - print ''."\n"; - print ''; - print_liste_field_titre($langs->trans('Id'),$_SERVER['PHP_SELF'],'t.rowid','',$param,'',$sortfield,$sortorder); - print_liste_field_titre($langs->trans('Ref'),$_SERVER['PHP_SELF'],'t.ref','',$param,'',$sortfield,$sortorder); - print_liste_field_titre($langs->trans('ResourceType'),$_SERVER['PHP_SELF'],'ty.code','',$param,'',$sortfield,$sortorder); - print_liste_field_titre($langs->trans('Action'),"","","","",'width="60" align="center"',"",""); - print "\n"; + print '
'."\n"; + print ''; + print_liste_field_titre($langs->trans('Id'),$_SERVER['PHP_SELF'],'t.rowid','',$param,'',$sortfield,$sortorder); + print_liste_field_titre($langs->trans('Ref'),$_SERVER['PHP_SELF'],'t.ref','',$param,'',$sortfield,$sortorder); + print_liste_field_titre($langs->trans('ResourceType'),$_SERVER['PHP_SELF'],'ty.code','',$param,'',$sortfield,$sortorder); + print_liste_field_titre($langs->trans('Action'),"","","","",'width="60" align="center"',"",""); + print "\n"; - foreach ($object->lines as $resource) - { - $var=!$var; + foreach ($object->lines as $resource) + { + $var=!$var; - $style=''; - if($resource->id == GETPOST('lineid')) - $style='style="background: orange;"'; + $style=''; + if($resource->id == GETPOST('lineid')) + $style='style="background: orange;"'; - print ''; + print ''; - print ''; + print ''; - print ''; + print ''; - print ''; + print ''; - print ''; - } + print ''; + } - print '
'; - print ''.$resource->id.''; - print '
'; + print ''.$resource->id.''; + print ''; - print $resource->ref; - print ''; + print $resource->ref; + print ''; - print $resource->type_label; - print ''; + print $resource->type_label; + print ''; - print ''; - print img_edit(); - print ''; - print ' '; - print ''; - print img_delete(); - print ''; - print ''; + print ''; + print img_edit(); + print ''; + print ' '; + print ''; + print img_delete(); + print ''; + print '
'; + print ''; } - llxFooter(); $db->close(); - - diff --git a/htdocs/resource/note.php b/htdocs/resource/note.php new file mode 100644 index 00000000000..e404a3bdef8 --- /dev/null +++ b/htdocs/resource/note.php @@ -0,0 +1,91 @@ + + * Copyright (C) 2011-2012 Juanjo Menent + * Copyright (C) 2013 Florian Henry + * Copyright (C) 2016 Gilles Poirier + * + * 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/resource/note.php + * \ingroup fichinter + * \brief Fiche d'information sur une resource + */ + +require '../main.inc.php'; +require_once DOL_DOCUMENT_ROOT.'/resource/class/dolresource.class.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/resource.lib.php'; + +$langs->load('companies'); +$langs->load("interventions"); + +$id = GETPOST('id','int'); +$ref = GETPOST('ref', 'alpha'); +$action=GETPOST('action','alpha'); + +// Security check +if ($user->societe_id) $socid=$user->societe_id; +$result = restrictedArea($user, 'resource', $id, 'resource'); + +$object = new DolResource($db); +$object->fetch($id,$ref); + +$permissionnote=$user->rights->resource->write; // Used by the include of actions_setnotes.inc.php + +/* + * Actions + */ + +include DOL_DOCUMENT_ROOT.'/core/actions_setnotes.inc.php'; // Must be include, not includ_once + + +/* + * View + */ + +llxHeader(); + +$form = new Form($db); + +if ($id > 0 || ! empty($ref)) +{ + $head = resource_prepare_head($object); + dol_fiche_head($head, 'note', $langs->trans('ResourceSingular'), 0, 'resource@resource'); + + print ''; + print ''; + print ''; + + // Resource type + print ''; + print ''; + print ''; + print ''; print "
'.$langs->trans("ResourceFormLabel_ref").''; + $linkback = $objet->ref.' '.$langs->trans("BackToList").''; + print $form->showrefnav($object, 'id', $linkback,1,"rowid"); + print '
' . $langs->trans("ResourceType") . ''; + print $object->type_label; + print '
"; + + print '
'; + $permission=$user->rights->resource->write; + $cssclass='titlefield'; + include DOL_DOCUMENT_ROOT.'/core/tpl/notes.tpl.php'; + + dol_fiche_end(); +} + +llxFooter(); +$db->close(); diff --git a/htdocs/societe/class/api_contact.class.php b/htdocs/societe/class/api_contact.class.php index ba7c0d4a211..5144c000b4d 100644 --- a/htdocs/societe/class/api_contact.class.php +++ b/htdocs/societe/class/api_contact.class.php @@ -251,7 +251,7 @@ class ContactApi extends DolibarrApi * * @param int $id Contact ID * @return integer - * + * * @url DELETE contact/{id} */ function delete($id) { diff --git a/htdocs/societe/class/societe.class.php b/htdocs/societe/class/societe.class.php index 17f96a93c3c..62364c57644 100644 --- a/htdocs/societe/class/societe.class.php +++ b/htdocs/societe/class/societe.class.php @@ -832,7 +832,10 @@ class Societe extends CommonObject $sql .= ",prefix_comm = ".(! empty($this->prefix_comm)?"'".$this->db->escape($this->prefix_comm)."'":"null"); $sql .= ",fk_effectif = ".(! empty($this->effectif_id)?"'".$this->db->escape($this->effectif_id)."'":"null"); - $sql .= ",fk_stcomm='".$this->stcomm_id."'"; + if (isset($this->stcomm_id)) + { + $sql .= ",fk_stcomm='".$this->stcomm_id."'"; + } $sql .= ",fk_typent = ".(! empty($this->typent_id)?"'".$this->db->escape($this->typent_id)."'":"0"); $sql .= ",fk_forme_juridique = ".(! empty($this->forme_juridique_code)?"'".$this->db->escape($this->forme_juridique_code)."'":"null"); @@ -848,7 +851,7 @@ class Societe extends CommonObject $sql .= ",barcode = ".(! empty($this->barcode)?"'".$this->db->escape($this->barcode)."'":"null"); $sql .= ",default_lang = ".(! empty($this->default_lang)?"'".$this->db->escape($this->default_lang)."'":"null"); $sql .= ",logo = ".(! empty($this->logo)?"'".$this->db->escape($this->logo)."'":"null"); - $sql .= ",outstanding_limit= '".($this->outstanding_limit!=''?$this->outstanding_limit:'null')."'"; + $sql .= ",outstanding_limit= ".($this->outstanding_limit!=''?$this->outstanding_limit:'null'); $sql .= ",fk_prospectlevel='".$this->fk_prospectlevel."'"; $sql .= ",webservices_url = ".(! empty($this->webservices_url)?"'".$this->db->escape($this->webservices_url)."'":"null"); diff --git a/htdocs/societe/soc.php b/htdocs/societe/soc.php index eedcd449c0d..02543d46993 100644 --- a/htdocs/societe/soc.php +++ b/htdocs/societe/soc.php @@ -783,10 +783,14 @@ else $modCodeFournisseur = new $module; // Define if customer/prospect or supplier status is set or not - if (GETPOST("type")!='f' && empty($conf->global->THIRDPARTY_NOTCUSTOMERPROSPECT_BY_DEFAULT)) { $object->client=3; } - if (GETPOST("type")=='c') { $object->client=1; } + if (GETPOST("type")!='f') + { + $object->client=-1; + if (! empty($conf->global->THIRDPARTY_CUSTOMERPROSPECT_BY_DEFAULT)) { $object->client=3; } + } + if (GETPOST("type")=='c') { $object->client=3; } // Prospect / Customer if (GETPOST("type")=='p') { $object->client=2; } - if (! empty($conf->fournisseur->enabled) && (GETPOST("type")=='f' || (GETPOST("type")=='' && empty($conf->global->THIRDPARTY_NOTSUPPLIER_BY_DEFAULT)))) { $object->fournisseur=1; } + if (! empty($conf->fournisseur->enabled) && (GETPOST("type")=='f' || (GETPOST("type")=='' && ! empty($conf->global->THIRDPARTY_SUPPLIER_BY_DEFAULT)))) { $object->fournisseur=1; } $object->name = GETPOST('name', 'alpha'); $object->firstname = GETPOST('firstname', 'alpha'); @@ -983,8 +987,9 @@ else // Prospect/Customer print ''.fieldLabel('ProspectCustomer','customerprospect',1).''; - print ''; if (GETPOST("type") == '') print ''; if (empty($conf->global->SOCIETE_DISABLE_PROSPECTS)) print ''; if (empty($conf->global->SOCIETE_DISABLE_PROSPECTS) && empty($conf->global->SOCIETE_DISABLE_CUSTOMERS)) print ''; @@ -1008,7 +1013,9 @@ else // Supplier print ''; print ''.fieldLabel('Supplier','fournisseur',1).''; - print $form->selectyesno("fournisseur", (isset($_POST['fournisseur'])?GETPOST('fournisseur'):(GETPOST("type") == '' ? -1 : $object->fournisseur)), 1, 0, (GETPOST("type") == '' ? 1 : 0)); + $default = -1; + if (! empty($conf->global->THIRDPARTY_SUPPLIER_BY_DEFAULT)) $default=1; + print $form->selectyesno("fournisseur", (isset($_POST['fournisseur'])?GETPOST('fournisseur'):(GETPOST("type") == '' ? $default : $object->fournisseur)), 1, 0, (GETPOST("type") == '' ? 1 : 0)); print ''; print ''.fieldLabel('SupplierCode','supplier_code').''; print '
'; diff --git a/htdocs/theme/eldy/ckeditor/config.js b/htdocs/theme/eldy/ckeditor/config.js index cffaadfba6e..cf7163671a3 100644 --- a/htdocs/theme/eldy/ckeditor/config.js +++ b/htdocs/theme/eldy/ckeditor/config.js @@ -32,14 +32,12 @@ CKEDITOR.editorConfig = function( config ) ['Cut','Copy','Paste','PasteText','PasteFromWord','-','Print', 'SpellChecker', 'Scayt'], ['Undo','Redo','-','Find','Replace','-','SelectAll','RemoveFormat'], ['Form', 'Checkbox', 'Radio', 'TextField', 'Textarea', 'Select', 'Button', 'ImageButton', 'HiddenField'], - '/', ['Bold','Italic','Underline','Strike','-','Subscript','Superscript'], ['NumberedList','BulletedList','-','Outdent','Indent','Blockquote','CreateDiv'], ['JustifyLeft','JustifyCenter','JustifyRight','JustifyBlock'], ['BidiLtr', 'BidiRtl'], ['Link','Unlink','Anchor'], ['Image','Flash','Table','HorizontalRule','Smiley','SpecialChar','PageBreak','Iframe'], - '/', ['Styles','Format','Font','FontSize'], ['TextColor','BGColor'], ['Maximize', 'ShowBlocks','-','About'] diff --git a/htdocs/theme/eldy/style.css.php b/htdocs/theme/eldy/style.css.php index 59238e786f1..162310f4697 100644 --- a/htdocs/theme/eldy/style.css.php +++ b/htdocs/theme/eldy/style.css.php @@ -350,7 +350,7 @@ legend { margin-bottom: 8px; } fieldset { border: 1px solid #AAAAAA !important; } -.button, input[name="sbmtConnexion"] { +.button, .buttonDelete, input[name="sbmtConnexion"] { font-family: ; border-color: #c5c5c5; border-color: rgba(0, 0, 0, 0.15) rgba(0, 0, 0, 0.15) rgba(0, 0, 0, 0.25); @@ -383,17 +383,17 @@ fieldset { border: 1px solid #AAAAAA !important; } -moz-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05); box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05); } -.button:focus { +.button:focus, .buttonDelete:focus { -moz-box-shadow: 0px 0px 6px 1px rgba(0, 0, 60, 0.2), 0px 0px 0px rgba(60,60,60,0.1); -webkit-box-shadow: 0px 0px 6px 1px rgba(0, 0, 60, 0.2), 0px 0px 0px rgba(60,60,60,0.1); box-shadow: 0px 0px 6px 1px rgba(0, 0, 60, 0.2), 0px 0px 0px rgba(60,60,60,0.1); } -.button:hover { +.button:hover, .buttonDelete:hover { -moz-box-shadow: 0px 0px 6px 1px rgba(0, 0, 0, 0.2), 0px 0px 0px rgba(60,60,60,0.1); -webkit-box-shadow: 0px 0px 6px 1px rgba(0, 0, 0, 0.2), 0px 0px 0px rgba(60,60,60,0.1); box-shadow: 0px 0px 6px 1px rgba(0, 0, 0, 0.2), 0px 0px 0px rgba(60,60,60,0.1); } -.button:disabled { +.button:disabled, .buttonDelete:disabled { opacity: 0.4; filter: alpha(opacity=40); /* For IE8 and earlier */ box-shadow: none; @@ -1907,31 +1907,16 @@ span.butAction, span.butActionDelete { } .butAction:hover { -/* for bootstrap look - color: #fff; - background-color: #286090; - border-color: #204d74; -*/ -moz-box-shadow: 0px 0px 6px 1px rgba(0, 0, 0, 0.2), 0px 0px 0px rgba(60,60,60,0.1); -webkit-box-shadow: 0px 0px 6px 1px rgba(0, 0, 0, 0.2), 0px 0px 0px rgba(60,60,60,0.1); box-shadow: 0px 0px 6px 1px rgba(0, 0, 0, 0.2), 0px 0px 0px rgba(60,60,60,0.1); } -.butActionDelete, .butActionDelete:link, .butActionDelete:visited, .butActionDelete:hover, .butActionDelete:active { -/* for bootstrap look - color: #fff; - background-color: #d9534f; - border-color: #d43f3a; -*/ - color: #800; +.butActionDelete, .butActionDelete:link, .butActionDelete:visited, .butActionDelete:hover, .butActionDelete:active, .buttonDelete { + color: #800 !important; } .butActionDelete:hover { -/* for bootstrap look - color: #fff; - background-color: #c9302c; - border-color: #ac2925; -*/ -moz-box-shadow: 0px 0px 6px 1px rgba(0, 0, 0, 0.2), 0px 0px 0px rgba(60,60,60,0.1); -webkit-box-shadow: 0px 0px 6px 1px rgba(0, 0, 0, 0.2), 0px 0px 0px rgba(60,60,60,0.1); box-shadow: 0px 0px 6px 1px rgba(0, 0, 0, 0.2), 0px 0px 0px rgba(60,60,60,0.1); @@ -3126,19 +3111,27 @@ td.hidden { .websitebar { border-bottom: 1px solid #888; - height: 30px; + background: #eee; +} +.websitebar .button, .websitebar .buttonDelete +{ + padding: 2px 5px 3px 5px !important; + margin: 2px 4px 2px 4px !important; + line-height: normal; } .websiteselection { display: inline-block; padding-left: 10px; vertical-align: middle; - margin-bottom: 5px; line-height: 29px; } .websitetools { float: right; padding-top: 2px; } +.websiteiframenoborder { + border: 0px; +} /* ============================================================================== */ diff --git a/htdocs/theme/md/ckeditor/config.js b/htdocs/theme/md/ckeditor/config.js index cffaadfba6e..cf7163671a3 100644 --- a/htdocs/theme/md/ckeditor/config.js +++ b/htdocs/theme/md/ckeditor/config.js @@ -32,14 +32,12 @@ CKEDITOR.editorConfig = function( config ) ['Cut','Copy','Paste','PasteText','PasteFromWord','-','Print', 'SpellChecker', 'Scayt'], ['Undo','Redo','-','Find','Replace','-','SelectAll','RemoveFormat'], ['Form', 'Checkbox', 'Radio', 'TextField', 'Textarea', 'Select', 'Button', 'ImageButton', 'HiddenField'], - '/', ['Bold','Italic','Underline','Strike','-','Subscript','Superscript'], ['NumberedList','BulletedList','-','Outdent','Indent','Blockquote','CreateDiv'], ['JustifyLeft','JustifyCenter','JustifyRight','JustifyBlock'], ['BidiLtr', 'BidiRtl'], ['Link','Unlink','Anchor'], ['Image','Flash','Table','HorizontalRule','Smiley','SpecialChar','PageBreak','Iframe'], - '/', ['Styles','Format','Font','FontSize'], ['TextColor','BGColor'], ['Maximize', 'ShowBlocks','-','About'] diff --git a/htdocs/theme/md/style.css.php b/htdocs/theme/md/style.css.php index c45055a96f5..3de39efb50f 100644 --- a/htdocs/theme/md/style.css.php +++ b/htdocs/theme/md/style.css.php @@ -1913,7 +1913,7 @@ span.butAction, span.butActionDelete { background-repeat: repeat-x } -.butActionDelete { +.butActionDelete, .buttonDelete { color: #ffffff !important; text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); background-color: #cc6d00; @@ -2988,19 +2988,27 @@ td.hidden { .websitebar { border-bottom: 1px solid #888; - height: 30px; + background: #eee; +} +.websitebar .button, .websitebar .buttonDelete +{ + padding: 2px 4px 2px 4px !important; + margin: 2px 4px 2px 4px !important; + line-height: normal; } .websiteselection { display: inline-block; padding-left: 10px; vertical-align: middle; - margin-bottom: 5px; line-height: 29px; } .websitetools { float: right; padding-top: 2px; } +.websiteiframenoborder { + border: 0px; +} /* ============================================================================== */ diff --git a/htdocs/user/class/api_user.class.php b/htdocs/user/class/api_user.class.php index d09785d3ccb..af0db5bfb2d 100644 --- a/htdocs/user/class/api_user.class.php +++ b/htdocs/user/class/api_user.class.php @@ -159,8 +159,35 @@ class UserApi extends DolibarrApi if ($this->useraccount->update($id, DolibarrApiAccess::$user, 1, '', '', 'update')) return $this->get($id); - return false; - } + return false; + } + + /** + * add user to group + * + * @param int $id User ID + * @param int $group Group ID + * @return int + * + * @url GET user/{id}/setGroup/{group} + */ + function setGroup($id,$group) { + //if (!DolibarrApiAccess::$user->rights->user->user->supprimer) { + //throw new RestException(401); + //} + $result = $this->useraccount->fetch($id); + if (!$result) + { + throw new RestException(404, 'User not found'); + } + + if (!DolibarrApi::_checkAccessToResource('user', $this->useraccount->id, 'user')) + { + throw new RestException(401, 'Access not allowed for login ' . DolibarrApiAccess::$user->login); + } + + return $this->useraccount->SetInGroup($group,1); + } /** * Delete account diff --git a/htdocs/viewimage.php b/htdocs/viewimage.php index 949884df6e9..585db4c343e 100644 --- a/htdocs/viewimage.php +++ b/htdocs/viewimage.php @@ -62,7 +62,7 @@ $entity=GETPOST('entity')?GETPOST('entity','int'):$conf->entity; // Security check if (empty($modulepart)) accessforbidden('Bad value for parameter modulepart'); - +if ($modulepart == 'fckeditor') $modulepart='medias'; // For backward compatibility /* @@ -95,7 +95,7 @@ $type = 'application/octet-stream'; if (! empty($_GET["type"])) $type=$_GET["type"]; else $type=dol_mimetype($original_file); -// Suppression de la chaine de caractere ../ dans $original_file +// Security: Delete string ../ into $original_file $original_file = str_replace("../","/", $original_file); // Find the subdirectory name as the reference diff --git a/htdocs/webservices/server_productorservice.php b/htdocs/webservices/server_productorservice.php index 43facbb24fa..aa43dbb185c 100644 --- a/htdocs/webservices/server_productorservice.php +++ b/htdocs/webservices/server_productorservice.php @@ -411,7 +411,8 @@ function getProductOrService($authentication,$id='',$ref='',$ref_ext='',$lang='' 'localtax1_tx' => $product->localtax1_tx, 'localtax2_tx' => $product->localtax2_tx, - 'stock_real' => $product->stock_reel, + 'stock_real' => $product->stock_reel, + 'stock_virtual' => $product->stock_theorique, 'stock_alert' => $product->seuil_stock_alerte, 'pmp' => $product->pmp, 'import_key' => $product->import_key, @@ -572,7 +573,7 @@ function createProductOrService($authentication,$product) require_once DOL_DOCUMENT_ROOT.'/product/stock/class/entrepot.class.php'; $savstockreal=$newobject->stock_reel; - $newobject->load_stock(); // This overwrite ->stock_reel + $newobject->load_stock('novirtual,nobatch'); // This overwrite ->stock_reel, surely 0 because we have just created product $getstockreal = $newobject->stock_reel; if ($savstockreal != $getstockreal) @@ -741,7 +742,7 @@ function updateProductOrService($authentication,$product) require_once DOL_DOCUMENT_ROOT.'/product/stock/class/entrepot.class.php'; $savstockreal=$newobject->stock_reel; - $newobject->load_stock(); // This overwrite ->stock_reel + $newobject->load_stock('novirtual,nobatch'); // This overwrite ->stock_reel $getstockreal = $newobject->stock_reel; if ($savstockreal != $getstockreal) diff --git a/htdocs/websites/class/websitepage.class.php b/htdocs/websites/class/websitepage.class.php index ac9adf8f480..b363687765f 100644 --- a/htdocs/websites/class/websitepage.class.php +++ b/htdocs/websites/class/websitepage.class.php @@ -253,13 +253,13 @@ class WebsitePage extends CommonObject /** * Load object in memory from the database * + * @param string $website_id Web site id * @param string $sortorder Sort Order * @param string $sortfield Sort field * @param int $limit limit * @param int $offset Offset * @param array $filter Filter array * @param string $filtermode Filter mode (AND or OR) - * * @return array|int int <0 if KO, array of pages if OK */ public function fetchAll($website_id, $sortorder='', $sortfield='', $limit=0, $offset=0, array $filter = array(), $filtermode='AND') @@ -307,7 +307,7 @@ class WebsitePage extends CommonObject while ($obj = $this->db->fetch_object($resql)) { - $record = new Websitepage($this->db); + $record = new WebsitePage($this->db); $record->id = $obj->rowid; $record->fk_website = $obj->fk_website; @@ -320,7 +320,7 @@ class WebsitePage extends CommonObject $record->date_creation = $this->db->jdate($obj->date_creation); $record->date_modification = $this->db->jdate($obj->date_modification); $record->tms = $this->db->jdate($obj->tms); - + //var_dump($record->id); $records[$record->id] = $record; } $this->db->free($resql); diff --git a/htdocs/websites/index.php b/htdocs/websites/index.php index 58a2981d2da..98efd23f45b 100644 --- a/htdocs/websites/index.php +++ b/htdocs/websites/index.php @@ -1,5 +1,5 @@ +/* Copyright (C) 2016 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 @@ -16,11 +16,14 @@ */ /** - * \file htdocs/admin/website.php + * \file htdocs/website/index.php * \ingroup website - * \brief Page to setup the module Website + * \brief Page to website view/edit */ +define('NOSCANPOSTFORINJECTION',1); +define('NOSTYLECHECK',1); + /** * Show HTML header HTML + BODY + Top menu + left menu + DIV @@ -63,6 +66,7 @@ function llxHeader($head='', $title='', $help_url='', $target='', $disablejs=0, require '../main.inc.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/admin.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; require_once DOL_DOCUMENT_ROOT.'/websites/class/website.class.php'; require_once DOL_DOCUMENT_ROOT.'/websites/class/websitepage.class.php'; @@ -77,11 +81,14 @@ $conf->dol_hide_leftmenu = 1; $error=0; $website=GETPOST('website', 'alpha'); $page=GETPOST('page', 'alpha'); -$pageid=GETPOST('pageid', 'alpha'); +$pageid=GETPOST('pageid', 'int'); $action=GETPOST('action','alpha'); +if (GETPOST('delete')) { $action='delete'; } if (GETPOST('preview')) $action='preview'; if (GETPOST('create')) { $action='create'; } +if (GETPOST('editmedia')) { $action='editmedia'; } +if (GETPOST('editcss')) { $action='editcss'; } if (GETPOST('editmenu')) { $action='editmenu'; } if (GETPOST('editmeta')) { $action='editmeta'; } if (GETPOST('editcontent')) { $action='editcontent'; } @@ -91,15 +98,34 @@ if (empty($action)) $action='preview'; $object=new Website($db); $objectpage=new WebsitePage($db); +$object->fetchAll(); // Init $object->records + +// If website not defined, we take first found +if (empty($website)) +{ + foreach($object->records as $key => $valwebsite) + { + $website=$valwebsite->ref; + break; + } +} if ($website) { $res = $object->fetch(0, $website); } -if ($pageid) + +if ($pageid < 0) $pageid = 0; +if ($pageid > 0 && $action != 'add') { $res = $objectpage->fetch($pageid); } +global $dolibarr_main_data_root; +$pathofwebsite=$dolibarr_main_data_root.'/websites/'.$website; +$filecss=$pathofwebsite.'/styles.css'; +$filetpl=$pathofwebsite.'/page'.$pageid.'.tpl.php'; + + /* * Actions @@ -115,7 +141,7 @@ if ($action == 'add') $objectpage->title = GETPOST('WEBSITE_TITLE'); $objectpage->pageurl = GETPOST('WEBSITE_PAGENAME'); $objectpage->description = GETPOST('WEBSITE_DESCRIPTION'); - $objectpage->keyword = GETPOST('WEBSITE_KEYWORD'); + $objectpage->keywords = GETPOST('WEBSITE_KEYWORD'); if (empty($objectpage->title)) { @@ -186,22 +212,129 @@ if ($action == 'update') } } +// Update page +if ($action == 'delete') +{ + $db->begin(); + + $res = $object->fetch(0, $website); + + $res = $objectpage->fetch($pageid, $object->fk_website); + + if ($res > 0) + { + $res = $objectpage->delete($user); + if (! $res > 0) + { + $error++; + setEventMessages($objectpage->error, $objectpage->errors, 'errors'); + } + + if (! $error) + { + $db->commit(); + setEventMessages($langs->trans("PageDeleted", $objectpage->pageurl, $website), null, 'mesgs'); + + header("Location: ".$_SERVER["PHP_SELF"].'?website='.$website); + exit; + } + else + { + $db->rollback(); + } + } + else + { + dol_print_error($db); + } +} + +// Update css +if ($action == 'updatecss') +{ + $db->begin(); + + $res = $object->fetch(0, $website); + /* + $res = $object->update($user); + if ($res > 0) + { + $db->commit(); + setEventMessages($langs->trans("SetupSaved"), null, 'mesgs'); + $action=''; + } + else + { + $db->rollback(); + }*/ + + $csscontent = GETPOST('WEBSITE_CSS_INLINE'); + + dol_mkdir($pathofwebsite); + file_put_contents($filecss, $csscontent); + if (! empty($conf->global->MAIN_UMASK)) + @chmod($filecss, octdec($conf->global->MAIN_UMASK)); + + $action='preview'; +} + +// Update page +if ($action == 'updatemeta') +{ + $db->begin(); + $object->fetch(0, $website); + + $objectpage->fk_website = $object->id; + + $res = $objectpage->fetch($pageid, $object->fk_website); + if ($res > 0) + { + $objectpage->pageurl = GETPOST('WEBSITE_PAGENAME'); + $objectpage->title = GETPOST('WEBSITE_TITLE'); + $objectpage->description = GETPOST('WEBSITE_DESCRIPTION'); + $objectpage->keywords = GETPOST('WEBSITE_KEYWORDS'); + + $res = $objectpage->update($user); + if (! $res > 0) + { + $error++; + setEventMessages($objectpage->error, $objectpage->errors, 'errors'); + } + + if (! $error) + { + $db->commit(); + setEventMessages($langs->trans("Saved"), null, 'mesgs'); + $action='preview'; + } + else + { + $db->rollback(); + } + } + else + { + dol_print_error($db, 'Page not found'); + } +} + // Update page if ($action == 'updatecontent') { $db->begin(); - $object->fetch(0, $website); - + $objectpage->fk_website = $object->id; - $objectpage->pageurl = GETPOST('WEBSITE_PAGENAME'); - - $res = $objectpage->fetch(0, $object->fk_website, $objectpage->pageurl); + $res = $objectpage->fetch($pageid, $object->fk_website); if ($res > 0) { $objectpage->content = GETPOST('PAGE_CONTENT'); + // Clean data. We remove all the head section. + $objectpage->content = preg_replace('//s', '', $objectpage->content); + /* $objectpage->content = preg_replace('//s', '', $objectpage->content); */ + $res = $objectpage->update($user); if (! $res > 0) { @@ -213,7 +346,15 @@ if ($action == 'updatecontent') { $db->commit(); setEventMessages($langs->trans("Saved"), null, 'mesgs'); - $action=''; + + dol_mkdir($pathofwebsite); + dol_delete_file($filetpl); + file_put_contents($filetpl, $objectpage->content); + if (! empty($conf->global->MAIN_UMASK)) + @chmod($filetpl, octdec($conf->global->MAIN_UMASK)); + + header("Location: ".$_SERVER["PHP_SELF"].'?website='.$website.'&pageid='.$pageid); + exit; } else { @@ -222,7 +363,7 @@ if ($action == 'updatecontent') } else { - dol_print_error($db); + dol_print_error($db, 'Page not found'); } } @@ -244,6 +385,18 @@ if ($action == 'create') { print ''; } +if ($action == 'editcss') +{ + print ''; +} +if ($action == 'editmenu') +{ + print ''; +} +if ($action == 'editmeta') +{ + print ''; +} if ($action == 'editcontent') { print ''; @@ -252,7 +405,6 @@ if ($action == 'edit') { print ''; } -if ($website) print ''; // Add a margin under toolbar ? @@ -262,32 +414,41 @@ if ($action != 'preview' && $action != 'editcontent') $style=' margin-bottom: 5p print '
'; -$tmp = $object->fetchAll(); if (count($object->records) > 0) { print '
'; print $langs->trans("Website").': '; print '
'; + // List of websites print '
'; + $out=''; + $out.=''; + print $out; + print ''; + if ($website) + { + print ''.$langs->trans("ViewInNewTab").''; + } print '
'; + // Button for websites print '
'; if ($action == 'preview') @@ -295,10 +456,18 @@ if (count($object->records) > 0) $disabled=''; if (empty($user->rights->websites->create)) $disabled=' disabled="disabled"'; + //print ''; + print ''; print ''; print ''; } - //else print ''; + + if (in_array($action, array('editcss','editmenu','create'))) + { + if ($action != 'preview') print ''; + if (preg_match('/^create/',$action)) print ''; + if (preg_match('/^edit/',$action)) print ''; + } print '
'; @@ -317,19 +486,24 @@ if (count($object->records) > 0) print '
'; $out=''; $out.=''; print $out; print ''; + print ''; //print $form->selectarray('page', $array); print '
'; print '
'; @@ -344,13 +518,19 @@ if (count($object->records) > 0) if ($pageid > 0) { - print ''; - print ''; + print ''; + print ''; + //print ''.dol_escape_htmltag($langs->trans("EditPageMeta")).''; + //print ''.dol_escape_htmltag($langs->trans("EditPageContent")).''; } } - else print ''; - if (preg_match('/^create/',$action)) print ''; - if (preg_match('/^edit/',$action)) print ''; + + if (! in_array($action, array('editcss','editmenu','create'))) + { + if ($action != 'preview') print ''; + if (preg_match('/^create/',$action)) print ''; + if (preg_match('/^edit/',$action)) print ''; + } print '
'; @@ -375,45 +555,96 @@ $head = array(); * Edit mode */ +if ($action == 'editcss') +{ + print '
'; + + print '
'; + + $csscontent = @file_get_contents($filecss); + + dol_fiche_head(); + + print ''; + + print ''; + + print ''; + + /*print '';*/ + + print '
'; + print $langs->trans('WebSite'); + print ''; + print $website; + print '
'; + print $langs->trans('WEBSITE_CSS_INLINE'); + print ''; + print ''; + print '
'; + print $langs->trans('WEBSITE_CSS_URL'); + print ''; + print ''; + print '
'; + + dol_fiche_end(); + + print '
'; + + print '
'; +} + if ($action == 'editmeta' || $action == 'create') { print '
'; + + print '
'; dol_fiche_head(); print ''; - print ''; - if ($action != 'create') { print ''; + $pageurl=dol_escape_htmltag($objectpage->pageurl); + $pagetitle=dol_escape_htmltag($objectpage->title); + $pagedescription=dol_escape_htmltag($objectpage->description); + $pagekeywords=dol_escape_htmltag($objectpage->keywords); } + if (GETPOST('WEBSITE_PAGENAME')) $pageurl=GETPOST('WEBSITE_PAGENAME'); + if (GETPOST('WEBSITE_TITLE')) $pagetitle=GETPOST('WEBSITE_TITLE'); + if (GETPOST('WEBSITE_DESCRIPTION')) $pagedescription=GETPOST('WEBSITE_DESCRIPTION'); + if (GETPOST('WEBSITE_KEYWORDS')) $pagekeywords=GETPOST('WEBSITE_KEYWORDS'); + + print ''; print ''; print ''; print ''; print '
'; - print $langs->trans('WEBSITE_PAGENAME'); - print ''; - print ''; - print '
'; - print $langs->trans('WEBSITE_URL'); + print $langs->trans('WEBSITE_PAGEURL'); print ''; - print '/public/websites/'.$website.'/index.php?pageid='.urlencode($pageid); + print '/public/websites/index.php?website='.urlencode($website).'&pageid='.urlencode($pageid); print '
'; + print $langs->trans('WEBSITE_PAGENAME'); + print ''; + print ''; + print '
'; print $langs->trans('WEBSITE_TITLE'); print ''; - print ''; + print ''; print '
'; print $langs->trans('WEBSITE_DESCRIPTION'); print ''; - print ''; + print ''; print '
'; print $langs->trans('WEBSITE_KEYWORDS'); print ''; - print ''; + print ''; print '
'; @@ -425,6 +656,11 @@ if ($action == 'editmeta' || $action == 'create') print '
'; } +if ($action == 'editmedia') +{ + print '
'.$langs->trans("FeatureNotYetAvailable").''; +} + if ($action == 'editmenu') { print '
'.$langs->trans("FeatureNotYetAvailable").''; @@ -436,7 +672,7 @@ if ($action == 'editcontent') * Editing global variables not related to a specific theme */ require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php'; - $doleditor=new DolEditor('PAGE_CONTENT',$obj->value,'',160,'dolibarr_notes','',false,false,$conf->fckeditor->enabled,5,60); + $doleditor=new DolEditor('PAGE_CONTENT',$objectpage->content,'',500,'Full','',true,true,true,5,60); $doleditor->Create(); } @@ -450,10 +686,45 @@ if ($action == 'preview') { $objectpage->fetch($pageid); - print ''."\n"; - print '
'; - print $objectpage->content; - print '
'; + print "\n".''."\n"; + + + $csscontent = @file_get_contents($filecss); + + $out=''; + + $out.='
'."\n"; + + $out.=''."\n"; + + $out.=$objectpage->content."\n"; + + $out.='
'; + + print $out; + + /*file_put_contents($filetpl, $out); + if (! empty($conf->global->MAIN_UMASK)) + @chmod($filetpl, octdec($conf->global->MAIN_UMASK)); + + // Output file on browser + dol_syslog("index.php include $filetpl $filename content-type=$type"); + $original_file_osencoded=dol_osencode($filetpl); // New file name encoded in OS encoding charset + + // This test if file exists should be useless. We keep it to find bug more easily + if (! file_exists($original_file_osencoded)) + { + dol_print_error(0,$langs->trans("ErrorFileDoesNotExists",$original_file)); + exit; + } + + //include_once $original_file_osencoded; + */ + + /*print '';*/ } else {