Merge branch 'develop' of github.com:Dolibarr/dolibarr into develop#1

This commit is contained in:
lmarcouiller 2021-03-08 10:15:00 +01:00
commit f627637490
56 changed files with 1855 additions and 373 deletions

View File

@ -4,15 +4,17 @@ How to contribute to Dolibarr
Bug reports and feature requests
--------------------------------
<a name="not-a-support-forum"></a>*Note*: Issues are not a support forum. If you need help using the software, please use [the forums](https://www.dolibarr.org/forum.php). Forums exist in different languages.
<a name="not-a-support-forum"></a>*Note*: **GitHub Issues is not a support forum.** If you have questions about Dolibarr / need help using the software, please use [the forums](https://www.dolibarr.org/forum.php). Forums exist in different languages.
Issues are managed on [GitHub](https://github.com/Dolibarr/dolibarr/issues).
Default language here is english. So please prepare your contributions in english.
Default **language here is english**. So please prepare your contributions in english.
1. Please [use the search engine](https://help.github.com/articles/searching-issues) to check if nobody's already reported your problem.
2. [Create an issue](https://help.github.com/articles/creating-an-issue). Choose an appropriate title. Prepend appropriately with Bug or Feature Request.
4. Tell us the version you are using! (look at /htdocs/admin/system/dolibarr.php? and check if you are using the latest version)
3. Write a report with as much detail as possible (Use [screenshots](https://help.github.com/articles/issue-attachments) or even screencasts and provide logging and debugging informations whenever possible).
3. Tell us the version you are using! (look at /htdocs/admin/system/dolibarr.php? and check if you are using the latest version)
4. Write a report with as much detail as possible (Use [screenshots](https://help.github.com/articles/issue-attachments) or even screencasts and provide logging and debugging informations whenever possible).
5. Delete unnecessary submissions.
6. **Check your Message at Preview before sending.**

View File

@ -1,5 +1,9 @@
#!/bin/sh
# To install this precommit file: TODO
# To install this precommit file: put this file in your local repo in .git/hooks directory and make it executable
# you need to adapt the path to your phpcs install
# if phpcs check fail, then it run phpcbf to fix automaticaly the syntax, and git commit is canceled
# if you have a multiprocessor computer, you can add to the option --parallel=xx
# when running git commit, it first execute this file checking only modified files, so it is faster than running on all files
# To run the fix manually: cd ~/git/dolibarr; phpcbf -s -p -d memory_limit=-1 --extensions=php --colors --tab-width=4 --standard=dev/setup/codesniffer/ruleset.xml --encoding=utf-8 --runtime-set ignore_warnings_on_exit true fileordir
PROJECT=`php -r "echo dirname(dirname(dirname(realpath('$0'))));"`

View File

@ -57,7 +57,9 @@ if ($action == 'setvalue' && $user->admin) {
if (!dolibarr_set_const($db, 'LDAP_GROUP_OBJECT_CLASS', GETPOST("objectclass", 'alphanohtml'), 'chaine', 0, '', $conf->entity)) {
$error++;
}
if (!dolibarr_set_const($db, 'LDAP_GROUP_FILTER', GETPOST("filter"), 'chaine', 0, '', $conf->entity)) {
$error++;
}
if (!dolibarr_set_const($db, 'LDAP_GROUP_FIELD_FULLNAME', GETPOST("fieldfullname", 'alphanohtml'), 'chaine', 0, '', $conf->entity)) {
$error++;
}
@ -141,6 +143,13 @@ print '</td><td>'.$langs->trans("LDAPGroupObjectClassListExample").'</td>';
print '<td>&nbsp;</td>';
print '</tr>';
// Filter, used to filter search
print '<tr class="oddeven"><td>'.$langs->trans("LDAPFilterConnection").'</td><td>';
print '<input size="48" type="text" name="filter" value="'.$conf->global->LDAP_GROUP_FILTER.'">';
print '</td><td>'.$langs->trans("LDAPGroupFilterExample").'</td>';
print '<td></td>';
print '</tr>';
print '</table>';
print '<br>';
print '<table class="noborder centpercent">';
@ -211,11 +220,18 @@ if ($conf->global->LDAP_SYNCHRO_ACTIVE == 'dolibarr2ldap') {
$dn = $conf->global->LDAP_GROUP_DN;
$objectclass = $conf->global->LDAP_GROUP_OBJECT_CLASS;
show_ldap_test_button($butlabel, $testlabel, $key, $dn, $objectclass);
} elseif ($conf->global->LDAP_SYNCHRO_ACTIVE == 'ldap2dolibarr') {
$butlabel = $langs->trans("LDAPTestSearch");
$testlabel = 'testsearchgroup';
$key = $conf->global->LDAP_KEY_GROUPS;
$dn = $conf->global->LDAP_GROUP_DN;
$objectclass = $conf->global->LDAP_GROUP_OBJECT_CLASS;
show_ldap_test_button($butlabel, $testlabel, $key, $dn, $objectclass);
}
if (function_exists("ldap_connect")) {
if ($_GET["action"] == 'testgroup') {
if ($action == 'testgroup') {
// Creation objet
$object = new UserGroup($db);
$object->initAsSpecimen();
@ -260,6 +276,62 @@ if (function_exists("ldap_connect")) {
print $langs->trans("ErrorLDAPMakeManualTest", $conf->ldap->dir_temp).'<br>';
}
}
if ($action == 'testsearchgroup') {
// TODO Mutualize code following with other ldap_xxxx.php pages
// Test synchro
$ldap = new Ldap();
$result = $ldap->connect_bind();
if ($result > 0) {
$required_fields = array(
$conf->global->LDAP_KEY_GROUPS,
// $conf->global->LDAP_GROUP_FIELD_NAME,
$conf->global->LDAP_GROUP_FIELD_DESCRIPTION,
$conf->global->LDAP_GROUP_FIELD_GROUPMEMBERS,
$conf->global->LDAP_GROUP_FIELD_GROUPID
);
// Remove from required_fields all entries not configured in LDAP (empty) and duplicated
$required_fields = array_unique(array_values(array_filter($required_fields, "dol_validElement")));
// Get from LDAP database an array of results
$ldapgroups = $ldap->getRecords('*', $conf->global->LDAP_GROUP_DN, $conf->global->LDAP_KEY_GROUPS, $required_fields, 'group');
//$ldapgroups = $ldap->getRecords('*', $conf->global->LDAP_GROUP_DN, $conf->global->LDAP_KEY_GROUPS, '', 'group');
if (is_array($ldapgroups)) {
$liste = array();
foreach ($ldapgroups as $key => $ldapgroup) {
// Define the label string for this group
$label = '';
foreach ($required_fields as $value) {
if ($value) {
$label .= $value."=".$ldapgroup[$value]." ";
}
}
$liste[$key] = $label;
}
} else {
setEventMessages($ldap->error, $ldap->errors, 'errors');
}
print "<br>\n";
print "LDAP search for group:<br>\n";
print "search: *<br>\n";
print "userDN: ".$conf->global->LDAP_GROUP_DN."<br>\n";
print "useridentifier: ".$conf->global->LDAP_KEY_GROUPS."<br>\n";
print "required_fields: ".implode(',', $required_fields)."<br>\n";
print "=> ".count($liste)." records<br>\n";
print "\n<br>";
} else {
print img_picto('', 'error').' ';
print '<font class="error">'.$langs->trans("LDAPSynchroKO");
print ': '.$ldap->error;
print '</font><br>';
print $langs->trans("ErrorLDAPMakeManualTest", $conf->ldap->dir_temp).'<br>';
}
}
}
// End of page

View File

@ -69,13 +69,20 @@ $search_desc = GETPOST("search_desc", "alpha");
$search_ua = GETPOST("search_ua", "restricthtml");
$search_prefix_session = GETPOST("search_prefix_session", "restricthtml");
if (GETPOST("date_startmonth") == '' || GETPOST("date_startmonth") > 0) {
$date_start = dol_mktime(0, 0, 0, GETPOST("date_startmonth"), GETPOST("date_startday"), GETPOST("date_startyear"));
$now = dol_now();
$nowarray = dol_getdate($now);
if (!GETPOSTISSET("date_startmonth")) {
$date_start = dol_get_first_day($nowarray['year'], $nowarray['mon'], 'tzuserrel');
} else if (GETPOST("date_startmonth") > 0) {
$date_start = dol_mktime(0, 0, 0, GETPOST("date_startmonth", 'int'), GETPOST("date_startday", 'int'), GETPOST("date_startyear", 'int'), 'tzuserrel');
} else {
$date_start = -1;
}
if (GETPOST("date_endmonth") == '' || GETPOST("date_endmonth") > 0) {
$date_end = dol_mktime(23, 59, 59, GETPOST("date_endmonth"), GETPOST("date_endday"), GETPOST("date_endyear"));
if (!GETPOSTISSET("date_endmonth")) {
$date_end = dol_get_last_hour(dol_now('gmt'), 'tzuserrel');
} elseif (GETPOST("date_endmonth") > 0) {
$date_end = dol_get_last_hour(dol_mktime(23, 59, 59, GETPOST("date_endmonth", 'int'), GETPOST("date_endday", 'int'), GETPOST("date_endyear", 'int'), 'tzuserrel'), 'tzuserrel');
} else {
$date_end = -1;
}
@ -85,8 +92,6 @@ if ($date_start > 0 && $date_end > 0 && $date_start > $date_end) {
$date_end = $date_start + 86400;
}
$now = dol_now();
$nowarray = dol_getdate($now);
if (empty($date_start)) { // We define date_start and date_end
$date_start = dol_get_first_day($nowarray['year'], $nowarray['mon'], false);
@ -114,7 +119,6 @@ $arrayfields = array(
)
);
/*
* Actions
*/
@ -316,19 +320,22 @@ if ($result) {
// Fields title search
print '<tr class="liste_titre">';
print '<td class="liste_titre" width="15%">'.$form->selectDate($date_start, 'date_start', 0, 0, 0, '', 1, 0).$form->selectDate($date_end, 'date_end', 0, 0, 0, '', 1, 0).'</td>';
print '<td class="liste_titre" width="15%">';
print $form->selectDate($date_start, 'date_start', 0, 0, 0, '', 1, 0, 0, '', '', '', '', 1, '', '', 'tzuserrel');
print $form->selectDate($date_end, 'date_end', 0, 0, 0, '', 1, 0, 0, '', '', '', '', 1, '', '', 'tzuserrel');
print '</td>';
print '<td class="liste_titre left">';
print '<input class="flat maxwidth100" type="text" name="search_code" value="'.$search_code.'">';
print '<input class="flat maxwidth100" type="text" name="search_code" value="'.dol_escape_htmltag($search_code).'">';
print '</td>';
// IP
print '<td class="liste_titre left">';
print '<input class="flat maxwidth100" type="text" name="search_ip" value="'.$search_ip.'">';
print '<input class="flat maxwidth100" type="text" name="search_ip" value="'.dol_escape_htmltag($search_ip).'">';
print '</td>';
print '<td class="liste_titre left">';
print '<input class="flat maxwidth100" type="text" name="search_user" value="'.$search_user.'">';
print '<input class="flat maxwidth100" type="text" name="search_user" value="'.dol_escape_htmltag($search_user).'">';
print '</td>';
print '<td class="liste_titre left">';
@ -337,13 +344,13 @@ if ($result) {
if (!empty($arrayfields['e.user_agent']['checked'])) {
print '<td class="liste_titre left">';
print '<input class="flat maxwidth100" type="text" name="search_ua" value="'.$search_ua.'">';
print '<input class="flat maxwidth100" type="text" name="search_ua" value="'.dol_escape_htmltag($search_ua).'">';
print '</td>';
}
if (!empty($arrayfields['e.prefix_session']['checked'])) {
print '<td class="liste_titre left">';
print '<input class="flat maxwidth100" type="text" name="search_prefix_session" value="'.$search_prefix_session.'">';
print '<input class="flat maxwidth100" type="text" name="search_prefix_session" value="'.dol_escape_htmltag($search_prefix_session).'">';
print '</td>';
}
@ -376,7 +383,7 @@ if ($result) {
print '<tr class="oddeven">';
// Date
print '<td class="nowrap left">'.dol_print_date($db->jdate($obj->dateevent), '%Y-%m-%d %H:%M:%S').'</td>';
print '<td class="nowrap left">'.dol_print_date($db->jdate($obj->dateevent), '%Y-%m-%d %H:%M:%S', 'tzuserrel').'</td>';
// Code
print '<td>'.$obj->type.'</td>';

View File

@ -92,8 +92,8 @@ class BOM extends CommonObject
'entity' => array('type'=>'integer', 'label'=>'Entity', 'enabled'=>1, 'visible'=>0, 'notnull'=> 1, 'default'=>1, 'index'=>1, 'position'=>5),
'ref' => array('type'=>'varchar(128)', 'label'=>'Ref', 'enabled'=>1, 'noteditable'=>1, 'visible'=>4, 'position'=>10, 'notnull'=>1, 'default'=>'(PROV)', 'index'=>1, 'searchall'=>1, 'comment'=>"Reference of BOM", 'showoncombobox'=>'1',),
'label' => array('type'=>'varchar(255)', 'label'=>'Label', 'enabled'=>1, 'visible'=>1, 'position'=>30, 'notnull'=>1, 'searchall'=>1, 'showoncombobox'=>'1', 'autofocusoncreate'=>1),
//'bomtype' => array('type'=>'integer', 'label'=>'Type', 'enabled'=>1, 'visible'=>1, 'position'=>10, 'notnull'=>1, 'default'=>'0', 'arrayofkeyval'=>array(0=>'Manufacturing', 1=>'Disassembly')),
'bomtype' => array('type'=>'integer', 'label'=>'Type', 'enabled'=>1, 'visible'=>-1, 'position'=>32, 'notnull'=>1, 'default'=>'0', 'arrayofkeyval'=>array(0=>'Manufacturing')),
'bomtype' => array('type'=>'integer', 'label'=>'Type', 'enabled'=>1, 'visible'=>1, 'position'=>33, 'notnull'=>1, 'default'=>'0', 'arrayofkeyval'=>array(0=>'Manufacturing', 1=>'Disassemble')),
//'bomtype' => array('type'=>'integer', 'label'=>'Type', 'enabled'=>1, 'visible'=>-1, 'position'=>32, 'notnull'=>1, 'default'=>'0', 'arrayofkeyval'=>array(0=>'Manufacturing')),
'fk_product' => array('type'=>'integer:Product:product/class/product.class.php:1:(finished IS NULL or finished <> 0)', 'label'=>'Product', 'picto'=>'product', 'enabled'=>1, 'visible'=>1, 'position'=>35, 'notnull'=>1, 'index'=>1, 'help'=>'ProductBOMHelp', 'css'=>'maxwidth500'),
'description' => array('type'=>'text', 'label'=>'Description', 'enabled'=>1, 'visible'=>-1, 'position'=>60, 'notnull'=>-1,),
'qty' => array('type'=>'real', 'label'=>'Quantity', 'enabled'=>1, 'visible'=>1, 'default'=>1, 'position'=>55, 'notnull'=>1, 'isameasure'=>'1', 'css'=>'maxwidth75imp'),

View File

@ -207,8 +207,8 @@ if (empty($reshook)) {
$substitutionarray['__OTHER4__'] = $other4;
$substitutionarray['__OTHER5__'] = $other5;
$substitutionarray['__USER_SIGNATURE__'] = $signature; // Signature is empty when ran from command line or taken from user in parameter)
$substitutionarray['__CHECK_READ__'] = '<img src="'.DOL_MAIN_URL_ROOT.'/public/emailing/mailing-read.php?tag='.$obj->tag.'&securitykey='.urlencode($conf->global->MAILING_EMAIL_UNSUBSCRIBE_KEY).'" width="1" height="1" style="width:1px;height:1px" border="0"/>';
$substitutionarray['__UNSUBSCRIBE__'] = '<a href="'.DOL_MAIN_URL_ROOT.'/public/emailing/mailing-unsubscribe.php?tag='.$obj->tag.'&unsuscrib=1&securitykey='.urlencode($conf->global->MAILING_EMAIL_UNSUBSCRIBE_KEY).'" target="_blank">'.$langs->trans("MailUnsubcribe").'</a>';
$substitutionarray['__CHECK_READ__'] = '<img src="'.DOL_MAIN_URL_ROOT.'/public/emailing/mailing-read.php?tag='.urlencode($obj->tag).'&securitykey='.urlencode($conf->global->MAILING_EMAIL_UNSUBSCRIBE_KEY).'&email='.urlencode($obj->email).'&mtid='.$obj->rowid.'" width="1" height="1" style="width:1px;height:1px" border="0"/>';
$substitutionarray['__UNSUBSCRIBE__'] = '<a href="'.DOL_MAIN_URL_ROOT.'/public/emailing/mailing-unsubscribe.php?tag='.urlencode($obj->tag).'&unsuscrib=1&securitykey='.urlencode($conf->global->MAILING_EMAIL_UNSUBSCRIBE_KEY).'&email='.urlencode($obj->email).'&mtid='.$obj->rowid.'" target="_blank">'.$langs->trans("MailUnsubcribe").'</a>';
$onlinepaymentenabled = 0;
if (!empty($conf->paypal->enabled)) {

View File

@ -315,10 +315,11 @@ if ($result) {
$i++;
// Bank account
print '<tr><td class="titlefield">'.$langs->trans("Account").'</td>';
print '<tr><td class="titlefieldcreate">'.$langs->trans("Account").'</td>';
print '<td>';
if (!$objp->rappro && !$bankline->getVentilExportCompta()) {
$form->select_comptes($acct->id, 'accountid', 0, '', 0);
print img_picto('', 'bank_account', 'class="paddingright"');
print $form->select_comptes($acct->id, 'accountid', 0, '', 0, '', 0, '', 1);
} else {
print $acct->getNomUrl(1, 'transactions', 'reflabel');
}
@ -566,7 +567,7 @@ if ($result) {
// Bank line
print '<tr><td class="toptd">'.$form->editfieldkey('RubriquesTransactions', 'custcats', '', $object, 0).'</td><td>';
$cate_arbo = $form->select_all_categories(Categorie::TYPE_BANK_LINE, null, 'parent', null, null, 1);
print $form->multiselectarray('custcats', $cate_arbo, $arrayselected, null, null, null, null, "90%");
print img_picto('', 'category', 'class="paddingright"').$form->multiselectarray('custcats', $cate_arbo, $arrayselected, null, null, null, null, "90%");
print "</td></tr>";
}

View File

@ -79,19 +79,22 @@ class FactureRec extends CommonInvoice
*/
public $title;
public $socid;
public $number;
public $date;
public $remise;
public $remise_absolue;
public $remise_percent;
public $tva;
public $total;
public $db_table;
public $propalid;
public $date_last_gen;
public $date_when;
public $nb_gen_done;
public $nb_gen_max;
public $user_author;
/**
* @var int Frequency
*/
@ -107,8 +110,22 @@ class FactureRec extends CommonInvoice
public $usenewprice = 0;
public $date_lim_reglement;
public $cond_reglement_code; // Code in llx_c_paiement
public $mode_reglement_code; // Code in llx_c_paiement
public $suspended; // status
public $auto_validate; // 0 to create in draft, 1 to create and validate the new invoice
public $generate_pdf; // 1 to generate PDF on invoice generation (default)
/**
* @var int 1 if status is draft
* @deprecated
*/
public $brouillon;
/**
* 'type' if the field format ('integer', 'integer:ObjectClass:PathToClass[:AddCreateButtonOrNot[:Filter]]', 'varchar(x)', 'double(24,8)', 'real', 'price', 'text', 'html', 'date', 'datetime', 'timestamp', 'duration', 'mail', 'phone', 'url', 'password')
* Note: Filter can be a string like "(t.ref:like:'SO-%') or (t.date_creation:<:'20160101') or (t.nature:is:NULL)"
@ -335,14 +352,20 @@ class FactureRec extends CommonInvoice
$facsrc->lines[$i]->special_code,
$facsrc->lines[$i]->label,
$facsrc->lines[$i]->fk_unit,
$facsrc->lines[$i]->multicurrency_subprice
$facsrc->lines[$i]->multicurrency_subprice,
0,
0,
null,
$facsrc->lines[$i]->pa_ht
);
if ($result_insert < 0) {
$error++;
} else {
$objectline = new FactureLigneRec($this->db);
if ($objectline->fetch($result_insert)) {
$result2 = $objectline->fetch($result_insert);
if ($result2 > 0) {
// Extrafields
if (method_exists($facsrc->lines[$i], 'fetch_optionals')) {
$facsrc->lines[$i]->fetch_optionals($facsrc->lines[$i]->id);
@ -353,6 +376,9 @@ class FactureRec extends CommonInvoice
if ($result < 0) {
$error++;
}
} elseif ($result2 < 0) {
$this->errors[] = $objectline->error;
$error++;
}
}
}
@ -403,6 +429,7 @@ class FactureRec extends CommonInvoice
if ($error) {
$this->db->rollback();
return -3;
} else {
$this->db->commit();
return $this->id;
@ -494,14 +521,15 @@ class FactureRec extends CommonInvoice
//$sql.= " LEFT JOIN ".MAIN_DB_PREFIX."element_element as el ON el.fk_target = f.rowid AND el.targettype = 'facture'";
$sql .= ' WHERE f.entity IN ('.getEntity('invoice').')';
if ($rowid) {
$sql .= ' AND f.rowid='.$rowid;
$sql .= ' AND f.rowid='.((int) $rowid);
} elseif ($ref) {
$sql .= " AND f.titre='".$this->db->escape($ref)."'";
} else {
$sql .= ' AND f.rowid = 0';
}
/* This field are not used for template invoice
if ($ref_ext) $sql.= " AND f.ref_ext='".$this->db->escape($ref_ext)."'";
if ($ref_int) $sql.= " AND f.ref_int='".$this->db->escape($ref_int)."'";
*/
if ($ref_ext) $sql.= " AND f.ref_ext='".$this->db->escape($ref_ext)."'";
*/
$result = $this->db->query($sql);
if ($result) {
@ -513,11 +541,7 @@ class FactureRec extends CommonInvoice
$this->titre = $obj->title; // deprecated
$this->title = $obj->title;
$this->ref = $obj->title;
$this->ref_client = $obj->ref_client;
$this->suspended = $obj->suspended;
$this->type = $obj->type;
$this->datep = $obj->dp;
$this->date = $obj->df;
$this->remise_percent = $obj->remise_percent;
$this->remise_absolue = $obj->remise_absolue;
$this->remise = $obj->remise;
@ -526,9 +550,6 @@ class FactureRec extends CommonInvoice
$this->total_localtax1 = $obj->localtax1;
$this->total_localtax2 = $obj->localtax2;
$this->total_ttc = $obj->total_ttc;
$this->paye = $obj->paye;
$this->close_code = $obj->close_code;
$this->close_note = $obj->close_note;
$this->socid = $obj->fk_soc;
$this->date_lim_reglement = $this->db->jdate($obj->dlr);
$this->mode_reglement_id = $obj->fk_mode_reglement;
@ -540,14 +561,12 @@ class FactureRec extends CommonInvoice
$this->cond_reglement_doc = $obj->cond_reglement_libelle_doc;
$this->fk_project = $obj->fk_project;
$this->fk_account = $obj->fk_account;
$this->fk_facture_source = $obj->fk_facture_source;
$this->note_private = $obj->note_private;
$this->note_public = $obj->note_public;
$this->user_author = $obj->fk_user_author;
$this->modelpdf = $obj->model_pdf; // deprecated
$this->model_pdf = $obj->model_pdf;
$this->rang = $obj->rang;
$this->special_code = $obj->special_code;
//$this->special_code = $obj->special_code;
$this->frequency = $obj->frequency;
$this->unit_frequency = $obj->unit_frequency;
$this->date_when = $this->db->jdate($obj->date_when);
@ -629,11 +648,11 @@ class FactureRec extends CommonInvoice
$sql = 'SELECT l.rowid, l.fk_product, l.product_type, l.label as custom_label, l.description, l.product_type, l.price, l.qty, l.vat_src_code, l.tva_tx, ';
$sql .= ' l.localtax1_tx, l.localtax2_tx, l.localtax1_type, l.localtax2_type, l.remise, l.remise_percent, l.subprice,';
$sql .= ' l.info_bits, l.date_start_fill, l.date_end_fill, l.total_ht, l.total_tva, l.total_ttc, l.fk_product_fournisseur_price as fk_fournprice, l.buy_price_ht as pa_ht,';
$sql .= ' l.info_bits, l.date_start_fill, l.date_end_fill, l.total_ht, l.total_tva, l.total_ttc, l.fk_product_fournisseur_price, l.buy_price_ht as pa_ht,';
//$sql.= ' l.situation_percent, l.fk_prev_id,';
//$sql.= ' l.localtax1_tx, l.localtax2_tx, l.localtax1_type, l.localtax2_type, l.remise_percent, l.fk_remise_except, l.subprice,';
$sql .= ' l.rang, l.special_code,';
//$sql.= ' l.info_bits, l.total_ht, l.total_tva, l.total_localtax1, l.total_localtax2, l.total_ttc, l.fk_code_ventilation, l.fk_product_fournisseur_price as fk_fournprice, l.buy_price_ht as pa_ht,';
//$sql.= ' l.info_bits, l.total_ht, l.total_tva, l.total_localtax1, l.total_localtax2, l.total_ttc, l.fk_code_ventilation, l.fk_product_fournisseur_price, l.buy_price_ht as pa_ht,';
$sql .= ' l.fk_unit, l.fk_contract_line,';
$sql .= ' l.fk_multicurrency, l.multicurrency_code, l.multicurrency_subprice, l.multicurrency_total_ht, l.multicurrency_total_tva, l.multicurrency_total_ttc,';
$sql .= ' p.ref as product_ref, p.fk_product_type as fk_product_type, p.label as product_label, p.description as product_desc';
@ -682,10 +701,16 @@ class FactureRec extends CommonInvoice
$line->total_ht = $objp->total_ht;
$line->total_tva = $objp->total_tva;
$line->total_ttc = $objp->total_ttc;
//$line->code_ventilation = $objp->fk_code_ventilation;
$line->fk_fournprice = $objp->fk_fournprice;
$marginInfos = getMarginInfos($objp->subprice, $objp->remise_percent, $objp->tva_tx, $objp->localtax1_tx, $objp->localtax2_tx, $line->fk_fournprice, $objp->pa_ht);
$line->pa_ht = $marginInfos[0];
$line->fk_product_fournisseur_price = $objp->fk_product_fournisseur_price;
$line->fk_fournprice = $objp->fk_product_fournisseur_price; // For backward compatibility
$marginInfos = getMarginInfos($objp->subprice, $objp->remise_percent, $objp->tva_tx, $objp->localtax1_tx, $objp->localtax2_tx, $objp->fk_product_fournisseur_price, $objp->pa_ht);
$line->buyprice = $marginInfos[0];
$line->pa_ht = $marginInfos[0]; // For backward compatibility
$line->marge_tx = $marginInfos[1];
$line->marque_tx = $marginInfos[2];
$line->rang = $objp->rang;
@ -821,6 +846,7 @@ class FactureRec extends CommonInvoice
$localtaxes_type = getLocalTaxesFromRate($txtva, 0, $this->thirdparty, $mysoc);
// Clean vat code
$reg = array();
$vat_src_code = '';
if (preg_match('/\((.*)\)/', $txtva, $reg)) {
$vat_src_code = $reg[1];
@ -1261,6 +1287,8 @@ class FactureRec extends CommonInvoice
$facture->type = self::TYPE_STANDARD;
$facture->brouillon = 1;
$facture->statut = self::STATUS_DRAFT;
$facture->status = self::STATUS_DRAFT;
$facture->date = (empty($facturerec->date_when) ? $now : $facturerec->date_when); // We could also use dol_now here but we prefer date_when so invoice has real date when we would like even if we generate later.
$facture->socid = $facturerec->socid;
@ -1586,6 +1614,7 @@ class FactureRec extends CommonInvoice
// Initialize parameters
$this->id = 0;
$this->ref = 'SPECIMEN';
$this->title = 'SPECIMEN';
$this->specimen = 1;
$this->socid = 1;
$this->date = $nownotime;
@ -1962,6 +1991,10 @@ class FactureLigneRec extends CommonInvoiceLine
$sql .= ' l.date_start_fill, l.date_end_fill, l.info_bits, l.total_ht, l.total_tva, l.total_ttc,';
$sql .= ' l.rang, l.special_code,';
$sql .= ' l.fk_unit, l.fk_contract_line,';
$sql .= ' l.import_key, l.fk_multicurrency,';
$sql .= ' l.multicurrency_code, l.multicurrency_subprice, l.multicurrency_total_ht, l.multicurrency_total_tva, l.multicurrency_total_ttc,';
$sql .= ' l.buy_price_ht, l.fk_product_fournisseur_price,';
$sql .= ' l.fk_user_author, l.fk_user_modif,';
$sql .= ' p.ref as product_ref, p.fk_product_type as fk_product_type, p.label as product_label, p.description as product_desc';
$sql .= ' FROM '.MAIN_DB_PREFIX.'facturedet_rec as l';
$sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'product as p ON l.fk_product = p.rowid';
@ -2008,7 +2041,17 @@ class FactureLigneRec extends CommonInvoiceLine
$this->special_code = $objp->special_code;
$this->fk_unit = $objp->fk_unit;
$this->fk_contract_line = $objp->fk_contract_line;
$this->import_key = $objp->import_key;
$this->fk_multicurrency = $objp->fk_multicurrency;
$this->multicurrency_code = $objp->multicurrency_code;
$this->multicurrency_subprice = $objp->multicurrency_subprice;
$this->multicurrency_total_ht = $objp->multicurrency_total_ht;
$this->multicurrency_total_tva = $objp->multicurrency_total_tva;
$this->multicurrency_total_ttc = $objp->multicurrency_total_ttc;
$this->buy_price_ht = $objp->buy_price_ht;
$this->fk_product_fournisseur_price = $objp->fk_product_fournisseur_price;
$this->fk_user_author = $objp->fk_user_author;
$this->fk_user_modif = $objp->fk_user_modif;
$this->db->free($result);
return 1;

View File

@ -99,6 +99,12 @@ class Facture extends CommonInvoice
*/
protected $table_ref_field = 'ref';
/**
* @var int 1 if status is draft
* @deprecated
*/
public $brouillon;
/**
* @var int thirdparty ID
*/
@ -171,6 +177,7 @@ class Facture extends CommonInvoice
//! id of source invoice if replacement invoice or credit note
public $fk_facture_source;
public $linked_objects = array();
public $date_lim_reglement;
public $cond_reglement_code; // Code in llx_c_paiement
public $mode_reglement_code; // Code in llx_c_paiement
@ -446,6 +453,8 @@ class Facture extends CommonInvoice
$this->mode_reglement_id = 0;
}
$this->brouillon = 1;
$this->status = self::STATUS_DRAFT;
$this->statut = self::STATUS_DRAFT;
// Multicurrency (test on $this->multicurrency_tx because we should take the default rate only if not using origin rate)
if (!empty($this->multicurrency_code) && empty($this->multicurrency_tx)) {
@ -537,6 +546,8 @@ class Facture extends CommonInvoice
$this->mode_reglement_id = 0;
}
$this->brouillon = 1;
$this->status = self::STATUS_DRAFT;
$this->statut = self::STATUS_DRAFT;
$this->linked_objects = $_facrec->linkedObjectsIds;
// We do not add link to template invoice or next invoice will be linked to all generated invoices
@ -917,8 +928,9 @@ class Facture extends CommonInvoice
$localtax1_tx = $_facrec->lines[$i]->localtax1_tx;
$localtax2_tx = $_facrec->lines[$i]->localtax2_tx;
$fk_product_fournisseur_price = empty($_facrec->lines[$i]->fk_product_fournisseur_price) ?null:$_facrec->lines[$i]->fk_product_fournisseur_price;
$fk_product_fournisseur_price = empty($_facrec->lines[$i]->fk_product_fournisseur_price) ? null : $_facrec->lines[$i]->fk_product_fournisseur_price;
$buyprice = empty($_facrec->lines[$i]->buyprice) ? 0 : $_facrec->lines[$i]->buyprice;
// If buyprice not defined from template invoice, we try to guess the best value
if (!$buyprice && $_facrec->lines[$i]->fk_product > 0) {
require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.product.class.php';
@ -1682,7 +1694,7 @@ class Facture extends CommonInvoice
$this->fetchPreviousNextSituationInvoice();
}
if ($this->statut == self::STATUS_DRAFT) {
if ($this->status == self::STATUS_DRAFT) {
$this->brouillon = 1;
}
@ -2583,8 +2595,8 @@ class Facture extends CommonInvoice
$this->fetch_lines();
// Check parameters
if (!$this->brouillon) {
dol_syslog(get_class($this)."::validate no draft status", LOG_WARNING);
if ($this->statut != self::STATUS_DRAFT) {
dol_syslog(get_class($this)."::validate status is not draft. operation canceled.", LOG_WARNING);
return 0;
}
if (count($this->lines) <= 0) {
@ -2848,6 +2860,7 @@ class Facture extends CommonInvoice
$this->ref = $num;
$this->ref = $num;
$this->statut = self::STATUS_VALIDATED;
$this->status = self::STATUS_VALIDATED;
$this->brouillon = 0;
$this->date_validation = $now;
$i = 0;
@ -2886,7 +2899,7 @@ class Facture extends CommonInvoice
* Update price of next invoice
*
* @param Translate $langs Translate object
* @return bool false if KO, true if OK
* @return bool false if KO, true if OK
*/
public function updatePriceNextInvoice(&$langs)
{
@ -2899,6 +2912,7 @@ class Facture extends CommonInvoice
}
$next_invoice->brouillon = 1;
foreach ($next_invoice->lines as $line) {
$result = $next_invoice->updateline(
$line->id,
@ -2994,12 +3008,14 @@ class Facture extends CommonInvoice
$old_statut = $this->statut;
$this->brouillon = 1;
$this->statut = self::STATUS_DRAFT;
$this->status = self::STATUS_DRAFT;
// Call trigger
$result = $this->call_trigger('BILL_UNVALIDATE', $user);
if ($result < 0) {
$error++;
$this->statut = $old_statut;
$this->status = $old_statut;
$this->brouillon = 0;
}
// End call triggers
@ -3361,7 +3377,7 @@ class Facture extends CommonInvoice
dol_syslog(get_class($this)."::updateline rowid=$rowid, desc=$desc, pu=$pu, qty=$qty, remise_percent=$remise_percent, date_start=$date_start, date_end=$date_end, txtva=$txtva, txlocaltax1=$txlocaltax1, txlocaltax2=$txlocaltax2, price_base_type=$price_base_type, info_bits=$info_bits, type=$type, fk_parent_line=$fk_parent_line pa_ht=$pa_ht, special_code=$special_code, fk_unit=$fk_unit, pu_ht_devise=$pu_ht_devise", LOG_DEBUG);
if ($this->brouillon) {
if ($this->statut == self::STATUS_DRAFT) {
if (!$this->is_last_in_cycle() && empty($this->error)) {
if (!$this->checkProgressLine($rowid, $situation_percent)) {
if (!$this->error) {
@ -3630,7 +3646,7 @@ class Facture extends CommonInvoice
dol_syslog(get_class($this)."::deleteline rowid=".$rowid, LOG_DEBUG);
if (!$this->brouillon) {
if ($this->statut != self::STATUS_DRAFT) {
$this->error = 'ErrorDeleteLineNotAllowedByObjectStatus';
return -1;
}

View File

@ -364,8 +364,9 @@ if ($action == 'new') {
print '</form>';
print '<br>';
$sql = "SELECT ba.rowid as bid, b.datec as datec, b.dateo as date, b.rowid as transactionid, ";
$sql .= " b.amount, ba.label, b.emetteur, b.num_chq, b.banque,";
$sql = "SELECT ba.rowid as bid, ba.label,";
$sql .= " b.rowid as transactionid, b.label as transactionlabel, b.datec as datec, b.dateo as date, ";
$sql .= " b.amount, b.emetteur, b.num_chq, b.banque,";
$sql .= " p.rowid as paymentid, p.ref as paymentref";
$sql .= " FROM ".MAIN_DB_PREFIX."bank as b";
$sql .= " LEFT JOIN ".MAIN_DB_PREFIX."paiement as p ON p.fk_bank = b.rowid";
@ -393,6 +394,8 @@ if ($action == 'new') {
$lines[$obj->bid][$i]["numero"] = $obj->num_chq;
$lines[$obj->bid][$i]["banque"] = $obj->banque;
$lines[$obj->bid][$i]["id"] = $obj->transactionid;
$lines[$obj->bid][$i]["ref"] = $obj->transactionid;
$lines[$obj->bid][$i]["label"] = $obj->transactionlabel;
$lines[$obj->bid][$i]["paymentid"] = $obj->paymentid;
$lines[$obj->bid][$i]["paymentref"] = $obj->paymentref;
$i++;
@ -473,8 +476,9 @@ if ($action == 'new') {
print '</td>';
// Link to bank transaction
print '<td class="center">';
$accountlinestatic->rowid = $value["id"];
if ($accountlinestatic->rowid) {
$accountlinestatic->id = $value["id"];
$accountlinestatic->ref = $value["ref"];
if ($accountlinestatic->id > 0) {
print $accountlinestatic->getNomUrl(1);
} else {
print '&nbsp;';
@ -594,7 +598,7 @@ if ($action == 'new') {
// List of bank checks
$sql = "SELECT b.rowid, b.amount, b.num_chq, b.emetteur,";
$sql = "SELECT b.rowid, b.rowid as ref, b.label, b.amount, b.num_chq, b.emetteur,";
$sql .= " b.dateo as date, b.datec as datec, b.banque,";
$sql .= " p.rowid as pid, p.ref as pref, ba.rowid as bid, p.statut";
$sql .= " FROM ".MAIN_DB_PREFIX."bank_account as ba";
@ -648,8 +652,9 @@ if ($action == 'new') {
print '</td>';
// Link to bank transaction
print '<td class="center">';
$accountlinestatic->rowid = $objp->rowid;
if ($accountlinestatic->rowid) {
$accountlinestatic->id = $objp->rowid;
$accountlinestatic->ref = $objp->ref;
if ($accountlinestatic->id > 0) {
print $accountlinestatic->getNomUrl(1);
} else {
print '&nbsp;';

View File

@ -74,9 +74,9 @@ if ($action == 'add' && !empty($permissiontoadd)) {
if (in_array($object->fields[$key]['type'], array('text', 'html'))) {
$value = GETPOST($key, 'restricthtml');
} elseif ($object->fields[$key]['type'] == 'date') {
$value = dol_mktime(12, 0, 0, GETPOST($key.'month', 'int'), GETPOST($key.'day', 'int'), GETPOST($key.'year', 'int'));
$value = dol_mktime(12, 0, 0, GETPOST($key.'month', 'int'), GETPOST($key.'day', 'int'), GETPOST($key.'year', 'int')); // for date without hour, we use gmt
} elseif ($object->fields[$key]['type'] == 'datetime') {
$value = dol_mktime(GETPOST($key.'hour', 'int'), GETPOST($key.'min', 'int'), 0, GETPOST($key.'month', 'int'), GETPOST($key.'day', 'int'), GETPOST($key.'year', 'int'));
$value = dol_mktime(GETPOST($key.'hour', 'int'), GETPOST($key.'min', 'int'), GETPOST($key.'sec', 'int'), GETPOST($key.'month', 'int'), GETPOST($key.'day', 'int'), GETPOST($key.'year', 'int'), 'tzuserrel');
} elseif ($object->fields[$key]['type'] == 'duration') {
$value = 60 * 60 * GETPOST($key.'hour', 'int') + 60 * GETPOST($key.'min', 'int');
} elseif (preg_match('/^(integer|price|real|double)/', $object->fields[$key]['type'])) {
@ -174,9 +174,9 @@ if ($action == 'update' && !empty($permissiontoadd)) {
$value = GETPOST($key, 'restricthtml');
}
} elseif ($object->fields[$key]['type'] == 'date') {
$value = dol_mktime(12, 0, 0, GETPOST($key.'month'), GETPOST($key.'day'), GETPOST($key.'year'));
$value = dol_mktime(12, 0, 0, GETPOST($key.'month', 'int'), GETPOST($key.'day', 'int'), GETPOST($key.'year', 'int')); // for date without hour, we use gmt
} elseif ($object->fields[$key]['type'] == 'datetime') {
$value = dol_mktime(GETPOST($key.'hour'), GETPOST($key.'min'), 0, GETPOST($key.'month'), GETPOST($key.'day'), GETPOST($key.'year'));
$value = dol_mktime(GETPOST($key.'hour', 'int'), GETPOST($key.'min', 'int'), GETPOST($key.'sec', 'int'), GETPOST($key.'month', 'int'), GETPOST($key.'day', 'int'), GETPOST($key.'year', 'int'), 'tzuserrel');
} elseif ($object->fields[$key]['type'] == 'duration') {
if (GETPOST($key.'hour', 'int') != '' || GETPOST($key.'min', 'int') != '') {
$value = 60 * 60 * GETPOST($key.'hour', 'int') + 60 * GETPOST($key.'min', 'int');

View File

@ -6455,11 +6455,10 @@ abstract class CommonObject
}
}
if (in_array($type, array('date', 'datetime'))) {
if (in_array($type, array('date'))) {
$tmp = explode(',', $size);
$newsize = $tmp[0];
$showtime = in_array($type, array('datetime')) ? 1 : 0;
$showtime = 0;
// Do not show current date when field not required (see selectDate() method)
if (!$required && $value == '') {
@ -6468,6 +6467,16 @@ abstract class CommonObject
// TODO Must also support $moreparam
$out = $form->selectDate($value, $keyprefix.$key.$keysuffix, $showtime, $showtime, $required, '', 1, (($keyprefix != 'search_' && $keyprefix != 'search_options_') ? 1 : 0), 0, 1);
} elseif (in_array($type, array('datetime'))) {
$tmp = explode(',', $size);
$newsize = $tmp[0];
$showtime = 1;
// Do not show current date when field not required (see selectDate() method)
if (!$required && $value == '') $value = '-1';
// TODO Must also support $moreparam
$out = $form->selectDate($value, $keyprefix.$key.$keysuffix, $showtime, $showtime, $required, '', 1, (($keyprefix != 'search_' && $keyprefix != 'search_options_') ? 1 : 0), 0, 1, '', '', '', 1, '', '', 'tzuserrel');
} elseif (in_array($type, array('duration'))) {
$out = $form->select_duration($keyprefix.$key.$keysuffix, $value, 0, 'text', 0, 1);
} elseif (in_array($type, array('int', 'integer'))) {
@ -7025,13 +7034,13 @@ abstract class CommonObject
$value = $this->getLibStatut(3);
} elseif ($type == 'date') {
if (!empty($value)) {
$value = dol_print_date($value, 'day');
$value = dol_print_date($value, 'day'); // We suppose dates without time are always gmt (storage of course + output)
} else {
$value = '';
}
} elseif ($type == 'datetime' || $type == 'timestamp') {
if (!empty($value)) {
$value = dol_print_date($value, 'dayhour');
$value = dol_print_date($value, 'dayhour', 'tzuserrel');
} else {
$value = '';
}
@ -7410,12 +7419,19 @@ abstract class CommonObject
}
// Convert date into timestamp format (value in memory must be a timestamp)
if (in_array($extrafields->attributes[$this->table_element]['type'][$key], array('date', 'datetime'))) {
if (in_array($extrafields->attributes[$this->table_element]['type'][$key], array('date'))) {
$datenotinstring = $this->array_options['options_'.$key];
if (!is_numeric($this->array_options['options_'.$key])) { // For backward compatibility
$datenotinstring = $this->db->jdate($datenotinstring);
}
$value = (GETPOSTISSET($keyprefix.'options_'.$key.$keysuffix)) ? dol_mktime(GETPOST($keyprefix.'options_'.$key.$keysuffix."hour", 'int', 3), GETPOST($keyprefix.'options_'.$key.$keysuffix."min", 'int', 3), 0, GETPOST($keyprefix.'options_'.$key.$keysuffix."month", 'int', 3), GETPOST($keyprefix.'options_'.$key.$keysuffix."day", 'int', 3), GETPOST($keyprefix.'options_'.$key.$keysuffix."year", 'int', 3)) : $datenotinstring;
$value = (GETPOSTISSET($keyprefix.'options_'.$key.$keysuffix)) ? dol_mktime(12, 0, 0, GETPOST($keyprefix.'options_'.$key.$keysuffix."month", 'int', 3), GETPOST($keyprefix.'options_'.$key.$keysuffix."day", 'int', 3), GETPOST($keyprefix.'options_'.$key.$keysuffix."year", 'int', 3)) : $datenotinstring;
}
if (in_array($extrafields->attributes[$this->table_element]['type'][$key], array('datetime'))) {
$datenotinstring = $this->array_options['options_'.$key];
if (!is_numeric($this->array_options['options_'.$key])) { // For backward compatibility
$datenotinstring = $this->db->jdate($datenotinstring);
}
$value = (GETPOSTISSET($keyprefix.'options_'.$key.$keysuffix)) ? dol_mktime(GETPOST($keyprefix.'options_'.$key.$keysuffix."hour", 'int', 3), GETPOST($keyprefix.'options_'.$key.$keysuffix."min", 'int', 3), GETPOST($keyprefix.'options_'.$key.$keysuffix."sec", 'int', 3), GETPOST($keyprefix.'options_'.$key.$keysuffix."month", 'int', 3), GETPOST($keyprefix.'options_'.$key.$keysuffix."day", 'int', 3), GETPOST($keyprefix.'options_'.$key.$keysuffix."year", 'int', 3), 'tzuserrel') : $datenotinstring;
}
// Convert float submited string into real php numeric (value in memory must be a php numeric)
if (in_array($extrafields->attributes[$this->table_element]['type'][$key], array('price', 'double'))) {
@ -8174,12 +8190,14 @@ abstract class CommonObject
*/
public function setVarsFromFetchObj(&$obj)
{
global $db;
foreach ($this->fields as $field => $info) {
if ($this->isDate($info)) {
if (empty($obj->{$field}) || $obj->{$field} === '0000-00-00 00:00:00' || $obj->{$field} === '1000-01-01 00:00:00') {
$this->{$field} = 0;
if (is_null($obj->{$field}) || $obj->{$field} === '' || $obj->{$field} === '0000-00-00 00:00:00' || $obj->{$field} === '1000-01-01 00:00:00') {
$this->{$field} = '';
} else {
$this->{$field} = strtotime($obj->{$field});
$this->{$field} = $db->jdate($obj->{$field});
}
} elseif ($this->isArray($info)) {
if (!empty($obj->{$field})) {

View File

@ -1062,11 +1062,10 @@ class ExtraFields
}
}
if (in_array($type, array('date', 'datetime'))) {
if (in_array($type, array('date'))) {
$tmp = explode(',', $size);
$newsize = $tmp[0];
$showtime = in_array($type, array('datetime')) ? 1 : 0;
$showtime = 0;
// Do not show current date when field not required (see selectDate() method)
if (!$required && $value == '') {
@ -1079,16 +1078,41 @@ class ExtraFields
'start' => isset($value['start']) ? $value['start'] : '',
'end' => isset($value['end']) ? $value['end'] : ''
);
$out = '<div ' . ($moreparam ? $moreparam : '') . '><div class="nowrap">'
. $form->selectDate($prefill['start'], $keyprefix.$key.$keysuffix.'_start', 0, 0, 1, '', 1, 0, 0, '', '', '', '', 1, '', $langs->trans("From"))
. '</div><div class="nowrap">'
. $form->selectDate($prefill['end'], $keyprefix.$key.$keysuffix.'_end', 0, 0, 1, '', 1, 0, 0, '', '', '', '', 1, '', $langs->trans("to"))
. '</div></div>';
$out = '<div ' . ($moreparam ? $moreparam : '') . '><div class="nowrap">';
$out .= $form->selectDate($prefill['start'], $keyprefix.$key.$keysuffix.'_start', 0, 0, 1, '', 1, 0, 0, '', '', '', '', 1, '', $langs->trans("From"));
$out .= '</div><div class="nowrap">';
$out .= $form->selectDate($prefill['end'], $keyprefix.$key.$keysuffix.'_end', 0, 0, 1, '', 1, 0, 0, '', '', '', '', 1, '', $langs->trans("to"));
$out .= '</div></div>';
} else {
// TODO Must also support $moreparam
$out = $form->selectDate($value, $keyprefix.$key.$keysuffix, $showtime, $showtime, $required, '', 1, (($keyprefix != 'search_' && $keyprefix != 'search_options_') ? 1 : 0), 0, 1);
}
} elseif (in_array($type, array('int', 'integer'))) {
} elseif (in_array($type, array('datetime'))) {
$tmp = explode(',', $size);
$newsize = $tmp[0];
$showtime = 1;
// Do not show current date when field not required (see selectDate() method)
if (!$required && $value == '') {
$value = '-1';
}
if ($mode == 1) {
// search filter on a date extrafield shows two inputs to select a date range
$prefill = array(
'start' => isset($value['start']) ? $value['start'] : '',
'end' => isset($value['end']) ? $value['end'] : ''
);
$out = '<div ' . ($moreparam ? $moreparam : '') . '><div class="nowrap">';
$out .= $form->selectDate($prefill['start'], $keyprefix.$key.$keysuffix.'_start', 1, 1, 1, '', 1, 0, 0, '', '', '', '', 1, '', $langs->trans("From"), 'tzuserrel');
$out .= '</div><div class="nowrap">';
$out .= $form->selectDate($prefill['end'], $keyprefix.$key.$keysuffix.'_end', 1, 1, 1, '', 1, 0, 0, '', '', '', '', 1, '', $langs->trans("to"), 'tzuserrel');
$out .= '</div></div>';
} else {
// TODO Must also support $moreparam
$out = $form->selectDate($value, $keyprefix.$key.$keysuffix, $showtime, $showtime, $required, '', 1, (($keyprefix != 'search_' && $keyprefix != 'search_options_') ? 1 : 0), 0, 1, '', '', '', 1, '', '', 'tzuserrel');
}
} elseif (in_array($type, array('int', 'integer'))) {
$tmp = explode(',', $size);
$newsize = $tmp[0];
$out = '<input type="text" class="flat '.$morecss.' maxwidthonsmartphone" name="'.$keyprefix.$key.$keysuffix.'" id="'.$keyprefix.$key.$keysuffix.'" maxlength="'.$newsize.'" value="'.dol_escape_htmltag($value).'"'.($moreparam ? $moreparam : '').'>';
@ -1611,10 +1635,10 @@ class ExtraFields
$showsize = 0;
if ($type == 'date') {
$showsize = 10;
$value = dol_print_date($value, 'day');
$value = dol_print_date($value, 'day'); // For date without hour, date is always GMT for storage and output
} elseif ($type == 'datetime') {
$showsize = 19;
$value = dol_print_date($value, 'dayhour');
$value = dol_print_date($value, 'dayhour', 'tzuserrel');
} elseif ($type == 'int') {
$showsize = 10;
} elseif ($type == 'double') {
@ -2064,12 +2088,10 @@ class ExtraFields
if (in_array($key_type, array('date'))) {
// Clean parameters
// TODO GMT date in memory must be GMT so we should add gm=true in parameters
$value_key = dol_mktime(0, 0, 0, $_POST["options_".$key."month"], $_POST["options_".$key."day"], $_POST["options_".$key."year"]);
$value_key = dol_mktime(12, 0, 0, GETPOST("options_".$key."month", 'int'), GETPOST("options_".$key."day", 'int'), GETPOST("options_".$key."year", 'int'));
} elseif (in_array($key_type, array('datetime'))) {
// Clean parameters
// TODO GMT date in memory must be GMT so we should add gm=true in parameters
$value_key = dol_mktime($_POST["options_".$key."hour"], $_POST["options_".$key."min"], 0, $_POST["options_".$key."month"], $_POST["options_".$key."day"], $_POST["options_".$key."year"]);
$value_key = dol_mktime(GETPOST("options_".$key."hour", 'int'), GETPOST("options_".$key."min", 'int'), GETPOST("options_".$key."sec", 'int'), GETPOST("options_".$key."month", 'int'), GETPOST("options_".$key."day", 'int'), GETPOST("options_".$key."year", 'int'), 'tzuserrel');
} elseif (in_array($key_type, array('checkbox', 'chkbxlst'))) {
$value_arr = GETPOST("options_".$key, 'array'); // check if an array
if (!empty($value_arr)) {
@ -2134,32 +2156,33 @@ class ExtraFields
$key_type = $this->attributes[$extrafieldsobjectkey]['type'][$key];
}
if (in_array($key_type, array('date', 'datetime'))) {
if (in_array($key_type, array('date'))) {
$dateparamname_start = $keysuffix . 'options_' . $key . $keyprefix . '_start';
$dateparamname_end = $keysuffix . 'options_' . $key . $keyprefix . '_end';
if (GETPOSTISSET($dateparamname_start . 'year') && GETPOSTISSET($dateparamname_end . 'year')) {
// values provided as a date pair (start date + end date), each date being broken down as year, month, day, etc.
$value_key = array(
'start' => dol_mktime(
0,
0,
0,
GETPOST($dateparamname_start . 'month', 'int'),
GETPOST($dateparamname_start . 'day', 'int'),
GETPOST($dateparamname_start . 'year', 'int')
),
'end' => dol_mktime(
23,
59,
59,
GETPOST($dateparamname_end . 'month', 'int'),
GETPOST($dateparamname_end . 'day', 'int'),
GETPOST($dateparamname_end . 'year', 'int')
)
'start' => dol_mktime(0, 0, 0, GETPOST($dateparamname_start . 'month', 'int'), GETPOST($dateparamname_start . 'day', 'int'), GETPOST($dateparamname_start . 'year', 'int')),
'end' => dol_mktime(23, 59, 59, GETPOST($dateparamname_end . 'month', 'int'), GETPOST($dateparamname_end . 'day', 'int'), GETPOST($dateparamname_end . 'year', 'int'))
);
} elseif (GETPOSTISSET($keysuffix."options_".$key.$keyprefix."year")) {
// Clean parameters
$value_key = dol_mktime(GETPOST($keysuffix."options_".$key.$keyprefix."hour", 'int'), GETPOST($keysuffix."options_".$key.$keyprefix."min", 'int'), 0, GETPOST($keysuffix."options_".$key.$keyprefix."month", 'int'), GETPOST($keysuffix."options_".$key.$keyprefix."day", 'int'), GETPOST($keysuffix."options_".$key.$keyprefix."year", 'int'));
$value_key = dol_mktime(12, 0, 0, GETPOST($keysuffix."options_".$key.$keyprefix."month", 'int'), GETPOST($keysuffix."options_".$key.$keyprefix."day", 'int'), GETPOST($keysuffix."options_".$key.$keyprefix."year", 'int'));
} else {
continue; // Value was not provided, we should not set it.
}
} elseif (in_array($key_type, array('datetime'))) {
$dateparamname_start = $keysuffix . 'options_' . $key . $keyprefix . '_start';
$dateparamname_end = $keysuffix . 'options_' . $key . $keyprefix . '_end';
if (GETPOSTISSET($dateparamname_start . 'year') && GETPOSTISSET($dateparamname_end . 'year')) {
// values provided as a date pair (start date + end date), each date being broken down as year, month, day, etc.
$value_key = array(
'start' => dol_mktime(GETPOST($dateparamname_start . 'hour', 'int'), GETPOST($dateparamname_start . 'min', 'int'), GETPOST($dateparamname_start . 'sec', 'int'), GETPOST($dateparamname_start . 'month', 'int'), GETPOST($dateparamname_start . 'day', 'int'), GETPOST($dateparamname_start . 'year', 'int'), 'tzuserrel'),
'end' => dol_mktime(GETPOST($dateparamname_end . 'hour', 'int'), GETPOST($dateparamname_start . 'min', 'int'), GETPOST($dateparamname_start . 'sec', 'int'), GETPOST($dateparamname_end . 'month', 'int'), GETPOST($dateparamname_end . 'day', 'int'), GETPOST($dateparamname_end . 'year', 'int'), 'tzuserrel')
);
} elseif (GETPOSTISSET($keysuffix."options_".$key.$keyprefix."year")) {
// Clean parameters
$value_key = dol_mktime(GETPOST($keysuffix."options_".$key.$keyprefix."hour", 'int'), GETPOST($keysuffix."options_".$key.$keyprefix."min", 'int'), GETPOST($keysuffix."options_".$key.$keyprefix."sec", 'int'), GETPOST($keysuffix."options_".$key.$keyprefix."month", 'int'), GETPOST($keysuffix."options_".$key.$keyprefix."day", 'int'), GETPOST($keysuffix."options_".$key.$keyprefix."year", 'int'), 'tzuserrel');
} else {
continue; // Value was not provided, we should not set it.
}

View File

@ -2,6 +2,7 @@
/* Copyright (C) 2013-2015 Jean-François FERRY <hello@librethic.io>
* Copyright (C) 2016 Christophe Battarel <christophe@altairis.fr>
* Copyright (C) 2019 Frédéric France <frederic.france@netlogic.fr>
* Copyright (C) 2021 Juanjo Menent <jmenent@2byte.es>
*
* 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
@ -517,7 +518,7 @@ class FormTicket
print ' selected="selected"';
} elseif ($selected == $id) {
print ' selected="selected"';
} elseif ($arraytypes['use_default'] == "1" && !$empty) {
} elseif ($arraytypes['use_default'] == "1" && !$selected && !$empty) {
print ' selected="selected"';
}
@ -612,7 +613,7 @@ class FormTicket
print ' selected="selected"';
} elseif ($selected == $id) {
print ' selected="selected"';
} elseif ($arraycategories['use_default'] == "1" && !$empty) {
} elseif ($arraycategories['use_default'] == "1" && !$selected && !$empty) {
print ' selected="selected"';
}
@ -713,7 +714,7 @@ class FormTicket
print ' selected="selected"';
} elseif ($selected == $id) {
print ' selected="selected"';
} elseif ($arrayseverities['use_default'] == "1" && !$empty) {
} elseif ($arrayseverities['use_default'] == "1" && !$selected && !$empty) {
print ' selected="selected"';
}

View File

@ -139,6 +139,7 @@ class Ldap
$this->groups = $conf->global->LDAP_GROUP_DN;
$this->filter = $conf->global->LDAP_FILTER_CONNECTION; // Filter on user
$this->filtergroup = $conf->global->LDAP_GROUP_FILTER; // Filter on groups
$this->filtermember = $conf->global->LDAP_MEMBER_FILTER; // Filter on member
// Users
@ -935,7 +936,7 @@ class Ldap
* @param string $userDn DN (Ex: ou=adherents,ou=people,dc=parinux,dc=org)
* @param string $useridentifier Name of key field (Ex: uid)
* @param array $attributeArray Array of fields required. Note this array must also contains field $useridentifier (Ex: sn,userPassword)
* @param int $activefilter '1' or 'user'=use field this->filter as filter instead of parameter $search, 'member'=use field this->filtermember as filter
* @param int $activefilter '1' or 'user'=use field this->filter as filter instead of parameter $search, 'group'=use field this->filtergroup as filter, 'member'=use field this->filtermember as filter
* @param array $attributeAsArray Array of fields wanted as an array not a string
* @return array Array of [id_record][ldap_field]=value
*/
@ -955,6 +956,8 @@ class Ldap
if (!empty($activefilter)) {
if (((string) $activefilter == '1' || (string) $activefilter == 'user') && $this->filter) {
$filter = '('.$this->filter.')';
} elseif (((string) $activefilter == 'group') && $this->filtergroup ) {
$filter = '('.$this->filtergroup.')';
} elseif (((string) $activefilter == 'member') && $this->filter) {
$filter = '('.$this->filtermember.')';
} else {

View File

@ -546,24 +546,28 @@ function dol_get_last_day($year, $month = 12, $gm = false)
* Return GMT time for last hour of a given GMT date (it replaces hours, min and second part to 23:59:59)
*
* @param int $date Date GMT
* @param mixed $gm False or 0 or 'tzserver' = Return date to compare with server TZ,
* True or 1 or 'gmt' to compare with GMT date.
* @return int Date for last hour of a given date
*/
function dol_get_last_hour($date)
function dol_get_last_hour($date, $gm = 'tzserver')
{
$tmparray = dol_getdate($date);
return dol_mktime(23, 59, 59, $tmparray['mon'], $tmparray['mday'], $tmparray['year'], false);
return dol_mktime(23, 59, 59, $tmparray['mon'], $tmparray['mday'], $tmparray['year'], $gm);
}
/**
* Return GMT time for first hour of a given GMT date (it removes hours, min and second part)
*
* @param int $date Date
* @param int $date Date GMT
* @param mixed $gm False or 0 or 'tzserver' = Return date to compare with server TZ,
* True or 1 or 'gmt' to compare with GMT date.
* @return int Date for last hour of a given date
*/
function dol_get_first_hour($date)
function dol_get_first_hour($date, $gm = 'tzserver')
{
$tmparray = dol_getdate($date);
return dol_mktime(0, 0, 0, $tmparray['mon'], $tmparray['mday'], $tmparray['year'], false);
return dol_mktime(0, 0, 0, $tmparray['mon'], $tmparray['mday'], $tmparray['year'], $gm);
}
/** Return first day of week for a date. First day of week may be monday if option MAIN_START_WEEK is 1.

View File

@ -4277,7 +4277,7 @@ function img_searchclear($titlealt = 'default', $other = '')
* @param string $text Text info
* @param integer $infoonimgalt Info is shown only on alt of star picto, otherwise it is show on output after the star picto
* @param int $nodiv No div
* @param string $admin '1'=Info for admin users. '0'=Info for standard users (change only the look), 'error','xxx'=Other
* @param string $admin '1'=Info for admin users. '0'=Info for standard users (change only the look), 'error', 'warning', 'xxx'=Other
* @param string $morecss More CSS ('', 'warning', 'error')
* @param string $textfordropdown Show a text to click to dropdown the info box.
* @return string String with info text

View File

@ -282,12 +282,10 @@ function show_ticket_messaging($conf, $langs, $db, $filterobj, $objcon = '', $no
dol_print_error('', 'BadParameter');
}
$out = '';
$histo = array();
$numaction = 0;
$now = dol_now();
// Open DSI -- Fix order by -- Begin
$sortfield_list = explode(',', $sortfield);
$sortfield_label_list = array('a.id' => 'id', 'a.datep' => 'dp', 'a.percent' => 'percent');
$sortfield_new_list = array();
@ -297,7 +295,7 @@ function show_ticket_messaging($conf, $langs, $db, $filterobj, $objcon = '', $no
$sortfield_new = implode(',', $sortfield_new_list);
if (!empty($conf->agenda->enabled)) {
// Recherche histo sur actioncomm
// Search histo on actioncomm
if (is_object($objcon) && $objcon->id > 0) {
$sql = "SELECT DISTINCT a.id, a.label as label,";
} else {
@ -464,87 +462,97 @@ function show_ticket_messaging($conf, $langs, $db, $filterobj, $objcon = '', $no
$sql = $sql2;
}
//TODO Add limit in nb of results
$sql .= $db->order($sortfield_new, $sortorder);
// TODO Add limit in nb of results
if ($sql) { // May not be defined if module Agenda is not enabled and mailing module disabled too
$sql .= $db->order($sortfield_new, $sortorder);
dol_syslog("company.lib::show_actions_done", LOG_DEBUG);
$resql = $db->query($sql);
if ($resql) {
$i = 0;
$num = $db->num_rows($resql);
dol_syslog("company.lib::show_actions_done", LOG_DEBUG);
$resql = $db->query($sql);
if ($resql) {
$i = 0;
$num = $db->num_rows($resql);
while ($i < $num) {
$obj = $db->fetch_object($resql);
while ($i < $num) {
$obj = $db->fetch_object($resql);
if ($obj->type == 'action') {
$contactaction = new ActionComm($db);
$contactaction->id = $obj->id;
$result = $contactaction->fetchResources();
if ($result < 0) {
dol_print_error($db);
setEventMessage("company.lib::show_actions_done Error fetch ressource", 'errors');
if ($obj->type == 'action') {
$contactaction = new ActionComm($db);
$contactaction->id = $obj->id;
$result = $contactaction->fetchResources();
if ($result < 0) {
dol_print_error($db);
setEventMessage("company.lib::show_actions_done Error fetch ressource", 'errors');
}
//if ($donetodo == 'todo') $sql.= " AND ((a.percent >= 0 AND a.percent < 100) OR (a.percent = -1 AND a.datep > '".$db->idate($now)."'))";
//elseif ($donetodo == 'done') $sql.= " AND (a.percent = 100 OR (a.percent = -1 AND a.datep <= '".$db->idate($now)."'))";
$tododone = '';
if (($obj->percent >= 0 and $obj->percent < 100) || ($obj->percent == -1 && $obj->datep > $now)) {
$tododone = 'todo';
}
$histo[$numaction] = array(
'type'=>$obj->type,
'tododone'=>$tododone,
'id'=>$obj->id,
'datestart'=>$db->jdate($obj->dp),
'dateend'=>$db->jdate($obj->dp2),
'note'=>$obj->label,
'message'=>$obj->message,
'percent'=>$obj->percent,
'userid'=>$obj->user_id,
'login'=>$obj->user_login,
'userfirstname'=>$obj->user_firstname,
'userlastname'=>$obj->user_lastname,
'userphoto'=>$obj->user_photo,
'contact_id'=>$obj->fk_contact,
'socpeopleassigned' => $contactaction->socpeopleassigned,
'lastname'=>$obj->lastname,
'firstname'=>$obj->firstname,
'fk_element'=>$obj->fk_element,
'elementtype'=>$obj->elementtype,
// Type of event
'acode'=>$obj->acode,
'alabel'=>$obj->alabel,
'libelle'=>$obj->alabel, // deprecated
'apicto'=>$obj->apicto
);
} else {
$histo[$numaction] = array(
'type'=>$obj->type,
'tododone'=>'done',
'id'=>$obj->id,
'datestart'=>$db->jdate($obj->dp),
'dateend'=>$db->jdate($obj->dp2),
'note'=>$obj->label,
'message'=>$obj->message,
'percent'=>$obj->percent,
'acode'=>$obj->acode,
'userid'=>$obj->user_id,
'login'=>$obj->user_login,
'userfirstname'=>$obj->user_firstname,
'userlastname'=>$obj->user_lastname,
'userphoto'=>$obj->user_photo
);
}
//if ($donetodo == 'todo') $sql.= " AND ((a.percent >= 0 AND a.percent < 100) OR (a.percent = -1 AND a.datep > '".$db->idate($now)."'))";
//elseif ($donetodo == 'done') $sql.= " AND (a.percent = 100 OR (a.percent = -1 AND a.datep <= '".$db->idate($now)."'))";
$tododone = '';
if (($obj->percent >= 0 and $obj->percent < 100) || ($obj->percent == -1 && $obj->datep > $now)) {
$tododone = 'todo';
}
$histo[$numaction] = array(
'type'=>$obj->type,
'tododone'=>$tododone,
'id'=>$obj->id,
'datestart'=>$db->jdate($obj->dp),
'dateend'=>$db->jdate($obj->dp2),
'note'=>$obj->label,
'message'=>$obj->message,
'percent'=>$obj->percent,
'userid'=>$obj->user_id,
'login'=>$obj->user_login,
'userfirstname'=>$obj->user_firstname,
'userlastname'=>$obj->user_lastname,
'userphoto'=>$obj->user_photo,
'contact_id'=>$obj->fk_contact,
'socpeopleassigned' => $contactaction->socpeopleassigned,
'lastname'=>$obj->lastname,
'firstname'=>$obj->firstname,
'fk_element'=>$obj->fk_element,
'elementtype'=>$obj->elementtype,
// Type of event
'acode'=>$obj->acode,
'alabel'=>$obj->alabel,
'libelle'=>$obj->alabel, // deprecated
'apicto'=>$obj->apicto
);
} else {
$histo[$numaction] = array(
'type'=>$obj->type,
'tododone'=>'done',
'id'=>$obj->id,
'datestart'=>$db->jdate($obj->dp),
'dateend'=>$db->jdate($obj->dp2),
'note'=>$obj->label,
'message'=>$obj->message,
'percent'=>$obj->percent,
'acode'=>$obj->acode,
'userid'=>$obj->user_id,
'login'=>$obj->user_login,
'userfirstname'=>$obj->user_firstname,
'userlastname'=>$obj->user_lastname,
'userphoto'=>$obj->user_photo
);
$numaction++;
$i++;
}
$numaction++;
$i++;
} else {
dol_print_error($db);
}
} else {
dol_print_error($db);
}
// Set $out to sow events
$out = '';
if (empty($conf->agenda->enabled)) {
$langs->loadLangs(array("admin", "errors"));
$out = info_admin($langs->trans("WarningModuleXDisabledSoYouMayMissEventHere", $langs->transnoentitiesnoconv("Module2400Name")), 0, 0, 'warning');
}
if (!empty($conf->agenda->enabled) || (!empty($conf->mailing->enabled) && !empty($objcon->email))) {

View File

@ -449,7 +449,7 @@ class doc_generic_shipment_odt extends ModelePdfExpedition
}
// Replace tags of object + external modules
$tmparray = $this->get_substitutionarray_shipment($object, $outputlangs);
$tmparray = array_merge($tmparray, $this->get_substitutionarray_shipment($object, $outputlangs));
complete_substitutions_array($tmparray, $outputlangs, $object);
// Call the ODTSubstitution hook

View File

@ -161,6 +161,7 @@ class MailingTargets // This can't be abstract as it is used for some method
public function addTargetsToDatabase($mailing_id, $cibles)
{
global $conf;
global $dolibarr_main_instance_unique_id;
$this->db->begin();
@ -183,7 +184,7 @@ class MailingTargets // This can't be abstract as it is used for some method
$sql .= "'".$this->db->escape($targetarray['other'])."',";
$sql .= "'".$this->db->escape($targetarray['source_url'])."',";
$sql .= (empty($targetarray['source_id']) ? 'null' : "'".$this->db->escape($targetarray['source_id'])."'").",";
$sql .= "'".$this->db->escape(dol_hash($targetarray['email'].';'.$targetarray['lastname'].';'.$mailing_id.';'.$conf->global->MAILING_EMAIL_UNSUBSCRIBE_KEY))."',";
$sql .= "'".$this->db->escape(dol_hash($dolibarr_main_instance_unique_id.';'.$targetarray['email'].';'.$targetarray['lastname'].';'.$mailing_id.';'.$conf->global->MAILING_EMAIL_UNSUBSCRIBE_KEY), 'md5')."',";
$sql .= "'".$this->db->escape($targetarray['source_type'])."')";
dol_syslog(__METHOD__, LOG_DEBUG);
$result = $this->db->query($sql);

View File

@ -85,6 +85,7 @@ class modLdap extends DolibarrModules
11=>array('LDAP_FIELD_PHONE', 'chaine', 'telephonenumber', '', 0),
12=>array('LDAP_FIELD_FAX', 'chaine', 'facsimiletelephonenumber', '', 0),
13=>array('LDAP_FIELD_MOBILE', 'chaine', 'mobile', '', 0),
14=>array('LDAP_GROUP_FILTER', 'chaine', '&(objectClass=groupOfNames)', '', 0),
);
// Boxes

View File

@ -587,7 +587,7 @@ class modProduct extends DolibarrModules
));
$this->import_regex_array[$r] = array_merge($this->import_regex_array[$r], array(
'p.tobatch' => '^[0|1]$'
'p.tobatch' => '^[0|1|2]$'
));
$this->import_convertvalue_array[$r] = array_merge($this->import_convertvalue_array[$r], array(
@ -679,7 +679,7 @@ class modProduct extends DolibarrModules
//clauses copied from import_fields_array
if (!empty($conf->stock->enabled)) {
$import_sample = array_merge($import_sample, array(
'p.tobatch'=>"0 (don't use) / 1 (use batch/serial number)",
'p.tobatch'=>"0 (don't use) / 1 (use batch) / 2 (use serial number)",
'p.seuil_stock_alerte' => '',
'p.pmp' => '0',
'p.desiredstock' => ''

View File

@ -201,14 +201,23 @@ if (empty($reshook) && is_array($extrafields->attributes[$object->table_element]
print '<td id="'.$html_id.'" class="valuefield '.$object->element.'_extras_'.$tmpkeyextra.' wordbreak"'.(!empty($cols) ? ' colspan="'.$cols.'"' : '').'>';
// Convert date into timestamp format
if (in_array($extrafields->attributes[$object->table_element]['type'][$tmpkeyextra], array('date', 'datetime'))) {
if (in_array($extrafields->attributes[$object->table_element]['type'][$tmpkeyextra], array('date'))) {
$datenotinstring = $object->array_options['options_'.$tmpkeyextra];
// print 'X'.$object->array_options['options_' . $tmpkeyextra].'-'.$datenotinstring.'x';
if (!is_numeric($object->array_options['options_'.$tmpkeyextra])) { // For backward compatibility
$datenotinstring = $db->jdate($datenotinstring);
}
//print 'x'.$object->array_options['options_' . $tmpkeyextra].'-'.$datenotinstring.' - '.dol_print_date($datenotinstring, 'dayhour');
$value = GETPOSTISSET("options_".$tmpkeyextra) ? dol_mktime(GETPOST("options_".$tmpkeyextra."hour", 'int'), GETPOST("options_".$tmpkeyextra."min", 'int'), 0, GETPOST("options_".$tmpkeyextra."month", 'int'), GETPOST("options_".$tmpkeyextra."day", 'int'), GETPOST("options_".$tmpkeyextra."year", 'int')) : $datenotinstring;
$value = GETPOSTISSET("options_".$tmpkeyextra) ? dol_mktime(12, 0, 0, GETPOST("options_".$tmpkeyextra."month", 'int'), GETPOST("options_".$tmpkeyextra."day", 'int'), GETPOST("options_".$tmpkeyextra."year", 'int')) : $datenotinstring;
}
if (in_array($extrafields->attributes[$object->table_element]['type'][$tmpkeyextra], array('datetime'))) {
$datenotinstring = $object->array_options['options_'.$tmpkeyextra];
// print 'X'.$object->array_options['options_' . $tmpkeyextra].'-'.$datenotinstring.'x';
if (!is_numeric($object->array_options['options_'.$tmpkeyextra])) { // For backward compatibility
$datenotinstring = $db->jdate($datenotinstring);
}
//print 'x'.$object->array_options['options_' . $tmpkeyextra].'-'.$datenotinstring.' - '.dol_print_date($datenotinstring, 'dayhour');
$value = GETPOSTISSET("options_".$tmpkeyextra) ? dol_mktime(GETPOST("options_".$tmpkeyextra."hour", 'int'), GETPOST("options_".$tmpkeyextra."min", 'int'), GETPOST("options_".$tmpkeyextra."sec", 'int'), GETPOST("options_".$tmpkeyextra."month", 'int'), GETPOST("options_".$tmpkeyextra."day", 'int'), GETPOST("options_".$tmpkeyextra."year", 'int'), 'tzuserrel') : $datenotinstring;
}
//TODO Improve element and rights detection

View File

@ -104,10 +104,12 @@ if (($line->info_bits & 2) == 2) {
print '</a>';
if ($line->description) {
if ($line->description == '(CREDIT_NOTE)' && $line->fk_remise_except > 0) {
include_once DOL_DOCUMENT_ROOT.'/core/class/discount.class.php';
$discount = new DiscountAbsolute($this->db);
$discount->fetch($line->fk_remise_except);
print ($txt ? ' - ' : '').$langs->transnoentities("DiscountFromCreditNote", $discount->getNomUrl(0));
} elseif ($line->description == '(DEPOSIT)' && $line->fk_remise_except > 0) {
} elseif ($line->description == '(DEPOSIT)' && $line->fk_remise_except > 0) {
include_once DOL_DOCUMENT_ROOT.'/core/class/discount.class.php';
$discount = new DiscountAbsolute($this->db);
$discount->fetch($line->fk_remise_except);
print ($txt ? ' - ' : '').$langs->transnoentities("DiscountFromDeposit", $discount->getNomUrl(0));
@ -115,11 +117,13 @@ if (($line->info_bits & 2) == 2) {
if (!empty($conf->global->INVOICE_ADD_DEPOSIT_DATE)) {
print ' ('.dol_print_date($discount->datec).')';
}
} elseif ($line->description == '(EXCESS RECEIVED)' && $objp->fk_remise_except > 0) {
} elseif ($line->description == '(EXCESS RECEIVED)' && $objp->fk_remise_except > 0) {
include_once DOL_DOCUMENT_ROOT.'/core/class/discount.class.php';
$discount = new DiscountAbsolute($this->db);
$discount->fetch($line->fk_remise_except);
print ($txt ? ' - ' : '').$langs->transnoentities("DiscountFromExcessReceived", $discount->getNomUrl(0));
} elseif ($line->description == '(EXCESS PAID)' && $objp->fk_remise_except > 0) {
include_once DOL_DOCUMENT_ROOT.'/core/class/discount.class.php';
$discount = new DiscountAbsolute($this->db);
$discount->fetch($line->fk_remise_except);
print ($txt ? ' - ' : '').$langs->transnoentities("DiscountFromExcessPaid", $discount->getNomUrl(0));

View File

@ -545,13 +545,13 @@ if ($num > 0) {
print '<td class="center">';
if (!empty($obj->datestart)) {
print dol_print_date($db->jdate($obj->datestart), 'dayhour');
print dol_print_date($db->jdate($obj->datestart), 'dayhour', 'tzserver');
}
print '</td>';
print '<td class="center">';
if (!empty($obj->dateend)) {
print dol_print_date($db->jdate($obj->dateend), 'dayhour');
print dol_print_date($db->jdate($obj->dateend), 'dayhour', 'tzserver');
}
print '</td>';
@ -569,7 +569,7 @@ if ($num > 0) {
// Date start last run
print '<td class="center">';
if (!empty($datelastrun)) {
print dol_print_date($datelastrun, 'dayhoursec');
print dol_print_date($datelastrun, 'dayhoursec', 'tzserver');
}
print '</td>';

View File

@ -1009,16 +1009,7 @@ if ($action == 'create') {
$i++;
}
print '});
jQuery("#autoreset").click(function() { console.log("Reset values to 0"); ';
$i = 0;
while ($i < $numAsked) {
print 'jQuery("#qtyl'.$i.'").val(0);'."\n";
if (!empty($conf->productbatch->enabled)) {
print 'jQuery("#qtyl'.$i.'_'.$i.'").val(0);'."\n";
}
$i++;
}
print '});
jQuery("#autoreset").click(function() { console.log("Reset values to 0"); jQuery(".qtyl").val(0); });
});
</script>';
@ -1252,7 +1243,7 @@ if ($action == 'create') {
$deliverableQty = min($quantityToBeDelivered, $batchStock);
print '<!-- subj='.$subj.'/'.$nbofsuggested.' --><tr '.((($subj + 1) == $nbofsuggested) ? $bc[$var] : '').'>';
print '<td colspan="3" ></td><td class="center">';
print '<input name="qtyl'.$indiceAsked.'_'.$subj.'" id="qtyl'.$indiceAsked.'_'.$subj.'" type="text" size="4" value="'.$deliverableQty.'">';
print '<input class="qtyl" name="qtyl'.$indiceAsked.'_'.$subj.'" id="qtyl'.$indiceAsked.'_'.$subj.'" type="text" size="4" value="'.$deliverableQty.'">';
print '</td>';
print '<!-- Show details of lot -->';
@ -1284,7 +1275,7 @@ if ($action == 'create') {
} else {
print '<!-- Case there is no details of lot at all -->';
print '<tr class="oddeven"><td colspan="3"></td><td class="center">';
print '<input name="qtyl'.$indiceAsked.'_'.$subj.'" id="qtyl'.$indiceAsked.'_'.$subj.'" type="text" size="4" value="0" disabled="disabled"> ';
print '<input class="qtyl" name="qtyl'.$indiceAsked.'_'.$subj.'" id="qtyl'.$indiceAsked.'_'.$subj.'" type="text" size="4" value="0" disabled="disabled"> ';
print '</td>';
print '<td class="left">';
@ -1395,7 +1386,7 @@ if ($action == 'create') {
$deliverableQty = 0;
}
print '<!-- subj='.$subj.'/'.$nbofsuggested.' --><tr '.((($subj + 1) == $nbofsuggested) ? $bc[$var] : '').'><td colspan="3"></td><td class="center">';
print '<input name="qtyl'.$indiceAsked.'_'.$subj.'" id="qtyl'.$indiceAsked.'_'.$subj.'" type="text" size="4" value="'.$deliverableQty.'">';
print '<input class="qtyl" name="qtyl'.$indiceAsked.'_'.$subj.'" id="qtyl'.$indiceAsked.'_'.$subj.'" type="text" size="4" value="'.$deliverableQty.'">';
print '</td>';
print '<td class="left">';
@ -1439,7 +1430,7 @@ if ($action == 'create') {
if ($warehouse_selected_id <= 0) { // We did not force a given warehouse, so we won't have no warehouse to change qty.
$disabled = 'disabled="disabled"';
}
print '<input name="qtyl'.$indiceAsked.'_'.$subj.'" id="qtyl'.$indiceAsked.'_'.$subj.'" type="text" size="4" value="0"'.($disabled ? ' '.$disabled : '').'> ';
print '<input class="qtyl" name="qtyl'.$indiceAsked.'_'.$subj.'" id="qtyl'.$indiceAsked.'_'.$subj.'" type="text" size="4" value="0"'.($disabled ? ' '.$disabled : '').'> ';
} else {
print $langs->trans("NA");
}
@ -2141,7 +2132,7 @@ if ($action == 'create') {
foreach ($lines[$i]->detail_batch as $detail_batch) {
print '<tr>';
// Qty to ship or shipped
print '<td><input name="qtyl'.$detail_batch->fk_expeditiondet.'_'.$detail_batch->id.'" id="qtyl'.$line_id.'_'.$detail_batch->id.'" type="text" size="4" value="'.$detail_batch->qty.'"></td>';
print '<td><input class="qtyl" name="qtyl'.$detail_batch->fk_expeditiondet.'_'.$detail_batch->id.'" id="qtyl'.$line_id.'_'.$detail_batch->id.'" type="text" size="4" value="'.$detail_batch->qty.'"></td>';
// Batch number managment
if ($lines[$i]->entrepot_id == 0) {
// only show lot numbers from src warehouse when shipping from multiple warehouses
@ -2153,7 +2144,7 @@ if ($action == 'create') {
// add a 0 qty lot row to be able to add a lot
print '<tr>';
// Qty to ship or shipped
print '<td><input name="qtyl'.$line_id.'_0" id="qtyl'.$line_id.'_0" type="text" size="4" value="0"></td>';
print '<td><input class="qtyl" name="qtyl'.$line_id.'_0" id="qtyl'.$line_id.'_0" type="text" size="4" value="0"></td>';
// Batch number managment
print '<td>'.$formproduct->selectLotStock('', 'batchl'.$line_id.'_0', '', 1, 0, $lines[$i]->fk_product).'</td>';
print '</tr>';
@ -2163,7 +2154,7 @@ if ($action == 'create') {
print '<!-- case edit 2 -->';
print '<tr>';
// Qty to ship or shipped
print '<td><input name="qtyl'.$line_id.'" id="qtyl'.$line_id.'" type="text" size="4" value="'.$lines[$i]->qty_shipped.'"></td>';
print '<td><input class="qtyl" name="qtyl'.$line_id.'" id="qtyl'.$line_id.'" type="text" size="4" value="'.$lines[$i]->qty_shipped.'"></td>';
// Warehouse source
print '<td>'.$formproduct->selectWarehouses($lines[$i]->entrepot_id, 'entl'.$line_id, '', 1, 0, $lines[$i]->fk_product, '', 1).'</td>';
// Batch number managment
@ -2174,7 +2165,7 @@ if ($action == 'create') {
foreach ($lines[$i]->details_entrepot as $detail_entrepot) {
print '<tr>';
// Qty to ship or shipped
print '<td><input name="qtyl'.$detail_entrepot->line_id.'" id="qtyl'.$detail_entrepot->line_id.'" type="text" size="4" value="'.$detail_entrepot->qty_shipped.'"></td>';
print '<td><input class="qtyl" name="qtyl'.$detail_entrepot->line_id.'" id="qtyl'.$detail_entrepot->line_id.'" type="text" size="4" value="'.$detail_entrepot->qty_shipped.'"></td>';
// Warehouse source
print '<td>'.$formproduct->selectWarehouses($detail_entrepot->entrepot_id, 'entl'.$detail_entrepot->line_id, '', 1, 0, $lines[$i]->fk_product, '', 1).'</td>';
// Batch number managment
@ -2189,7 +2180,7 @@ if ($action == 'create') {
print '<!-- case edit 5 -->';
print '<tr>';
// Qty to ship or shipped
print '<td><input name="qtyl'.$line_id.'" id="qtyl'.$line_id.'" type="text" size="4" value="'.$lines[$i]->qty_shipped.'"></td>';
print '<td><input class="qtyl" name="qtyl'.$line_id.'" id="qtyl'.$line_id.'" type="text" size="4" value="'.$lines[$i]->qty_shipped.'"></td>';
// Warehouse source
print '<td></td>';
// Batch number managment

View File

@ -855,7 +855,7 @@ if ($id > 0 || !empty($ref)) {
// Already dispatched
print '<td class="right">'.$products_dispatched[$objp->rowid].'</td>';
if (!empty($conf->productbatch->enabled) && $objp->tobatch == 1) {
if (!empty($conf->productbatch->enabled) && $objp->tobatch > 0) {
$type = 'batch';
print '<td class="right">';
print '</td>'; // Qty to dispatch
@ -967,7 +967,7 @@ if ($id > 0 || !empty($ref)) {
print '</td>';
print '<td>';
if (!empty($conf->productbatch->enabled) && $objp->tobatch == 1) {
if (!empty($conf->productbatch->enabled) && $objp->tobatch > 0) {
$type = 'batch';
print img_picto($langs->trans('AddStockLocationLine'), 'split.png', 'class="splitbutton" onClick="addDispatchLine('.$i.', \''.$type.'\')"');
} else {

View File

@ -178,3 +178,6 @@ INSERT INTO llx_accounting_system (fk_country, pcg_version, label, active) VALUE
-- Description of chart of account Canada CA-ENG-BASE
INSERT INTO llx_accounting_system (fk_country, pcg_version, label, active) VALUES ( 14, 'CA-ENG-BASE', 'Canadian basic chart of accounts - English', 1);
-- Description of chart of account Mexico SAT/24-2019
INSERT INTO llx_accounting_system (fk_country, pcg_version, label, active) VALUES ( 154, 'SAT/24-2019', 'Catalogo y codigo agrupador fiscal del 2019', 1);

File diff suppressed because it is too large Load Diff

View File

@ -48,6 +48,10 @@ UPDATE llx_c_country SET eec = 1 WHERE code IN ('AT','BE','BG','CY','CZ','DE','D
-- For v14
ALTER TABLE llx_mailing_cibles MODIFY COLUMN tag varchar(64) NULL;
ALTER TABLE llx_mailing_cibles ADD INDEX idx_mailing_cibles_tag (tag);
ALTER TABLE llx_c_availability ADD COLUMN position integer NOT NULL DEFAULT 0;
ALTER TABLE llx_adherent ADD COLUMN ref varchar(30) AFTER rowid;
@ -167,7 +171,7 @@ create table llx_payment_vat
ALTER TABLE llx_tva ADD COLUMN paye smallint default 1 NOT NULL;
ALTER TABLE llx_tva ADD COLUMN fk_account integer;
--INSERT INTO llx_payment_vat (fk_tva, datec, datep, amount, fk_typepaiement, num_paiement, note, fk_bank, fk_user_creat, fk_user_modif) SELECT rowid, NOW(), datep, amount, COALESCE(fk_typepayment, 0), num_payment, '', fk_bank, fk_user_creat, fk_user_modif FROM llx_tva;
INSERT INTO llx_payment_vat (rowid, fk_tva, datec, datep, amount, fk_typepaiement, num_paiement, note, fk_bank, fk_user_creat, fk_user_modif) SELECT rowid, rowid, NOW(), datep, amount, COALESCE(fk_typepayment, 0), num_payment, 'Created automatically by migration v13 to v14', fk_bank, fk_user_creat, fk_user_modif FROM llx_tva WHERE fk_bank IS NOT NULL;
--UPDATE llx_bank_url as url INNER JOIN llx_tva tva ON tva.rowid = url.url_id SET url.type = 'vat', url.label = CONCAT('(', tva.label, ')') WHERE type = 'payment_vat';
--INSERT INTO llx_bank_url (fk_bank, url_id, url, label, type) SELECT b.fk_bank, ptva.rowid, REPLACE(b.url, 'tva/card.php', 'payment_vat/card.php'), '(paiement)', 'payment_vat' FROM llx_bank_url b INNER JOIN llx_tva tva ON (tva.fk_bank = b.fk_bank) INNER JOIN llx_payment_vat ptva on (ptva.fk_bank = b.fk_bank) WHERE type = 'vat';
@ -211,6 +215,13 @@ ALTER TABLE llx_propal CHANGE COLUMN tva total_tva double(24,8) default 0;
ALTER TABLE llx_propal CHANGE COLUMN total total_ttc double(24,8) default 0;
ALTER TABLE llx_commande_fournisseur CHANGE COLUMN tva total_tva double(24,8) default 0;
--VMYSQL4.3 ALTER TABLE llx_c_civility CHANGE COLUMN rowid rowid INTEGER NOT NULL AUTO_INCREMENT;
--VPGSQL8.2 CREATE SEQUENCE llx_c_civility_rowid_seq OWNED BY llx_c_civility.rowid;
--VPGSQL8.2 ALTER TABLE llx_c_civility ALTER COLUMN rowid SET DEFAULT nextval('llx_c_civility_rowid_seq');
--VPGSQL8.2 SELECT setval('llx_c_civility_rowid_seq', MAX(rowid)) FROM llx_c_civility;
-- Change for salary intent table
create table llx_salary
(
@ -235,7 +246,7 @@ create table llx_salary
fk_account integer, -- default bank account for payment
fk_user_author integer, -- user creating
fk_user_modif integer -- user making last change
)ENGINE=innodb;
) ENGINE=innodb;
ALTER TABLE llx_payment_salary CHANGE COLUMN fk_user fk_user integer NULL;
ALTER TABLE llx_payment_salary ADD COLUMN fk_salary integer;

View File

@ -19,7 +19,7 @@
create table llx_c_civility
(
rowid integer PRIMARY KEY,
rowid integer AUTO_INCREMENT PRIMARY KEY NOT NULL
code varchar(6) NOT NULL,
label varchar(50),
active tinyint DEFAULT 1 NOT NULL,

View File

@ -21,3 +21,5 @@ ALTER TABLE llx_mailing_cibles ADD UNIQUE uk_mailing_cibles (fk_mailing, email);
ALTER TABLE llx_mailing_cibles ADD INDEX idx_mailing_cibles_email (email);
ALTER TABLE llx_mailing_cibles ADD INDEX idx_mailing_cibles_tag (tag);

View File

@ -28,7 +28,7 @@ create table llx_mailing_cibles
firstname varchar(160),
email varchar(160) NOT NULL,
other varchar(255) NULL,
tag varchar(128) NULL,
tag varchar(64) NULL, -- a unique key as a hash of: dolibarr_main_instance_unique_id;email;lastname;mailing_id;MAILING_EMAIL_UNSUBSCRIBE_KEY
statut smallint NOT NULL DEFAULT 0, -- -1 = error, 0 = not sent, ...
source_url varchar(255),
source_id integer,

View File

@ -897,7 +897,7 @@ if ($ok && GETPOST('clean_product_stock_batch', 'alpha')) {
$sql = "SELECT p.rowid, p.ref, p.tobatch, ps.rowid as psrowid, ps.fk_entrepot, ps.reel, SUM(pb.qty) as reelbatch";
$sql .= " FROM ".MAIN_DB_PREFIX."product as p, ".MAIN_DB_PREFIX."product_stock as ps LEFT JOIN ".MAIN_DB_PREFIX."product_batch as pb ON ps.rowid = pb.fk_product_stock";
$sql .= " WHERE p.rowid = ps.fk_product";
$sql .= " AND p.tobatch = 1";
$sql .= " AND p.tobatch > 0";
$sql .= " GROUP BY p.rowid, p.ref, p.tobatch, ps.rowid, ps.fk_entrepot, ps.reel";
$sql .= " HAVING reel != SUM(pb.qty) or SUM(pb.qty) IS NULL";
print $sql;
@ -981,7 +981,7 @@ if ($ok && GETPOST('clean_product_stock_negative_if_batch', 'alpha')) {
$sql = "SELECT p.rowid, p.ref, p.tobatch, ps.rowid as psrowid, ps.fk_entrepot, ps.reel, SUM(pb.qty) as reelbatch";
$sql .= " FROM ".MAIN_DB_PREFIX."product as p, ".MAIN_DB_PREFIX."product_stock as ps, ".MAIN_DB_PREFIX."product_batch as pb";
$sql .= " WHERE p.rowid = ps.fk_product AND ps.rowid = pb.fk_product_stock";
$sql .= " AND p.tobatch = 1";
$sql .= " AND p.tobatch > 0";
$sql .= " GROUP BY p.rowid, p.ref, p.tobatch, ps.rowid, ps.fk_entrepot, ps.reel";
$sql .= " HAVING reel != SUM(pb.qty)";
$resql = $db->query($sql);

View File

@ -1512,6 +1512,7 @@ LDAPFieldLoginUnix=Login (unix)
LDAPFieldLoginExample=Example: uid
LDAPFilterConnection=Search filter
LDAPFilterConnectionExample=Example: &(objectClass=inetOrgPerson)
LDAPGroupFilterExample=Example: &(objectClass=groupOfUsers)
LDAPFieldLoginSamba=Login (samba, activedirectory)
LDAPFieldLoginSambaExample=Example: samaccountname
LDAPFieldFullname=Full name

View File

@ -291,4 +291,5 @@ WarningSomeBankTransactionByChequeWereRemovedAfter=Some bank transaction were re
WarningFailedToAddFileIntoDatabaseIndex=Warning, failed to add file entry into ECM database index table
WarningTheHiddenOptionIsOn=Warning, the hidden option <b>%s</b> is on.
WarningCreateSubAccounts=Warning, you can't create directly a sub account, you must create a third party or an user and assign them an accounting code to find them in this list
WarningAvailableOnlyForHTTPSServers=Available only if using HTTPS secured connection.
WarningAvailableOnlyForHTTPSServers=Available only if using HTTPS secured connection.
WarningModuleXDisabledSoYouMayMissEventHere=Module %s has not been enabled. So you may miss a lot of event here.

View File

@ -24,3 +24,5 @@ ProductLotSetup=Setup of module lot/serial
ShowCurrentStockOfLot=Show current stock for couple product/lot
ShowLogOfMovementIfLot=Show log of movements for couple product/lot
StockDetailPerBatch=Stock detail per lot
SerialNumberAlreadyInUse=Serial number %s is already used for product %s
TooManyQtyForSerialNumber=You can only have one product %s for serial number %S

View File

@ -24,3 +24,5 @@ ProductLotSetup=Configuration du module lot/série
ShowCurrentStockOfLot=Afficher le stock actuel pour le couple produit / lot
ShowLogOfMovementIfLot=Afficher l'historique des mouvements de couple produit / lot
StockDetailPerBatch=Stock détaillé par lot
SerialNumberAlreadyInUse=Le numéro de série %s est déjà utilisé pour le produit %s
TooManyQtyForSerialNumber=Vous ne pouvez avoir qu'un produit %s avec le numéro de série %s

View File

@ -96,7 +96,7 @@ class Mo extends CommonObject
'rowid' => array('type'=>'integer', 'label'=>'TechnicalID', 'enabled'=>1, 'visible'=>-1, 'position'=>1, 'notnull'=>1, 'index'=>1, 'comment'=>"Id",),
'entity' => array('type'=>'integer', 'label'=>'Entity', 'enabled'=>1, 'visible'=>0, 'position'=>5, 'notnull'=>1, 'default'=>'1', 'index'=>1),
'ref' => array('type'=>'varchar(128)', 'label'=>'Ref', 'enabled'=>1, 'visible'=>4, 'position'=>10, 'notnull'=>1, 'default'=>'(PROV)', 'index'=>1, 'searchall'=>1, 'comment'=>"Reference of object", 'showoncombobox'=>'1', 'noteditable'=>1),
'fk_bom' => array('type'=>'integer:Bom:bom/class/bom.class.php:0:t.status=1', 'filter'=>'active=1', 'label'=>'BOM', 'enabled'=>1, 'visible'=>1, 'position'=>33, 'notnull'=>-1, 'index'=>1, 'comment'=>"Original BOM", 'css'=>'maxwidth300'),
'fk_bom' => array('type'=>'integer:Bom:bom/class/bom.class.php:0:t.status=1', 'filter'=>'active=1', 'label'=>'BOM', 'enabled'=>1, 'visible'=>1, 'position'=>33, 'notnull'=>-1, 'index'=>1, 'comment'=>"Original BOM", 'css'=>'minwidth100 maxwidth300'),
'fk_product' => array('type'=>'integer:Product:product/class/product.class.php:0', 'label'=>'Product', 'enabled'=>1, 'visible'=>1, 'position'=>35, 'notnull'=>1, 'index'=>1, 'comment'=>"Product to produce", 'css'=>'maxwidth300', 'picto'=>'product'),
'qty' => array('type'=>'real', 'label'=>'QtyToProduce', 'enabled'=>1, 'visible'=>1, 'position'=>40, 'notnull'=>1, 'comment'=>"Qty to produce", 'css'=>'width75', 'default'=>1, 'isameasure'=>1),
'label' => array('type'=>'varchar(255)', 'label'=>'Label', 'enabled'=>1, 'visible'=>1, 'position'=>42, 'notnull'=>-1, 'searchall'=>1, 'showoncombobox'=>'1',),
@ -632,9 +632,21 @@ class Mo extends CommonObject
$moline->fk_mo = $this->id;
$moline->qty = $this->qty;
$moline->fk_product = $this->fk_product;
$moline->role = 'toproduce';
$moline->position = 1;
if ($this->fk_bom > 0) { // If a BOM is defined, we know what to consume.
include_once DOL_DOCUMENT_ROOT.'/bom/class/bom.class.php';
$bom = new Bom($this->db);
$bom->fetch($this->fk_bom);
if ($bom->bomtype == 1) {
$role = 'toproduce';
$moline->role = 'toconsume';
} else {
$role = 'toconsume';
$moline->role = 'toproduce';
}
}
$resultline = $moline->create($user, false); // Never use triggers here
if ($resultline <= 0) {
$error++;
@ -644,9 +656,6 @@ class Mo extends CommonObject
}
if ($this->fk_bom > 0) { // If a BOM is defined, we know what to consume.
include_once DOL_DOCUMENT_ROOT.'/bom/class/bom.class.php';
$bom = new Bom($this->db);
$bom->fetch($this->fk_bom);
if ($bom->id > 0) {
// Lines to consume
if (!$error) {
@ -667,7 +676,7 @@ class Mo extends CommonObject
break;
} else {
$moline->fk_product = $line->fk_product;
$moline->role = 'toconsume';
$moline->role = $role;
$moline->position = $line->position;
$moline->qty_frozen = $line->qty_frozen;
$moline->disable_stock_change = $line->disable_stock_change;

View File

@ -76,7 +76,7 @@ $search_array_options = $extrafields->getOptionalsFromPost($object->table_elemen
// Default sort order (if not yet defined by previous GETPOST)
if (!$sortfield) {
$sortfield = "t.".key($object->fields); // Set here default search field. By default 1st field in definition.
$sortfield = "t.ref"; // Set here default search field. By default 1st field in definition.
}
if (!$sortorder) {
$sortorder = "ASC";

View File

@ -1084,11 +1084,7 @@ if (is_object($objcanvas) && $objcanvas->displayCanvasExists($action)) {
// Batch number management
if (!empty($conf->productbatch->enabled)) {
print '<tr><td>'.$langs->trans("ManageLotSerial").'</td><td colspan="3">';
if (empty($conf->global ->MAIN_ADVANCE_NUMLOT)) {
$statutarray = array('0' => $langs->trans("ProductStatusNotOnBatch"), '1' => $langs->trans("ProductStatusOnBatch"));
} else {
$statutarray = array('0' => $langs->trans("ProductStatusNotOnBatch"), '1' => $langs->trans("ProductStatusOnBatch"), '2' => $langs->trans("ProductStatusOnSerial"));
}
$statutarray = array('0' => $langs->trans("ProductStatusNotOnBatch"), '1' => $langs->trans("ProductStatusOnBatch"), '2' => $langs->trans("ProductStatusOnSerial"));
print $form->selectarray('status_batch', $statutarray, GETPOST('status_batch'));
print '</td></tr>';
}
@ -1548,11 +1544,7 @@ if (is_object($objcanvas) && $objcanvas->displayCanvasExists($action)) {
if ($conf->productbatch->enabled) {
if ($object->isProduct() || !empty($conf->global->STOCK_SUPPORTS_SERVICES)) {
print '<tr><td>'.$langs->trans("ManageLotSerial").'</td><td colspan="3">';
if (empty($conf->global ->MAIN_ADVANCE_NUMLOT)) {
$statutarray = array('0' => $langs->trans("ProductStatusNotOnBatch"), '1' => $langs->trans("ProductStatusOnBatch"));
} else {
$statutarray = array('0' => $langs->trans("ProductStatusNotOnBatch"), '1' => $langs->trans("ProductStatusOnBatch"), '2' => $langs->trans("ProductStatusOnSerial"));
}
$statutarray = array('0' => $langs->trans("ProductStatusNotOnBatch"), '1' => $langs->trans("ProductStatusOnBatch"), '2' => $langs->trans("ProductStatusOnSerial"));
print $form->selectarray('status_batch', $statutarray, $object->status_batch);
print '</td></tr>';
}
@ -2040,11 +2032,7 @@ if (is_object($objcanvas) && $objcanvas->displayCanvasExists($action)) {
if (!empty($conf->productbatch->enabled)) {
if ($object->isProduct() || !empty($conf->global->STOCK_SUPPORTS_SERVICES)) {
print '<tr><td>'.$langs->trans("ManageLotSerial").'</td><td colspan="2">';
if (!empty($conf->use_javascript_ajax) && $usercancreate && !empty($conf->global->MAIN_DIRECT_STATUS_UPDATE) && empty($conf->global->MAIN_ADVANCE_NUMLOT)) {
print ajax_object_onoff($object, 'status_batch', 'tobatch', 'ProductStatusOnBatch', 'ProductStatusNotOnBatch');
} else {
print $object->getLibStatut(0, 2);
}
print $object->getLibStatut(0, 2);
print '</td></tr>';
}
}

View File

@ -4747,10 +4747,10 @@ class Product extends CommonObject
if ($type == 2) {
switch ($mode) {
case 0:
$label = ($status == 0 ? $langs->trans('ProductStatusNotOnBatch') : ($status == 1 || empty($conf->global->MAIN_ADVANCE_NUMLOT) ? $langs->trans('ProductStatusOnBatch') : $langs->trans('ProductStatusOnSerial')));
$label = ($status == 0 ? $langs->trans('ProductStatusNotOnBatch') : ($status == 1 ? $langs->trans('ProductStatusOnBatch') : $langs->trans('ProductStatusOnSerial')));
return dolGetStatus($label);
case 1:
$label = ($status == 0 ? $langs->trans('ProductStatusNotOnBatchShort') : ($status == 1 || empty($conf->global->MAIN_ADVANCE_NUMLOT) ? $langs->trans('ProductStatusOnBatchShort') : $langs->trans('ProductStatusOnSerialShort')));
$label = ($status == 0 ? $langs->trans('ProductStatusNotOnBatchShort') : ($status == 1 ? $langs->trans('ProductStatusOnBatchShort') : $langs->trans('ProductStatusOnSerialShort')));
return dolGetStatus($label);
case 2:
return $this->LibStatut($status, 3, 2).' '.$this->LibStatut($status, 1, 2);
@ -4788,10 +4788,10 @@ class Product extends CommonObject
$labelStatus = $langs->trans('ProductStatusOnBuyShort');
$labelStatusShort = $langs->trans('ProductStatusOnBuy');
} elseif ($type == 2) {
$labelStatus = ($status == 1 || empty($conf->global->MAIN_ADVANCE_NUMLOT) ? $langs->trans('ProductStatusOnBatch') : $langs->trans('ProductStatusOnSerial'));
$labelStatusShort = ($status == 1 || empty($conf->global->MAIN_ADVANCE_NUMLOT) ? $langs->trans('ProductStatusOnBatchShort') : $langs->trans('ProductStatusOnSerialShort'));
$labelStatus = ($status == 1 ? $langs->trans('ProductStatusOnBatch') : $langs->trans('ProductStatusOnSerial'));
$labelStatusShort = ($status == 1 ? $langs->trans('ProductStatusOnBatchShort') : $langs->trans('ProductStatusOnSerialShort'));
}
} elseif (! empty($conf->global->MAIN_ADVANCE_NUMLOT) && $type == 2 && $status == 2) {
} elseif ( $type == 2 && $status == 2 ) {
$labelStatus = $langs->trans('ProductStatusOnSerial');
$labelStatusShort = $langs->trans('ProductStatusOnSerialShort');
}

View File

@ -971,18 +971,13 @@ if ($resql) {
// To batch
if (!empty($arrayfields['p.tobatch']['checked'])) {
print '<td class="liste_titre center">';
if (empty($conf->global ->MAIN_ADVANCE_NUMLOT)) {
print $form->selectyesno('search_tobatch', $search_tobatch, 1, false, 1);
} else {
$statutarray = array(
'-1' => '',
'0' => $langs->trans("ProductStatusNotOnBatchShort"),
'1' => $langs->trans("ProductStatusOnBatchShort"),
'2' => $langs->trans("ProductStatusOnSerialShort")
);
print $form->selectarray('search_tobatch', $statutarray, $search_tobatch);
}
$statutarray = array(
'-1' => '',
'0' => $langs->trans("ProductStatusNotOnBatchShort"),
'1' => $langs->trans("ProductStatusOnBatchShort"),
'2' => $langs->trans("ProductStatusOnSerialShort")
);
print $form->selectarray('search_tobatch', $statutarray, $search_tobatch);
print '</td>';
}
// Country
@ -1672,11 +1667,7 @@ if ($resql) {
// Lot/Serial
if (!empty($arrayfields['p.tobatch']['checked'])) {
print '<td class="center">';
if (empty($conf->global->MAIN_ADVANCE_NUMLOT)) {
print yn($obj->tobatch);
} else {
print $product_static->getLibStatut(1, 2);
}
print $product_static->getLibStatut(1, 2);
print '</td>';
if (!$i) {
$totalarray['nbfield']++;

View File

@ -1185,6 +1185,7 @@ if ($action == 'edit_price' && $object->getRights()->creer) {
print dol_get_fiche_head('');
print '<div class="div-table-responsive-no-min">';
print '<table class="border centpercent">';
// VAT
@ -1271,6 +1272,7 @@ if ($action == 'edit_price' && $object->getRights()->creer) {
$reshook = $hookmanager->executeHooks('formObjectOptions', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
print '</table>';
print '</div>';
print dol_get_fiche_end();
@ -1318,6 +1320,7 @@ if ($action == 'edit_price' && $object->getRights()->creer) {
print $langs->trans('UseMultipriceRules').' <input type="checkbox" id="usePriceRules" name="usePriceRules" '.($object->price_autogen ? 'checked' : '').'><br><br>';
}
print '<div class="div-table-responsive-no-min">';
print '<table class="noborder">';
print '<thead><tr class="liste_titre">';
@ -1392,6 +1395,7 @@ if ($action == 'edit_price' && $object->getRights()->creer) {
print '</tbody>';
print '</table>';
print '</div>';
//print dol_get_fiche_end();
@ -1493,7 +1497,7 @@ if ((empty($conf->global->PRODUIT_CUSTOMER_PRICES) || $action == 'showlog_defaul
print '<tr class="oddeven">';
// Date
print "<td>".dol_print_date($db->jdate($objp->dp), "dayhour")."</td>";
print "<td>".dol_print_date($db->jdate($objp->dp), "dayhour", 'tzuserrel')."</td>";
// Price level
if (!empty($conf->global->PRODUIT_MULTIPRICES) || !empty($conf->global->PRODUIT_CUSTOMER_PRICES_BY_QTY_MULTIPRICES)) {
@ -1665,13 +1669,11 @@ if (!empty($conf->global->PRODUIT_CUSTOMER_PRICES)) {
print '<input type="hidden" name="action" value="add_customer_price_confirm">';
print '<input type="hidden" name="id" value="'.$object->id.'">';
print dol_get_fiche_head();
print '<table class="liste centpercent">';
print '<tr>';
print '<td class="fieldrequired">'.$langs->trans('ThirdParty').'</td>';
print '<td>';
print $form->select_company('', 'socid', 's.client IN (1,2,3)', 'SelectThirdParty', 0, 0, array(), 0, 'minwidth300');
print img_picto('', 'company').$form->select_company('', 'socid', 's.client IN (1,2,3)', 'SelectThirdParty', 0, 0, array(), 0, 'minwidth300');
print '</td>';
print '</tr>';
@ -1721,14 +1723,13 @@ if (!empty($conf->global->PRODUIT_CUSTOMER_PRICES)) {
print '</table>';
print dol_get_fiche_end();
print '<div class="center">';
// Update all child soc
print '<div class="marginbottomonly">';
print '<input type="checkbox" name="updatechildprice" value="1"> ';
print $langs->trans('ForceUpdateChildPriceSoc');
print '<input type="checkbox" name="updatechildprice" id="updatechildprice" value="1"> ';
print '<label for="updatechildprice">'.$langs->trans('ForceUpdateChildPriceSoc').'</label>';
print '</div>';
print '<input type="submit" class="button button-save" value="'.$langs->trans("Save").'">';
@ -1753,14 +1754,12 @@ if (!empty($conf->global->PRODUIT_CUSTOMER_PRICES)) {
print '<input type="hidden" name="action" value="update_customer_price_confirm">';
print '<input type="hidden" name="lineid" value="'.$prodcustprice->id.'">';
print dol_get_fiche_head();
print '<table class="liste centpercent">';
print '<tr>';
print '<td class="titlefield">'.$langs->trans('ThirdParty').'</td>';
print '<td class="titlefield fieldrequired">'.$langs->trans('ThirdParty').'</td>';
$staticsoc = new Societe($db);
$staticsoc->fetch($prodcustprice->fk_soc);
print "<td colspan='2'>".$staticsoc->getNomUrl(1)."</td>";
print "<td>".$staticsoc->getNomUrl(1)."</td>";
print '</tr>';
// Ref. Customer
@ -1768,12 +1767,12 @@ if (!empty($conf->global->PRODUIT_CUSTOMER_PRICES)) {
print '<td><input name="ref_customer" size="12" value="' . dol_escape_htmltag($prodcustprice->ref_customer) . '"></td></tr>';
// VAT
print '<tr><td>'.$langs->trans("DefaultTaxRate").'</td><td colspan="2">';
print '<tr><td class="fieldrequired">'.$langs->trans("DefaultTaxRate").'</td><td>';
print $form->load_tva("tva_tx", $prodcustprice->default_vat_code ? $prodcustprice->tva_tx.' ('.$prodcustprice->default_vat_code.')' : $prodcustprice->tva_tx, $mysoc, '', $object->id, $prodcustprice->recuperableonly, $object->type, false, 1);
print '</td></tr>';
// Price base
print '<tr><td>';
print '<tr><td class="fieldrequired">';
print $langs->trans('PriceBase');
print '</td>';
print '<td>';
@ -1782,7 +1781,7 @@ if (!empty($conf->global->PRODUIT_CUSTOMER_PRICES)) {
print '</tr>';
// Price
print '<tr><td>';
print '<tr><td class="fieldrequired">';
$text = $langs->trans('SellingPrice');
print $form->textwithpicto($text, $langs->trans("PrecisionUnitIsLimitedToXDecimals", $conf->global->MAIN_MAX_DECIMALS_UNIT), 1, 1);
print '</td><td>';
@ -1809,21 +1808,13 @@ if (!empty($conf->global->PRODUIT_CUSTOMER_PRICES)) {
}
print '</tr>';
// Update all child soc
print '<tr><td>';
print '</td>';
print '<td>';
print '</td>';
print '</tr>';
print '</table>';
print dol_get_fiche_end();
print '<div class="center">';
print '<div class="marginbottomonly">';
print '<input type="checkbox" name="updatechildprice" value="1"> ';
print $langs->trans('ForceUpdateChildPriceSoc');
print '<input type="checkbox" name="updatechildprice" id="updatechildprice" value="1"> ';
print '<label for="updatechildprice">'.$langs->trans('ForceUpdateChildPriceSoc').'</label>';
print "</div>";
print '<input type="submit" class="button button-save" value="'.$langs->trans("Save").'">';
@ -1866,6 +1857,7 @@ if (!empty($conf->global->PRODUIT_CUSTOMER_PRICES)) {
print '<input type="hidden" name="token" value="'.newToken().'">';
print '<input type="hidden" name="id" value="'.$object->id.'">';
print '<div class="div-table-responsive-no-min">';
print '<table class="liste centpercent">';
print '<tr class="liste_titre">';
@ -1915,8 +1907,8 @@ if (!empty($conf->global->PRODUIT_CUSTOMER_PRICES)) {
print '<tr class="oddeven">';
print "<td>".$staticsoc->getNomUrl(1)."</td>";
print '<td>' . $line->ref_customer . '</td>';
print "<td>".dol_print_date($line->datec, "dayhour")."</td>";
print '<td>'.$line->ref_customer.'</td>';
print "<td>".dol_print_date($line->datec, "dayhour", 'tzuserrel')."</td>";
print '<td class="center">'.$langs->trans($line->price_base_type)."</td>";
print '<td class="right">';
@ -1960,6 +1952,7 @@ if (!empty($conf->global->PRODUIT_CUSTOMER_PRICES)) {
print '</tr>';
}
print "</table>";
print '</div>';
} else {
print $langs->trans('None');
}
@ -1986,6 +1979,7 @@ if (!empty($conf->global->PRODUIT_CUSTOMER_PRICES)) {
print '<input type="hidden" name="token" value="'.newToken().'">';
print '<input type="hidden" name="id" value="'.$object->id.'">';
print '<div class="div-table-responsive-no-min">';
print '<table class="liste centpercent">';
if (count($prodcustprice->lines) > 0 || $search_soc) {
@ -2020,7 +2014,7 @@ if (!empty($conf->global->PRODUIT_CUSTOMER_PRICES)) {
print '<td class="right">'.$langs->trans("MinPrice").' '.$langs->trans("HT").'</td>';
print '<td class="right">'.$langs->trans("MinPrice").' '.$langs->trans("TTC").'</td>';
print '<td class="right">'.$langs->trans("ChangedBy").'</td>';
print '<td>&nbsp;</td>';
print '<td></td>';
print '</tr>';
// Line for default price
@ -2081,15 +2075,14 @@ if (!empty($conf->global->PRODUIT_CUSTOMER_PRICES)) {
print '<td class="right">';
print '</td>';
if ($user->rights->produit->supprimer || $user->rights->service->supprimer) {
print '<td class="right">';
print '<a href="'.$_SERVER["PHP_SELF"].'?action=showlog_default_price&amp;id='.$object->id.'">';
print '<td class="nowraponall">';
print '<a class="marginleftonly marginrightonly" href="'.$_SERVER["PHP_SELF"].'?action=showlog_default_price&amp;id='.$object->id.'">';
print img_info($langs->trans('PriceByCustomerLog'));
print '</a>';
print ' ';
print '<a class="marginleftonly editfielda" href="'.$_SERVER["PHP_SELF"].'?action=edit_price&amp;id='.$object->id.'">';
print '<a class="marginleftonly marginrightonly editfielda" href="'.$_SERVER["PHP_SELF"].'?action=edit_price&amp;id='.$object->id.'">';
print img_edit('default', 0, 'style="vertical-align: middle;"');
print '</a>';
print ' &nbsp; ';
print '</td>';
}
print "</tr>\n";
@ -2124,8 +2117,7 @@ if (!empty($conf->global->PRODUIT_CUSTOMER_PRICES)) {
print "<td>".$staticsoc->getNomUrl(1)."</td>";
print '<td>' . $line->ref_customer . '</td>';
print "<td>".dol_print_date($line->datec, "dayhour")."</td>";
print "<td>".dol_print_date($line->datec, "dayhour", 'tzuserrel')."</td>";
print '<td class="center">'.$langs->trans($line->price_base_type)."</td>";
print '<td class="right">';
@ -2142,6 +2134,7 @@ if (!empty($conf->global->PRODUIT_CUSTOMER_PRICES)) {
if (empty($positiverates)) {
$positiverates = '0';
}
echo vatrate($positiverates.($line->default_vat_code ? ' ('.$line->default_vat_code.')' : ''), '%', ($line->tva_npr ? $line->tva_npr : $line->recuperableonly));
print "</td>";
@ -2185,16 +2178,9 @@ if (!empty($conf->global->PRODUIT_CUSTOMER_PRICES)) {
print "</tr>\n";
}
}
/*else
{
$colspan=9;
if ($user->rights->produit->supprimer || $user->rights->service->supprimer) $colspan+=1;
print "<tr ".$bc[false].">";
print '<td colspan="'.$colspan.'">'.$langs->trans('None').'</td>';
print "</tr>";
}*/
print "</table>";
print '</div>';
print "</form>";
}

View File

@ -192,7 +192,7 @@ class MouvementStock extends CommonObject
}
}
// end hook at beginning
// Clean parameters
$price = price2num($price, 'MU'); // Clean value for the casse we receive a float zero value, to have it a real zero value.
if (empty($price)) $price = 0;
@ -568,14 +568,32 @@ class MouvementStock extends CommonObject
// Update detail stock for batch product
if (!$error && !empty($conf->productbatch->enabled) && $product->hasbatch() && !$skip_batch)
{
if ($id_product_batch > 0)
// check unicity for serial numbered equipments ( different for lots managed products)
if ( $product->status_batch == 2 && $qty > 0 )
{
$result = $this->createBatch($id_product_batch, $qty);
} else {
$param_batch = array('fk_product_stock' =>$fk_product_stock, 'batchnumber'=>$batch);
$result = $this->createBatch($param_batch, $qty);
if ( $this->getBatchCount($fk_product, $batch) > 0 )
{
$error++;
$this->errors[] = $langs->trans("SerialNumberAlreadyInUse", $batch, $product->ref);
}
elseif ( $qty > 1 )
{
$error++;
$this->errors[] = $langs->trans("TooManyQtyForSerialNumber", $product->ref, $batch);
}
}
if ( ! $error )
{
if ($id_product_batch > 0)
{
$result = $this->createBatch($id_product_batch, $qty);
} else {
$param_batch = array('fk_product_stock' =>$fk_product_stock, 'batchnumber'=>$batch);
$result = $this->createBatch($param_batch, $qty);
}
if ($result < 0) $error++;
}
if ($result < 0) $error++;
}
// Update PMP and denormalized value of stock qty at product level
@ -1208,4 +1226,39 @@ class MouvementStock extends CommonObject
return $this->deleteCommon($user, $notrigger);
//return $this->deleteCommon($user, $notrigger, 1);
}
/**
* Retrieve number of equipments for a product batch
*
* @param int $fk_product Product id
* @param varchar $batch batch number
* @return int <0 if KO, number of equipments if OK
*/
private function getBatchCount($fk_product, $batch)
{
global $conf;
$cpt = 0;
$sql = "SELECT sum(pb.qty) as cpt";
$sql .= " FROM ".MAIN_DB_PREFIX."product_batch as pb";
$sql .= " INNER JOIN ".MAIN_DB_PREFIX."product_stock as ps ON ps.rowid = pb.fk_product_stock";
$sql .= " WHERE ps.fk_product = " . $fk_product;
$sql .= " AND pb.batch = '" . $this->db->escape($batch) . "'";
$result = $this->db->query($sql);
if ($result) {
if ($this->db->num_rows($result)) {
$obj = $this->db->fetch_object($result);
$cpt = $obj->cpt;
}
$this->db->free($result);
} else {
dol_print_error($this->db);
return -1;
}
return $cpt;
}
}

View File

@ -133,18 +133,24 @@ if (empty($reshook)) {
$backurlforlist = dol_buildpath('/product/stock/productlot_list.php', 1);
if ($action == 'seteatby' && $user->rights->stock->creer) {
$newvalue = dol_mktime(12, 0, 0, $_POST['eatbymonth'], $_POST['eatbyday'], $_POST['eatbyyear']);
$newvalue = dol_mktime(12, 0, 0, GETPOST('eatbymonth', 'int'), GETPOST('eatbyday', 'int'), GETPOST('eatbyyear', 'int'));
$result = $object->setValueFrom('eatby', $newvalue, '', null, 'date', '', $user, 'PRODUCTLOT_MODIFY');
if ($result < 0) {
dol_print_error($db, $object->error);
setEventMessages($object->error, null, 'errors');
$action == 'editeatby';
} else {
$action = 'view';
}
}
if ($action == 'setsellby' && $user->rights->stock->creer) {
$newvalue = dol_mktime(12, 0, 0, $_POST['sellbymonth'], $_POST['sellbyday'], $_POST['sellbyyear']);
$newvalue = dol_mktime(12, 0, 0, GETPOST('sellbymonth', 'int'), GETPOST('sellbyday', 'int'), GETPOST('sellbyyear', 'int'));
$result = $object->setValueFrom('sellby', $newvalue, '', null, 'date', '', $user, 'PRODUCTLOT_MODIFY');
if ($result < 0) {
dol_print_error($db, $object->error);
setEventMessages($object->error, null, 'errors');
$action == 'editsellby';
} else {
$action = 'view';
}
}
@ -172,8 +178,9 @@ if (empty($reshook)) {
}
}
if ($error)
if ($error) {
$action = 'edit_extras';
}
}
// Action to add record
@ -415,7 +422,7 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea
print '</tr>';
}
// Other attributes. Fields from hook formObjectOptions and Extrafields.
// Other attributes
include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_view.tpl.php';
print '</table>';

View File

@ -46,6 +46,9 @@ if (!defined('NOREQUIREMENU')) {
if (!defined('NOIPCHECK')) {
define('NOIPCHECK', '1'); // Do not check IP defined into conf $dolibarr_main_restrict_ip
}
if (!defined("NOSESSION")) {
define("NOSESSION", '1');
}
/**
* Header empty
@ -67,6 +70,8 @@ function llxFooter()
require '../../main.inc.php';
$mtid = GETPOST('mtid');
$email = GETPOST('email');
$tag = GETPOST('tag');
$securitykey = GETPOST('securitykey');
@ -83,23 +88,55 @@ if ($securitykey != $conf->global->MAILING_EMAIL_UNSUBSCRIBE_KEY) {
}
if (!empty($tag)) {
$statut = '2';
$sql = "UPDATE ".MAIN_DB_PREFIX."mailing_cibles SET statut=".$statut." WHERE tag='".$db->escape($tag)."'";
dol_syslog("public/emailing/mailing-read.php : Mail read : ".$sql, LOG_DEBUG);
dol_syslog("public/emailing/mailing-read.php : Update status of email target and thirdparty for tag ".$tag, LOG_DEBUG);
$sql = "SELECT mc.rowid, mc.email, mc.statut, mc.source_type, mc.source_id, m.entity";
$sql .= " FROM ".MAIN_DB_PREFIX."mailing_cibles as mc, ".MAIN_DB_PREFIX."mailing as m";
$sql .= " WHERE mc.fk_mailing = m.rowid AND mc.tag='".$db->escape($tag)."'";
$resql = $db->query($sql);
if (!$resql) dol_print_error($db);
$obj = $db->fetch_object($resql);
if (empty($obj)) {
print 'Email target not valid. Operation canceled.';
exit;
}
if (empty($obj->email)) {
print 'Email target not valid. Operation canceled.';
exit;
}
if ($obj->statut == 2 || $obj->statut == 3) {
print 'Email target already set to read or unsubscribe. Operation canceled.';
exit;
}
// TODO Test that mtid and email match also with the one found from $tag
/*
if ($obj->email != $email)
{
print 'Email does not match tagnot found. No need to unsubscribe.';
exit;
}
*/
//Update status of target
$statut = '2';
$sql = "UPDATE ".MAIN_DB_PREFIX."mailing_cibles SET statut=".$statut." WHERE rowid = ".((int) $obj->rowid);
$resql = $db->query($sql);
if (!$resql) dol_print_error($db);
//Update status communication of thirdparty prospect
$sql = "UPDATE ".MAIN_DB_PREFIX."societe SET fk_stcomm=3 WHERE fk_stcomm != -1 AND rowid IN (SELECT source_id FROM ".MAIN_DB_PREFIX."mailing_cibles WHERE tag='".$db->escape($tag)."' AND source_type='thirdparty' AND source_id is not null)";
dol_syslog("public/emailing/mailing-read.php : Mail read thirdparty : ".$sql, LOG_DEBUG);
$resql = $db->query($sql);
if ($obj->source_id > 0 && $obj->source_type == 'thirdparty' && $obj->entity) {
$sql = "UPDATE ".MAIN_DB_PREFIX.'societe SET fk_stcomm = 3 WHERE fk_stcomm <> -1 AND entity = '.$obj->entity.' AND rowid = '.$obj->source_id;
$resql = $db->query($sql);
}
//Update status communication of contact prospect
$sql = "UPDATE ".MAIN_DB_PREFIX."societe SET fk_stcomm=3 WHERE fk_stcomm != -1 AND rowid IN (SELECT sc.fk_soc FROM ".MAIN_DB_PREFIX."socpeople AS sc INNER JOIN ".MAIN_DB_PREFIX."mailing_cibles AS mc ON mc.tag = '".$db->escape($tag)."' AND mc.source_type = 'contact' AND mc.source_id = sc.rowid)";
dol_syslog("public/emailing/mailing-read.php : Mail read contact : ".$sql, LOG_DEBUG);
$resql = $db->query($sql);
if ($obj->source_id > 0 && $obj->source_type == 'contact' && $obj->entity) {
$sql = "UPDATE ".MAIN_DB_PREFIX.'societe SET fk_stcomm = 3 WHERE fk_stcomm <> -1 AND entity = '.$obj->entity.' AND rowid IN (SELECT sc.fk_soc FROM '.MAIN_DB_PREFIX.'socpeople AS sc WHERE sc.rowid = '.$obj->source_id.')';
$resql = $db->query($sql);
}
}
$db->close();

View File

@ -42,6 +42,9 @@ if (!defined('NOREQUIREMENU')) {
if (!defined('NOIPCHECK')) {
define('NOIPCHECK', '1'); // Do not check IP defined into conf $dolibarr_main_restrict_ip
}
if (!defined("NOSESSION")) {
define("NOSESSION", '1');
}
/**
* Header empty
@ -68,6 +71,8 @@ global $user, $conf, $langs;
$langs->loadLangs(array("main", "mails"));
$mtid = GETPOST('mtid');
$email = GETPOST('email');
$tag = GETPOST('tag');
$unsuscrib = GETPOST('unsuscrib');
$securitykey = GETPOST('securitykey');
@ -88,7 +93,7 @@ if ($securitykey != $conf->global->MAILING_EMAIL_UNSUBSCRIBE_KEY) {
if (!empty($tag) && ($unsuscrib == '1')) {
dol_syslog("public/emailing/mailing-unsubscribe.php : Launch unsubscribe requests", LOG_DEBUG);
$sql = "SELECT mc.email, m.entity";
$sql = "SELECT mc.rowid, mc.email, mc.statut, m.entity";
$sql .= " FROM ".MAIN_DB_PREFIX."mailing_cibles as mc, ".MAIN_DB_PREFIX."mailing as m";
$sql .= " WHERE mc.fk_mailing = m.rowid AND mc.tag='".$db->escape($tag)."'";
@ -99,10 +104,26 @@ if (!empty($tag) && ($unsuscrib == '1')) {
$obj = $db->fetch_object($resql);
if (empty($obj->email)) {
print 'Email not found. No need to unsubscribe.';
if (empty($obj)) {
print 'Email target not valid. Operation canceled.';
exit;
}
if (empty($obj->email)) {
print 'Email target not valid. Operation canceled.';
exit;
}
if ($obj->statut == 3) {
print 'Email target already set to unsubscribe. Operation canceled.';
exit;
}
// TODO Test that mtid and email match also with the one found from $tag
/*
if ($obj->email != $email)
{
print 'Email does not match tagnot found. No need to unsubscribe.';
exit;
}
*/
// Update status of mail in recipient mailing list table
$statut = '3';
@ -128,7 +149,7 @@ if (!empty($tag) && ($unsuscrib == '1')) {
*/
// Update status communication of email (new usage)
$sql = "INSERT INTO ".MAIN_DB_PREFIX."mailing_unsubscribe (date_creat, entity, email) VALUES ('".$db->idate(dol_now())."', ".$db->escape($obj->entity).", '".$db->escape($obj->email)."')";
$sql = "INSERT INTO ".MAIN_DB_PREFIX."mailing_unsubscribe (date_creat, entity, email, unsubscribegroup, ip) VALUES ('".$db->idate(dol_now())."', ".$db->escape($obj->entity).", '".$db->escape($obj->email)."', '', '".$db->escape(getUserRemoteIP())."')";
$resql = $db->query($sql);
//if (! $resql) dol_print_error($db); No test on errors, may fail if already unsubscribed

View File

@ -61,6 +61,9 @@ class Dolresource extends CommonObject
public $cache_code_type_resource = array();
/**
* @var Dolresource Clone of object before changing it
*/
public $oldcopy;
/**

View File

@ -2,6 +2,7 @@
/* Copyright (C) 2011-2019 Alexandre Spangaro <aspangaro@open-dsi.fr>
* Copyright (C) 2015-2016 Laurent Destailleur <eldy@users.sourceforge.net>
* Copyright (C) 2015 Jean-François Ferry <jfefe@aternatik.fr>
* Copyright (C) 2021 Gauthier VERDOL <gauthier.verdol@atm-consulting.fr>
*
* 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
@ -24,6 +25,7 @@
*/
require '../main.inc.php';
require_once DOL_DOCUMENT_ROOT.'/salaries/class/salary.class.php';
require_once DOL_DOCUMENT_ROOT.'/salaries/class/paymentsalary.class.php';
require_once DOL_DOCUMENT_ROOT.'/compta/bank/class/account.class.php';
if (!empty($conf->accounting->enabled)) require_once DOL_DOCUMENT_ROOT.'/accountancy/class/accountingjournal.class.php';
@ -68,6 +70,7 @@ if (!$sortfield) $sortfield = "s.datep,s.rowid";
if (!$sortorder) $sortorder = "DESC,DESC";
$search_ref = GETPOST('search_ref', 'int');
$search_ref_salary = GETPOST('search_ref_salary', 'int');
$search_user = GETPOST('search_user', 'alpha');
$search_label = GETPOST('search_label', 'alpha');
$search_date_start = dol_mktime(0, 0, 0, GETPOST('search_date_startmonth', 'int'), GETPOST('search_date_startday', 'int'), GETPOST('search_date_startyear', 'int'));
@ -131,6 +134,7 @@ if (empty($reshook)) {
// Purge search criteria
if (GETPOST('button_removefilter_x', 'alpha') || GETPOST('button_removefilter.x', 'alpha') || GETPOST('button_removefilter', 'alpha')) { // All test are required to be compatible with all browsers
$search_ref = "";
$search_ref_salary = "";
$search_user = "";
$search_label = "";
$search_date_start = '';
@ -163,7 +167,8 @@ if (empty($reshook)) {
*/
$form = new Form($db);
$salstatic = new PaymentSalary($db);
$salstatic = new Salary($db);
$paymentsalstatic = new PaymentSalary($db);
$userstatic = new User($db);
$accountstatic = new Account($db);
@ -174,22 +179,24 @@ $help_url = '';
$title = $langs->trans('SalariesPayments');
$sql = "SELECT u.rowid as uid, u.lastname, u.firstname, u.login, u.email, u.admin, u.salary as current_salary, u.fk_soc as fk_soc, u.statut as status,";
$sql .= " s.rowid, s.fk_user, s.amount, s.salary, s.label, s.datep as datep, s.datev as datev, s.fk_typepayment as type, s.num_payment, s.fk_bank,";
$sql .= " s.rowid, s.fk_user, s.amount, s.salary, sal.rowid as id_salary, sal.label, s.datep as datep, b.datev as datev, s.fk_typepayment as type, s.num_payment, s.fk_bank,";
$sql .= " ba.rowid as bid, ba.ref as bref, ba.number as bnumber, ba.account_number, ba.fk_accountancy_journal, ba.label as blabel,";
$sql .= " pst.code as payment_code";
$sql .= " FROM ".MAIN_DB_PREFIX."payment_salary as s";
$sql .= " INNER JOIN ".MAIN_DB_PREFIX."salary as sal ON (sal.rowid = s.fk_salary)";
$sql .= " LEFT JOIN ".MAIN_DB_PREFIX."c_paiement as pst ON s.fk_typepayment = pst.id";
$sql .= " LEFT JOIN ".MAIN_DB_PREFIX."bank as b ON s.fk_bank = b.rowid";
$sql .= " LEFT JOIN ".MAIN_DB_PREFIX."bank_account as ba ON b.fk_account = ba.rowid,";
$sql .= " ".MAIN_DB_PREFIX."user as u";
$sql .= " WHERE u.rowid = s.fk_user";
$sql .= " WHERE u.rowid = sal.fk_user";
$sql .= " AND s.entity IN (".getEntity('payment_salaries').")";
if (empty($user->rights->salaries->readall)) $sql .= " AND s.fk_user IN (".join(',', $childids).")";
// Search criteria
if ($search_ref) $sql .= " AND s.rowid=".((int) $search_ref);
if ($search_ref_salary) $sql .= " AND sal.rowid=".((int) $search_ref_salary);
if ($search_user) $sql .= natural_search(array('u.login', 'u.lastname', 'u.firstname', 'u.email'), $search_user);
if ($search_label) $sql .= natural_search(array('s.label'), $search_label);
if ($search_label) $sql .= natural_search(array('sal.label'), $search_label);
if ($search_date_start) $sql .= " AND s.datep >= '".$db->idate($search_date_start)."'";
if ($search_date_end) $sql .= " AND s.datep <= '".$db->idate($search_date_end)."'";
if ($search_amount) $sql .= natural_search("s.amount", $search_amount, 1);
@ -241,6 +248,7 @@ if ($limit > 0 && $limit != $conf->liste_limit) $param .= '&limit='.urlencode($l
if ($search_type_id) $param .= '&search_type_id='.urlencode($search_type_id);
if ($optioncss != '') $param .= '&optioncss='.urlencode($optioncss);
if ($search_ref) $param .= '&search_ref='.urlencode($search_ref);
if ($search_ref_salary) $param .= '&search_ref_salary='.urlencode($search_ref_salary);
if ($search_user > 0) $param .= '&search_user='.urlencode($search_user);
if ($search_label) $param .= '&search_label='.urlencode($search_label);
if ($search_account) $param .= '&search_account='.urlencode($search_account);
@ -292,6 +300,10 @@ print '</td>';
print '<td class="liste_titre">';
print '<input class="flat" type="text" size="6" name="search_user" value="'.$db->escape($search_user).'">';
print '</td>';
// Salary
print '<td class="liste_titre center">';
print '<input class="flat" type="text" size="3" name="search_ref_salary" value="'.$db->escape($search_ref_salary).'">';
print '</td>';
// Label
print '<td class="liste_titre"><input type="text" class="flat width150" name="search_label" value="'.$db->escape($search_label).'"></td>';
// Date payment
@ -339,10 +351,11 @@ print '</tr>'."\n";
print '<tr class="liste_titre">';
print_liste_field_titre("Ref", $_SERVER["PHP_SELF"], "s.rowid", "", $param, "", $sortfield, $sortorder);
print_liste_field_titre("Employee", $_SERVER["PHP_SELF"], "u.rowid", "", $param, "", $sortfield, $sortorder);
print_liste_field_titre("Salary", $_SERVER["PHP_SELF"], "sal.rowid", "", $param, '', $sortfield, $sortorder);
print_liste_field_titre("Label", $_SERVER["PHP_SELF"], "s.label", "", $param, 'class="left"', $sortfield, $sortorder);
print_liste_field_titre("DatePayment", $_SERVER["PHP_SELF"], "s.datep,s.rowid", "", $param, '', $sortfield, $sortorder, 'center ');
print_liste_field_titre("DateValue", $_SERVER["PHP_SELF"], "s.datev,s.rowid", "", $param, '', $sortfield, $sortorder, 'center ');
print_liste_field_titre("PaymentMode", $_SERVER["PHP_SELF"], "type", "", $param, 'class="left"', $sortfield, $sortorder);
print_liste_field_titre("DateValue", $_SERVER["PHP_SELF"], "b.datev,s.rowid", "", $param, '', $sortfield, $sortorder, 'center ');
print_liste_field_titre("PaymentMode", $_SERVER["PHP_SELF"], "pst.code", "", $param, 'class="left"', $sortfield, $sortorder);
if (!empty($conf->banque->enabled)) print_liste_field_titre("BankAccount", $_SERVER["PHP_SELF"], "ba.label", "", $param, "", $sortfield, $sortorder);
print_liste_field_titre("PayedByThisPayment", $_SERVER["PHP_SELF"], "s.amount", "", $param, 'class="right"', $sortfield, $sortorder);
// Extra fields
@ -388,17 +401,23 @@ while ($i < ($limit ? min($num, $limit) : $num)) {
$userstatic->socid = $obj->fk_soc;
$userstatic->statut = $obj->status;
$salstatic->id = $obj->rowid;
$salstatic->ref = $obj->rowid;
$salstatic->id = $obj->id_salary;
$salstatic->ref = $obj->id_salary;
$paymentsalstatic->id = $obj->rowid;
$paymentsalstatic->ref = $obj->rowid;
// Ref
print "<td>".$salstatic->getNomUrl(1)."</td>\n";
print "<td>".$paymentsalstatic->getNomUrl(1)."</td>\n";
if (!$i) $totalarray['nbfield']++;
// Employee
print "<td>".$userstatic->getNomUrl(1)."</td>\n";
if (!$i) $totalarray['nbfield']++;
print "<td>".$salstatic->getNomUrl(1)."</td>\n";
if (!$i) $totalarray['nbfield']++;
// Label payment
print "<td>".dol_trunc($obj->label, 40)."</td>\n";
if (!$i) $totalarray['nbfield']++;

View File

@ -4,6 +4,7 @@
* Copyright (C) 2013-2015 Juanjo Menent <jmenent@2byte.es>
* Copyright (C) 2015 Marcos García <marcosgdf@gmail.com>
* Copyright (C) 2015-2017 Ferran Marcet <fmarcet@2byte.es>
* Copyright (C) 2021 Frédéric France <frederic.france@netlogic.fr>
*
* 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
@ -472,6 +473,7 @@ if ($sql_select) {
$documentstatic->statut = $objp->status;
$documentstatic->status = $objp->status;
$documentstatic->paye = $objp->paid;
$documentstatic->alreadypaid = $objp->paid;
if (is_object($documentstaticline)) {
$documentstaticline->statut = $objp->status;
@ -487,6 +489,8 @@ if ($sql_select) {
print '<td class="center">';
if ($type_element == 'contract') {
print $documentstaticline->getLibStatut(5);
} elseif ($type_element == 'invoice') {
print $documentstatic->getLibStatut(5, $objp->paid);
} else {
print $documentstatic->getLibStatut(5);
}
@ -496,7 +500,9 @@ if ($sql_select) {
print '<td class="tdoverflowmax300">';
// Define text, description and type
$text = ''; $description = ''; $type = 0;
$text = '';
$description = '';
$type = 0;
// Code to show product duplicated from commonobject->printObjectLine
if ($objp->fk_product > 0) {

View File

@ -1606,7 +1606,7 @@ td.showDragHandle {
float: left;
}
.classforhorizontalscrolloftabs #id-right {
width:calc(100% - 210px);
width: calc(100% - 210px);
display: inline-block;
}
@ -1710,10 +1710,17 @@ div.vmenu, td.vmenu {
/* rule to reduce top menu - 3rd reduction: The menu for user is on left */
@media only screen and (max-width: <?php echo empty($conf->global->THEME_ELDY_WITDHOFFSET_FOR_REDUC3) ? round($nbtopmenuentries * 47, 0) + 130 : $conf->global->THEME_ELDY_WITDHOFFSET_FOR_REDUC3; ?>px) /* reduction 3 */
{
/* no side-nav */
body.sidebar-collapse .side-nav {
display: none;
}
/* if no side-nav, we don't need to have width forced */
.classforhorizontalscrolloftabs #id-right {
width: unset;
display: unset;
}
body.sidebar-collapse .login_block {
display: none;
}

View File

@ -712,7 +712,7 @@ class Ticket extends CommonObject
if (!empty($filter)) {
foreach ($filter as $key => $value) {
if (strpos($key, 'date')) { // To allow $filter['YEAR(s.dated)']=>$year
$sql .= ' AND '.$key." = '".$this->db->scape($value)."'";
$sql .= ' AND '.$key." = '".$this->db->escape($value)."'";
} elseif (($key == 't.fk_user_assign') || ($key == 't.type_code') || ($key == 't.category_code') || ($key == 't.severity_code') || ($key == 't.fk_soc')) {
$sql .= " AND ".$key." = '".$this->db->escape($value)."'";
} elseif ($key == 't.fk_statut') {

View File

@ -356,7 +356,7 @@ if ($action != 'edit' && $action != 'create') { // If not bank account yet, $ac
if (!empty($conf->salaries->enabled) &&
$user->rights->salaries->read && (in_array($object->id, $childids) || $object->id == $user->id)
) {
$salary = new PaymentSalary($db);
$payment_salary = new PaymentSalary($db);
$sql = "SELECT ps.rowid, s.datesp, s.dateep, ps.amount";
$sql .= " FROM ".MAIN_DB_PREFIX."payment_salary as ps";
@ -372,7 +372,7 @@ if ($action != 'edit' && $action != 'create') { // If not bank account yet, $ac
print '<table class="noborder centpercent">';
print '<tr class="liste_titre">';
print '<td colspan="4"><table width="100%" class="nobordernopadding"><tr><td>'.$langs->trans("LastSalaries", ($num <= $MAXLIST ? "" : $MAXLIST)).'</td><td class="right"><a class="notasortlink" href="'.DOL_URL_ROOT.'/salaries/payments.php?search_user='.$object->id.'">'.$langs->trans("AllSalaries").'<span class="badge marginleftonlyshort">'.$num.'</span></a></td>';
print '<td colspan="4"><table width="100%" class="nobordernopadding"><tr><td>'.$langs->trans("LastSalaries", ($num <= $MAXLIST ? "" : $MAXLIST)).'</td><td class="right"><a class="notasortlink" href="'.DOL_URL_ROOT.'/salaries/payments.php?search_user='.$object->login.'">'.$langs->trans("AllSalaries").'<span class="badge marginleftonlyshort">'.$num.'</span></a></td>';
print '</tr></table></td>';
print '</tr>';

View File

@ -97,7 +97,11 @@ print "port=".$conf->global->LDAP_SERVER_PORT."\n";
print "login=".$conf->global->LDAP_ADMIN_DN."\n";
print "pass=".preg_replace('/./i', '*', $conf->global->LDAP_ADMIN_PASS)."\n";
print "DN to extract=".$conf->global->LDAP_GROUP_DN."\n";
print 'Filter=('.$conf->global->LDAP_KEY_GROUPS.'=*)'."\n";
if (!empty($conf->global->LDAP_GROUP_FILTER)) {
print 'Filter=('.$conf->global->LDAP_GROUP_FILTER.')'."\n"; // Note: filter is defined into function getRecords
} else {
print 'Filter=('.$conf->global->LDAP_KEY_GROUPS.'=*)'."\n";
}
print "----- To Dolibarr database:\n";
print "type=".$conf->db->type."\n";
print "host=".$conf->db->host."\n";
@ -127,7 +131,7 @@ if ($result >= 0) {
// We disable synchro Dolibarr-LDAP
$conf->global->LDAP_SYNCHRO_ACTIVE = 0;
$ldaprecords = $ldap->getRecords('*', $conf->global->LDAP_GROUP_DN, $conf->global->LDAP_KEY_GROUPS, $required_fields, 0, array($conf->global->LDAP_GROUP_FIELD_GROUPMEMBERS));
$ldaprecords = $ldap->getRecords('*', $conf->global->LDAP_GROUP_DN, $conf->global->LDAP_KEY_GROUPS, $required_fields, 'group', array($conf->global->LDAP_GROUP_FIELD_GROUPMEMBERS));
if (is_array($ldaprecords)) {
$db->begin();

View File

@ -127,13 +127,14 @@ class FactureRecTest extends PHPUnit\Framework\TestCase
}
/**
* testFactureCreate
* testFactureRecCreate
*
* @return int
*/
public function testFactureRecCreate()
{
global $conf,$user,$langs,$db;
$conf=$this->savconf;
$user=$this->savuser;
$langs=$this->savlangs;
@ -141,21 +142,51 @@ class FactureRecTest extends PHPUnit\Framework\TestCase
$localobjectinv=new Facture($this->savdb);
$localobjectinv->initAsSpecimen();
$localobjectinv->create($user);
$result = $localobjectinv->create($user);
print __METHOD__." result=".$result."\n";
$localobject=new FactureRec($this->savdb);
$localobject->initAsSpecimen();
$result=$localobject->create($user, $localobjectinv->id);
$result = $localobject->create($user, $localobjectinv->id);
$this->assertLessThan($result, 0);
print __METHOD__." result=".$result."\n";
$this->assertGreaterThan(0, $result, 'Create recurring invoice from common invoice');
return $result;
}
/**
* testFactureRecFetch
*
* @param int $id Id of created recuriing invoice
* @return int
*
* @depends testFactureRecCreate
* The depends says test is run only if previous is ok
*/
public function testFactureRecFetch($id)
{
global $conf,$user,$langs,$db;
$conf=$this->savconf;
$user=$this->savuser;
$langs=$this->savlangs;
$db=$this->savdb;
$localobject=new FactureRec($this->savdb);
$result = $localobject->fetch($id);
print __METHOD__." result=".$result."\n";
$this->assertGreaterThan(0, $result);
return $result;
}
/**
* Edit an object to test updates
*
* @param Facture $localobject Object Facture
* @param FactureRec $localobject Object Facture rec
* @return void
*/
public function changeProperties(&$localobject)