Empêcher CONTRACT_VALIDATE après LINECONTRACT_ACTI

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…

Bonjour,

Visiblement vous utilisez le module payant : https://www.dolistore.com/fr/modules/918-Abonnement-et-diffusion-des-publications-v2.html
Je suis pas trés sur qu’ils apprécient que vous pubiliez leur code…

De plus si vous avez un probléme avec leur module, le mieux c’est de les contacter : https://wiki.artaban.fr/doku.php?id=supports
Ils ont un bugtracker : https://www.dolistore.com/fr/modules/918-Abonnement-et-diffusion-des-publications-v2.html

@+

C’est moi qui développe ce module ! Cette partie a été développé par Raphaël Doursenaud.Mais je rencontre des difficultés et j’ai besoin d’aide. Pour bien exposer le problème, j’ai jugé bon de montrer le code…

J’aime toujours les développeurs qui vendent leurs modules 510euros et qui viennent demander un dépannage gratuit sur un forum
Si vous n’avez pas les compétences : demandez à gpcsolutions.fr