Files
crm-ms1/application/models/Tache_model.php
2026-05-27 11:44:10 -04:00

1090 lines
48 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
/**
* Created by PhpStorm.
* User: Utilisateur
* Date: 2019-04-23
* Time: 10:21
*/
class Tache_model extends CI_Model {
public function __construct()
{
$this->load->database();
}
public function mod_getformtache($id,$section,$section_id)
{
global $mem_data, $validation;
$this->load->model('Config_model');
$this->load->model('FxForm_model');
// vas chercher les info de la fiche
$mem_data['section']=$section;
$mem_data['section_id']=$section_id;
$mem_data['id']=$id;
$mem_data['terminer'] =1;
$mem_data['projet']='';
if ($id != 0){
$info = $this->mod_getRecord($id);
$mem_data['terminer'] = $info->tach_active;
$mem_data['projet']=$info->com_compagnie.' ('.$info->proj_nom.')';
}
// -----------------------------------
$mem_champ = 'tach_aqui_id';
$mem_value = ($id == 0 ? '' : $info->$mem_champ);
$mem_data['select'][$mem_champ]['choix'] = $this->Config_model->conf_getRepresentantsClient();
// value multipli select
$mem_value = explode(',', $mem_value);
$mem_data['select'][$mem_champ]['value'] = $mem_value;
$mem_data['label'][$mem_champ] = 'Responsable ';
$mem_data['icon'][$mem_champ] = '';
// -----------------------------------------
// -------------------------------------------------------------------------
$mem_champ = 'tach_note_demande';
$mem_value = ($id == 0 ? '' : $info->$mem_champ);
$this->FxForm_model->fxinputtxt($mem_champ, $mem_value, 'Demande', '', 'Demande');
// -------------------------------------------------------------------------
// -------------------------------------------------------------------------
$mem_champ = 'tach_note_suivie';
$mem_value = ($id == 0 ? '' : $info->$mem_champ);
$this->FxForm_model->fxinputtxt($mem_champ, $mem_value, 'Suivie', '', 'Demande');
// -------------------------------------------------------------------------
$mem_champ = 'tach_echeance_date';
$mem_data['icon'][$mem_champ] = 'icon-append fa fa-calendar';
$mem_value = ($id == 0 ? '' : $info->$mem_champ);
$mem_data['value'][$mem_champ] = $mem_value;
$this->FxForm_model->fxinputtxt($mem_champ, $mem_value, 'Echeance', '', '', 'form_datetime', '', '');
// -------------------------------------------------------------------------
$mem_champ = 'tach_type';
if (strtoupper($section)=='PROJETS')
$mem_liste='a';
else
$mem_liste='b';
if (strtoupper($section) == 'PROJETS') {
$mem_liste = 'a';
} elseif (strtoupper($section) == 'CLIENTS') {
$mem_liste = 'a';
} elseif (strtoupper($section) == 'FOURNISSEURS') {
$mem_liste = 'a';
}else {
$mem_liste = 'b';
}
$mem_value = ($id == 0 ? '' : $info->$mem_champ);
$mem_data['select'][$mem_champ]['choix'] = $this->Config_model->conf_getGenresTache('fr', true, $mem_liste,'t');
// value multipli select
// $mem_value = explode(',', $mem_value);
$mem_data['select'][$mem_champ]['value'] = $mem_value;
if (strtoupper($section)=='PROJETS' || strtoupper($section)=='CLIENTS' || strtoupper($section)=='FOURNISSEURS')
$mem_data['label'][$mem_champ] = 'Statut';
else
$mem_data['label'][$mem_champ] = 'Type';
// -------------------------------------------------------------------------
$mem_champ = 'tach_statut';
$mem_value = ($id == 0 ? '' : $info->$mem_champ);
$mem_data['select'][$mem_champ]['choix'] = $this->Config_model->conf_getGenresTache('fr', true, $mem_liste,'s');
// value multipli select
// $mem_value = explode(',', $mem_value);
$mem_data['select'][$mem_champ]['value'] = $mem_value;
$mem_data['label'][$mem_champ] = 'Statut';
// $mem_data['validation'] = $this->FxForm_model->fxValidation($validation['rule'], $validation['message']);
return $mem_data;
}
public function mod_getforminfo($id,$section,$section_id)
{
$mem_data = array();
$mem_data = $this->mod_getformtache($id,$section,$section_id);
return $mem_data;
}
public function mod_createRecordbd($data,$section,$section_id,$details_id)
{
$pref='tach';
$mem_data=[];
// print_r($data);
foreach($data as $k=>$v){
if (substr($k,0,strlen($pref))==$pref) $mem_data[$k]=$v;
}
// print_r($mem_data);
$mem_data['tach_create_date']=date("Y-m-d H:i:s");
$mem_data['tach_active']=1;
$mem_data['tach_create_user_id']=$_SESSION['id'];
$mem_data['tach_section']=$section;
$mem_data['tach_section_id']=$section_id;
$mem_data['tach_details_id']=$details_id;
$this->db->insert('tach_details', $mem_data);
$id = $this->db->insert_id();
if($this->config->item('pw_client')=="ms1") {
// -------------------------------------------------------
// ----- Google Calendar (try/catch pour ne pas casser lUX)
// --------- BLOC DE TEST (à retirer plus tard) ----------
$info=$this->Config_model->fx_info_google_calendar($id);
log_message('debug', 'Contenu de $info : ' . print_r($info, true));
$aqui = $info['email'] ?? "";
log_message('debug', 'Contenu de : ' . $aqui);
$mem_data['nomclientfour']=$info["com_client_affiche"];
if ($mem_aqui=!"") {
$mem_data['tach_type_nom']=$this->Config_model->conf_getGenresTache_id( $mem_data['tach_type']);
$mem_data['tach_statut_nom']=$this->Config_model->conf_getGenresTache_id( $mem_data['tach_statut']);
$mem_data['tach_assignee_email']= $aqui;
$mem_data['tach_title'] = "⏱️𝗠·𝗦⁻¹🔸".$mem_data['nomclientfour']."".$mem_data['tach_type_nom']." ". $mem_data['tach_statut_nom'];
$mem_data['tach_description'] = "Ceci est une tâche insérée automatiquement via l'API Google Calendar.";
$mem_data['tach_start'] = $mem_data["tach_echeance_date"]; // heure de début
$mem_data['tach_end'] = $mem_data["tach_echeance_date"]; // heure de fin
$mem_data['tach_timezone'] = "America/Toronto"; // fuseau horaire
// $mem_data['tach_assignee_email'] = $mem_data["tach_assignee_email"]; // email cible
$this->create_google_reunion($mem_data, $id);
}
}
return $id;
}
public function mod_createRecordbdold($data,$section,$section_id,$details_id)
{
// if (!isset($data['com_actif']))
// $data['com_actif']=0;
// creation de la chaine de save
$pref='tach';
$mem_data=array();
foreach($data as $key => $value )
{
if (substr($key,0,strlen($pref))==$pref){
$mem_data[$key]=$value;
}
}
$mem_data['tach_create_date']=date("Y-m-d H:i:s");
$mem_data['tach_active']=1;
$mem_data['tach_create_user_id']=$_SESSION['id'];
$mem_data['tach_section']=$section;
$mem_data['tach_section_id']=$section_id;
$mem_data['tach_details_id']=$details_id;
$str = $this->db->insert('tach_details', $mem_data);
$ok=true;
return $this->db->insert_id();
}
public function mod_saveRecordbd($data, $id)
{
$pref = 'tach';
$mem_data = array();
// 1) Collecte des champs tach_*
foreach ($data as $key => $value) {
if (substr($key, 0, strlen($pref)) == $pref) {
$mem_data[$key] = $value;
}
}
// 2) Boutons daction (Activer/Terminer)
if (isset($data['button'])) {
if ($data['button'] == 'Activer') {
$mem_data['tach_active'] = 1;
}
if ($data['button'] == 'Terminer') {
$mem_data['tach_active'] = 0;
$mem_data['tach_fin_user_date'] = date("Y-m-d H:i:s");
$mem_data['tach_fin_user_id'] = $_SESSION['id'];
}
}
// 3) Update BD
$mem_where = "tach_id = " . (int)$id;
$this->db->update('tach_details', $mem_data, $mem_where);
// 4) Sync Google Calendar (client ms1 seulement)
if ($this->config->item('pw_client') == "ms1") {
// On relit lenregistrement complet (incluant eventId/email potentiels)
$row = $this->db->get_where('tach_details', ['tach_id' => (int)$id])->row_array();
log_message('debug', 'mod saveContenu de $row: ' . $row);
// Si lemail assignée nest pas là, on refait le lookup comme au CREATE
if (empty($row['tach_assignee_email']) && !empty($row['tach_aqui_id'])) {
$info=$this->Config_model->fx_info_google_calendar($id);
$mem_data['nomclientfour']=$info["com_client_affiche"];
$aqui = $info['email'] ?? "";
log_message('debug', 'mod saveContenu de : ' . $aqui);
$row['tach_assignee_email'] = $aqui;
}
$mem_data['tach_type_nom']=$this->Config_model->conf_getGenresTache_id( $mem_data['tach_type']);
$mem_data['tach_statut_nom']=$this->Config_model->conf_getGenresTache_id( $mem_data['tach_statut']);
$row['tach_title'] = "⏱️𝗠·𝗦⁻¹🔸". $mem_data['nomclientfour']."".$mem_data['tach_type_nom']." ". $mem_data['tach_statut_nom'];
// Valeurs par défaut cohérentes avec le CREATE
$row['tach_timezone'] = "America/Toronto";
// Source de vérité: tach_echeance_date utilisé pour start/end
$row['tach_start'] = $row['tach_echeance_date'];
$row['tach_end'] = $row['tach_echeance_date'];
// ROUTAGE selon le bouton ou édition simple
if (isset($data['button'])) {
if ($data['button'] == 'Terminer') {
// Ferme la tâche -> SUPPRIME lévénement
$this->delete_google_reunion($row, $id);
} elseif ($data['button'] == 'Activer') {
// Active :
// - pas devent -> CREATE
// - event présent -> UPDATE
if (empty($row['tach_gcal_event_id'])) {
$this->create_google_reunion($row, $id);
} else {
$this->update_google_reunion($row, $id);
}
} else {
// Autres boutons -> traite comme une ÉDITION
if (!empty($row['tach_gcal_event_id']) && (int)$row['tach_active'] === 1) {
$this->update_google_reunion($row, $id);
}
}
} else {
// ÉDITION sans bouton -> UPDATE si actif et event existant
if (!empty($row['tach_gcal_event_id']) && (int)$row['tach_active'] === 1) {
$this->update_google_reunion($row, $id);
}
}
}
return true;
}
public function mod_saveRecordbdold( $data,$id)
{
$pref='tach';
// creation de la chaine de save
$mem_data = array();
foreach ($data as $key => $value) {
if (substr($key, 0, strlen($pref)) == $pref) {
$mem_data[$key] = $value;
}
}
if (isset($data['button'])){
if ($data['button']=='Activer'){
$mem_data['tach_active']=1;
}
if ($data['button']=='Terminer'){
$mem_data['tach_active']=0;
$mem_data['tach_fin_user_date']=date("Y-m-d H:i:s");
$mem_data['tach_fin_user_id']=$_SESSION['id'];
}
}
$mem_where = "tach_id =" . $id;
$str = $this->db->update('tach_details', $mem_data, $mem_where);
$ok = true;
return $ok;
}
public function mod_getRecordCount()
{
$this->db->select('count(*) as allcount');
$this->db->from('tach_details');
$query = $this->db->get();
$result = $query->result_array();
return $result[0]['allcount'];
}
public function mod_getRecord($id)
{
$this->db->select('*');
$this->db->from('tach_details');
$this->db->join('proj_entete', 'tach_details.tach_section_id = proj_id and tach_details.tach_section="Projets"', 'left');
$this->db->join('cli_compte', 'proj_entete.proj_client_id = com_id', 'left');
$this->db->where('tach_id',$id);
$this->db->limit(1);
$query = $this->db->get();
return $query->row();
}
public function mod_getRecordCountfilter($filtre1 = "", $filtre2 = "", $filtre3 = "",$filtre4 = "",$listactive)
{
// list la bb client
$this->db->select('count(*) as allcount');
$this->db->from('tach_details');
$this->db->join('usa_usagers aqui', 'tach_details.tach_aqui_id = aqui.usa_id ', 'left');
$this->db->join('usa_usagers create', 'tach_details.tach_create_user_id = create.usa_id ', 'left');
$this->db->join('usa_usagers fin', 'tach_details.tach_create_user_id = fin.usa_id ', 'left');
$this->db->join('tach_genres', 'tach_details.tach_type = gen_id', 'left');
if ($filtre1 != "")
$this->db->where("tach_section='" . $filtre1."'");
if ($filtre2 != "")
$this->db->where("tach_details.tach_aqui_id",$filtre2);
if ($filtre3 != "")
$this->db->where("tach_type=" . $filtre3);
if ($listactive==1)
$this->db->where("tach_details.tach_active!=0");
$query = $this->db->get();
$result = $query->result_array();
return $result[0]['allcount'];
}
public function mod_getRecords($record, $recordPerPage,$filtre1 = "", $filtre2 = "", $filtre3 = "",$filtre4 = "",$trie="",$listactive)
{
// list la bb client
$this->db->select('*,statut.gen_id as statutid, type.gen_nom_fr as type_fr, statut.gen_nom_fr as statut_fr,projdetails.det_desc,DATEDIFF( now(),tach_create_date) AS days,fournisseur.com_compagnie as fournisseur,client.com_compagnie as compagnie, CONCAT(aqui.usa_prenom," ",aqui.usa_nom) as usa_aqui,CONCAT(create.usa_prenom," ",create.usa_nom) as usa_create,CONCAT(fin.usa_prenom," ",fin.usa_nom) as usa_fin');
$this->db->from('tach_details');
$this->db->join('usa_usagers aqui', 'tach_details.tach_aqui_id = aqui.usa_id ', 'left');
$this->db->join('usa_usagers create', 'tach_details.tach_create_user_id = create.usa_id ', 'left');
$this->db->join('usa_usagers fin', 'tach_details.tach_create_user_id = fin.usa_id ', 'left');
$this->db->join('tach_genres type', 'tach_details.tach_type = type.gen_id', 'left');
$this->db->join('tach_genres statut', 'tach_details.tach_statut = statut.gen_id', 'left');
$this->db->join('proj_entete', 'tach_details.tach_section_id = proj_id and (tach_details.tach_section="Projets" or tach_details.tach_section="projetsclient" or tach_details.tach_section="projetsfournisseur" )', 'left');
$this->db->join('cli_compte client', 'tach_details.tach_section_id = client.com_id and tach_details.tach_section="Clients"', 'left');
$this->db->join('fou_compte fournisseur', 'tach_details.tach_section_id = fournisseur.com_id and tach_details.tach_section="Fournisseurs"', 'left');
$this->db->join('proj_details_details projdetails', 'tach_details.tach_details_id = projdetails.detail_id', 'left');
$this->db->join('proj_details projdetails1', 'tach_details.tach_details_id = projdetails1.proj_det_id', 'left');
$this->db->join('pro_descriptions prodescriptions', 'projdetails1.proj_prod_id = prodescriptions.des_id', 'left');
$this->db->join('cli_compte', 'proj_entete.proj_client_id = cli_compte.com_id', 'left');
if ($trie != "null"){
$this->db->order_by($trie);
}else{
}
//$this->db->order_by('tach_echeance_date');
if ($filtre1 != "")
$this->db->where("tach_section='" . $filtre1."'");
if ($filtre2 != "")
$this->db->where("tach_details.tach_aqui_id",$filtre2);
if ($filtre4 != "")
$this->db->where("tach_details.tach_create_user_id",$filtre4);
if ($filtre3 != "")
$this->db->where("tach_type=" . $filtre3);
if ($listactive==1)
$this->db->where("tach_details.tach_active!=0");
$query = $this->db->get();
$result = $query->result_array();
// a faire sl affiche tableau de tache
// print_r($result);
return $result;
}
public function mod_getRecordstache($record, $recordPerPage,$filtre1 = "", $filtre2 = "", $filtre3 = "",$filtre4 = "",$trie="",$listactive)
{
// list la bb client
$this->db->select('*,statut.gen_id as statutid, type.gen_nom_fr as type_fr, statut.gen_nom_fr as statut_fr,projdetails.det_desc,DATEDIFF( now(),tach_create_date) AS days,fournisseur.com_compagnie as fournisseur,client.com_compagnie as compagnie, CONCAT(aqui.usa_prenom," ",aqui.usa_nom) as usa_aqui,CONCAT(create.usa_prenom," ",create.usa_nom) as usa_create,CONCAT(fin.usa_prenom," ",fin.usa_nom) as usa_fin');
$this->db->from('tach_details');
$this->db->join('usa_usagers aqui', 'tach_details.tach_aqui_id = aqui.usa_id ', 'left');
$this->db->join('usa_usagers create', 'tach_details.tach_create_user_id = create.usa_id ', 'left');
$this->db->join('usa_usagers fin', 'tach_details.tach_create_user_id = fin.usa_id ', 'left');
$this->db->join('tach_genres type', 'tach_details.tach_type = type.gen_id', 'left');
$this->db->join('tach_genres statut', 'tach_details.tach_statut = statut.gen_id', 'left');
$this->db->join('proj_entete', 'tach_details.tach_section_id = proj_id and (tach_details.tach_section="Projets" or tach_details.tach_section="projetsclient" or tach_details.tach_section="projetsfournisseur" )', 'left');
$this->db->join('cli_compte client', 'tach_details.tach_section_id = client.com_id and tach_details.tach_section="Clients"', 'left');
$this->db->join('fou_compte fournisseur', 'tach_details.tach_section_id = fournisseur.com_id and tach_details.tach_section="Fournisseurs"', 'left');
$this->db->join('proj_details_details projdetails', 'tach_details.tach_details_id = projdetails.detail_id', 'left');
$this->db->join('proj_details projdetails1', 'tach_details.tach_details_id = projdetails1.proj_det_id', 'left');
$this->db->join('pro_descriptions prodescriptions', 'projdetails1.proj_prod_id = prodescriptions.des_id', 'left');
$this->db->join('cli_compte', 'proj_entete.proj_client_id = cli_compte.com_id', 'left');
if ($trie != "null"){
if ($trie === 'tach_echeance_date') {
$this->db->order_by(
"CASE
WHEN tach_details.tach_echeance_date = '0000-00-00'
OR tach_details.tach_echeance_date IS NULL
THEN '9999-12-31'
ELSE tach_details.tach_echeance_date
END",
null,
false
);
} else {
$this->db->order_by($trie);
}
}
//$this->db->order_by('tach_echeance_date');
if ($filtre1 != "")
$this->db->where("statut.gen_id='" . $filtre1."'");
if ($filtre2 != "")
$this->db->where("tach_details.tach_aqui_id",$filtre2);
if ($filtre4 != "")
$this->db->where("tach_details.tach_create_user_id",$filtre4);
if ($filtre3 != "")
$this->db->where("tach_type=" . $filtre3);
if ($listactive==1)
$this->db->where("tach_details.tach_active!=0");
$query = $this->db->get();
$result = $query->result_array();
// a faire sl affiche tableau de tache
// print_r($result);
return $result;
}
public function mod_listtache($section,$section_id,$details_id=0)
{
$this->db->select('*,statut.gen_id as statutid,genres.gen_id as typeid,statut.gen_nom_fr as statut_fr,genres.gen_nom_fr as gen_nom_fr, CONCAT(aqui.usa_prenom," ",aqui.usa_nom) as usa_aqui,CONCAT(create.usa_prenom," ",create.usa_nom) as usa_create,CONCAT(fin.usa_prenom," ",fin.usa_nom) as usa_fin');
$this->db->from('tach_details');
$this->db->join('usa_usagers aqui', 'tach_details.tach_aqui_id = aqui.usa_id ', 'left');
$this->db->join('usa_usagers create', 'tach_details.tach_create_user_id = create.usa_id ', 'left');
$this->db->join('usa_usagers fin', 'tach_details.tach_create_user_id = fin.usa_id ', 'left');
$this->db->join('tach_genres genres', 'tach_details.tach_type = genres.gen_id', 'left');
$this->db->join('tach_genres statut', 'tach_details.tach_statut = statut.gen_id', 'left');
$this->db->where('tach_section',$section);
$this->db->where('tach_section_id',$section_id);
$this->db->join('proj_details_details projdetails', 'tach_details.tach_details_id = projdetails.detail_id', 'left');
$this->db->join('proj_details projdetails1', 'tach_details.tach_details_id = projdetails1.proj_det_id', 'left');
$this->db->join('pro_descriptions prodescriptions', 'projdetails1.proj_prod_id = prodescriptions.des_id', 'left');
$this->db->join('fou_compte fournisseur', 'projdetails1.proj_fou_id = fournisseur.com_id', 'left');
if ($details_id!=0){
$this->db->where('tach_details_id',$details_id);
}
$this->db->order_by('tach_echeance_date');
$query = $this->db->get();
$result = $query->result_array();
return $result ;
}
public function mod_listtache_count_jour($filtre1)
{
$this->db->select('*,projet.com_compagnie as com_projet, CONCAT(aqui.usa_prenom," ",aqui.usa_nom) as usa_aqui,CONCAT(create.usa_prenom," ",create.usa_nom) as usa_create,CONCAT(fin.usa_prenom," ",fin.usa_nom) as usa_fin,,fournisseur.com_compagnie as fournisseur');
$this->db->from('tach_details');
$this->db->join('usa_usagers aqui', 'tach_details.tach_aqui_id = aqui.usa_id ', 'left');
$this->db->join('usa_usagers create', 'tach_details.tach_create_user_id = create.usa_id ', 'left');
$this->db->join('usa_usagers fin', 'tach_details.tach_create_user_id = fin.usa_id ', 'left');
$this->db->join('tach_genres', 'tach_details.tach_type = gen_id', 'left');
$this->db->join('proj_entete', 'tach_details.tach_section_id = proj_id AND LOWER(tach_details.tach_section) LIKE "%projet%"', 'left');
$this->db->join('cli_compte client', 'tach_details.tach_section_id = client.com_id and tach_details.tach_section="Clients"', 'left');
$this->db->join('cli_compte projet', 'projet.com_id=proj_entete.proj_client_id AND LOWER(tach_details.tach_section) LIKE "%projet%"', 'left');
$this->db->join('fou_compte fournisseur', 'tach_details.tach_section_id = fournisseur.com_id and tach_details.tach_section="Fournisseurs"', 'left');
if ($filtre1!=0)
$this->db->where('tach_details.tach_aqui_id',$filtre1);
// $this->db->where('tach_section',$section);
// $this->db->where('tach_section_id',$section_id);
$this->db->where('tach_active',1);
$this->db->order_by('tach_echeance_date');
$query = $this->db->get();
$result = $query->result_array();
$sortie['details']=$result;
$sortie['jour']=array();
$index_date=0;
$mem_date='';
foreach ($sortie['details'] as $key => $row){
$goto=$row['tach_section'];
if($row['tach_section']=='projetsclient' || $row['tach_section']=='projetsfournisseur'){
$goto='projets';}
if($mem_date!=$row['tach_echeance_date']){
$index_date++;
$mem_date=$row['tach_echeance_date'];
$sortie['jour'][$index_date]['start']=$row['tach_echeance_date'];
$sortie['jour'][$index_date]['qte']=0;
$sortie['jour'][$index_date]['details']='';
}
//$mem_link_go = anchor( $row['tach_section'].'/formsl/' .$row['tach_section_id'], ' ', 'target="tache" class="btn btn-primary btn-circle glyphicon glyphicon-circle-arrow-right " ');
$mem_link_go = anchor( $goto.'/form/' .$row['tach_section_id'], ' ', 'class="btn btn-primary btn-circle glyphicon glyphicon-circle-arrow-right " ');
$sortie['jour'][$index_date]['qte']=$sortie['jour'][$index_date]['qte']+1;
$sortie['jour'][$index_date]['details']=$sortie['jour'][$index_date]['details'].' '.$mem_link_go.' '.$row['gen_nom_fr'].' •'.$row['com_projet'].'•'.$row['com_compagnie'].$row['proj_nom'].' &#013;&#010;Res :'.$row['usa_aqui'].'&#013;&#010;'. '<br>';
}
if ($sortie['details']!=null){
if($mem_date!=$row['tach_echeance_date']){
$index_date++;
$sortie['jour'][$index_date]['start']=$row['tach_echeance_date'];
$sortie['jour'][$index_date]['qte']=0;
}
$goto=$row['tach_section'];
if($row['tach_section']=='projetsclient' || $row['tach_section']=='projetsfournisseur'){
$goto='projets';}
// $mem_link_go = anchor( $row['tach_section'].'/formsl2/' .$row['tach_section_id'], ' ', 'target="tache" class="btn btn-primary btn-circle glyphicon glyphicon-circle-arrow-right " ');
$mem_link_go = anchor( $goto.'/form/' .$row['tach_section_id'], ' ', 'class="btn btn-primary btn-circle glyphicon glyphicon-circle-arrow-right " ');
$sortie['jour'][$index_date]['qte']=$sortie['jour'][$index_date]['qte']+1;
$sortie['jour'][$index_date]['details']=$sortie['jour'][$index_date]['details'].' '.$mem_link_go.' '.$row['gen_nom_fr'].' '.$row['com_projet'].' '.$row['com_compagnie'].$row['proj_nom'].' &#013;&#010;Res :'.$row['usa_aqui'].'&#013;&#010;'. '<br>';
}
return $sortie ;
}
public function mod_listtache_btn($section,$section_id,$details_id=0)
{
$data=$this->Tache_model->mod_listtache($section,$section_id,$details_id);
$mem_bt='';
foreach($data as $key => $value )
{
$mem_color='btn-warning';
if ($value['tach_active']==0){
$mem_color='btn-success';
}else{
if ($value['tach_echeance_date']< date("Y-m-d")){
$mem_color='btn-danger';
}
}
// $mem_titre=$value['gen_nom_fr'].' &#013;&#010;Responsable :'.$value['usa_aqui'].'&#013;&#010;Echeance :'.$value['tach_echeance_date'];
$mem_titre=$value['gen_nom_fr'].' &#013;&#010;Demande :&#013;&#010;'.$value['tach_note_demande'].'&#013;&#010;Suivie :&#013;&#010;'.$value['tach_note_suivie'];
$mem_bt =$mem_bt.'<a data-toggle="modal" data-section="'.$value['tach_section'].'" data-id="'.$value['tach_id'].'" data-section_id="'.$value['tach_section_id'].'" class="btn '.$mem_color.' btn-circle glyphicon glyphicon-bell popup" title="'.$mem_titre.'"></a>';
// $mem_bt =$mem_bt.'<a data-toggle="modal"';
// $mem_bt =$mem_bt.'a';
}
echo $mem_bt;
}
public function mod_listtache_projet_produit($section,$section_id,$details_id=0)
{
$data=$this->Tache_model->mod_listtache($section,$section_id,$details_id);
if (strtoupper($section)=='PROJETS')
$mem_bt = '<table class="table table-striped table-bordered table-hove"><thead><tr><th></th><th>Echeance</th> <th>Statut</th><th>Produit</th><th>Responsable</th></tr></thead><tbody>';
else
$mem_bt = '<table class="table table-striped table-bordered table-hove"><thead><tr><th></th><th>Echeance</th><th>Type</th><th>Statut</th><th>Produit</th><th>Responsable</th></tr></thead><tbody>';
foreach($data as $key => $value )
{
$mem_color='btn-warning';
if ($value['tach_active']==0){
$mem_color='btn-success';
}else{
if ($value['tach_echeance_date']< date("Y-m-d")){
$mem_color='btn-danger';
}
}
// $mem_titre=$value['gen_nom_fr'].' &#013;&#010;Responsable :'.$value['usa_aqui'].'&#013;&#010;Echeance :'.$value['tach_echeance_date'];
$mem_titre=$value['gen_nom_fr'].' &#013;&#010;Demande :&#013;&#010;'.$value['tach_note_demande'].'&#013;&#010;Suivie :&#013;&#010;'.$value['tach_note_suivie'];
// $mem_row = '<div class="row"><div class="col-sm-1" ><a data-toggle="modal" data-section="'.$value['tach_section'].'" data-id="'.$value['tach_id'].'" data-section_id="'.$value['tach_section_id'].'" class="btn '.$mem_color.' btn-circle glyphicon glyphicon-bell popup" title="'.$mem_titre.'"></a></div>';
// $mem_row =$mem_row.'<div class="col-sm-2" >'.$value['usa_aqui'].'</div>';
// $mem_row =$mem_row.'<div class="col-sm-3" >'.$value['tach_echeance_date'].'</div>';
// $mem_row =$mem_row.'<div class="col-sm-3" >'.$value['des_nom_fr'].'</div></div>';
// $mem_row = '<td align="left"><a data-toggle="modal" data-section="'.$value['tach_section'].'" data-id="'.$value['tach_id'].'" data-section_id="'.$value['tach_section_id'].'" class="btn '.$mem_color.' btn-circle glyphicon glyphicon-bell popup" title="'.$mem_titre.'"></a></td><td align="left">'.$value['usa_aqui'].' </td><td align="left">'.$value['tach_echeance_date'].'</td><td align="left">'.$value['com_compagnie'].'-'.$value['det_desc'].'-'.$value['des_nom_fr'].'</td></tr><tr>';
$mem_row = '<tr><td width="10"><a data-toggle="modal" data-section="'.$value['tach_section'].'" data-id="'.$value['tach_id'].'" data-section_id="'.$value['tach_section_id'].'" class="btn '.$mem_color.' btn-circle glyphicon glyphicon-bell popup" title="'.$mem_titre.'"></a></td>';
$mem_row =$mem_row. '<td align="left" width="100">'.$value['tach_echeance_date'].' </td>';
if (strtoupper($section)!='PROJETS'){
$mem_row =$mem_row. '<td class = "statuttach_'.$value['typeid'] .'" >'.$value['gen_nom_fr'].'</td>';
$mem_row =$mem_row. '<td class = "statuttach_'.$value['statutid'] .'" >'.$value['statut_fr'].'</td>';
}else{ $mem_row =$mem_row. '<td class = "statut_'.$value['tach_type'] .'" >'.$value['gen_nom_fr'].'</td>';
}
$mem_row =$mem_row. '<td>'.$value['com_compagnie'].'-'.$value['det_desc'].'-'.$value['des_nom_fr'].'</td>';
$mem_row =$mem_row. '<td>'.$value['usa_aqui'].' </td></tr>';
$mem_bt=$mem_bt.$mem_row;
// $mem_bt =$mem_bt.'a';
}
$mem_bt =$mem_bt. '</tbody></table>';
echo $mem_bt;
}
function create_google_reunion($data, $id){
$tach_section_id = (int) trim($data['tach_section_id']);
$goto=$data['tach_section'];
if($data['tach_section']=='projetsclient' || $data['tach_section']=='projetsfournisseur'){
$goto='projets';}
$base = rtrim($this->config->item('base_url'), '/'); // CI3
$href = $base . '/index.php/' . $goto. '/form/' . $tach_section_id ;
$data['tach_description'] = $data['tach_note_demande'] .'<br><a href="' . $href . '" target="tache">CRM</a>';
log_message('debug', 'create Contenu de $data : ' . print_r($data, true));
try {
try {
$rid = uniqid('GCAL:', false); // id corrélé pour suivre une exécution
log_message('error', "$rid ENTER createEvent()"); // marqueur d'entrée
$this->load->library('GCalService');
log_message('error', "$rid lib GCalService loaded=" . (isset($this->gcalservice) ? 'yes' : 'no'));
// Tâche / contexte (si $id existe dans ce scope)
if (isset($id)) {
log_message('error', "$rid tach_id=$id");
} else {
log_message('error', "$rid WARN tach_id not set in this scope");
}
// Données entrantes
$assignee = $data['tach_assignee_email'] ?? '';
$tz = $data['tach_timezone'] ?? 'America/Toronto';
$startRaw = $data['tach_start'] ?? '';
$endRaw = $data['tach_end'] ?? '';
$dueRaw = $data['tach_echeance_date'] ?? '';
log_message('error', "$rid INPUT assignee=$assignee tz=$tz startRaw=$startRaw endRaw=$endRaw dueRaw=$dueRaw");
// Convertis vers ISO8601
$startIso = $startRaw ? date('c', strtotime($startRaw)) : '';
$endIso = $endRaw ? date('c', strtotime($endRaw)) : '';
// **** AUTO-PLACEMENT si heures manquantes/minuit ****
$baseTime = $this->config->item('gcal_autoplace_time') ?? '08:00';
$durationMin = (int)($this->config->item('gcal_autoplace_duration') ?? 1);
$dateYmd = !empty($dueRaw)
? date('Y-m-d', strtotime($dueRaw))
: date('Y-m-d', strtotime($startRaw ?: 'now'));
$isMidnightStart = !empty($startRaw) && (substr(date('H:i', strtotime($startRaw)), 0, 5) === '00:00');
$isMidnightEnd = !empty($endRaw) && (substr(date('H:i', strtotime($endRaw)), 0, 5) === '00:00');
log_message('error', "$rid TIME pre slot startIso=$startIso endIso=$endIso dateYmd=$dateYmd midStart=" . ($isMidnightStart?'1':'0') . " midEnd=" . ($isMidnightEnd?'1':'0'));
if (empty($startRaw) || empty($endRaw) || $isMidnightStart || $isMidnightEnd) {
log_message('error', "$rid CALL gcal_find_slot_minute assignee=$assignee baseTime=$baseTime durationMin=$durationMin");
$slot = $this->gcal_find_slot_minute($assignee, $dateYmd, $tz, $baseTime, $durationMin);
$startIso = $slot['startIso'] ?? $startIso;
$endIso = $slot['endIso'] ?? $endIso;
log_message('error', "$rid SLOT result startIso=$startIso endIso=$endIso");
}
$payload = [
'summary' => $data['tach_title'] ?? 'Tâche',
'description' => $data['tach_description'] ?? '',
'start' => $startIso,
'end' => $endIso,
'timezone' => $tz,
];
// Log du payload (compact, sans caractères échappés moches)
$payloadLog = json_encode($payload, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
log_message('error', "$rid PAYLOAD $payloadLog");
// Avant l'appel Google
$calendarId = 'primary';
log_message('error', "$rid CALL GCalService.createEvent(subject=$assignee, calendarId=$calendarId)");
$res = $this->gcalservice->createEvent($assignee, $calendarId, $payload);
// Résultat Google
$eventId = is_array($res) ? ($res['eventId'] ?? '') : '';
$gcalIdOut = is_array($res) ? ($res['calendarId'] ?? '') : '';
log_message('error', "$rid RETURN eventId=$eventId calendarIdOut=$gcalIdOut");
// Update DB
if (isset($id)) {
$okDb = $this->db->update('tach_details', [
'tach_gcal_event_id' => $eventId,
'tach_gcal_calendar_id' => $gcalIdOut
], "tach_id=".$id);
log_message('error', "$rid DB update ok=" . ($okDb?'1':'0') . " affected_rows=" . $this->db->affected_rows());
} else {
log_message('error', "$rid SKIP DB update (tach_id missing)");
}
log_message('error', "$rid EXIT createEvent() OK");
} catch (Throwable $e) { // Throwable pour avoir les Error/TypeError aussi
log_message('error', "$rid EXCEPTION ". $e->getMessage());
log_message('error', "$rid TRACE \n". $e->getTraceAsString());
// (on garde ton comportement : pas de rethrow)
}
} catch (Exception $e) {
log_message('error', 'GCal create error: '.$e->getMessage());
// à toi de voir si tu veux notifier lutilisateur
}
}
function update_google_reunion($data, $id)
{
try {
$this->load->library('GCalService');
// Sécurité minimale
if (empty($data['tach_assignee_email']) || empty($data['tach_gcal_event_id'])) {
log_message('error', 'GCal UPDATE: pas demail ou pas deventId pour tach_id=' . $id);
return;
}
$tach_section_id = (int) trim($data['tach_section_id']);
$goto=$data['tach_section'];
if($data['tach_section']=='projetsclient' || $data['tach_section']=='projetsfournisseur'){
$goto='projets';}
$base = rtrim($this->config->item('base_url'), '/'); // CI3
$href = $base . '/index.php/' . $goto. '/form/' . $tach_section_id ;
$description = ($data['tach_note_demande'] ?? '') . '<br><a href="' . $href . '" target="tache">CRM</a>';
$tz = $data['tach_timezone'] ?? 'America/Toronto';
// Source de vérité pour les dates: tach_echeance_date (comme au create)
$startIso = date('c', strtotime($data['tach_echeance_date'] ?? $data['tach_start'] ?? 'now'));
$endIso = date('c', strtotime($data['tach_echeance_date'] ?? $data['tach_end'] ?? 'now'));
// ******** AJOUT : auto-placement minute par minute si heure absente ou à minuit ********
$baseTime = $this->config->item('gcal_autoplace_time') ?? '08:00';
$durationMin = (int)($this->config->item('gcal_autoplace_duration') ?? 1);
$dateYmd = !empty($data['tach_echeance_date'])
? date('Y-m-d', strtotime($data['tach_echeance_date']))
: date('Y-m-d', strtotime($data['tach_start'] ?? 'now'));
$hasStart = !empty($data['tach_start']);
$hasEnd = !empty($data['tach_end']);
$isMidnightStart = $hasStart && (substr(date('H:i', strtotime($data['tach_start'])),0,5) === '00:00');
$isMidnightEnd = $hasEnd && (substr(date('H:i', strtotime($data['tach_end'])),0,5) === '00:00');
if (!$hasStart || !$hasEnd || $isMidnightStart || $isMidnightEnd) {
$slot = $this->gcal_find_slot_minute($data['tach_assignee_email'], $dateYmd, $tz, $baseTime, $durationMin);
$startIso = $slot['startIso'];
$endIso = $slot['endIso'];
}
// ******** FIN AJOUT ********
$payload = [
'summary' => $data['tach_title'] ?? 'Tâche',
'description' => $description,
'start' => $startIso,
'end' => $endIso,
'timezone' => $tz,
];
// Update (PATCH) lévénement existant
$this->gcalservice->updateEvent($data['tach_assignee_email'], 'primary', $data['tach_gcal_event_id'], $payload);
log_message('debug', 'GCal UPDATE OK pour tach_id=' . $id);
} catch (Exception $e) {
// Si lévénement nexiste plus (404) → on le recrée proprement
$msg = $e->getMessage();
if (stripos($msg, '404') !== false || stripos($msg, 'not found') !== false) {
log_message('error', 'GCal update: event introuvable, recréation. tach_id=' . $id . ' | ' . $msg);
$this->create_google_reunion($data, $id);
} else {
log_message('error', 'GCal update error tach_id=' . $id . ' : ' . $msg);
}
}
}
function delete_google_reunion($data, $id)
{
try {
$this->load->library('GCalService');
if (!empty($data['tach_assignee_email']) && !empty($data['tach_gcal_event_id'])) {
$this->gcalservice->deleteEvent($data['tach_assignee_email'], 'primary', $data['tach_gcal_event_id']);
log_message('debug', 'GCal DELETE OK pour tach_id=' . $id);
} else {
log_message('debug', 'GCal DELETE: rien à supprimer (pas deventId ou pas demail) pour tach_id=' . $id);
}
// On nettoie les champs GCal dans la BD
$this->db->update('tach_details', [
'tach_gcal_event_id' => null,
'tach_gcal_calendar_id' => null,
], "tach_id=" . (int)$id);
} catch (Exception $e) {
log_message('error', 'GCal delete error tach_id=' . $id . ' : ' . $e->getMessage());
}
}
/**
* Trouve le prochain créneau libre (minute par minute) à partir d'une heure de base,
* en interrogeant UNIQUEMENT Google Calendar (FreeBusy) pour l'utilisateur ciblé.
*
* Prérequis config (application/config/config.php) :
* $config['google_sa_keyfile'] = APPPATH.'third_party/google/sa.json'; // chemin absolu vers la clé JSON du compte de service
* $config['google_sa_impersonate'] = true; // true si Domain-Wide Delegation activée et autorisée
*
* Notes :
* - Le compte de service doit avoir DWD activé et autorisé sur le scope https://www.googleapis.com/auth/calendar
* - L'admin Google Workspace doit autoriser le SA à "se faire passer" (impersonate) pour les utilisateurs du domaine
* - Cette fonction NE modifie rien dans Google ; elle ne fait que LIRE via FreeBusy.
*/
/**
* Google-only (Service Account + FreeBusy) — ne dépend pas de GCalService.
* Trouve le prochain créneau libre (minute par minute) à partir d'une heure de base.
* Prérequis config:
* $config['google_sa_keyfile'] = '/chemin/absolu/vers/sa.json';
* $config['google_sa_impersonate'] = true; // si DWD activée
*/
private function gcal_find_slot_minute($assigneeEmail, $dateYmd, $tz = 'America/Toronto', $baseTime = '08:00', $durationMin = 1)
{
if (empty($assigneeEmail)) {
log_message('error', '[GCal] gcal_find_slot_minute: assigneeEmail manquant');
$tzObj = new DateTimeZone('America/Toronto');
$start = new DateTime("$dateYmd $baseTime:00", $tzObj);
$end = (clone $start)->modify("+$durationMin minutes");
return ['startIso' => $start->format(DateTime::RFC3339), 'endIso' => $end->format(DateTime::RFC3339)];
}
try { $tzObj = new DateTimeZone($tz); } catch (Exception $e) { $tzObj = new DateTimeZone('America/Toronto'); }
$dayStart = new DateTime("$dateYmd 00:00:00", $tzObj);
$dayEnd = new DateTime("$dateYmd 23:59:59", $tzObj);
// Charger les classes Google (Composer/autoload)
if (!class_exists('Google_Client')) {
$paths = [
APPPATH.'third_party/google-api-php-client/vendor/autoload.php',
APPPATH.'third_party/google/vendor/autoload.php',
FCPATH.'vendor/autoload.php',
];
$loaded = false;
foreach ($paths as $p) { if (is_file($p)) { require_once $p; $loaded = true; break; } }
if (!$loaded) {
log_message('error', '[GCal] google-api-php-client introuvable (autoload.php).');
$start = new DateTime("$dateYmd $baseTime:00", $tzObj);
$end = (clone $start)->modify("+$durationMin minutes");
return ['startIso' => $start->format(DateTime::RFC3339), 'endIso' => $end->format(DateTime::RFC3339)];
}
}
$keyFile = $this->config->item('google_sa_keyfile');
$doImpersonate= (bool)($this->config->item('google_sa_impersonate') ?? true);
if (empty($keyFile) || !is_file($keyFile)) {
log_message('error', '[GCal] Clé de compte de service introuvable: '.$keyFile);
$start = new DateTime("$dateYmd $baseTime:00", $tzObj);
$end = (clone $start)->modify("+$durationMin minutes");
return ['startIso' => $start->format(DateTime::RFC3339), 'endIso' => $end->format(DateTime::RFC3339)];
}
try {
$client = new Google_Client();
$client->setAuthConfig($keyFile);
$client->setScopes([Google_Service_Calendar::CALENDAR_READONLY]);
if ($doImpersonate) { $client->setSubject($assigneeEmail); }
$service = new Google_Service_Calendar($client);
// FreeBusy sur la journée
$fbReq = new Google_Service_Calendar_FreeBusyRequest();
$fbReq->setTimeMin($dayStart->format(DateTime::RFC3339));
$fbReq->setTimeMax($dayEnd->format(DateTime::RFC3339));
$fbReq->setTimeZone($tz);
$item = new Google_Service_Calendar_FreeBusyRequestItem();
$item->setId('primary');
$fbReq->setItems([$item]);
$fbResp = $service->freebusy->query($fbReq);
$cals = $fbResp->getCalendars();
$busy = [];
if (isset($cals['primary'])) {
$blocks = $cals['primary']['busy'] ?? [];
foreach ($blocks as $b) {
$s = new DateTime($b['start']); $e = new DateTime($b['end']);
$s->setTimezone($tzObj); $e->setTimezone($tzObj);
$busy[] = [$s, $e];
}
} else {
foreach ($cals as $cal) {
$blocks = $cal['busy'] ?? [];
foreach ($blocks as $b) {
$s = new DateTime($b['start']); $e = new DateTime($b['end']);
$s->setTimezone($tzObj); $e->setTimezone($tzObj);
$busy[] = [$s, $e];
}
break;
}
}
// Tri par start
usort($busy, function($a,$b){ return $a[0] <=> $b[0]; });
// Balayage minute par minute
$candidate = new DateTime("$dateYmd $baseTime:00", $tzObj);
$endOfDay = new DateTime("$dateYmd 23:59:59", $tzObj);
for ($i=0; $i<1440; $i++) {
if ($candidate > $endOfDay) break;
$candEnd = (clone $candidate)->modify("+$durationMin minutes");
$conflict = false;
foreach ($busy as $pair) {
$bs = $pair[0]; $be = $pair[1];
if ($candidate < $be && $candEnd > $bs) { $conflict = true; break; }
}
if (!$conflict) {
return [
'startIso' => $candidate->format(DateTime::RFC3339),
'endIso' => $candEnd->format(DateTime::RFC3339),
];
}
$candidate->modify('+1 minute');
}
// Fallback (journée saturée)
$fallbackStart = new DateTime("$dateYmd $baseTime:00", $tzObj);
$fallbackEnd = (clone $fallbackStart)->modify("+$durationMin minutes");
return ['startIso' => $fallbackStart->format(DateTime::RFC3339), 'endIso' => $fallbackEnd->format(DateTime::RFC3339)];
} catch (Exception $e) {
log_message('error', '[GCal] gcal_find_slot_minute FreeBusy error: '.$e->getMessage());
$start = new DateTime("$dateYmd $baseTime:00", $tzObj);
$end = (clone $start)->modify("+$durationMin minutes");
return ['startIso' => $start->format(DateTime::RFC3339), 'endIso' => $end->format(DateTime::RFC3339)];
}
}
}