Merge branch 'develop' of git@github.com:Dolibarr/dolibarr.git into new_add_hook_in_contact_list

This commit is contained in:
Regis Houssin 2022-03-22 10:09:01 +01:00
commit c23752b3d5
41 changed files with 743 additions and 347 deletions

View File

@ -8,6 +8,10 @@ https://en.wikipedia.org/wiki/EPC_QR_code#Generators
* For ZATCA QR Code format (Saudi Arabia)
-----------------------------------------
* For ZATCA QR Code format (Saudi Arabia). Used when INVOICE_ADD_ZATCA_QR_CODE is set
-------------------------------------------------------------------------------------
https://www.pwc.com/m1/en/services/tax/me-tax-legal-news/2021/saudi-arabia-guide-to-develop-compliant-qr-code-for-simplified-einvoices.html
https://www.tecklenborgh.com/post/ksa-zatca-publishes-guide-on-how-to-develop-a-fatoora-compliant-qr-code
Method to encode/decode ZATCA string is available in test/phpunit/BarcodeTest.php

View File

@ -358,7 +358,7 @@ class Members extends DolibarrApi
if ($member->update(DolibarrApiAccess::$user) >= 0) {
return $this->get($id);
} else {
throw new RestException(500, $member->error);
throw new RestException(500, 'Error when updating member: '.$member->error);
}
}

View File

@ -204,7 +204,7 @@ class MembersTypes extends DolibarrApi
if ($membertype->update(DolibarrApiAccess::$user) >= 0) {
return $this->get($id);
} else {
throw new RestException(500, $membertype->error);
throw new RestException(500, 'Error when updating member type: '.$membertype->error);
}
}

View File

@ -159,7 +159,7 @@ class Subscriptions extends DolibarrApi
$subscription->$field = $value;
}
if ($subscription->create(DolibarrApiAccess::$user) < 0) {
throw new RestException(500, 'Error when creating subscription', array_merge(array($subscription->error), $subscription->errors));
throw new RestException(500, 'Error when creating contribution', array_merge(array($subscription->error), $subscription->errors));
}
return $subscription->id;
}
@ -193,7 +193,7 @@ class Subscriptions extends DolibarrApi
if ($subscription->update(DolibarrApiAccess::$user) > 0) {
return $this->get($id);
} else {
throw new RestException(500, $subscription->error);
throw new RestException(500, 'Error when updating contribution: '.$subscription->error);
}
}

View File

