Work on reminders

This commit is contained in:
Laurent Destailleur
2017-10-31 23:10:29 +01:00
parent 1db68b2a32
commit 9458c80c48
12 changed files with 339 additions and 49 deletions

View File

@@ -1530,10 +1530,18 @@ class ActionComm extends CommonObject
return 0;
}
$now = dol_now();
dol_syslog(__METHOD__, LOG_DEBUG);
// TODO Scan events of type 'email' into table llx_actioncomm_reminder with status todo, send email, then set status to done
// Delete also very old past events (we do not keep more than 1 month record in past)
$sql = "DELETE FROM ".MAIN_DB_PREFIX."actioncomm_reminder WHERE dateremind < '".$this->jdate($now - (3600 * 24 * 32))."'";
$this->db->query($sql);
return 0;
}

View File

@@ -0,0 +1,229 @@
<?php
/* Copyright (C) 2017 Laurent Destailleur <eldy@users.sourceforge.net>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* \file class/actioncommreminder.class.php
* \ingroup agenda
* \brief This file is a CRUD class file for ActionCommReminder (Create/Read/Update/Delete)
*/
// Put here all includes required by your class file
require_once DOL_DOCUMENT_ROOT . '/core/class/commonobject.class.php';
/**
* Class for ActionCommReminder
*/
class ActionCommReminder extends CommonObject
{
/**
* @var string ID to identify managed object
*/
public $element = 'actioncomm_reminder';
/**
* @var string Name of table without prefix where object is stored
*/
public $table_element = 'actioncomm_reminder';
/**
* @var array Does actioncommreminder support multicompany module ? 0=No test on entity, 1=Test with field entity, 2=Test with link by societe
*/
public $ismultientitymanaged = 0;
/**
* @var string String with name of icon for actioncommreminder. Must be the part after the 'object_' into object_actioncommreminder.png
*/
public $picto = 'generic';
/**
* 'type' if the field format.
* 'label' the translation key.
* 'enabled' is a condition when the field must be managed.
* 'visible' says if field is visible in list (Examples: 0=Not visible, 1=Visible on list and create/update/view forms, 2=Visible on list only. Using a negative value means field is not shown by default on list but can be selected for viewing)
* 'notnull' is set to 1 if not null in database. Set to -1 if we must set data to null if empty ('' or 0).
* 'index' if we want an index in database.
* 'foreignkey'=>'tablename.field' if the field is a foreign key (it is recommanded to name the field fk_...).
* 'position' is the sort order of field.
* 'searchall' is 1 if we want to search in this field when making a search from the quick search button.
* 'isameasure' must be set to 1 if you want to have a total on list for this field. Field type must be summable like integer or double(24,8).
* 'help' is a string visible as a tooltip on field
* 'comment' is not used. You can store here any text of your choice. It is not used by application.
* 'default' is a default value for creation (can still be replaced by the global setup of default values)
* 'showoncombobox' if field must be shown into the label of combobox
*/
// BEGIN MODULEBUILDER PROPERTIES
/**
* @var array Array with all fields and their property. Do not use it as a static var. It may be modified by constructor.
*/
public $fields=array(
'rowid' => array('type'=>'integer', 'label'=>'TechnicalID', 'visible'=>-1, 'enabled'=>1, 'position'=>1, 'notnull'=>1, 'index'=>1, 'comment'=>"Id",),
'dateremind' => array('type'=>'datetime', 'label'=>'DateRemind', 'visible'=>1, 'enabled'=>1, 'position'=>60, 'notnull'=>1, 'index'=>1,),
'typeremind' => array('type'=>'varchar(32)', 'label'=>'TypeRemind', 'visible'=>-1, 'enabled'=>1, 'position'=>55, 'notnull'=>1, 'comment'=>"email, browser, sms",),
'fk_user' => array('type'=>'integer', 'label'=>'User', 'visible'=>-1, 'enabled'=>1, 'position'=>65, 'notnull'=>1, 'index'=>1,),
'offsetvalue' => array('type'=>'integer', 'label'=>'OffsetValue', 'visible'=>1, 'enabled'=>1, 'position'=>56, 'notnull'=>1,),
'offsetunit' => array('type'=>'varchar(1)', 'label'=>'OffsetUnit', 'visible'=>1, 'enabled'=>1, 'position'=>57, 'notnull'=>1, 'comment'=>"m, h, d, w",),
'status' => array('type'=>'integer', 'label'=>'Status', 'visible'=>1, 'enabled'=>1, 'position'=>1000, 'notnull'=>1, 'default'=>0, 'index'=>0, 'arrayofkeyval'=>array('0'=>'ToDo', '1'=>'Done')),
);
public $rowid;
public $dateremind;
public $typeremind;
public $fk_user;
public $offsetvalue;
public $offsetunit;
public $status;
// END MODULEBUILDER PROPERTIES
/**
* Constructor
*
* @param DoliDb $db Database handler
*/
public function __construct(DoliDB $db)
{
global $conf;
$this->db = $db;
if (empty($conf->global->MAIN_SHOW_TECHNICAL_ID)) $this->fields['rowid']['visible']=0;
if (empty($conf->multicompany->enabled)) $this->fields['entity']['enabled']=0;
}
/**
* Create object into database
*
* @param User $user User that creates
* @param bool $notrigger false=launch triggers after, true=disable triggers
* @return int <0 if KO, Id of created object if OK
*/
public function create(User $user, $notrigger = false)
{
return $this->createCommon($user, $notrigger);
}
/**
* Load object in memory from the database
*
* @param int $id Id object
* @param string $ref Ref
* @return int <0 if KO, 0 if not found, >0 if OK
*/
public function fetch($id, $ref = null)
{
$result = $this->fetchCommon($id, $ref);
return $result;
}
/**
* Update object into database
*
* @param User $user User that modifies
* @param bool $notrigger false=launch triggers after, true=disable triggers
* @return int <0 if KO, >0 if OK
*/
public function update(User $user, $notrigger = false)
{
return $this->updateCommon($user, $notrigger);
}
/**
* Delete object in database
*
* @param User $user User that deletes
* @param bool $notrigger false=launch triggers after, true=disable triggers
* @return int <0 if KO, >0 if OK
*/
public function delete(User $user, $notrigger = false)
{
return $this->deleteCommon($user, $notrigger);
}
/**
* Retourne le libelle du status d'un user (actif, inactif)
*
* @param int $mode 0=libelle long, 1=libelle court, 2=Picto + Libelle court, 3=Picto, 4=Picto + Libelle long, 5=Libelle court + Picto
* @return string Label of status
*/
function getLibStatut($mode=0)
{
return $this->LibStatut($this->status,$mode);
}
/**
* Return the status
*
* @param int $status Id status
* @param int $mode 0=long label, 1=short label, 2=Picto + short label, 3=Picto, 4=Picto + long label, 5=Short label + Picto, 6=Long label + Picto
* @return string Label of status
*/
static function LibStatut($status,$mode=0)
{
global $langs;
if ($mode == 0)
{
$prefix='';
if ($status == 1) return $langs->trans('Done');
if ($status == 0) return $langs->trans('ToDo');
}
if ($mode == 1)
{
if ($status == 1) return $langs->trans('Done');
if ($status == 0) return $langs->trans('ToDo');
}
if ($mode == 2)
{
if ($status == 1) return img_picto($langs->trans('Done'),'statut4').' '.$langs->trans('Done');
if ($status == 0) return img_picto($langs->trans('ToDo'),'statut5').' '.$langs->trans('ToDo');
}
if ($mode == 3)
{
if ($status == 1) return img_picto($langs->trans('Done'),'statut4');
if ($status == 0) return img_picto($langs->trans('ToDo'),'statut5');
}
if ($mode == 4)
{
if ($status == 1) return img_picto($langs->trans('Done'),'statut4').' '.$langs->trans('Done');
if ($status == 0) return img_picto($langs->trans('ToDo'),'statut5').' '.$langs->trans('ToDo');
}
if ($mode == 5)
{
if ($status == 1) return $langs->trans('Done').' '.img_picto($langs->trans('Done'),'statut4');
if ($status == 0) return $langs->trans('ToDo').' '.img_picto($langs->trans('ToDo'),'statut5');
}
if ($mode == 6)
{
if ($status == 1) return $langs->trans('Done').' '.img_picto($langs->trans('Done'),'statut4');
if ($status == 0) return $langs->trans('ToDo').' '.img_picto($langs->trans('ToDo'),'statut5');
}
}
/**
* Initialise object with example values
* Id must be 0 if object instance is a specimen
*
* @return void
*/
public function initAsSpecimen()
{
$this->initAsSpecimenCommon();
}
}

