Mon but : empêcher CONTRACT_VALIDATE après LINECONTRACT_ACTIVATE pour dolilibarr 9.0.x et 8.0.4.
Pour un module d’abonnement, il a été développé un fonctionnalité qui créé les abonnements à l’activation de tous les services depuis une fiche ‹ service ›.
Cela se fait grâce aux triggers.
Voici le code
<?php
/* Contracts management triggers for Parution Abonnement
* Copyright (C) 2016 Raphaël Doursenaud <[email protected]>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
require_once DOL_DOCUMENT_ROOT . '/core/lib/admin.lib.php';
dol_include_once('/supportparutionabonnement/lib/supportparutionabonnement.lib.php');
/**
* Class InterfaceContracts
*/
class InterfaceContracts extends DolibarrTriggers {
/** @var DoliDB Database handler */
protected $db;
/** @var User Trigger called by */
protected $user;
/**
* Constructor
*
* @param DoliDB $db Database handler
*/
public function __construct($db) {
$this->db = $db;
$this->name = preg_replace('/^Interface/i', '', get_class($this));
$this->family = "contract";
$this->description = "Allows creating subsriptions from contracts with subscription services";
$this->version = '0.0.1';
//$this->picto = 'supportparution@supportparution';
}
/**
* Function called when a Dolibarrr business event is done.
* All functions "runTrigger" are triggered if file
* is inside directory core/triggers
*
* @param string $action Event action code
* @param Object $object Object
* @param User $user Object user
* @param Translate $langs Object langs
* @param Conf $conf Object conf
* @return int <0 if KO, 0 if no triggered ran, >0 if OK
*/
public function runTrigger($action, $object, User $user, Translate $langs, Conf $conf) {
$this->user = $user;
var_dump($action . ' ' . $object->id);
// Contracts
if ($action == 'CONTRACT_REOPEN') {
dol_syslog(
"Trigger '" . $this->name . "' for action '$action' launched by " . __FILE__ . ". id=" . $object->id
);
} elseif ($action == 'CONTRACT_DELETE') {
dol_syslog(
"Trigger '" . $this->name . "' for action '$action' launched by " . __FILE__ . ". id=" . $object->id
);
} elseif ($action == 'CONTRACT_SERVICE_ACTIVATE' || $action == 'LINECONTRACT_ACTIVATE') {
dol_syslog(
"Trigger '" . $this->name . "' for action '$action' launched by " . __FILE__ . ". id=" . $object->id
);
return $this->serviceActivated($object);
} elseif ($action == 'CONTRACT_VALIDATE') {
dol_syslog(
"Trigger '" . $this->name . "' for action '$action' launched by " . __FILE__ . ". id=" . $object->id
);
return $this->contractValidated($object);
} elseif ($action == 'CONTRACT_SERVICE_CLOSE') {
dol_syslog(
"Trigger '" . $this->name . "' for action '$action' launched by " . __FILE__ . ". id=" . $object->id
);
// We do nothing here because subscriptions already paid should terminate automatically
}
return 0;
}
/**
* Handles contract validation and automatic subscription creation
*
* @param Contrat $contract
* @return int Status
*/
private function contractValidated(Contrat $contract) {
// FIXME: This is silly. The element property should be declared static in upstream code! F*ck it!
// https://github.com/Dolibarr/dolibarr/issues/5326
dol_include_once('/supportparution/class/supportparutionversionsupport.class.php');
$supportparutionversionsupport = new Supportparutionversionsupport($this->db);
$parution_lines = array(); // Lines with service linked to a publication
foreach ($contract->lines as $index => $line) {
if ($line->fk_product) {
$product = new Product($this->db);
$product->fetch($line->fk_product);
$linkedSupportParutionVersionSupportIds = linkedElementSourceFromTargetIds($supportparutionversionsupport->element, $product->element, $product->id);
if (is_array($linkedSupportParutionVersionSupportIds)) {
$parution_lines[$index] = $linkedSupportParutionVersionSupportIds;
}
}
}
if (empty($parution_lines)) {
// No parution found, do nothing
return 0;
}
// Check we have a signature contact
$sign_contacts = $contract->getIdContact('external', 'SALESREPSIGN', 4);
if (empty($sign_contacts)) {
$contract->errors[] = "Merci d'ajouter un « Contact client signataire contrat » pour créer les abonnements";
return -1;
}
// Make sure we only have one
if (count($sign_contacts) !== 1) {
$contract->errors[] = "Il faut un et un seul « Contact client signataire contrat » pour créer les abonnements";
return -1;
}
// Make sure we have everything we need on each contract lines
foreach ($parution_lines as $index => $linked_parution) {
// Quantity
if (empty($contract->lines[$index]->qty)) {
$contract->errors[] = "Impossible de créer un abonnement de quantité nulle";
return -1;
}
// Start date
if (empty($contract->lines[$index]->date_ouverture_prevue)) {
$contract->errors[] = "Il faut une « date prévue de mise en service » pour créer un abonnement";
return -1;
}
// End date
if (empty($contract->lines[$index]->date_fin_validite)) {
$contract->errors[] = "Il faut une « date prévue fin de service » pour créer un abonnement";
return -1;
}
}
// Get subscription contact
$subscription_contact = new Contact($this->db);
$subscription_contact->fetch($sign_contacts[0]);
// Create subscriptions
$subscription_errors = 0;
foreach ($parution_lines as $index => $linked_parutions) {
foreach ($linked_parutions as $linked_parution) {
print '<br />contractValidated : appelle subscribe<br />';
$subscription_errors += $this->subscribe($subscription_contact, $linked_parution, $contract->lines[$index]);
}
}
if ($subscription_errors !== 0) {
$contract->errors[] = "L'abonnement automatique a échoué.";
return -1;
}
return 1;
}
/**
* Subscribe a contact to a parution version
*
* @param Contact $contact Contact subscribing
* @param int $version Parution version to subscribe to
* @param ContratLigne $line Context from contract line
* @return int
*/
private function subscribe(Contact $contact, $version, ContratLigne &$line) {
dol_include_once('/supportparutionabonnement/class/abonnesupportparution.class.php');
$abonnesupportparution = new Abonnesupportparution($this->db);
$abonnesupportparution->fk_support_parution_version_support = $version;
$abonnesupportparution->date_debut = $line->date_ouverture_prevue;
$abonnesupportparution->date_fin = $line->date_end; //date_fin_validite; Modif GL ARTABAN 02/10/2018 suite pb abo créé avec date de fin 31/12/1969...
$abonnesupportparution->abonnement_etat_code = "INACTIF";
$abonnesupportparution->quantite = $line->qty;
$abonnesupportparution->fk_socpeople = $contact->id;
// var_dump("line id : " . $line->id. "line : element ".$line->element);
// $linkedSupportParutionVersionSupportIds = linkedElementSourceFromTargetIds('abonnesupportparution', $line->element, $line->id);
// var_dump($linkedSupportParutionVersionSupportIds);
// var_dump('count : '.count($linkedSupportParutionVersionSupportIds));
// if (count($linkedSupportParutionVersionSupportIds) > 0) {
// $statusAbo = '';
// foreach ($linkedSupportParutionVersionSupportIds as $rowid => $idAbo) {
$line->fetchObjectLinked('', '', $line->id, $line->element);
$linkedSupportParutionVersionSupportIds = linkedElementSourceFromTargetIds('abonnesupportparution', $line->element, $line->id);
if ($abonnesupportparution->isSubscribed() > 0 && count($linkedSupportParutionVersionSupportIds) > 0) {
$statusAbo = '';
foreach ($linkedSupportParutionVersionSupportIds as $rowid => $idAbo) {
$aboStatic = new Abonnesupportparution($this->db);
$aboStatic->fetch($idAbo);
$statusAbo = $aboStatic->abonnement_etat_code;
break;
}
$abonnesupportparution->abonnement_etat_code = (!empty($statusAbo) ? $statusAbo : "ACTIF");
$result = $abonnesupportparution->update($this->user);
print'UPDATE<br />';
} else {
$abonnesupportparution->datec = dol_now();
$result = $abonnesupportparution->create($this->user);
print'CREATE<br />';
}
if ($result > 0) {
// Link subscription to contract line
$line->add_object_linked($abonnesupportparution->element, $abonnesupportparution->id);
return 0;
}
return $result;
}
/**
* Handles service activation, activating subscription
*
* @param ContratLigne $contractline
* @return int Status
*/
private function serviceActivated(ContratLigne $contractline) {
dol_include_once('/supportparutionabonnement/class/abonnesupportparution.class.php');
$abonnesupportparution = new Abonnesupportparution($this->db);
// Get the linked subscription(s)
$linkedSupportParutionVersionSupportLinkedSubscriptionsIds = linkedElementSourceFromTargetIds($abonnesupportparution->element, $contractline->element, $contractline->id);
// Si les abonnements n'ont pas été créés, on les créait
if (count($linkedSupportParutionVersionSupportLinkedSubscriptionsIds) == 0) {
$contract = new Contrat($this->db);
$contract->fetch($contractline->fk_contrat);
if ($this->contractValidated($contract) > 0) {
$contractline->fetch($contractline->id);
$linkedSupportParutionVersionSupportLinkedSubscriptionsIds = linkedElementSourceFromTargetIds($abonnesupportparution->element, $contractline->element, $contractline->id);
}
}
// Enable subscription(s)
if (count($linkedSupportParutionVersionSupportLinkedSubscriptionsIds) > 0) {// On ne retourne pas si test failed, car sinon, les message pour l'utilisateur ne s'affichent pas...
$subscription_errors = 0;
foreach ($linkedSupportParutionVersionSupportLinkedSubscriptionsIds as $subscription_id) {
if ($abonnesupportparution->fetch($subscription_id) > 0) {
$abonnesupportparution->date_debut = $contractline->date_ouverture_prevue;
$abonnesupportparution->date_fin = $contractline->date_end;
$abonnesupportparution->abonnement_etat_code = 'ACTIF';
if ($abonnesupportparution->update($this->user) < 0) {
$subscription_errors++;
}
} else {
$subscription_errors++;
}
}
if ($subscription_errors !== 0) {
return -1;
}
}
return 1;
}
}
Avec ce code, lorsque l’on active tous les services, l’abonnement est créé en double. Comme vous pouvez-le voir, j’ai mis des mouchard qui donne :
Notez que que si je commente la ligne « return $this->contractValidated($object); » dans la partie « action == CONTRACT_VALIDATE », l’abonnement n’est créé qu’une seul fois.
J’avais ecrit pour de script pour tester si une ligne ou plus de contrat existait, mais ça ne marcher que sur dol 9 et pas sur dol 8…
Si vous avez une idée qui marche sur dol 8 et 9, je suis preneur.
N’hésitez pas à me poser des questions si ce n’est pas clair.
Merci d’avance pour votre aide…