@ -214,10 +214,6 @@ if (in_array($type, array('mysql', 'mysqli'))) {
print '<br>';
print '<fieldset><legend>'.$langs->trans("ExportOptions").'</legend>';
print '<div class="formelementrow">';
print '<input type="checkbox" name="use_transaction" value="yes" id="checkbox_use_transaction" />';
print '<label for="checkbox_use_transaction">'.$langs->trans("UseTransactionnalMode").'</label>';
print '</div>';
if (!empty($conf->global->MYSQL_OLD_OPTION_DISABLE_FK)) {
print '<div class="formelementrow">';
@ -239,14 +235,35 @@ if (in_array($type, array('mysql', 'mysqli'))) {
print '<option value="ORACLE">ORACLE</option>';
print '<option value="POSTGRESQL">POSTGRESQL</option>';
print '</select>';
print '<br>';
print '<br><br>';
print '<input type="checkbox" name="use_mysql_quick_param" value="yes" id="checkbox_use_quick" />';
print '<div class="formelementrow">';
print '<input type="checkbox" name="use_transaction" value="yes" id="checkbox_use_transaction" checked="checked" />';
print '<label for="checkbox_use_transaction">'.$langs->trans("UseTransactionnalMode").'</label>';
print '</div>';
print '<input type="checkbox" name="use_mysql_quick_param" value="yes" id="checkbox_use_quick" checked="checked" />';
print '<label for="checkbox_use_quick">';
print $form->textwithpicto($langs->trans('ExportUseMySQLQuickParameter'), $langs->trans('ExportUseMySQLQuickParameterHelp'));
print '</label>';
print '<br>';
$execmethod = 0;
if (!empty($conf->global->MAIN_EXEC_USE_POPEN)) {
$execmethod = $conf->global->MAIN_EXEC_USE_POPEN;
}
if (empty($execmethod)) {
$execmethod = 1;
}
if ($execmethod == 1) {
// If we use the "exec" method for shell, we ask if we need to use the alternative low memory exec mode.
print '<input type="checkbox" name="lowmemorydump" value="yes" id="lowmemorydump"'.(GETPOSTISSET('lowmemorydump') ? GETPOST('lowmemorydump', 'alpha') : getDolGlobalString('MAIN_LOW_MEMORY_DUMP') ? ' checked="checked"' : '').'" />';
print '<label for="lowmemorydump">';
print $form->textwithpicto($langs->trans('ExportUseLowMemoryMode'), $langs->trans('ExportUseLowMemoryModeHelp'));
print '</label>';
print '<br>';
}
print '<!-- <input type="checkbox" name="drop_database" value="yes" id="checkbox_drop_database" />';
print '<label for="checkbox_drop_database">'.$langs->trans("AddDropDatabase").'</label>';
print '-->';

View File

@ -126,7 +126,7 @@ class Documents extends DolibarrApi
* @param string $langcode Language code like 'en_US', 'fr_FR', 'es_ES', ... (If not set, use the default language).
* @return array List of documents
*
* @throws RestException 500
* @throws RestException 500 System error
* @throws RestException 501
* @throws RestException 400
* @throws RestException 401
@ -249,7 +249,7 @@ class Documents extends DolibarrApi
* @throws RestException 400
* @throws RestException 401
* @throws RestException 404
* @throws RestException 500
* @throws RestException 500 System error
*
* @url GET /
*/
@ -546,7 +546,7 @@ class Documents extends DolibarrApi
* @throws RestException 400
* @throws RestException 401
* @throws RestException 404
* @throws RestException 500
* @throws RestException 500 System error
*
* @url POST /upload
*/

View File

@ -158,6 +158,25 @@ if (!empty($reg[1]) && $reg[1] == 'explorer' && ($reg[2] == '/swagger.json' || $
$api = new DolibarrApi($db, '', $refreshcache);
//var_dump($api->r->apiVersionMap);
// If MAIN_API_DEBUG is set to 1, we save logs into file "dolibarr_api.log"
if (!empty($conf->global->MAIN_API_DEBUG)) {
$r = $api->r;
$r->onCall(function () use ($r) {
// Don't log Luracast Restler Explorer recources calls
//if (!preg_match('/^explorer/', $r->url)) {
// 'method' => $api->r->requestMethod,
// 'url' => $api->r->url,
// 'route' => $api->r->apiMethodInfo->className.'::'.$api->r->apiMethodInfo->methodName,
// 'version' => $api->r->getRequestedApiVersion(),
// 'data' => $api->r->getRequestData(),
//dol_syslog("Debug API input ".var_export($r, true), LOG_DEBUG, 0, '_api');
dol_syslog("Debug API url ".var_export($r->url, true), LOG_DEBUG, 0, '_api');
dol_syslog("Debug API input ".var_export($r->getRequestData(), true), LOG_DEBUG, 0, '_api');
//}
});
}
// Enable the Restler API Explorer.
// See https://github.com/Luracast/Restler-API-Explorer for more info.
$api->r->addAPIClass('Luracast\\Restler\\Explorer');

View File

@ -1491,6 +1491,10 @@ if ($id > 0) {
$("#fullday").change(function() {
setdatefields();
});
$("#actioncode").change(function() {
if ($("#actioncode").val() == \'AC_RDV\') $("#dateend").addClass("fieldrequired");
else $("#dateend").removeClass("fieldrequired");
});
})';
print '</script>'."\n";
}
@ -1535,7 +1539,11 @@ if ($id > 0) {
print '<tr><td>'.$langs->trans("EventOnFullDay").'</td><td colspan="3"><input type="checkbox" id="fullday" name="fullday" '.($object->fulldayevent ? ' checked' : '').'></td></tr>';
// Date start - end
print '<tr><td class="nowrap"><span class="fieldrequired">'.$langs->trans("DateActionStart").' - '.$langs->trans("DateActionEnd").'</span></td><td colspan="3">';
print '<tr><td class="nowrap">';
print '<span class="fieldrequired">'.$langs->trans("DateActionStart").'</span>';
print ' - ';
print '<span id="dateend"'.($object->type_code == 'AC_RDV' ? ' class="fieldrequired"' : '').'>'.$langs->trans("DateActionEnd").'</span>';
print '</td><td td colspan="3">';
$tzforfullday = getDolGlobalString('MAIN_STORE_FULL_EVENT_IN_GMT');
if (GETPOST("afaire") == 1) {
print $form->selectDate($datep ? $datep : $object->datep, 'ap', 1, 1, 0, "action", 1, 1, 0, 'fulldaystart', '', '', '', 1, '', '', $object->fulldayevent ? ($tzforfullday ? $tzforfullday : 'tzuser') : 'tzuser');

View File

@ -246,8 +246,11 @@ if (empty($reshook)) {
// Remove line
$result = $object->deleteline($lineid);
// reorder lines
if ($result) {
if ($result > 0) {
$object->line_order(true);
} else {
$langs->load("errors");
setEventMessages($object->error, $object->errors, 'errors');
}
if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) {

View File

@ -625,7 +625,7 @@ class Proposals extends DolibarrApi
*
* @throws RestException 401
* @throws RestException 404
* @throws RestException 500
* @throws RestException 500 System error
*/
public function deleteContact($id, $contactid, $type)
{
@ -799,7 +799,7 @@ class Proposals extends DolibarrApi
* @throws RestException 304
* @throws RestException 401
* @throws RestException 404
* @throws RestException 500
* @throws RestException 500 System error
*
* @return array
*/

View File

@ -992,6 +992,8 @@ class Propal extends CommonObject
$this->db->commit();
return 1;
} else {
$this->error = $line->error;
$this->errors = $line->errors;
$this->db->rollback();
return -1;
}
@ -4194,36 +4196,40 @@ class PropaleLigne extends CommonObjectLine
$error = 0;
$this->db->begin();
$sql = "DELETE FROM ".MAIN_DB_PREFIX."propaldet WHERE rowid = ".((int) $this->rowid);
dol_syslog("PropaleLigne::delete", LOG_DEBUG);
if ($this->db->query($sql)) {
// Remove extrafields
if (!$error) {
$this->id = $this->rowid;
$result = $this->deleteExtraFields();
if ($result < 0) {
$error++;
dol_syslog(get_class($this)."::delete error -4 ".$this->error, LOG_ERR);
}
if (!$notrigger) {
// Call trigger
$result = $this->call_trigger('LINEPROPAL_DELETE', $user);
if ($result < 0) {
$error++;
}
}
// End call triggers
if (!$error && !$notrigger) {
// Call trigger
$result = $this->call_trigger('LINEPROPAL_DELETE', $user);
if ($result < 0) {
$this->db->rollback();
return -1;
if (!$error) {
$sql = "DELETE FROM " . MAIN_DB_PREFIX . "propaldet WHERE rowid = " . ((int) $this->rowid);
dol_syslog("PropaleLigne::delete", LOG_DEBUG);
if ($this->db->query($sql)) {
// Remove extrafields
if (!$error) {
$this->id = $this->rowid;
$result = $this->deleteExtraFields();
if ($result < 0) {
$error++;
dol_syslog(get_class($this) . "::delete error -4 " . $this->error, LOG_ERR);
}
}
} else {
$this->error = $this->db->error() . " sql=" . $sql;
$error++;
}
// End call triggers
}
$this->db->commit();
return 1;
} else {
$this->error = $this->db->error()." sql=".$sql;
if ($error) {
$this->db->rollback();
return -1;
} else {
$this->db->commit();
return 1;
}
}

View File

@ -574,7 +574,7 @@ class Orders extends DolibarrApi
*
* @throws RestException 401
* @throws RestException 404
* @throws RestException 500
* @throws RestException 500 System error
*/
public function deleteContact($id, $contactid, $type)
{
@ -704,7 +704,7 @@ class Orders extends DolibarrApi
* @throws RestException 304
* @throws RestException 401
* @throws RestException 404
* @throws RestException 500
* @throws RestException 500 System error
*
* @return array
*/
@ -974,7 +974,7 @@ class Orders extends DolibarrApi
*
* @throws RestException 401
* @throws RestException 404
* @throws RestException 500
* @throws RestException 500 System error
*/
public function getOrderShipments($id)
{
@ -1030,7 +1030,7 @@ class Orders extends DolibarrApi
*
* @throws RestException 401
* @throws RestException 404
* @throws RestException 500
* @throws RestException 500 System error
*/
public function createOrderShipment($id, $warehouse_id)
{

View File

@ -519,7 +519,7 @@ class Invoices extends DolibarrApi
*
* @throws RestException 401
* @throws RestException 404
* @throws RestException 500
* @throws RestException 500 System error
*/
public function deleteContact($id, $contactid, $type)
{
@ -661,7 +661,7 @@ class Invoices extends DolibarrApi
$result = $this->invoice->delete(DolibarrApiAccess::$user);
if ($result < 0) {
throw new RestException(500);
throw new RestException(500, 'Error when deleting invoice');
}
return array(
@ -780,7 +780,7 @@ class Invoices extends DolibarrApi
* @throws RestException 304
* @throws RestException 401
* @throws RestException 404
* @throws RestException 500
* @throws RestException 500 System error
*
*/
public function addContact($id, $fk_socpeople, $type_contact, $source, $notrigger = 0)
@ -829,7 +829,7 @@ class Invoices extends DolibarrApi
* @throws RestException 304
* @throws RestException 401
* @throws RestException 404
* @throws RestException 500
* @throws RestException 500 System error
*
*/
public function settodraft($id, $idwarehouse = -1)
@ -932,7 +932,7 @@ class Invoices extends DolibarrApi
* @throws RestException 304
* @throws RestException 401
* @throws RestException 404
* @throws RestException 500
* @throws RestException 500 System error
*/
public function settopaid($id, $close_code = '', $close_note = '')
{
@ -982,7 +982,7 @@ class Invoices extends DolibarrApi
* @throws RestException 304
* @throws RestException 401
* @throws RestException 404
* @throws RestException 500
* @throws RestException 500 System error
*/
public function settounpaid($id)
{
@ -1069,7 +1069,7 @@ class Invoices extends DolibarrApi
* @throws RestException 304
* @throws RestException 401
* @throws RestException 404
* @throws RestException 500
* @throws RestException 500 System error
*/
public function markAsCreditAvailable($id)
{

View File

@ -2750,8 +2750,8 @@ class ContratLigne extends CommonObjectLine
//'model_pdf' =>array('type'=>'varchar(255)', 'label'=>'Model pdf', 'enabled'=>1, 'visible'=>0, 'position'=>115),
//'import_key' =>array('type'=>'varchar(14)', 'label'=>'ImportId', 'enabled'=>1, 'visible'=>-2, 'position'=>120),
//'extraparams' =>array('type'=>'varchar(255)', 'label'=>'Extraparams', 'enabled'=>1, 'visible'=>-1, 'position'=>125),
'fk_user_ouverture' =>array('type'=>'integer:User:user/class/user.class.php', 'label'=>'UserOpen', 'enabled'=>1, 'visible'=>-2, 'notnull'=>-1, 'position'=>135),
'fk_user_cloture' =>array('type'=>'integer:User:user/class/user.class.php', 'label'=>'UserCloture', 'enabled'=>1, 'visible'=>-2, 'notnull'=>-1, 'position'=>135),
'fk_user_ouverture' =>array('type'=>'integer:User:user/class/user.class.php', 'label'=>'UserStartingService', 'enabled'=>1, 'visible'=>-2, 'notnull'=>-1, 'position'=>135),
'fk_user_cloture' =>array('type'=>'integer:User:user/class/user.class.php', 'label'=>'UserClosingService', 'enabled'=>1, 'visible'=>-2, 'notnull'=>-1, 'position'=>135),
'statut' =>array('type'=>'smallint(6)', 'label'=>'Statut', 'enabled'=>1, 'visible'=>-1, 'position'=>500, 'arrayofkeyval'=>array(0=>'Draft', 4=>'Open', 5=>'Closed'))
);
// END MODULEBUILDER PROPERTIES

View File

@ -350,25 +350,43 @@ if ($search_dfyear > 0 && $search_op2df) {
$sql .= " HAVING MIN(".$db->ifsql("cd.statut=4", "cd.date_fin_validite", "null").") <= '".$db->idate(dol_get_last_day($search_dfyear, $search_dfmonth, false))."' AND MIN(".$db->ifsql("cd.statut=4", "cd.date_fin_validite", "null").") >= '".$db->idate(dol_get_first_day($search_dfyear, $search_dfmonth, false))."'";
}
}
$sql .= $db->order($sortfield, $sortorder);
$totalnboflines = 0;
$result = $db->query($sql);
if ($result) {
$totalnboflines = $db->num_rows($result);
}
$nbtotalofrecords = '';
if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST)) {
$result = $db->query($sql);
$nbtotalofrecords = $db->num_rows($result);
//$result = $db->query($sql);
//$nbtotalofrecords = $db->num_rows($result);
if ($search_dfyear > 0 && $search_op2df) {
$resql = $db->query($sql, 0, 'auto', 1);
while ($db->fetch_object($resql)) {
if (empty($nbtotalofrecords)) {
$nbtotalofrecords = 1; // We can't make +1 because init value is ''
} else {
$nbtotalofrecords++;
}
}
} else {
$sqlforcount = preg_replace('/^SELECT[a-zA-Z0-9\._\s\(\),=<>\:\-\']+\sFROM/', 'SELECT COUNT(*) as nbtotalofrecords FROM', $sql);
$sqlforcount = preg_replace('/LEFT JOIN '.MAIN_DB_PREFIX.'contratdet as cd ON c.rowid = cd.fk_contrat/', '', $sqlforcount);
$sqlforcount = preg_replace('/LEFT JOIN '.MAIN_DB_PREFIX.'categorie_product as cp ON cp.fk_product=cd.fk_product/', '', $sqlforcount);
$sqlforcount = preg_replace('/AND cp.fk_categorie = '.((int) $search_product_category).'/', '', $sqlforcount);
$sqlforcount = preg_replace('/GROUP BY.*$/', '', $sqlforcount);
$resql = $db->query($sqlforcount);
$objforcount = $db->fetch_object($resql);
$nbtotalofrecords = $objforcount->nbtotalofrecords;
}
if (($page * $limit) > $nbtotalofrecords) { // if total resultset is smaller then paging size (filtering), goto and load page 0
$page = 0;
$offset = 0;
}
}
$sql .= $db->plimit($limit + 1, $offset);
$sql .= $db->order($sortfield, $sortorder);
if ($limit) {
$sql .= $db->plimit($limit + 1, $offset);
}
$resql = $db->query($sql);
if (!$resql) {
@ -508,7 +526,7 @@ print '<input type="hidden" name="sortfield" value="'.$sortfield.'">';
print '<input type="hidden" name="sortorder" value="'.$sortorder.'">';
print '<input type="hidden" name="contextpage" value="'.$contextpage.'">';
print_barre_liste($langs->trans("ListOfContracts"), $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, $massactionbutton, $num, $totalnboflines, 'contract', 0, $newcardbutton, '', $limit, 0, 0, 1);
print_barre_liste($langs->trans("ListOfContracts"), $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, $massactionbutton, $num, $nbtotalofrecords, 'contract', 0, $newcardbutton, '', $limit, 0, 0, 1);
$topicmail = "SendContractRef";
$modelmail = "contract";

View File

@ -827,8 +827,10 @@ abstract class CommonInvoice extends CommonObject
$tmplang->load("main");
$datestring = dol_print_date($this->date, 'dayhourrfc');
$pricewithtaxstring = price($this->total_ttc, 0, $tmplang, 0, -1, 2);
$pricetaxstring = price($this->total_tva, 0, $tmplang, 0, -1, 2);
//$pricewithtaxstring = price($this->total_ttc, 0, $tmplang, 0, -1, 2);
//$pricetaxstring = price($this->total_tva, 0, $tmplang, 0, -1, 2);
$pricewithtaxstring = price2num($this->total_ttc, 2, 1);
$pricetaxstring = price2num($this->total_tva, 2, 1);
/*
$name = implode(unpack("H*", $this->thirdparty->name));
@ -857,7 +859,7 @@ abstract class CommonInvoice extends CommonObject
// Using TLV format
$s = pack('C1', 1).pack('C1', strlen($this->thirdparty->name)).$this->thirdparty->name;
$s .= pack('C1', 2).pack('C1', strlen($this->thirdparty->tva_intra)).$this->thirdparty->tva_intra;
$s .= pack('C1', 3).pack('C1', strlen($datestring)).$this->date;
$s .= pack('C1', 3).pack('C1', strlen($datestring)).$datestring;
$s .= pack('C1', 4).pack('C1', strlen($pricewithtaxstring)).$pricewithtaxstring;
$s .= pack('C1', 5).pack('C1', strlen($pricetaxstring)).$pricetaxstring;
$s .= ''; // Hash of xml invoice

View File

@ -54,12 +54,21 @@ class DiscountAbsolute
public $fk_soc;
public $discount_type; // 0 => customer discount, 1 => supplier discount
public $amount_ht; //
public $amount_tva; //
public $amount_ttc; //
public $multicurrency_amount_ht;
public $multicurrency_amount_tva;
public $multicurrency_amount_ttc;
public $total_ht;
public $total_tva;
public $total_ttc;
public $amount_ht; // deprecated
public $amount_tva; // deprecated
public $amount_ttc; // deprecated
public $multicurrency_total_ht;
public $multicurrency_total_tva;
public $multicurrency_total_ttc;
public $multicurrency_amount_ht; // deprecated
public $multicurrency_amount_tva; // deprecated
public $multicurrency_amount_ttc; // deprecated
// Vat rate
public $tva_tx;
public $vat_src_code;
@ -163,13 +172,21 @@ class DiscountAbsolute
$this->fk_soc = $obj->fk_soc;
$this->discount_type = $obj->discount_type;
$this->amount_ht = $obj->amount_ht;
$this->amount_tva = $obj->amount_tva;
$this->amount_ttc = $obj->amount_ttc;
$this->total_ht = $obj->amount_ht;
$this->total_tva = $obj->amount_tva;
$this->total_ttc = $obj->amount_ttc;
// For backward compatibility
$this->amount_ht = $this->total_ht;
$this->amount_tva = $this->total_tva;
$this->amount_ttc = $this->total_ttc;
$this->multicurrency_amount_ht = $this->multicurrency_subprice = $obj->multicurrency_amount_ht;
$this->multicurrency_amount_tva = $obj->multicurrency_amount_tva;
$this->multicurrency_amount_ttc = $obj->multicurrency_amount_ttc;
$this->multicurrency_total_ht = $this->multicurrency_subprice = $obj->multicurrency_amount_ht;
$this->multicurrency_total_tva = $obj->multicurrency_amount_tva;
$this->multicurrency_total_ttc = $obj->multicurrency_amount_ttc;
// For backward compatibility
$this->multicurrency_amount_ht = $this->multicurrency_total_ht;
$this->multicurrency_amount_tva = $this->multicurrency_total_tva;
$this->multicurrency_amount_ttc = $this->multicurrency_total_ttc;
$this->tva_tx = $obj->tva_tx;
$this->vat_src_code = $obj->vat_src_code;

View File

@ -193,10 +193,10 @@ class DolEditor
removePlugins : \''.$pluginstodisable.'\',
readOnly : '.($this->readonly ? 'true' : 'false').',
htmlEncodeOutput :'.$htmlencode_force.',
allowedContent :'.($disallowAnyContent ? 'false' : 'true').',
extraAllowedContent : \'a[target];div{float,display}\', /* Add the style float and display into div to default other allowed tags */
disallowedContent : '.($disallowAnyContent ? '\'\'' : '\'\'').',
fullPage : '.($fullpage ? 'true' : 'false').',
allowedContent :'.($disallowAnyContent ? 'false' : 'true').', /* Advanced Content Filter (ACF) is own when allowedContent is false */
extraAllowedContent : \'a[target];div{float,display}\', /* Add the style float and display into div to default other allowed tags */
disallowedContent : '.($disallowAnyContent ? '\'\'' : '\'\'').', /* Tags that are not allowed */
fullPage : '.($fullpage ? 'true' : 'false').', /* if true, the html, header and body tags are kept */
toolbar: \''.$this->toolbarname.'\',
toolbarStartupExpanded: '.($this->toolbarstartexpanded ? 'true' : 'false').',
width: '.($this->width ? '\''.$this->width.'\'' : '\'\'').',

View File

@ -189,7 +189,7 @@ class Utils
* @param int $usedefault 1=Use default backup profile (Set this to 1 when used as cron)
* @param string $file 'auto' or filename to build
* @param int $keeplastnfiles Keep only last n files (not used yet)
* @param int $execmethod 0=Use default method (that is 1 by default), 1=Use the PHP 'exec', 2=Use the 'popen' method
* @param int $execmethod 0=Use default method (that is 1 by default), 1=Use the PHP 'exec' - need size of dump in memory, but low memory method is used if GETPOST('lowmemorydump') is set, 2=Use the 'popen' method (low memory method)
* @return int 0 if OK, < 0 if KO (this function is used also by cron so only 0 is OK)
*/
public function dumpDatabase($compression = 'none', $type = 'auto', $usedefault = 1, $file = 'auto', $keeplastnfiles = 0, $execmethod = 0)
@ -278,8 +278,8 @@ class Utils
if (!empty($dolibarr_main_db_port)) {
$param .= " -P ".$dolibarr_main_db_port;
}
if (!GETPOST("use_transaction", "alpha")) {
$param .= " -l --single-transaction";
if (GETPOST("use_transaction", "alpha")) {
$param .= " --single-transaction";
}
if (GETPOST("disable_fk", "alpha") || $usedefault) {
$param .= " -K";
@ -342,17 +342,42 @@ class Utils
$handle = '';
$lowmemorydump = GETPOSTISSET("lowmemorydump", "alpha") ? GETPOST("lowmemorydump") : getDolGlobalString('MAIN_LOW_MEMORY_DUMP');
// Start call method to execute dump
$fullcommandcrypted = $command." ".$paramcrypted." 2>&1";
$fullcommandclear = $command." ".$paramclear." 2>&1";
if ($compression == 'none') {
$handle = fopen($outputfile, 'w');
} elseif ($compression == 'gz') {
$handle = gzopen($outputfile, 'w');
} elseif ($compression == 'bz') {
$handle = bzopen($outputfile, 'w');
} elseif ($compression == 'zstd') {
$handle = fopen($outputfile, 'w');
if (!$lowmemorydump) {
if ($compression == 'none') {
$handle = fopen($outputfile, 'w');
} elseif ($compression == 'gz') {
$handle = gzopen($outputfile, 'w');
} elseif ($compression == 'bz') {
$handle = bzopen($outputfile, 'w');
} elseif ($compression == 'zstd') {
$handle = fopen($outputfile, 'w');
}
} else {
if ($compression == 'none') {
$fullcommandclear .= " > ".$outputfile;
$fullcommandcrypted .= " > ".$outputfile;
$handle = 1;
} elseif ($compression == 'gz') {
$fullcommandclear .= " | gzip > ".$outputfile;
$fullcommandcrypted .= " | gzip > ".$outputfile;
$paramcrypted.=" | gzip";
$handle = 1;
} elseif ($compression == 'bz') {
$fullcommandclear .= " | bzip2 > ".$outputfile;
$fullcommandcrypted .= " | bzip2 > ".$outputfile;
$paramcrypted.=" | bzip2";
$handle = 1;
} elseif ($compression == 'zstd') {
$fullcommandclear .= " | zstd > ".$outputfile;
$fullcommandcrypted .= " | zstd > ".$outputfile;
$paramcrypted.=" | zstd";
$handle = 1;
}
}
$ok = 0;
@ -374,7 +399,8 @@ class Utils
}
// TODO Replace with executeCLI function
// TODO Replace with executeCLI function but
// we must first introduce a low memory mode
if ($execmethod == 1) {
$output_arr = array();
$retval = null;
@ -394,16 +420,23 @@ class Utils
if ($i == 1 && preg_match('/Warning.*Using a password/i', $read)) {
continue;
}
fwrite($handle, $read.($execmethod == 2 ? '' : "\n"));
if (preg_match('/'.preg_quote('-- Dump completed', '/').'/i', $read)) {
$ok = 1;
} elseif (preg_match('/'.preg_quote('SET SQL_NOTES=@OLD_SQL_NOTES', '/').'/i', $read)) {
$ok = 1;
if (!$lowmemorydump) {
fwrite($handle, $read.($execmethod == 2 ? '' : "\n"));
if (preg_match('/'.preg_quote('-- Dump completed', '/').'/i', $read)) {
$ok = 1;
} elseif (preg_match('/'.preg_quote('SET SQL_NOTES=@OLD_SQL_NOTES', '/').'/i', $read)) {
$ok = 1;
}
} else {
// If we have a result here in lowmemorydump mode, something is strange
}
}
} elseif ($lowmemorydump) {
$ok = 1;
}
}
}
if ($execmethod == 2) { // With this method, there is no way to get the return code, only output
$handlein = popen($fullcommandclear, 'r');
$i = 0;

View File

@ -556,9 +556,26 @@ if (!empty($search_measures) && !empty($search_xaxis)) {
$sql .= ' AND parenttable.entity IN ('.getEntity($tmparray[1]).')';
}
}
// Add INNER JOIN for all parent tables
//var_dump($arrayofxaxis); var_dump($search_xaxis);
$listoftablesalreadyadded = array($object->table_element => $object->table_element);
foreach ($search_xaxis as $key => $val) {
if (!empty($arrayofxaxis[$val])) {
$tmpval = explode('.', $val);
//var_dump($arrayofxaxis[$val]['table']);
if (! in_array($arrayofxaxis[$val]['table'], $listoftablesalreadyadded)) { // We do not add join for main table already added
$sql .= ' INNER JOIN '.MAIN_DB_PREFIX.$arrayofxaxis[$val]['table'].' as '.$tmpval[0];
$listoftablesalreadyadded[$arrayofxaxis[$val]['table']] = $arrayofxaxis[$val]['table'];
}
} else {
dol_print_error($db, 'Found an key into search_xaxis not found into arrayofxaxis');
}
}
$sql .= ' WHERE 1 = 1';
if ($object->ismultientitymanaged == 1) {
$sql .= ' AND entity IN ('.getEntity($object->element).')';
$sql .= ' AND t.entity IN ('.getEntity($object->element).')';
}
// Add the where here
$sqlfilters = $search_component_params_hidden;
@ -914,7 +931,7 @@ function fillArrayOfMeasures($object, $tablealias, $labelofobject, &$arrayofmesu
* Fill arrayofmesures for an object
*
* @param mixed $object Any object
* @param string $tablealias Alias of table
* @param string $tablealias Alias of table ('t' for example)
* @param string $labelofobject Label of object
* @param array $arrayofxaxis Array of xaxis already filled
* @param int $level Level
@ -964,14 +981,31 @@ function fillArrayOfXAxis($object, $tablealias, $labelofobject, &$arrayofxaxis,
continue;
}
if (in_array($val['type'], array('timestamp', 'date', 'datetime'))) {
$arrayofxaxis[$tablealias.'.'.$key.'-year'] = array('label' => img_picto('', $object->picto, 'class="pictofixedwidth"').' '.$labelofobject.': '.$langs->trans($val['label']).' <span class="opacitymedium">('.$YYYY.')</span>', 'position' => ($val['position']+($count * 100000)).'.1');
$arrayofxaxis[$tablealias.'.'.$key.'-month'] = array('label' => img_picto('', $object->picto, 'class="pictofixedwidth"').' '.$labelofobject.': '.$langs->trans($val['label']).' <span class="opacitymedium">('.$YYYY.'-'.$MM.')</span>', 'position' => ($val['position']+($count * 100000)).'.2');
$arrayofxaxis[$tablealias.'.'.$key.'-day'] = array('label' => img_picto('', $object->picto, 'class="pictofixedwidth"').' '.$labelofobject.': '.$langs->trans($val['label']).' <span class="opacitymedium">('.$YYYY.'-'.$MM.'-'.$DD.')</span>', 'position' => ($val['position']+($count * 100000)).'.3');
$arrayofxaxis[$tablealias.'.'.$key.'-year'] = array(
'label' => img_picto('', $object->picto, 'class="pictofixedwidth"').' '.$labelofobject.': '.$langs->trans($val['label']).' <span class="opacitymedium">('.$YYYY.')</span>',
'position' => ($val['position']+($count * 100000)).'.1',
'table' => $object->table_element
);
$arrayofxaxis[$tablealias.'.'.$key.'-month'] = array(
'label' => img_picto('', $object->picto, 'class="pictofixedwidth"').' '.$labelofobject.': '.$langs->trans($val['label']).' <span class="opacitymedium">('.$YYYY.'-'.$MM.')</span>',
'position' => ($val['position']+($count * 100000)).'.2',
'table' => $object->table_element
);
$arrayofxaxis[$tablealias.'.'.$key.'-day'] = array(
'label' => img_picto('', $object->picto, 'class="pictofixedwidth"').' '.$labelofobject.': '.$langs->trans($val['label']).' <span class="opacitymedium">('.$YYYY.'-'.$MM.'-'.$DD.')</span>',
'position' => ($val['position']+($count * 100000)).'.3',
'table' => $object->table_element
);
} else {
$arrayofxaxis[$tablealias.'.'.$key] = array('label' => img_picto('', $object->picto, 'class="pictofixedwidth"').' '.$labelofobject.': '.$langs->trans($val['label']), 'position' => ($val['position']+($count * 100000)));
$arrayofxaxis[$tablealias.'.'.$key] = array(
'label' => img_picto('', $object->picto, 'class="pictofixedwidth"').' '.$labelofobject.': '.$langs->trans($val['label']),
'position' => ($val['position']+($count * 100000)),
'table' => $object->table_element
);
}
}
}
// Add extrafields to X-Axis
if ($object->isextrafieldmanaged) {
foreach ($extrafields->attributes[$object->table_element]['label'] as $key => $val) {
@ -981,9 +1015,14 @@ function fillArrayOfXAxis($object, $tablealias, $labelofobject, &$arrayofxaxis,
if (!empty($extrafields->attributes[$object->table_element]['totalizable'][$key])) {
continue;
}
$arrayofxaxis[$tablealias.'e.'.$key] = array('label' => img_picto('', $object->picto, 'class="pictofixedwidth"').' '.$labelofobject.': '.$langs->trans($extrafields->attributes[$object->table_element]['label'][$key]), 'position' => 1000 + (int) $extrafields->attributes[$object->table_element]['pos'][$key] + ($count * 100000));
$arrayofxaxis[$tablealias.'e.'.$key] = array(
'label' => img_picto('', $object->picto, 'class="pictofixedwidth"').' '.$labelofobject.': '.$langs->trans($extrafields->attributes[$object->table_element]['label'][$key]),
'position' => 1000 + (int) $extrafields->attributes[$object->table_element]['pos'][$key] + ($count * 100000),
'table' => $object->table_element
);
}
}
// Add fields for parent objects
foreach ($object->fields as $key => $val) {
if (preg_match('/^[^:]+:[^:]+:/', $val['type'])) {
@ -993,10 +1032,7 @@ function fillArrayOfXAxis($object, $tablealias, $labelofobject, &$arrayofxaxis,
dol_include_once($tmptype[2]);
if (class_exists($newobject)) {
$tmpobject = new $newobject($db);
/*var_dump($val['label']);
var_dump($tmptype);
var_dump($arrayofmesures);
var_dump('t-'.$key);*/
//var_dump($key); var_dump($tmpobject->element); var_dump($val['label']); var_dump($tmptype); var_dump('t-'.$key);
$count++;
$arrayofxaxis = fillArrayOfXAxis($tmpobject, $tablealias.'__'.$key, $langs->trans($val['label']), $arrayofxaxis, $level + 1, $count);
} else {

View File

@ -266,7 +266,7 @@ class DoliDBMysqli extends DoliDB
* @param int $usesavepoint 0=Default mode, 1=Run a savepoint before and a rollback to savepoint if error (this allow to have some request with errors inside global transactions).
* Note that with Mysql, this parameter is not used as Myssql can already commit a transaction even if one request is in error, without using savepoints.
* @param string $type Type of SQL order ('ddl' for insert, update, select, delete or 'dml' for create, alter...)
* @param int $result_mode Result mode
* @param int $result_mode Result mode (Using 1=MYSQLI_USE_RESULT instead of 0=MYSQLI_STORE_RESULT will not buffer the result and save memory)
* @return bool|mysqli_result Resultset of answer
*/
public function query($query, $usesavepoint = 0, $type = 'auto', $result_mode = 0)

View File

@ -156,8 +156,8 @@ function print_eldy_menu($db, $atarget, $type_user, &$tabMenu, &$menu, $noout =
'name' => 'Products',
'link' => '/product/index.php?mainmenu=products&amp;leftmenu=',
'title' => (!empty($conf->product->enabled) && !empty($conf->service->enabled))
? (array("TMenuProducts", " | ", "TMenuServices"))
: (!empty($conf->product->enabled) ? "TMenuProducts" : "TMenuServices"),
? (array("TMenuProducts", " | ", "TMenuServices"))
: (!empty($conf->product->enabled) ? "TMenuProducts" : "TMenuServices"),
'level' => 0,
'enabled' => $showmode = isVisibleToUserType($type_user, $tmpentry, $listofmodulesforexternal),
'target' => $atarget,
@ -232,7 +232,7 @@ function print_eldy_menu($db, $atarget, $type_user, &$tabMenu, &$menu, $noout =
|| !empty($conf->supplier_order->enabled)
|| !empty($conf->contrat->enabled)
|| !empty($conf->ficheinter->enabled)
) ? 1 : 0,
) ? 1 : 0,
'perms'=>(!empty($user->rights->propal->lire)
|| !empty($user->rights->commande->lire)
|| !empty($user->rights->supplier_proposal->lire)
@ -241,17 +241,17 @@ function print_eldy_menu($db, $atarget, $type_user, &$tabMenu, &$menu, $noout =
|| !empty($user->rights->supplier_order->lire)
|| !empty($user->rights->contrat->lire)
|| !empty($user->rights->ficheinter->lire)
),
),
'module'=>'propal|commande|supplier_proposal|supplier_order|contrat|ficheinter'
);
$onlysupplierorder = !empty($user->rights->fournisseur->commande->lire) &&
empty($user->rights->propal->lire) &&
empty($user->rights->commande->lire) &&
empty($user->rights->supplier_order->lire) &&
empty($user->rights->supplier_proposal->lire) &&
empty($user->rights->contrat->lire) &&
empty($user->rights->ficheinter->lire);
empty($user->rights->propal->lire) &&
empty($user->rights->commande->lire) &&
empty($user->rights->supplier_order->lire) &&
empty($user->rights->supplier_proposal->lire) &&
empty($user->rights->contrat->lire) &&
empty($user->rights->ficheinter->lire);
$menu_arr[] = array(
'name' => 'Commercial',
@ -524,7 +524,7 @@ function print_eldy_menu($db, $atarget, $type_user, &$tabMenu, &$menu, $noout =
$idsel,
$classname,
$newTabMenu[$i]['prefix']
);
);
}
// Sort on position
@ -544,9 +544,9 @@ function print_eldy_menu($db, $atarget, $type_user, &$tabMenu, &$menu, $noout =
if (!empty($mysoc->logo_squarred_mini) && is_readable($conf->mycompany->dir_output.'/logos/thumbs/'.$mysoc->logo_squarred_mini)) {
$urllogo = DOL_URL_ROOT.'/viewimage.php?cache=1&amp;modulepart=mycompany&amp;file='.urlencode('logos/thumbs/'.$mysoc->logo_squarred_mini);
/*} elseif (! empty($mysoc->logo_mini) && is_readable($conf->mycompany->dir_output.'/logos/thumbs/'.$mysoc->logo_mini))
{
$urllogo=DOL_URL_ROOT.'/viewimage.php?cache=1&amp;modulepart=mycompany&amp;file='.urlencode('logos/thumbs/'.$mysoc->logo_mini);
}*/
{
$urllogo=DOL_URL_ROOT.'/viewimage.php?cache=1&amp;modulepart=mycompany&amp;file='.urlencode('logos/thumbs/'.$mysoc->logo_mini);
}*/
} else {
$urllogo = DOL_URL_ROOT.'/theme/dolibarr_512x512_white.png';
$logoContainerAdditionalClass = '';
@ -798,7 +798,7 @@ function print_left_eldy_menu($db, $menu_array_before, $menu_array_after, &$tabM
/*
* Menu HRM
*/
*/
if ($mainmenu == 'hrm') {
get_left_menu_hrm($mainmenu, $newmenu, $usemenuhider, $leftmenu, $type_user);
}
@ -881,13 +881,13 @@ function print_left_eldy_menu($db, $menu_array_before, $menu_array_after, &$tabM
// TODO Use the position property in menu_array to reorder the $menu_array
//var_dump($menu_array);
/*$new_menu_array = array();
$level=0; $cusor=0; $position=0;
$nbentry = count($menu_array);
while (findNextEntryForLevel($menu_array, $cursor, $position, $level))
{
$level=0; $cusor=0; $position=0;
$nbentry = count($menu_array);
while (findNextEntryForLevel($menu_array, $cursor, $position, $level))
{
$cursor++;
}*/
$cursor++;
}*/
// Show menu
$invert = empty($conf->global->MAIN_MENU_INVERT) ? "" : "invert";
@ -1046,11 +1046,11 @@ function print_left_eldy_menu($db, $menu_array_before, $menu_array_after, &$tabM
/**
* Get left Menu HOME
*
* @param string $mainmenu
* @param Menu &$newmenu Object Menu to return back list of menu entries
* @param string $usemenuhider
* @param string $leftmenu
* @param int $type_user
* @param string $mainmenu Main menu
* @param Menu $newmenu Object Menu to return back list of menu entries
* @param string $usemenuhider Use menu hider
* @param string $leftmenu Left menu
* @param int $type_user Type of user
* @return void
*/
function get_left_menu_home($mainmenu, &$newmenu, $usemenuhider = 1, $leftmenu = 'none', $type_user = 0)
@ -1165,11 +1165,11 @@ function get_left_menu_home($mainmenu, &$newmenu, $usemenuhider = 1, $leftmenu =
/**
* Get left Menu THIRDPARTIES
*
* @param string $mainmenu
* @param Menu &$newmenu Object Menu to return back list of menu entries
* @param string $usemenuhider
* @param string $leftmenu
* @param int $type_user
* @param string $mainmenu Main menu
* @param Menu $newmenu Object Menu to return back list of menu entries
* @param string $usemenuhider Use menu hider
* @param string $leftmenu Left menu
* @param int $type_user Type of targeted user for menu
* @return void
*/
function get_left_menu_thridparties($mainmenu, &$newmenu, $usemenuhider = 1, $leftmenu = 'none', $type_user = 0)
@ -1197,12 +1197,12 @@ function get_left_menu_thridparties($mainmenu, &$newmenu, $usemenuhider = 1, $le
$langs->load("commercial");
$newmenu->add("/societe/list.php?type=p&amp;leftmenu=prospects", $langs->trans("ListProspectsShort"), 2, $user->rights->societe->lire, '', $mainmenu, 'prospects');
/* no more required, there is a filter that can do more
if ($usemenuhider || empty($leftmenu) || $leftmenu=="prospects") $newmenu->add("/societe/list.php?type=p&amp;sortfield=s.datec&amp;sortorder=desc&amp;begin=&amp;search_stcomm=-1", $langs->trans("LastProspectDoNotContact"), 2, $user->rights->societe->lire);
if ($usemenuhider || empty($leftmenu) || $leftmenu=="prospects") $newmenu->add("/societe/list.php?type=p&amp;sortfield=s.datec&amp;sortorder=desc&amp;begin=&amp;search_stcomm=0", $langs->trans("LastProspectNeverContacted"), 2, $user->rights->societe->lire);
if ($usemenuhider || empty($leftmenu) || $leftmenu=="prospects") $newmenu->add("/societe/list.php?type=p&amp;sortfield=s.datec&amp;sortorder=desc&amp;begin=&amp;search_stcomm=1", $langs->trans("LastProspectToContact"), 2, $user->rights->societe->lire);
if ($usemenuhider || empty($leftmenu) || $leftmenu=="prospects") $newmenu->add("/societe/list.php?type=p&amp;sortfield=s.datec&amp;sortorder=desc&amp;begin=&amp;search_stcomm=2", $langs->trans("LastProspectContactInProcess"), 2, $user->rights->societe->lire);
if ($usemenuhider || empty($leftmenu) || $leftmenu=="prospects") $newmenu->add("/societe/list.php?type=p&amp;sortfield=s.datec&amp;sortorder=desc&amp;begin=&amp;search_stcomm=3", $langs->trans("LastProspectContactDone"), 2, $user->rights->societe->lire);
*/
if ($usemenuhider || empty($leftmenu) || $leftmenu=="prospects") $newmenu->add("/societe/list.php?type=p&amp;sortfield=s.datec&amp;sortorder=desc&amp;begin=&amp;search_stcomm=-1", $langs->trans("LastProspectDoNotContact"), 2, $user->rights->societe->lire);
if ($usemenuhider || empty($leftmenu) || $leftmenu=="prospects") $newmenu->add("/societe/list.php?type=p&amp;sortfield=s.datec&amp;sortorder=desc&amp;begin=&amp;search_stcomm=0", $langs->trans("LastProspectNeverContacted"), 2, $user->rights->societe->lire);
if ($usemenuhider || empty($leftmenu) || $leftmenu=="prospects") $newmenu->add("/societe/list.php?type=p&amp;sortfield=s.datec&amp;sortorder=desc&amp;begin=&amp;search_stcomm=1", $langs->trans("LastProspectToContact"), 2, $user->rights->societe->lire);
if ($usemenuhider || empty($leftmenu) || $leftmenu=="prospects") $newmenu->add("/societe/list.php?type=p&amp;sortfield=s.datec&amp;sortorder=desc&amp;begin=&amp;search_stcomm=2", $langs->trans("LastProspectContactInProcess"), 2, $user->rights->societe->lire);
if ($usemenuhider || empty($leftmenu) || $leftmenu=="prospects") $newmenu->add("/societe/list.php?type=p&amp;sortfield=s.datec&amp;sortorder=desc&amp;begin=&amp;search_stcomm=3", $langs->trans("LastProspectContactDone"), 2, $user->rights->societe->lire);
*/
$newmenu->add("/societe/card.php?leftmenu=prospects&amp;action=create&amp;type=p", $langs->trans("MenuNewProspect"), 3, $user->rights->societe->creer);
}
@ -1270,11 +1270,11 @@ function get_left_menu_thridparties($mainmenu, &$newmenu, $usemenuhider = 1, $le
/**
* Get left Menu COMMERCIAL (propal, commande, supplier_proposal, supplier_order, contrat, ficheinter)
*
* @param string $mainmenu
* @param Menu &$newmenu Object Menu to return back list of menu entries
* @param string $usemenuhider
* @param string $leftmenu
* @param int $type_user
* @param string $mainmenu Main menu
* @param Menu $newmenu Object Menu to return back list of menu entries
* @param string $usemenuhider Use menu hider
* @param string $leftmenu Left menu
* @param int $type_user Type of targeted user for menu
* @return void
*/
function get_left_menu_commercial($mainmenu, &$newmenu, $usemenuhider = 1, $leftmenu = 'none', $type_user = 0)
@ -1386,11 +1386,11 @@ function get_left_menu_commercial($mainmenu, &$newmenu, $usemenuhider = 1, $left
/**
* Get left COMPTA-FINANCIAL
*
* @param string $mainmenu
* @param Menu &$newmenu Object Menu to return back list of menu entries
* @param string $usemenuhider
* @param string $leftmenu
* @param int $type_user
* @param string $mainmenu Main menu
* @param Menu $newmenu Object Menu to return back list of menu entries
* @param string $usemenuhider Use menu hider
* @param string $leftmenu Left menu
* @param int $type_user Type of targeted user for menu
* @return void
*/
function get_left_menu_billing($mainmenu, &$newmenu, $usemenuhider = 1, $leftmenu = 'none', $type_user = 0)
@ -1567,17 +1567,17 @@ function get_left_menu_billing($mainmenu, &$newmenu, $usemenuhider = 1, $leftmen
/**
* Get left COMPTA-FINANCIAL (accountancy)
*
* @param string $mainmenu
* @param Menu &$newmenu Object Menu to return back list of menu entries
* @param string $usemenuhider
* @param string $leftmenu
* @param int $type_user
* @param DB $db
* @param string $mainmenu Main menu
* @param Menu $newmenu Object Menu to return back list of menu entries
* @param string $usemenuhider Use menu hider
* @param string $leftmenu Left menu
* @param int $type_user Type of targeted user for menu
* @return void
*/
function get_left_menu_accountancy($mainmenu, &$newmenu, $usemenuhider = 1, $leftmenu = 'none', $type_user = 0, $db)
function get_left_menu_accountancy($mainmenu, &$newmenu, $usemenuhider = 1, $leftmenu = 'none', $type_user = 0)
{
global $user, $conf, $langs;
global $db;
if ($mainmenu == 'accountancy') {
$langs->load("companies");
@ -1679,7 +1679,7 @@ function get_left_menu_accountancy($mainmenu, &$newmenu, $usemenuhider = 1, $lef
if ($objp->nature == 3
&& ((!empty($conf->fournisseur->enabled) && empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD)) || !empty($conf->supplier_invoice->enabled))
&& empty($conf->global->ACCOUNTING_DISABLE_BINDING_ON_PURCHASES)) {
$nature = "purchases";
$nature = "purchases";
}
if ($objp->nature == 4 && !empty($conf->banque->enabled)) {
$nature = "bank";
@ -1697,7 +1697,7 @@ function get_left_menu_accountancy($mainmenu, &$newmenu, $usemenuhider = 1, $lef
$nature = "hasnew";
}
// To enable when page exists
// To enable when page exists
if (empty($conf->global->ACCOUNTANCY_SHOW_DEVELOP_JOURNAL)) {
if ($nature == 'hasnew' || $nature == 'inventory') {
$nature = '';
@ -1709,7 +1709,7 @@ function get_left_menu_accountancy($mainmenu, &$newmenu, $usemenuhider = 1, $lef
$journallabel = $langs->transnoentities($objp->label); // Labels in this table are set by loading llx_accounting_abc.sql. Label can be 'ACCOUNTING_SELL_JOURNAL', 'InventoryJournal', ...
$newmenu->add('/accountancy/journal/'.$nature.'journal.php?mainmenu=accountancy&leftmenu=accountancy_journal&id_journal='.$objp->rowid, $journallabel, 2, $user->rights->accounting->comptarapport->lire);
}
$i++;
$i++;
}
} else {
// Should not happend. Entries are added
@ -1815,17 +1815,17 @@ function get_left_menu_accountancy($mainmenu, &$newmenu, $usemenuhider = 1, $lef
$newmenu->add("/compta/resultat/index.php?leftmenu=report", $langs->trans("MenuReportInOut"), 1, $user->rights->compta->resultat->lire);
$newmenu->add("/compta/resultat/clientfourn.php?leftmenu=report", $langs->trans("ByCompanies"), 2, $user->rights->compta->resultat->lire);
/* On verra ca avec module compabilite expert
$newmenu->add("/compta/resultat/compteres.php?leftmenu=report","Compte de resultat",2,$user->rights->compta->resultat->lire);
$newmenu->add("/compta/resultat/bilan.php?leftmenu=report","Bilan",2,$user->rights->compta->resultat->lire);
*/
$newmenu->add("/compta/resultat/compteres.php?leftmenu=report","Compte de resultat",2,$user->rights->compta->resultat->lire);
$newmenu->add("/compta/resultat/bilan.php?leftmenu=report","Bilan",2,$user->rights->compta->resultat->lire);
*/
/*
$newmenu->add("/compta/stats/cumul.php?leftmenu=report","Cumule",2,$user->rights->compta->resultat->lire);
if (! empty($conf->propal->enabled)) {
$newmenu->add("/compta/stats/prev.php?leftmenu=report","Previsionnel",2,$user->rights->compta->resultat->lire);
$newmenu->add("/compta/stats/comp.php?leftmenu=report","Transforme",2,$user->rights->compta->resultat->lire);
}
*/
$newmenu->add("/compta/stats/cumul.php?leftmenu=report","Cumule",2,$user->rights->compta->resultat->lire);
if (! empty($conf->propal->enabled)) {
$newmenu->add("/compta/stats/prev.php?leftmenu=report","Previsionnel",2,$user->rights->compta->resultat->lire);
$newmenu->add("/compta/stats/comp.php?leftmenu=report","Transforme",2,$user->rights->compta->resultat->lire);
}
*/
$modecompta = 'CREANCES-DETTES';
$newmenu->add("/compta/stats/index.php?leftmenu=report&modecompta=".$modecompta, $langs->trans("ReportTurnover"), 1, $user->rights->compta->resultat->lire);
@ -1846,11 +1846,11 @@ function get_left_menu_accountancy($mainmenu, &$newmenu, $usemenuhider = 1, $lef
$newmenu->add("/compta/stats/supplier_turnover_by_prodserv.php?leftmenu=accountancy_report&modecompta=".$modecompta, $langs->trans("ByProductsAndServices"), 2, $user->rights->compta->resultat->lire);
/*
$modecompta = 'RECETTES-DEPENSES';
$newmenu->add("/compta/stats/index.php?leftmenu=accountancy_report&modecompta=".$modecompta, $langs->trans("ReportPurchaseTurnoverCollected"), 1, $user->rights->compta->resultat->lire);
$newmenu->add("/compta/stats/casoc.php?leftmenu=accountancy_report&modecompta=".$modecompta, $langs->trans("ByCompanies"), 2, $user->rights->compta->resultat->lire);
$newmenu->add("/compta/stats/cabyuser.php?leftmenu=accountancy_report&modecompta=".$modecompta, $langs->trans("ByUsers"), 2, $user->rights->compta->resultat->lire);
*/
$modecompta = 'RECETTES-DEPENSES';
$newmenu->add("/compta/stats/index.php?leftmenu=accountancy_report&modecompta=".$modecompta, $langs->trans("ReportPurchaseTurnoverCollected"), 1, $user->rights->compta->resultat->lire);
$newmenu->add("/compta/stats/casoc.php?leftmenu=accountancy_report&modecompta=".$modecompta, $langs->trans("ByCompanies"), 2, $user->rights->compta->resultat->lire);
$newmenu->add("/compta/stats/cabyuser.php?leftmenu=accountancy_report&modecompta=".$modecompta, $langs->trans("ByUsers"), 2, $user->rights->compta->resultat->lire);
*/
// Journals
$newmenu->add("/compta/journal/sellsjournal.php?leftmenu=report", $langs->trans("SellsJournal"), 1, $user->rights->compta->resultat->lire, '', '', '', 50);
@ -1886,11 +1886,11 @@ function get_left_menu_accountancy($mainmenu, &$newmenu, $usemenuhider = 1, $lef
/**
* Get left Menu BANK
*
* @param string $mainmenu
* @param Menu &$newmenu Object Menu to return back list of menu entries
* @param string $usemenuhider
* @param string $leftmenu
* @param int $type_user
* @param string $mainmenu Main menu
* @param Menu $newmenu Object Menu to return back list of menu entries
* @param string $usemenuhider Use menu hider
* @param string $leftmenu Left menu
* @param int $type_user Type of targeted user for menu
* @return void
*/
function get_left_menu_bank($mainmenu, &$newmenu, $usemenuhider = 1, $leftmenu = 'none', $type_user = 0)
@ -1969,11 +1969,11 @@ function get_left_menu_bank($mainmenu, &$newmenu, $usemenuhider = 1, $leftmenu =
/**
* Get left Menu PRODUCTS-SERVICES
*
* @param string $mainmenu
* @param Menu &$newmenu Object Menu to return back list of menu entries
* @param string $usemenuhider
* @param string $leftmenu
* @param int $type_user
* @param string $mainmenu Main menu
* @param Menu $newmenu Object Menu to return back list of menu entries
* @param string $usemenuhider Use menu hider
* @param string $leftmenu Left menu
* @param int $type_user Type of targeted user for menu
* @return void
*/
function get_left_menu_products($mainmenu, &$newmenu, $usemenuhider = 1, $leftmenu = 'none', $type_user = 0)
@ -2100,17 +2100,17 @@ function get_left_menu_products($mainmenu, &$newmenu, $usemenuhider = 1, $leftme
/**
* Get left Menu PRODUCTS-SERVICES MRP - GPAO
*
* @param string $mainmenu
* @param Menu &$newmenu Object Menu to return back list of menu entries
* @param string $usemenuhider
* @param string $leftmenu
* @param int $type_user
* @param string $mainmenu Main menu
* @param Menu $newmenu Object Menu to return back list of menu entries
* @param string $usemenuhider Use menu hider
* @param string $leftmenu Left menu
* @param int $type_user Type of targeted user for menu
* @return void
*/
function get_left_menu_mrp($mainmenu, &$newmenu, $usemenuhider = 1, $leftmenu = 'none', $type_user = 0)
{
global $user, $conf, $langs;
if ($mainmenu == 'mrp') {
// BOM
if (!empty($conf->bom->enabled) || !empty($conf->mrp->enabled)) {
@ -2134,17 +2134,17 @@ function get_left_menu_mrp($mainmenu, &$newmenu, $usemenuhider = 1, $leftmenu =
/**
* Get left Menu PROJECTS
*
* @param string $mainmenu
* @param Menu &$newmenu Object Menu to return back list of menu entries
* @param string $usemenuhider
* @param string $leftmenu
* @param int $type_user
* @param string $mainmenu Main menu
* @param Menu $newmenu Object Menu to return back list of menu entries
* @param string $usemenuhider Use menu hider
* @param string $leftmenu Left menu
* @param int $type_user Type of targeted user for menu
* @return void
*/
function get_left_menu_projects($mainmenu, &$newmenu, $usemenuhider = 1, $leftmenu = 'none', $type_user = 0)
{
global $user, $conf, $langs;
if ($mainmenu == 'project') {
if (!empty($conf->projet->enabled)) {
$langs->load("projects");
@ -2208,11 +2208,11 @@ function get_left_menu_projects($mainmenu, &$newmenu, $usemenuhider = 1, $leftme
/**
* Get left Menu HRM
*
* @param string $mainmenu
* @param Menu &$newmenu Object Menu to return back list of menu entries
* @param string $usemenuhider
* @param string $leftmenu
* @param int $type_user
* @param string $mainmenu Main menu
* @param Menu $newmenu Object Menu to return back list of menu entries
* @param string $usemenuhider Use menu hider
* @param string $leftmenu Left menu
* @param int $type_user Type of targeted user for menu
* @return void
*/
function get_left_menu_hrm($mainmenu, &$newmenu, $usemenuhider = 1, $leftmenu = 'none', $type_user = 0)
@ -2315,17 +2315,17 @@ function get_left_menu_hrm($mainmenu, &$newmenu, $usemenuhider = 1, $leftmenu =
/**
* Get left Menu TOOLS
*
* @param string $mainmenu
* @param Menu &$newmenu Object Menu to return back list of menu entries
* @param string $usemenuhider
* @param string $leftmenu
* @param int $type_user
* @param string $mainmenu Main menu
* @param Menu $newmenu Object Menu to return back list of menu entries
* @param string $usemenuhider Use menu hider
* @param string $leftmenu Left menu
* @param int $type_user Type of targeted user for menu
* @return void
*/
function get_left_menu_tools($mainmenu, &$newmenu, $usemenuhider = 1, $leftmenu = 'none', $type_user = 0)
{
global $user, $conf, $langs;
if ($mainmenu == 'tools') {
if (empty($user->socid)) { // limit to internal users
$langs->load("mails");
@ -2356,11 +2356,11 @@ function get_left_menu_tools($mainmenu, &$newmenu, $usemenuhider = 1, $leftmenu
/**
* Get left Menu MEMBERS
*
* @param string $mainmenu
* @param Menu &$newmenu Object Menu to return back list of menu entries
* @param string $usemenuhider
* @param string $leftmenu
* @param int $type_user
* @param string $mainmenu Main menu
* @param Menu $newmenu Object Menu to return back list of menu entries
* @param string $usemenuhider Use menu hider
* @param string $leftmenu Left menu
* @param int $type_user Type of targeted user for menu
* @return void
*/
function get_left_menu_members($mainmenu, &$newmenu, $usemenuhider = 1, $leftmenu = 'none', $type_user = 0)

View File

@ -897,7 +897,7 @@ class pdf_crabe extends ModelePDFFactures
$tab3_width = 80;
$tab3_height = 4;
if ($this->page_largeur < 210) { // To work with US executive format
$tab3_posx -= 20;
$tab3_posx -= 15;
}
$default_font_size = pdf_getPDFFontSize($outputlangs);
@ -1289,7 +1289,8 @@ class pdf_crabe extends ModelePDFFactures
$col1x = 120;
$col2x = 170;
if ($this->page_largeur < 210) { // To work with US executive format
$col2x -= 20;
$col1x -= 15;
$col2x -= 10;
}
$largcol2 = ($this->page_largeur - $this->marge_droite - $col2x);

View File

@ -540,7 +540,7 @@ class pdf_sponge extends ModelePDFFactures
$pdf->useTemplate($tplidx);
}
if (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)) {
$this->_pagehead($pdf, $object, 0, $outputlangs);
$this->_pagehead($pdf, $object, 0, $outputlangs, $outputlangsbis);
}
// $this->_pagefoot($pdf,$object,$outputlangs,1);
$pdf->setTopMargin($tab_top_newpage);
@ -598,7 +598,7 @@ class pdf_sponge extends ModelePDFFactures
$pdf->useTemplate($tplidx);
}
if (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)) {
$this->_pagehead($pdf, $object, 0, $outputlangs);
$this->_pagehead($pdf, $object, 0, $outputlangs, $outputlangsbis);
}
$height_note = $posyafter - $tab_top_newpage;
$pdf->Rect($this->marge_gauche, $tab_top_newpage - 1, $tab_width, $height_note + 1);
@ -620,7 +620,7 @@ class pdf_sponge extends ModelePDFFactures
$pdf->useTemplate($tplidx);
}
if (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)) {
$this->_pagehead($pdf, $object, 0, $outputlangs);
$this->_pagehead($pdf, $object, 0, $outputlangs, $outputlangsbis);
}
$posyafter = $tab_top_newpage;
@ -870,9 +870,9 @@ class pdf_sponge extends ModelePDFFactures
// Retrieve type from database for backward compatibility with old records
if ((!isset($localtax1_type) || $localtax1_type == '' || !isset($localtax2_type) || $localtax2_type == '') // if tax type not defined
&& (!empty($localtax1_rate) || !empty($localtax2_rate))) { // and there is local tax
$localtaxtmp_array = getLocalTaxesFromRate($vatrate, 0, $object->thirdparty, $mysoc);
$localtax1_type = isset($localtaxtmp_array[0]) ? $localtaxtmp_array[0] : '';
$localtax2_type = isset($localtaxtmp_array[2]) ? $localtaxtmp_array[2] : '';
$localtaxtmp_array = getLocalTaxesFromRate($vatrate, 0, $object->thirdparty, $mysoc);
$localtax1_type = isset($localtaxtmp_array[0]) ? $localtaxtmp_array[0] : '';
$localtax2_type = isset($localtaxtmp_array[2]) ? $localtaxtmp_array[2] : '';
}
// retrieve global local tax
@ -922,7 +922,7 @@ class pdf_sponge extends ModelePDFFactures
$pdf->setPage($pagenb);
$pdf->setPageOrientation('', 1, 0); // The only function to edit the bottom margin of current page to set it.
if (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)) {
$this->_pagehead($pdf, $object, 0, $outputlangs);
$this->_pagehead($pdf, $object, 0, $outputlangs, $outputlangsbis);
}
}
@ -940,7 +940,7 @@ class pdf_sponge extends ModelePDFFactures
}
$pagenb++;
if (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)) {
$this->_pagehead($pdf, $object, 0, $outputlangs);
$this->_pagehead($pdf, $object, 0, $outputlangs, $outputlangsbis);
}
}
}
@ -989,9 +989,9 @@ class pdf_sponge extends ModelePDFFactures
@chmod($file, octdec($conf->global->MAIN_UMASK));
}
$this->result = array('fullpath'=>$file);
$this->result = array('fullpath'=>$file);
return 1; // No error
return 1; // No error
} else {
$this->error = $langs->transnoentities("ErrorCanNotCreateDir", $dir);
return 0;
@ -1026,7 +1026,7 @@ class pdf_sponge extends ModelePDFFactures
$tab3_width = 80;
$tab3_height = 4;
if ($this->page_largeur < 210) { // To work with US executive format
$tab3_posx -= 20;
$tab3_posx -= 15;
}
$default_font_size = pdf_getPDFFontSize($outputlangs);
@ -1177,20 +1177,24 @@ class pdf_sponge extends ModelePDFFactures
$posy = $pdf->GetY() + 4;
}
$posxval = 52;
$posxval = 52; // Position of values of properties shown on left side
$posxend = 110; // End of x for text on left side
if ($this->page_largeur < 210) { // To work with US executive format
$posxend -= 10;
}
// Show payments conditions
if ($object->type != 2 && ($object->cond_reglement_code || $object->cond_reglement)) {
$pdf->SetFont('', 'B', $default_font_size - 2);
$pdf->SetXY($this->marge_gauche, $posy);
$titre = $outputlangs->transnoentities("PaymentConditions").':';
$pdf->MultiCell(43, 4, $titre, 0, 'L');
$pdf->MultiCell($posxval - $this->marge_gauche, 4, $titre, 0, 'L');
$pdf->SetFont('', '', $default_font_size - 2);
$pdf->SetXY($posxval, $posy);
$lib_condition_paiement = $outputlangs->transnoentities("PaymentCondition".$object->cond_reglement_code) != ('PaymentCondition'.$object->cond_reglement_code) ? $outputlangs->transnoentities("PaymentCondition".$object->cond_reglement_code) : $outputlangs->convToOutputCharset($object->cond_reglement_doc ? $object->cond_reglement_doc : $object->cond_reglement_label);
$lib_condition_paiement = str_replace('\n', "\n", $lib_condition_paiement);
$pdf->MultiCell(67, 4, $lib_condition_paiement, 0, 'L');
$pdf->MultiCell($posxend - $posxval, 4, $lib_condition_paiement, 0, 'L');
$posy = $pdf->GetY() + 3; // We need spaces for 2 lines payment conditions
}
@ -1198,42 +1202,42 @@ class pdf_sponge extends ModelePDFFactures
if ($object->type != 2) {
// Check a payment mode is defined
if (empty($object->mode_reglement_code)
&& empty($conf->global->FACTURE_CHQ_NUMBER)
&& empty($conf->global->FACTURE_RIB_NUMBER)) {
$this->error = $outputlangs->transnoentities("ErrorNoPaiementModeConfigured");
&& empty($conf->global->FACTURE_CHQ_NUMBER)
&& empty($conf->global->FACTURE_RIB_NUMBER)) {
$this->error = $outputlangs->transnoentities("ErrorNoPaiementModeConfigured");
} elseif (($object->mode_reglement_code == 'CHQ' && empty($conf->global->FACTURE_CHQ_NUMBER) && empty($object->fk_account) && empty($object->fk_bank))
|| ($object->mode_reglement_code == 'VIR' && empty($conf->global->FACTURE_RIB_NUMBER) && empty($object->fk_account) && empty($object->fk_bank))) {
// Avoid having any valid PDF with setup that is not complete
$outputlangs->load("errors");
|| ($object->mode_reglement_code == 'VIR' && empty($conf->global->FACTURE_RIB_NUMBER) && empty($object->fk_account) && empty($object->fk_bank))) {
// Avoid having any valid PDF with setup that is not complete
$outputlangs->load("errors");
$pdf->SetXY($this->marge_gauche, $posy);
$pdf->SetTextColor(200, 0, 0);
$pdf->SetFont('', 'B', $default_font_size - 2);
$this->error = $outputlangs->transnoentities("ErrorPaymentModeDefinedToWithoutSetup", $object->mode_reglement_code);
$pdf->MultiCell(80, 3, $this->error, 0, 'L', 0);
$pdf->SetTextColor(0, 0, 0);
$pdf->SetXY($this->marge_gauche, $posy);
$pdf->SetTextColor(200, 0, 0);
$pdf->SetFont('', 'B', $default_font_size - 2);
$this->error = $outputlangs->transnoentities("ErrorPaymentModeDefinedToWithoutSetup", $object->mode_reglement_code);
$pdf->MultiCell($posxend - $this->marge_gauche, 3, $this->error, 0, 'L', 0);
$pdf->SetTextColor(0, 0, 0);
$posy = $pdf->GetY() + 1;
$posy = $pdf->GetY() + 1;
}
// Show payment mode
// Show payment mode
if (!empty($object->mode_reglement_code)
&& $object->mode_reglement_code != 'CHQ'
&& $object->mode_reglement_code != 'VIR') {
$pdf->SetFont('', 'B', $default_font_size - 2);
$pdf->SetXY($this->marge_gauche, $posy);
$titre = $outputlangs->transnoentities("PaymentMode").':';
$pdf->MultiCell(80, 5, $titre, 0, 'L');
&& $object->mode_reglement_code != 'CHQ'
&& $object->mode_reglement_code != 'VIR') {
$pdf->SetFont('', 'B', $default_font_size - 2);
$pdf->SetXY($this->marge_gauche, $posy);
$titre = $outputlangs->transnoentities("PaymentMode").':';
$pdf->MultiCell($posxend - $this->marge_gauche, 5, $titre, 0, 'L');
$pdf->SetFont('', '', $default_font_size - 2);
$pdf->SetXY($posxval, $posy);
$lib_mode_reg = $outputlangs->transnoentities("PaymentType".$object->mode_reglement_code) != ('PaymentType'.$object->mode_reglement_code) ? $outputlangs->transnoentities("PaymentType".$object->mode_reglement_code) : $outputlangs->convToOutputCharset($object->mode_reglement);
$pdf->MultiCell(80, 5, $lib_mode_reg, 0, 'L');
$pdf->SetFont('', '', $default_font_size - 2);
$pdf->SetXY($posxval, $posy);
$lib_mode_reg = $outputlangs->transnoentities("PaymentType".$object->mode_reglement_code) != ('PaymentType'.$object->mode_reglement_code) ? $outputlangs->transnoentities("PaymentType".$object->mode_reglement_code) : $outputlangs->convToOutputCharset($object->mode_reglement);
$pdf->MultiCell($posxend - $posxval, 5, $lib_mode_reg, 0, 'L');
$posy = $pdf->GetY();
$posy = $pdf->GetY();
}
// Show online payment link
// Show online payment link
if (empty($object->mode_reglement_code) || $object->mode_reglement_code == 'CB' || $object->mode_reglement_code == 'VAD') {
$useonlinepayment = 0;
if (!empty($conf->global->PDF_SHOW_LINK_TO_ONLINE_PAYMENT)) {
@ -1258,13 +1262,13 @@ class pdf_sponge extends ModelePDFFactures
$linktopay = $langs->trans("ToOfferALinkForOnlinePayment", $servicename).' <a href="'.$paiement_url.'">'.$outputlangs->transnoentities("ClickHere").'</a>';
$pdf->SetXY($this->marge_gauche, $posy);
$pdf->writeHTMLCell(80, 5, '', '', dol_htmlentitiesbr($linktopay), 0, 1);
$pdf->writeHTMLCell($posxend - $this->marge_gauche, 5, '', '', dol_htmlentitiesbr($linktopay), 0, 1);
$posy = $pdf->GetY() + 1;
}
}
// Show payment mode CHQ
// Show payment mode CHQ
if (empty($object->mode_reglement_code) || $object->mode_reglement_code == 'CHQ') {
// If payment mode unregulated or payment mode forced to CHQ
if (!empty($conf->global->FACTURE_CHQ_NUMBER)) {
@ -1276,33 +1280,33 @@ class pdf_sponge extends ModelePDFFactures
$pdf->SetXY($this->marge_gauche, $posy);
$pdf->SetFont('', 'B', $default_font_size - $diffsizetitle);
$pdf->MultiCell(100, 3, $outputlangs->transnoentities('PaymentByChequeOrderedTo', $account->proprio), 0, 'L', 0);
$pdf->MultiCell($posxend - $this->marge_gauche, 3, $outputlangs->transnoentities('PaymentByChequeOrderedTo', $account->proprio), 0, 'L', 0);
$posy = $pdf->GetY() + 1;
if (empty($conf->global->MAIN_PDF_HIDE_CHQ_ADDRESS)) {
$pdf->SetXY($this->marge_gauche, $posy);
$pdf->SetFont('', '', $default_font_size - $diffsizetitle);
$pdf->MultiCell(100, 3, $outputlangs->convToOutputCharset($account->owner_address), 0, 'L', 0);
$pdf->MultiCell($posxend - $this->marge_gauche, 3, $outputlangs->convToOutputCharset($account->owner_address), 0, 'L', 0);
$posy = $pdf->GetY() + 2;
}
}
if ($conf->global->FACTURE_CHQ_NUMBER == -1) {
$pdf->SetXY($this->marge_gauche, $posy);
$pdf->SetFont('', 'B', $default_font_size - $diffsizetitle);
$pdf->MultiCell(100, 3, $outputlangs->transnoentities('PaymentByChequeOrderedTo', $this->emetteur->name), 0, 'L', 0);
$pdf->MultiCell($posxend - $this->marge_gauche, 3, $outputlangs->transnoentities('PaymentByChequeOrderedTo', $this->emetteur->name), 0, 'L', 0);
$posy = $pdf->GetY() + 1;
if (empty($conf->global->MAIN_PDF_HIDE_CHQ_ADDRESS)) {
$pdf->SetXY($this->marge_gauche, $posy);
$pdf->SetFont('', '', $default_font_size - $diffsizetitle);
$pdf->MultiCell(100, 3, $outputlangs->convToOutputCharset($this->emetteur->getFullAddress()), 0, 'L', 0);
$pdf->MultiCell($posxend - $this->marge_gauche, 3, $outputlangs->convToOutputCharset($this->emetteur->getFullAddress()), 0, 'L', 0);
$posy = $pdf->GetY() + 2;
}
}
}
}
// If payment mode not forced or forced to VIR, show payment with BAN
// If payment mode not forced or forced to VIR, show payment with BAN
if (empty($object->mode_reglement_code) || $object->mode_reglement_code == 'VIR') {
if ($object->fk_account > 0 || $object->fk_bank > 0 || !empty($conf->global->FACTURE_RIB_NUMBER)) {
$bankid = ($object->fk_account <= 0 ? $conf->global->FACTURE_RIB_NUMBER : $object->fk_account);
@ -1350,13 +1354,18 @@ class pdf_sponge extends ModelePDFFactures
$tab2_top = $posy;
$tab2_hl = 4;
$pdf->SetFont('', '', $default_font_size - 1);
if (is_object($outputlangsbis)) { // When we show 2 languages we need more room for text, so we use a smaller font.
$pdf->SetFont('', '', $default_font_size - 2);
} else {
$pdf->SetFont('', '', $default_font_size - 1);
}
// Total table
$col1x = 120;
$col2x = 170;
if ($this->page_largeur < 210) { // To work with US executive format
$col2x -= 20;
$col1x -= 15;
$col2x -= 10;
}
$largcol2 = ($this->page_largeur - $this->marge_droite - $col2x);
@ -1481,9 +1490,10 @@ class pdf_sponge extends ModelePDFFactures
$tab2_top = $posy;
$index = 0;
$tab2_top += 3;
}
$tab2_top += 3;
// Get Total HT
$total_ht = (!empty($conf->multicurrency->enabled) && $object->mylticurrency_tx != 1 ? $object->multicurrency_total_ht : $object->total_ht);
@ -1804,19 +1814,19 @@ class pdf_sponge extends ModelePDFFactures
}
/*
if ($object->close_code == Facture::CLOSECODE_DISCOUNTVAT)
{
$index++;
$pdf->SetFillColor(255, 255, 255);
if ($object->close_code == Facture::CLOSECODE_DISCOUNTVAT)
{
$index++;
$pdf->SetFillColor(255, 255, 255);
$pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
$pdf->MultiCell($col2x - $col1x, $tab2_hl, $outputlangs->transnoentities("EscompteOfferedShort").(is_object($outputlangsbis) ? ' / '.$outputlangsbis->transnoentities("EscompteOfferedShort") : ''), $useborder, 'L', 1);
$pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
$pdf->MultiCell($largcol2, $tab2_hl, price($object->total_ttc - $deja_regle - $creditnoteamount - $depositsamount, 0, $outputlangs), $useborder, 'R', 1);
$pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
$pdf->MultiCell($col2x - $col1x, $tab2_hl, $outputlangs->transnoentities("EscompteOfferedShort").(is_object($outputlangsbis) ? ' / '.$outputlangsbis->transnoentities("EscompteOfferedShort") : ''), $useborder, 'L', 1);
$pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
$pdf->MultiCell($largcol2, $tab2_hl, price($object->total_ttc - $deja_regle - $creditnoteamount - $depositsamount, 0, $outputlangs), $useborder, 'R', 1);
$resteapayer = 0;
}
*/
$resteapayer = 0;
}
*/
$index++;
$pdf->SetTextColor(0, 0, 60);
@ -1936,7 +1946,7 @@ class pdf_sponge extends ModelePDFFactures
// Show Draft Watermark
if ($object->statut == $object::STATUS_DRAFT && (!empty($conf->global->FACTURE_DRAFT_WATERMARK))) {
pdf_watermark($pdf, $outputlangs, $this->page_hauteur, $this->page_largeur, 'mm', $conf->global->FACTURE_DRAFT_WATERMARK);
pdf_watermark($pdf, $outputlangs, $this->page_hauteur, $this->page_largeur, 'mm', $conf->global->FACTURE_DRAFT_WATERMARK);
}
$pdf->SetTextColor(0, 0, 60);
@ -2023,15 +2033,15 @@ class pdf_sponge extends ModelePDFFactures
$pdf->SetFont('', 'B', $default_font_size);
/*
$posy += 5;
$pdf->SetXY($posx, $posy);
$pdf->SetTextColor(0, 0, 60);
$textref = $outputlangs->transnoentities("Ref")." : ".$outputlangs->convToOutputCharset($object->ref);
if ($object->statut == $object::STATUS_DRAFT) {
$pdf->SetTextColor(128, 0, 0);
$textref .= ' - '.$outputlangs->transnoentities("NotValidated");
}
$pdf->MultiCell($w, 4, $textref, '', 'R');*/
$posy += 5;
$pdf->SetXY($posx, $posy);
$pdf->SetTextColor(0, 0, 60);
$textref = $outputlangs->transnoentities("Ref")." : ".$outputlangs->convToOutputCharset($object->ref);
if ($object->statut == $object::STATUS_DRAFT) {
$pdf->SetTextColor(128, 0, 0);
$textref .= ' - '.$outputlangs->transnoentities("NotValidated");
}
$pdf->MultiCell($w, 4, $textref, '', 'R');*/
$posy += 3;
$pdf->SetFont('', '', $default_font_size - 2);
@ -2295,21 +2305,21 @@ class pdf_sponge extends ModelePDFFactures
/*
* For exemple
$this->cols['theColKey'] = array(
'rank' => $rank, // int : use for ordering columns
'width' => 20, // the column width in mm
'title' => array(
'textkey' => 'yourLangKey', // if there is no label, yourLangKey will be translated to replace label
'label' => ' ', // the final label : used fore final generated text
'align' => 'L', // text alignement : R,C,L
'padding' => array(0.5,0.5,0.5,0.5), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left
),
'content' => array(
'align' => 'L', // text alignement : R,C,L
'padding' => array(0.5,0.5,0.5,0.5), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left
),
);
*/
$this->cols['theColKey'] = array(
'rank' => $rank, // int : use for ordering columns
'width' => 20, // the column width in mm
'title' => array(
'textkey' => 'yourLangKey', // if there is no label, yourLangKey will be translated to replace label
'label' => ' ', // the final label : used fore final generated text
'align' => 'L', // text alignement : R,C,L
'padding' => array(0.5,0.5,0.5,0.5), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left
),
'content' => array(
'align' => 'L', // text alignement : R,C,L
'padding' => array(0.5,0.5,0.5,0.5), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left
),
);
*/
$rank = 0; // do not use negative rank
$this->cols['desc'] = array(

View File

@ -293,7 +293,7 @@ class Donations extends DolibarrApi
* @throws RestException 304
* @throws RestException 401
* @throws RestException 404
* @throws RestException 500
* @throws RestException 500 System error
*
* @return array
*/

View File

@ -401,7 +401,7 @@ class ExpenseReports extends DolibarrApi
*
* @throws RestException 401 Not allowed
* @throws RestException 404 Expense report not found
* @throws RestException 500
* @throws RestException 500 System error
*/
public function put($id, $request_data = null)
{

View File

@ -211,7 +211,7 @@ class SupplierInvoices extends DolibarrApi
* @return int ID of supplier invoice
*
* @throws RestException 401
* @throws RestException 500
* @throws RestException 500 System error
*/
public function post($request_data = null)
{
@ -283,7 +283,7 @@ class SupplierInvoices extends DolibarrApi
*
* @throws RestException 401
* @throws RestException 404
* @throws RestException 500
* @throws RestException 500 System error
*/
public function delete($id)
{
@ -300,7 +300,7 @@ class SupplierInvoices extends DolibarrApi
}
if ($this->invoice->delete(DolibarrApiAccess::$user) < 0) {
throw new RestException(500);
throw new RestException(500, 'Error when deleting invoice');
}
return array(
@ -326,7 +326,7 @@ class SupplierInvoices extends DolibarrApi
* @throws RestException 401
* @throws RestException 404
* @throws RestException 405
* @throws RestException 500
* @throws RestException 500 System error
*/
public function validate($id, $idwarehouse = 0, $notrigger = 0)
{

View File

@ -309,7 +309,7 @@ class SupplierOrders extends DolibarrApi
}
if ($this->order->delete(DolibarrApiAccess::$user) < 0) {
throw new RestException(500);
throw new RestException(500, 'Error when deleting order');
}
return array(

View File

@ -84,8 +84,8 @@ UPDATE llx_const set value = __ENCRYPT('eldy')__ WHERE __DECRYPT('value')__ = 'a
UPDATE llx_const set value = __ENCRYPT('eldy')__ WHERE __DECRYPT('value')__ = 'cameleo';
DELETE FROM llx_user_param where param = 'MAIN_THEME' and value in ('auguria', 'amarok', 'cameleo');
ALTER TABLE llx_product_fournisseur_price ADD COLUMN packaging varchar(64) DEFAULT NULL;
ALTER TABLE llx_product_fournisseur_price MODIFY COLUMN packaging varchar(64) DEFAULT NULL;
ALTER TABLE llx_product_fournisseur_price ADD COLUMN packaging real DEFAULT NULL;
ALTER TABLE llx_product_fournisseur_price MODIFY COLUMN packaging real DEFAULT NULL;
-- For v14

View File

@ -91,6 +91,10 @@ INSERT INTO llx_c_forme_juridique (fk_pays, code, libelle, active) VALUES (154,
INSERT INTO llx_c_forme_juridique (fk_pays, code, libelle, active) VALUES (154, '15419', '626 - Régimen Simplificado de Confianza', 1);
ALTER TABLE llx_partnership ADD UNIQUE INDEX uk_fk_type_fk_soc (fk_type, fk_soc, date_partnership_start);
ALTER TABLE llx_partnership ADD UNIQUE INDEX uk_fk_type_fk_member (fk_type, fk_member, date_partnership_start);
-- v16
ALTER TABLE llx_projet_task_time ADD COLUMN fk_product integer NULL;

View File

@ -19,3 +19,6 @@
ALTER TABLE llx_partnership ADD INDEX idx_partnership_entity (entity);
ALTER TABLE llx_partnership ADD UNIQUE INDEX uk_partnership_ref (ref, entity);
ALTER TABLE llx_partnership ADD UNIQUE INDEX uk_fk_type_fk_soc (fk_type, fk_soc, date_partnership_start);
ALTER TABLE llx_partnership ADD UNIQUE INDEX uk_fk_type_fk_member (fk_type, fk_member, date_partnership_start);

View File

@ -2225,3 +2225,5 @@ PreviousHash=Previous hash
LateWarningAfter="Late" warning after
TemplateforBusinessCards=Template for a business card in different size
InventorySetup= Inventory Setup
ExportUseLowMemoryMode=Use a low memory mode
ExportUseLowMemoryModeHelp=Use the low memory mode to execute the exec of the dump (compression is done through a pipe instead of into the PHP memory). This method does not allow to check that file is completed and error message can't be reported if it fails.

View File

@ -102,4 +102,6 @@ TypeContact_contrat_external_CUSTOMER=Follow-up customer contact
TypeContact_contrat_external_SALESREPSIGN=Signing contract customer contact
HideClosedServiceByDefault=Hide closed services by default
ShowClosedServices=Show Closed Services
HideClosedServices=Hide Closed Services
HideClosedServices=Hide Closed Services
UserStartingService=User starting service
UserClosingService=User closing service

View File

@ -16,6 +16,7 @@ Language_bg_BG=Bulgarian
Language_bs_BA=Bosnian
Language_ca_ES=Catalan
Language_cs_CZ=Czech
Language_cy_GB=Welsh
Language_da_DA=Danish
Language_da_DK=Danish
Language_de_DE=German

View File

@ -369,10 +369,14 @@ if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST)) {
/* The slow method does not consume memory on mysql (not tested on pgsql) */
/*$resql = $db->query($sql, 0, 'auto', 1);
while ($db->fetch_object($resql)) {
$nbtotalofrecords++;
}*/
if (empty($nbtotalofrecords)) {
$nbtotalofrecords = 1; // We can't make +1 because init value is ''
} else {
$nbtotalofrecords++;
}
}*/
/* The fast and low memory method to get and count full list converts the sql into a sql count */
$sqlforcount = preg_replace('/^SELECT[a-z0-9\._\s\(\),]+FROM/i', 'SELECT COUNT(*) as nbtotalofrecords FROM', $sql);
$sqlforcount = preg_replace('/^SELECT[a-zA-Z0-9\._\s\(\),=<>\:\-\']+\sFROM/', 'SELECT COUNT(*) as nbtotalofrecords FROM', $sql);
$resql = $db->query($sqlforcount);
$objforcount = $db->fetch_object($resql);
$nbtotalofrecords = $objforcount->nbtotalofrecords;

View File

@ -742,7 +742,7 @@ class Products extends DolibarrApi
* @param int $fk_barcode_type Barcode type
* @return int
*
* @throws RestException 500
* @throws RestException 500 System error
* @throws RestException 401
*
* @url POST {id}/purchase_prices
@ -1161,7 +1161,7 @@ class Products extends DolibarrApi
* @param string $ref_ext External reference of Attribute
* @return array
*
* @throws RestException 500
* @throws RestException 500 System error
* @throws RestException 401
*
* @url GET attributes/ref_ext/{ref_ext}
@ -1212,7 +1212,7 @@ class Products extends DolibarrApi
* @param string $ref_ext Reference of Attribute
* @return int
*
* @throws RestException 500
* @throws RestException 500 System error
* @throws RestException 401
*
* @url POST attributes
@ -1289,7 +1289,7 @@ class Products extends DolibarrApi
* @param int $id ID of Attribute
* @return int Result of deletion
*
* @throws RestException 500
* @throws RestException 500 System error
* @throws RestException 401
*
* @url DELETE attributes/{id}
@ -1317,7 +1317,7 @@ class Products extends DolibarrApi
* @param int $id ID of Attribute value
* @return array
*
* @throws RestException 500
* @throws RestException 500 System error
* @throws RestException 401
*
* @url GET attributes/values/{id}
@ -1358,7 +1358,7 @@ class Products extends DolibarrApi
* @param string $ref Ref of Attribute value
* @return array
*
* @throws RestException 500
* @throws RestException 500 System error
* @throws RestException 401
*
* @url GET attributes/{id}/values/ref/{ref}
@ -1445,7 +1445,7 @@ class Products extends DolibarrApi
* @return array
*
* @throws RestException 401
* @throws RestException 500
* @throws RestException 500 System error
*
* @url GET attributes/{id}/values
*/
@ -1517,7 +1517,7 @@ class Products extends DolibarrApi
* @param string $value Value of Attribute value
* @return int
*
* @throws RestException 500
* @throws RestException 500 System error
* @throws RestException 401
*
* @url POST attributes/{id}/values
@ -1551,7 +1551,7 @@ class Products extends DolibarrApi
* @return array
*
* @throws RestException 401
* @throws RestException 500
* @throws RestException 500 System error
*
* @url PUT attributes/values/{id}
*/
@ -1596,7 +1596,7 @@ class Products extends DolibarrApi
* @param int $id ID of Attribute value
* @return int
*
* @throws RestException 500
* @throws RestException 500 System error
* @throws RestException 401
*
* @url DELETE attributes/values/{id}
@ -1623,7 +1623,7 @@ class Products extends DolibarrApi
* @param int $includestock Default value 0. If parameter is set to 1 the response will contain stock data of each variant
* @return array
*
* @throws RestException 500
* @throws RestException 500 System error
* @throws RestException 401
*
* @url GET {id}/variants
@ -1659,7 +1659,7 @@ class Products extends DolibarrApi
* @param string $ref Ref of Product
* @return array
*
* @throws RestException 500
* @throws RestException 500 System error
* @throws RestException 401
*
* @url GET ref/{ref}/variants
@ -1701,7 +1701,7 @@ class Products extends DolibarrApi
* @param string $ref_ext External reference of variant
* @return int
*
* @throws RestException 500
* @throws RestException 500 System error
* @throws RestException 401
* @throws RestException 404
*
@ -1758,7 +1758,7 @@ class Products extends DolibarrApi
* @param array $features List of attributes pairs id_attribute->id_value. Example: array(id_color=>id_Blue, id_size=>id_small, id_option=>id_val_a, ...)
* @return int
*
* @throws RestException 500
* @throws RestException 500 System error
* @throws RestException 401
* @throws RestException 404
*
@ -1813,7 +1813,7 @@ class Products extends DolibarrApi
* @param array $request_data Datas
* @return int
*
* @throws RestException 500
* @throws RestException 500 System error
* @throws RestException 401
*
* @url PUT variants/{id}
@ -1847,7 +1847,7 @@ class Products extends DolibarrApi
* @param int $id ID of Variant
* @return int Result of deletion
*
* @throws RestException 500
* @throws RestException 500 System error
* @throws RestException 401
*
* @url DELETE variants/{id}
@ -1875,7 +1875,7 @@ class Products extends DolibarrApi
* @param int $selected_warehouse_id ID of warehouse
* @return int
*
* @throws RestException 500
* @throws RestException 500 System error
* @throws RestException 401
* @throws RestException 404
*

View File

@ -216,7 +216,7 @@ if (empty($reshook)) {
}
}
// Save quantity found during inventory
// Save quantity found during inventory (when we click on Save button on inventory page)
if ($action =='updateinventorylines' && $permissiontoadd) {
$sql = 'SELECT id.rowid, id.datec as date_creation, id.tms as date_modification, id.fk_inventory, id.fk_warehouse,';
$sql .= ' id.fk_product, id.batch, id.qty_stock, id.qty_view, id.qty_regulated';
@ -236,6 +236,9 @@ if (empty($reshook)) {
$line = $db->fetch_object($resql);
$lineid = $line->rowid;
$result = 0;
$resultupdate = 0;
if (GETPOST("id_".$lineid, 'alpha') != '') { // If a value was set ('0' or something else)
$qtytoupdate = price2num(GETPOST("id_".$lineid, 'alpha'), 'MS');
$result = $inventoryline->fetch($lineid);
@ -265,7 +268,7 @@ if (empty($reshook)) {
}
}
// Update line with id of stock movement (and the start quantity if it has changed this last recording)
// Update user that update quantities
if (! $error) {
$sqlupdate = "UPDATE ".MAIN_DB_PREFIX."inventory";
$sqlupdate .= " SET fk_user_modif = ".((int) $user->id);

View File

@ -1409,7 +1409,7 @@ class Thirdparties extends DolibarrApi
if ($result > 0) {
return array("success" => $result);
} else {
throw new RestException(500);
throw new RestException(500, 'Error generating the document '.$this->error);
}
}

View File

@ -377,7 +377,7 @@ class Tickets extends DolibarrApi
}
$this->ticket->message = $ticketMessageText;
if (!$this->ticket->createTicketMessage(DolibarrApiAccess::$user)) {
throw new RestException(500);
throw new RestException(500, 'Error when creating ticket');
}
return $this->ticket->id;
}
@ -438,7 +438,7 @@ class Tickets extends DolibarrApi
}
if (!$this->ticket->delete($id)) {
throw new RestException(500);
throw new RestException(500, 'Error when deleting ticket');
}
return array(

View File

@ -466,7 +466,7 @@ class Users extends DolibarrApi
*
* @throws RestException 401 Not allowed
* @throws RestException 404 User not found
* @throws RestException 500 Error
* @throws RestException 500 System error
*
* @url GET {id}/setGroup/{group}
*/

View File

@ -0,0 +1,203 @@
<?php
/* Copyright (C) 2010 Laurent Destailleur <eldy@users.sourceforge.net>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
* or see https://www.gnu.org/
*/
/**
* \file test/phpunit/BarcodeTest.php
* \ingroup test
* \brief PHPUnit test
* \remarks To run this script as CLI: phpunit filename.php
*/
global $conf,$user,$langs,$db;
//define('TEST_DB_FORCE_TYPE','mysql'); // This is to force using mysql driver
//require_once 'PHPUnit/Autoload.php';
require_once dirname(__FILE__).'/../../htdocs/master.inc.php';
require_once dirname(__FILE__).'/../../htdocs/compta/facture/class/facture.class.php';
if (empty($user->id)) {
print "Load permissions for admin user nb 1\n";
$user->fetch(1);
$user->getrights();
}
$conf->global->MAIN_DISABLE_ALL_MAILS=1;
$langs->load("main");
/**
* Class for PHPUnit tests
*
* @backupGlobals disabled
* @backupStaticAttributes enabled
* @remarks backupGlobals must be disabled to have db,conf,user and lang not erased.
*/
class BarcodeTest extends PHPUnit\Framework\TestCase
{
protected $savconf;
protected $savuser;
protected $savlangs;
protected $savdb;
/**
* Constructor
* We save global variables into local variables
*
* @return BarcodeTest
*/
public function __construct()
{
parent::__construct();
//$this->sharedFixture
global $conf,$user,$langs,$db;
$this->savconf=$conf;
$this->savuser=$user;
$this->savlangs=$langs;
$this->savdb=$db;
print __METHOD__." db->type=".$db->type." user->id=".$user->id;
//print " - db ".$db->db;
print "\n";
}
/**
* setUpBeforeClass
*
* @return void
*/
public static function setUpBeforeClass()
{
global $conf,$user,$langs,$db;
$db->begin(); // This is to have all actions inside a transaction even if test launched without suite.
print __METHOD__."\n";
}
/**
* tearDownAfterClass
*
* @return void
*/
public static function tearDownAfterClass()
{
global $conf,$user,$langs,$db;
$db->rollback();
print __METHOD__."\n";
}
/**
* Init phpunit tests
*
* @return void
*/
protected function setUp()
{
global $conf,$user,$langs,$db;
$conf=$this->savconf;
$user=$this->savuser;
$langs=$this->savlangs;
$db=$this->savdb;
print __METHOD__."\n";
}
/**
* End phpunit tests
*
* @return void
*/
protected function tearDown()
{
print __METHOD__."\n";
}
/**
* testBarcodeZATCAEncode
*
* @return int
*/
public function testBarcodeZATCAEncode()
{
global $conf,$user,$langs,$db;
$conf=$this->savconf;
$user=$this->savuser;
$langs=$this->savlangs;
$db=$this->savdb;
$company = new Societe($db);
$company->name = 'Specimen company';
$company->tva_intra = '123456789';
$tmpinvoice = new Facture($db);
$tmpinvoice->thirdparty = $company;
$tmpinvoice->total_ht = 100;
$tmpinvoice->total_tva = 20;
$tmpinvoice->total_ttc = $tmpinvoice->total_ht + $tmpinvoice->total_tva;
$tmpinvoice->date = dol_mktime(12, 34, 56, 1, 1, 2020, 'gmt');
$string_zatca = $tmpinvoice->buildZATCAQRString();
$this->assertEquals($string_zatca, "ARBTcGVjaW1lbiBjb21wYW55AgkxMjM0NTY3ODkDFDIwMjAtMDEtMDFUMDk6MzQ6NTZaBAMxMjAFAjIw");
return 1;
}
/**
* testBarcodeZATCADecode
*
* @return int
*/
public function testBarcodeZATCADecode()
{
global $conf,$user,$langs,$db;
$conf=$this->savconf;
$user=$this->savuser;
$langs=$this->savlangs;
$db=$this->savdb;
//$string_zatca_base64 = "AQZSYWZlZXECDTEyMzQ1Njc4OVQxMjUDFDIwMjEtMDctMTJUMTQ6MjU6MDlaBAM3ODYFAjI1";
$string_zatca_base64 = "ARBTcGVjaW1lbiBjb21wYW55AgkxMjM0NTY3ODkDFDIwMjAtMDEtMDFUMDk6MzQ6NTZaBAMxMjAFAjIw";
$decoded = base64_decode($string_zatca_base64);
//print_r($decoded)
//raw data
//\u0001\u0006Rafeeq\u0002\t123456789\u0003\u00142021-07-12T14:25:09Z\u0004\u0003786\u0005\u000225
$result_data = preg_replace('/[\x00-\x1F\x80-\xFF]/', ',', $decoded);
$arrayOfData = explode(',,', $result_data);
print __METHOD__." result=".var_export($arrayOfData, true)."\n";
$this->assertEquals("", $arrayOfData[0]);
$this->assertEquals("Specimen company", $arrayOfData[1]);
$this->assertEquals("123456789", $arrayOfData[2]);
$this->assertEquals("2020-01-01T09:34:56Z", $arrayOfData[3]);
$this->assertEquals("120", $arrayOfData[4]);
$this->assertEquals("20", $arrayOfData[5]);
return 1;
}
}