Example #1
0
 /**
  * Tag invoice as validated + call trigger BILL_VALIDATE
  * Object must have lines loaded with fetch_lines
  *
  * @param	User	$user           Object user that validate
  * @param   string	$force_number	Reference to force on invoice
  * @param	int		$idwarehouse	Id of warehouse to use for stock decrease if option to decreasenon stock is on (0=no decrease)
  * @param	int		$notrigger		1=Does not execute triggers, 0= execuete triggers
  * @return	int						<0 if KO, >0 if OK
  */
 function validate($user, $force_number = '', $idwarehouse = 0, $notrigger = 0)
 {
     global $conf, $langs;
     require_once DOL_DOCUMENT_ROOT . '/core/lib/files.lib.php';
     $now = dol_now();
     $error = 0;
     dol_syslog(get_class($this) . '::validate user='******', force_number=' . $force_number . ', idwarehouse=' . $idwarehouse);
     // Check parameters
     if (!$this->brouillon) {
         dol_syslog(get_class($this) . "::validate no draft status", LOG_WARNING);
         return 0;
     }
     if (empty($conf->global->MAIN_USE_ADVANCED_PERMS) && empty($user->rights->facture->creer) || !empty($conf->global->MAIN_USE_ADVANCED_PERMS) && empty($user->rights->facture->invoice_advance->validate)) {
         $this->error = 'Permission denied';
         dol_syslog(get_class($this) . "::validate " . $this->error, LOG_ERR);
         return -1;
     }
     $this->db->begin();
     $this->fetch_thirdparty();
     $this->fetch_lines();
     // Check parameters
     if ($this->type == self::TYPE_REPLACEMENT) {
         // Controle que facture source connue
         if ($this->fk_facture_source <= 0) {
             $this->error = $langs->trans("ErrorFieldRequired", $langs->trans("InvoiceReplacement"));
             $this->db->rollback();
             return -10;
         }
         // Charge la facture source a remplacer
         $facreplaced = new Facture($this->db);
         $result = $facreplaced->fetch($this->fk_facture_source);
         if ($result <= 0) {
             $this->error = $langs->trans("ErrorBadInvoice");
             $this->db->rollback();
             return -11;
         }
         // Controle que facture source non deja remplacee par une autre
         $idreplacement = $facreplaced->getIdReplacingInvoice('validated');
         if ($idreplacement && $idreplacement != $this->id) {
             $facreplacement = new Facture($this->db);
             $facreplacement->fetch($idreplacement);
             $this->error = $langs->trans("ErrorInvoiceAlreadyReplaced", $facreplaced->ref, $facreplacement->ref);
             $this->db->rollback();
             return -12;
         }
         $result = $facreplaced->set_canceled($user, 'replaced', '');
         if ($result < 0) {
             $this->error = $facreplaced->error;
             $this->db->rollback();
             return -13;
         }
     }
     // Define new ref
     if ($force_number) {
         $num = $force_number;
     } else {
         if (preg_match('/^[\\(]?PROV/i', $this->ref) || empty($this->ref)) {
             if (!empty($conf->global->FAC_FORCE_DATE_VALIDATION)) {
                 $this->date = dol_now();
                 $this->date_lim_reglement = $this->calculate_date_lim_reglement();
             }
             $num = $this->getNextNumRef($this->client);
         } else {
             $num = $this->ref;
         }
     }
     $this->newref = $num;
     if ($num) {
         $this->update_price(1);
         // Validate
         $sql = 'UPDATE ' . MAIN_DB_PREFIX . 'facture';
         $sql .= " SET facnumber='" . $num . "', fk_statut = " . self::STATUS_VALIDATED . ", fk_user_valid = " . $user->id . ", date_valid = '" . $this->db->idate($now) . "'";
         if (!empty($conf->global->FAC_FORCE_DATE_VALIDATION)) {
             $sql .= ", datef='" . $this->db->idate($this->date) . "'";
             $sql .= ", date_lim_reglement='" . $this->db->idate($this->date_lim_reglement) . "'";
         }
         $sql .= ' WHERE rowid = ' . $this->id;
         dol_syslog(get_class($this) . "::validate", LOG_DEBUG);
         $resql = $this->db->query($sql);
         if (!$resql) {
             dol_print_error($this->db);
             $error++;
         }
         // On verifie si la facture etait une provisoire
         if (!$error && preg_match('/^[\\(]?PROV/i', $this->ref)) {
             // La verif qu'une remise n'est pas utilisee 2 fois est faite au moment de l'insertion de ligne
         }
         if (!$error) {
             // Define third party as a customer
             $result = $this->client->set_as_client();
             // Si active on decremente le produit principal et ses composants a la validation de facture
             if ($this->type != self::TYPE_DEPOSIT && $result >= 0 && !empty($conf->stock->enabled) && !empty($conf->global->STOCK_CALCULATE_ON_BILL) && $idwarehouse > 0) {
                 require_once DOL_DOCUMENT_ROOT . '/product/stock/class/mouvementstock.class.php';
                 $langs->load("agenda");
                 // Loop on each line
                 $cpt = count($this->lines);
                 for ($i = 0; $i < $cpt; $i++) {
                     if ($this->lines[$i]->fk_product > 0) {
                         $mouvP = new MouvementStock($this->db);
                         $mouvP->origin =& $this;
                         // We decrease stock for product
                         if ($this->type == self::TYPE_CREDIT_NOTE) {
                             $result = $mouvP->reception($user, $this->lines[$i]->fk_product, $idwarehouse, $this->lines[$i]->qty, 0, $langs->trans("InvoiceValidatedInDolibarr", $num));
                         } else {
                             $result = $mouvP->livraison($user, $this->lines[$i]->fk_product, $idwarehouse, $this->lines[$i]->qty, $this->lines[$i]->subprice, $langs->trans("InvoiceValidatedInDolibarr", $num));
                         }
                         if ($result < 0) {
                             $error++;
                         }
                     }
                 }
             }
         }
         // Trigger calls
         if (!$error && !$notrigger) {
             // Call trigger
             $result = $this->call_trigger('BILL_VALIDATE', $user);
             if ($result < 0) {
                 $error++;
             }
             // End call triggers
         }
         if (!$error) {
             $this->oldref = $this->ref;
             // Rename directory if dir was a temporary ref
             if (preg_match('/^[\\(]?PROV/i', $this->ref)) {
                 // Rename of object directory ($this->ref = old ref, $num = new ref)
                 // to  not lose the linked files
                 $oldref = dol_sanitizeFileName($this->ref);
                 $newref = dol_sanitizeFileName($num);
                 $dirsource = $conf->facture->dir_output . '/' . $oldref;
                 $dirdest = $conf->facture->dir_output . '/' . $newref;
                 if (file_exists($dirsource)) {
                     dol_syslog(get_class($this) . "::validate rename dir " . $dirsource . " into " . $dirdest);
                     if (@rename($dirsource, $dirdest)) {
                         dol_syslog("Rename ok");
                         // Rename docs starting with $oldref with $newref
                         $listoffiles = dol_dir_list($conf->facture->dir_output . '/' . $newref, 'files', 1, '^' . preg_quote($oldref, '/'));
                         foreach ($listoffiles as $fileentry) {
                             $dirsource = $fileentry['name'];
                             $dirdest = preg_replace('/^' . preg_quote($oldref, '/') . '/', $newref, $dirsource);
                             $dirsource = $fileentry['path'] . '/' . $dirsource;
                             $dirdest = $fileentry['path'] . '/' . $dirdest;
                             @rename($dirsource, $dirdest);
                         }
                     }
                 }
             }
         }
         // Set new ref and define current statut
         if (!$error) {
             $this->ref = $num;
             $this->facnumber = $num;
             $this->statut = self::STATUS_VALIDATED;
             $this->brouillon = 0;
             $this->date_validation = $now;
             $i = 0;
             $final = True;
             while ($i < count($this->lines) && $final == True) {
                 $final = $this->lines[$i]->situation_percent == 100;
                 $i++;
             }
             if ($final) {
                 $this->setFinal();
             }
         }
     } else {
         $error++;
     }
     if (!$error) {
         $this->db->commit();
         return 1;
     } else {
         $this->db->rollback();
         return -1;
     }
 }
