diff --git a/.gitattributes b/.gitattributes index 0523a53..da47483 100644 --- a/.gitattributes +++ b/.gitattributes @@ -13,6 +13,7 @@ formulaires/editer_abonnements_offre.php -text formulaires/editer_abonnements_offre_notifications.html -text formulaires/editer_abonnements_offre_notifications.php -text genie/abonnements_verifier_desactivation.php -text +genie/abonnements_verifier_echeances.php -text genie/abonnements_verifier_notifications.php -text inc/abonnements.php -text lang/abonnement.xml -text diff --git a/abonnements_pipelines.php b/abonnements_pipelines.php index 64e07d4..6e3ba33 100644 --- a/abonnements_pipelines.php +++ b/abonnements_pipelines.php @@ -41,57 +41,19 @@ function abonnements_optimiser_base_disparus($flux){ function abonnements_post_edition($flux){ // Si on modifie un abonnement if ($flux['args']['table'] == 'spip_abonnements') { + include_spip('inc/abonnements'); $abonnement = sql_fetsel('*', 'spip_abonnements', 'id_abonnement = '.intval($flux['args']['id_objet'])); $offre = sql_fetsel('*', 'spip_abonnements_offres', 'id_abonnements_offre = '.intval($abonnement['id_abonnements_offre'])); + $jourdhui = date('Y-m-d H:i:s'); - $modifs = array(); - - // Si l'échéance est VIDE, et que pourtant l'offre parente A BIEN une durée - // alors c'est qu'il faut initialiser l'échéance ! - if ($abonnement['date_fin'] == '0000-00-00 00:00:00' and ($duree = $offre['duree']) > 0){ - // De combien doit-on augmenter la date - switch ($offre['periode']){ - case 'heures': - $ajout = " + ${duree} hours"; - break; - case 'jours': - $ajout = " + ${duree} days"; - break; - case 'mois': - $ajout = " + ${duree} months"; - break; - default: - $ajout =''; - break; - } - - // Calcul de la date de fin - $modifs['date_fin'] = date('Y-m-d H:i:s', strtotime($abonnement['date_debut'].$ajout)); - - $modifs = pipeline( - 'abonnement_initialisation_dates', - array( - 'args' => array('abonnement' => $abonnement, 'offre' => $offre), - 'data' => $modifs - ) - ); - - // Si les dates ont été changées, on change le tableau de l'abonnement pour le test de statut qui suivra - if (isset($modifs['date_debut'])) { - $abonnement['date_debut'] = $modifs['date_debut']; - } - if (isset($modifs['date_fin'])) { - $abonnement['date_fin'] = $modifs['date_fin']; - } + // Si la date de fin a été modifiée et qu'elle est dans le future + // on reprogramme la désactivation + if (isset($flux['data']['date_fin']) and $flux['data']['date_fin'] > $jourdhui) { + abonnements_programmer_desactivation($flux['args']['id_objet'], $flux['data']['date_fin']); } - // Si le statut est "prepa" c'est une création et on doit changer ça - // car pour l'instant SPIP ne permet pas de déclarer le statut par défaut ! - if ($abonnement['statut'] == 'prepa') { - $modifs['statut'] = $abonnement['statut'] = 'actif'; - } - // Si on a mis l'abonnement à la poubelle, on doit enlever les tâches liées - elseif ($abonnement['statut'] == 'poubelle') { + // Si on a mis l'abonnement inactif ou à la poubelle, on doit enlever les tâches liées + if (in_array($abonnement['statut'], array('inactif', 'poubelle'))) { $liens = objet_trouver_liens(array('job' => '*'), array('abonnement' => $abonnement['id_abonnement'])); if ($liens and is_array($liens)){ // Et on les supprime toutes ! @@ -101,21 +63,37 @@ function abonnements_post_edition($flux){ } } + $modifs = array(); + + // Si l'échéance est VIDE, et que pourtant l'offre parente A BIEN une durée + // alors c'est qu'il faut initialiser les dates ! + if ($abonnement['date_echeance'] == '0000-00-00 00:00:00' and ($duree = $offre['duree']) > 0) { + $modifs = abonnements_initialisation_dates($abonnement, $offre); + } + + // Si les dates doivent être changées, on change le tableau de l'abonnement pour le test de statut qui suivra + if (isset($modifs['date_debut'])) { + $abonnement['date_debut'] = $modifs['date_debut']; + } + if (isset($modifs['date_fin'])) { + $abonnement['date_fin'] = $modifs['date_fin']; + } + // Seulement si personne n'a modifié le statut manuellement, alors on check les dates pour statufier if (!$flux['data']['statut']) { - $jourdhui = date('Y-m-d H:i:s'); - // Si aujourd'hui est dans les dates, on active + // Si aujourd'hui est entre date_debut et date_echeance, on active if ( $abonnement['statut'] == 'inactif' and $jourdhui >= $abonnement['date_debut'] - and $jourdhui <= $abonnement['date_fin'] + and $jourdhui <= $abonnement['date_echeance'] ) { $modifs['statut'] = 'actif'; } - // Si aujourd'hui est en dehors des dates, on désactive + // Si aujourd'hui est en dehors des dates début et FIN, on désactive + // on ne teste pas date_echeance car ce sera à un génie de désactiver si trop dépassée elseif ( $abonnement['statut'] == 'actif' - and ($jourdhui < $abonnement['date_debut'] or $jourdhui > $abonnement['date_fin']) + and ($jourdhui < $abonnement['date_debut'] or $jourdhui >= $abonnement['date_fin']) ) { $modifs['statut'] = 'inactif'; } @@ -126,12 +104,6 @@ function abonnements_post_edition($flux){ include_spip('action/editer_objet'); objet_modifier('abonnement', $flux['args']['id_objet'], $modifs); } - - // Si dans les modifications demandées au départ, il y a la date de fin, on reprogramme la désactivation - if (isset($flux['data']['date_fin'])) { - include_spip('inc/abonnements'); - abonnements_programmer_desactivation($flux['args']['id_objet'], $flux['data']['date_fin']); - } } // Détection magique du plugin Commandes et d'une commande d'offre d'abonnement elseif ( @@ -179,9 +151,18 @@ function abonnements_post_edition($flux){ } /* - * Ajout d'une tache CRON pour vérifier toutes les heures si les abonnements actifs ont une tâche de désactivation + * Ajout de tâches nécessaires aux abonnements + * + * - Une tâche pour vérifier toutes les heures si on a pas trop dépassé des échéances + * - Une tâche pour vérifier toutes les heures si les abonnements actifs ont une tâche de désactivation + * - Une tâche pour programmer les emails de notification à envoyer + * + * @pipeline taches_generales_cron + * @param array $taches Liste des génies et leur périodicité + * @return array Liste des tâches possiblement modifiées */ function abonnements_taches_generales_cron($taches){ + $taches['abonnements_verifier_echeances'] = 60 * 60; // toutes les heures $taches['abonnements_verifier_desactivation'] = 60 * 60; // toutes les heures $taches['abonnements_verifier_notifications'] = 24 * 3600; // une fois par jour return $taches; diff --git a/action/modifier_echeance_abonnement.php b/action/modifier_echeance_abonnement.php index a665c2e..1927f7c 100644 --- a/action/modifier_echeance_abonnement.php +++ b/action/modifier_echeance_abonnement.php @@ -21,17 +21,20 @@ function action_modifier_echeance_abonnement_dist($arg=null) { $duree = intval($duree) and $id_abonnement = intval($id_abonnement) and autoriser('modifier', 'abonnement', $id_abonnement) - and $abonnement = sql_fetsel('date_debut, date_fin', 'spip_abonnements', 'id_abonnement = '.$id_abonnement) + and $abonnement = sql_fetsel('date_debut, date_echeance, date_fin', 'spip_abonnements', 'id_abonnement = '.$id_abonnement) ) { + $jourdhui = date('Y-m-d H:i:s'); + // Calculons la date de départ du renouvellement - $date_depart = $abonnement['date_fin']; - // Si la date de fin n'était pas encore défini, on reprend depuis le début + // Par défaut on part de la dernière échéance + $date_depart = $abonnement['date_echeance']; + + // Si la date d'échéance n'était pas encore définie, on reprend depuis le début if ($date_depart == '0000-00-00 00:00:00'){ $date_depart = $abonnement['date_debut']; } - // Et si la date de fin était *déjà passée*, alors on renouvelle *à partir d'aujourd'hui* ! - $jourdhui = date('Y-m-d H:i:s'); - if ($date_depart < $jourdhui) { + // Et si la date d'échéance était *déjà passée*, alors on renouvelle *à partir d'aujourd'hui* ! + elseif ($date_depart < $jourdhui) { $date_depart = $jourdhui; } @@ -53,17 +56,27 @@ function action_modifier_echeance_abonnement_dist($arg=null) { // Si la période existe if ($ajout){ + $modifications = array(); + // Si la durée est positive, on ajoute un + devant (le - est déjà là pour les négatives) if ($duree > 0){ $ajout = ' +'.$ajout; } - // Calcul de la date de fin - $nouvelle_echeance = date('Y-m-d H:i:s', strtotime($date_depart.$ajout)); + $modifications['date_echeance'] = date('Y-m-d H:i:s', strtotime($date_depart.$ajout)); + + // Si la date de fin n'est PAS infinie ET qu'elle se retrouve plus petite que l'échéance + // On la remet au moins au même endroit que la nouvelle échéance + if ( + $abonnement['date_fin'] != '0000-00-00 00:00:00' + and $abonnement['date_fin'] < $modifications['date_echeance'] + ) { + $modifications['date_fin'] = $modifications['date_echeance']; + } // On lance la modification include_spip('action/editer_objet'); - $erreur = objet_modifier('abonnement', $id_abonnement, array('date_fin' => $nouvelle_echeance)); + $erreur = objet_modifier('abonnement', $id_abonnement, $modifications); return array($id_abonnement, $erreur); } @@ -71,4 +84,3 @@ function action_modifier_echeance_abonnement_dist($arg=null) { return false; } - diff --git a/genie/abonnements_verifier_echeances.php b/genie/abonnements_verifier_echeances.php new file mode 100644 index 0000000..4a17791 --- /dev/null +++ b/genie/abonnements_verifier_echeances.php @@ -0,0 +1,39 @@ + $jourdhui", + "date_echeance < $date_max_retard", + ) + ) + and is_array($abonnements_retard) + ) { + include_spip('action/editer_objet'); + + // Pour chaque abonnement trop dépassé, on met la date de fin à maintenant + // ce qui va normalement provoquer la désactivation immédiate + foreach ($abonnements_retard as $abonnement) { + objet_modifier('abonnement', $abonnement['id_abonnement'], array('date_fin' => $jourdhui)); + } + } + + return 1; +} diff --git a/inc/abonnements.php b/inc/abonnements.php index db5781a..1a91db6 100644 --- a/inc/abonnements.php +++ b/inc/abonnements.php @@ -7,6 +7,79 @@ if (!defined('_ECRIRE_INC_VERSION')) return; +/** + * Initialiser les dates d'échéance et de fin pour un abonnement créé + * + * @pipeline_appel abonnement_initialisation_dates + * @param array $abonnement + * Informations sur l'abonnement à initialiser + * @param array $offre + * Informations sur l'offre de l'abonnement à initialiser + * @return array + * Retourne les modifications de dates initialisées + **/ +function abonnements_initialisation_dates($abonnement, $offre){ + $modifs = array(); + + // De combien doit-on augmenter la date + switch ($offre['periode']){ + case 'heures': + $ajout = " + ${duree} hours"; + break; + case 'jours': + $ajout = " + ${duree} days"; + break; + case 'mois': + $ajout = " + ${duree} months"; + break; + default: + $ajout = ''; + break; + } + + // Par défaut les dates de fin et de la prochaine échéance sont les mêmes + $modifs['date_echeance'] = date('Y-m-d H:i:s', strtotime($abonnement['date_debut'].$ajout)); + $modifs['date_fin'] = $modifs['date_echeance']; + + // Mais s'il y a le plugin Commandes et Bank et qu'on trouve commande et transaction + if ( + _DIR_PLUGIN_COMMANDES + and _DIR_PLUGIN_BANK + and include_spip('action/editer_liens') + and $lien_commande = objet_trouver_liens(array('commande' => '*'), array('abonnement' => $abonnement['id_abonnement'])) + and is_array($lien_commande) + // On prend juste la première commande qu'on trouve + and $id_commande = intval($lien_commande[0]['id_commande']) + // On cherche le dernier paiement bien payé pour cette commande + and $transaction = sql_fetsel( + '*', 'spip_transactions', array('id_commande = '.$id_commande, 'statut = "ok"') + ) + ) { + // On a trouvé la transaction qui a activé la commande qui a activé l'abonnement + // Si on détecte un prélèvement SEPA, on annule la date de fin ! + if ($refcb = $transaction['refcb'] and strpos($refcb, 'SEPA') === 0) { + $modifs['date_fin'] = '0000-00-00 00:00:00'; + } + // Si ya une fin de validité de carte bleue on en déduit une fin d'abonnement ! + elseif ($validite = $transaction['validite']) { + include_spip('inc/bank'); + list($year, $month) = explode('-', $validite); + $modifs['date_fin'] = bank_date_fin_mois($year, $month); + } + } + + $modifs = pipeline( + 'abonnement_initialisation_dates', + array( + 'args' => array('abonnement' => $abonnement, 'offre' => $offre), + 'data' => $modifs + ) + ); + + return $modifs; +} + + /* * Programmer la désactivation d'un abonnement lors de sa date de fin * @@ -84,5 +157,3 @@ function abonnements_notifier_echeance($id_abonnement, $nom, $email, $duree, $pe ) ); } - -?>