diff --git a/build/docker/Dockerfile b/build/docker/Dockerfile index 4b1df7e0876..9264eed5ef2 100644 --- a/build/docker/Dockerfile +++ b/build/docker/Dockerfile @@ -3,7 +3,7 @@ FROM php:7.2-apache ENV HOST_USER_ID 33 ENV PHP_INI_DATE_TIMEZONE 'UTC' -RUN apt-get update && apt-get install -y libpng-dev libjpeg-dev libldap2-dev libzip-dev zlib1g-dev libicu-dev g++\ +RUN apt-get update && apt-get install -y libpng16-16 libpng-dev libjpeg62-turbo libjpeg62-turbo-dev libldap2-dev zlib1g-dev libicu-dev g++\ && rm -rf /var/lib/apt/lists/* \ && docker-php-ext-configure gd --with-png-dir=/usr --with-jpeg-dir=/usr \ && docker-php-ext-install gd \ @@ -14,7 +14,7 @@ RUN apt-get update && apt-get install -y libpng-dev libjpeg-dev libldap2-dev lib && docker-php-ext-install calendar \ && docker-php-ext-configure intl \ && docker-php-ext-install intl \ - && apt-get autoremove --purge -y libjpeg-dev libldap2-dev zlib1g-dev libicu-dev g++ + && apt-get autoremove --purge -y libpng-dev libjpeg62-turbo-dev libldap2-dev zlib1g-dev libicu-dev g++ RUN mkdir /var/documents RUN chown www-data /var/documents diff --git a/build/docker/docker-compose.yml b/build/docker/docker-compose.yml index 3fe6125a874..cc839810e7f 100644 --- a/build/docker/docker-compose.yml +++ b/build/docker/docker-compose.yml @@ -21,5 +21,12 @@ web: - ../../htdocs:/var/www/html links: - mariadb + - mail ports: - "80:80" + +mail: + image: maildev/maildev + ports: + - "8081:80" + - "25:25" \ No newline at end of file diff --git a/htdocs/bom/bom_card.php b/htdocs/bom/bom_card.php index 48e9c9d965a..c98dee97f51 100644 --- a/htdocs/bom/bom_card.php +++ b/htdocs/bom/bom_card.php @@ -523,7 +523,7 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea $keyforbreak = 'duration'; include DOL_DOCUMENT_ROOT.'/core/tpl/commonfields_view.tpl.php'; - print ''.$langs->trans("TotalCost").''.price($object->total_cost).''; + print ''.$form->textwithpicto($langs->trans("TotalCost"), $langs->trans("BOMTotalCost")).''.price($object->total_cost).''; print ''.$langs->trans("UnitCost").''.price($object->unit_cost).''; // Other attributes diff --git a/htdocs/bom/class/bom.class.php b/htdocs/bom/class/bom.class.php index 3e522b3c11f..86e0b84b655 100644 --- a/htdocs/bom/class/bom.class.php +++ b/htdocs/bom/class/bom.class.php @@ -1013,11 +1013,20 @@ class BOM extends CommonObject $this->unit_cost = 0; $this->total_cost = 0; + require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.product.class.php'; + $productFournisseur = new ProductFournisseur($this->db); + foreach ($this->lines as &$line) { $tmpproduct = new Product($this->db); $tmpproduct->fetch($line->fk_product); + $line->unit_cost = price2num((!empty($tmpproduct->cost_price)) ? $tmpproduct->cost_price : $tmpproduct->pmp); + if (empty($line->unit_cost)) { + if ($productFournisseur->find_min_price_product_fournisseur($line->fk_product) > 0) + { + $line->unit_cost = $productFournisseur->fourn_unitprice; + } + } - $line->unit_cost = (!empty($tmpproduct->cost_price)) ? $tmpproduct->cost_price : $tmpproduct->pmp; // TODO : add option to work with cost_price or pmp $line->total_cost = price2num($line->qty * $line->unit_cost, 'MT'); $this->total_cost += $line->total_cost; } diff --git a/htdocs/compta/facture/card.php b/htdocs/compta/facture/card.php index ab2262844bf..038120151e3 100644 --- a/htdocs/compta/facture/card.php +++ b/htdocs/compta/facture/card.php @@ -2907,6 +2907,18 @@ if ($action == 'create') if (!empty($conf->multicurrency->enabled) && !empty($soc->multicurrency_code)) $currency_code = $soc->multicurrency_code; } + // when payment condition is empty (means not override by payment condition form a other object, like third-party), try to use default value + if(empty($cond_reglement_id)) + { + $cond_reglement_id = GETPOST("cond_reglement_id"); + } + + // when payment mode is empty (means not override by payment mode form a other object, like third-party), try to use default value + if(empty($mode_reglement_id)) + { + $mode_reglement_id = GETPOST("mode_reglement_id"); + } + if (!empty($soc->id)) $absolute_discount = $soc->getAvailableDiscounts(); $note_public = $object->getDefaultCreateValueFor('note_public', ((!empty($origin) && !empty($originid) && is_object($objectsrc) && !empty($conf->global->FACTURE_REUSE_NOTES_ON_CREATE_FROM)) ? $objectsrc->note_public : null)); $note_private = $object->getDefaultCreateValueFor('note_private', ((!empty($origin) && !empty($originid) && is_object($objectsrc) && !empty($conf->global->FACTURE_REUSE_NOTES_ON_CREATE_FROM)) ? $objectsrc->note_private : null)); diff --git a/htdocs/contact/list.php b/htdocs/contact/list.php index 9e7485d189f..781daacd030 100644 --- a/htdocs/contact/list.php +++ b/htdocs/contact/list.php @@ -358,7 +358,6 @@ if (strlen($search_fax)) $sql .= natural_search('p.fax', $search_fax) if (!empty($conf->socialnetworks->enabled)) { foreach ($socialnetworks as $key => $value) { if ($value['active'] && strlen($search_{$key})) { - //$sql.= natural_search("p.socialnetworks->'$.".$key."'", $search_{$key}); $sql .= ' AND p.socialnetworks LIKE \'%"'.$key.'":"'.$search_{$key}.'%\''; } } diff --git a/htdocs/core/antispamimage.php b/htdocs/core/antispamimage.php index 68e585c3ea0..7d6512a64a9 100644 --- a/htdocs/core/antispamimage.php +++ b/htdocs/core/antispamimage.php @@ -43,7 +43,7 @@ $number = strlen($letters); $string = ''; for ($i = 0; $i < $length; $i++) { - $string .= $letters{mt_rand(0, $number - 1)}; + $string .= $letters[mt_rand(0, $number - 1)]; } //print $string; diff --git a/htdocs/core/class/lessc.class.php b/htdocs/core/class/lessc.class.php index 210c3d3c29d..8ab9e58aa58 100644 --- a/htdocs/core/class/lessc.class.php +++ b/htdocs/core/class/lessc.class.php @@ -1966,7 +1966,7 @@ class Lessc { $this->pushEnv(); $parser = new lessc_parser($this, __METHOD__); foreach ($args as $name => $strValue) { - if ($name{0} !== '@') { + if ($name[0] !== '@') { $name = '@'.$name; } $parser->count = 0; @@ -2638,7 +2638,7 @@ class lessc_parser { $hidden = true; if (!isset($block->args)) { foreach ($block->tags as $tag) { - if (!is_string($tag) || $tag{0} != $this->lessc->mPrefix) { + if (!is_string($tag) || $tag[0] != $this->lessc->mPrefix) { $hidden = false; break; } @@ -2692,7 +2692,7 @@ class lessc_parser { protected function fixTags($tags) { // move @ tags out of variable namespace foreach ($tags as &$tag) { - if ($tag{0} == $this->lessc->vPrefix) + if ($tag[0] == $this->lessc->vPrefix) $tag[0] = $this->lessc->mPrefix; } return $tags; diff --git a/htdocs/core/lib/security2.lib.php b/htdocs/core/lib/security2.lib.php index 04d16084365..c7f5a7b7330 100644 --- a/htdocs/core/lib/security2.lib.php +++ b/htdocs/core/lib/security2.lib.php @@ -463,15 +463,15 @@ function getRandomPassword($generic = false, $replaceambiguouschars = null, $len { $max = strlen($lowercase) - 1; for ($x = 0; $x < $nbofchar; $x++) { - $randomCode .= $lowercase{random_int(0, $max)}; + $randomCode .= $lowercase[random_int(0, $max)]; } $max = strlen($uppercase) - 1; for ($x = 0; $x < $nbofchar; $x++) { - $randomCode .= $uppercase{random_int(0, $max)}; + $randomCode .= $uppercase[random_int(0, $max)]; } $max = strlen($numbers) - 1; for ($x = 0; $x < $nbofcharlast; $x++) { - $randomCode .= $numbers{random_int(0, $max)}; + $randomCode .= $numbers[random_int(0, $max)]; } $generated_password = str_shuffle($randomCode); @@ -480,15 +480,15 @@ function getRandomPassword($generic = false, $replaceambiguouschars = null, $len { $max = strlen($lowercase) - 1; for ($x = 0; $x < $nbofchar; $x++) { - $randomCode .= $lowercase{mt_rand(0, $max)}; + $randomCode .= $lowercase[mt_rand(0, $max)]; } $max = strlen($uppercase) - 1; for ($x = 0; $x < $nbofchar; $x++) { - $randomCode .= $uppercase{mt_rand(0, $max)}; + $randomCode .= $uppercase[mt_rand(0, $max)]; } $max = strlen($numbers) - 1; for ($x = 0; $x < $nbofcharlast; $x++) { - $randomCode .= $numbers{mt_rand(0, $max)}; + $randomCode .= $numbers[mt_rand(0, $max)]; } $generated_password = str_shuffle($randomCode); @@ -512,11 +512,11 @@ function getRandomPassword($generic = false, $replaceambiguouschars = null, $len $max = strlen($numbers) - 1; if (function_exists('random_int')) // Cryptographic random { - $generated_password = str_replace($replaceambiguouschars, $numbers{random_int(0, $max)}, $generated_password); + $generated_password = str_replace($replaceambiguouschars, $numbers[random_int(0, $max)], $generated_password); } else { - $generated_password = str_replace($replaceambiguouschars, $numbers{mt_rand(0, $max)}, $generated_password); + $generated_password = str_replace($replaceambiguouschars, $numbers[mt_rand(0, $max)], $generated_password); } } diff --git a/htdocs/core/lib/website2.lib.php b/htdocs/core/lib/website2.lib.php index 33093fb953c..776c535d586 100644 --- a/htdocs/core/lib/website2.lib.php +++ b/htdocs/core/lib/website2.lib.php @@ -229,11 +229,11 @@ function dolSavePageContent($filetpl, Website $object, WebsitePage $objectpage) /** - * Save content of the index.php and wrapper.php page + * Save content of the index.php and/or wrapper.php page * * @param string $pathofwebsite Path of website root * @param string $fileindex Full path of file index.php - * @param string $filetpl File tpl to index.php page redirect to + * @param string $filetpl File tpl the index.php page redirect to * @param string $filewrapper Full path of file wrapper.php * @return boolean True if OK */ @@ -246,29 +246,39 @@ function dolSaveIndexPage($pathofwebsite, $fileindex, $filetpl, $filewrapper) dol_mkdir($pathofwebsite); - dol_delete_file($fileindex); - $indexcontent = ''."\n"; - $result1 = file_put_contents($fileindex, $indexcontent); - if (!empty($conf->global->MAIN_UMASK)) { - @chmod($fileindex, octdec($conf->global->MAIN_UMASK)); + if ($fileindex) { + dol_delete_file($fileindex); + $indexcontent = ''."\n"; + + $result1 = file_put_contents($fileindex, $indexcontent); + if (!empty($conf->global->MAIN_UMASK)) { + @chmod($fileindex, octdec($conf->global->MAIN_UMASK)); + } + } + else { + $result1 = true; } - dol_delete_file($filewrapper); - $wrappercontent = file_get_contents(DOL_DOCUMENT_ROOT.'/website/samples/wrapper.php'); + if ($filewrapper) { + dol_delete_file($filewrapper); + $wrappercontent = file_get_contents(DOL_DOCUMENT_ROOT.'/website/samples/wrapper.php'); - $result2 = file_put_contents($filewrapper, $wrappercontent); - if (!empty($conf->global->MAIN_UMASK)) { - @chmod($filewrapper, octdec($conf->global->MAIN_UMASK)); + $result2 = file_put_contents($filewrapper, $wrappercontent); + if (!empty($conf->global->MAIN_UMASK)) { + @chmod($filewrapper, octdec($conf->global->MAIN_UMASK)); + } + } else { + $result2 = true; } return ($result1 && $result2); diff --git a/htdocs/core/lib/xcal.lib.php b/htdocs/core/lib/xcal.lib.php index 440f1147cbf..3d8120a6d29 100644 --- a/htdocs/core/lib/xcal.lib.php +++ b/htdocs/core/lib/xcal.lib.php @@ -334,9 +334,10 @@ function build_calfile($format, $title, $desc, $events_array, $outputfile) * @param string $outputfile Output file * @param string $filter (optional) Filter * @param string $url Url (If empty, forge URL for agenda RSS export) + * @param string $langcode Language code to show in header * @return int < 0 if ko, Nb of events in file if ok */ -function build_rssfile($format, $title, $desc, $events_array, $outputfile, $filter = '', $url = '') +function build_rssfile($format, $title, $desc, $events_array, $outputfile, $filter = '', $url = '', $langcode = '') { global $user, $conf, $langs; global $dolibarr_main_url_root; @@ -362,7 +363,9 @@ function build_rssfile($format, $title, $desc, $events_array, $outputfile, $filt fwrite($fichier, ''); fwrite($fichier, "\n"); - fwrite($fichier, "\n".$title."\n"); + fwrite($fichier, "\n"); + fwrite($fichier, "".$title."\n"); + if ($langcode) fwrite($fichier, "".$langcode."\n"); /* fwrite($fichier, ""."\n". diff --git a/htdocs/fourn/facture/card.php b/htdocs/fourn/facture/card.php index 6e8f259bc01..05cb43fceb8 100644 --- a/htdocs/fourn/facture/card.php +++ b/htdocs/fourn/facture/card.php @@ -1780,6 +1780,18 @@ if ($action == 'create') if (!empty($conf->multicurrency->enabled) && !empty($soc->multicurrency_code)) $currency_code = $soc->multicurrency_code; } + // when payment condition is empty (means not override by payment condition form a other object, like third-party), try to use default value + if(empty($cond_reglement_id)) + { + $cond_reglement_id = GETPOST("cond_reglement_id"); + } + + // when payment mode is empty (means not override by payment condition form a other object, like third-party), try to use default value + if(empty($mode_reglement_id)) + { + $mode_reglement_id = GETPOST("mode_reglement_id"); + } + print '
'; print ''; print ''; diff --git a/htdocs/langs/en_US/mrp.lang b/htdocs/langs/en_US/mrp.lang index d3c4d3253c6..faa8eb60cf4 100644 --- a/htdocs/langs/en_US/mrp.lang +++ b/htdocs/langs/en_US/mrp.lang @@ -74,3 +74,4 @@ ProductsToConsume=Products to consume ProductsToProduce=Products to produce UnitCost=Unit cost TotalCost=Total cost +BOMTotalCost=The cost to produce this BOM based on cost of each quantity and product to consume (use Cost price if defined, else Average Weighted Price if defined, else the Best purchase price) \ No newline at end of file diff --git a/htdocs/langs/en_US/website.lang b/htdocs/langs/en_US/website.lang index 2c555b40c20..6109f3ca879 100644 --- a/htdocs/langs/en_US/website.lang +++ b/htdocs/langs/en_US/website.lang @@ -127,4 +127,6 @@ OtherLanguages=Other languages UseManifest=Provide a manifest.json file PublicAuthorAlias=Public author alias AvailableLanguagesAreDefinedIntoWebsiteProperties=Available languages are defined into website properties -ReplacementDoneInXPages=Replacement done in %s pages or containers \ No newline at end of file +ReplacementDoneInXPages=Replacement done in %s pages or containers +RSSFeed=RSS Feed +RSSFeedDesc=You can get a RSS feed of latest articles with type 'blogpost' using this URL \ No newline at end of file diff --git a/htdocs/variants/class/ProductCombination.class.php b/htdocs/variants/class/ProductCombination.class.php index c3cb5f77a5f..118953c25ad 100644 --- a/htdocs/variants/class/ProductCombination.class.php +++ b/htdocs/variants/class/ProductCombination.class.php @@ -326,16 +326,20 @@ class ProductCombination $child = new Product($this->db); $child->fetch($this->fk_product_child); - $child->price_autogen = $parent->price_autogen; - $child->weight = $parent->weight + $this->variation_weight; - $child->weight_units = $parent->weight_units; + + $child->price_autogen = $parent->price_autogen; + $child->weight = $parent->weight; + if ($this->variation_weight) { // If we must add a delta on weight + $child->weight = ($child->weight ? $child->weight : 0) + $this->variation_weight; + } + $child->weight_units = $parent->weight_units; - // Don't update the child label if the user modified it. - if ($child->label == $parent->label) { + // Don't update the child label if the user has already modified it. + if ($child->label == $parent->label) { // This will trigger only at variant creation time $varlabel = $this->getCombinationLabel($this->fk_product_child); $child->label = $parent->label.$varlabel;; - } + } if ($child->update($child->id, $user) > 0) { $new_vat = $parent->tva_tx; diff --git a/htdocs/website/index.php b/htdocs/website/index.php index 1eef84a1ae7..ed2801c2820 100644 --- a/htdocs/website/index.php +++ b/htdocs/website/index.php @@ -197,6 +197,7 @@ $fileindex = $pathofwebsite.'/index.php'; $filewrapper = $pathofwebsite.'/wrapper.php'; $filemanifestjson = $pathofwebsite.'/manifest.json.php'; $filereadme = $pathofwebsite.'/README.md'; +$filemaster = $pathofwebsite.'/master.inc.php'; // Define $urlwithroot $urlwithouturlroot = preg_replace('/'.preg_quote(DOL_URL_ROOT, '/').'$/i', '', trim($dolibarr_main_url_root)); @@ -1189,8 +1190,6 @@ if ($action == 'updatecss') if (!$error) { // Save master.inc.php file - $filemaster = $pathofwebsite.'/master.inc.php'; - dol_syslog("Save master file ".$filemaster); dol_mkdir($pathofwebsite); @@ -1384,6 +1383,10 @@ if ($action == 'updatecss') } + // Save wrapper.php + $result = dolSaveIndexPage($pathofwebsite, '', '', $filewrapper); + + // Message if no error if (!$error) { @@ -1727,8 +1730,8 @@ if (($action == 'updatesource' || $action == 'updatecontent' || $action == 'conf } else { - $fileindex = $pathofwebsitenew.'/index.php'; $filetpl = $pathofwebsitenew.'/page'.$resultpage->id.'.tpl.php'; + $fileindex = $pathofwebsitenew.'/index.php'; $filewrapper = $pathofwebsitenew.'/wrapper.php'; //var_dump($pathofwebsitenew); @@ -2978,6 +2981,14 @@ if ($action == 'editcss') print ''; + // RSS + print ''; + $htmlhelp = $langs->trans('RSSFeedDesc'); + print $form->textwithpicto($langs->trans('RSSFeed'), $htmlhelp, 1, 'help', '', 0, 2, ''); + print ''; + print '/wrapper.php?rss=1[&l=XX][&limit=123]'; + print ''; + print ''; dol_fiche_end(); diff --git a/htdocs/website/samples/wrapper.php b/htdocs/website/samples/wrapper.php index 25483a36f53..abb2bea0179 100644 --- a/htdocs/website/samples/wrapper.php +++ b/htdocs/website/samples/wrapper.php @@ -12,6 +12,8 @@ $hashp = GETPOST('hashp', 'aZ09'); $modulepart = GETPOST('modulepart', 'aZ09'); $entity = GETPOST('entity', 'int') ?GETPOST('entity', 'int') : $conf->entity; $original_file = GETPOST("file", "alpha"); +$l = GETPOST('l', 'aZ09'); +$limit = GETPOST('limit', 'int'); // Parameters for RSS $rss = GETPOST('rss', 'aZ09'); @@ -90,8 +92,8 @@ if ($rss) { $type = ''; $cachedelay = 0; $filename = $original_file; - $filters = array('type_container'=>'blogpost', 'lang'=>'en_US'); $dir_temp = $conf->website->dir_temp; + include_once DOL_DOCUMENT_ROOT.'/website/class/website.class.php'; include_once DOL_DOCUMENT_ROOT.'/website/class/websitepage.class.php'; $website = new Website($db); @@ -99,7 +101,10 @@ if ($rss) { $website->fetch('', $websitekey); - $MAXNEWS = 20; + $filters = array('type_container'=>'blogpost'); + if ($l) $filters['lang'] = $l; + + $MAXNEWS = ($limit ? $limit : 20); $arrayofblogs = $websitepage->fetchAll($website->id, 'DESC', 'date_creation', $MAXNEWS, 0, $filters); $eventarray = array(); if (is_array($arrayofblogs)) { @@ -151,7 +156,7 @@ if ($rss) { @chmod($outputfiletmp, octdec($conf->global->MAIN_UMASK)); // Write file - $result = build_rssfile($format, $title, $desc, $eventarray, $outputfiletmp, '', $website->virtualhost.'/wrapper.php?rss=1'); + $result = build_rssfile($format, $title, $desc, $eventarray, $outputfiletmp, '', $website->virtualhost.'/wrapper.php?rss=1'.($l ? '&l='.$l : ''), $l); if ($result >= 0) {