View File

@@ -340,16 +340,6 @@ abstract class CommonObject
// No constructor as it is an abstract class
/**
* Return if an object manage the multicompany field and how.
*
* @return int 0=No entity field managed, 1=Test with field entity, 2=Test with link to thirdparty (and sales representative)
*/
function getIsmultientitymanaged()
{
return $this->ismultientitymanaged;
}
/**
* Check an object id/ref exists
* If you don't need/want to instantiate object and just need to know if object exists, use this method instead of fetch

View File

@@ -132,9 +132,9 @@ function rebuildObjectClass($destdir, $module, $objectname, $newmask, $readdir='
$texttoinsert.= " 'notnull'=>".($val['notnull']!=''?$val['notnull']:-1).",";
if ($val['index']) $texttoinsert.= " 'index'=>".$val['index'].",";
if ($val['searchall']) $texttoinsert.= " 'searchall'=>".$val['searchall'].",";
if ($val['comment']) $texttoinsert.= " 'comment'=>'".$val['comment']."',";
if ($val['comment']) $texttoinsert.= " 'comment'=>\"".preg_replace('/"/', '', $val['comment'])."\","; // addslashes is escape for PHP
if ($val['isameasure']) $texttoinsert.= " 'isameasure'=>'".$val['isameasure']."',";
if ($val['help']) $texttoinsert.= " 'help'=>'".$val['help']."',";
if ($val['help']) $texttoinsert.= " 'help'=>\"".preg_replace('/"/', '', $val['help'])."\","; // addslashes is escape for PHP
if ($val['arrayofkeyval'])
{
$texttoinsert.= " 'arrayofkeyval'=>array(";
@@ -215,8 +215,8 @@ function rebuildObjectSql($destdir, $module, $objectname, $newmask, $readdir='',
$pathoffiletoclasssrc=$readdir.'/class/'.strtolower($objectname).'.class.php';
// Edit .sql file
$pathoffiletoeditsrc=$readdir.'/sql/llx_'.strtolower($objectname).'.sql';
$pathoffiletoedittarget=$destdir.'/sql/llx_'.strtolower($objectname).'.sql'.($readdir != $destdir ? '.new' : '');
$pathoffiletoeditsrc=$readdir.'/sql/llx_'.strtolower($module).'_'.strtolower($objectname).'.sql';
$pathoffiletoedittarget=$destdir.'/sql/llx_'.strtolower($module).'_'.strtolower($objectname).'.sql'.($readdir != $destdir ? '.new' : '');
if (! dol_is_file($pathoffiletoeditsrc))
{
$langs->load("errors");
@@ -287,8 +287,8 @@ function rebuildObjectSql($destdir, $module, $objectname, $newmask, $readdir='',
}
// Edit .key.sql file
$pathoffiletoeditsrc=$destdir.'/sql/llx_'.strtolower($objectname).'.key.sql';
$pathoffiletoedittarget=$destdir.'/sql/llx_'.strtolower($objectname).'.key.sql'.($readdir != $destdir ? '.new' : '');
$pathoffiletoeditsrc=$destdir.'/sql/llx_'.strtolower($module).'_'.strtolower($objectname).'.key.sql';
$pathoffiletoedittarget=$destdir.'/sql/llx_'.strtolower($module).'_'.strtolower($objectname).'.key.sql'.($readdir != $destdir ? '.new' : '');
$contentsql = file_get_contents(dol_osencode($pathoffiletoeditsrc), 'r');
@@ -301,7 +301,7 @@ function rebuildObjectSql($destdir, $module, $objectname, $newmask, $readdir='',
$i++;
if ($val['index'])
{
$texttoinsert.= "ALTER TABLE llx_".strtolower($objectname)." ADD INDEX idx_".strtolower($objectname)."_".$key." (".$key.");";
$texttoinsert.= "ALTER TABLE llx_".strtolower($module).'_'.strtolower($objectname)." ADD INDEX idx_".strtolower($module).'_'.strtolower($objectname)."_".$key." (".$key.");";
$texttoinsert.= "\n";
}
}

View File

@@ -461,6 +461,26 @@ UPDATE llx_accounting_system SET fk_country =140 WHERE pcg_version = 'PCN-LUXEMB
UPDATE llx_accounting_system SET fk_country = 12 WHERE pcg_version = 'PCG';
CREATE TABLE llx_actioncomm_reminder(
-- BEGIN MODULEBUILDER FIELDS
rowid integer AUTO_INCREMENT PRIMARY KEY NOT NULL,
dateremind datetime NOT NULL,
typeremind varchar(32) NOT NULL,
fk_user integer NOT NULL,
offsetvalue integer NOT NULL,
offsetunit varchar(1) NOT NULL,
status integer NOT NULL DEFAULT 0
-- END MODULEBUILDER FIELDS
) ENGINE=innodb;
ALTER TABLE llx_actioncomm_reminder ADD INDEX idx_actioncomm_reminder_rowid (rowid);
ALTER TABLE llx_actioncomm_reminder ADD INDEX idx_actioncomm_reminder_dateremind (dateremind);
ALTER TABLE llx_actioncomm_reminder ADD INDEX idx_actioncomm_reminder_fk_user (fk_user);
ALTER TABLE llx_actioncomm_reminder ADD UNIQUE INDEX uk_actioncomm_reminder_unique(fk_user, typeremind, offsetvalue, offsetunit);
-- VPGSQL8.2 CREATE SEQUENCE llx_supplier_proposal_rowid_seq;
-- VPGSQL8.2 ALTER TABLE llx_supplier_proposal ALTER COLUMN rowid SET DEFAULT nextval('llx_supplier_proposal_rowid_seq');
-- VPGSQL8.2 ALTER TABLE llx_supplier_proposal ALTER COLUMN rowid SET NOT NULL;

View File

@@ -0,0 +1,25 @@
-- Copyright (C) 2017 Laurent Destailleur <eldy@users.sourceforge.net>
--
-- This program is free software: you can redistribute it and/or modify
-- it under the terms of the GNU General Public License as published by
-- the Free Software Foundation, either version 3 of the License, or
-- (at your option) any later version.
--
-- This program is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-- GNU General Public License for more details.
--
-- You should have received a copy of the GNU General Public License
-- along with this program. If not, see http://www.gnu.org/licenses/.
-- BEGIN MODULEBUILDER INDEXES
ALTER TABLE llx_actioncomm_reminder ADD INDEX idx_actioncomm_reminder_rowid (rowid);
ALTER TABLE llx_actioncomm_reminder ADD INDEX idx_actioncomm_reminder_dateremind (dateremind);
ALTER TABLE llx_actioncomm_reminder ADD INDEX idx_actioncomm_reminder_fk_user (fk_user);
-- END MODULEBUILDER INDEXES
ALTER TABLE llx_actioncomm_reminder ADD UNIQUE INDEX uk_actioncomm_reminder_unique(fk_user, typeremind, offsetvalue, offsetunit);

View File

@@ -0,0 +1,27 @@
-- Copyright (C) 2017 Laurent Destailleur <eldy@users.sourceforge.net>
--
-- This program is free software: you can redistribute it and/or modify
-- it under the terms of the GNU General Public License as published by
-- the Free Software Foundation, either version 3 of the License, or
-- (at your option) any later version.
--
-- This program is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-- GNU General Public License for more details.
--
-- You should have received a copy of the GNU General Public License
-- along with this program. If not, see http://www.gnu.org/licenses/.
CREATE TABLE llx_actioncomm_reminder(
-- BEGIN MODULEBUILDER FIELDS
rowid integer AUTO_INCREMENT PRIMARY KEY NOT NULL,
dateremind datetime NOT NULL,
typeremind varchar(32) NOT NULL,
fk_user integer NOT NULL,
offsetvalue integer NOT NULL,
offsetunit varchar(1) NOT NULL,
status integer NOT NULL DEFAULT 0
-- END MODULEBUILDER FIELDS
) ENGINE=innodb;

View File

@@ -375,7 +375,7 @@ if ($dirins && $action == 'addproperty' && !empty($module) && ! empty($tabobj))
'arrayofkeyval'=>GETPOST('proparrayofkeyval','none'), // Example json string '{"0":"Draft","1":"Active","-1":"Cancel"}'
'visible'=>GETPOST('propvisible','int'),'enabled'=>GETPOST('propenabled','int'),
'position'=>GETPOST('propposition','int'),'notnull'=>GETPOST('propnotnull','int'),'index'=>GETPOST('propindex','int'),'searchall'=>GETPOST('propsearchall','int'),
'isameasure'=>GETPOST('propisameasure','int'), 'comment'=>GETPOST('propcomment','alpha'),'help'=>GETPOST('prophelp'));
'isameasure'=>GETPOST('propisameasure','int'), 'comment'=>GETPOST('propcomment','alpha'),'help'=>GETPOST('prophelp','alpha'));
if (! empty($addfieldentry['arrayofkeyval']) && ! is_array($addfieldentry['arrayofkeyval']))
{
@@ -401,14 +401,14 @@ if ($dirins && $action == 'addproperty' && !empty($module) && ! empty($tabobj))
if (! $error)
{
clearstatcache();
setEventMessages($langs->trans('FilesForObjectUpdated', $objectname), null);
// Make a redirect to reload all data
header("Location: ".DOL_URL_ROOT.'/modulebuilder/index.php?tab=objects&module='.$module.'&tabobj='.$objectname);
clearstatcache(true);
sleep(4); // With sleep 2, after the header("Location...", the new page output does not see the change. TODO Why do we need this sleep ?
// Make a redirect to reload all data
header("Location: ".DOL_URL_ROOT.'/modulebuilder/index.php?tab=objects&module='.$module.'&tabobj='.$objectname.'&nocache='.time());
clearstatcache();
exit;
}
}
@@ -437,14 +437,14 @@ if ($dirins && $action == 'confirm_deleteproperty' && $propertykey)
if (! $error)
{
clearstatcache();
setEventMessages($langs->trans('FilesForObjectUpdated', $objectname), null);
clearstatcache(true);
sleep(4); // With sleep 2, after the header("Location...", the new page output does not see the change. TODO Why do we need this sleep ?
// Make a redirect to reload all data
header("Location: ".DOL_URL_ROOT.'/modulebuilder/index.php?tab=objects&module='.$module.'&tabobj='.$objectname);
clearstatcache();
exit;
}
}
@@ -768,6 +768,7 @@ if ($action == 'reset' && $user->admin)
}
/*
* View
*/
@@ -1528,9 +1529,10 @@ elseif (! empty($module))
if (! empty($tmpobjet))
{
$reflector = new ReflectionClass($tabobj);
$properties = $reflector->getProperties(); // Can also use get_object_vars
//$propdefault = $reflector->getDefaultProperties(); // Can also use get_object_vars
$reflectorproperties = $reflector->getProperties(); // Can also use get_object_vars
$reflectorpropdefault = $reflector->getDefaultProperties(); // Can also use get_object_vars
//$propstat = $reflector->getStaticProperties();
//var_dump($reflectorpropdefault);
print load_fiche_titre($langs->trans("Properties"), '', '');
@@ -1565,7 +1567,10 @@ elseif (! empty($module))
print '<td></td>';
print '</tr>';
$properties = dol_sort_array($tmpobjet->fields, 'position');
// We must use $reflectorpropdefault['fields'] to get list of fields because $tmpobjet->fields may have been
// modified during the constructor and we want value into head of class before constructor is called.
//$properties = dol_sort_array($tmpobjet->fields, 'position');
$properties = dol_sort_array($reflectorpropdefault['fields'], 'position');
if (! empty($properties))
{

View File

@@ -1,8 +1,5 @@
<?php
/* Copyright (C) 2007-2017 Laurent Destailleur <eldy@users.sourceforge.net>
* Copyright (C) 2014-2016 Juanjo Menent <jmenent@2byte.es>
* Copyright (C) 2015 Florian Henry <florian.henry@open-concept.pro>
* Copyright (C) 2015 Raphaël Doursenaud <rdoursenaud@gpcsolutions.fr>
/* Copyright (C) 2017 Laurent Destailleur <eldy@users.sourceforge.net>
* Copyright (C) ---Put here your own copyright and developer email---
*
* This program is free software; you can redistribute it and/or modify
@@ -228,14 +225,14 @@ class MyObject extends CommonObject
*
* @return int <0 if KO, 0 if not found, >0 if OK
*/
public function fetchLines()
/*public function fetchLines()
{
$this->lines=array();
// Load lines with object MyObjectLine
return count($this->lines)?1:0;
}
}*/
/**
* Update object into database
@@ -322,17 +319,6 @@ class MyObject extends CommonObject
return $result;
}
/**
* Return link to download file from a direct external access
*
* @param int $withpicto Add download picto into link
* @return string HTML link to file
*/
function getDirectExternalLink($withpicto=0)
{
return 'todo';
}
/**
* Retourne le libelle du status d'un user (actif, inactif)
*

View File

@@ -213,7 +213,7 @@ $sql.=$hookmanager->resPrint;
$sql=preg_replace('/, $/','', $sql);
$sql.= " FROM ".MAIN_DB_PREFIX."myobject as t";
if (is_array($extrafields->attribute_label) && count($extrafields->attribute_label)) $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."myobject_extrafields as ef on (t.rowid = ef.fk_object)";
if ($object->getIsmultientitymanaged() == 1) $sql.= " WHERE t.entity IN (".getEntity('myobject').")";
if ($object->ismultientitymanaged == 1) $sql.= " WHERE t.entity IN (".getEntity('myobject').")";
else $sql.=" WHERE 1 = 1";
foreach($search as $key => $val)
{

View File

@@ -13,6 +13,6 @@
-- You should have received a copy of the GNU General Public License
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
INSERT INTO llx_myobject VALUES (
INSERT INTO llx_mymodule_myobject VALUES (
1, 1, 'mydata'
);

View File

@@ -257,7 +257,7 @@ $sql.=$hookmanager->resPrint;
$sql=preg_replace('/, $/','', $sql);
$sql.= " FROM ".MAIN_DB_PREFIX."websiteaccount as t";
if (is_array($extrafields->attribute_label) && count($extrafields->attribute_label)) $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."websiteaccount_extrafields as ef on (t.rowid = ef.fk_object)";
if ($objectwebsiteaccount->getIsmultientitymanaged() == 1) $sql.= " WHERE t.entity IN (".getEntity('websiteaccount').")";
if ($objectwebsiteaccount->ismultientitymanaged == 1) $sql.= " WHERE t.entity IN (".getEntity('websiteaccount').")";
else $sql.=" WHERE 1 = 1";
$sql.=" AND fk_soc = ".$object->id;
foreach($search as $key => $val)