Example #2
0
 /**
  * Tag invoice as validated + call trigger BILL_VALIDATE
  * Object must have lines loaded with fetch_lines
  *
  * @param	User	$user           Object user that validate
  * @param   string	$force_number	Reference to force on invoice
  * @param	int		$idwarehouse	Id of warehouse to use for stock decrease
  * @return	int						<0 if KO, >0 if OK
  */
 function validate($user, $force_number = '', $idwarehouse = 0)
 {
     global $conf, $langs;
     require_once DOL_DOCUMENT_ROOT . "/core/lib/files.lib.php";
     $now = dol_now();
     $error = 0;
     dol_syslog(get_class($this) . '::validate user='******', force_number=' . $force_number . ', idwarehouse=' . $idwarehouse, LOG_WARNING);
     // Check parameters
     if (!$this->brouillon) {
         dol_syslog(get_class($this) . "::validate no draft status", LOG_WARNING);
         return 0;
     }
     if (!$user->rights->facture->valider) {
         $this->error = 'Permission denied';
         dol_syslog(get_class($this) . "::validate " . $this->error, LOG_ERR);
         return -1;
     }
     $this->db->begin();
     $this->fetch_thirdparty();
     $this->fetch_lines();
     // Check parameters
     if ($this->type == 1) {
         // Controle que facture source connue
         if ($this->fk_facture_source <= 0) {
             $this->error = $langs->trans("ErrorFieldRequired", $langs->trans("InvoiceReplacement"));
             $this->db->rollback();
             return -10;
         }
         // Charge la facture source a remplacer
         $facreplaced = new Facture($this->db);
         $result = $facreplaced->fetch($this->fk_facture_source);
         if ($result <= 0) {
             $this->error = $langs->trans("ErrorBadInvoice");
             $this->db->rollback();
             return -11;
         }
         // Controle que facture source non deja remplacee par une autre
         $idreplacement = $facreplaced->getIdReplacingInvoice('validated');
         if ($idreplacement && $idreplacement != $this->id) {
             $facreplacement = new Facture($this->db);
             $facreplacement->fetch($idreplacement);
             $this->error = $langs->trans("ErrorInvoiceAlreadyReplaced", $facreplaced->ref, $facreplacement->ref);
             $this->db->rollback();
             return -12;
         }
         $result = $facreplaced->set_canceled($user, 'replaced', '');
         if ($result < 0) {
             $this->error = $facreplaced->error;
             $this->db->rollback();
             return -13;
         }
     }
     // Define new ref
     if ($force_number) {
         $num = $force_number;
     } else {
         if (preg_match('/^[\\(]?PROV/i', $this->ref)) {
             if (!empty($conf->global->FAC_FORCE_DATE_VALIDATION)) {
                 $this->date = dol_now();
                 $this->date_lim_reglement = $this->calculate_date_lim_reglement();
             }
             $num = $this->getNextNumRef($this->client);
         } else {
             $num = $this->ref;
         }
     }
     if ($num) {
         $this->update_price(1);
         // Validate
         $sql = 'UPDATE ' . MAIN_DB_PREFIX . 'facture';
         $sql .= " SET facnumber='" . $num . "', fk_statut = 1, fk_user_valid = " . $user->id . ", date_valid = '" . $this->db->idate($now) . "'";
         if (!empty($conf->global->FAC_FORCE_DATE_VALIDATION)) {
             $sql .= ', datef=' . $this->db->idate($this->date);
             $sql .= ', date_lim_reglement=' . $this->db->idate($this->date_lim_reglement);
         }
         $sql .= ' WHERE rowid = ' . $this->id;
         dol_syslog(get_class($this) . "::validate sql=" . $sql);
         $resql = $this->db->query($sql);
         if (!$resql) {
             dol_syslog(get_class($this) . "::validate Echec update - 10 - sql=" . $sql, LOG_ERR);
             dol_print_error($this->db);
             $error++;
         }
         // On verifie si la facture etait une provisoire
         if (!$error && preg_match('/^[\\(]?PROV/i', $this->ref)) {
             // La verif qu'une remise n'est pas utilisee 2 fois est faite au moment de l'insertion de ligne
         }
         if (!$error) {
             // Define third party as a customer
             $result = $this->client->set_as_client();
             // Si active on decremente le produit principal et ses composants a la validation de facture
             if ($this->type != 3 && $result >= 0 && $conf->stock->enabled && $conf->global->STOCK_CALCULATE_ON_BILL) {
                 require_once DOL_DOCUMENT_ROOT . "/product/stock/class/mouvementstock.class.php";
                 $langs->load("agenda");
                 // Loop on each line
                 $cpt = count($this->lines);
                 for ($i = 0; $i < $cpt; $i++) {
                     if ($this->lines[$i]->fk_product > 0) {
                         $mouvP = new MouvementStock($this->db);
                         // We decrease stock for product
                         if ($this->type == 2) {
                             $result = $mouvP->reception($user, $this->lines[$i]->fk_product, $idwarehouse, $this->lines[$i]->qty, $this->lines[$i]->subprice, $langs->trans("InvoiceValidatedInDolibarr", $num));
                         } else {
                             $result = $mouvP->livraison($user, $this->lines[$i]->fk_product, $idwarehouse, $this->lines[$i]->qty, $this->lines[$i]->subprice, $langs->trans("InvoiceValidatedInDolibarr", $num));
                         }
                         if ($result < 0) {
                             $error++;
                         }
                     }
                 }
             }
         }
         if (!$error) {
             $this->oldref = '';
             // Rename directory if dir was a temporary ref
             if (preg_match('/^[\\(]?PROV/i', $this->ref)) {
                 // On renomme repertoire facture ($this->ref = ancienne ref, $num = nouvelle ref)
                 // afin de ne pas perdre les fichiers attaches
                 $facref = dol_sanitizeFileName($this->ref);
                 $snumfa = dol_sanitizeFileName($num);
                 $dirsource = $conf->facture->dir_output . '/' . $facref;
                 $dirdest = $conf->facture->dir_output . '/' . $snumfa;
                 if (file_exists($dirsource)) {
                     dol_syslog(get_class($this) . "::validate rename dir " . $dirsource . " into " . $dirdest);
                     if (@rename($dirsource, $dirdest)) {
                         $this->oldref = $facref;
                         dol_syslog("Rename ok");
                         // Suppression ancien fichier PDF dans nouveau rep
                         dol_delete_file($conf->facture->dir_output . '/' . $snumfa . '/' . $facref . '.*');
                     }
                 }
             }
         }
         // Set new ref and define current statut
         if (!$error) {
             $this->ref = $num;
             $this->facnumber = $num;
             $this->statut = 1;
             $this->date_validation = $now;
         }
         // Trigger calls
         if (!$error) {
             // Appel des triggers
             include_once DOL_DOCUMENT_ROOT . "/core/class/interfaces.class.php";
             $interface = new Interfaces($this->db);
             $result = $interface->run_triggers('BILL_VALIDATE', $this, $user, $langs, $conf);
             if ($result < 0) {
                 $error++;
                 $this->errors = $interface->errors;
             }
             // Fin appel triggers
         }
     } else {
         $error++;
     }
     if (!$error) {
         $this->db->commit();
         return 1;
     } else {
         $this->db->rollback();
         $this->error = $this->db->lasterror();
         return -1;
     }
 }