1090 lines
48 KiB
PHP
1090 lines
48 KiB
PHP
<?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 l’UX)
|
||
// --------- 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 d’action (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 l’enregistrement 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 l’email assignée n’est 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 d’event -> 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'].' 
Res :'.$row['usa_aqui'].'
'. '<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'].' 
Res :'.$row['usa_aqui'].'
'. '<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'].' 
Responsable :'.$value['usa_aqui'].'
Echeance :'.$value['tach_echeance_date'];
|
||
$mem_titre=$value['gen_nom_fr'].' 
Demande :
'.$value['tach_note_demande'].'
Suivie :
'.$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'].' 
Responsable :'.$value['usa_aqui'].'
Echeance :'.$value['tach_echeance_date'];
|
||
$mem_titre=$value['gen_nom_fr'].' 
Demande :
'.$value['tach_note_demande'].'
Suivie :
'.$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 l’utilisateur
|
||
}
|
||
|
||
}
|
||
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 d’email ou pas d’eventId 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 n’existe 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 d’eventId ou pas d’email) 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)];
|
||
}
|
||
}
|
||
|
||
} |