From 772ff248c84112eaaa2a820fece6a94c2544dab6 Mon Sep 17 00:00:00 2001 From: sparkyx Date: Tue, 12 Dec 2023 18:30:02 +0100 Subject: [PATCH 01/37] Code : change filename --- include/{payment_middle.inc.php => payment_method.inc.php} | 0 sql/upgrade.sql | 2 ++ 2 files changed, 2 insertions(+) rename include/{payment_middle.inc.php => payment_method.inc.php} (100%) diff --git a/include/payment_middle.inc.php b/include/payment_method.inc.php similarity index 100% rename from include/payment_middle.inc.php rename to include/payment_method.inc.php diff --git a/sql/upgrade.sql b/sql/upgrade.sql index 7d4f8e9d1..9440fefa3 100644 --- a/sql/upgrade.sql +++ b/sql/upgrade.sql @@ -38,3 +38,5 @@ update fiche_detail set ad_value=ad_value where ad_id in (select ad_id from attr insert into parameter values ('MY_REPORT','N') ON CONFLICT DO NOTHING; +update menu_ref set me_file='payment_method.inc.php' where me_code='CFGPAY'; + From 934e0c0a3690113b1dac48dbbbc4dbf497147faf Mon Sep 17 00:00:00 2001 From: sparkyx Date: Tue, 12 Dec 2023 18:31:02 +0100 Subject: [PATCH 02/37] PHP Compatibility --- include/class/document_export.class.php | 2 +- include/recover.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/include/class/document_export.class.php b/include/class/document_export.class.php index 302b85d6b..e1d0a20b5 100644 --- a/include/class/document_export.class.php +++ b/include/class/document_export.class.php @@ -165,7 +165,7 @@ class Document_Export * @param int $reconcilied_operation 1 with receipt of reconcilied operation 2 without them * */ - function export_all($p_array, Progress_Bar $progress,$p_separate=1,$reconcilied_document) + function export_all($p_array, Progress_Bar $progress,$p_separate=1,$reconcilied_document=2) { $this->progress=$this->progress; diff --git a/include/recover.php b/include/recover.php index ed8d7ad47..1e4bee25e 100644 --- a/include/recover.php +++ b/include/recover.php @@ -76,7 +76,7 @@ elseif ($action=="send_email") : if ($valid==true): - $request_id=generate_random_string(SIZE_REQUEST,special: 0); + $request_id=generate_random_string(SIZE_REQUEST, 0); $user_password=generate_random_password(10); // exist a valid request for this user ? $exist_request= $cn->get_array("select request , password from recover_pass From 17302884c0410e24f70f194451ddfd40514cbe53 Mon Sep 17 00:00:00 2001 From: sparkyx Date: Tue, 12 Dec 2023 18:31:13 +0100 Subject: [PATCH 03/37] PHP 8.0 Minimum --- html/install.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/html/install.php b/html/install.php index 9ec75f0a9..d0358d248 100644 --- a/html/install.php +++ b/html/install.php @@ -376,10 +376,10 @@ if (!defined('PHP_VERSION_ID')) { define('PHP_VERSION_ID', ($version[0] * 10000 + $version[1] * 100 )); } -if ( PHP_VERSION_ID < 70400) { - echo $g_failed. " ".phpversion()." ". _("Version PHP trop basse , minimum 7.4"); +if ( PHP_VERSION_ID < 80000) { + echo $g_failed. " ".phpversion()." ". _("Version PHP trop basse , minimum 8.0"); echo '

'; - printf(_("Il est déconseillé de travailler avec une version < 7.4")); + printf(_("Il est déconseillé de travailler avec une version < 8.0")); echo '

'; } else { echo $g_succeed. " Version PHP ".phpversion(); From 51ea645a3dc593bd13d0b20b5db8feba23139b89 Mon Sep 17 00:00:00 2001 From: sparkyx Date: Fri, 15 Dec 2023 19:02:33 +0100 Subject: [PATCH 04/37] cosmetic info password --- html/css/style-classic7.css | 2 +- include/user.inc.php | 17 ++++++++++++----- include/user_detail.inc.php | 2 +- 3 files changed, 14 insertions(+), 7 deletions(-) diff --git a/html/css/style-classic7.css b/html/css/style-classic7.css index 86376d701..9df3f72ee 100644 --- a/html/css/style-classic7.css +++ b/html/css/style-classic7.css @@ -3393,6 +3393,6 @@ li.li-active { */ #info_passid { position:absolute; - background-color: yellow; + background-color: rgba(255,160,122,0.58); color:red; } \ No newline at end of file diff --git a/include/user.inc.php b/include/user.inc.php index dddccd752..c9d7bfa07 100644 --- a/include/user.inc.php +++ b/include/user.inc.php @@ -48,9 +48,9 @@ if ( isset ($_POST["ADD"]) ) $new_user->login=$login; $new_user->email=$http->post('EMAIL',"string",''); - if ( trim($login)=="") + if ( trim($login)=="" || strlen($login)<5) { - alert(_("Le login ne peut pas être vide")); + alert(_("Le login ne peut pas être vide et avoir au moins 5 lettres")); }elseif (count($a_result['msg']) > 0){ // password too weak $msg=''._("Mot de passe inchangé").''; @@ -182,6 +182,7 @@ if ( isset($_REQUEST['det']) && $sbaction=="")
+ @@ -192,9 +193,9 @@ if ( isset($_REQUEST['det']) && $sbaction=="")
- +
@@ -218,8 +219,14 @@ echo HtmlInput::button_action(_("Fermer"), "$('create_user').style.display='none $('input_password').setStyle({border:"red solid 2px"}); return false; } + if ($F('input_login').length < 5) { + smoke.alert(''); + $('input_password').setStyle({border:"red solid 2px"}); + return false; + } return true; } +
@@ -253,7 +260,7 @@ if ( !empty ($a_user) ) { echo ''; echo _('Cherche').Icon_Action::infobulle(22); - echo HtmlInput::filter_table("user", "0,1,2,5","1"); + echo HtmlInput::filter_table("user", "0,1,2,3,5,6","1"); echo ''; echo ''; echo ''; diff --git a/include/user_detail.inc.php b/include/user_detail.inc.php index c84f5602f..3a3c61c8d 100644 --- a/include/user_detail.inc.php +++ b/include/user_detail.inc.php @@ -82,7 +82,7 @@ $it_pass->value=""; From 9ecd10dcb7f5a7c9021f9ac956865953db89e788 Mon Sep 17 00:00:00 2001 From: sparkyx Date: Fri, 15 Dec 2023 19:02:49 +0100 Subject: [PATCH 05/37] Bug cosmetic : when update in a window --- html/js/acc_ledger.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/html/js/acc_ledger.js b/html/js/acc_ledger.js index 5ad1e921b..e9a1184c3 100644 --- a/html/js/acc_ledger.js +++ b/html/js/acc_ledger.js @@ -1245,7 +1245,9 @@ function op_save(obj) parameters: queryString, onFailure: null, onSuccess: function (req){ - if (req.responseText !=='OK') { + remove_waiting_box(); + var answer=req.getElementsByTagName('code'); + if (answer[0] !=='OK') { console.error("D2. op_save") smoke.alert(req.responseText); } From 469735b79ee10ad3aa92f71b27f0914b309b5ecc Mon Sep 17 00:00:00 2001 From: sparkyx Date: Fri, 15 Dec 2023 19:03:24 +0100 Subject: [PATCH 06/37] PHP 8.2 compatibility --- include/admin_repo.inc.php | 1 + include/backup.inc.php | 2 ++ include/class/calendar.class.php | 3 ++- include/class/dossier.class.php | 6 ++++++ include/lib/select_box.class.php | 2 +- 5 files changed, 12 insertions(+), 2 deletions(-) diff --git a/include/admin_repo.inc.php b/include/admin_repo.inc.php index 08bdddff6..1fab37313 100644 --- a/include/admin_repo.inc.php +++ b/include/admin_repo.inc.php @@ -161,6 +161,7 @@ if ( $action == "info" && SYSINFO_DISPLAY == true) { echo phpinfo(INFO_GENERAL | INFO_CONFIGURATION | INFO_MODULES | INFO_ENVIRONMENT | INFO_VARIABLES); $r=ob_get_clean(); $html=new DOMDocument(); + libxml_use_internal_errors(true); $html->loadHTML($r); $nodelist=$html->getElementsByTagName("style"); $nodelist->item(0)->nodeValue=' diff --git a/include/backup.inc.php b/include/backup.inc.php index 6c2667f9c..2be381e00 100644 --- a/include/backup.inc.php +++ b/include/backup.inc.php @@ -73,6 +73,7 @@ if ( isset ($_REQUEST['sa']) ) $database=domaine."dossier".$dossier_number; $filename= str_replace(array('/','\\' ,'<','>','"','[',']',':','*',' ','{','}','&'),'_', $name); $filename= str_replace("__", "_", $filename); + $filename=str_replace(PHP_EOL,'',$filename); $filename.="-".date('Ymd'); $args= " -Fc -Z9 --no-owner -h ".getenv("PGHOST")." -p ".getenv("PGPORT")." ".$database; header('Content-type: application/octet'); @@ -90,6 +91,7 @@ if ( isset ($_REQUEST['sa']) ) $database=domaine."mod".$dossier_number; $filename= str_replace(array('/','\\' ,'<','>','"','[',']',':','*',' ','{','}','&'),'_', $name); $filename= str_replace("__", "_", $filename); + $filename=str_replace(PHP_EOL,'',$filename); $filename.="-".date('Ymd'); $args= " -Fc -Z9 --no-owner -h ".getenv("PGHOST")." -p ".getenv("PGPORT")." ".$database; header('Content-type: bin/x-application'); diff --git a/include/class/calendar.class.php b/include/class/calendar.class.php index bbaa7fc35..d3a5fb962 100644 --- a/include/class/calendar.class.php +++ b/include/class/calendar.class.php @@ -42,6 +42,7 @@ class Calendar var $str_name; // array of tiers for event - follow-up (T: action_gestion) var $title; // array of title for each event - follow-up (T: action_gestion) var $hour ; // array of hour for each event - follow-up (T: action_gestion) + var $default_periode; //default periode function __construct() { @@ -257,7 +258,7 @@ class Calendar { $p_id=$g_user->get_periode(); } - $this->default_periode=$p_id; + $this->default_periode=$p_id; return $p_id; } /** diff --git a/include/class/dossier.class.php b/include/class/dossier.class.php index 46c53e615..251bab7b9 100644 --- a/include/class/dossier.class.php +++ b/include/class/dossier.class.php @@ -44,6 +44,12 @@ class Dossier "desc"=>"dos_description", "max_email"=>'dos_email'); + var $cn; //!< Database connexion + var $dos_id; //!< number of db + var $dos_name; + var $dos_description; + var $dos_email; + function __construct($p_id) { $this->cn=new Database(); // Connect to the repository diff --git a/include/lib/select_box.class.php b/include/lib/select_box.class.php index 56bfb10fb..f5b61a5b9 100644 --- a/include/lib/select_box.class.php +++ b/include/lib/select_box.class.php @@ -38,7 +38,7 @@ class Select_Box private $position; //!< change depending if we are in an absolute block or not protected $style_box; protected $value; - public $style_box; + /** * Default constructor * @param type $p_id javascript DOMid From 4e76a652d3a0c8cc64b560f71bca19c70e3078fb Mon Sep 17 00:00:00 2001 From: sparkyx Date: Fri, 15 Dec 2023 19:03:43 +0100 Subject: [PATCH 07/37] Improve Debug --- include/balance.inc.php | 1 + 1 file changed, 1 insertion(+) diff --git a/include/balance.inc.php b/include/balance.inc.php index 7b186b49d..16ff44ea3 100644 --- a/include/balance.inc.php +++ b/include/balance.inc.php @@ -472,6 +472,7 @@ if ( isset($_GET['view'] ) ) } echo '
input();?> - +
'; + if ( DEBUGNOALYSS>1) echo \Noalyss\Dbg::hidden_info("\$row", $row); // display the summary if ($is_summary==1) { if ( $previous == 1) { From 9a4cfeb2d16d7ed5edbf6e45451b0d2c7d27efcd Mon Sep 17 00:00:00 2001 From: sparkyx Date: Fri, 15 Dec 2023 19:03:53 +0100 Subject: [PATCH 08/37] typo --- include/lib/ac_common.php | 2 +- include/lib/config_file.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/include/lib/ac_common.php b/include/lib/ac_common.php index d65c1ed4f..5aa23874e 100644 --- a/include/lib/ac_common.php +++ b/include/lib/ac_common.php @@ -1444,7 +1444,7 @@ function confirm_with_string($p_ctl_name,$p_car) { $code=generate_random_string($p_car ); $r = HtmlInput::hidden("ctlcode",$code); - $r.=''. $code.''; + $r.=''. $code.''; $ctl=new IText($p_ctl_name); $r.=$ctl->input(); return $r; diff --git a/include/lib/config_file.php b/include/lib/config_file.php index 3aa8a569f..b3d8a9d42 100644 --- a/include/lib/config_file.php +++ b/include/lib/config_file.php @@ -253,7 +253,7 @@ function display_file_config($p_array,$from_setup=1,$p_os=1) print ("// define('NOALYSS_CAPTCHA',true);\r\n"); print ("// Uncomment if you want to activate the possibility to reinitialize;\r\n"); print ("// password by email\r\n"); - print ("// defined('RECOVER','1');\r\n"); + print ("// define ('RECOVER','1');\r\n"); print ("// Uncomment and define if you want to Name of the sender of the email \r\n"); print ("// if you activate the possibility to reinitialize password by email\r\n"); print ("// define('ADMIN_WEB', 'www-data@localhost');\r\n"); From e23270877924dd0ecf46744b6d0cd3475584bfb5 Mon Sep 17 00:00:00 2001 From: sparkyx Date: Fri, 15 Dec 2023 19:04:24 +0100 Subject: [PATCH 09/37] Fix Bug Balance Accountancy --- include/class/acc_balance.class.php | 2 +- .../class/print_ledger_detail_item.class.php | 20 +++++++++---------- include/export/export_balance_csv.php | 17 ++++++++++++---- 3 files changed, 24 insertions(+), 15 deletions(-) diff --git a/include/class/acc_balance.class.php b/include/class/acc_balance.class.php index 074710ba9..f079bcf7d 100644 --- a/include/class/acc_balance.class.php +++ b/include/class/acc_balance.class.php @@ -275,7 +275,7 @@ class Acc_Balance $side_delta=findSide($delta); $a['poste']=""; - $a['label']=sprintf(_("Totaux %s %s"),nbm(abs($delta)),$side_delta); + $a['label']=sprintf(_("Totaux delta %s %s"),nbm(abs($delta)),$side_delta); $a['sum_deb']=$tot_deb; $a['sum_cred']=$tot_cred; $a['solde_deb']=$tot_deb_saldo; diff --git a/include/class/print_ledger_detail_item.class.php b/include/class/print_ledger_detail_item.class.php index 84399c08c..243ef9217 100644 --- a/include/class/print_ledger_detail_item.class.php +++ b/include/class/print_ledger_detail_item.class.php @@ -50,16 +50,16 @@ class Print_Ledger_Detail_Item extends Print_Ledger $this->Ln(20); $high=6; $this->SetFont('DejaVu', '', 6); - $this->Cell(20, $high, _('Date'),0, 'L', false); - $this->Cell(20, $high, _('Numéro interne'), 0, 0, 'L', false); - $this->Cell(50, $high, _('Code'),0,'L',false); - $this->Cell(80, $high, _('Libellé'),0,'L',false); - $this->Cell(20, $high, _('Tot HTVA'), 0, 0, 'R', false); - $this->Cell(20, $high, _('Tot TVA NP'), 0, 0, 'R', false); - $this->Cell(20, $high, _("Autre Tx"), 0, 0, 'R', false); - $this->Cell(20, $high, _('Tot TVA'), 0, 0, 'R', false); - $this->Cell(20, $high, _('TVAC'), 0, 0, 'R', false); - $this->Ln(6); + $this->write_cell(20, $high, _('Date'),0,0, 'L', false); + $this->write_cell(20, $high, _('Numéro interne'), 0,0, 'L', false); + $this->write_cell(50, $high, _('Code'),0,0,'L',false); + $this->write_cell(80, $high, _('Libellé'),0,0,'L',false); + $this->write_cell(20, $high, _('Tot HTVA'), 0, 0,'R', false,'R', false); + $this->write_cell(20, $high, _('Tot TVA NP'), 0, 0,'R', false, false); + $this->write_cell(20, $high, _("Autre Tx"), 0, 0, 'R', false); + $this->write_cell(20, $high, _('Tot TVA'), 0, 0, 'R', false); + $this->write_cell(20, $high, _('TVAC'), 0, 0, 'R', false); + $this->line_new(6); $this->show_col=true; } diff --git a/include/export/export_balance_csv.php b/include/export/export_balance_csv.php index 9278b852c..359ed1bad 100644 --- a/include/export/export_balance_csv.php +++ b/include/export/export_balance_csv.php @@ -101,12 +101,21 @@ foreach ($row as $r) $export->add($r['sum_deb'],"number"); $export->add($r['sum_cred'],"number"); - if ( $delta < 0 ){ + if ( $delta < 0){ $export->add("0","number"); - $export->add(abs($delta),"number"); - }else { - $export->add(abs($delta),"number"); + $export->add($r['solde_cred'],"number"); + }elseif ( $delta > 0 ) { + $export->add($r['solde_deb'],"number"); $export->add("0","number"); + }elseif ($delta==0 && $r['poste']!="") + { + $export->add("0","number"); + $export->add("0","number"); + }elseif ( $delta == 0 && $r['poste'] =="" ) { + $export->add($r['solde_deb'],"number"); + $export->add($r['solde_cred'],"number"); + } else { + throw new \Exception(__FILE__.":".__LINE__); } $export->write(); } From c0c8548c5da55b6a3ab9828e52fdb31ec8733174 Mon Sep 17 00:00:00 2001 From: sparkyx Date: Sat, 16 Dec 2023 14:41:06 +0100 Subject: [PATCH 10/37] cosmetic : color info password --- html/css/style-classic7.css | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/html/css/style-classic7.css b/html/css/style-classic7.css index 9df3f72ee..fac6a4ea1 100644 --- a/html/css/style-classic7.css +++ b/html/css/style-classic7.css @@ -3393,6 +3393,7 @@ li.li-active { */ #info_passid { position:absolute; - background-color: rgba(255,160,122,0.58); + background-color: rgba(246, 180, 157, 0.58); color:red; + } \ No newline at end of file From bf822d3c0dc0e9805295721b2ae6f1435f721804 Mon Sep 17 00:00:00 2001 From: sparkyx Date: Sat, 16 Dec 2023 15:03:36 +0100 Subject: [PATCH 11/37] PHP8.1 Compatibility --- html/securimage/securimage.php | 2 +- include/constant.php | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/html/securimage/securimage.php b/html/securimage/securimage.php index 43c5b8391..2621a715a 100644 --- a/html/securimage/securimage.php +++ b/html/securimage/securimage.php @@ -1570,7 +1570,7 @@ class Securimage_Color { * @param $green Green component 0-255 * @param $blue Blue component 0-255 */ - function Securimage_Color($red, $green = null, $blue = null) + function __construct($red, $green = null, $blue = null) { if ($green == null && $blue == null && preg_match('/^#[a-f0-9]{3,6}$/i', $red)) { $col = substr($red, 1); diff --git a/include/constant.php b/include/constant.php index 48584f3e1..5ee720e1e 100644 --- a/include/constant.php +++ b/include/constant.php @@ -67,6 +67,7 @@ if (strpos($inc_path, ";") != 0) { set_include_path($new_path); @ini_set('default_charset', "UTF-8"); @ini_set('session.use_cookies', 1); +// deprecated @ini_set('magic_quotes_gpc', 'off'); if (!defined('OVERRIDE_PARAM')) { From 7a84161b5c6fa3001dcc3dfcd706cdf76ffc5a9f Mon Sep 17 00:00:00 2001 From: sparkyx Date: Sun, 17 Dec 2023 12:07:02 +0100 Subject: [PATCH 12/37] =?UTF-8?q?Fix=20bug=20:=20$g=5Fparameter=20non=20in?= =?UTF-8?q?itialis=C3=A9=20pour=20plugin?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- html/extension.raw.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/html/extension.raw.php b/html/extension.raw.php index 2b639dc90..af1cbae03 100644 --- a/html/extension.raw.php +++ b/html/extension.raw.php @@ -36,11 +36,16 @@ require_once NOALYSS_INCLUDE . '/class/noalyss_user.class.php'; MaintenanceMode("block.html"); global $g_user,$cn,$g_parameter; +$cn=Dossier::connect(); +$g_parameter=new Noalyss_Parameter_Folder($cn); + $http=new HttpInput(); $cn=Dossier::connect(); $g_user=new Noalyss_user($cn); $g_user->check(); $only_plugin=$g_user->check_dossier(dossier::id()); + + set_language(); $ext=new Extension($cn); From e58c2ae378ff1ab6223770d5ca934404e6cecdaa Mon Sep 17 00:00:00 2001 From: sparkyx Date: Sun, 17 Dec 2023 12:07:44 +0100 Subject: [PATCH 13/37] Code improve : Acc_Balance utilise PDF_CORE::is_fill --- include/export/export_balance_pdf.php | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/include/export/export_balance_pdf.php b/include/export/export_balance_pdf.php index f60903f7c..d82bcd8ba 100644 --- a/include/export/export_balance_pdf.php +++ b/include/export/export_balance_pdf.php @@ -210,13 +210,7 @@ if (!empty($array)) { $nlvl3[$a] = bcadd($nlvl3[$a], $r[$a]); } - if ($i % 2 == 0) { - $pdf->SetFillColor(220, 221, 255); - $fill = 1; - } else { - $pdf->SetFillColor(0, 0, 0); - $fill = 0; - } + $fill=$pdf->is_fill($i); $pdf->LongLine(30, 6, $value['poste'], 0, 'L', $fill); $pdf->LongLine(60, 6, $value['label'], 0, 'L', $fill); From 65a6d1b14a27ca729e4bc3ce3997ace7a7241a1a Mon Sep 17 00:00:00 2001 From: sparkyx Date: Sun, 17 Dec 2023 12:08:20 +0100 Subject: [PATCH 14/37] Improve Code : permet d'avoir plusieurs couleurs sur une ligne --- include/lib/pdf_core.class.php | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/include/lib/pdf_core.class.php b/include/lib/pdf_core.class.php index 3b4563889..9111751ea 100644 --- a/include/lib/pdf_core.class.php +++ b/include/lib/pdf_core.class.php @@ -184,7 +184,32 @@ class PDF_Core extends TFPDF } return false; } - private function print_row() + + /** + * @brief print the current array of cell and reset it , if different colors are set on the same row + * you have to print it before changing + *@code + * // fill red , text white + * $this->SetFillColor(255,0,0); + * $this->SetTextColor(255,255,255); + * $this->write_cell(15,5,"PRICE",0,0,'R',fill:true); + * + * // print the cell without a linefeed + * $this->print_row(); + * + * // text in black on green + * + * $this->SetTextColor(0,0,0); + * $this->SetFillColor(0,255,0); + * + * $this->write_cell(15,5,nbm($other['price']),0,0,'R'); + *@endcode + * @see TFPDF::SetTextColor() + * @see TFPDF::SetFillColor() + * @see TFPDF::SetFontSize() + * @return void + */ + protected function print_row() { static $e=0; $e++; From 3817deb492e1d607d469ede3731a7bee2948c21e Mon Sep 17 00:00:00 2001 From: sparkyx Date: Sun, 17 Dec 2023 12:09:11 +0100 Subject: [PATCH 15/37] =?UTF-8?q?TFPDF=20mise=20=C3=A0=20jour=201.33?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- include/tfpdf/tfpdf.php | 1198 +++++++++++++++++++++------------------ 1 file changed, 636 insertions(+), 562 deletions(-) diff --git a/include/tfpdf/tfpdf.php b/include/tfpdf/tfpdf.php index e1f51c794..b52048999 100644 --- a/include/tfpdf/tfpdf.php +++ b/include/tfpdf/tfpdf.php @@ -1,95 +1,94 @@ * +* Version: 1.33 * +* Date: 2022-12-20 * +* Authors: Ian Back * +* Tycho Veltmeijer (versions 1.30+) * * License: LGPL * *******************************************************************************/ -define('tFPDF_VERSION','1.24'); -#[AllowDynamicProperties] class tFPDF { - -var $unifontSubset; -var $page; // current page number -var $n; // current object number -var $offsets; // array of object offsets -var $buffer; // buffer holding in-memory PDF -var $pages; // array containing pages -var $state; // current document state -var $compress; // compression flag -var $k; // scale factor (number of points in user unit) -var $DefOrientation; // default orientation -var $CurOrientation; // current orientation -var $StdPageSizes; // standard page sizes -var $DefPageSize; // default page size -var $CurPageSize; // current page size -var $PageSizes; // used for pages with non default sizes or orientations -var $wPt, $hPt; // dimensions of current page in points -var $w, $h; // dimensions of current page in user unit -var $lMargin; // left margin -var $tMargin; // top margin -var $rMargin; // right margin -var $bMargin; // page break margin -var $cMargin; // cell margin -var $x, $y; // current position in user unit -var $lasth; // height of last printed cell -var $LineWidth; // line width in user unit -var $fontpath; // path containing fonts -var $CoreFonts; // array of core font names -var $fonts; // array of used fonts -var $FontFiles; // array of font files -var $diffs; // array of encoding differences -var $FontFamily; // current font family -var $FontStyle; // current font style -var $underline; // underlining flag -var $CurrentFont; // current font info -var $FontSizePt; // current font size in points -var $FontSize; // current font size in user unit -var $DrawColor; // commands for drawing color -var $FillColor; // commands for filling color -var $TextColor; // commands for text color -var $ColorFlag; // indicates whether fill and text colors are different -var $ws; // word spacing -var $images; // array of used images -var $PageLinks; // array of links in pages -var $links; // array of internal links -var $AutoPageBreak; // automatic page breaking -var $PageBreakTrigger; // threshold used to trigger page breaks -var $InHeader; // flag set when processing header -var $InFooter; // flag set when processing footer -var $ZoomMode; // zoom display mode -var $LayoutMode; // layout display mode -var $title; // title -var $subject; // subject -var $author; // author -var $keywords; // keywords -var $creator; // creator -var $AliasNbPages; // alias for total number of pages -var $PDFVersion; // PDF version number +const VERSION = '1.33'; +protected $unifontSubset; +protected $page; // current page number +protected $n; // current object number +protected $offsets; // array of object offsets +protected $buffer; // buffer holding in-memory PDF +protected $pages; // array containing pages +protected $state; // current document state +protected $compress; // compression flag +protected $k; // scale factor (number of points in user unit) +protected $DefOrientation; // default orientation +protected $CurOrientation; // current orientation +protected $StdPageSizes; // standard page sizes +protected $DefPageSize; // default page size +protected $CurPageSize; // current page size +protected $CurRotation; // current page rotation +protected $PageInfo; // page-related data +protected $wPt, $hPt; // dimensions of current page in points +protected $w, $h; // dimensions of current page in user unit +protected $lMargin; // left margin +protected $tMargin; // top margin +protected $rMargin; // right margin +protected $bMargin; // page break margin +protected $cMargin; // cell margin +protected $x, $y; // current position in user unit +protected $lasth; // height of last printed cell +protected $LineWidth; // line width in user unit +protected $fontpath; // path containing fonts +protected $CoreFonts; // array of core font names +protected $fonts; // array of used fonts +protected $FontFiles; // array of font files +protected $encodings; // array of encodings +protected $cmaps; // array of ToUnicode CMaps +protected $FontFamily; // current font family +protected $FontStyle; // current font style +protected $underline; // underlining flag +protected $CurrentFont; // current font info +protected $FontSizePt; // current font size in points +protected $FontSize; // current font size in user unit +protected $DrawColor; // commands for drawing color +protected $FillColor; // commands for filling color +protected $TextColor; // commands for text color +protected $ColorFlag; // indicates whether fill and text colors are different +protected $WithAlpha; // indicates whether alpha channel is used +protected $ws; // word spacing +protected $images; // array of used images +protected $PageLinks; // array of links in pages +protected $links; // array of internal links +protected $AutoPageBreak; // automatic page breaking +protected $PageBreakTrigger; // threshold used to trigger page breaks +protected $InHeader; // flag set when processing header +protected $InFooter; // flag set when processing footer +protected $AliasNbPages; // alias for total number of pages +protected $ZoomMode; // zoom display mode +protected $LayoutMode; // layout display mode +protected $metadata; // document properties +protected $CreationDate; // document creation date +protected $PDFVersion; // PDF version number /******************************************************************************* -* * * Public methods * -* * *******************************************************************************/ + function __construct($orientation='P', $unit='mm', $size='A4') { // Some checks $this->_dochecks(); // Initialization of properties + $this->state = 0; $this->page = 0; $this->n = 2; $this->buffer = ''; $this->pages = array(); - $this->PageSizes = array(); - $this->state = 0; + $this->PageInfo = array(); $this->fonts = array(); $this->FontFiles = array(); - $this->diffs = array(); + $this->encodings = array(); + $this->cmaps = array(); $this->images = array(); $this->links = array(); $this->InHeader = false; @@ -103,6 +102,7 @@ function __construct($orientation='P', $unit='mm', $size='A4') $this->FillColor = '0 g'; $this->TextColor = '0 g'; $this->ColorFlag = false; + $this->WithAlpha = false; $this->ws = 0; // Font path if(defined('FPDF_FONTPATH')) @@ -153,6 +153,8 @@ function __construct($orientation='P', $unit='mm', $size='A4') $this->CurOrientation = $this->DefOrientation; $this->wPt = $this->w*$this->k; $this->hPt = $this->h*$this->k; + // Page rotation + $this->CurRotation = 0; // Page margins (1 cm) $margin = 28.35/$this->k; $this->SetMargins($margin,$margin); @@ -166,6 +168,8 @@ function __construct($orientation='P', $unit='mm', $size='A4') $this->SetDisplayMode('default'); // Enable compression $this->SetCompression(true); + // Metadata + $this->metadata = array('Producer'=>'tFPDF '.self::VERSION); // Set default PDF version number $this->PDFVersion = '1.3'; } @@ -233,41 +237,31 @@ function SetCompression($compress) function SetTitle($title, $isUTF8=false) { // Title of document - if($isUTF8) - $title = $this->_UTF8toUTF16($title); - $this->title = $title; -} - -function SetSubject($subject, $isUTF8=false) -{ - // Subject of document - if($isUTF8) - $subject = $this->_UTF8toUTF16($subject); - $this->subject = $subject; + $this->metadata['Title'] = $isUTF8 ? $title : $this->_UTF8encode($title); } function SetAuthor($author, $isUTF8=false) { // Author of document - if($isUTF8) - $author = $this->_UTF8toUTF16($author); - $this->author = $author; + $this->metadata['Author'] = $isUTF8 ? $author : $this->_UTF8encode($author); +} + +function SetSubject($subject, $isUTF8=false) +{ + // Subject of document + $this->metadata['Subject'] = $isUTF8 ? $subject : $this->_UTF8encode($subject); } function SetKeywords($keywords, $isUTF8=false) { // Keywords of document - if($isUTF8) - $keywords = $this->_UTF8toUTF16($keywords); - $this->keywords = $keywords; + $this->metadata['Keywords'] = $isUTF8 ? $keywords : $this->_UTF8encode($keywords); } function SetCreator($creator, $isUTF8=false) { // Creator of document - if($isUTF8) - $creator = $this->_UTF8toUTF16($creator); - $this->creator = $creator; + $this->metadata['Creator'] = $isUTF8 ? $creator : $this->_UTF8encode($creator); } function AliasNbPages($alias='{nb}') @@ -279,13 +273,7 @@ function AliasNbPages($alias='{nb}') function Error($msg) { // Fatal error - die('FPDF error: '.$msg); -} - -function Open() -{ - // Begin document - $this->state = 1; + throw new Exception('tFPDF error: '.$msg); } function Close() @@ -305,11 +293,11 @@ function Close() $this->_enddoc(); } -function AddPage($orientation='', $size='') +function AddPage($orientation='', $size='', $rotation=0) { // Start a new page - if($this->state==0) - $this->Open(); + if($this->state==3) + $this->Error('The document is closed'); $family = $this->FontFamily; $style = $this->FontStyle.($this->underline ? 'U' : ''); $fontsize = $this->FontSizePt; @@ -328,7 +316,7 @@ function AddPage($orientation='', $size='') $this->_endpage(); } // Start new page - $this->_beginpage($orientation,$size); + $this->_beginpage($orientation,$size,$rotation); // Set line cap style to square $this->_out('2 J'); // Set line width @@ -427,12 +415,12 @@ function GetStringWidth($s) { // Get width of a string in the current font $s = (string)$s; - $cw = &$this->CurrentFont['cw']; + $cw = $this->CurrentFont['cw']; $w=0; if ($this->unifontSubset) { $unicode = $this->UTF8StringToArray($s); foreach($unicode as $char) { - if (isset($cw[$char])) { $w += (ord($cw[2*$char])<<8) + ord($cw[2*$char+1]); } + if (isset($cw[2*$char])) { $w += (ord($cw[2*$char])<<8) + ord($cw[2*$char+1]); } else if($char>0 && $char<128 && isset($cw[chr($char)])) { $w += $cw[chr($char)]; } else if(isset($this->CurrentFont['desc']['MissingWidth'])) { $w += $this->CurrentFont['desc']['MissingWidth']; } else if(isset($this->CurrentFont['MissingWidth'])) { $w += $this->CurrentFont['MissingWidth']; } @@ -479,7 +467,7 @@ function AddFont($family, $style='', $file='', $uni=false) $family = strtolower($family); $style = strtoupper($style); if($style=='IB') - $style='BI'; + $style = 'BI'; if($file=='') { if ($uni) { $file = str_replace(' ','',$family).strtolower($style).'.ttf'; @@ -491,11 +479,10 @@ function AddFont($family, $style='', $file='', $uni=false) $fontkey = $family.$style; if(isset($this->fonts[$fontkey])) return; - if ($uni) { if (defined("_SYSTEM_TTFONTS") && file_exists(_SYSTEM_TTFONTS.$file )) { $ttffilename = _SYSTEM_TTFONTS.$file ; } - else { $ttffilename = $this->_getfontpath().'unifont/'.$file ; } - $unifilename = $this->_getfontpath().'unifont/'.strtolower(substr($file ,0,(strpos($file ,'.')))); + else { $ttffilename = $this->fontpath.'unifont/'.$file ; } + $unifilename = $this->fontpath.'unifont/'.strtolower(substr($file ,0,(strpos($file ,'.')))); $name = ''; $originalsize = 0; $ttfstat = stat($ttffilename); @@ -504,7 +491,7 @@ function AddFont($family, $style='', $file='', $uni=false) } if (!isset($type) || !isset($name) || $originalsize != $ttfstat['size']) { $ttffile = $ttffilename; - require_once($this->_getfontpath().'unifont/ttfonts.php'); + require_once($this->fontpath.'unifont/ttfonts.php'); $ttf = new TTFontFile(); $ttf->getMetrics($ttffile); $cw = $ttf->charWidths; @@ -533,7 +520,7 @@ function AddFont($family, $style='', $file='', $uni=false) $s.='$originalsize='.$originalsize.";\n"; $s.='$fontkey=\''.$fontkey."';\n"; $s.="?>"; - if (is_writable(dirname($this->_getfontpath().'unifont/'.'x'))) { + if (is_writable(dirname($this->fontpath.'unifont/'.'x'))) { $fh = fopen($unifilename.'.mtx.php',"w"); fwrite($fh,$s,strlen($s)); fclose($fh); @@ -561,17 +548,6 @@ function AddFont($family, $style='', $file='', $uni=false) else { $info = $this->_loadfont($file); $info['i'] = count($this->fonts)+1; - if(!empty($info['diff'])) - { - // Search existing encodings - $n = array_search($info['diff'],$this->diffs); - if(!$n) - { - $n = count($this->diffs)+1; - $this->diffs[$n] = $info['diff']; - } - $info['diffn'] = $n; - } if(!empty($info['file'])) { // Embedded font @@ -606,6 +582,7 @@ function SetFont($family, $style='', $size=0) // Test if font is already selected if($this->FontFamily==$family && $this->FontStyle==$style && $this->FontSizePt==$size) return; + // Test if font is already loaded $fontkey = $family.$style; if(!isset($this->fonts[$fontkey])) @@ -674,6 +651,9 @@ function Link($x, $y, $w, $h, $link) function Text($x, $y, $txt) { // Output a string + $txt = (string)$txt; + if(!isset($this->CurrentFont)) + $this->Error('No font has been set'); if ($this->unifontSubset) { $txt2 = '('.$this->_escape($this->UTF8ToUTF16BE($txt, false)).')'; @@ -699,6 +679,7 @@ function AcceptPageBreak() function Cell($w, $h=0, $txt='', $border=0, $ln=0, $align='', $fill=false, $link='') { // Output a cell + $txt = (string)$txt; $k = $this->k; if($this->y+$h>$this->PageBreakTrigger && !$this->InHeader && !$this->InFooter && $this->AcceptPageBreak()) { @@ -710,7 +691,7 @@ function Cell($w, $h=0, $txt='', $border=0, $ln=0, $align='', $fill=false, $link $this->ws = 0; $this->_out('0 Tw'); } - $this->AddPage($this->CurOrientation,$this->CurPageSize); + $this->AddPage($this->CurOrientation,$this->CurPageSize,$this->CurRotation); $this->x = $x; if($ws>0) { @@ -744,6 +725,8 @@ function Cell($w, $h=0, $txt='', $border=0, $ln=0, $align='', $fill=false, $link } if($txt!=='') { + if(!isset($this->CurrentFont)) + $this->Error('No font has been set'); if($align=='R') $dx = $w-$this->cMargin-$this->GetStringWidth($txt); elseif($align=='C') @@ -752,7 +735,6 @@ function Cell($w, $h=0, $txt='', $border=0, $ln=0, $align='', $fill=false, $link $dx = $this->cMargin; if($this->ColorFlag) $s .= 'q '.$this->TextColor.' '; - // If multibyte, Tw has no effect - do word spacing using an adjustment before each space if ($this->ws && $this->unifontSubset) { foreach($this->UTF8StringToArray($txt) as $uni) @@ -781,7 +763,7 @@ function Cell($w, $h=0, $txt='', $border=0, $ln=0, $align='', $fill=false, $link $this->CurrentFont['subset'][$uni] = $uni; } else - $txt2='('.str_replace(')','\\)',str_replace('(','\\(',str_replace('\\','\\\\',$txt))).')'; + $txt2='('.$this->_escape($txt).')'; $s .= sprintf('BT %.2F %.2F Td %s Tj ET',($this->x+$dx)*$k,($this->h-($this->y+.5*$h+.3*$this->FontSize))*$k,$txt2); } if($this->underline) @@ -808,11 +790,14 @@ function Cell($w, $h=0, $txt='', $border=0, $ln=0, $align='', $fill=false, $link function MultiCell($w, $h, $txt, $border=0, $align='J', $fill=false) { // Output text with automatic or explicit line breaks - $cw = &$this->CurrentFont['cw']; + if(!isset($this->CurrentFont)) + $this->Error('No font has been set'); + $cw = $this->CurrentFont['cw']; if($w==0) $w = $this->w-$this->rMargin-$this->x; $wmax = ($w-2*$this->cMargin); - $s = str_replace("\r",'',$txt); + //$wmax = ($w-2*$this->cMargin)*1000/$this->FontSize; + $s = str_replace("\r",'',(string)$txt); if ($this->unifontSubset) { $nb=mb_strlen($s, 'utf-8'); while($nb>0 && mb_substr($s,$nb-1,1,'utf-8')=="\n") $nb--; @@ -955,11 +940,12 @@ function MultiCell($w, $h, $txt, $border=0, $align='J', $fill=false) function Write($h, $txt, $link='') { // Output text in flowing mode - $cw = &$this->CurrentFont['cw']; + if(!isset($this->CurrentFont)) + $this->Error('No font has been set'); + $cw = $this->CurrentFont['cw']; $w = $this->w-$this->rMargin-$this->x; - $wmax = ($w-2*$this->cMargin); - $s = str_replace("\r",'',$txt); + $s = str_replace("\r",'',(string)$txt); if ($this->unifontSubset) { $nb = mb_strlen($s, 'UTF-8'); if($nb==1 && $s==" ") { @@ -988,10 +974,10 @@ function Write($h, $txt, $link='') { // Explicit line break if ($this->unifontSubset) { - $this->Cell($w,$h,mb_substr($s,$j,$i-$j,'UTF-8'),0,2,'',0,$link); + $this->Cell($w,$h,mb_substr($s,$j,$i-$j,'UTF-8'),0,2,'',false,$link); } else { - $this->Cell($w,$h,substr($s,$j,$i-$j),0,2,'',0,$link); + $this->Cell($w,$h,substr($s,$j,$i-$j),0,2,'',false,$link); } $i++; $sep = -1; @@ -1031,19 +1017,19 @@ function Write($h, $txt, $link='') if($i==$j) $i++; if ($this->unifontSubset) { - $this->Cell($w,$h,mb_substr($s,$j,$i-$j,'UTF-8'),0,2,'',0,$link); + $this->Cell($w,$h,mb_substr($s,$j,$i-$j,'UTF-8'),0,2,'',false,$link); } else { - $this->Cell($w,$h,substr($s,$j,$i-$j),0,2,'',0,$link); + $this->Cell($w,$h,substr($s,$j,$i-$j),0,2,'',false,$link); } } else { if ($this->unifontSubset) { - $this->Cell($w,$h,mb_substr($s,$j,$sep-$j,'UTF-8'),0,2,'',0,$link); + $this->Cell($w,$h,mb_substr($s,$j,$sep-$j,'UTF-8'),0,2,'',false,$link); } else { - $this->Cell($w,$h,substr($s,$j,$sep-$j),0,2,'',0,$link); + $this->Cell($w,$h,substr($s,$j,$sep-$j),0,2,'',false,$link); } $i = $sep+1; } @@ -1064,17 +1050,17 @@ function Write($h, $txt, $link='') // Last chunk if($i!=$j) { if ($this->unifontSubset) { - $this->Cell($l,$h,mb_substr($s,$j,$i-$j,'UTF-8'),0,0,'',0,$link); + $this->Cell($l,$h,mb_substr($s,$j,$i-$j,'UTF-8'),0,0,'',false,$link); } else { - $this->Cell($l,$h,substr($s,$j),0,0,'',0,$link); + $this->Cell($l,$h,substr($s,$j),0,0,'',false,$link); } } } function Ln($h=null) { - // Line feed; default value is last cell height + // Line feed; default value is the last cell height $this->x = $this->lMargin; if($h===null) $this->y += $this->lasth; @@ -1085,6 +1071,8 @@ function Ln($h=null) function Image($file, $x=null, $y=null, $w=0, $h=0, $type='', $link='') { // Put an image on the page + if($file=='') + $this->Error('Image file name is empty'); if(!isset($this->images[$file])) { // First use of this image, get info @@ -1131,7 +1119,7 @@ function Image($file, $x=null, $y=null, $w=0, $h=0, $type='', $link='') { // Automatic page break $x2 = $this->x; - $this->AddPage($this->CurOrientation,$this->CurPageSize); + $this->AddPage($this->CurOrientation,$this->CurPageSize,$this->CurRotation); $this->x = $x2; } $y = $this->y; @@ -1145,6 +1133,18 @@ function Image($file, $x=null, $y=null, $w=0, $h=0, $type='', $link='') $this->Link($x,$y,$w,$h,$link); } +function GetPageWidth() +{ + // Get current page width + return $this->w; +} + +function GetPageHeight() +{ + // Get current page height + return $this->h; +} + function GetX() { // Get x position @@ -1166,40 +1166,40 @@ function GetY() return $this->y; } -function SetY($y) +function SetY($y, $resetX=true) { - // Set y position and reset x - $this->x = $this->lMargin; + // Set y position and optionally reset x if($y>=0) $this->y = $y; else $this->y = $this->h+$y; + if($resetX) + $this->x = $this->lMargin; } function SetXY($x, $y) { // Set x and y positions - $this->SetY($y); $this->SetX($x); + $this->SetY($y,false); } -function Output($name='', $dest='') +function Output($dest='', $name='', $isUTF8=false) { // Output PDF to some destination - if($this->state<3) - $this->Close(); - $dest = strtoupper($dest); - if($dest=='') + $this->Close(); + if(strlen($name)==1 && strlen($dest)!=1) { - if($name=='') - { - $name = 'doc.pdf'; - $dest = 'I'; - } - else - $dest = 'F'; + // Fix parameter order + $tmp = $dest; + $dest = $name; + $name = $tmp; } - switch($dest) + if($dest=='') + $dest = 'I'; + if($name=='') + $name = 'doc.pdf'; + switch(strtoupper($dest)) { case 'I': // Send to standard output @@ -1208,7 +1208,7 @@ function Output($name='', $dest='') { // We send to a browser header('Content-Type: application/pdf'); - header('Content-Disposition: inline; filename="'.$name.'"'); + header('Content-Disposition: inline; '.$this->_httpencode('filename',$name,$isUTF8)); header('Cache-Control: private, max-age=0, must-revalidate'); header('Pragma: public'); } @@ -1217,19 +1217,16 @@ function Output($name='', $dest='') case 'D': // Download file $this->_checkoutput(); - header('Content-Type: application/x-download'); - header('Content-Disposition: attachment; filename="'.$name.'"'); + header('Content-Type: application/pdf'); + header('Content-Disposition: attachment; '.$this->_httpencode('filename',$name,$isUTF8)); header('Cache-Control: private, max-age=0, must-revalidate'); header('Pragma: public'); echo $this->buffer; break; case 'F': // Save to local file - $f = fopen($name,'wb'); - if(!$f) + if(!file_put_contents($name,$this->buffer)) $this->Error('Unable to create output file: '.$name); - fwrite($f,$this->buffer,strlen($this->buffer)); - fclose($f); break; case 'S': // Return as a string @@ -1241,29 +1238,17 @@ function Output($name='', $dest='') } /******************************************************************************* -* * * Protected methods * -* * *******************************************************************************/ -function _dochecks() + +protected function _dochecks() { - // Check availability of %F - if(sprintf('%.1F',1.0)!='1.0') - $this->Error('This version of PHP is not supported'); // Check availability of mbstring if(!function_exists('mb_strlen')) $this->Error('mbstring extension is not available'); - // Check mbstring overloading - if(ini_get('mbstring.func_overload') & 2) - $this->Error('mbstring overloading must be disabled'); } -function _getfontpath() -{ - return $this->fontpath; -} - -function _checkoutput() +protected function _checkoutput() { if(PHP_SAPI!='cli') { @@ -1276,14 +1261,14 @@ function _checkoutput() if(preg_match('/^(\xEF\xBB\xBF)?\s*$/',ob_get_contents())) { // It contains only a UTF-8 BOM and/or whitespace, let's clean it - ob_end_clean(); + ob_clean(); } else $this->Error("Some data has already been output, can't send PDF file"); } } -function _getpagesize($size) +protected function _getpagesize($size) { if(is_string($size)) { @@ -1302,10 +1287,11 @@ function _getpagesize($size) } } -function _beginpage($orientation, $size) +protected function _beginpage($orientation, $size, $rotation) { $this->page++; $this->pages[$this->page] = ''; + $this->PageLinks[$this->page] = array(); $this->state = 2; $this->x = $this->lMargin; $this->y = $this->tMargin; @@ -1339,74 +1325,88 @@ function _beginpage($orientation, $size) $this->CurPageSize = $size; } if($orientation!=$this->DefOrientation || $size[0]!=$this->DefPageSize[0] || $size[1]!=$this->DefPageSize[1]) - $this->PageSizes[$this->page] = array($this->wPt, $this->hPt); + $this->PageInfo[$this->page]['size'] = array($this->wPt, $this->hPt); + if($rotation!=0) + { + if($rotation%90!=0) + $this->Error('Incorrect rotation value: '.$rotation); + $this->PageInfo[$this->page]['rotation'] = $rotation; + } + $this->CurRotation = $rotation; } -function _endpage() +protected function _endpage() { $this->state = 1; } -function _loadfont($font) +protected function _loadfont($font) { // Load a font definition file from the font directory + if(strpos($font,'/')!==false || strpos($font,"\\")!==false) + $this->Error('Incorrect font definition file name: '.$font); include($this->fontpath.$font); - $a = get_defined_vars(); - if(!isset($a['name'])) + if(!isset($name)) $this->Error('Could not include font definition file'); - return $a; + if(isset($enc)) + $enc = strtolower($enc); + if(!isset($subsetted)) + $subsetted = false; + return get_defined_vars(); } -function _escape($s) +protected function _isascii($s) { - // Escape special characters in strings - $s = str_replace('\\','\\\\',$s); - $s = str_replace('(','\\(',$s); - $s = str_replace(')','\\)',$s); - $s = str_replace("\r",'\\r',$s); - return $s; + // Test if string is ASCII + $nb = strlen($s); + for($i=0;$i<$nb;$i++) + { + if(ord($s[$i])>127) + return false; + } + return true; } -function _textstring($s) +protected function _httpencode($param, $value, $isUTF8) +{ + // Encode HTTP header field parameter + if($this->_isascii($value)) + return $param.'="'.$value.'"'; + if(!$isUTF8) + $value = $this->_UTF8encode($value); + return $param."*=UTF-8''".rawurlencode($value); +} + +protected function _UTF8encode($s) +{ + // Convert ISO-8859-1 to UTF-8 + return mb_convert_encoding($s,'UTF-8','ISO-8859-1'); +} + +protected function _UTF8toUTF16($s) +{ + // Convert UTF-8 to UTF-16BE with BOM + return "\xFE\xFF".mb_convert_encoding($s,'UTF-16BE','UTF-8'); +} + +protected function _escape($s) +{ + // Escape special characters + if(strpos($s,'(')!==false || strpos($s,')')!==false || strpos($s,'\\')!==false || strpos($s,"\r")!==false) + return str_replace(array('\\','(',')',"\r"), array('\\\\','\\(','\\)','\\r'), $s); + else + return $s; +} + +protected function _textstring($s) { // Format a text string + if(!$this->_isascii($s)) + $s = $this->_UTF8toUTF16($s); return '('.$this->_escape($s).')'; } -function _UTF8toUTF16($s) -{ - // Convert UTF-8 to UTF-16BE with BOM - $res = "\xFE\xFF"; - $nb = strlen($s); - $i = 0; - while($i<$nb) - { - $c1 = ord($s[$i++]); - if($c1>=224) - { - // 3-byte character - $c2 = ord($s[$i++]); - $c3 = ord($s[$i++]); - $res .= chr((($c1 & 0x0F)<<4) + (($c2 & 0x3C)>>2)); - $res .= chr((($c2 & 0x03)<<6) + ($c3 & 0x3F)); - } - elseif($c1>=192) - { - // 2-byte character - $c2 = ord($s[$i++]); - $res .= chr(($c1 & 0x1C)>>2); - $res .= chr((($c1 & 0x03)<<6) + ($c2 & 0x3F)); - } - else - { - // Single-byte character - $res .= "\0".chr($c1); - } - } - return $res; -} - -function _dounderline($x, $y, $txt) +protected function _dounderline($x, $y, $txt) { // Underline text $up = $this->CurrentFont['up']; @@ -1415,7 +1415,7 @@ function _dounderline($x, $y, $txt) return sprintf('%.2F %.2F %.2F %.2F re f',$x*$this->k,($this->h-($y-$up/1000*$this->FontSize))*$this->k,$w*$this->k,-$ut/1000*$this->FontSizePt); } -function _parsejpg($file) +protected function _parsejpg($file) { // Extract info from a JPEG file $a = getimagesize($file); @@ -1434,7 +1434,7 @@ function _parsejpg($file) return array('w'=>$a[0], 'h'=>$a[1], 'cs'=>$colspace, 'bpc'=>$bpc, 'f'=>'DCTDecode', 'data'=>$data); } -function _parsepng($file) +protected function _parsepng($file) { // Extract info from a PNG file $f = fopen($file,'rb'); @@ -1445,7 +1445,7 @@ function _parsepng($file) return $info; } -function _parsepngstream($f, $file) +protected function _parsepngstream($f, $file) { // Check signature if($this->_readstream($f,8)!=chr(137).'PNG'.chr(13).chr(10).chr(26).chr(10)) @@ -1563,6 +1563,7 @@ function _parsepngstream($f, $file) unset($data); $data = gzcompress($color); $info['smask'] = gzcompress($alpha); + $this->WithAlpha = true; if($this->PDFVersion<'1.4') $this->PDFVersion = '1.4'; } @@ -1570,7 +1571,7 @@ function _parsepngstream($f, $file) return $info; } -function _readstream($f, $n) +protected function _readstream($f, $n) { // Read n bytes from stream $res = ''; @@ -1587,14 +1588,14 @@ function _readstream($f, $n) return $res; } -function _readint($f) +protected function _readint($f) { // Read a 4-byte integer from stream $a = unpack('Ni',$this->_readstream($f,4)); return $a['i']; } -function _parsegif($file) +protected function _parsegif($file) { // Extract info from a GIF file (via PNG conversion) if(!function_exists('imagepng')) @@ -1605,245 +1606,290 @@ function _parsegif($file) if(!$im) $this->Error('Missing or incorrect image file: '.$file); imageinterlace($im,0); - $f = @fopen('php://temp','rb+'); - if($f) - { - // Perform conversion in memory - ob_start(); - imagepng($im); - $data = ob_get_clean(); - fwrite($f,$data); - rewind($f); - $info = $this->_parsepngstream($f,$file); - fclose($f); - } - else - { - // Use temporary file - $tmp = tempnam('.','gif'); - if(!$tmp) - $this->Error('Unable to create a temporary file'); - if(!imagepng($im,$tmp)) - $this->Error('Error while saving to temporary file'); - $info = $this->_parsepng($tmp); - unlink($tmp); - } + ob_start(); + imagepng($im); + $data = ob_get_clean(); + imagedestroy($im); + $f = fopen('php://temp','rb+'); + if(!$f) + $this->Error('Unable to create memory stream'); + fwrite($f,$data); + rewind($f); + $info = $this->_parsepngstream($f,$file); + fclose($f); return $info; } -function _newobj() -{ - // Begin a new object - $this->n++; - $this->offsets[$this->n] = strlen($this->buffer); - $this->_out($this->n.' 0 obj'); -} - -function _putstream($s) -{ - $this->_out('stream'); - $this->_out($s); - $this->_out('endstream'); -} - -function _out($s) +protected function _out($s) { // Add a line to the document if($this->state==2) $this->pages[$this->page] .= $s."\n"; - else - $this->buffer .= $s."\n"; + elseif($this->state==1) + $this->_put($s); + elseif($this->state==0) + $this->Error('No page has been added yet'); + elseif($this->state==3) + $this->Error('The document is closed'); } -function _putpages() +protected function _put($s) +{ + $this->buffer .= $s."\n"; +} + +protected function _getoffset() +{ + return strlen($this->buffer); +} + +protected function _newobj($n=null) +{ + // Begin a new object + if($n===null) + $n = ++$this->n; + $this->offsets[$n] = $this->_getoffset(); + $this->_put($n.' 0 obj'); +} + +protected function _putstream($data) +{ + $this->_put('stream'); + $this->_put($data); + $this->_put('endstream'); +} + +protected function _putstreamobject($data) +{ + if($this->compress) + { + $entries = '/Filter /FlateDecode '; + $data = gzcompress($data); + } + else + $entries = ''; + $entries .= '/Length '.strlen($data); + $this->_newobj(); + $this->_put('<<'.$entries.'>>'); + $this->_putstream($data); + $this->_put('endobj'); +} + +protected function _putlinks($n) +{ + foreach($this->PageLinks[$n] as $pl) + { + $this->_newobj(); + $rect = sprintf('%.2F %.2F %.2F %.2F',$pl[0],$pl[1],$pl[0]+$pl[2],$pl[1]-$pl[3]); + $s = '<_textstring($pl[4]).'>>>>'; + else + { + $l = $this->links[$pl[4]]; + if(isset($this->PageInfo[$l[0]]['size'])) + $h = $this->PageInfo[$l[0]]['size'][1]; + else + $h = ($this->DefOrientation=='P') ? $this->DefPageSize[1]*$this->k : $this->DefPageSize[0]*$this->k; + $s .= sprintf('/Dest [%d 0 R /XYZ 0 %.2F null]>>',$this->PageInfo[$l[0]]['n'],$h-$l[1]*$this->k); + } + $this->_put($s); + $this->_put('endobj'); + } +} + +protected function _putpage($n) +{ + $this->_newobj(); + $this->_put('<_put('/Parent 1 0 R'); + if(isset($this->PageInfo[$n]['size'])) + $this->_put(sprintf('/MediaBox [0 0 %.2F %.2F]',$this->PageInfo[$n]['size'][0],$this->PageInfo[$n]['size'][1])); + if(isset($this->PageInfo[$n]['rotation'])) + $this->_put('/Rotate '.$this->PageInfo[$n]['rotation']); + $this->_put('/Resources 2 0 R'); + if(!empty($this->PageLinks[$n])) + { + $s = '/Annots ['; + foreach($this->PageLinks[$n] as $pl) + $s .= $pl[5].' 0 R '; + $s .= ']'; + $this->_put($s); + } + if($this->WithAlpha) + $this->_put('/Group <>'); + $this->_put('/Contents '.($this->n+1).' 0 R>>'); + $this->_put('endobj'); + // Page content + if(!empty($this->AliasNbPages)) { + $alias = $this->UTF8ToUTF16BE($this->AliasNbPages, false); + $r = $this->UTF8ToUTF16BE($this->page, false); + $this->pages[$n] = str_replace($alias,$r,$this->pages[$n]); + // Now repeat for no pages in non-subset fonts + $this->pages[$n] = str_replace($this->AliasNbPages,$this->page,$this->pages[$n]); + } + $this->_putstreamobject($this->pages[$n]); + // Link annotations + $this->_putlinks($n); +} + +protected function _putpages() { $nb = $this->page; - if(!empty($this->AliasNbPages)) + $n = $this->n; + for($i=1;$i<=$nb;$i++) { - // Replace number of pages in fonts using subsets - $alias = $this->UTF8ToUTF16BE($this->AliasNbPages, false); - $r = $this->UTF8ToUTF16BE("$nb", false); - for($n=1;$n<=$nb;$n++) - $this->pages[$n] = str_replace($alias,$r,$this->pages[$n]); - // Now repeat for no pages in non-subset fonts - for($n=1;$n<=$nb;$n++) - $this->pages[$n] = str_replace($this->AliasNbPages,$nb,$this->pages[$n]); + $this->PageInfo[$i]['n'] = ++$n; + $n++; + foreach($this->PageLinks[$i] as &$pl) + $pl[5] = ++$n; + unset($pl); } + for($i=1;$i<=$nb;$i++) + $this->_putpage($i); + // Pages root + $this->_newobj(1); + $this->_put('<PageInfo[$i]['n'].' 0 R '; + $kids .= ']'; + $this->_put($kids); + $this->_put('/Count '.$nb); if($this->DefOrientation=='P') { - $wPt = $this->DefPageSize[0]*$this->k; - $hPt = $this->DefPageSize[1]*$this->k; + $w = $this->DefPageSize[0]; + $h = $this->DefPageSize[1]; } else { - $wPt = $this->DefPageSize[1]*$this->k; - $hPt = $this->DefPageSize[0]*$this->k; + $w = $this->DefPageSize[1]; + $h = $this->DefPageSize[0]; } - $filter = ($this->compress) ? '/Filter /FlateDecode ' : ''; - for($n=1;$n<=$nb;$n++) - { - // Page - $this->_newobj(); - $this->_out('<_out('/Parent 1 0 R'); - if(isset($this->PageSizes[$n])) - $this->_out(sprintf('/MediaBox [0 0 %.2F %.2F]',$this->PageSizes[$n][0],$this->PageSizes[$n][1])); - $this->_out('/Resources 2 0 R'); - if(isset($this->PageLinks[$n])) - { - // Links - $annots = '/Annots ['; - foreach($this->PageLinks[$n] as $pl) - { - $rect = sprintf('%.2F %.2F %.2F %.2F',$pl[0],$pl[1],$pl[0]+$pl[2],$pl[1]-$pl[3]); - $annots .= '<_textstring($pl[4]).'>>>>'; - else - { - $l = $this->links[$pl[4]]; - $h = isset($this->PageSizes[$l[0]]) ? $this->PageSizes[$l[0]][1] : $hPt; - $annots .= sprintf('/Dest [%d 0 R /XYZ 0 %.2F null]>>',1+2*$l[0],$h-$l[1]*$this->k); - } - } - $this->_out($annots.']'); - } - if($this->PDFVersion>'1.3') - $this->_out('/Group <>'); - $this->_out('/Contents '.($this->n+1).' 0 R>>'); - $this->_out('endobj'); - // Page content - $p = ($this->compress) ? gzcompress($this->pages[$n]) : $this->pages[$n]; - $this->_newobj(); - $this->_out('<<'.$filter.'/Length '.strlen($p).'>>'); - $this->_putstream($p); - $this->_out('endobj'); - } - // Pages root - $this->offsets[1] = strlen($this->buffer); - $this->_out('1 0 obj'); - $this->_out('<_out($kids.']'); - $this->_out('/Count '.$nb); - $this->_out(sprintf('/MediaBox [0 0 %.2F %.2F]',$wPt,$hPt)); - $this->_out('>>'); - $this->_out('endobj'); + $this->_put(sprintf('/MediaBox [0 0 %.2F %.2F]',$w*$this->k,$h*$this->k)); + $this->_put('>>'); + $this->_put('endobj'); } -function _putfonts() +protected function _putfonts() { - $nf=$this->n; - foreach($this->diffs as $diff) - { - // Encodings - $this->_newobj(); - $this->_out('<>'); - $this->_out('endobj'); - } foreach($this->FontFiles as $file=>$info) { - if (!isset($info['type']) || $info['type']!='TTF') { - // Font file embedding - $this->_newobj(); - $this->FontFiles[$file]['n']=$this->n; - $font=''; - $f=fopen($this->_getfontpath().$file,'rb',1); - if(!$f) - $this->Error('Font file not found'); - while(!feof($f)) - $font.=fread($f,8192); - fclose($f); - $compressed=(substr($file,-2)=='.z'); - if(!$compressed && isset($info['length2'])) - { - $header=(ord($font[0])==128); - if($header) - { - // Strip first binary header - $font=substr($font,6); - } - if($header && ord($font[$info['length1']])==128) - { - // Strip second binary header - $font=substr($font,0,$info['length1']).substr($font,$info['length1']+6); - } + if (!isset($info['type']) || $info['type']!='TTF') { + // Font file embedding + $this->_newobj(); + $this->FontFiles[$file]['n'] = $this->n; + $font = file_get_contents($this->fontpath.$file,true); + if(!$font) + $this->Error('Font file not found: '.$file); + $compressed = (substr($file,-2)=='.z'); + if(!$compressed && isset($info['length2'])) + $font = substr($font,6,$info['length1']).substr($font,6+$info['length1']+6,$info['length2']); + $this->_put('<_put('/Filter /FlateDecode'); + $this->_put('/Length1 '.$info['length1']); + if(isset($info['length2'])) + $this->_put('/Length2 '.$info['length2'].' /Length3 0'); + $this->_put('>>'); + $this->_putstream($font); + $this->_put('endobj'); } - $this->_out('<_out('/Filter /FlateDecode'); - $this->_out('/Length1 '.$info['length1']); - if(isset($info['length2'])) - $this->_out('/Length2 '.$info['length2'].' /Length3 0'); - $this->_out('>>'); - $this->_putstream($font); - $this->_out('endobj'); - } } foreach($this->fonts as $k=>$font) { - // Font objects - //$this->fonts[$k]['n']=$this->n+1; + // Encoding + if(isset($font['diff'])) + { + if(!isset($this->encodings[$font['enc']])) + { + $this->_newobj(); + $this->_put('<>'); + $this->_put('endobj'); + $this->encodings[$font['enc']] = $this->n; + } + } + // ToUnicode CMap + if(isset($font['uv'])) + { + if(isset($font['enc'])) + $cmapkey = $font['enc']; + else + $cmapkey = $font['name']; + if(!isset($this->cmaps[$cmapkey])) + { + $cmap = $this->_tounicodecmap($font['uv']); + $this->_putstreamobject($cmap); + $this->cmaps[$cmapkey] = $this->n; + } + } + // Font object $type = $font['type']; $name = $font['name']; if($type=='Core') { - // Standard font - $this->fonts[$k]['n']=$this->n+1; + // Core font + $this->fonts[$k]['n'] = $this->n+1; $this->_newobj(); - $this->_out('<_out('/BaseFont /'.$name); - $this->_out('/Subtype /Type1'); + $this->_put('<_put('/BaseFont /'.$name); + $this->_put('/Subtype /Type1'); if($name!='Symbol' && $name!='ZapfDingbats') - $this->_out('/Encoding /WinAnsiEncoding'); - $this->_out('>>'); - $this->_out('endobj'); + $this->_put('/Encoding /WinAnsiEncoding'); + if(isset($font['uv'])) + $this->_put('/ToUnicode '.$this->cmaps[$cmapkey].' 0 R'); + $this->_put('>>'); + $this->_put('endobj'); } elseif($type=='Type1' || $type=='TrueType') { - // Additional Type1 or TrueType font - $this->fonts[$k]['n']=$this->n+1; + // Additional Type1 or TrueType/OpenType font + if(isset($font['subsetted']) && $font['subsetted']) + $name = 'AAAAAA+'.$name; + $this->fonts[$k]['n'] = $this->n+1; $this->_newobj(); - $this->_out('<_out('/BaseFont /'.$name); - $this->_out('/Subtype /'.$type); - $this->_out('/FirstChar 32 /LastChar 255'); - $this->_out('/Widths '.($this->n+1).' 0 R'); - $this->_out('/FontDescriptor '.($this->n+2).' 0 R'); + $this->_put('<_put('/BaseFont /'.$name); + $this->_put('/Subtype /'.$type); + $this->_put('/FirstChar 32 /LastChar 255'); + $this->_put('/Widths '.($this->n+1).' 0 R'); + $this->_put('/FontDescriptor '.($this->n+2).' 0 R'); + if($font['enc']) { if(isset($font['diff'])) - $this->_out('/Encoding '.($nf+$font['diff']).' 0 R'); + $this->_put('/Encoding '.$this->encodings[$font['enc']].' 0 R'); else - $this->_out('/Encoding /WinAnsiEncoding'); + $this->_put('/Encoding /WinAnsiEncoding'); } - $this->_out('>>'); - $this->_out('endobj'); + + if(isset($font['uv'])) + $this->_put('/ToUnicode '.$this->cmaps[$cmapkey].' 0 R'); + $this->_put('>>'); + $this->_put('endobj'); // Widths $this->_newobj(); - $cw=&$font['cw']; - $s='['; + $cw = $font['cw']; + $s = '['; for($i=32;$i<=255;$i++) - $s.=$cw[chr($i)].' '; - $this->_out($s.']'); - $this->_out('endobj'); + $s .= $cw[chr($i)].' '; + $this->_put($s.']'); + $this->_put('endobj'); // Descriptor $this->_newobj(); - $s='<$v) - $s.=' /'.$k.' '.$v; - $file=$font['file']; - if($file) - $s.=' /FontFile'.($type=='Type1' ? '' : '2').' '.$this->FontFiles[$file]['n'].' 0 R'; - $this->_out($s.'>>'); - $this->_out('endobj'); + $s .= ' /'.$k.' '.$v; + + if(!empty($font['file'])) + $s .= ' /FontFile'.($type=='Type1' ? '' : '2').' '.$this->FontFiles[$font['file']]['n'].' 0 R'; + $this->_put($s.'>>'); + $this->_put('endobj'); } // TrueType embedded SUBSETS or FULL else if ($type=='TTF') { $this->fonts[$k]['n']=$this->n+1; - require_once($this->_getfontpath().'unifont/ttfonts.php'); + require_once($this->fontpath.'unifont/ttfonts.php'); $ttf = new TTFontFile(); $fontname = 'MPDFAA'.'+'.$font['name']; $subset = $font['subset']; @@ -1857,32 +1903,32 @@ function _putfonts() // Type0 Font // A composite font - a font composed of other fonts, organized hierarchically $this->_newobj(); - $this->_out('<_out('/Subtype /Type0'); - $this->_out('/BaseFont /'.$fontname.''); - $this->_out('/Encoding /Identity-H'); - $this->_out('/DescendantFonts ['.($this->n + 1).' 0 R]'); - $this->_out('/ToUnicode '.($this->n + 2).' 0 R'); - $this->_out('>>'); - $this->_out('endobj'); + $this->_put('<_put('/Subtype /Type0'); + $this->_put('/BaseFont /'.$fontname.''); + $this->_put('/Encoding /Identity-H'); + $this->_put('/DescendantFonts ['.($this->n + 1).' 0 R]'); + $this->_put('/ToUnicode '.($this->n + 2).' 0 R'); + $this->_put('>>'); + $this->_put('endobj'); // CIDFontType2 // A CIDFont whose glyph descriptions are based on TrueType font technology $this->_newobj(); - $this->_out('<_out('/Subtype /CIDFontType2'); - $this->_out('/BaseFont /'.$fontname.''); - $this->_out('/CIDSystemInfo '.($this->n + 2).' 0 R'); - $this->_out('/FontDescriptor '.($this->n + 3).' 0 R'); + $this->_put('<_put('/Subtype /CIDFontType2'); + $this->_put('/BaseFont /'.$fontname.''); + $this->_put('/CIDSystemInfo '.($this->n + 2).' 0 R'); + $this->_put('/FontDescriptor '.($this->n + 3).' 0 R'); if (isset($font['desc']['MissingWidth'])){ $this->_out('/DW '.$font['desc']['MissingWidth'].''); } $this->_putTTfontwidths($font, $ttf->maxUni); - $this->_out('/CIDToGIDMap '.($this->n + 4).' 0 R'); - $this->_out('>>'); - $this->_out('endobj'); + $this->_put('/CIDToGIDMap '.($this->n + 4).' 0 R'); + $this->_put('>>'); + $this->_put('endobj'); // ToUnicode $this->_newobj(); @@ -1906,29 +1952,29 @@ function _putfonts() $toUni .= "CMapName currentdict /CMap defineresource pop\n"; $toUni .= "end\n"; $toUni .= "end"; - $this->_out('<>'); + $this->_put('<>'); $this->_putstream($toUni); - $this->_out('endobj'); + $this->_put('endobj'); // CIDSystemInfo dictionary $this->_newobj(); - $this->_out('<_out('/Ordering (UCS)'); - $this->_out('/Supplement 0'); - $this->_out('>>'); - $this->_out('endobj'); + $this->_put('<_put('/Ordering (UCS)'); + $this->_put('/Supplement 0'); + $this->_put('>>'); + $this->_put('endobj'); // Font descriptor $this->_newobj(); - $this->_out('<_out('/FontName /'.$fontname); + $this->_put('<_put('/FontName /'.$fontname); foreach($font['desc'] as $kd=>$v) { if ($kd == 'Flags') { $v = $v | 4; $v = $v & ~32; } // SYMBOLIC font flag $this->_out(' /'.$kd.' '.$v); } - $this->_out('/FontFile2 '.($this->n + 2).' 0 R'); - $this->_out('>>'); - $this->_out('endobj'); + $this->_put('/FontFile2 '.($this->n + 2).' 0 R'); + $this->_put('>>'); + $this->_put('endobj'); // Embed CIDToGIDMap // A specification of the mapping from CIDs to glyph indices @@ -1940,27 +1986,27 @@ function _putfonts() } $cidtogidmap = gzcompress($cidtogidmap); $this->_newobj(); - $this->_out('<_out('/Filter /FlateDecode'); - $this->_out('>>'); + $this->_put('<_put('/Filter /FlateDecode'); + $this->_put('>>'); $this->_putstream($cidtogidmap); - $this->_out('endobj'); + $this->_put('endobj'); //Font file $this->_newobj(); - $this->_out('<_out('/Filter /FlateDecode'); - $this->_out('/Length1 '.$ttfontsize); - $this->_out('>>'); + $this->_put('<_put('/Filter /FlateDecode'); + $this->_put('/Length1 '.$ttfontsize); + $this->_put('>>'); $this->_putstream($fontstream); - $this->_out('endobj'); + $this->_put('endobj'); unset($ttf); } else { // Allow for additional types $this->fonts[$k]['n'] = $this->n+1; - $mtd='_put'.strtolower($type); + $mtd = '_put'.strtolower($type); if(!method_exists($this,$mtd)) $this->Error('Unsupported font type: '.$type); $this->$mtd($font); @@ -1968,7 +2014,7 @@ function _putfonts() } } -function _putTTfontwidths(&$font, $maxUni) { +protected function _putTTfontwidths($font, $maxUni) { if (file_exists($font['unifilename'].'.cw127.php')) { include($font['unifilename'].'.cw127.php') ; $startcid = 128; @@ -1986,7 +2032,7 @@ function _putTTfontwidths(&$font, $maxUni) { // for each character for ($cid=$startcid; $cid<$cwlen; $cid++) { if ($cid==128 && (!file_exists($font['unifilename'].'.cw127.php'))) { - if (is_writable(dirname($this->_getfontpath().'unifont/x'))) { + if (is_writable(dirname($this->fontpath.'unifont/x'))) { $fh = fopen($font['unifilename'].'.cw127.php',"wb"); $cw127=' 255 && (!isset($font['subset'][$cid]) || !$font['subset'][$cid])) { continue; } @@ -2068,7 +2116,58 @@ function _putTTfontwidths(&$font, $maxUni) { $this->_out('/W ['.$w.' ]'); } -function _putimages() +protected function _tounicodecmap($uv) +{ + $ranges = ''; + $nbr = 0; + $chars = ''; + $nbc = 0; + foreach($uv as $c=>$v) + { + if(is_array($v)) + { + $ranges .= sprintf("<%02X> <%02X> <%04X>\n",$c,$c+$v[1]-1,$v[0]); + $nbr++; + } + else + { + $chars .= sprintf("<%02X> <%04X>\n",$c,$v); + $nbc++; + } + } + $s = "/CIDInit /ProcSet findresource begin\n"; + $s .= "12 dict begin\n"; + $s .= "begincmap\n"; + $s .= "/CIDSystemInfo\n"; + $s .= "<0) + { + $s .= "$nbr beginbfrange\n"; + $s .= $ranges; + $s .= "endbfrange\n"; + } + if($nbc>0) + { + $s .= "$nbc beginbfchar\n"; + $s .= $chars; + $s .= "endbfchar\n"; + } + $s .= "endcmap\n"; + $s .= "CMapName currentdict /CMap defineresource pop\n"; + $s .= "end\n"; + $s .= "end"; + return $s; +} + +protected function _putimages() { foreach(array_keys($this->images) as $file) { @@ -2078,39 +2177,39 @@ function _putimages() } } -function _putimage(&$info) +protected function _putimage(&$info) { $this->_newobj(); $info['n'] = $this->n; - $this->_out('<_out('/Subtype /Image'); - $this->_out('/Width '.$info['w']); - $this->_out('/Height '.$info['h']); + $this->_put('<_put('/Subtype /Image'); + $this->_put('/Width '.$info['w']); + $this->_put('/Height '.$info['h']); if($info['cs']=='Indexed') - $this->_out('/ColorSpace [/Indexed /DeviceRGB '.(strlen($info['pal'])/3-1).' '.($this->n+1).' 0 R]'); + $this->_put('/ColorSpace [/Indexed /DeviceRGB '.(strlen($info['pal'])/3-1).' '.($this->n+1).' 0 R]'); else { - $this->_out('/ColorSpace /'.$info['cs']); + $this->_put('/ColorSpace /'.$info['cs']); if($info['cs']=='DeviceCMYK') - $this->_out('/Decode [1 0 1 0 1 0 1 0]'); + $this->_put('/Decode [1 0 1 0 1 0 1 0]'); } - $this->_out('/BitsPerComponent '.$info['bpc']); + $this->_put('/BitsPerComponent '.$info['bpc']); if(isset($info['f'])) - $this->_out('/Filter /'.$info['f']); + $this->_put('/Filter /'.$info['f']); if(isset($info['dp'])) - $this->_out('/DecodeParms <<'.$info['dp'].'>>'); + $this->_put('/DecodeParms <<'.$info['dp'].'>>'); if(isset($info['trns']) && is_array($info['trns'])) { $trns = ''; for($i=0;$i_out('/Mask ['.$trns.']'); + $this->_put('/Mask ['.$trns.']'); } if(isset($info['smask'])) - $this->_out('/SMask '.($this->n+1).' 0 R'); - $this->_out('/Length '.strlen($info['data']).'>>'); + $this->_put('/SMask '.($this->n+1).' 0 R'); + $this->_put('/Length '.strlen($info['data']).'>>'); $this->_putstream($info['data']); - $this->_out('endobj'); + $this->_put('endobj'); // Soft mask if(isset($info['smask'])) { @@ -2120,146 +2219,131 @@ function _putimage(&$info) } // Palette if($info['cs']=='Indexed') - { - $filter = ($this->compress) ? '/Filter /FlateDecode ' : ''; - $pal = ($this->compress) ? gzcompress($info['pal']) : $info['pal']; - $this->_newobj(); - $this->_out('<<'.$filter.'/Length '.strlen($pal).'>>'); - $this->_putstream($pal); - $this->_out('endobj'); - } + $this->_putstreamobject($info['pal']); } -function _putxobjectdict() +protected function _putxobjectdict() { foreach($this->images as $image) - $this->_out('/I'.$image['i'].' '.$image['n'].' 0 R'); + $this->_put('/I'.$image['i'].' '.$image['n'].' 0 R'); } -function _putresourcedict() +protected function _putresourcedict() { - $this->_out('/ProcSet [/PDF /Text /ImageB /ImageC /ImageI]'); - $this->_out('/Font <<'); - foreach($this->fonts as $font) { - $this->_out('/F'.$font['i'].' '.$font['n'].' 0 R'); - } - $this->_out('>>'); - $this->_out('/XObject <<'); + $this->_put('/ProcSet [/PDF /Text /ImageB /ImageC /ImageI]'); + $this->_put('/Font <<'); + foreach($this->fonts as $font) + $this->_put('/F'.$font['i'].' '.$font['n'].' 0 R'); + $this->_put('>>'); + $this->_put('/XObject <<'); $this->_putxobjectdict(); - $this->_out('>>'); + $this->_put('>>'); } -function _putresources() +protected function _putresources() { $this->_putfonts(); $this->_putimages(); // Resource dictionary - $this->offsets[2] = strlen($this->buffer); - $this->_out('2 0 obj'); - $this->_out('<<'); + $this->_newobj(2); + $this->_put('<<'); $this->_putresourcedict(); - $this->_out('>>'); - $this->_out('endobj'); + $this->_put('>>'); + $this->_put('endobj'); } -function _putinfo() +protected function _putinfo() { - $this->_out('/Producer '.$this->_textstring('tFPDF '.tFPDF_VERSION)); - if(!empty($this->title)) - $this->_out('/Title '.$this->_textstring($this->title)); - if(!empty($this->subject)) - $this->_out('/Subject '.$this->_textstring($this->subject)); - if(!empty($this->author)) - $this->_out('/Author '.$this->_textstring($this->author)); - if(!empty($this->keywords)) - $this->_out('/Keywords '.$this->_textstring($this->keywords)); - if(!empty($this->creator)) - $this->_out('/Creator '.$this->_textstring($this->creator)); - $this->_out('/CreationDate '.$this->_textstring('D:'.@date('YmdHis'))); + $date = @date('YmdHisO',$this->CreationDate); + $this->metadata['CreationDate'] = 'D:'.substr($date,0,-2)."'".substr($date,-2)."'"; + foreach($this->metadata as $key=>$value) + $this->_put('/'.$key.' '.$this->_textstring($value)); } -function _putcatalog() +protected function _putcatalog() { - $this->_out('/Type /Catalog'); - $this->_out('/Pages 1 0 R'); + $n = $this->PageInfo[1]['n']; + $this->_put('/Type /Catalog'); + $this->_put('/Pages 1 0 R'); if($this->ZoomMode=='fullpage') - $this->_out('/OpenAction [3 0 R /Fit]'); + $this->_put('/OpenAction ['.$n.' 0 R /Fit]'); elseif($this->ZoomMode=='fullwidth') - $this->_out('/OpenAction [3 0 R /FitH null]'); + $this->_put('/OpenAction ['.$n.' 0 R /FitH null]'); elseif($this->ZoomMode=='real') - $this->_out('/OpenAction [3 0 R /XYZ null null 1]'); + $this->_put('/OpenAction ['.$n.' 0 R /XYZ null null 1]'); elseif(!is_string($this->ZoomMode)) - $this->_out('/OpenAction [3 0 R /XYZ null null '.sprintf('%.2F',$this->ZoomMode/100).']'); + $this->_put('/OpenAction ['.$n.' 0 R /XYZ null null '.sprintf('%.2F',$this->ZoomMode/100).']'); if($this->LayoutMode=='single') - $this->_out('/PageLayout /SinglePage'); + $this->_put('/PageLayout /SinglePage'); elseif($this->LayoutMode=='continuous') - $this->_out('/PageLayout /OneColumn'); + $this->_put('/PageLayout /OneColumn'); elseif($this->LayoutMode=='two') - $this->_out('/PageLayout /TwoColumnLeft'); + $this->_put('/PageLayout /TwoColumnLeft'); } -function _putheader() +protected function _putheader() { - $this->_out('%PDF-'.$this->PDFVersion); + $this->_put('%PDF-'.$this->PDFVersion); } -function _puttrailer() +protected function _puttrailer() { - $this->_out('/Size '.($this->n+1)); - $this->_out('/Root '.$this->n.' 0 R'); - $this->_out('/Info '.($this->n-1).' 0 R'); + $this->_put('/Size '.($this->n+1)); + $this->_put('/Root '.$this->n.' 0 R'); + $this->_put('/Info '.($this->n-1).' 0 R'); } -function _enddoc() +protected function _enddoc() { + $this->CreationDate = time(); $this->_putheader(); $this->_putpages(); $this->_putresources(); // Info $this->_newobj(); - $this->_out('<<'); + $this->_put('<<'); $this->_putinfo(); - $this->_out('>>'); - $this->_out('endobj'); + $this->_put('>>'); + $this->_put('endobj'); // Catalog $this->_newobj(); - $this->_out('<<'); + $this->_put('<<'); $this->_putcatalog(); - $this->_out('>>'); - $this->_out('endobj'); + $this->_put('>>'); + $this->_put('endobj'); // Cross-ref - $o = strlen($this->buffer); - $this->_out('xref'); - $this->_out('0 '.($this->n+1)); - $this->_out('0000000000 65535 f '); + $offset = $this->_getoffset(); + $this->_put('xref'); + $this->_put('0 '.($this->n+1)); + $this->_put('0000000000 65535 f '); for($i=1;$i<=$this->n;$i++) - $this->_out(sprintf('%010d 00000 n ',$this->offsets[$i])); + $this->_put(sprintf('%010d 00000 n ',$this->offsets[$i])); // Trailer - $this->_out('trailer'); - $this->_out('<<'); + $this->_put('trailer'); + $this->_put('<<'); $this->_puttrailer(); - $this->_out('>>'); - $this->_out('startxref'); - $this->_out($o); - $this->_out('%%EOF'); + $this->_put('>>'); + $this->_put('startxref'); + $this->_put($offset); + $this->_put('%%EOF'); $this->state = 3; } // ********* NEW FUNCTIONS ********* // Converts UTF-8 strings to UTF16-BE. -function UTF8ToUTF16BE($str, $setbom=true) { +protected function UTF8ToUTF16BE($str, $setbom=true) { $outstr = ""; if ($setbom) { $outstr .= "\xFE\xFF"; // Byte Order Mark (BOM) } - $outstr .= mb_convert_encoding($str??"", 'UTF-16BE', 'UTF-8'); + $outstr .= mb_convert_encoding($str, 'UTF-16BE', 'UTF-8'); return $outstr; } // Converts UTF-8 strings to codepoints array -function UTF8StringToArray($str) { +protected function UTF8StringToArray($str) { $out = array(); - $len = strlen($str??""); + $len = strlen($str); for ($i = 0; $i < $len; $i++) { $uni = -1; $h = ord($str[$i]); @@ -2283,15 +2367,5 @@ function UTF8StringToArray($str) { return $out; } - -// End of class } - -// Handle special IE contype request -if(isset($_SERVER['HTTP_USER_AGENT']) && $_SERVER['HTTP_USER_AGENT']=='contype') -{ - header('Content-Type: application/pdf'); - exit; -} - ?> From 9bc39834df3c2b0191f92f59dbf96c7af7d5c631 Mon Sep 17 00:00:00 2001 From: sparkyx Date: Sun, 17 Dec 2023 17:13:02 +0100 Subject: [PATCH 16/37] Improve : PRINTJRN search in one line mode --- .../acc_ledger_history_generic.class.php | 4 +++- .../acc_ledger_history_financial_oneline.php | 4 +++- .../acc_ledger_history_purchase_oneline.php | 19 +++++++++++-------- .../acc_ledger_history_sale_oneline.php | 17 +++++++++++------ 4 files changed, 28 insertions(+), 16 deletions(-) diff --git a/include/class/acc_ledger_history_generic.class.php b/include/class/acc_ledger_history_generic.class.php index b99bde395..6bbabe3b1 100644 --- a/include/class/acc_ledger_history_generic.class.php +++ b/include/class/acc_ledger_history_generic.class.php @@ -700,7 +700,9 @@ class Acc_Ledger_History_Generic extends Acc_Ledger_History public function export_oneline_html() { $this->get_rowSimple(); - echo ''; + + echo \HtmlInput::filter_table("tb_print_ledger", "0,1,2,3,4,5,6", 1); + echo '
'; echo "". th(_("Date")). th(_("n° pièce")). diff --git a/include/template/acc_ledger_history_financial_oneline.php b/include/template/acc_ledger_history_financial_oneline.php index 42f820ab7..9cc21f80c 100644 --- a/include/template/acc_ledger_history_financial_oneline.php +++ b/include/template/acc_ledger_history_financial_oneline.php @@ -25,8 +25,10 @@ if (!defined('ALLOWED')) * @file * @brief display Financial operation , simple and detailled */ + +echo \HtmlInput::filter_table("tb_print_ledger", "0,1,2,3,4,5,6,7,8,9", 1); ?> -
+
diff --git a/include/template/acc_ledger_history_purchase_oneline.php b/include/template/acc_ledger_history_purchase_oneline.php index 9c57fa649..34fbb83b7 100644 --- a/include/template/acc_ledger_history_purchase_oneline.php +++ b/include/template/acc_ledger_history_purchase_oneline.php @@ -28,8 +28,11 @@ if (!defined('ALLOWED')) * @todo prévoir aussi pour les non assujetti : faire disparaître les montants TVA */ bcscale(2); +$p_col=($nb_other_tax<>0)?"0,1,2,3,4,5,6,7,8,9,10,11":"0,1,2,3,4,5,6,7,8,9,10,11,12"; +echo \HtmlInput::filter_table("tb_print_ledger", $p_col, 1); + ?> -
+
- - - 0) :?> - - - - diff --git a/include/template/acc_ledger_history_sale_oneline.php b/include/template/acc_ledger_history_sale_oneline.php index 4c7041ccc..b1fb3af96 100644 --- a/include/template/acc_ledger_history_sale_oneline.php +++ b/include/template/acc_ledger_history_sale_oneline.php @@ -24,9 +24,11 @@ * @brief * @todo prévoir aussi pour les non assujetti : faire disparaître les montants TVA */ +$p_col=($nb_other_tax<>0)?"0,1,2,3,4,5,6,7,8,9,10":"0,1,2,3,4,5,6,7,8,9,10,11"; +echo \HtmlInput::filter_table("tb_print_ledger", $p_col, 1); ?> -
@@ -49,28 +52,28 @@ bcscale(2); + + + + + + +
+
- - 0) :?> - - - + data); From 7470954f0197a2c0bd9e8ca6c3dc305c27ab5fd7 Mon Sep 17 00:00:00 2001 From: sparkyx Date: Sun, 17 Dec 2023 17:22:18 +0100 Subject: [PATCH 17/37] Improve : PRINTJRN search in detail VAT mode --- include/template/acc_ledger_history_purchase_detail.php | 1 + include/template/acc_ledger_history_sale_detail.php | 2 ++ include/template/acc_ledger_history_sale_extended.php | 4 +++- 3 files changed, 6 insertions(+), 1 deletion(-) diff --git a/include/template/acc_ledger_history_purchase_detail.php b/include/template/acc_ledger_history_purchase_detail.php index d69372270..bd75f0d53 100644 --- a/include/template/acc_ledger_history_purchase_detail.php +++ b/include/template/acc_ledger_history_purchase_detail.php @@ -26,6 +26,7 @@ if (!defined('ALLOWED')) * @file * @brief Display one purchase operation on one line , with the sum of VAT, ND... */ +echo \HtmlInput::filter_table("tb_print_ledger", "0,1,2,3,4,5,6,7", 1); ?>
@@ -46,24 +48,27 @@ + + + + + + +
diff --git a/include/template/acc_ledger_history_sale_detail.php b/include/template/acc_ledger_history_sale_detail.php index d15f30918..0e18240e2 100644 --- a/include/template/acc_ledger_history_sale_detail.php +++ b/include/template/acc_ledger_history_sale_detail.php @@ -27,6 +27,8 @@ if (!defined('ALLOWED')) * @brief from Acc_Ledger_History_Sale::export_html_oneline * @todo prévoir aussi pour les non assujetti : faire disparaître les montants TVA */ + +echo \HtmlInput::filter_table("tb_print_ledger", "0,1,2,3,4,5,6", 1); ?>
diff --git a/include/template/acc_ledger_history_sale_extended.php b/include/template/acc_ledger_history_sale_extended.php index cb738620b..24a3ff93a 100644 --- a/include/template/acc_ledger_history_sale_extended.php +++ b/include/template/acc_ledger_history_sale_extended.php @@ -25,8 +25,10 @@ * @brief detail of the list of operation with VAT and items */ bcscale(2); + + ?> -
+
'. ''. ''. - ''. + ''. ''; @@ -1065,13 +1065,13 @@ class Acc_Ledger extends jrn_def_sql $amount->value=(isset(${'amount'.$i}))?${"amount".$i}:'' ; $amount->readonly=$p_readonly; - $amount->javascript=' onChange="format_number(this);checkTotalDirect()"'; + $amount->javascript='onChange="format_number(this);checkTotalDirect()"'; // D/C $deb=new ICheckBox(); $deb->name='ck'.$i; $deb->selected=(isset(${'ck'.$i}))?true:false; $deb->readonly=$p_readonly; - $deb->javascript=' onChange="checkTotalDirect()"'; + $deb->javascript='class="debit-credit" onChange="checkTotalDirect()"'; $str_add_button=($add_card==true)?$this->add_card("-1", $quick_code->id):""; $ret.=''; @@ -1085,7 +1085,9 @@ class Acc_Ledger extends jrn_def_sql ''; $ret.=''; $ret.=''; - $ret.=''; + $ret.=''; $ret.=''; // If readonly == 1 then show CA } @@ -1099,6 +1101,9 @@ class Acc_Ledger extends jrn_def_sql $ret.=sprintf(_("Réconciliation/rapprochements : %s"), $w->input()); } $ret.=create_script("$('".$wDate->id."').focus()"); + // for displaying Credit or Debit + $ret.=create_script("activate_checkbox_side()"); + return $ret; } diff --git a/include/operation_ods_new.inc.php b/include/operation_ods_new.inc.php index 5b5197a0b..811434099 100644 --- a/include/operation_ods_new.inc.php +++ b/include/operation_ods_new.inc.php @@ -25,6 +25,7 @@ * \brief to write into the ledgers ODS a new operation */ if ( ! defined ('ALLOWED') ) die('Appel direct ne sont pas permis'); +\Noalyss\Dbg::echo_file(__FILE__); global $g_user,$g_parameter,$http; From 54e3a654d88fb3ef9f1bdc16c708169c4ad7a00d Mon Sep 17 00:00:00 2001 From: sparkyx Date: Sat, 30 Dec 2023 01:31:57 +0100 Subject: [PATCH 24/37] =?UTF-8?q?Task=20#1749:=20Cases=20=C2=ABD=C3=A9bit?= =?UTF-8?q?=C2=BB=20dans=20les=20OD's=20fait=20remarquer=20si=20d=C3=A9bit?= =?UTF-8?q?=20ou=20cr=C3=A9dit?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- html/js/noalyss_checkbox.js | 49 ++++++++++++++++++++++++++++-- include/class/acc_ledger.class.php | 2 +- 2 files changed, 47 insertions(+), 4 deletions(-) diff --git a/html/js/noalyss_checkbox.js b/html/js/noalyss_checkbox.js index a04fa1469..80ce301ca 100644 --- a/html/js/noalyss_checkbox.js +++ b/html/js/noalyss_checkbox.js @@ -94,12 +94,55 @@ function activate_checkbox_range(p_range_name) { function activate_checkbox_side() { var aCheckBox=$$('.debit-credit') - aCheckBox.forEach((item)=>item.addEventListener('click',function (event) {display_dcside(item)})) + aCheckBox.forEach((item)=>item.addEventListener('click',function (event) { + display_range_dcside(event,item); + display_dcside(item); + } + )); aCheckBox.forEach((item)=>display_dcside(item)) } /** - * Update the SPAN , id based on checkbox id (txtck0), if checked , display Debit otherwise Credit + * Update the range of checkbox in Misc Operation + * @see Acc_Ledger::input + * @param item checkbox to change + * @param event event + */ +function display_range_dcside(evt,item) +{ + if (!evt.shiftKey) { + lastcheck = item; + return; + } + var p_name='debit-credit' + var aName = document.getElementsByClassName(p_name); + + var from = 0; + var end = 0; + for (var i = 0; i < aName.length; i++) { + if (aName[i] == item) { + endcheck = aName[i]; + from = i; + } + if (aName[i] == lastcheck) { + end = i; + } + } + if (from > end) { + let a = from; + from = end; + end = a; + } + var check = (aName[from].checked) ? true : false; + for (x = from; x <= end; x++) { + aName[x].checked = check; + display_dcside(aName[x]); + } + checkTotalDirect() +} + +/** + * Update the SPAN for the range , id based on checkbox id (txtck0), if checked , display Debit otherwise Credit * @param item */ function display_dcside(item) @@ -109,4 +152,4 @@ function display_dcside(item) } else { $('txt'+item.id).update("Crédit") } -} +} \ No newline at end of file diff --git a/include/class/acc_ledger.class.php b/include/class/acc_ledger.class.php index 41650f0b3..8fe002ce2 100644 --- a/include/class/acc_ledger.class.php +++ b/include/class/acc_ledger.class.php @@ -1102,7 +1102,7 @@ class Acc_Ledger extends jrn_def_sql } $ret.=create_script("$('".$wDate->id."').focus()"); // for displaying Credit or Debit - $ret.=create_script("activate_checkbox_side()"); + $ret.=create_script("(function(){activate_checkbox_side()})();"); return $ret; } From c8e96a7f7a51b608b06db1c9ce489d044e897370 Mon Sep 17 00:00:00 2001 From: sparkyx Date: Sat, 30 Dec 2023 15:26:29 +0100 Subject: [PATCH 25/37] =?UTF-8?q?fixup!=20Task=20#1749:=20Cases=20=C2=ABD?= =?UTF-8?q?=C3=A9bit=C2=BB=20dans=20les=20OD's=20fait=20remarquer=20si=20d?= =?UTF-8?q?=C3=A9bit=20ou=20cr=C3=A9dit?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- html/js/acc_ledger.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/html/js/acc_ledger.js b/html/js/acc_ledger.js index e9a1184c3..eec05dfe8 100644 --- a/html/js/acc_ledger.js +++ b/html/js/acc_ledger.js @@ -441,7 +441,7 @@ function ledger_fin_add_row() /** * Add multiple row - * @param p_numrow + * @param string p_elid is the id of element with the number of rows to add, and p_elid+"_ledger" is the type of ledger : M : Misc Operation O : Sales or purchase and F for financial */ function ledger_add_multiple(p_elid) { @@ -452,7 +452,7 @@ function ledger_add_multiple(p_elid) for (i=0;i Date: Sat, 30 Dec 2023 15:37:19 +0100 Subject: [PATCH 26/37] =?UTF-8?q?fixup!=20fixup!=20Task=20#1749:=20Cases?= =?UTF-8?q?=20=C2=ABD=C3=A9bit=C2=BB=20dans=20les=20OD's=20fait=20remarque?= =?UTF-8?q?r=20si=20d=C3=A9bit=20ou=20cr=C3=A9dit?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- html/js/acc_ledger.js | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/html/js/acc_ledger.js b/html/js/acc_ledger.js index eec05dfe8..4816af465 100644 --- a/html/js/acc_ledger.js +++ b/html/js/acc_ledger.js @@ -452,7 +452,7 @@ function ledger_add_multiple(p_elid) for (i=0;i Date: Sat, 30 Dec 2023 15:40:59 +0100 Subject: [PATCH 27/37] =?UTF-8?q?fixup!=20fixup!=20Task=20#1749:=20Cases?= =?UTF-8?q?=20=C2=ABD=C3=A9bit=C2=BB=20dans=20les=20OD's=20fait=20remarque?= =?UTF-8?q?r=20si=20d=C3=A9bit=20ou=20cr=C3=A9dit?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- html/js/acc_ledger.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/html/js/acc_ledger.js b/html/js/acc_ledger.js index 4816af465..41dd5f16f 100644 --- a/html/js/acc_ledger.js +++ b/html/js/acc_ledger.js @@ -454,6 +454,10 @@ function ledger_add_multiple(p_elid) if ( type_ledger == 'F') { ledger_fin_add_row();} if ( type_ledger == 'M') { quick_writing_add_row();} } + if ( type_ledger == 'M') { + var aCheckBox=$$('.debit-credit') + aCheckBox.forEach((item)=>display_dcside(item)) + } } /** * add a line in the form for the purchase ledger From 9cc01d6787ecf782f29b6a0dbf842a0e60ebd951 Mon Sep 17 00:00:00 2001 From: sparkyx Date: Sat, 30 Dec 2023 16:30:24 +0100 Subject: [PATCH 28/37] Task #0002219 PHP 8.1 Compatibility --- include/opening.inc.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/opening.inc.php b/include/opening.inc.php index 295c81044..18fa6cae9 100644 --- a/include/opening.inc.php +++ b/include/opening.inc.php @@ -250,7 +250,7 @@ if ($sa=='step4') $amount='amount'.$idx; $ck='ck'.$idx; $result[$qcode]=$row['j_qcode']; - if (trim($row['j_qcode'])=='') + if (trim($row['j_qcode']??"")=='') $result[$poste]=$row['j_poste']; $result[$amount]=abs($row['solde']); if ($row['solde']>0) From ead8d5f238705ea70fe187a068ab9dc69e9a40a2 Mon Sep 17 00:00:00 2001 From: sparkyx Date: Sat, 30 Dec 2023 16:30:46 +0100 Subject: [PATCH 29/37] Cosmetic Totaux OD --- include/operation_ods_new.inc.php | 51 +++++++++++++++++++------------ 1 file changed, 31 insertions(+), 20 deletions(-) diff --git a/include/operation_ods_new.inc.php b/include/operation_ods_new.inc.php index 811434099..7a14b09c3 100644 --- a/include/operation_ods_new.inc.php +++ b/include/operation_ods_new.inc.php @@ -86,30 +86,41 @@ $default_currency=new Acc_Currency($cn,0); echo $ledger->input($p_post); +$style=' style="display:inline-block;width: 15rem;text-align: right"'; +?> +
+
From 6d053fe5e2b46b06f407771b2708851e4414b4fb Mon Sep 17 00:00:00 2001 From: sparkyx Date: Sat, 23 Dec 2023 11:06:02 +0100 Subject: [PATCH 18/37] PHP8.1 Compatibility --- include/template/ledger_detail_bottom.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/template/ledger_detail_bottom.php b/include/template/ledger_detail_bottom.php index ecef286b1..0512a3c8c 100644 --- a/include/template/ledger_detail_bottom.php +++ b/include/template/ledger_detail_bottom.php @@ -208,10 +208,10 @@ if ($aRap != null ) { array($internal)); // add additional tax if any $add=$operation->get_sum_other_tax(); - $amount=bcadd($amount,$add,2); + $amount=bcadd($amount??0,$add??0,2); break; } - $total_rec=bcadd($total_rec,$amount); + $total_rec=bcadd($total_rec,$amount??0); $str="modifyOperation(".$aRap[$e].",".$gDossier.")"; // If write access , allow to drop Reconciles operations From a77dfacbf8bc4c64eeb049ef5fd97a0c6cf1307e Mon Sep 17 00:00:00 2001 From: sparkyx Date: Sat, 23 Dec 2023 16:55:42 +0100 Subject: [PATCH 19/37] 0002317: Paiement : forcer la fiche pour les banques --- include/class/acc_ledger.class.php | 2 +- include/class/acc_ledger_fin.class.php | 3 +- include/class/acc_ledger_purchase.class.php | 23 +++-- include/class/acc_ledger_sale.class.php | 27 ++++-- .../include/class/acc_ledger_purchaseTest.php | 97 +++++++++++++++++++ .../include/class/acc_ledger_saleTest.php | 90 ++++++++++++++++- 6 files changed, 222 insertions(+), 20 deletions(-) diff --git a/include/class/acc_ledger.class.php b/include/class/acc_ledger.class.php index 94f89cb11..267b5f79b 100644 --- a/include/class/acc_ledger.class.php +++ b/include/class/acc_ledger.class.php @@ -128,7 +128,7 @@ class Acc_Ledger extends jrn_def_sql } /** * @brief Return the type of a ledger (ACH,VEN,ODS or FIN) or GL - * + * @return string FIN ODS ACH VEN or GL if id == 0 */ function get_type() { diff --git a/include/class/acc_ledger_fin.class.php b/include/class/acc_ledger_fin.class.php index 5ad81d64e..166037523 100644 --- a/include/class/acc_ledger_fin.class.php +++ b/include/class/acc_ledger_fin.class.php @@ -1136,11 +1136,12 @@ class Acc_Ledger_Fin extends Acc_Ledger } /** - * return the fiche_id of the bank + * @brief find and FICHE.F_ID of the bank or -1 if not found */ function get_bank() { $bank_id=$this->db->get_value('select jrn_def_bank from jrn_def where jrn_def_id=$1', array($this->id)); + if (empty($bank_id)) return -1; return $bank_id; } diff --git a/include/class/acc_ledger_purchase.class.php b/include/class/acc_ledger_purchase.class.php index f9a6ca35d..6f32d645c 100644 --- a/include/class/acc_ledger_purchase.class.php +++ b/include/class/acc_ledger_purchase.class.php @@ -950,20 +950,22 @@ class Acc_Ledger_Purchase extends Acc_Ledger $mp=new Acc_Payment($this->db,$e_mp); $mp->load(); - /* fiche */ - if ($mp->get_parameter('qcode') == '') - $fqcode=${'e_mp_qcode_'.$e_mp}; - else - $fqcode=$mp->get_parameter('qcode'); - - $acfiche = new Fiche($this->db); - $acfiche->get_by_qcode($fqcode); - /* jrnx */ $acseq=$this->db->get_next_seq('s_grpt'); $acjrn=new Acc_Ledger($this->db,$mp->get_parameter('ledger_target')); $acinternal=$acjrn->compute_internal_code($acseq); - + /* + * for the use of the card of the bank + */ + if ( $acjrn->get_type()=='FIN') { + $acjrn=new Acc_Ledger_Fin($this->db, $mp->get_parameter('ledger_target')); + $acfiche=new Fiche($this->db,$acjrn->get_bank()); + $fqcode=$acfiche->strAttribut(ATTR_DEF_QUICKCODE); + } else { + $fqcode = ${'e_mp_qcode_' . $e_mp}; + $acfiche = new Fiche($this->db); + $acfiche->get_by_qcode($fqcode); + } /* Insert paid by */ $acc_pay=new Acc_Operation($this->db); $acc_pay->date=$e_date; @@ -2141,6 +2143,7 @@ EOF; return $array; } + } diff --git a/include/class/acc_ledger_sale.class.php b/include/class/acc_ledger_sale.class.php index c8ca25eb4..69da7c3aa 100644 --- a/include/class/acc_ledger_sale.class.php +++ b/include/class/acc_ledger_sale.class.php @@ -242,9 +242,13 @@ class Acc_Ledger_Sale extends Acc_Ledger { $this->check_currency_setting($p_currency_code); } - /*!\brief insert into the database, it calls first the verify function, - * change the value of this->jr_id and this->jr_internal - * * It generates the document if gen_invoice is set and save the middle of payment if any ($e_mp) + /*! + * \brief insert into the database, it calls first the verify function, + * store the value of the inserted operation in $this->jr_id and this->jr_internal + * + * It generates the document if gen_invoice is set and save the middle of payment if any ($e_mp) + * + * It also create a second operation if there is a payment * * \param $p_array is usually $_POST or a predefined operation * \return string : internal number @@ -653,16 +657,25 @@ class Acc_Ledger_Sale extends Acc_Ledger { $mp = new Acc_Payment($this->db, $e_mp); $mp->load(); - /* fiche */ - $fqcode = ${'e_mp_qcode_' . $e_mp}; - $acfiche = new Fiche($this->db); - $acfiche->get_by_qcode($fqcode); /* jrnx */ $acseq = $this->db->get_next_seq('s_grpt'); $acjrn = new Acc_Ledger($this->db, $mp->get_parameter('ledger_target')); $acinternal = $acjrn->compute_internal_code($acseq); + /* + * for the use of the card of the bank + */ + if ( $acjrn->get_type()=='FIN') { + $acjrn=new Acc_Ledger_Fin($this->db, $mp->get_parameter('ledger_target')); + $acfiche=new Fiche($this->db,$acjrn->get_bank()); + $fqcode=$acfiche->strAttribut(ATTR_DEF_QUICKCODE); + } else { + $fqcode = ${'e_mp_qcode_' . $e_mp}; + $acfiche = new Fiche($this->db); + $acfiche->get_by_qcode($fqcode); + } + /* Insert paid by */ $acc_pay = new Acc_Operation($this->db); $acc_pay->date = $pay_date; diff --git a/unit-test/include/class/acc_ledger_purchaseTest.php b/unit-test/include/class/acc_ledger_purchaseTest.php index 9f17ab819..e7c13a162 100644 --- a/unit-test/include/class/acc_ledger_purchaseTest.php +++ b/unit-test/include/class/acc_ledger_purchaseTest.php @@ -222,6 +222,103 @@ class Acc_Ledger_PurchaseTest extends TestCase $this->clean_operation(); } + /** + * @covers Acc_Ledger_Purchase::insert + */ + public function testInsertPayment() + { + global $g_connection; + $array=$this->array; + $array["mt"]="1572704002.1732"; + $array["pa_id"]=array(2); + $array["op"]=array(0); + $array["amount_t0"]=658.25; + $array['hplan']=array(array(-1)); + $array["val"]=array(array(658.25)); + $sql=" + from quant_purchase + join jrnx using(j_id) + join jrn on (jr_grpt_id=j_grpt) + where + jr_mt='1572704002.1732' + and j_qcode='LOYER' + "; + + $this->clean_operation(); + $array=array_merge($array, array("e_march1"=>"DOCUME", + "e_march1_price"=>18.25, + "e_quant1"=>"", + "htva_march1"=>18.25, + "e_march1_tva_id"=>1, + "e_march1_tva_amount"=>22.08, + "tva_march1"=>3.83, + "tvac_march1"=>22.08 + ,"p_currency_rate"=>1 + ,"p_currency_code"=>0 + )); + + // create a payment method with a valid card + $payment_methodSQL=$this->insert_payment_method(); + $array['mp_date'] =""; + $array['acompte'] = 0; + $array['e_mp'] = $payment_methodSQL->getp("mp_id"); + $array['e_mp_qcode_'.$array['e_mp']]='CDOLLAR'; + $this->object->insert($array); + + $this->assertEquals($array['htva_march0'],$g_connection->get_value("select qp_price ".$sql)); + + // check payment + $nQuant_FinId=$this->get_reconcilied_operation(); + + $quant_fin=new Quant_Fin_SQL($g_connection,$nQuant_FinId); + $nQuantFin_Amount=$quant_fin->getp("qf_amount") ; + + $this->assertTrue($nQuantFin_Amount == -658.25,"error : purchase 658.25 and payment {$nQuantFin_Amount} not equal "); + + // check card used in bank + $expected_bank=$g_connection->get_value(" + select jrn_def_bank + from + jrn_def jd1 + join payment_method pm1 on (jd1.jrn_def_id=pm1.mp_jrn_def_id) + where mp_id=$1",[$array['e_mp']]); + + $found_bank =$quant_fin->getp("qf_bank"); + + $this->assertTrue($expected_bank==$found_bank,"error : payment done with a wrong card {$found_bank} instead of $expected_bank"); + $payment_methodSQL->delete(); + $this->clean_operation(); + + } + + private function insert_payment_method() + { + global $g_connection; + $payment_methodSQl=new Payment_method_SQL($g_connection); + $payment_methodSQl->from_array([ + "mp_lib"=>"caisse" + ,"mp_jrn_def_id"=>1 + ,'mp_fd_id'=>3 + ,"jrn_def_id"=>3 + ]); + $payment_methodSQl->insert(); + return $payment_methodSQl; + + + } + /** + * @brief return the reconcilied operation of this->object + * @return mixed|string + * @throws Exception + */ + private function get_reconcilied_operation() + { + global $g_connection; + $nValue=$g_connection->get_value("select jra_concerned + from jrn_rapt where jr_id=$1",[$this->object->jr_id]); + $nQuant_FinId=$g_connection->get_value("select qf_id from quant_fin where jr_id=$1",[$nValue]); + return $nQuant_FinId; + } /** * @brief set special attributes to test NOT DEDUCTIBLE : private, VAT and tax * @global type $g_connection diff --git a/unit-test/include/class/acc_ledger_saleTest.php b/unit-test/include/class/acc_ledger_saleTest.php index 2d821f2ba..de982eff6 100644 --- a/unit-test/include/class/acc_ledger_saleTest.php +++ b/unit-test/include/class/acc_ledger_saleTest.php @@ -83,8 +83,23 @@ class Acc_Ledger_SaleTest extends TestCase private function clean_operation() { global $g_connection; - $g_connection->exec_sql("delete from jrn where jr_mt=$1", ["1572714478.3155"]); + $mt="1572714478.3155"; + //delete reconcilied operations + $g_connection->exec_sql(" + delete from jrn + where jr_id in (select jr2.jr_id + from jrn_rapt ra1 join jrn jr2 on (ra1.jr_id=jr2.jr_id) + where jr2.jr_mt=$1)",[$mt]); + + $g_connection->exec_sql(" + delete from jrn + where jr_id in (select jr2.jr_id + from jrn_rapt ra1 join jrn jr2 on (ra1.jra_concerned=jr2.jr_id) + where jr2.jr_mt=$1)",[$mt]); + + $g_connection->exec_sql("delete from jrn where jr_mt=$1", [$mt]); $g_connection->exec_sql("delete from jrnx where j_grpt not in (select jr_grpt_id from jrn)"); + $g_connection->exec_sql("alter sequence s_jrn_pj2 restart with 40"); } /** @@ -168,6 +183,78 @@ class Acc_Ledger_SaleTest extends TestCase } + + /** + * @covers Acc_Ledger_Sale::insert + */ + public function testInsertPayment() + { + global $g_connection; + $this->clean_operation(); + $cnt=$g_connection->get_value("select count(*) from jrn where jr_mt=$1",["1572714478.3155"]); + $this->assertEquals(0,$cnt); + + $sql=" + from quant_sold + join jrnx using(j_id) + join jrn on (jr_grpt_id=j_grpt) + where + jr_mt='1572714478.3155' + and j_qcode='MARCHA' + "; + $array=$this->array; + $array["pa_id"]=array(2); + $array["op"]=array(0, 1); + $array["amount_t0"]=24.2; + $array["hplan"]=array(array(-1), array(-1)); + $array["val"]=array(array(24, 2), array(1212.5)); + $array["mt"]="1572714478.3155"; + + // create a payment method with a valid card + $array['mp_date'] =""; + $array['acompte'] = 0; + $array['e_mp'] = 1; + + $this->object->insert($array); + $this->assertEquals($array['htva_march1'],$g_connection->get_value("select qs_price ".$sql)); + + // check payment + $nQuant_FinId=$this->get_reconcilied_operation(); + + $quant_fin=new Quant_Fin_SQL($g_connection,$nQuant_FinId); + $nQuantFin_Amount=$quant_fin->getp("qf_amount") ; + + $this->assertTrue($nQuantFin_Amount ==bcadd( $array['tvac_march1'],$array['tvac_march0']),"error : sale {$array['tvac_march1']} and payment {$nQuantFin_Amount} not equal "); + + // check card used in bank + $expected_bank=$g_connection->get_value(" + select jrn_def_bank + from + jrn_def jd1 + join payment_method pm1 on (jd1.jrn_def_id=pm1.mp_jrn_def_id) + where mp_id=$1",[$array['e_mp']]); + + $found_bank =$quant_fin->getp("qf_bank"); + + $this->assertTrue($expected_bank==$found_bank,"error : payment done with a wrong card {$found_bank} instead of $expected_bank"); + + $this->clean_operation(); + + } + + /** + * @brief return the reconcilied operation of this->object + * @return mixed|string + * @throws Exception + */ + private function get_reconcilied_operation() + { + global $g_connection; + $nValue=$g_connection->get_value("select jra_concerned + from jrn_rapt where jr_id=$1",[$this->object->jr_id]); + $nQuant_FinId=$g_connection->get_value("select qf_id from quant_fin where jr_id=$1",[$nValue]); + return $nQuant_FinId; + } /** * @covers Acc_Ledger_Sale::confirm */ @@ -240,4 +327,5 @@ class Acc_Ledger_SaleTest extends TestCase $ret=$this->object->get_detail_sale(92,103,'unpaid'); $this->assertEquals(5,Database::num_row($ret),'only unpaid operations'); } + } From fe6b45c42bce0ddd2c912b375df943a477c0ce2d Mon Sep 17 00:00:00 2001 From: sparkyx Date: Sun, 24 Dec 2023 11:57:13 +0100 Subject: [PATCH 20/37] Bug fix : sent emails not counted properly --- include/class/acc_ledger.class.php | 2 +- include/class/sendmail.class.php | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/include/class/acc_ledger.class.php b/include/class/acc_ledger.class.php index 267b5f79b..01f1b7c3c 100644 --- a/include/class/acc_ledger.class.php +++ b/include/class/acc_ledger.class.php @@ -1943,7 +1943,7 @@ class Acc_Ledger extends jrn_def_sql $empl->get_by_qcode($e_mp_qcode); if ($empl->empty_attribute(ATTR_DEF_ACCOUNT)==true) { - throw new Exception(_("Celui qui paie n' a pas de poste comptable"), + throw new Exception(_("Le moyen de paiement choisi n'a pas de poste comptable"), 20); } /* get the account and explode if necessary */ diff --git a/include/class/sendmail.class.php b/include/class/sendmail.class.php index f06248651..d8cc8567d 100644 --- a/include/class/sendmail.class.php +++ b/include/class/sendmail.class.php @@ -109,6 +109,7 @@ class Sendmail extends Sendmail_Core $email_sent = $p_repo->get_value ('select de_sent_email from dossier_sent_email where dos_id = $1 and de_date=$2', array($p_dossier_id,$p_date)); + if ($email_sent == "") return 0; return $email_sent; @@ -123,7 +124,7 @@ class Sendmail extends Sendmail_Core { if ( $p_dossier == -1) return ; $email_sent = $this->get_email_sent($p_repo,$p_dossier,$p_date); - if ( $email_sent == 0 ){ + if ( empty($email_sent) ){ $p_repo->exec_sql("insert into public.dossier_sent_email(de_sent_email,dos_id,de_date) values($1,$2,$3)", array(1,$p_dossier,$p_date)); return; From 682e283177a1475193d80f0a352789b0802e9c86 Mon Sep 17 00:00:00 2001 From: sparkyx Date: Sun, 24 Dec 2023 15:31:53 +0100 Subject: [PATCH 21/37] PhpUnit : test --- ...meter_folder.Test.php => noalyss_parameter_folderTest.php} | 0 unit-test/include/class/pdf_anc_acc_listTest.php | 4 ++-- 2 files changed, 2 insertions(+), 2 deletions(-) rename unit-test/include/class/{noalyss_parameter_folder.Test.php => noalyss_parameter_folderTest.php} (100%) diff --git a/unit-test/include/class/noalyss_parameter_folder.Test.php b/unit-test/include/class/noalyss_parameter_folderTest.php similarity index 100% rename from unit-test/include/class/noalyss_parameter_folder.Test.php rename to unit-test/include/class/noalyss_parameter_folderTest.php diff --git a/unit-test/include/class/pdf_anc_acc_listTest.php b/unit-test/include/class/pdf_anc_acc_listTest.php index 8af94b519..19e71d0b2 100644 --- a/unit-test/include/class/pdf_anc_acc_listTest.php +++ b/unit-test/include/class/pdf_anc_acc_listTest.php @@ -124,8 +124,8 @@ EOF; $pdf_anc_acc=new PDF_Anc_Acc_List($anc_acc_list); $pdf_anc_acc->export_pdf()->Output(__DIR__."/file/pdf_anc_acc_list-card-activity.pdf","F"); $filesize=filesize(__DIR__."/file/pdf_anc_acc_list-card-activity.pdf"); - $this->assertTrue($filesize==77276, - __DIR__."/file/pdf_anc_acc_list-card-activity.pdf incorrect"); + $this->assertTrue($filesize >= 77276 && $filesize <= 77287, + __DIR__."/file/pdf_anc_acc_list-card-activity.pdf $filesize incorrect"); // By Account / Activity $anc_acc_list=new Anc_Acc_List($g_connection); From cafeec15f58f69572e71797860903f7fed930c4d Mon Sep 17 00:00:00 2001 From: sparkyx Date: Tue, 26 Dec 2023 11:25:35 +0100 Subject: [PATCH 22/37] =?UTF-8?q?Task=20#0002318:=20Envoi=20email=20:=20fo?= =?UTF-8?q?rcer=20le=20domaine=20de=20l'exp=C3=A9diteur=20Adapter=20le=20f?= =?UTF-8?q?ichier=20config?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- include/class/sendmail.class.php | 40 +++- include/config.inc.example | 5 +- include/lib/config_file.php | 276 +++++++++++++---------- include/lib/sendmail_core.class.php | 4 +- unit-test/include/class/sendmailTest.php | 187 +++++++++++++++ 5 files changed, 386 insertions(+), 126 deletions(-) create mode 100644 unit-test/include/class/sendmailTest.php diff --git a/include/class/sendmail.class.php b/include/class/sendmail.class.php index d8cc8567d..006298fb4 100644 --- a/include/class/sendmail.class.php +++ b/include/class/sendmail.class.php @@ -96,6 +96,7 @@ class Sendmail extends Sendmail_Core { $max_email = $p_repo->get_value("select dos_email from ac_dossier where dos_id=$1", array($p_dossier_id)); + if ($max_email == "") return 0; return $max_email; } /** @@ -114,6 +115,43 @@ class Sendmail extends Sendmail_Core } + + /** + * @brief check if there is a mandatory domain, if yes + * @return void + * @throws Exception + */ + function verify() + { + try { + parent::verify(); + } catch (\Exception $e) { + throw $e; + } + if ( defined('ALLOWED_EMAIL_DOMAIN') ) + { + if ( ALLOWED_EMAIL_DOMAIN != "") + { + $as_domain=explode(",", ALLOWED_EMAIL_DOMAIN); + $valid=0; + foreach ($as_domain as $domain) { + $domain="@$domain"; + if (strpos($this->from,$domain) != 0 ) { + $valid=1; + break; + } + } + if ( $valid == 0) { + throw new Exception("Domaine email {$this->from} interdit",EXC_INVALID); + + } + + } + + } + + } + /** * @brief Add $p_amount_email to email sent * @param $p_repo Database @@ -124,7 +162,7 @@ class Sendmail extends Sendmail_Core { if ( $p_dossier == -1) return ; $email_sent = $this->get_email_sent($p_repo,$p_dossier,$p_date); - if ( empty($email_sent) ){ + if ( $email_sent == 0 ){ $p_repo->exec_sql("insert into public.dossier_sent_email(de_sent_email,dos_id,de_date) values($1,$2,$3)", array(1,$p_dossier,$p_date)); return; diff --git a/include/config.inc.example b/include/config.inc.example index 114108b1b..f98304544 100644 --- a/include/config.inc.example +++ b/include/config.inc.example @@ -88,4 +88,7 @@ define ("DEBUGNOALYSS",0); // define ("AUDIT_ENABLE",true); // // display a captcha -// define ("NOALYSS_CAPTCHA",true); \ No newline at end of file +// define ("NOALYSS_CAPTCHA",true); +// When sending an email , the domain of this email must be in comma separated list , +// if the list is an empty string then all the domain are allowed +// define ('ALLOWED_EMAIL_DOMAIN',''); \ No newline at end of file diff --git a/include/lib/config_file.php b/include/lib/config_file.php index b3d8a9d42..19eee50fc 100644 --- a/include/lib/config_file.php +++ b/include/lib/config_file.php @@ -19,7 +19,8 @@ // Copyright Author Dany De Bontridder danydb@aevalys.eu -/*!\file +/*! + \file * \brief functions concerning the config file config.inc.php. The domain is not set into the form for security issues */ @@ -40,7 +41,8 @@ function is_unix() } -/*!\brief +/* + * !\brief *\param array with the index * - ctmp temporary folder * - cpath path to postgresql @@ -112,63 +114,60 @@ function config_file_form($p_array=null) require NOALYSS_TEMPLATE.'/template_config_form.php'; } /** - * Display the content of the config.inc.php with variables + * @brief Display the content of the config.inc.php with variables * @param type $p_array * @param type $from_setup * @param type $p_os */ -function display_file_config($p_array,$from_setup=1,$p_os=1) +function display_file_config($p_array, $from_setup = 1, $p_os = 1) { extract($p_array, EXTR_SKIP); print ('$name) == "") + if (trim($this->$name??"") == "") { - throw new Exception( sprintf(_("%s est vide"),$name)); + throw new Exception( sprintf(_("%s est vide"),$name),EXC_INVALID); } } } diff --git a/unit-test/include/class/sendmailTest.php b/unit-test/include/class/sendmailTest.php new file mode 100644 index 000000000..1b327c82f --- /dev/null +++ b/unit-test/include/class/sendmailTest.php @@ -0,0 +1,187 @@ + + * + * 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 2 + * 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, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * + * Author : Dany De Bontridder danydb@noalyss.eu $(DATE) + */ + +/** + * @file + * @brief noalyss + */ + +use PHPUnit\Framework\TestCase; + +require DIRTEST . '/global.php'; + +define ("ALLOWED_EMAIL_DOMAIN","linux.org,localhost"); + +/** + * @testdox Class SendmailTest : used for ... + * @backupGlobals enabled + * @coversDefaultClass Sendmail + */ +class SendmailTest extends TestCase +{ + + /** + * @testdox verify that email has the mandatory filed + * @covers Sendmail::verify + * @backupGlobals enabled + */ + function testVerifyCorrect() + { + $sendmail=new \Sendmail(); + $sendmail->mailto("dany@gmail.com"); + $sendmail->set_from("web@localhost"); + $sendmail->set_subject("Test envoi"); + $sendmail->set_message("corps du message"); + try { + $sendmail->verify(); + $this->assertTrue(true); + } catch (\Exception $e) { + $this->assertTrue(false," check email fails"); + } + + } + /** + * @testdox verify that email fails it mailto is absent + * @covers Sendmail::verify + * @backupGlobals enabled + */ + function testVerifyFailsMailto() + { + $sendmail=new \Sendmail(); + $sendmail->mailto(""); + $sendmail->set_from("web@localhost"); + $sendmail->set_subject("Test envoi"); + $sendmail->set_message("corps du message"); + $this->expectExceptionCode(EXC_INVALID); + $sendmail->verify(); + + } + /** + * @testdox verify that email fails it recipient is absent + * @covers Sendmail::verify + * @backupGlobals enabled + */ + function testVerifyFailsFrom() + { + $sendmail=new \Sendmail(); + $sendmail->mailto("web@localhost"); + $sendmail->set_from(""); + $sendmail->set_subject("Test envoi"); + $sendmail->set_message("corps du message"); + $this->expectExceptionCode(EXC_INVALID); + $sendmail->verify(); + + } + /** + * @testdox verify that email fails it subject is absent + * @covers Sendmail::verify + * @backupGlobals enabled + */ + function testVerifyFailsSubject() + { + $sendmail=new \Sendmail(); + $sendmail->mailto("web@localhost"); + $sendmail->set_from("dany@gmail.com"); + $sendmail->set_message("corps du message"); + $this->expectExceptionCode(EXC_INVALID); + $sendmail->verify(); + + } + /** + * @testdox verify that email fails it content is absent + * @covers Sendmail::verify + * @backupGlobals enabled + */ + function testVerifyFailsContent() + { + $sendmail=new \Sendmail(); + $sendmail->mailto(""); + $sendmail->set_from("web@localhost"); + $sendmail->set_subject("Test envoi"); + $this->expectExceptionCode(EXC_INVALID); + $sendmail->verify(); + + } + /** + * @testdox Check that the from of email respect Domain : domain allowed + * @covers Sendmail::verify + * @backupGlobals enabled + */ + function testVerifyDomainFails() + { + $sendmail=new \Sendmail(); + $sendmail->mailto("web@localhost"); + $sendmail->set_from("dany@gmail.com"); + $sendmail->set_subject("Test envoi"); + $sendmail->set_message("corps du message"); + + $this->expectExceptionCode(EXC_INVALID); + $sendmail->verify(); + + } + /** + * @testdox Check that the from of email respect Domain : domain forbidden + * @covers Sendmail::verify + * @backupGlobals enabled + */ + function testVerifyDomainSuccess() + { + $sendmail=new \Sendmail(); + $sendmail->mailto("web@localhost"); + $sendmail->set_from("dany@linux.org"); + $sendmail->set_subject("Test envoi"); + $sendmail->set_message("corps du message"); + + $sendmail->verify(); + $this->assertTrue(true); + + } + /* + *@testdox test increment email + *@covers Sendmail::increment_mail Sendmail::get_email_sent + */ + function testIncrement_mail() + { + $cn=new \Database(); + $dos_id=DOSSIER; + $sendmail=new Sendmail(); + $cn->exec_sql("delete from dossier_sent_email where dos_id=$dos_id and de_date='20100101'"); + $email_sent=$sendmail->get_email_sent($cn, $dos_id, '20100101'); + $this->assertTrue($email_sent == 0,"error cannot count email get $email_sent"); + + $sendmail->increment_mail($cn, $dos_id, "20100101"); + $email_sent=$sendmail->get_email_sent($cn, $dos_id, '20100101'); + $this->assertTrue($email_sent == 1,"error cannot count email get $email_sent"); + + $sendmail->increment_mail($cn, $dos_id, "20100101"); + $email_sent=$sendmail->get_email_sent($cn, $dos_id, '20100101'); + $this->assertTrue($email_sent == 2,"error cannot count email"); + + $sendmail->increment_mail($cn, $dos_id, "20100101"); + $email_sent=$sendmail->get_email_sent($cn, $dos_id, '20100101'); + $this->assertTrue($email_sent == 3,"error cannot count email $email_sent"); + + $cn->exec_sql("delete from dossier_sent_email where dos_id=$dos_id and de_date='20100101'"); + + } +} \ No newline at end of file From 15be1c4e64fd65b27fdf395255e9399e8ff3d089 Mon Sep 17 00:00:00 2001 From: sparkyx Date: Sat, 30 Dec 2023 01:31:57 +0100 Subject: [PATCH 23/37] =?UTF-8?q?Task=20#1749:=20Cases=20=C2=ABD=C3=A9bit?= =?UTF-8?q?=C2=BB=20dans=20les=20OD's=20fait=20remarquer=20si=20d=C3=A9bit?= =?UTF-8?q?=20ou=20cr=C3=A9dit?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- html/js/noalyss_checkbox.js | 22 +++++++++++++++++++++- include/class/acc_ledger.class.php | 13 +++++++++---- include/operation_ods_new.inc.php | 1 + 3 files changed, 31 insertions(+), 5 deletions(-) diff --git a/html/js/noalyss_checkbox.js b/html/js/noalyss_checkbox.js index 61272c176..a04fa1469 100644 --- a/html/js/noalyss_checkbox.js +++ b/html/js/noalyss_checkbox.js @@ -87,6 +87,26 @@ function activate_checkbox_range(p_range_name) { checkbox_set_range(event, elt, p_range_name); },false)); } -; +/** + * Checkbox for Debit - Credit , from Misc Operation + */ +function activate_checkbox_side() +{ + var aCheckBox=$$('.debit-credit') + aCheckBox.forEach((item)=>item.addEventListener('click',function (event) {display_dcside(item)})) + aCheckBox.forEach((item)=>display_dcside(item)) +} +/** + * Update the SPAN , id based on checkbox id (txtck0), if checked , display Debit otherwise Credit + * @param item + */ +function display_dcside(item) +{ + if (item.checked == true) { + $('txt'+item.id).update("Débit") + } else { + $('txt'+item.id).update("Crédit") + } +} diff --git a/include/class/acc_ledger.class.php b/include/class/acc_ledger.class.php index 01f1b7c3c..41650f0b3 100644 --- a/include/class/acc_ledger.class.php +++ b/include/class/acc_ledger.class.php @@ -995,7 +995,7 @@ class Acc_Ledger extends jrn_def_sql ''._('Poste').$info_poste.''._('Libellé').''._('Montant').''._('Débit').''._('Côté').'
'.$line_desc->input().''.$amount->input().''.$deb->input().''.$deb->input() + .'' + .'
+ + + + + + + + + + + -echo '
'; -echo '
+ > + + > + + > +
get_code()?> + > + + > +
'. - ''.td(''). - td(_('Débit')) . - '' . - td(_('Crédit')) . - ' ' . - td(_('Difference')) . - ' '. - ''; -// For currency -echo ''.td($default_currency->get_code()). - td(_('Débit')) . - '' . - td(_('Crédit')) . - ' ' . - td(). - ''; -echo '
'; + + + -echo ''; + + +amount_id="totalDeb"; From 1b5b9781ca7cfbc0649db27a1fced5f8031753ed Mon Sep 17 00:00:00 2001 From: sparkyx Date: Fri, 12 Jan 2024 12:59:23 +0100 Subject: [PATCH 30/37] OPTION_CARD : Correct options for FollowUp --- include/class/card_multiple.class.php | 2 +- include/template/form_ledger_detail.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/include/class/card_multiple.class.php b/include/class/card_multiple.class.php index b7a2f3c82..d9932d250 100644 --- a/include/class/card_multiple.class.php +++ b/include/class/card_multiple.class.php @@ -146,7 +146,7 @@ class Card_Multiple select contact_option_ref_id from action_person_option join action_person a on (a.ap_id=action_person_id) - where f_id=$2)",[$p_action_person_id,$fiche_id]); + where f_id=$2 and ag_id=$3)",[$p_action_person_id,$fiche_id,$ag_id]); // delete disable $cn->exec_sql("delete diff --git a/include/template/form_ledger_detail.php b/include/template/form_ledger_detail.php index e72cd2bc5..37e192928 100644 --- a/include/template/form_ledger_detail.php +++ b/include/template/form_ledger_detail.php @@ -7,7 +7,7 @@ */ $default_currency=new Acc_Currency(Dossier::connect(),0); - +\Noalyss\Dbg::echo_file(__FILE__); ?>

get_name()?>

From 67b5ae90d0dcc9253088ac2155b36f8b44d81555 Mon Sep 17 00:00:00 2001 From: sparkyx Date: Fri, 12 Jan 2024 17:54:46 +0100 Subject: [PATCH 31/37] Bug Fiche Option --- include/class/follow_up_other_concerned.class.php | 3 ++- include/export/export_follow_up_contact_csv.php | 13 +++++++++++-- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/include/class/follow_up_other_concerned.class.php b/include/class/follow_up_other_concerned.class.php index d1ba3aea9..1c4a28c47 100644 --- a/include/class/follow_up_other_concerned.class.php +++ b/include/class/follow_up_other_concerned.class.php @@ -190,7 +190,8 @@ EOF; where apo2.contact_option_ref_id =$1 and ap.f_id=$2 - ", array($pa_Column[$i]['cor_id'], $p_fid)); + and ap.ag_id=$3 + ", array($pa_Column[$i]['cor_id'], $p_fid, $this->ag_id)); $r.=td($value); } $r.=''.$remove.''; diff --git a/include/export/export_follow_up_contact_csv.php b/include/export/export_follow_up_contact_csv.php index ebd929fda..5b1251962 100644 --- a/include/export/export_follow_up_contact_csv.php +++ b/include/export/export_follow_up_contact_csv.php @@ -44,7 +44,7 @@ join fiche_detail f on (a.f_id=f.f_id) join fiche_def fd on (fd.fd_id=f1.fd_id) join jnt_fic_attr jfa on (fd.fd_id=jfa.fd_id and jfa.ad_id=f.ad_id) where ag_id=$1 -order by f1.fd_id, a.f_id,jnt_order;;",[$ag_id]); +order by f1.fd_id, a.f_id,jnt_order",[$ag_id]); $nb=count($aRow); $lastcat=0;$lastcard=0; @@ -105,5 +105,14 @@ where ag_id=$1 and f_id=$2 order by cor_id",array($ag_id,$lastcard)); $csv->add($aRow[$i]['ad_value']); } - +$aOption=$cn->get_array(" select ap_value +from +action_person a +join action_person_option apo on (a.ap_id=apo.action_person_id) +join contact_option_ref cor on (cor.cor_id=apo.contact_option_ref_id) +where ag_id=$1 and f_id=$2 order by cor_id",array($ag_id,$lastcard)); +$nb_option=count($aOption); +for ($h=0;$h < $nb_option;$h++) { + $csv->add($aOption[$h]['ap_value']); +} $csv->write(); \ No newline at end of file From 4db377ebbac321343bb8f52e706c3ff07ccaaf20 Mon Sep 17 00:00:00 2001 From: sparkyx Date: Sun, 7 Jan 2024 17:14:24 +0100 Subject: [PATCH 32/37] PHP8.1 compatibility --- include/class/acc_ledger_fin.class.php | 2 +- include/template/dashboard.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/include/class/acc_ledger_fin.class.php b/include/class/acc_ledger_fin.class.php index 166037523..de3a2ea72 100644 --- a/include/class/acc_ledger_fin.class.php +++ b/include/class/acc_ledger_fin.class.php @@ -654,7 +654,7 @@ class Acc_Ledger_Fin extends Acc_Ledger td(_("Ancien solde")). td(nbm($solde).$cur, 'class="num"') ); - $new_solde=bcadd($solde, $tot_amount); + $new_solde=bcadd($solde??0, $tot_amount??0); $r.=tr( td(_("Nouveau solde")). td(nbm($new_solde).$cur, ' class="num"') diff --git a/include/template/dashboard.php b/include/template/dashboard.php index 5b1b7c0e7..cd32f25cd 100644 --- a/include/template/dashboard.php +++ b/include/template/dashboard.php @@ -122,7 +122,7 @@ for($i=0;$i - + From f8bff0171eae46c5ec1106df28488fa62ed05d38 Mon Sep 17 00:00:00 2001 From: sparkyx Date: Sun, 7 Jan 2024 17:17:10 +0100 Subject: [PATCH 33/37] =?UTF-8?q?Task=200002128:=20Cl=C3=B4ture=20comptabi?= =?UTF-8?q?lit=C3=A9=20fran=C3=A7aise?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- html/ajax_misc.php | 13 +- html/js/acc_ledger.js | 1812 +++++++++-------- include/ajax/ajax_operation_exercice.php | 153 ++ include/class/acc_ledger.class.php | 28 - include/class/operation_closing.class.php | 43 + include/class/operation_exercice.class.php | 156 ++ include/class/operation_opening.class.php | 146 ++ include/constant.php | 1 + .../operation_exercice_detail_sql.class.php | 79 + .../database/operation_exercice_sql.class.php | 81 + include/operation_exercice.inc.php | 49 + .../template/operation_exercice-input_row.php | 114 ++ .../operation_exercice-input_source.php | 129 ++ sql/upgrade.sql | 56 +- 14 files changed, 2027 insertions(+), 833 deletions(-) create mode 100644 include/ajax/ajax_operation_exercice.php create mode 100644 include/class/operation_closing.class.php create mode 100644 include/class/operation_exercice.class.php create mode 100644 include/class/operation_opening.class.php create mode 100644 include/database/operation_exercice_detail_sql.class.php create mode 100644 include/database/operation_exercice_sql.class.php create mode 100644 include/operation_exercice.inc.php create mode 100644 include/template/operation_exercice-input_row.php create mode 100644 include/template/operation_exercice-input_source.php diff --git a/html/ajax_misc.php b/html/ajax_misc.php index 0492c3772..173edfb35 100644 --- a/html/ajax_misc.php +++ b/html/ajax_misc.php @@ -327,7 +327,18 @@ $path = array( //visibility quantity "update_visibility_quantity"=>"ajax_update_visibility_quantity", // detail customer , supplier operation - "event_display_detail"=>"ajax_event_display_detail" + "event_display_detail"=>"ajax_event_display_detail", + // update periode in opening operation + "operation_exercice+update_periode"=>"ajax_operation_exercice", + // modify row in exercice (opening/closing) operation + "operation_exercice+modify_row"=>"ajax_operation_exercice", + // save row in exercice (opening/closing) operation + "operation_exercice+save_row"=>"ajax_operation_exercice", + // compute the balance after saving row in exercice (opening/closing) operation + "operation_exercice+display_total"=>"ajax_operation_exercice", + // delete row in exercice (opening/closing) operation + "operation_exercice+delete_row"=>"ajax_operation_exercice", + ) ; if (array_key_exists($op, $path)) { diff --git a/html/js/acc_ledger.js b/html/js/acc_ledger.js index 41dd5f16f..8c205ff85 100644 --- a/html/js/acc_ledger.js +++ b/html/js/acc_ledger.js @@ -26,77 +26,75 @@ * */ var layer = 1; + /** * \fn * \brief update the list of available predefined operation when we change the ledger. */ -function update_predef(p_type, p_direct, p_ac) -{ +function update_predef(p_type, p_direct, p_ac) { var jrn = g("p_jrn").value; var dossier = g("gDossier").value; var querystring = 'gDossier=' + dossier + '&l=' + jrn + '&t=' + p_type + '&d=' + p_direct + "&op=up_predef&ac=" + p_ac; g("p_jrn_predef").value = jrn; var action = new Ajax.Request( - "ajax_misc.php", - { - method: 'get', - parameters: querystring, - onFailure: error_get_predef, - onSuccess: function (req) { - try { - $('info_div').innerHTML = "ok"; - var answer = req.responseXML; - var a = answer.getElementsByTagName('code'); - var html = answer.getElementsByTagName('value'); - if (a.length == 0) - { - var rec = req.responseText; - alert_box(content[48] + rec); - } - var code_html = getNodeText(html[0]); - code_html = unescape_xml(code_html); - // document.getElementsByName(name_ctl)[0].value = code_html; - $('modele_op_div').innerHTML = code_html; - } catch (e) { - $('info_div').innerHTML = e.message; + "ajax_misc.php", + { + method: 'get', + parameters: querystring, + onFailure: error_get_predef, + onSuccess: function (req) { + try { + $('info_div').innerHTML = "ok"; + var answer = req.responseXML; + var a = answer.getElementsByTagName('code'); + var html = answer.getElementsByTagName('value'); + if (a.length == 0) { + var rec = req.responseText; + alert_box(content[48] + rec); } + var code_html = getNodeText(html[0]); + code_html = unescape_xml(code_html); + // document.getElementsByName(name_ctl)[0].value = code_html; + $('modele_op_div').innerHTML = code_html; + } catch (e) { + $('info_div').innerHTML = e.message; } } + } ); } /** * update the list of payment method when we change the ledger. */ -function update_pay_method() -{ +function update_pay_method() { waiting_box(); var jrn = g("p_jrn").value; var dossier = g("gDossier").value; var querystring = 'gDossier=' + dossier + '&l=' + jrn + "&op=up_pay_method"; var action = new Ajax.Request( - "ajax_misc.php", - { - method: 'get', - parameters: querystring, - onFailure: error_get_predef, - onSuccess: function (req) { - remove_waiting_box(); - var answer = req.responseText; - $('payment').innerHTML = answer; - } + "ajax_misc.php", + { + method: 'get', + parameters: querystring, + onFailure: error_get_predef, + onSuccess: function (req) { + remove_waiting_box(); + var answer = req.responseText; + $('payment').innerHTML = answer; } + } ); } + /** * update the list of additional tax */ -function update_other_tax() -{ +function update_other_tax() { waiting_box(); var jrn = g("p_jrn").value; var dossier = g("gDossier").value; - var querystring ={gDossier: dossier,jrn_id:jrn ,op:"up_other_tax"}; + var querystring = {gDossier: dossier, jrn_id: jrn, op: "up_other_tax"}; var action = new Ajax.Request( "ajax_misc.php", { @@ -112,32 +110,32 @@ function update_other_tax() } ); } + /** * update ctl id =jrn_name with the value of p_jrn */ -function update_name() -{ +function update_name() { var jrn_id = $('p_jrn').value; var dossier = g("gDossier").value; var querystring = 'gDossier=' + dossier + '&l=' + jrn_id + "&op=ledger_description"; var action = new Ajax.Request( - "ajax_misc.php", - { - method: 'get', - parameters: querystring, - onFailure: error_get_pj, - onSuccess: function (req) { - $('jrn_name_div').innerHTML = req.responseText; - } + "ajax_misc.php", + { + method: 'get', + parameters: querystring, + onFailure: error_get_pj, + onSuccess: function (req) { + $('jrn_name_div').innerHTML = req.responseText; } + } ); } + /** * update the field predef */ -function error_get_predef(request, json) -{ +function error_get_predef(request, json) { alert_box(content[49]); } @@ -145,122 +143,124 @@ function error_get_predef(request, json) /** * update the list of available predefined operation when we change the ledger. */ -function update_pj() -{ +function update_pj() { var jrn = g("p_jrn").value; var dossier = g("gDossier").value; var querystring = 'gDossier=' + dossier + '&l=' + jrn + "&op=upd_receipt"; var action = new Ajax.Request( - "ajax_misc.php", - { - method: 'get', - parameters: querystring, - onFailure: error_get_pj, - onSuccess: success_get_pj - } + "ajax_misc.php", + { + method: 'get', + parameters: querystring, + onFailure: error_get_pj, + onSuccess: success_get_pj + } ); } + /** * ask the name, quick_code of the bank for the ledger */ -function update_bank() -{ +function update_bank() { var jrn = g('p_jrn').value; var dossier = g('gDossier').value; var qs = 'gDossier=' + dossier + '&op=bkname&p_jrn=' + jrn; var action = new Ajax.Request( - "ajax_misc.php", - { - method: 'get', - parameters: qs, - onFailure: error_get_pj, - onSuccess: success_update_bank - } + "ajax_misc.php", + { + method: 'get', + parameters: qs, + onFailure: error_get_pj, + onSuccess: success_update_bank + } ); } + /** * Update the number of rows when changing of ledger */ -function update_row(ctl) -{ - try - { - var row_to_keep=3; /* Number of row to keep (head and foot)*/ - if ( ctl === 'quick_item' ) { row_to_keep=1;} /* for ODS , only 1 rows to keep */ +function update_row(ctl) { + try { + var row_to_keep = 3; /* Number of row to keep (head and foot)*/ + if (ctl === 'quick_item') { + row_to_keep = 1; + } /* for ODS , only 1 rows to keep */ var jrn = g('p_jrn').value; var dossier = g('gDossier').value; var qs = encodeURI('gDossier=' + dossier + '&op=minrow&j=' + jrn + '&ctl=' + ctl); var current_row = parseFloat($('nb_item').value); var action = new Ajax.Request( - "ajax_misc.php", - { - method: 'get', - parameters: qs, - onFailure: null, - onSuccess: function (request, json) - { - try { - var answer = request.responseText.evalJSON(true); - var row = parseFloat(answer.row); - - var table_to_update=$(ctl); - if (current_row > row) { - // Too many row, we always must keep 2 rows for the sum - var delta = $('nb_item').value - row ; - var idx = $('nb_item').value; - for (var i = 0; i < delta; i++) { - var pos_row=table_to_update.rows.length; - var cell0 = table_to_update.rows[pos_row-row_to_keep].cells[0]; - var cell0Element=cell0.childNodes; - var canDelete=true; - /** - * prevent truncating - */ - cell0Element.forEach(function (x) { - if (canDelete && x.nodeName=='INPUT' && x.type==="text" && x.value) - { - canDelete=false; - }} - ); - /* - * prevent truncating - * For ODS we also need to check the second column - * */ - if ( canDelete && ctl === 'quick_item') { - var cell1 = table_to_update.rows[pos_row-row_to_keep].cells[1]; - var cell1Element=cell1.childNodes; - cell1Element.forEach(function (x) { - if (canDelete && x.nodeName=='INPUT' && x.type==="text" && x.value) - { - canDelete=false; - }}); + "ajax_misc.php", + { + method: 'get', + parameters: qs, + onFailure: null, + onSuccess: function (request, json) { + try { + var answer = request.responseText.evalJSON(true); + var row = parseFloat(answer.row); + + var table_to_update = $(ctl); + if (current_row > row) { + // Too many row, we always must keep 2 rows for the sum + var delta = $('nb_item').value - row; + var idx = $('nb_item').value; + for (var i = 0; i < delta; i++) { + var pos_row = table_to_update.rows.length; + var cell0 = table_to_update.rows[pos_row - row_to_keep].cells[0]; + var cell0Element = cell0.childNodes; + var canDelete = true; + /** + * prevent truncating + */ + cell0Element.forEach(function (x) { + if (canDelete && x.nodeName == 'INPUT' && x.type === "text" && x.value) { + canDelete = false; + } } - if ( canDelete ) { table_to_update.deleteRow(pos_row-row_to_keep);idx--;} - + ); + /* + * prevent truncating + * For ODS we also need to check the second column + * */ + if (canDelete && ctl === 'quick_item') { + var cell1 = table_to_update.rows[pos_row - row_to_keep].cells[1]; + var cell1Element = cell1.childNodes; + cell1Element.forEach(function (x) { + if (canDelete && x.nodeName == 'INPUT' && x.type === "text" && x.value) { + canDelete = false; + } + }); } - $('nb_item').value = table_to_update.rows.length-row_to_keep; - } - if (current_row < row) { - // We need to add rows - var delta = row - current_row ; - for (var i = 0; i < delta; i++) { - if (ctl == 'fin_item') { - ledger_fin_add_row(); - } - if (ctl == 'sold_item') { - ledger_add_row(); - } - if (ctl == 'quick_item') { - quick_writing_add_row(); - } + if (canDelete) { + table_to_update.deleteRow(pos_row - row_to_keep); + idx--; } + } - } catch (e) { - alert_box("update_row:01"+e.message); + $('nb_item').value = table_to_update.rows.length - row_to_keep; } + if (current_row < row) { + // We need to add rows + var delta = row - current_row; + for (var i = 0; i < delta; i++) { + if (ctl == 'fin_item') { + ledger_fin_add_row(); + } + if (ctl == 'sold_item') { + ledger_add_row(); + } + if (ctl == 'quick_item') { + quick_writing_add_row(); + } + } + } + } catch (e) { + alert_box("update_row:01" + e.message); } } + } ); } catch (e) { alert_box(e.message); @@ -270,8 +270,7 @@ function update_row(ctl) /** * @brief hide or show the column quantity */ -function update_visibility_quantity() -{ +function update_visibility_quantity() { var jrn = g("p_jrn").value; var dossier = g("gDossier").value; var querystring = 'gDossier=' + dossier + '&l=' + jrn + "&op=update_visibility_quantity"; @@ -283,21 +282,21 @@ function update_visibility_quantity() onSuccess: function (req) { try { // retrieve quantity - var quantity_col=document.getElementsByClassName("col_quant"); - for (var i=0;i < quantity_col.length;i++){ - if (req.responseText=="0") { + var quantity_col = document.getElementsByClassName("col_quant"); + for (var i = 0; i < quantity_col.length; i++) { + if (req.responseText == "0") { // hide the columns quantity and return quantity_col[i].hide(); quantity_col[i].addClassName('d-none'); } - if (req.responseText=="1") { + if (req.responseText == "1") { // show the columns quantity and return quantity_col[i].show(); quantity_col[i].removeClassName('d-none'); } } } catch (e) { - console.error("update_visibility_quantity"+e.message); + console.error("update_visibility_quantity" + e.message); } @@ -305,80 +304,72 @@ function update_visibility_quantity() } ); } + /** * Put into the span, the name of the bank, the bank account * and the quick_code */ -function success_update_bank(req) -{ - try - { +function success_update_bank(req) { + try { var answer = req.responseXML; var a = answer.getElementsByTagName('code'); var html = answer.getElementsByTagName('value'); - if (a.length == 0) - { + if (a.length == 0) { var rec = req.responseText; - alert_box('UPDBK-'+content[48]+ rec); + alert_box('UPDBK-' + content[48] + rec); } var name_ctl = a[0].firstChild.nodeValue; var code_html = getNodeText(html[0]); code_html = unescape_xml(code_html); $(name_ctl).innerHTML = code_html; - } - catch (e) - { + } catch (e) { alert_box("success_update_bank" + e.message); } } + /** * call ajax, ask what is the last date for the current ledger */ -function get_last_date() -{ +function get_last_date() { var jrn = g('p_jrn').value; var dossier = g('gDossier').value; var qs = 'gDossier=' + dossier + '&op=lastdate&p_jrn=' + jrn; var action = new Ajax.Request( - "ajax_misc.php", - { - method: 'get', - parameters: qs, - onFailure: error_get_pj, - onSuccess: success_get_last_date - } + "ajax_misc.php", + { + method: 'get', + parameters: qs, + onFailure: error_get_pj, + onSuccess: success_get_last_date + } ); } + /** * callback ajax, set the ctl with the last date from the ledger */ -function success_get_last_date(req) -{ - try - { +function success_get_last_date(req) { + try { var answer = req.responseXML; var a = answer.getElementsByTagName('code'); var html = answer.getElementsByTagName('value'); - if (a.length == 0) - { + if (a.length == 0) { var rec = req.responseText; - alert_box('GETLASTDA:'+content[48] + rec); + alert_box('GETLASTDA:' + content[48] + rec); } var name_ctl = a[0].firstChild.nodeValue; var code_html = getNodeText(html[0]); code_html = unescape_xml(code_html); document.getElementsByName(name_ctl)[0].value = code_html; - } - catch (e) - { + } catch (e) { alert_box(e.message); } } + /** * update the field predef */ -function success_get_pj(request, json) -{ +function success_get_pj(request, json) { var answer = request.responseText.evalJSON(true); var obj = g("e_pj"); @@ -388,19 +379,18 @@ function success_get_pj(request, json) obj.value = answer.pj; g("e_pj_suggest").value = answer.pj; } + /** * update the field predef */ -function error_get_pj(request, json) -{ - alert_box("GETPJ:"+content[48]); +function error_get_pj(request, json) { + alert_box("GETPJ:" + content[48]); } /** * add a line in the form for the ledger fin */ -function ledger_fin_add_row() -{ +function ledger_fin_add_row() { var style = 'class="input_text"'; var mytable = g("fin_item").tBodies[0]; var line = mytable.rows.length; @@ -408,8 +398,7 @@ function ledger_fin_add_row() var nb = g("nb_item"); var rowToCopy = mytable.rows[1]; var nNumberCell = rowToCopy.cells.length; - for (var e = 0; e < nNumberCell; e++) - { + for (var e = 0; e < nNumberCell; e++) { var newCell = row.insertCell(e); if (e == 0) { newCell.id = 'tdchdate' + nb.value; @@ -423,7 +412,7 @@ function ledger_fin_add_row() new_tt = new_tt.replace(/e_other0_label/g, "e_other" + nb.value + '_label'); new_tt = new_tt.replace(/dateop0/g, "dateop" + nb.value); newCell.innerHTML = new_tt; - newCell.className=rowToCopy.cells[e].className; + newCell.className = rowToCopy.cells[e].className; new_tt.evalScripts(); } g("e_other" + nb.value).value = ""; @@ -443,29 +432,36 @@ function ledger_fin_add_row() * Add multiple row * @param string p_elid is the id of element with the number of rows to add, and p_elid+"_ledger" is the type of ledger : M : Misc Operation O : Sales or purchase and F for financial */ -function ledger_add_multiple(p_elid) -{ - var nbrow=$(p_elid).value; - if (nbrow == NaN) {nbrow=1;} - var type_ledger=$(p_elid+"_ledger").value; - var i=0; - for (i=0;idisplay_dcside(item)) + var type_ledger = $(p_elid + "_ledger").value; + var i = 0; + for (i = 0; i < nbrow; i++) { + if (type_ledger == 'O') { + ledger_add_row(); + } + if (type_ledger == 'F') { + ledger_fin_add_row(); + } + if (type_ledger == 'M') { + quick_writing_add_row(); + } + } + if (type_ledger == 'M') { + var aCheckBox = $$('.debit-credit') + aCheckBox.forEach((item) => display_dcside(item)) } } + /** * add a line in the form for the purchase ledger * @param p_dossier folder id * @param p_table_name */ -function ledger_add_row() -{ +function ledger_add_row() { try { style = 'class="input_text"'; var mytable = g("sold_item").tBodies[0]; @@ -474,8 +470,7 @@ function ledger_add_row() var nCell = mytable.rows[1].cells.length; var row = mytable.insertRow(line); var nb = g("nb_item"); - for (var e = 0; e < nCell; e++) - { + for (var e = 0; e < nCell; e++) { var newCell = row.insertCell(e); var tt = ofirstRow.cells[e].innerHTML; var new_tt = tt.replace(/march0/g, "march" + nb.value); @@ -484,7 +479,7 @@ function ledger_add_row() new_tt = new_tt.replace(/compute_ledger\(0\)/g, "compute_ledger(" + nb.value + ")"); new_tt = new_tt.replace(/clean_tva\(0\)/g, "clean_tva(" + nb.value + ")"); newCell.innerHTML = new_tt; - newCell.className=ofirstRow.cells[e].className; + newCell.className = ofirstRow.cells[e].className; new_tt.evalScripts(); } @@ -503,17 +498,16 @@ function ledger_add_row() alert_box(e.message); } } + /** * compute the sum of a purchase, update the span tvac, htva and tva * all the needed data are taken from the document (hidden field : gdossier) * @param the number of the changed ctrl */ -function compute_ledger(p_ctl_nb) -{ +function compute_ledger(p_ctl_nb) { var dossier = g("gDossier").value; var a = -1; - if (document.getElementById("e_march" + p_ctl_nb + '_tva_amount')) - { + if (document.getElementById("e_march" + p_ctl_nb + '_tva_amount')) { a = trim(g("e_march" + p_ctl_nb + '_tva_amount').value); g("e_march" + p_ctl_nb + '_tva_amount').value = a; } @@ -523,8 +517,7 @@ function compute_ledger(p_ctl_nb) g("e_march" + p_ctl_nb).value = trim(g("e_march" + p_ctl_nb).value); var qcode = g("e_march" + p_ctl_nb).value; - if (qcode.length == 0) - { + if (qcode.length == 0) { clean_ledger(p_ctl_nb); refresh_ledger(); return; @@ -533,11 +526,9 @@ function compute_ledger(p_ctl_nb) * if tva_id is empty send a value of -1 */ var tva_id = -1; - if (g('e_march' + p_ctl_nb + '_tva_id')) - { + if (g('e_march' + p_ctl_nb + '_tva_id')) { tva_id = g('e_march' + p_ctl_nb + '_tva_id').value; - if (trim(tva_id) == '') - { + if (trim(tva_id) == '') { tva_id = -1; } } @@ -547,32 +538,39 @@ function compute_ledger(p_ctl_nb) g('e_quant' + p_ctl_nb).value = trim(g('e_quant' + p_ctl_nb).value); var quantity = g('e_quant' + p_ctl_nb).value; - let other_tax=g("other_tax"); - let other_tax_id=(other_tax && other_tax.checked)?other_tax.value:-1; + let other_tax = g("other_tax"); + let other_tax_id = (other_tax && other_tax.checked) ? other_tax.value : -1; - var querystring = { gDossier : dossier , c : qcode ,t :tva_id,p : price , q:quantity,n:p_ctl_nb,'other_tax_id':other_tax_id}; + var querystring = { + gDossier: dossier, + c: qcode, + t: tva_id, + p: price, + q: quantity, + n: p_ctl_nb, + 'other_tax_id': other_tax_id + }; var action = new Ajax.Request( - "compute.php", - { - method: 'get', - parameters: querystring, - onFailure: error_compute_ledger, - onSuccess: success_compute_ledger - } + "compute.php", + { + method: 'get', + parameters: querystring, + onFailure: error_compute_ledger, + onSuccess: success_compute_ledger + } ); } + /** * refresh the purchase screen, recompute vat, total... */ -function refresh_ledger() -{ +function refresh_ledger() { var tva = 0; var htva = 0; var tvac = 0; - nb_item=g("nb_item").value; - for (var i = 0; i < nb_item; i++) - { + nb_item = g("nb_item").value; + for (var i = 0; i < nb_item; i++) { if (g('tva_march' + i)) tva += g('tva_march' + i).value * 1; if (g('htva_march' + i)) @@ -580,62 +578,57 @@ function refresh_ledger() if (g('tvac_march' + i)) tvac += g('tvac_march' + i).value * 1; } - id_tva=g("tva"); - id_htva=g("htva"); - id_tvac=g("tvac"); - id_other_tax=g("other_tax_amount"); + id_tva = g("tva"); + id_htva = g("htva"); + id_tvac = g("tvac"); + id_other_tax = g("other_tax_amount"); if (id_tva) id_tva.innerHTML = Math.round(tva * 100) / 100; if (id_htva) id_htva.innerHTML = Math.round(htva * 100) / 100; - if ( id_other_tax) { - let total_operation=tvac+parseFloat(id_other_tax.value); - $('total_operation_other_tax').innerHTML=Math.round(total_operation*100)/100; + if (id_other_tax) { + let total_operation = tvac + parseFloat(id_other_tax.value); + $('total_operation_other_tax').innerHTML = Math.round(total_operation * 100) / 100; } if (id_tvac) id_tvac.innerHTML = Math.round(tvac * 100) / 100; } + /** * update the field htva, tva_id and tvac, callback function for compute_sold * it the field TVA in the answer contains NA it means that VAT is appliable and then do not * update the VAT field except htva_martc */ -function success_compute_ledger(request, json) -{ +function success_compute_ledger(request, json) { var answer = request.responseText.evalJSON(true); var ctl = answer.ctl; var rtva = answer.tva; var rhtva = answer.htva; var rtvac = answer.tvac; - let other_tax=g("other_tax_amount") - if ( other_tax) { - other_tax.value=answer.other_tax; + let other_tax = g("other_tax_amount") + if (other_tax) { + other_tax.value = answer.other_tax; } - if (rtva == 'NA') - { + if (rtva == 'NA') { var rhtva = answer.htva * 1; g('htva_march' + ctl).value = rhtva; g('tvac_march' + ctl).value = rtvac; g('sum').show(); refresh_ledger(); - CurrencyCompute('p_currency_rate','p_currency_euro'); + CurrencyCompute('p_currency_rate', 'p_currency_euro'); return; } rtva = answer.tva * 1; - g('sum').show(); - if (g('e_march' + ctl + '_tva_amount').value == "" || g('e_march' + ctl + '_tva_amount').value == 0) - { + if (g('e_march' + ctl + '_tva_amount').value == "" || g('e_march' + ctl + '_tva_amount').value == 0) { g('tva_march' + ctl).value = rtva; g('e_march' + ctl + '_tva_amount').value = rtva; - } - else - { + } else { g('tva_march' + ctl).value = g('e_march' + ctl + '_tva_amount').value; } g('htva_march' + ctl).value = Math.round(parseFloat(rhtva) * 100) / 100; @@ -643,31 +636,28 @@ function success_compute_ledger(request, json) var tmp2 = Math.round(parseFloat(g('tva_march' + ctl).value) * 100) / 100; g('tvac_march' + ctl).value = Math.round((tmp1 + tmp2) * 100) / 100; refresh_ledger(); - CurrencyCompute('p_currency_rate','p_currency_euro'); - + CurrencyCompute('p_currency_rate', 'p_currency_euro'); + } /** * callback error function for compute_sold */ -function error_compute_ledger(request, json) -{ +function error_compute_ledger(request, json) { alert_box('Ajax does not work'); } -function compute_all_ledger() -{ + +function compute_all_ledger() { var loop = 0; - let nb_item=g("nb_item").value; - for (loop = 0; loop < nb_item; loop++) - { + let nb_item = g("nb_item").value; + for (loop = 0; loop < nb_item; loop++) { compute_ledger(loop); } var tva = 0; var htva = 0; var tvac = 0; - for (var i = 0; i < nb_item; i++) - { + for (var i = 0; i < nb_item; i++) { if (g('tva_march')) tva += g('tva_march' + i).value * 1; if (g('htva_march' + i)) @@ -675,61 +665,54 @@ function compute_all_ledger() if (g('tvac_march' + i)) tvac += g('tvac_march' + i).value * 1; } - id_other_tax=g("other_tax_amount"); + id_other_tax = g("other_tax_amount"); if (g('tva')) g('tva').innerHTML = Math.round(tva * 100) / 100; if (g('htva')) g('htva').innerHTML = Math.round(htva * 100) / 100; - if (id_other_tax) { tvac+=id_other_tax.value;} + if (id_other_tax) { + tvac += id_other_tax.value; + } if (g('tvac')) g('tvac').innerHTML = Math.round(tvac * 100) / 100; - + } -function clean_tva(p_ctl) -{ +function clean_tva(p_ctl) { if (g('e_march' + p_ctl + '_tva_amount')) g('e_march' + p_ctl + '_tva_amount').value = 0; } -function clean_ledger(p_ctl_nb) -{ - if (g("e_march" + p_ctl_nb)) - { +function clean_ledger(p_ctl_nb) { + if (g("e_march" + p_ctl_nb)) { g("e_march" + p_ctl_nb).value = trim(g("e_march" + p_ctl_nb).value); } - if (g('e_march' + p_ctl_nb + '_price')) - { + if (g('e_march' + p_ctl_nb + '_price')) { g('e_march' + p_ctl_nb + '_price').value = ''; } - if (g('e_quant' + p_ctl_nb)) - { + if (g('e_quant' + p_ctl_nb)) { g('e_quant' + p_ctl_nb).value = '1'; } - if (g('tva_march' + p_ctl_nb + '_show')) - { + if (g('tva_march' + p_ctl_nb + '_show')) { g('tva_march' + p_ctl_nb + '_show').value = '0'; } - if (g('tva_march' + p_ctl_nb)) - { + if (g('tva_march' + p_ctl_nb)) { g('tva_march' + p_ctl_nb).value = 0; } - if (g('htva_march' + p_ctl_nb)) - { + if (g('htva_march' + p_ctl_nb)) { g('htva_march' + p_ctl_nb).value = 0; } - if (g('tvac_march' + p_ctl_nb)) - { + if (g('tvac_march' + p_ctl_nb)) { g('tvac_march' + p_ctl_nb).value = 0; } } + /** * add a line in the form for the quick_writing */ -function quick_writing_add_row() -{ +function quick_writing_add_row() { style = 'class="input_text"'; var mytable = g("quick_item").tBodies[0]; var nNumberRow = mytable.rows.length; @@ -739,8 +722,7 @@ function quick_writing_add_row() var nb = g("nb_item"); var oNewRow = mytable.insertRow(nNumberRow); - for (var e = 0; e < nNumberCell; e++) - { + for (var e = 0; e < nNumberCell; e++) { var newCell = oRow.insertCell(e); var tt = rowToCopy.cells[e].innerHTML; new_tt = tt.replace(/qc_0/g, "qc_" + nb.value); @@ -749,12 +731,15 @@ function quick_writing_add_row() new_tt = new_tt.replace(/ck0/g, "ck" + nb.value); new_tt = new_tt.replace(/ld0/g, "ld" + nb.value); newCell.innerHTML = new_tt; - newCell.className=rowToCopy.cells[e].className; + newCell.className = rowToCopy.cells[e].className; new_tt.evalScripts(); } - var ck=$('ck'+nb.value); - ck.addEventListener('click',function(event) { display_range_dcside(event,ck); display_dcside(ck);}); + var ck = $('ck' + nb.value); + ck.addEventListener('click', function (event) { + display_range_dcside(event, ck); + display_dcside(ck); + }); $("qc_" + nb.value).value = ""; @@ -763,230 +748,240 @@ function quick_writing_add_row() $("ld" + nb.value).value = ""; - nb.value++; } -function RefreshMe() -{ + +function RefreshMe() { window.location.reload(); } -function go_next_concerned() -{ +function go_next_concerned() { var form = document.forms[1]; - for (var e = 0; e < form.elements.length; e++) - { + for (var e = 0; e < form.elements.length; e++) { var elmt = form.elements[e]; - if (elmt.type == "checkbox") - { - if (elmt.checked == true) - { + if (elmt.type == "checkbox") { + if (elmt.checked == true) { return confirm(content[52]); } } } return true; } + /** * View the history of an account * @param {type} p_value * @param {type} dossier * @returns {undefined} */ -function view_history_account(p_value, dossier,p_exercice) -{ +function view_history_account(p_value, dossier, p_exercice) { layer++; var idbox = 'det' + layer; var popup = {'id': idbox, 'cssclass': 'inner_box', 'html': loading(), 'drag': false}; - var querystring={'gDossier':dossier,'act':'de','pcm_val':p_value,'div':idbox,'l':layer,'op':'history','exercice':p_exercice}; + var querystring = { + 'gDossier': dossier, + 'act': 'de', + 'pcm_val': p_value, + 'div': idbox, + 'l': layer, + 'op': 'history', + 'exercice': p_exercice + }; waiting_box(); var action = new Ajax.Request( - "ajax_misc.php", - { - method: 'get', - parameters: querystring, - onFailure: error_box, - onSuccess: function (req, xml) - { - remove_waiting_box(); - add_div(popup); - success_box(req, xml); - $(idbox).style.top = calcy(140 + (layer * 3)) + "px"; - } + "ajax_misc.php", + { + method: 'get', + parameters: querystring, + onFailure: error_box, + onSuccess: function (req, xml) { + remove_waiting_box(); + add_div(popup); + success_box(req, xml); + $(idbox).style.top = calcy(140 + (layer * 3)) + "px"; } + } ); } + /** * View the history of an account * @param {type} p_value * @param {type} dossier * @returns {undefined} */ -function view_history_anc_account(p_value, dossier,p_exercice) -{ +function view_history_anc_account(p_value, dossier, p_exercice) { layer++; var idbox = 'det' + layer; var popup = {'id': idbox, 'cssclass': 'inner_box', 'html': loading(), 'drag': false}; - var querystring={'gDossier':dossier,'op':'history_anc_account','po_id':p_value,'div':idbox,'l':layer,'act':'history','exercice':p_exercice}; + var querystring = { + 'gDossier': dossier, + 'op': 'history_anc_account', + 'po_id': p_value, + 'div': idbox, + 'l': layer, + 'act': 'history', + 'exercice': p_exercice + }; waiting_box(); var action = new Ajax.Request( - "ajax_misc.php", - { - method: 'get', - parameters: querystring, - onFailure: error_box, - onSuccess: function (req, xml) - { - remove_waiting_box(); - add_div(popup); - $(idbox).innerHTML=req.responseText; - $(idbox).style.top = calcy(140 + (layer * 3)) + "px"; - } + "ajax_misc.php", + { + method: 'get', + parameters: querystring, + onFailure: error_box, + onSuccess: function (req, xml) { + remove_waiting_box(); + add_div(popup); + $(idbox).innerHTML = req.responseText; + $(idbox).style.top = calcy(140 + (layer * 3)) + "px"; } + } ); } + /** * Change the view of account history * @param {type} obj * @returns {Boolean} */ -function update_history_account(obj) -{ +function update_history_account(obj) { try { var querystring = { - "l" :obj.div , - "div" :obj.div , - "gDossier" : obj.gDossier, - "pcm_val" : obj.pcm_val , - "ex" : obj.select.options[obj.select.selectedIndex].text, - "op":"history", - "exercice":obj.exercice + "l": obj.div, + "div": obj.div, + "gDossier": obj.gDossier, + "pcm_val": obj.pcm_val, + "ex": obj.select.options[obj.select.selectedIndex].text, + "op": "history", + "exercice": obj.exercice }; waiting_box(); var action = new Ajax.Request( - "ajax_misc.php", - { - method: 'get', - parameters: querystring, - onFailure: error_box, - onSuccess: function (req, xml) - { - remove_waiting_box(); - success_box(req, xml); - g(obj.div).style.top = calcy(140 + (layer * 3)) + "px"; - } - }); - } catch (e) - { - alert_box("update_history_account error " + e.message); - } - - return false; -} -/*!\brief Change the view of card history - * \param p_value f_id of the card - */ -function view_history_card(p_value, dossier,p_exercice) -{ - layer++; - var idbox = 'det' + layer; - var popup = {'id':idbox, - 'cssclass': 'inner_box', - 'html':loading(), - 'drag':false}; - var querystring = { 'gDossier' : dossier , - 'act':'de', - 'f_id' : p_value , - 'div' : idbox , - "l" : layer, - "op":"history", - "exercice":p_exercice}; - waiting_box(); - var action = new Ajax.Request( "ajax_misc.php", { method: 'get', parameters: querystring, onFailure: error_box, - onSuccess: function (req, xml) - { + onSuccess: function (req, xml) { remove_waiting_box(); - add_div(popup); success_box(req, xml); - g(idbox).style.top = calcy(140 + (layer * 3)) + "px"; + g(obj.div).style.top = calcy(140 + (layer * 3)) + "px"; } - } - ); -} -/** - * update history view after changing the exercice - * @param {type} obj - * @returns {Boolean} - */ -function update_history_card(obj) -{ - try { - var querystring = { - "l" : obj.div , - "div" : obj.div , - "gDossier" : obj.gDossier, - "f_id" : obj.f_id , - "ex" : obj.select.options[obj.select.selectedIndex].text, - "op":"history", - "exercice":obj.exercice - }; - waiting_box(); - var action = new Ajax.Request( - "ajax_misc.php", - { - method: 'get', - parameters: querystring, - onFailure: error_box, - onSuccess: function (req, xml) - { - remove_waiting_box(); - success_box(req, xml); - g(obj.div).style.top = calcy(140 + (layer * 3)) + "px"; - } - }); - } catch (e) - { + }); + } catch (e) { alert_box("update_history_account error " + e.message); } return false; } + +/*!\brief Change the view of card history + * \param p_value f_id of the card + */ +function view_history_card(p_value, dossier, p_exercice) { + layer++; + var idbox = 'det' + layer; + var popup = { + 'id': idbox, + 'cssclass': 'inner_box', + 'html': loading(), + 'drag': false + }; + var querystring = { + 'gDossier': dossier, + 'act': 'de', + 'f_id': p_value, + 'div': idbox, + "l": layer, + "op": "history", + "exercice": p_exercice + }; + waiting_box(); + var action = new Ajax.Request( + "ajax_misc.php", + { + method: 'get', + parameters: querystring, + onFailure: error_box, + onSuccess: function (req, xml) { + remove_waiting_box(); + add_div(popup); + success_box(req, xml); + g(idbox).style.top = calcy(140 + (layer * 3)) + "px"; + } + } + ); +} + +/** + * update history view after changing the exercice + * @param {type} obj + * @returns {Boolean} + */ +function update_history_card(obj) { + try { + var querystring = { + "l": obj.div, + "div": obj.div, + "gDossier": obj.gDossier, + "f_id": obj.f_id, + "ex": obj.select.options[obj.select.selectedIndex].text, + "op": "history", + "exercice": obj.exercice + }; + waiting_box(); + var action = new Ajax.Request( + "ajax_misc.php", + { + method: 'get', + parameters: querystring, + onFailure: error_box, + onSuccess: function (req, xml) { + remove_waiting_box(); + success_box(req, xml); + g(obj.div).style.top = calcy(140 + (layer * 3)) + "px"; + } + }); + } catch (e) { + alert_box("update_history_account error " + e.message); + } + + return false; +} + /** * remove an Operation *@param p_jr_id is the jrn.jr_id *@param dossier *@param the div */ -function removeOperation(p_jr_id, dossier, div) -{ +function removeOperation(p_jr_id, dossier, div) { waiting_box(); - var qs = { "gDossier" : dossier , - "op":"ledger", - "act":"rmop", - "div" : div , - "jr_id" : p_jr_id}; + var qs = { + "gDossier": dossier, + "op": "ledger", + "act": "rmop", + "div": div, + "jr_id": p_jr_id + }; new Ajax.Request( - "ajax_misc.php", - { - method: 'get', - parameters: qs, - onFailure: error_box, - onSuccess: infodiv - } + "ajax_misc.php", + { + method: 'get', + parameters: qs, + onFailure: error_box, + onSuccess: infodiv + } ); } @@ -995,36 +990,41 @@ function removeOperation(p_jr_id, dossier, div) * reverse an Operation *@param pointer to the FORM */ -function reverseOperation(obj) -{ - var qs = $(obj).serialize()+ "&op=ledger"; +function reverseOperation(obj) { + var qs = $(obj).serialize() + "&op=ledger"; g('ext' + obj.divname).style.display = 'none'; waiting_box(); new Ajax.Request( - "ajax_misc.php", - { - method: 'get', - parameters: qs, - onFailure: error_box, - onSuccess: function (req) { - try { - var action = new Ajax.Request( - "ajax_misc.php", - { - method: 'get', - parameters:{"gDossier" : obj["gDossier"].value,"op":"ledger","act":"de","div":obj['div'].value,"jr_id":obj['jr_id'].value}, - onFailure: error_box, - onSuccess: function (xml, txt) { - - success_box(xml, txt); - infodiv(req); - } - }); - } catch (ex) { - smoke.alert(ex.message); - } + "ajax_misc.php", + { + method: 'get', + parameters: qs, + onFailure: error_box, + onSuccess: function (req) { + try { + var action = new Ajax.Request( + "ajax_misc.php", + { + method: 'get', + parameters: { + "gDossier": obj["gDossier"].value, + "op": "ledger", + "act": "de", + "div": obj['div'].value, + "jr_id": obj['jr_id'].value + }, + onFailure: error_box, + onSuccess: function (xml, txt) { + + success_box(xml, txt); + infodiv(req); + } + }); + } catch (ex) { + smoke.alert(ex.message); } } + } ); return false; @@ -1035,33 +1035,39 @@ function reverseOperation(obj) * \param p_value jrn.jr_id * \param dossier dossier id */ -function modifyOperation(p_value, dossier) -{ +function modifyOperation(p_value, dossier) { layer++; var id_div = 'det' + layer; waiting_box(); - var querystring = { "gDossier" : dossier , - "op":"ledger", - "act":"de", - "div" : id_div , - "jr_id" : p_value}; + var querystring = { + "gDossier": dossier, + "op": "ledger", + "act": "de", + "div": id_div, + "jr_id": p_value + }; var action = new Ajax.Request( - "ajax_misc.php", - { - method: 'get', - parameters: querystring, - onFailure: error_box, - onSuccess: function (xml, txt) { - if ( xml.responseText === 'NOCONX') { reconnect();return;} - var popup = {'id': id_div, 'cssclass': 'inner_box' - , 'html': "", 'drag': false}; - remove_waiting_box(); - add_div(popup); - success_box(xml, txt); - $(id_div).style.position = "absolute"; - $(id_div).style.top = calcy(100 + (layer * 3)) + "px"; + "ajax_misc.php", + { + method: 'get', + parameters: querystring, + onFailure: error_box, + onSuccess: function (xml, txt) { + if (xml.responseText === 'NOCONX') { + reconnect(); + return; } + var popup = { + 'id': id_div, 'cssclass': 'inner_box' + , 'html': "", 'drag': false + }; + remove_waiting_box(); + add_div(popup); + success_box(xml, txt); + $(id_div).style.position = "absolute"; + $(id_div).style.top = calcy(100 + (layer * 3)) + "px"; } + } ); } @@ -1069,27 +1075,29 @@ function modifyOperation(p_value, dossier) * \param p_value jrn.jr_id */ -function viewOperation(p_value, p_dossier) -{ +function viewOperation(p_value, p_dossier) { modifyOperation(p_value, p_dossier) } -function dropLink(p_dossier, p_div, p_jr_id, p_jr_id2) -{ - var querystring = { "gDossier" : p_dossier , - "op":"ledger", - "act":"rmr", - "div" : p_div , - "jr_id" : p_jr_id, - "jr_id2" : p_jr_id2}; + +function dropLink(p_dossier, p_div, p_jr_id, p_jr_id2) { + var querystring = { + "gDossier": p_dossier, + "op": "ledger", + "act": "rmr", + "div": p_div, + "jr_id": p_jr_id, + "jr_id2": p_jr_id2 + }; var action = new Ajax.Request('ajax_misc.php', - { - method: 'get', - parameters: querystring, - onFailure: null, - onSuccess: null - } + { + method: 'get', + parameters: querystring, + onFailure: null, + onSuccess: null + } ); } + /** * this function is called before the querystring is send to the * fid2.php, add a filter based on the ledger 'p_jrn' @@ -1097,60 +1105,50 @@ function dropLink(p_dossier, p_div, p_jr_id, p_jr_id2) *@param queryString is the queryString to modify *@see ICard::input */ -function filter_card(obj, queryString) -{ +function filter_card(obj, queryString) { jrn = $('p_jrn').value; - if (jrn == -1) - { + if (jrn == -1) { type = $('ledger_type').value; queryString = queryString + '&type=' + type; - } - else - { + } else { queryString = queryString + '&j=' + jrn; } return queryString; } + /** * to display the lettering for the operation, call * ajax function *@param obj object attribut : gDossier,j_id,obj_type */ -function dsp_letter(obj) -{ - try - { +function dsp_letter(obj) { + try { //var queryString = 'gDossier=' + obj.gDossier + '&j_id=' + obj.j_id + '&op=dl' + '&ot=' + obj.obj_type+'&start='+obj.start; - + var action = new Ajax.Request( - "ajax_misc.php", - { - method: 'get', - parameters: obj, - onFailure: error_dsp_letter, - onSuccess: success_dsp_letter - } + "ajax_misc.php", + { + method: 'get', + parameters: obj, + onFailure: error_dsp_letter, + onSuccess: success_dsp_letter + } ); g('search').style.display = 'none'; g('list').style.display = 'none'; $('detail').innerHTML = loading(); g('detail').style.display = 'block'; - } - catch (e) - { + } catch (e) { alert_box('dsp_letter failed ' + e.message); } } -function success_dsp_letter(req) -{ - try - { +function success_dsp_letter(req) { + try { var answer = req.responseXML; var a = answer.getElementsByTagName('code'); var html = answer.getElementsByTagName('value'); - if (a.length == 0) - { + if (a.length == 0) { var rec = req.responseText; alert_box('erreur :' + rec); } @@ -1158,30 +1156,23 @@ function success_dsp_letter(req) var code_html = getNodeText(html[0]); code_html = unescape_xml(code_html); $('detail').innerHTML = code_html; - } - catch (e) - { + } catch (e) { alert_box(e.message); } - try - { + try { code_html.evalScripts(); - } - catch (e) - { - alert_box("DSPLETTER:"+content[48] + e.message); + } catch (e) { + alert_box("DSPLETTER:" + content[48] + e.message); } } -function error_dsp_letter(req) -{ - alert_box("DSPLETTER:"+content[48]); + +function error_dsp_letter(req) { + alert_box("DSPLETTER:" + content[48]); } -function search_letter(obj) -{ - try - { +function search_letter(obj) { + try { var str_query = ''; if (obj.elements['gDossier']) str_query = 'gDossier=' + obj.elements['gDossier'].value; @@ -1204,127 +1195,122 @@ function search_letter(obj) var action = new Ajax.Request( - "ajax_misc.php", - { - method: 'get', - parameters: str_query, - onFailure: error_dsp_letter, - onSuccess: success_dsp_letter - } + "ajax_misc.php", + { + method: 'get', + parameters: str_query, + onFailure: error_dsp_letter, + onSuccess: success_dsp_letter + } ); $('list').hide(); $('search').hide(); $('detail').innerHTML = loading(); $('detail').show(); - } - catch (e) - { + } catch (e) { alert_box('search_letter ' + e.message); } } + /** * save an operation in ajax, it concerns only the * comment, the pj and the rapt * the form elements are access by their name *@param obj form */ -function op_save(obj) -{ +function op_save(obj) { try { var queryString = $(obj).serialize(true); - queryString ["gDossier"]= obj.gDossier.value; + queryString ["gDossier"] = obj.gDossier.value; var rapt2 = "rapt" + obj.whatdiv.value; - queryString ["rapt"] = g(rapt2).value; + queryString ["rapt"] = g(rapt2).value; queryString ["jr_id"] = obj.jr_id.value; - var jr_id=obj.jr_id.value; - queryString ["div"]= obj.whatdiv.value; - var divid=obj.whatdiv.value; - queryString ["act"]="save"; - queryString ["op"]="ledger"; - + var jr_id = obj.jr_id.value; + queryString ["div"] = obj.whatdiv.value; + var divid = obj.whatdiv.value; + queryString ["act"] = "save"; + queryString ["op"] = "ledger"; + waiting_box(); /* * Operation detail is in a new window */ - if (g('inpopup')) - { + if (g('inpopup')) { var action = new Ajax.Request('ajax_misc.php', - { - method: 'post', - parameters: queryString, - onFailure: null, - onSuccess: function (req){ - remove_waiting_box(); - var answer=req.getElementsByTagName('code'); - if (answer[0] !=='OK') { - console.error("D2. op_save") - smoke.alert(req.responseText); - } + { + method: 'post', + parameters: queryString, + onFailure: null, + onSuccess: function (req) { + remove_waiting_box(); + var answer = req.getElementsByTagName('code'); + if (answer[0] !== 'OK') { + console.error("D2. op_save") + smoke.alert(req.responseText); } } + } ); // window.close(); - } - else - { + } else { /* *Operation is in a modal box */ var action = new Ajax.Request('ajax_misc.php', - { - method: 'post', - parameters: queryString, - onFailure: null, - onSuccess: function(req,json) { - - - if (req.responseXML == null ){ - smoke.alert(req.responseText); - } - new Ajax.Request('ajax_misc.php', { - parameters:{'gDossier':obj.gDossier.value, - 'act':'de', - 'op':'ledger', - 'jr_id' : jr_id, - 'div' : divid}, - onSuccess:function(xml) { - try { - var answer=xml.responseXML; - var html = answer.getElementsByTagName('code'); - $(divid).innerHTML=unescape(getNodeText(html[0])); - $(divid).innerHTML.evalScripts(); - remove_waiting_box(); - } catch (e) { - console.error("D1. op_save") - alert_box("1038"+e.message) - } - } - }); - + { + method: 'post', + parameters: queryString, + onFailure: null, + onSuccess: function (req, json) { + + + if (req.responseXML == null) { + smoke.alert(req.responseText); } - }); + new Ajax.Request('ajax_misc.php', { + parameters: { + 'gDossier': obj.gDossier.value, + 'act': 'de', + 'op': 'ledger', + 'jr_id': jr_id, + 'div': divid + }, + onSuccess: function (xml) { + try { + var answer = xml.responseXML; + var html = answer.getElementsByTagName('code'); + $(divid).innerHTML = unescape(getNodeText(html[0])); + $(divid).innerHTML.evalScripts(); + remove_waiting_box(); + } catch (e) { + console.error("D1. op_save") + alert_box("1038" + e.message) + } + } + }); + + } + }); } return false; - } catch (e) - { + } catch (e) { console.error("F1. op_save") alert_box(e.message); } } -function get_history_account(ctl, dossier) { - if ($(ctl).value != '') - { + +function get_history_account(ctl, dossier) { + if ($(ctl).value != '') { view_history_account($(ctl).value, dossier); } } + var previous = []; -var let_previous=""; -function show_reconcile(p_div, p_let) -{ - try - { - if (previous.length != 0 || p_let == let_previous ) - { +var let_previous = ""; + +function show_reconcile(p_div, p_let) { + try { + if (previous.length != 0 || p_let == let_previous) { var count_elt = previous.length; var i = 0; for (i = 0; i < count_elt; i++) { @@ -1335,8 +1321,8 @@ function show_reconcile(p_div, p_let) } var name = 'tr_' + p_let + '_' + p_div; var elt = document.getElementsByName(name); - if ( p_let != let_previous ) { - + if (p_let != let_previous) { + previous = elt; var count_elt = elt.length; var i = 0; @@ -1346,24 +1332,22 @@ function show_reconcile(p_div, p_let) elt[i].style.fontWeight = 'bolder'; } - let_previous=p_let; - } - else { - let_previous=""; + let_previous = p_let; + } else { + let_previous = ""; } - } catch (e) - { + } catch (e) { alert_box(e.message); } } + /** * add a line in the form for the purchase ledger */ -function gestion_add_row() -{ +function gestion_add_row() { try { style = 'class="input_text"'; var mytable = g("art").tBodies[0]; @@ -1372,8 +1356,7 @@ function gestion_add_row() var nCell = mytable.rows[1].cells.length; var row = mytable.insertRow(line); var nb = g("nb_item"); - for (var e = 0; e < nCell; e++) - { + for (var e = 0; e < nCell; e++) { var newCell = row.insertCell(e); var tt = ofirstRow.cells[e].innerHTML; var new_tt = tt.replace(/march0/g, "march" + nb.value); @@ -1407,97 +1390,109 @@ function gestion_add_row() } } -function document_remove(p_dossier,p_div,p_jrid) -{ - smoke.confirm(content[50], function (e) - { + +function document_remove(p_dossier, p_div, p_jrid) { + smoke.confirm(content[50], function (e) { if (e) { new Ajax.Request('ajax_misc.php', - { - parameters:{"op":"ledger","gDossier":p_dossier,"div":p_div,"p_jrid":p_jrid,'act':'rmf'}, - onSuccess : function(x) { - $('receipt'+p_div).innerHTML=x.responseText; - } - }) + { + parameters: {"op": "ledger", "gDossier": p_dossier, "div": p_div, "p_jrid": p_jrid, 'act': 'rmf'}, + onSuccess: function (x) { + $('receipt' + p_div).innerHTML = x.responseText; + } + }) } }); } + /*** * receive an object and display a list of filter + form to save one * fill up the span (id : {div}search_filter_span) with the name of the selected filter - * Object = '{'div':'','type':'ALL','all_type':1,'dossier':'10104'}' + * Object = '{'div':'','type':'ALL','all_type':1,'dossier':'10104'}' * @see Acc_Ledger_Search */ function manage_search_filter(p_obj) { waiting_box(); new Ajax.Request("ajax_misc.php", { - method:'get', - parameters:{"op":"display_search_filter","gDossier":p_obj.dossier,"div":p_obj.div,"ledger_type":p_obj.ledger_type,"all_type":p_obj.all_type}, - onSuccess:function(req) { + method: 'get', + parameters: { + "op": "display_search_filter", + "gDossier": p_obj.dossier, + "div": p_obj.div, + "ledger_type": p_obj.ledger_type, + "all_type": p_obj.all_type + }, + onSuccess: function (req) { remove_waiting_box(); - var x=posX; - var y=calcy(200) - create_div({'id':'boxfilter'+p_obj.div,'cssclass':'inner_box','html':req.responseText,'style':'top:'+y+'px;left:'+x+'px;position:absolute;width:400px',drag:1}); - $('boxfilter'+p_obj.div).show(); - } + var x = posX; + var y = calcy(200) + create_div({ + 'id': 'boxfilter' + p_obj.div, + 'cssclass': 'inner_box', + 'html': req.responseText, + 'style': 'top:' + y + 'px;left:' + x + 'px;position:absolute;width:400px', + drag: 1 + }); + $('boxfilter' + p_obj.div).show(); + } }); } /** * Send data from the form and record a new filter , the ajax answer is a json object * with the attribute filter_name,filter_id,status,message - * + * * @param p_div prefix id of all concerned DOM Element - * @param p_dossier + * @param p_dossier * @see Acc_Ledger_Search */ -function save_filter(p_div,p_dossier) { - var elt=['ledger_type','nb_jrn','date_start','date_end', - 'date_paid_start','date_paid_end','desc','amount_min','amount_max','qcode','accounting', - 'operation_filter','tag_option','p_currency_code','tva_id_search']; - var eltValue={}; - var i =0; - eltValue['gDossier']=p_dossier; - eltValue['op']="save_filter"; - eltValue['div']=p_div; - eltValue['filter_name']=$(p_div+"filter_new").value; +function save_filter(p_div, p_dossier) { + var elt = ['ledger_type', 'nb_jrn', 'date_start', 'date_end', + 'date_paid_start', 'date_paid_end', 'desc', 'amount_min', 'amount_max', 'qcode', 'accounting', + 'operation_filter', 'tag_option', 'p_currency_code', 'tva_id_search']; + var eltValue = {}; + var i = 0; + eltValue['gDossier'] = p_dossier; + eltValue['op'] = "save_filter"; + eltValue['div'] = p_div; + eltValue['filter_name'] = $(p_div + "filter_new").value; // Get all elt from the form - for ( var i = 0 ; i < elt.length;i++) { - var idx=elt[i]; - eltValue[idx]=$(p_div+elt[i]).value; - + for (var i = 0; i < elt.length; i++) { + var idx = elt[i]; + eltValue[idx] = $(p_div + elt[i]).value; + } - if (eltValue['amount_min']=="") eltValue["amount_min"]=0; - if (eltValue['amount_max']=="") eltValue["amount_max"]=0; - + if (eltValue['amount_min'] == "") eltValue["amount_min"] = 0; + if (eltValue['amount_max'] == "") eltValue["amount_max"] = 0; + //ledger's list r_jrn if (eltValue['nb_jrn'] > 0) { - eltValue['r_jrn']=[]; - for (i=0;i