/** * Mets a jour une ligne de contrat * * @param int $rowid Id de la ligne de facture * @param string $desc Description de la ligne * @param float $pu Prix unitaire * @param int $qty Quantite * @param float $remise_percent Pourcentage de remise de la ligne * @param int $date_start Date de debut prevue * @param int $date_end Date de fin prevue * @param float $tvatx Taux TVA * @param float $localtax1tx Local tax 1 rate * @param float $localtax2tx Local tax 2 rate * @param int|string $date_debut_reel Date de debut reelle * @param int|string $date_fin_reel Date de fin reelle * @param string $price_base_type HT or TTC * @param int $info_bits Bits de type de lignes * @param int $fk_fournprice Fourn price id * @param int $pa_ht Buying price HT * @return int < 0 si erreur, > 0 si ok */ function updateline($rowid, $desc, $pu, $qty, $remise_percent, $date_start, $date_end, $tvatx, $localtax1tx = 0.0, $localtax2tx = 0.0, $date_debut_reel = '', $date_fin_reel = '', $price_base_type = 'HT', $info_bits = 0, $fk_fournprice = null, $pa_ht = 0) { global $user, $conf, $langs, $mysoc; // Nettoyage parametres $qty = trim($qty); $desc = trim($desc); $desc = trim($desc); $price = price2num($pu); $tvatx = price2num($tvatx); $localtax1tx = price2num($localtax1tx); $localtax2tx = price2num($localtax2tx); $pa_ht = price2num($pa_ht); $subprice = $price; $remise = 0; if (dol_strlen($remise_percent) > 0) { $remise = round($pu * $remise_percent / 100, 2); $price = $pu - $remise; } else { $remise_percent = 0; } dol_syslog(get_class($this) . "::updateline {$rowid}, {$desc}, {$pu}, {$qty}, {$remise_percent}, {$date_start}, {$date_end}, {$date_debut_reel}, {$date_fin_reel}, {$tvatx}, {$localtax1tx}, {$localtax2tx}, {$price_base_type}, {$info_bits}"); $this->db->begin(); // Calcul du total TTC et de la TVA pour la ligne a partir de // qty, pu, remise_percent et tvatx // TRES IMPORTANT: C'est au moment de l'insertion ligne qu'on doit stocker // la part ht, tva et ttc, et ce au niveau de la ligne qui a son propre taux tva. $localtaxes_type = getLocalTaxesFromRate($tvatx, 0, $this->societe, $mysoc); $tabprice = calcul_price_total($qty, $pu, $remise_percent, $tvatx, $localtax1tx, $localtax2tx, 0, $price_base_type, $info_bits, 1, '', $localtaxes_type); $total_ht = $tabprice[0]; $total_tva = $tabprice[1]; $total_ttc = $tabprice[2]; $total_localtax1 = $tabprice[9]; $total_localtax2 = $tabprice[10]; $localtax1_type = $localtaxes_type[0]; $localtax2_type = $localtaxes_type[2]; // TODO A virer // Anciens indicateurs: $price, $remise (a ne plus utiliser) $remise = 0; $price = price2num(round($pu, 2)); if (dol_strlen($remise_percent) > 0) { $remise = round($pu * $remise_percent / 100, 2); $price = $pu - $remise; } if (empty($pa_ht)) { $pa_ht = 0; } // si prix d'achat non renseigne et utilise pour calcul des marges alors prix achat = prix vente if ($pa_ht == 0) { if ($pu > 0 && (isset($conf->global->ForceBuyingPriceIfNull) && $conf->global->ForceBuyingPriceIfNull == 1)) { $pa_ht = $pu * (1 - $remise_percent / 100); } } $sql = "UPDATE " . MAIN_DB_PREFIX . "contratdet set description='" . $this->db->escape($desc) . "'"; $sql .= ",price_ht='" . price2num($price) . "'"; $sql .= ",subprice='" . price2num($subprice) . "'"; $sql .= ",remise='" . price2num($remise) . "'"; $sql .= ",remise_percent='" . price2num($remise_percent) . "'"; $sql .= ",qty='" . $qty . "'"; $sql .= ",tva_tx='" . price2num($tvatx) . "'"; $sql .= ",localtax1_tx='" . price2num($localtax1tx) . "'"; $sql .= ",localtax2_tx='" . price2num($localtax2tx) . "'"; $sql .= ",localtax1_type='" . $localtax1_type . "'"; $sql .= ",localtax2_type='" . $localtax2_type . "'"; $sql .= ", total_ht='" . price2num($total_ht) . "'"; $sql .= ", total_tva='" . price2num($total_tva) . "'"; $sql .= ", total_localtax1='" . price2num($total_localtax1) . "'"; $sql .= ", total_localtax2='" . price2num($total_localtax2) . "'"; $sql .= ", total_ttc='" . price2num($total_ttc) . "'"; $sql .= ", fk_product_fournisseur_price='" . $fk_fournprice . "'"; $sql .= ", buy_price_ht='" . price2num($pa_ht) . "'"; if ($date_start > 0) { $sql .= ",date_ouverture_prevue='" . $this->db->idate($date_start) . "'"; } else { $sql .= ",date_ouverture_prevue=null"; } if ($date_end > 0) { $sql .= ",date_fin_validite='" . $this->db->idate($date_end) . "'"; } else { $sql .= ",date_fin_validite=null"; } if ($date_debut_reel > 0) { $sql .= ",date_ouverture='" . $this->db->idate($date_debut_reel) . "'"; } else { $sql .= ",date_ouverture=null"; } if ($date_fin_reel > 0) { $sql .= ",date_cloture='" . $this->db->idate($date_fin_reel) . "'"; } else { $sql .= ",date_cloture=null"; } $sql .= " WHERE rowid = " . $rowid; dol_syslog(get_class($this) . "::updateline", LOG_DEBUG); $result = $this->db->query($sql); if ($result) { $result = $this->update_statut($user); if ($result >= 0) { // Call trigger $result = $this->call_trigger('LINECONTRACT_UPDATE', $user); if ($result < 0) { $this->db->rollback(); return -3; } // End call triggers $this->db->commit(); return 1; } else { $this->db->rollback(); dol_syslog(get_class($this) . "::updateligne Erreur -2"); return -2; } } else { $this->db->rollback(); $this->error = $this->db->error(); dol_syslog(get_class($this) . "::updateligne Erreur -1"); return -1; } }
/** * Update a detail line * * @param int $rowid Id of line to update * @param string $desc Description of line * @param double $pu Prix unitaire (HT ou TTC selon price_base_type) (> 0 even for credit note lines) * @param double $qty Quantity * @param double $remise_percent Pourcentage de remise de la ligne * @param int $date_start Date de debut de validite du service * @param int $date_end Date de fin de validite du service * @param double $txtva VAT Rate * @param double $txlocaltax1 Local tax 1 rate * @param double $txlocaltax2 Local tax 2 rate * @param string $price_base_type HT or TTC * @param int $info_bits Miscellaneous informations * @param int $type Type of line (0=product, 1=service) * @param int $fk_parent_line Id of parent line (0 in most cases, used by modules adding sublevels into lines). * @param int $skip_update_total Keep fields total_xxx to 0 (used for special lines by some modules) * @param int $fk_fournprice Id of origin supplier price * @param int $pa_ht Price (without tax) of product when it was bought * @param string $label Label of the line (deprecated, do not use) * @param int $special_code Special code (also used by externals modules!) * @param array $array_options extrafields array * @param int $situation_percent Situation advance percentage * @param string $fk_unit Code of the unit to use. Null to use the default one * @return int < 0 if KO, > 0 if OK */ function updateline($rowid, $desc, $pu, $qty, $remise_percent, $date_start, $date_end, $txtva, $txlocaltax1 = 0, $txlocaltax2 = 0, $price_base_type = 'HT', $info_bits = 0, $type = self::TYPE_STANDARD, $fk_parent_line = 0, $skip_update_total = 0, $fk_fournprice = null, $pa_ht = 0, $label = '', $special_code = 0, $array_options = 0, $situation_percent = 0, $fk_unit = null) { // Deprecation warning if ($label) { dol_syslog(__METHOD__ . ": using line label is deprecated", LOG_WARNING); } include_once DOL_DOCUMENT_ROOT . '/core/lib/price.lib.php'; global $mysoc; dol_syslog(get_class($this) . "::updateline rowid={$rowid}, desc={$desc}, pu={$pu}, qty={$qty}, remise_percent={$remise_percent}, date_start={$date_start}, date_end={$date_end}, txtva={$txtva}, txlocaltax1={$txlocaltax1}, txlocaltax2={$txlocaltax2}, price_base_type={$price_base_type}, info_bits={$info_bits}, type={$type}, fk_parent_line={$fk_parent_line} pa_ht={$pa_ht}, special_code={$special_code} fk_unit={$fk_unit}", LOG_DEBUG); if ($this->brouillon) { $this->db->begin(); // Clean parameters if (empty($qty)) { $qty = 0; } if (empty($fk_parent_line) || $fk_parent_line < 0) { $fk_parent_line = 0; } if (empty($special_code) || $special_code == 3) { $special_code = 0; } if ($situation_percent > 100 || is_null($situation_percent) || $situation_percent == "") { $situation_percent = 100; } $remise_percent = price2num($remise_percent); $qty = price2num($qty); $pu = price2num($pu); $pa_ht = price2num($pa_ht); $txtva = price2num($txtva); $txlocaltax1 = price2num($txlocaltax1); $txlocaltax2 = price2num($txlocaltax2); // Check parameters if ($type < 0) { return -1; } // Calculate total with, without tax and tax from qty, pu, remise_percent and txtva // TRES IMPORTANT: C'est au moment de l'insertion ligne qu'on doit stocker // la part ht, tva et ttc, et ce au niveau de la ligne qui a son propre taux tva. $localtaxes_type = getLocalTaxesFromRate($txtva, 0, $this->thirdparty, $mysoc); $txtva = preg_replace('/\\s*\\(.*\\)/', '', $txtva); // Remove code into vatrate. $tabprice = calcul_price_total($qty, $pu, $remise_percent, $txtva, $txlocaltax1, $txlocaltax2, 0, $price_base_type, $info_bits, $type, $mysoc, $localtaxes_type, $situation_percent); $total_ht = $tabprice[0]; $total_tva = $tabprice[1]; $total_ttc = $tabprice[2]; $total_localtax1 = $tabprice[9]; $total_localtax2 = $tabprice[10]; $pu_ht = $tabprice[3]; $pu_tva = $tabprice[4]; $pu_ttc = $tabprice[5]; // Old properties: $price, $remise (deprecated) $price = $pu; $remise = 0; if ($remise_percent > 0) { $remise = round($pu * $remise_percent / 100, 2); $price = $pu - $remise; } $price = price2num($price); //Fetch current line from the database and then clone the object and set it in $oldline property $line = new FactureLigne($this->db); $line->fetch($rowid); $staticline = clone $line; $line->oldline = $staticline; $this->line = $line; $this->line->context = $this->context; // Reorder if fk_parent_line change if (!empty($fk_parent_line) && !empty($staticline->fk_parent_line) && $fk_parent_line != $staticline->fk_parent_line) { $rangmax = $this->line_max($fk_parent_line); $this->line->rang = $rangmax + 1; } $this->line->rowid = $rowid; $this->line->label = $label; $this->line->desc = $desc; $this->line->qty = $this->type == self::TYPE_CREDIT_NOTE ? abs($qty) : $qty; // For credit note, quantity is always positive and unit price negative $this->line->tva_tx = $txtva; $this->line->localtax1_tx = $txlocaltax1; $this->line->localtax2_tx = $txlocaltax2; $this->line->localtax1_type = $localtaxes_type[0]; $this->line->localtax2_type = $localtaxes_type[2]; $this->line->remise_percent = $remise_percent; $this->line->subprice = $this->type == 2 ? -abs($pu_ht) : $pu_ht; // For credit note, unit price always negative, always positive otherwise $this->line->date_start = $date_start; $this->line->date_end = $date_end; $this->line->total_ht = $this->type == self::TYPE_CREDIT_NOTE || $qty < 0 ? -abs($total_ht) : $total_ht; // For credit note and if qty is negative, total is negative $this->line->total_tva = $total_tva; $this->line->total_localtax1 = $total_localtax1; $this->line->total_localtax2 = $total_localtax2; $this->line->total_ttc = $this->type == self::TYPE_CREDIT_NOTE || $qty < 0 ? -abs($total_ttc) : $total_ttc; $this->line->info_bits = $info_bits; $this->line->special_code = $special_code; $this->line->product_type = $type; $this->line->fk_parent_line = $fk_parent_line; $this->line->skip_update_total = $skip_update_total; $this->line->situation_percent = $situation_percent; $this->line->fk_unit = $fk_unit; $this->line->fk_fournprice = $fk_fournprice; $this->line->pa_ht = $pa_ht; if (is_array($array_options) && count($array_options) > 0) { $this->line->array_options = $array_options; } $result = $this->line->update(); if ($result > 0) { // Reorder if child line if (!empty($fk_parent_line)) { $this->line_order(true, 'DESC'); } // Mise a jour info denormalisees au niveau facture $this->update_price(1); $this->db->commit(); return $result; } else { $this->error = $this->line->error; $this->db->rollback(); return -1; } } else { $this->error = "Invoice statut makes operation forbidden"; return -2; } }
/** * Update line * * @param int $rowid Id de la ligne de facture * @param string $desc Description de la ligne * @param double $pu Prix unitaire * @param double $qty Quantity * @param double $remise_percent Pourcentage de remise de la ligne * @param double $txtva Taux TVA * @param double $txlocaltax1 Localtax1 tax * @param double $txlocaltax2 Localtax2 tax * @param double $price_base_type Type of price base * @param int $info_bits Miscellaneous informations * @param int $type Type of line (0=product, 1=service) * @param int $notrigger Disable triggers * @param timestamp $date_start Date start of service * @param timestamp $date_end Date end of service * @param array $array_options Extrafields array * @param string $fk_unit Code of the unit to use. Null to use the default one * @return int < 0 if error, > 0 if ok */ function updateline($rowid, $desc, $pu, $qty, $remise_percent, $txtva, $txlocaltax1 = 0, $txlocaltax2 = 0, $price_base_type = 'HT', $info_bits = 0, $type = 0, $notrigger = false, $date_start = '', $date_end = '', $array_options = 0, $fk_unit = null) { global $mysoc; dol_syslog(get_class($this) . "::updateline {$rowid}, {$desc}, {$pu}, {$qty}, {$remise_percent}, {$txtva}, {$price_base_type}, {$info_bits}, {$type}, {$fk_unit}"); include_once DOL_DOCUMENT_ROOT . '/core/lib/price.lib.php'; if ($this->brouillon) { $this->db->begin(); // Clean parameters if (empty($qty)) { $qty = 0; } if (empty($info_bits)) { $info_bits = 0; } if (empty($txtva)) { $txtva = 0; } if (empty($txlocaltax1)) { $txlocaltax1 = 0; } if (empty($txlocaltax2)) { $txlocaltax2 = 0; } if (empty($remise)) { $remise = 0; } if (empty($remise_percent)) { $remise_percent = 0; } $remise_percent = price2num($remise_percent); $qty = price2num($qty); if (!$qty) { $qty = 1; } $pu = price2num($pu); $txtva = price2num($txtva); $txlocaltax1 = price2num($txlocaltax1); $txlocaltax2 = price2num($txlocaltax2); // Check parameters if ($type < 0) { return -1; } // Calcul du total TTC et de la TVA pour la ligne a partir de // qty, pu, remise_percent et txtva // TRES IMPORTANT: C'est au moment de l'insertion ligne qu'on doit stocker // la part ht, tva et ttc, et ce au niveau de la ligne qui a son propre taux tva. $localtaxes_type = getLocalTaxesFromRate($txtva, 0, $mysoc, $this->thirdparty); $txtva = preg_replace('/\\s*\\(.*\\)/', '', $txtva); // Remove code into vatrate. $tabprice = calcul_price_total($qty, $pu, $remise_percent, $txtva, $txlocaltax1, $txlocaltax2, 0, $price_base_type, $info_bits, $type, $this->thirdparty, $localtaxes_type); $total_ht = $tabprice[0]; $total_tva = $tabprice[1]; $total_ttc = $tabprice[2]; $total_localtax1 = $tabprice[9]; $total_localtax2 = $tabprice[10]; $localtax1_type = $localtaxes_type[0]; $localtax2_type = $localtaxes_type[2]; $subprice = price2num($pu, 'MU'); // Mise a jour ligne en base $sql = "UPDATE " . MAIN_DB_PREFIX . "commande_fournisseurdet SET"; $sql .= " description='" . $this->db->escape($desc) . "'"; $sql .= ",subprice='" . price2num($subprice) . "'"; //$sql.= ",remise='".price2num($remise)."'"; $sql .= ",remise_percent='" . price2num($remise_percent) . "'"; $sql .= ",tva_tx='" . price2num($txtva) . "'"; $sql .= ",localtax1_tx='" . price2num($txlocaltax1) . "'"; $sql .= ",localtax2_tx='" . price2num($txlocaltax2) . "'"; $sql .= ",localtax1_type='" . $localtax1_type . "'"; $sql .= ",localtax2_type='" . $localtax2_type . "'"; $sql .= ",qty='" . price2num($qty) . "'"; $sql .= ",date_start=" . (!empty($date_start) ? "'" . $this->db->idate($date_start) . "'" : "null"); $sql .= ",date_end=" . (!empty($date_end) ? "'" . $this->db->idate($date_end) . "'" : "null"); $sql .= ",info_bits='" . $info_bits . "'"; $sql .= ",total_ht='" . price2num($total_ht) . "'"; $sql .= ",total_tva='" . price2num($total_tva) . "'"; $sql .= ",total_localtax1='" . price2num($total_localtax1) . "'"; $sql .= ",total_localtax2='" . price2num($total_localtax2) . "'"; $sql .= ",total_ttc='" . price2num($total_ttc) . "'"; $sql .= ",product_type=" . $type; $sql .= $fk_unit ? ",fk_unit='" . $this->db->escape($fk_unit) . "'" : ", fk_unit=null"; $sql .= " WHERE rowid = " . $rowid; dol_syslog(get_class($this) . "::updateline", LOG_DEBUG); $result = $this->db->query($sql); if ($result > 0) { $this->rowid = $rowid; if (empty($conf->global->MAIN_EXTRAFIELDS_DISABLED)) { $tmpline = new CommandeFournisseurLigne($this->db); $tmpline->id = $this->rowid; $tmpline->array_options = $array_options; $result = $tmpline->insertExtraFields(); if ($result < 0) { $error++; } } if (!$error && !$notrigger) { global $conf, $langs, $user; // Call trigger $result = $this->call_trigger('LINEORDER_SUPPLIER_UPDATE', $user); if ($result < 0) { $this->db->rollback(); return -1; } // End call triggers } // Mise a jour info denormalisees au niveau facture if (!$error) { $this->update_price('', 'auto'); } if (!$error) { $this->db->commit(); return $result; } else { $this->db->rollback(); return -1; } } else { $this->error = $this->db->lasterror(); $this->db->rollback(); return -1; } } else { $this->error = "Order status makes operation forbidden"; dol_syslog(get_class($this) . "::updateline " . $this->error, LOG_ERR); return -2; } }
/** * Update a proposal line * * @param int $rowid Id de la ligne * @param float $pu Prix unitaire (HT ou TTC selon price_base_type) * @param float $qty Quantity * @param float $remise_percent Remise effectuee sur le produit * @param float $txtva Taux de TVA * @param float $txlocaltax1 Local tax 1 rate * @param float $txlocaltax2 Local tax 2 rate * @param string $desc Description * @param string $price_base_type HT ou TTC * @param int $info_bits Miscellaneous informations * @param int $special_code Special code (also used by externals modules!) * @param int $fk_parent_line Id of parent line (0 in most cases, used by modules adding sublevels into lines). * @param int $skip_update_total Keep fields total_xxx to 0 (used for special lines by some modules) * @param int $fk_fournprice Id of origin supplier price * @param int $pa_ht Price (without tax) of product when it was bought * @param string $label ??? * @param int $type 0/1=Product/service * @param int $date_start Start date of the line * @param int $date_end End date of the line * @param array $array_option extrafields array * @return int 0 if OK, <0 if KO */ function updateline($rowid, $pu, $qty, $remise_percent, $txtva, $txlocaltax1 = 0.0, $txlocaltax2 = 0.0, $desc = '', $price_base_type = 'HT', $info_bits = 0, $special_code = 0, $fk_parent_line = 0, $skip_update_total = 0, $fk_fournprice = 0, $pa_ht = 0, $label = '', $type = 0, $date_start = '', $date_end = '', $array_option = 0) { global $mysoc; dol_syslog(get_class($this) . "::updateLine rowid={$rowid}, pu={$pu}, qty={$qty}, remise_percent={$remise_percent}, txtva={$txtva}, desc={$desc}, price_base_type={$price_base_type}, info_bits={$info_bits}, special_code={$special_code}, fk_parent_line={$fk_parent_line}, pa_ht={$a_ht}, type={$type}, date_start={$date_start}, date_end={$date_end}"); include_once DOL_DOCUMENT_ROOT . '/core/lib/price.lib.php'; // Clean parameters $remise_percent = price2num($remise_percent); $qty = price2num($qty); $pu = price2num($pu); $txtva = price2num($txtva); $txlocaltax1 = price2num($txlocaltax1); $txlocaltax2 = price2num($txlocaltax2); $pa_ht = price2num($pa_ht); if (empty($qty) && empty($special_code)) { $special_code = 3; } // Set option tag if (!empty($qty) && $special_code == 3) { $special_code = 0; } // Remove option tag if ($this->statut == 0) { $this->db->begin(); // Calcul du total TTC et de la TVA pour la ligne a partir de // qty, pu, remise_percent et txtva // TRES IMPORTANT: C'est au moment de l'insertion ligne qu'on doit stocker // la part ht, tva et ttc, et ce au niveau de la ligne qui a son propre taux tva. $localtaxes_type = getLocalTaxesFromRate($txtva, 0, $this->thirdparty, $mysoc); $tabprice = calcul_price_total($qty, $pu, $remise_percent, $txtva, $txlocaltax1, $txlocaltax2, 0, $price_base_type, $info_bits, $type, $mysoc, $localtaxes_type); $total_ht = $tabprice[0]; $total_tva = $tabprice[1]; $total_ttc = $tabprice[2]; $total_localtax1 = $tabprice[9]; $total_localtax2 = $tabprice[10]; // Anciens indicateurs: $price, $remise (a ne plus utiliser) $price = $pu; if ($remise_percent > 0) { $remise = round($pu * $remise_percent / 100, 2); $price = $pu - $remise; } // Update line $this->line = new PropaleLigne($this->db); $this->line->context = $this->context; // Stock previous line records $staticline = new PropaleLigne($this->db); $staticline->fetch($rowid); $this->line->oldline = $staticline; // Reorder if fk_parent_line change if (!empty($fk_parent_line) && !empty($staticline->fk_parent_line) && $fk_parent_line != $staticline->fk_parent_line) { $rangmax = $this->line_max($fk_parent_line); $this->line->rang = $rangmax + 1; } $this->line->rowid = $rowid; $this->line->label = $label; $this->line->desc = $desc; $this->line->qty = $qty; $this->line->product_type = $type; $this->line->tva_tx = $txtva; $this->line->localtax1_tx = $txlocaltax1; $this->line->localtax2_tx = $txlocaltax2; $this->line->localtax1_type = $localtaxes_type[0]; $this->line->localtax2_type = $localtaxes_type[2]; $this->line->remise_percent = $remise_percent; $this->line->subprice = $pu; $this->line->info_bits = $info_bits; $this->line->total_ht = $total_ht; $this->line->total_tva = $total_tva; $this->line->total_localtax1 = $total_localtax1; $this->line->total_localtax2 = $total_localtax2; $this->line->total_ttc = $total_ttc; $this->line->special_code = $special_code; $this->line->fk_parent_line = $fk_parent_line; $this->line->skip_update_total = $skip_update_total; // infos marge if (!empty($fk_product) && empty($fk_fournprice) && empty($pa_ht)) { // by external module, take lowest buying price include_once DOL_DOCUMENT_ROOT . '/fourn/class/fournisseur.product.class.php'; $productFournisseur = new ProductFournisseur($this->db); $productFournisseur->find_min_price_product_fournisseur($fk_product); $this->line->fk_fournprice = $productFournisseur->product_fourn_price_id; } else { $this->line->fk_fournprice = $fk_fournprice; } $this->line->pa_ht = $pa_ht; $this->line->date_start = $date_start; $this->line->date_end = $date_end; // TODO deprecated $this->line->price = $price; $this->line->remise = $remise; if (is_array($array_option) && count($array_option) > 0) { $this->line->array_options = $array_option; } $result = $this->line->update(); if ($result > 0) { // Reorder if child line if (!empty($fk_parent_line)) { $this->line_order(true, 'DESC'); } $this->update_price(1); $this->fk_propal = $this->id; $this->rowid = $rowid; $this->db->commit(); return $result; } else { $this->error = $this->line->error; $this->db->rollback(); return -1; } } else { dol_syslog(get_class($this) . "::updateline Erreur -2 Propal en mode incompatible pour cette action"); return -2; } }
/** * Update a line in database * * @param int $rowid Id of line to update * @param string $desc Description de la ligne * @param float $pu Prix unitaire * @param float $qty Quantity * @param float $remise_percent Pourcentage de remise de la ligne * @param float $txtva Taux TVA * @param float $txlocaltax1 Local tax 1 rate * @param float $txlocaltax2 Local tax 2 rate * @param string $price_base_type HT or TTC * @param int $info_bits Miscellaneous informations on line * @param int $date_start Start date of the line * @param int $date_end End date of the line * @param int $type Type of line (0=product, 1=service) * @param int $fk_parent_line Id of parent line (0 in most cases, used by modules adding sublevels into lines). * @param int $skip_update_total Keep fields total_xxx to 0 (used for special lines by some modules) * @param int $fk_fournprice Id of origin supplier price * @param int $pa_ht Price (without tax) of product when it was bought * @param string $label Label * @param int $special_code Special code (also used by externals modules!) * @param array $array_options extrafields array * @param string $fk_unit Code of the unit to use. Null to use the default one * @return int < 0 if KO, > 0 if OK */ function updateline($rowid, $desc, $pu, $qty, $remise_percent, $txtva, $txlocaltax1 = 0.0, $txlocaltax2 = 0.0, $price_base_type = 'HT', $info_bits = 0, $date_start = '', $date_end = '', $type = 0, $fk_parent_line = 0, $skip_update_total = 0, $fk_fournprice = null, $pa_ht = 0, $label = '', $special_code = 0, $array_options = 0, $fk_unit = null) { global $conf, $mysoc; dol_syslog(get_class($this) . "::updateline id={$rowid}, desc={$desc}, pu={$pu}, qty={$qty}, remise_percent={$remise_percent}, txtva={$txtva}, txlocaltax1={$txlocaltax1}, txlocaltax2={$txlocaltax2}, price_base_type={$price_base_type}, info_bits={$info_bits}, date_start={$date_start}, date_end={$date_end}, type={$type}, fk_parent_line={$fk_parent_line}, pa_ht={$pa_ht}, special_code={$special_code}"); include_once DOL_DOCUMENT_ROOT . '/core/lib/price.lib.php'; if (!empty($this->brouillon)) { $this->db->begin(); // Clean parameters if (empty($qty)) { $qty = 0; } if (empty($info_bits)) { $info_bits = 0; } if (empty($txtva)) { $txtva = 0; } if (empty($txlocaltax1)) { $txlocaltax1 = 0; } if (empty($txlocaltax2)) { $txlocaltax2 = 0; } if (empty($remise)) { $remise = 0; } if (empty($remise_percent)) { $remise_percent = 0; } if (empty($special_code) || $special_code == 3) { $special_code = 0; } $remise_percent = price2num($remise_percent); $qty = price2num($qty); $pu = price2num($pu); $pa_ht = price2num($pa_ht); $txtva = price2num($txtva); $txlocaltax1 = price2num($txlocaltax1); $txlocaltax2 = price2num($txlocaltax2); // Calcul du total TTC et de la TVA pour la ligne a partir de // qty, pu, remise_percent et txtva // TRES IMPORTANT: C'est au moment de l'insertion ligne qu'on doit stocker // la part ht, tva et ttc, et ce au niveau de la ligne qui a son propre taux tva. $localtaxes_type = getLocalTaxesFromRate($txtva, 0, $this->thirdparty, $mysoc); $txtva = preg_replace('/\\s*\\(.*\\)/', '', $txtva); // Remove code into vatrate. $tabprice = calcul_price_total($qty, $pu, $remise_percent, $txtva, $txlocaltax1, $txlocaltax2, 0, $price_base_type, $info_bits, $type, $mysoc, $localtaxes_type); $total_ht = $tabprice[0]; $total_tva = $tabprice[1]; $total_ttc = $tabprice[2]; $total_localtax1 = $tabprice[9]; $total_localtax2 = $tabprice[10]; // Anciens indicateurs: $price, $subprice, $remise (a ne plus utiliser) $price = $pu; $subprice = $pu; $remise = 0; if ($remise_percent > 0) { $remise = round($pu * $remise_percent / 100, 2); $price = $pu - $remise; } //Fetch current line from the database and then clone the object and set it in $oldline property $line = new OrderLine($this->db); $line->fetch($rowid); $staticline = clone $line; $line->oldline = $staticline; $this->line = $line; $this->line->context = $this->context; // Reorder if fk_parent_line change if (!empty($fk_parent_line) && !empty($staticline->fk_parent_line) && $fk_parent_line != $staticline->fk_parent_line) { $rangmax = $this->line_max($fk_parent_line); $this->line->rang = $rangmax + 1; } $this->line->rowid = $rowid; $this->line->label = $label; $this->line->desc = $desc; $this->line->qty = $qty; $this->line->tva_tx = $txtva; $this->line->localtax1_tx = $txlocaltax1; $this->line->localtax2_tx = $txlocaltax2; $this->line->localtax1_type = $localtaxes_type[0]; $this->line->localtax2_type = $localtaxes_type[2]; $this->line->remise_percent = $remise_percent; $this->line->subprice = $subprice; $this->line->info_bits = $info_bits; $this->line->special_code = $special_code; $this->line->total_ht = $total_ht; $this->line->total_tva = $total_tva; $this->line->total_localtax1 = $total_localtax1; $this->line->total_localtax2 = $total_localtax2; $this->line->total_ttc = $total_ttc; $this->line->date_start = $date_start; $this->line->date_end = $date_end; $this->line->product_type = $type; $this->line->fk_parent_line = $fk_parent_line; $this->line->skip_update_total = $skip_update_total; $this->line->fk_unit = $fk_unit; $this->line->fk_fournprice = $fk_fournprice; $this->line->pa_ht = $pa_ht; // TODO deprecated $this->line->price = $price; $this->line->remise = $remise; if (is_array($array_options) && count($array_options) > 0) { $this->line->array_options = $array_options; } $result = $this->line->update(); if ($result > 0) { // Reorder if child line if (!empty($fk_parent_line)) { $this->line_order(true, 'DESC'); } // Mise a jour info denormalisees $this->update_price(1); $this->db->commit(); return $result; } else { $this->error = $this->line->error; $this->db->rollback(); return -1; } } else { $this->error = get_class($this) . "::updateline Order status makes operation forbidden"; $this->errors = array('OrderStatusMakeOperationForbidden'); return -2; } }
public static function calculePrice($product) { global $db, $mysoc; require_once DOL_DOCUMENT_ROOT . "/core/lib/price.lib.php"; $qty = $product["cant"]; if ($product["price_base_type"] == "HT") { $pu = $product["price"]; } else { $pu = $product["price_ttc"]; } $remise_percent_ligne = $product["discount"] ? $product["discount"] : 0; $txtva = $product["tva_tx"]; $uselocaltax1_rate = $product["localtax1_tx"] > 0 ? $product["localtax1_tx"] : 0; $uselocaltax2_rate = $product["localtax2_tx"] > 0 ? $product["localtax2_tx"] : 0; $remise_percent_global = $product["remise_percent_global"] ? $product["remise_percent_global"] : 0; $price_base_type = $product["price_base_type"]; $type = $product["fk_product_type"] ? $product["fk_product_type"] : 0; $info_bits = 0; $remise_percent_ligne = $remise_percent_global + $remise_percent_ligne; $remise_percent_global = 0; $localtaxes_type = getLocalTaxesFromRate($txtva, 0, $mysoc); $tabprice = calcul_price_total($qty, $pu, $remise_percent_ligne, $txtva, $uselocaltax1_rate, $uselocaltax2_rate, $remise_percent_global, $price_base_type, $info_bits, $type, $mysoc, $localtaxes_type); $result["total_ht"] = $tabprice[0]; $result["total_tva"] = $tabprice[1]; $result["total_ttc"] = $tabprice[2]; $result["total_localtax1"] = $tabprice[9]; $result["total_localtax2"] = $tabprice[10]; $result["pu_ht"] = $tabprice[3]; $result["pu_tva"] = $tabprice[4]; $result["pu_ttc"] = $tabprice[5]; $result["total_ttc_without_discount"] = $tabprice[8]; return $result; }
// les variables $cptcli = !empty($conf->global->COMPTA_ACCOUNT_CUSTOMER) ? $conf->global->COMPTA_ACCOUNT_CUSTOMER : $langs->trans("CodeNotDef"); $compta_soc = !empty($obj->code_compta) ? $obj->code_compta : $cptcli; $compta_prod = $obj->accountancy_code_sell; if (empty($compta_prod)) { if ($obj->product_type == 0) { $compta_prod = !empty($conf->global->COMPTA_PRODUCT_SOLD_ACCOUNT) ? $conf->global->COMPTA_PRODUCT_SOLD_ACCOUNT : $langs->trans("CodeNotDef"); } else { $compta_prod = !empty($conf->global->COMPTA_SERVICE_SOLD_ACCOUNT) ? $conf->global->COMPTA_SERVICE_SOLD_ACCOUNT : $langs->trans("CodeNotDef"); } } $cpttva = !empty($conf->global->COMPTA_VAT_ACCOUNT) ? $conf->global->COMPTA_VAT_ACCOUNT : $langs->trans("CodeNotDef"); $compta_tva = !empty($obj->account_tva) ? $obj->account_tva : $cpttva; $account_localtax1 = getLocalTaxesFromRate($obj->tva_tx, 1, $mysoc); $compta_localtax1 = !empty($account_localtax1[3]) ? $account_localtax1[3] : $langs->trans("CodeNotDef"); $account_localtax2 = getLocalTaxesFromRate($obj->tva_tx, 2, $mysoc); $compta_localtax2 = !empty($account_localtax2[3]) ? $account_localtax2[3] : $langs->trans("CodeNotDef"); //la ligne facture $tabfac[$obj->rowid]["date"] = $obj->datef; $tabfac[$obj->rowid]["ref"] = $obj->facnumber; $tabfac[$obj->rowid]["type"] = $obj->type; if (!isset($tabttc[$obj->rowid][$compta_soc])) { $tabttc[$obj->rowid][$compta_soc] = 0; } if (!isset($tabht[$obj->rowid][$compta_prod])) { $tabht[$obj->rowid][$compta_prod] = 0; } if (!isset($tabtva[$obj->rowid][$compta_tva])) { $tabtva[$obj->rowid][$compta_tva] = 0; } if (!isset($tablocaltax1[$obj->rowid][$compta_localtax1])) {
// contrôles $compta_soc = !empty($obj->code_compta_fournisseur) ? $obj->code_compta_fournisseur : $cptfour; $compta_prod = $obj->accountancy_code_buy; if (empty($compta_prod)) { if ($obj->product_type == 0) { $compta_prod = !empty($conf->global->ACCOUNTING_PRODUCT_BUY_ACCOUNT) ? $conf->global->ACCOUNTING_PRODUCT_BUY_ACCOUNT : $langs->trans("CodeNotDef"); } else { $compta_prod = !empty($conf->global->ACCOUNTING_SERVICE_BUY_ACCOUNT) ? $conf->global->ACCOUNTING_SERVICE_BUY_ACCOUNT : $langs->trans("CodeNotDef"); } } $compta_tva = !empty($obj->account_tva) ? $obj->account_tva : $cpttva; $compta_localtax1 = !empty($obj->account_localtax1) ? $obj->account_localtax1 : $langs->trans("CodeNotDef"); $compta_localtax2 = !empty($obj->account_localtax2) ? $obj->account_localtax2 : $langs->trans("CodeNotDef"); $account_localtax1 = getLocalTaxesFromRate($obj->tva_tx, 1, $mysoc, $obj->thirdparty); $compta_localtax1 = !empty($account_localtax1[2]) ? $account_localtax1[2] : $langs->trans("CodeNotDef"); $account_localtax2 = getLocalTaxesFromRate($obj->tva_tx, 2, $mysoc, $obj->thirdparty); $compta_localtax2 = !empty($account_localtax2[2]) ? $account_localtax2[2] : $langs->trans("CodeNotDef"); $tabfac[$obj->rowid]["date"] = $obj->datef; $tabfac[$obj->rowid]["ref"] = $obj->ref_supplier; $tabfac[$obj->rowid]["type"] = $obj->type; $tabfac[$obj->rowid]["lib"] = $obj->libelle; $tabttc[$obj->rowid][$compta_soc] += $obj->total_ttc; $tabht[$obj->rowid][$compta_prod] += $obj->total_ht; if ($obj->recuperableonly != 1) { $tabtva[$obj->rowid][$compta_tva] += $obj->total_tva; } $tablocaltax1[$obj->rowid][$compta_localtax1] += $obj->total_localtax1; $tablocaltax2[$obj->rowid][$compta_localtax2] += $obj->total_localtax2; $tabcompany[$obj->rowid] = array('id' => $obj->socid, 'name' => $obj->name); $i++; }
/** * Update a line detail into database * * @param int $id Id of line invoice * @param string $desc Description of line * @param double $pu Prix unitaire (HT ou TTC selon price_base_type) * @param double $vatrate VAT Rate * @param double $txlocaltax1 LocalTax1 Rate * @param double $txlocaltax2 LocalTax2 Rate * @param double $qty Quantity * @param int $idproduct Id produit * @param double $price_base_type HT or TTC * @param int $info_bits Miscellaneous informations of line * @param int $type Type of line (0=product, 1=service) * @param double $remise_percent Pourcentage de remise de la ligne * @param int $notrigger Disable triggers * @return int <0 if KO, >0 if OK */ function updateline($id, $desc, $pu, $vatrate, $txlocaltax1 = 0, $txlocaltax2 = 0, $qty = 1, $idproduct = 0, $price_base_type = 'HT', $info_bits = 0, $type = 0, $remise_percent = 0, $notrigger = false) { dol_syslog(get_class($this) . "::updateline {$id},{$desc},{$pu},{$vatrate},{$qty},{$idproduct},{$price_base_type},{$info_bits},{$type},{$remise_percent}", LOG_DEBUG); include_once DOL_DOCUMENT_ROOT . '/core/lib/price.lib.php'; $pu = price2num($pu); $qty = price2num($qty); $remise_percent = price2num($remise_percent); // Check parameters if (!is_numeric($pu) || !is_numeric($qty)) { return -1; } if ($type < 0) { return -1; } // Clean parameters if (empty($vatrate)) { $vatrate = 0; } if (empty($txlocaltax1)) { $txlocaltax1 = 0; } if (empty($txlocaltax2)) { $txlocaltax2 = 0; } $txlocaltax1 = price2num($txlocaltax1); $txlocaltax2 = price2num($txlocaltax2); // Calcul du total TTC et de la TVA pour la ligne a partir de // qty, pu, remise_percent et txtva // TRES IMPORTANT: C'est au moment de l'insertion ligne qu'on doit stocker // la part ht, tva et ttc, et ce au niveau de la ligne qui a son propre taux tva. $localtaxes_type = getLocalTaxesFromRate($vatrate, 0, $this->thirdparty); $tabprice = calcul_price_total($qty, $pu, $remise_percent, $vatrate, $txlocaltax1, $txlocaltax2, 0, $price_base_type, $info_bits, $type, $this->thirdparty, $localtaxes_type); $total_ht = $tabprice[0]; $total_tva = $tabprice[1]; $total_ttc = $tabprice[2]; $pu_ht = $tabprice[3]; $pu_tva = $tabprice[4]; $pu_ttc = $tabprice[5]; $total_localtax1 = $tabprice[9]; $total_localtax2 = $tabprice[10]; if (empty($info_bits)) { $info_bits = 0; } if ($idproduct) { $product = new Product($this->db); $result = $product->fetch($idproduct); $product_type = $product->type; } else { $product_type = $type; } $this->db->begin(); $sql = "UPDATE " . MAIN_DB_PREFIX . "facture_fourn_det SET"; $sql .= " description ='" . $this->db->escape($desc) . "'"; $sql .= ", pu_ht = " . price2num($pu_ht); $sql .= ", pu_ttc = " . price2num($pu_ttc); $sql .= ", qty = " . price2num($qty); $sql .= ", remise_percent = " . price2num($remise_percent); $sql .= ", tva_tx = " . price2num($vatrate); $sql .= ", localtax1_tx = " . price2num($txlocaltax1); $sql .= ", localtax2_tx = " . price2num($txlocaltax2); $sql .= ", localtax1_type = '" . $localtaxes_type[0] . "'"; $sql .= ", localtax2_type = '" . $localtaxes_type[2] . "'"; $sql .= ", total_ht = " . price2num($total_ht); $sql .= ", tva= " . price2num($total_tva); $sql .= ", total_localtax1= " . price2num($total_localtax1); $sql .= ", total_localtax2= " . price2num($total_localtax2); $sql .= ", total_ttc = " . price2num($total_ttc); if ($idproduct) { $sql .= ", fk_product = " . $idproduct; } else { $sql .= ", fk_product = null"; } $sql .= ", product_type = " . $product_type; $sql .= ", info_bits = " . $info_bits; $sql .= " WHERE rowid = " . $id; dol_syslog(get_class($this) . "::updateline sql=" . $sql); $resql = $this->db->query($sql); if ($resql) { $this->rowid = $id; if (!$notrigger) { global $conf, $langs, $user; // Appel des triggers include_once DOL_DOCUMENT_ROOT . '/core/class/interfaces.class.php'; $interface = new Interfaces($this->db); $result = $interface->run_triggers('LINEBILL_SUPPLIER_UPDATE', $this, $user, $langs, $conf); if ($result < 0) { $error++; $this->errors = $interface->errors; $this->db->rollback(); return -1; } // Fin appel triggers } // Update total price into invoice record $result = $this->update_price('', 'auto'); $this->db->commit(); return $result; } else { $this->db->rollback(); $this->error = $this->db->lasterror(); dol_syslog(get_class($this) . "::updateline error=" . $this->error, LOG_ERR); return -1; } }
/** * Update line * * @param int $rowid Id de la ligne de facture * @param string $desc Description de la ligne * @param double $pu Prix unitaire * @param double $qty Quantity * @param double $remise_percent Pourcentage de remise de la ligne * @param double $txtva Taux TVA * @param double $txlocaltax1 Localtax1 tax * @param double $txlocaltax2 Localtax2 tax * @param double $price_base_type Type of price base * @param int $info_bits Miscellaneous informations * @param int $type Type of line (0=product, 1=service) * @param int $notrigger Disable triggers * @return int < 0 if error, > 0 if ok */ function updateline($rowid, $desc, $pu, $qty, $remise_percent, $txtva, $txlocaltax1 = 0, $txlocaltax2 = 0, $price_base_type = 'HT', $info_bits = 0, $type = 0, $notrigger = false) { dol_syslog(get_class($this) . "::updateline {$rowid}, {$desc}, {$pu}, {$qty}, {$remise_percent}, {$txtva}, {$price_base_type}, {$info_bits}, {$type}"); include_once DOL_DOCUMENT_ROOT . '/core/lib/price.lib.php'; if ($this->brouillon) { $this->db->begin(); // Clean parameters if (empty($qty)) { $qty = 0; } if (empty($info_bits)) { $info_bits = 0; } if (empty($txtva)) { $txtva = 0; } if (empty($txlocaltax1)) { $txlocaltax1 = 0; } if (empty($txlocaltax2)) { $txlocaltax2 = 0; } if (empty($remise)) { $remise = 0; } if (empty($remise_percent)) { $remise_percent = 0; } $remise_percent = price2num($remise_percent); $qty = price2num($qty); if (!$qty) { $qty = 1; } $pu = price2num($pu); $txtva = price2num($txtva); $txlocaltax1 = price2num($txlocaltax1); $txlocaltax2 = price2num($txlocaltax2); // Check parameters if ($type < 0) { return -1; } // Calcul du total TTC et de la TVA pour la ligne a partir de // qty, pu, remise_percent et txtva // TRES IMPORTANT: C'est au moment de l'insertion ligne qu'on doit stocker // la part ht, tva et ttc, et ce au niveau de la ligne qui a son propre taux tva. $localtaxes_type = getLocalTaxesFromRate($txtva, 0, $this->thirdparty); $tabprice = calcul_price_total($qty, $pu, $remise_percent, $txtva, $txlocaltax1, $txlocaltax2, 0, $price_base_type, $info_bits, $type, $this->thirdparty, $localtaxes_type); $total_ht = $tabprice[0]; $total_tva = $tabprice[1]; $total_ttc = $tabprice[2]; $total_localtax1 = $tabprice[9]; $total_localtax2 = $tabprice[10]; $localtax1_type = $localtaxes_type[0]; $localtax2_type = $localtaxes_type[2]; $subprice = price2num($pu, 'MU'); // Mise a jour ligne en base $sql = "UPDATE " . MAIN_DB_PREFIX . "commande_fournisseurdet SET"; $sql .= " description='" . $this->db->escape($desc) . "'"; $sql .= ",subprice='" . price2num($subprice) . "'"; //$sql.= ",remise='".price2num($remise)."'"; $sql .= ",remise_percent='" . price2num($remise_percent) . "'"; $sql .= ",tva_tx='" . price2num($txtva) . "'"; $sql .= ",localtax1_tx='" . price2num($txlocaltax1) . "'"; $sql .= ",localtax2_tx='" . price2num($txlocaltax2) . "'"; $sql .= ",localtax1_type='" . $localtax1_type . "'"; $sql .= ",localtax2_type='" . $localtax2_type . "'"; $sql .= ",qty='" . price2num($qty) . "'"; /*if ($date_end) { $sql.= ",date_start='$date_end'"; } else { $sql.=',date_start=null'; } if ($date_end) { $sql.= ",date_end='$date_end'"; } else { $sql.=',date_end=null'; }*/ $sql .= ",info_bits='" . $info_bits . "'"; $sql .= ",total_ht='" . price2num($total_ht) . "'"; $sql .= ",total_tva='" . price2num($total_tva) . "'"; $sql .= ",total_localtax1='" . price2num($total_localtax1) . "'"; $sql .= ",total_localtax2='" . price2num($total_localtax2) . "'"; $sql .= ",total_ttc='" . price2num($total_ttc) . "'"; $sql .= ",product_type=" . $type; $sql .= " WHERE rowid = " . $rowid; dol_syslog(get_class($this) . "::updateline sql=" . $sql); $result = $this->db->query($sql); if ($result > 0) { $this->rowid = $rowid; if (!$notrigger) { global $conf, $langs, $user; // Appel des triggers include_once DOL_DOCUMENT_ROOT . '/core/class/interfaces.class.php'; $interface = new Interfaces($this->db); $result = $interface->run_triggers('LINEORDER_SUPPLIER_UPDATE', $this, $user, $langs, $conf); if ($result < 0) { $error++; $this->errors = $interface->errors; $this->db->rollback(); return -1; } // Fin appel triggers } // Mise a jour info denormalisees au niveau facture $this->update_price('', 'auto'); $this->db->commit(); return $result; } else { $this->error = $this->db->error(); dol_syslog(get_class($this) . "::updateline " . $this->error, LOG_ERR); $this->db->rollback(); return -1; } } else { $this->error = "Order status makes operation forbidden"; dol_syslog(get_class($this) . "::updateline " . $this->error, LOG_ERR); return -2; } }
if (!empty($conf->global->MAIN_USE_LOCALTAX_TYPE_7)) { if ($this->total_localtax1 == 0) { global $mysoc; $localtax1_array = getLocalTaxesFromRate($vatrate, 1, $mysoc); if (empty($obj->localtax1_type)) { $obj->localtax1_type = $localtax1_array[0]; $obj->localtax1_tx = $localtax1_array[1]; } if ($obj->localtax1_type == '7') { $total_localtax1 += $obj->localtax1_tx; $total_ttc += $obj->localtax1_tx; } } if ($this->total_localtax2 == 0) { global $mysoc; $localtax2_array = getLocalTaxesFromRate($vatrate, 2, $mysoc); if (empty($obj->localtax2_type)) { $obj->localtax2_type = $localtax2_array[0]; $obj->localtax2_tx = $localtax2_array[1]; } if ($obj->localtax2_type == '7') { $total_localtax2 += $obj->localtax2_tx; $total_ttc += $obj->localtax2_tx; } } } $i++; } $db->free($resql); $fieldht = 'total_ht'; $fieldtva = 'tva';
/** * Update database for contract line * * @param User $user User that modify * @param int $notrigger 0=no, 1=yes (no update trigger) * @return int <0 if KO, >0 if OK */ function update($user, $notrigger = 0) { global $conf, $langs, $mysoc; $error = 0; // Clean parameters $this->fk_contrat = trim($this->fk_contrat); $this->fk_product = trim($this->fk_product); $this->statut = (int) $this->statut; $this->label = trim($this->label); $this->description = trim($this->description); $this->tva_tx = trim($this->tva_tx); $this->localtax1_tx = trim($this->localtax1_tx); $this->localtax2_tx = trim($this->localtax2_tx); $this->qty = trim($this->qty); $this->remise_percent = trim($this->remise_percent); $this->remise = trim($this->remise); $this->fk_remise_except = trim($this->fk_remise_except); $this->subprice = price2num($this->subprice); $this->price_ht = price2num($this->price_ht); $this->total_ht = trim($this->total_ht); $this->total_tva = trim($this->total_tva); $this->total_localtax1 = trim($this->total_localtax1); $this->total_localtax2 = trim($this->total_localtax2); $this->total_ttc = trim($this->total_ttc); $this->info_bits = trim($this->info_bits); $this->fk_user_author = trim($this->fk_user_author); $this->fk_user_ouverture = trim($this->fk_user_ouverture); $this->fk_user_cloture = trim($this->fk_user_cloture); $this->commentaire = trim($this->commentaire); //if (empty($this->subprice)) $this->subprice = 0; if (empty($this->price_ht)) { $this->price_ht = 0; } if (empty($this->total_ht)) { $this->total_ht = 0; } if (empty($this->total_tva)) { $this->total_tva = 0; } if (empty($this->total_ttc)) { $this->total_ttc = 0; } // Check parameters // Put here code to add control on parameters values // Calcul du total TTC et de la TVA pour la ligne a partir de // qty, pu, remise_percent et txtva // TRES IMPORTANT: C'est au moment de l'insertion ligne qu'on doit stocker // la part ht, tva et ttc, et ce au niveau de la ligne qui a son propre taux tva. $localtaxes_type = getLocalTaxesFromRate($this->txtva, 0, $this->societe, $mysoc); $tabprice = calcul_price_total($this->qty, $this->price_ht, $this->remise_percent, $this->tva_tx, $this->localtax1_tx, $this->localtax2_tx, 0, 'HT', 0, 1, $mysoc, $localtaxes_type); $this->total_ht = $tabprice[0]; $this->total_tva = $tabprice[1]; $this->total_ttc = $tabprice[2]; $this->total_localtax1 = $tabprice[9]; $this->total_localtax2 = $tabprice[10]; if (empty($this->pa_ht)) { $this->pa_ht = 0; } // if buy price not defined, define buyprice as configured in margin admin if ($this->pa_ht == 0) { if (($result = $this->defineBuyPrice($this->subprice, $this->remise_percent, $this->fk_product)) < 0) { return $result; } else { $this->pa_ht = $result; } } $this->db->begin(); // Update request $sql = "UPDATE " . MAIN_DB_PREFIX . "contratdet SET"; $sql .= " fk_contrat='" . $this->fk_contrat . "',"; $sql .= " fk_product=" . ($this->fk_product ? "'" . $this->fk_product . "'" : 'null') . ","; $sql .= " statut='" . $this->statut . "',"; $sql .= " label='" . $this->db->escape($this->label) . "',"; $sql .= " description='" . $this->db->escape($this->description) . "',"; $sql .= " date_commande=" . ($this->date_commande != '' ? "'" . $this->db->idate($this->date_commande) . "'" : "null") . ","; $sql .= " date_ouverture_prevue=" . ($this->date_ouverture_prevue != '' ? "'" . $this->db->idate($this->date_ouverture_prevue) . "'" : "null") . ","; $sql .= " date_ouverture=" . ($this->date_ouverture != '' ? "'" . $this->db->idate($this->date_ouverture) . "'" : "null") . ","; $sql .= " date_fin_validite=" . ($this->date_fin_validite != '' ? "'" . $this->db->idate($this->date_fin_validite) . "'" : "null") . ","; $sql .= " date_cloture=" . ($this->date_cloture != '' ? "'" . $this->db->idate($this->date_cloture) . "'" : "null") . ","; $sql .= " tva_tx='" . $this->tva_tx . "',"; $sql .= " localtax1_tx='" . $this->localtax1_tx . "',"; $sql .= " localtax2_tx='" . $this->localtax2_tx . "',"; $sql .= " qty='" . $this->qty . "',"; $sql .= " remise_percent='" . $this->remise_percent . "',"; $sql .= " remise=" . ($this->remise ? "'" . $this->remise . "'" : "null") . ","; $sql .= " fk_remise_except=" . ($this->fk_remise_except ? "'" . $this->fk_remise_except . "'" : "null") . ","; $sql .= " subprice=" . ($this->subprice != '' ? $this->subprice : "null") . ","; $sql .= " price_ht=" . ($this->price_ht != '' ? $this->price_ht : "null") . ","; $sql .= " total_ht='" . $this->total_ht . "',"; $sql .= " total_tva='" . $this->total_tva . "',"; $sql .= " total_localtax1='" . $this->total_localtax1 . "',"; $sql .= " total_localtax2='" . $this->total_localtax2 . "',"; $sql .= " total_ttc='" . $this->total_ttc . "',"; $sql .= " fk_product_fournisseur_price=" . (!empty($this->fk_fournprice) ? $this->fk_fournprice : "NULL") . ","; $sql .= " buy_price_ht='" . price2num($this->pa_ht) . "',"; $sql .= " info_bits='" . $this->info_bits . "',"; $sql .= " fk_user_author=" . ($this->fk_user_author >= 0 ? $this->fk_user_author : "NULL") . ","; $sql .= " fk_user_ouverture=" . ($this->fk_user_ouverture > 0 ? $this->fk_user_ouverture : "NULL") . ","; $sql .= " fk_user_cloture=" . ($this->fk_user_cloture > 0 ? $this->fk_user_cloture : "NULL") . ","; $sql .= " commentaire='" . $this->db->escape($this->commentaire) . "'"; $sql .= ", fk_unit=" . (!$this->fk_unit ? 'NULL' : $this->fk_unit); $sql .= " WHERE rowid=" . $this->id; dol_syslog(get_class($this) . "::update", LOG_DEBUG); $resql = $this->db->query($sql); if ($resql) { $contrat = new Contrat($this->db); $contrat->fetch($this->fk_contrat); $result = $contrat->update_statut($user); } else { $this->error = "Error " . $this->db->lasterror(); $error++; //return -1; } if (empty($conf->global->MAIN_EXTRAFIELDS_DISABLED) && is_array($this->array_options) && count($this->array_options) > 0) { $result = $this->insertExtraFields(); if ($result < 0) { $error++; } } if (empty($error)) { if (!$notrigger) { // Call trigger $result = $this->call_trigger('LINECONTRACT_UPDATE', $user); if ($result < 0) { $error++; $this->db->rollback(); return -1; } // End call triggers } } if (empty($error)) { $this->db->commit(); return 1; } else { $this->db->rollback(); $this->errors[] = $this->error; return -1; } }
/** * Update a detail line * * @param int $rowid Id of line to update * @param string $desc Description of line * @param double $pu Prix unitaire (HT ou TTC selon price_base_type) (> 0 even for credit note lines) * @param double $qty Quantity * @param double $remise_percent Pourcentage de remise de la ligne * @param int $date_start Date de debut de validite du service * @param int $date_end Date de fin de validite du service * @param double $txtva VAT Rate * @param double $txlocaltax1 Local tax 1 rate * @param double $txlocaltax2 Local tax 2 rate * @param string $price_base_type HT or TTC * @param int $info_bits Miscellaneous informations * @param int $type Type of line (0=product, 1=service) * @param int $fk_parent_line Id of parent line (0 in most cases, used by modules adding sublevels into lines). * @param int $skip_update_total Keep fields total_xxx to 0 (used for special lines by some modules) * @param int $fk_fournprice Id of origin supplier price * @param int $pa_ht Price (without tax) of product when it was bought * @param string $label Label of the line (deprecated, do not use) * @param int $special_code Special code (also used by externals modules!) * @param array $array_option extrafields array * @return int < 0 if KO, > 0 if OK */ function updateline($rowid, $desc, $pu, $qty, $remise_percent, $date_start, $date_end, $txtva, $txlocaltax1 = 0, $txlocaltax2 = 0, $price_base_type = 'HT', $info_bits = 0, $type = self::TYPE_STANDARD, $fk_parent_line = 0, $skip_update_total = 0, $fk_fournprice = null, $pa_ht = 0, $label = '', $special_code = 0, $array_option = 0) { include_once DOL_DOCUMENT_ROOT . '/core/lib/price.lib.php'; global $mysoc; dol_syslog(get_class($this) . "::updateline rowid={$rowid}, desc={$desc}, pu={$pu}, qty={$qty}, remise_percent={$remise_percent}, date_start={$date_start}, date_end={$date_end}, txtva={$txtva}, txlocaltax1={$txlocaltax1}, txlocaltax2={$txlocaltax2}, price_base_type={$price_base_type}, info_bits={$info_bits}, type={$type}, fk_parent_line={$fk_parent_line} pa_ht={$pa_ht}, special_code={$special_code}", LOG_DEBUG); if ($this->brouillon) { $this->db->begin(); // Clean parameters if (empty($qty)) { $qty = 0; } if (empty($fk_parent_line) || $fk_parent_line < 0) { $fk_parent_line = 0; } if (empty($special_code) || $special_code == 3) { $special_code = 0; } $remise_percent = price2num($remise_percent); $qty = price2num($qty); $pu = price2num($pu); $pa_ht = price2num($pa_ht); $txtva = price2num($txtva); $txlocaltax1 = price2num($txlocaltax1); $txlocaltax2 = price2num($txlocaltax2); // Check parameters if ($type < 0) { return -1; } // Calculate total with, without tax and tax from qty, pu, remise_percent and txtva // TRES IMPORTANT: C'est au moment de l'insertion ligne qu'on doit stocker // la part ht, tva et ttc, et ce au niveau de la ligne qui a son propre taux tva. $localtaxes_type = getLocalTaxesFromRate($txtva, 0, $this->thirdparty, $mysoc); $tabprice = calcul_price_total($qty, $pu, $remise_percent, $txtva, $txlocaltax1, $txlocaltax2, 0, $price_base_type, $info_bits, $type, $mysoc, $localtaxes_type); $total_ht = $tabprice[0]; $total_tva = $tabprice[1]; $total_ttc = $tabprice[2]; $total_localtax1 = $tabprice[9]; $total_localtax2 = $tabprice[10]; $pu_ht = $tabprice[3]; $pu_tva = $tabprice[4]; $pu_ttc = $tabprice[5]; // Update line into database $this->line = new FactureLigne($this->db); $this->line->context = $this->context; // Stock previous line records $staticline = new FactureLigne($this->db); $staticline->fetch($rowid); $this->line->oldline = $staticline; // Reorder if fk_parent_line change if (!empty($fk_parent_line) && !empty($staticline->fk_parent_line) && $fk_parent_line != $staticline->fk_parent_line) { $rangmax = $this->line_max($fk_parent_line); $this->line->rang = $rangmax + 1; } $this->line->rowid = $rowid; $this->line->label = $label; $this->line->desc = $desc; $this->line->qty = $this->type == self::TYPE_CREDIT_NOTE ? abs($qty) : $qty; // For credit note, quantity is always positive and unit price negative $this->line->tva_tx = $txtva; $this->line->localtax1_tx = $txlocaltax1; $this->line->localtax2_tx = $txlocaltax2; $this->line->localtax1_type = $localtaxes_type[0]; $this->line->localtax2_type = $localtaxes_type[2]; $this->line->remise_percent = $remise_percent; $this->line->subprice = $this->type == 2 ? -abs($pu_ht) : $pu_ht; // For credit note, unit price always negative, always positive otherwise $this->line->date_start = $date_start; $this->line->date_end = $date_end; $this->line->total_ht = $this->type == self::TYPE_CREDIT_NOTE || $qty < 0 ? -abs($total_ht) : $total_ht; // For credit note and if qty is negative, total is negative $this->line->total_tva = $this->type == self::TYPE_CREDIT_NOTE || $qty < 0 ? -abs($total_tva) : $total_tva; $this->line->total_localtax1 = $this->type == self::TYPE_CREDIT_NOTE || $qty < 0 ? -abs($total_localtax1) : $total_localtax1; $this->line->total_localtax2 = $this->type == self::TYPE_CREDIT_NOTE || $qty < 0 ? -abs($total_localtax2) : $total_localtax2; $this->line->total_ttc = $this->type == self::TYPE_CREDIT_NOTE || $qty < 0 ? -abs($total_ttc) : $total_ttc; $this->line->info_bits = $info_bits; $this->line->special_code = $special_code; $this->line->product_type = $type; $this->line->fk_parent_line = $fk_parent_line; $this->line->skip_update_total = $skip_update_total; // infos marge if (!empty($fk_product) && empty($fk_fournprice) && empty($pa_ht)) { // POS or external module, take lowest buying price include_once DOL_DOCUMENT_ROOT . '/fourn/class/fournisseur.product.class.php'; $productFournisseur = new ProductFournisseur($this->db); $productFournisseur->find_min_price_product_fournisseur($fk_product); $this->line->fk_fournprice = $productFournisseur->product_fourn_price_id; } else { $this->line->fk_fournprice = $fk_fournprice; } $this->line->pa_ht = $pa_ht; if (is_array($array_option) && count($array_option) > 0) { $this->line->array_options = $array_option; } $result = $this->line->update(); if ($result > 0) { // Reorder if child line if (!empty($fk_parent_line)) { $this->line_order(true, 'DESC'); } // Mise a jour info denormalisees au niveau facture $this->update_price(1); $this->db->commit(); return $result; } else { $this->error = $this->line->error; $this->db->rollback(); return -1; } } else { $this->error = "Invoice statut makes operation forbidden"; return -2; } }
/** * Function to build pdf onto disk * * @param Object $object Object to generate * @param Translate $outputlangs Lang output object * @param string $srctemplatepath Full path of source filename for generator using a template file * @param int $hidedetails Do not show line details * @param int $hidedesc Do not show desc * @param int $hideref Do not show ref * @param object $hookmanager Hookmanager object * @return int 1=OK, 0=KO */ function write_file($object, $outputlangs, $srctemplatepath = '', $hidedetails = 0, $hidedesc = 0, $hideref = 0, $hookmanager = false) { global $user, $langs, $conf, $mysoc, $db; if (!is_object($outputlangs)) { $outputlangs = $langs; } // For backward compatibility with FPDF, force output charset to ISO, because FPDF expect text to be encoded in ISO if (!empty($conf->global->MAIN_USE_FPDF)) { $outputlangs->charset_output = 'ISO-8859-1'; } $outputlangs->load("main"); $outputlangs->load("dict"); $outputlangs->load("companies"); $outputlangs->load("bills"); $outputlangs->load("products"); if ($conf->facture->dir_output) { $object->fetch_thirdparty(); $deja_regle = $object->getSommePaiement(); $amount_credit_notes_included = $object->getSumCreditNotesUsed(); $amount_deposits_included = $object->getSumDepositsUsed(); // Definition of $dir and $file if ($object->specimen) { $dir = $conf->facture->dir_output; $file = $dir . "/SPECIMEN.pdf"; } else { $objectref = dol_sanitizeFileName($object->ref); $dir = $conf->facture->dir_output . "/" . $objectref; $file = $dir . "/" . $objectref . ".pdf"; } if (!file_exists($dir)) { if (dol_mkdir($dir) < 0) { $this->error = $langs->transnoentities("ErrorCanNotCreateDir", $dir); return 0; } } if (file_exists($dir)) { $nblignes = count($object->lines); $pdf = pdf_getInstance($this->format); $default_font_size = pdf_getPDFFontSize($outputlangs); // Must be after pdf_getInstance $heightforinfotot = 50; // Height reserved to output the info and total part $heightforfreetext = isset($conf->global->MAIN_PDF_FREETEXT_HEIGHT) ? $conf->global->MAIN_PDF_FREETEXT_HEIGHT : 5; // Height reserved to output the free text on last page $heightforfooter = $this->marge_basse + 8; // Height reserved to output the footer (value include bottom margin) $pdf->SetAutoPageBreak(1, 0); if (class_exists('TCPDF')) { $pdf->setPrintHeader(false); $pdf->setPrintFooter(false); } $pdf->SetFont(pdf_getPDFFont($outputlangs)); // Set path to the background PDF File if (empty($conf->global->MAIN_DISABLE_FPDI) && !empty($conf->global->MAIN_ADD_PDF_BACKGROUND)) { $pagecount = $pdf->setSourceFile($conf->mycompany->dir_output . '/' . $conf->global->MAIN_ADD_PDF_BACKGROUND); $tplidx = $pdf->importPage(1); } $pdf->Open(); $pagenb = 0; $pdf->SetDrawColor(128, 128, 128); $pdf->SetTitle($outputlangs->convToOutputCharset($object->ref)); $pdf->SetSubject($outputlangs->transnoentities("Invoice")); $pdf->SetCreator("Dolibarr " . DOL_VERSION); $pdf->SetAuthor($outputlangs->convToOutputCharset($user->getFullName($outputlangs))); $pdf->SetKeyWords($outputlangs->convToOutputCharset($object->ref) . " " . $outputlangs->transnoentities("Invoice")); if (!empty($conf->global->MAIN_DISABLE_PDF_COMPRESSION)) { $pdf->SetCompression(false); } $pdf->SetMargins($this->marge_gauche, $this->marge_haute, $this->marge_droite); // Left, Top, Right // Positionne $this->atleastonediscount si on a au moins une remise for ($i = 0; $i < $nblignes; $i++) { if ($object->lines[$i]->remise_percent) { $this->atleastonediscount++; } } // New page $pdf->AddPage(); if (!empty($tplidx)) { $pdf->useTemplate($tplidx); } $pagenb++; $this->_pagehead($pdf, $object, 1, $outputlangs, $hookmanager); $pdf->SetFont('', '', $default_font_size - 1); $pdf->MultiCell(0, 3, ''); // Set interline to 3 $pdf->SetTextColor(0, 0, 0); $tab_top = 90; $tab_top_newpage = empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD) ? 42 : 10; $tab_height = 130; $tab_height_newpage = 150; // Affiche notes if (!empty($object->note_public)) { $tab_top = 88; $pdf->SetFont('', '', $default_font_size - 1); $pdf->writeHTMLCell(190, 3, $this->posxdesc - 1, $tab_top, dol_htmlentitiesbr($object->note_public), 0, 1); $nexY = $pdf->GetY(); $height_note = $nexY - $tab_top; // Rect prend une longueur en 3eme param $pdf->SetDrawColor(192, 192, 192); $pdf->Rect($this->marge_gauche, $tab_top - 1, $this->page_largeur - $this->marge_gauche - $this->marge_droite, $height_note + 1); $tab_height = $tab_height - $height_note; $tab_top = $nexY + 6; } else { $height_note = 0; } $iniY = $tab_top + 7; $curY = $tab_top + 7; $nexY = $tab_top + 7; // Loop on each lines for ($i = 0; $i < $nblignes; $i++) { $curY = $nexY; $pdf->SetFont('', '', $default_font_size - 1); // Into loop to work with multipage $pdf->SetTextColor(0, 0, 0); $pdf->setTopMargin($tab_top_newpage); $pdf->setPageOrientation('', 1, $heightforfooter + $heightforfreetext + $heightforinfotot); // The only function to edit the bottom margin of current page to set it. $pageposbefore = $pdf->getPage(); // Description of product line $curX = $this->posxdesc - 1; $showpricebeforepagebreak = 1; $pdf->startTransaction(); pdf_writelinedesc($pdf, $object, $i, $outputlangs, $this->posxtva - $curX, 3, $curX, $curY, $hideref, $hidedesc, 0, $hookmanager); $pageposafter = $pdf->getPage(); if ($pageposafter > $pageposbefore) { $pdf->rollbackTransaction(true); $pageposafter = $pageposbefore; //print $pageposafter.'-'.$pageposbefore;exit; $pdf->setPageOrientation('', 1, $heightforfooter); // The only function to edit the bottom margin of current page to set it. pdf_writelinedesc($pdf, $object, $i, $outputlangs, $this->posxtva - $curX, 4, $curX, $curY, $hideref, $hidedesc, 0, $hookmanager); $pageposafter = $pdf->getPage(); $posyafter = $pdf->GetY(); //var_dump($posyafter); var_dump(($this->page_hauteur - ($heightforfooter+$heightforfreetext+$heightforinfotot))); exit; if ($posyafter > $this->page_hauteur - ($heightforfooter + $heightforfreetext + $heightforinfotot)) { if ($i == $nblignes - 1) { $pdf->AddPage('', '', true); if (!empty($tplidx)) { $pdf->useTemplate($tplidx); } if (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)) { $this->_pagehead($pdf, $object, 0, $outputlangs, $hookmanager); } $pdf->setPage($pagenb + 1); } } else { // We found a page break $showpricebeforepagebreak = 0; } } else { $pdf->commitTransaction(); } $nexY = $pdf->GetY(); $pageposafter = $pdf->getPage(); $pdf->setPage($pageposbefore); $pdf->setTopMargin($this->marge_haute); $pdf->setPageOrientation('', 1, 0); // The only function to edit the bottom margin of current page to set it. // We suppose that a too long description is moved completely on next page if ($pageposafter > $pageposbefore && empty($showpricebeforepagebreak)) { $pdf->setPage($pageposafter); $curY = $tab_top_newpage; } $pdf->SetFont('', '', $default_font_size - 1); // On repositionne la police par defaut // VAT Rate if (empty($conf->global->MAIN_GENERATE_DOCUMENTS_WITHOUT_VAT)) { $vat_rate = pdf_getlinevatrate($object, $i, $outputlangs, $hidedetails, $hookmanager); $pdf->SetXY($this->posxtva, $curY); $pdf->MultiCell($this->posxup - $this->posxtva - 1, 3, $vat_rate, 0, 'R'); } // Unit price before discount $up_excl_tax = pdf_getlineupexcltax($object, $i, $outputlangs, $hidedetails, $hookmanager); $pdf->SetXY($this->posxup, $curY); $pdf->MultiCell($this->posxqty - $this->posxup - 1, 3, $up_excl_tax, 0, 'R', 0); // Quantity $qty = pdf_getlineqty($object, $i, $outputlangs, $hidedetails, $hookmanager); $pdf->SetXY($this->posxqty, $curY); $pdf->MultiCell($this->posxdiscount - $this->posxqty - 1, 3, $qty, 0, 'R'); // Enough for 6 chars // Discount on line if ($object->lines[$i]->remise_percent) { $pdf->SetXY($this->posxdiscount - 2, $curY); $remise_percent = pdf_getlineremisepercent($object, $i, $outputlangs, $hidedetails, $hookmanager); $pdf->MultiCell($this->postotalht - $this->posxdiscount + 2, 3, $remise_percent, 0, 'R'); } // Total HT line $total_excl_tax = pdf_getlinetotalexcltax($object, $i, $outputlangs, $hidedetails, $hookmanager); $pdf->SetXY($this->postotalht, $curY); $pdf->MultiCell($this->page_largeur - $this->marge_droite - $this->postotalht, 3, $total_excl_tax, 0, 'R', 0); // Collecte des totaux par valeur de tva dans $this->tva["taux"]=total_tva $tvaligne = $object->lines[$i]->total_tva; $localtax1ligne = $object->lines[$i]->total_localtax1; $localtax2ligne = $object->lines[$i]->total_localtax2; $localtax1_rate = $object->lines[$i]->localtax1_tx; $localtax2_rate = $object->lines[$i]->localtax2_tx; $localtax1_type = $object->lines[$i]->localtax1_type; $localtax2_type = $object->lines[$i]->localtax2_type; if ($object->remise_percent) { $tvaligne -= $tvaligne * $object->remise_percent / 100; } if ($object->remise_percent) { $localtax1ligne -= $localtax1ligne * $object->remise_percent / 100; } if ($object->remise_percent) { $localtax2ligne -= $localtax2ligne * $object->remise_percent / 100; } $vatrate = (string) $object->lines[$i]->tva_tx; // TODO : store local taxes types into object lines and remove this $localtax1_array = getLocalTaxesFromRate($vatrate, 1, $mysoc); $localtax2_array = getLocalTaxesFromRate($vatrate, 2, $mysoc); if (!isset($localtax1_type)) { $localtax1_type = $localtax1_array[0]; } if (!isset($localtax2_type)) { $localtax2_type = $localtax2_array[0]; } //end TODO // retrieve global local tax if ($localtax1_type == '7') { $localtax1_rate = $localtax1_array[1]; } if ($localtax2_type == '7') { $localtax2_rate = $localtax2_array[1]; } if ($localtax1_type && ($localtax1ligne != 0 || $localtax1_type == '7')) { $this->localtax1[$localtax1_type][$localtax1_rate] += $localtax1ligne; } if ($localtax2_type && ($localtax2ligne != 0 || $localtax2_type == '7')) { $this->localtax2[$localtax2_type][$localtax2_rate] += $localtax2ligne; } if (($object->lines[$i]->info_bits & 0x1) == 0x1) { $vatrate .= '*'; } if (!isset($this->tva[$vatrate])) { $this->tva[$vatrate] = ''; } $this->tva[$vatrate] += $tvaligne; // Add line if (!empty($conf->global->MAIN_PDF_DASH_BETWEEN_LINES) && $i < $nblignes - 1) { $pdf->SetLineStyle(array('dash' => '1,1', 'color' => array(210, 210, 210))); //$pdf->SetDrawColor(190,190,200); $pdf->line($this->marge_gauche, $nexY + 1, $this->page_largeur - $this->marge_droite, $nexY + 1); $pdf->SetLineStyle(array('dash' => 0)); } $nexY += 2; // Passe espace entre les lignes // Detect if some page were added automatically and output _tableau for past pages while ($pagenb < $pageposafter) { $pdf->setPage($pagenb); if ($pagenb == 1) { $this->_tableau($pdf, $tab_top, $this->page_hauteur - $tab_top - $heightforfooter, 0, $outputlangs, 0, 1); } else { $this->_tableau($pdf, $tab_top_newpage, $this->page_hauteur - $tab_top_newpage - $heightforfooter, 0, $outputlangs, 1, 1); } $this->_pagefoot($pdf, $object, $outputlangs, 1); $pagenb++; $pdf->setPage($pagenb); $pdf->setPageOrientation('', 1, 0); // The only function to edit the bottom margin of current page to set it. if (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)) { $this->_pagehead($pdf, $object, 0, $outputlangs, $hookmanager); } } if (isset($object->lines[$i + 1]->pagebreak) && $object->lines[$i + 1]->pagebreak) { if ($pagenb == 1) { $this->_tableau($pdf, $tab_top, $this->page_hauteur - $tab_top - $heightforfooter, 0, $outputlangs, 0, 1); } else { $this->_tableau($pdf, $tab_top_newpage, $this->page_hauteur - $tab_top_newpage - $heightforfooter, 0, $outputlangs, 1, 1); } $this->_pagefoot($pdf, $object, $outputlangs, 1); // New page $pdf->AddPage(); if (!empty($tplidx)) { $pdf->useTemplate($tplidx); } $pagenb++; if (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)) { $this->_pagehead($pdf, $object, 0, $outputlangs, $hookmanager); } } } // Show square if ($pagenb == 1) { $this->_tableau($pdf, $tab_top, $this->page_hauteur - $tab_top - $heightforinfotot - $heightforfreetext - $heightforfooter, 0, $outputlangs, 0, 0); $bottomlasttab = $this->page_hauteur - $heightforinfotot - $heightforfreetext - $heightforfooter + 1; } else { $this->_tableau($pdf, $tab_top_newpage, $this->page_hauteur - $tab_top_newpage - $heightforinfotot - $heightforfreetext - $heightforfooter, 0, $outputlangs, 1, 0); $bottomlasttab = $this->page_hauteur - $heightforinfotot - $heightforfreetext - $heightforfooter + 1; } // Affiche zone infos $posy = $this->_tableau_info($pdf, $object, $bottomlasttab, $outputlangs); // Affiche zone totaux $posy = $this->_tableau_tot($pdf, $object, $deja_regle, $bottomlasttab, $outputlangs); // Affiche zone versements if ($deja_regle || $amount_credit_notes_included || $amount_deposits_included) { $posy = $this->_tableau_versements($pdf, $object, $posy, $outputlangs); } // Pied de page $this->_pagefoot($pdf, $object, $outputlangs); //$pdf->AliasNbPages(); $pdf->Close(); $pdf->Output($file, 'F'); // Add pdfgeneration hook if (!is_object($hookmanager)) { include_once DOL_DOCUMENT_ROOT . '/core/class/hookmanager.class.php'; $hookmanager = new HookManager($this->db); } $hookmanager->initHooks(array('pdfgeneration')); $parameters = array('file' => $file, 'object' => $object, 'outputlangs' => $outputlangs); global $action; $reshook = $hookmanager->executeHooks('afterPDFCreation', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks if (!empty($conf->global->MAIN_UMASK)) { @chmod($file, octdec($conf->global->MAIN_UMASK)); } return 1; // Pas d'erreur } else { $this->error = $langs->trans("ErrorCanNotCreateDir", $dir); return 0; } } else { $this->error = $langs->trans("ErrorConstantNotDefined", "FAC_OUTPUTDIR"); return 0; } $this->error = $langs->trans("ErrorUnknown"); return 0; // Erreur par defaut }
/** * Update a line detail into database * * @param int $id Id of line invoice * @param string $desc Description of line * @param double $pu Prix unitaire (HT ou TTC selon price_base_type) * @param double $vatrate VAT Rate * @param double $txlocaltax1 LocalTax1 Rate * @param double $txlocaltax2 LocalTax2 Rate * @param double $qty Quantity * @param int $idproduct Id produit * @param double $price_base_type HT or TTC * @param int $info_bits Miscellaneous informations of line * @param int $type Type of line (0=product, 1=service) * @param double $remise_percent Pourcentage de remise de la ligne * @param int $notrigger Disable triggers * @param timestamp $date_start Date start of service * @param timestamp $date_end Date end of service * @param array $array_options extrafields array * @param string $fk_unit Code of the unit to use. Null to use the default one * @return int <0 if KO, >0 if OK */ function updateline($id, $desc, $pu, $vatrate, $txlocaltax1 = 0, $txlocaltax2 = 0, $qty = 1, $idproduct = 0, $price_base_type = 'HT', $info_bits = 0, $type = 0, $remise_percent = 0, $notrigger = false, $date_start = '', $date_end = '', $array_options = 0, $fk_unit = null) { global $mysoc; dol_syslog(get_class($this) . "::updateline {$id},{$desc},{$pu},{$vatrate},{$qty},{$idproduct},{$price_base_type},{$info_bits},{$type},{$remise_percent},{$fk_unit}", LOG_DEBUG); include_once DOL_DOCUMENT_ROOT . '/core/lib/price.lib.php'; $pu = price2num($pu); $qty = price2num($qty); $remise_percent = price2num($remise_percent); // Check parameters if (!is_numeric($pu) || !is_numeric($qty)) { return -1; } if ($type < 0) { return -1; } // Clean parameters if (empty($vatrate)) { $vatrate = 0; } if (empty($txlocaltax1)) { $txlocaltax1 = 0; } if (empty($txlocaltax2)) { $txlocaltax2 = 0; } $txlocaltax1 = price2num($txlocaltax1); $txlocaltax2 = price2num($txlocaltax2); // Calcul du total TTC et de la TVA pour la ligne a partir de // qty, pu, remise_percent et txtva // TRES IMPORTANT: C'est au moment de l'insertion ligne qu'on doit stocker // la part ht, tva et ttc, et ce au niveau de la ligne qui a son propre taux tva. $localtaxes_type = getLocalTaxesFromRate($vatrate, 0, $mysoc, $this->thirdparty); $tabprice = calcul_price_total($qty, $pu, $remise_percent, $vatrate, $txlocaltax1, $txlocaltax2, 0, $price_base_type, $info_bits, $type, $this->thirdparty, $localtaxes_type); $total_ht = $tabprice[0]; $total_tva = $tabprice[1]; $total_ttc = $tabprice[2]; $pu_ht = $tabprice[3]; $pu_tva = $tabprice[4]; $pu_ttc = $tabprice[5]; $total_localtax1 = $tabprice[9]; $total_localtax2 = $tabprice[10]; if (empty($info_bits)) { $info_bits = 0; } if ($idproduct) { $product = new Product($this->db); $result = $product->fetch($idproduct); $product_type = $product->type; } else { $product_type = $type; } $line = new SupplierInvoiceLine($this->db); if ($line->fetch($id) < 1) { return -1; } $line->description = $desc; $line->subprice = $pu_ht; $line->pu_ht = $pu_ht; $line->pu_ttc = $pu_ttc; $line->qty = $qty; $line->remise_percent = $remise_percent; $line->tva_tx = $vatrate; $line->localtax1_tx = $txlocaltax1; $line->localtax2_tx = $txlocaltax2; $line->localtax1_type = $localtaxes_type[0]; $line->localtax2_type = $localtaxes_type[2]; $line->total_ht = $total_ht; $line->total_tva = $total_tva; $line->total_localtax1 = $total_localtax1; $line->total_localtax2 = $total_localtax2; $line->total_ttc = $total_ttc; $line->fk_product = $idproduct; $line->product_type = $product_type; $line->info_bits = $info_bits; $line->fk_unit = $fk_unit; $line->array_options = $array_options; $res = $line->update($notrigger); if ($res < 1) { $this->errors[] = $line->error; } else { // Update total price into invoice record $res = $this->update_price('', 'auto'); } return $res; }
/** * Function to build pdf onto disk * * @param Object $object Object to generate * @param Translate $outputlangs Lang output object * @param string $srctemplatepath Full path of source filename for generator using a template file * @param int $hidedetails Do not show line details * @param int $hidedesc Do not show desc * @param int $hideref Do not show ref * @return int 1=OK, 0=KO */ function write_file($object, $outputlangs, $srctemplatepath = '', $hidedetails = 0, $hidedesc = 0, $hideref = 0) { global $user, $langs, $conf, $mysoc, $db, $hookmanager; if (!is_object($outputlangs)) { $outputlangs = $langs; } // For backward compatibility with FPDF, force output charset to ISO, because FPDF expect text to be encoded in ISO if (!empty($conf->global->MAIN_USE_FPDF)) { $outputlangs->charset_output = 'ISO-8859-1'; } $outputlangs->load("main"); $outputlangs->load("dict"); $outputlangs->load("companies"); $outputlangs->load("bills"); $outputlangs->load("products"); $nblignes = count($object->lines); // Loop on each lines to detect if there is at least one image to show $realpatharray = array(); if (!empty($conf->global->MAIN_GENERATE_INVOICES_WITH_PICTURE)) { for ($i = 0; $i < $nblignes; $i++) { if (empty($object->lines[$i]->fk_product)) { continue; } $objphoto = new Product($this->db); $objphoto->fetch($object->lines[$i]->fk_product); $pdir = get_exdir($object->lines[$i]->fk_product, 2, 0, 0, $objphoto, 'product') . $object->lines[$i]->fk_product . "/photos/"; $dir = $conf->product->dir_output . '/' . $pdir; $realpath = ''; foreach ($objphoto->liste_photos($dir, 1) as $key => $obj) { $filename = $obj['photo']; //if ($obj['photo_vignette']) $filename='thumbs/'.$obj['photo_vignette']; $realpath = $dir . $filename; break; } if ($realpath) { $realpatharray[$i] = $realpath; } } } if (count($realpatharray) == 0) { $this->posxpicture = $this->posxtva; } if ($conf->facture->dir_output) { $object->fetch_thirdparty(); $deja_regle = $object->getSommePaiement(); $amount_credit_notes_included = $object->getSumCreditNotesUsed(); $amount_deposits_included = $object->getSumDepositsUsed(); // Definition of $dir and $file if ($object->specimen) { $dir = $conf->facture->dir_output; $file = $dir . "/SPECIMEN.pdf"; } else { $objectref = dol_sanitizeFileName($object->ref); $dir = $conf->facture->dir_output . "/" . $objectref; $file = $dir . "/" . $objectref . ".pdf"; } if (!file_exists($dir)) { if (dol_mkdir($dir) < 0) { $this->error = $langs->transnoentities("ErrorCanNotCreateDir", $dir); return 0; } } if (file_exists($dir)) { // Add pdfgeneration hook if (!is_object($hookmanager)) { include_once DOL_DOCUMENT_ROOT . '/core/class/hookmanager.class.php'; $hookmanager = new HookManager($this->db); } $hookmanager->initHooks(array('pdfgeneration')); $parameters = array('file' => $file, 'object' => $object, 'outputlangs' => $outputlangs); global $action; $reshook = $hookmanager->executeHooks('beforePDFCreation', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks // Set nblignes with the new facture lines content after hook $nblignes = count($object->lines); // Create pdf instance $pdf = pdf_getInstance($this->format); $default_font_size = pdf_getPDFFontSize($outputlangs); // Must be after pdf_getInstance $heightforinfotot = 50; // Height reserved to output the info and total part $heightforfreetext = isset($conf->global->MAIN_PDF_FREETEXT_HEIGHT) ? $conf->global->MAIN_PDF_FREETEXT_HEIGHT : 5; // Height reserved to output the free text on last page $heightforfooter = $this->marge_basse + 8; // Height reserved to output the footer (value include bottom margin) $pdf->SetAutoPageBreak(1, 0); if (class_exists('TCPDF')) { $pdf->setPrintHeader(false); $pdf->setPrintFooter(false); } $pdf->SetFont(pdf_getPDFFont($outputlangs)); // Set path to the background PDF File if (empty($conf->global->MAIN_DISABLE_FPDI) && !empty($conf->global->MAIN_ADD_PDF_BACKGROUND)) { $pagecount = $pdf->setSourceFile($conf->mycompany->dir_output . '/' . $conf->global->MAIN_ADD_PDF_BACKGROUND); $tplidx = $pdf->importPage(1); } $pdf->Open(); $pagenb = 0; $pdf->SetDrawColor(128, 128, 128); $pdf->SetTitle($outputlangs->convToOutputCharset($object->ref)); $pdf->SetSubject($outputlangs->transnoentities("Invoice")); $pdf->SetCreator("Dolibarr " . DOL_VERSION); $pdf->SetAuthor($outputlangs->convToOutputCharset($user->getFullName($outputlangs))); $pdf->SetKeyWords($outputlangs->convToOutputCharset($object->ref) . " " . $outputlangs->transnoentities("Invoice")); if (!empty($conf->global->MAIN_DISABLE_PDF_COMPRESSION)) { $pdf->SetCompression(false); } $pdf->SetMargins($this->marge_gauche, $this->marge_haute, $this->marge_droite); // Left, Top, Right // Positionne $this->atleastonediscount si on a au moins une remise for ($i = 0; $i < $nblignes; $i++) { if ($object->lines[$i]->remise_percent) { $this->atleastonediscount++; } } if (empty($this->atleastonediscount) && empty($conf->global->PRODUCT_USE_UNITS)) { $this->posxpicture += $this->postotalht - $this->posxdiscount; $this->posxtva += $this->postotalht - $this->posxdiscount; $this->posxup += $this->postotalht - $this->posxdiscount; $this->posxqty += $this->postotalht - $this->posxdiscount; $this->posxdiscount += $this->postotalht - $this->posxdiscount; //$this->postotalht; } // Situation invoice handling if ($object->situation_cycle_ref) { $this->situationinvoice = True; $progress_width = 14; $this->posxtva -= $progress_width; $this->posxup -= $progress_width; $this->posxqty -= $progress_width; $this->posxdiscount -= $progress_width; $this->posxprogress -= $progress_width; } // New page $pdf->AddPage(); if (!empty($tplidx)) { $pdf->useTemplate($tplidx); } $pagenb++; $this->_pagehead($pdf, $object, 1, $outputlangs); $pdf->SetFont('', '', $default_font_size - 1); $pdf->MultiCell(0, 3, ''); // Set interline to 3 $pdf->SetTextColor(0, 0, 0); $tab_top = 90; $tab_top_newpage = empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD) ? 42 : 10; $tab_height = 130; $tab_height_newpage = 150; // Incoterm $height_incoterms = 0; if ($conf->incoterm->enabled) { $desc_incoterms = $object->getIncotermsForPDF(); if ($desc_incoterms) { $tab_top = 88; $pdf->SetFont('', '', $default_font_size - 1); $pdf->writeHTMLCell(190, 3, $this->posxdesc - 1, $tab_top - 1, dol_htmlentitiesbr($desc_incoterms), 0, 1); $nexY = $pdf->GetY(); $height_incoterms = $nexY - $tab_top; // Rect prend une longueur en 3eme param $pdf->SetDrawColor(192, 192, 192); $pdf->Rect($this->marge_gauche, $tab_top - 1, $this->page_largeur - $this->marge_gauche - $this->marge_droite, $height_incoterms + 1); $tab_top = $nexY + 6; $height_incoterms += 4; } } // Affiche notes $notetoshow = empty($object->note_public) ? '' : $object->note_public; if (!empty($conf->global->MAIN_ADD_SALE_REP_SIGNATURE_IN_NOTE)) { // Get first sale rep if (is_object($object->thirdparty)) { $salereparray = $object->thirdparty->getSalesRepresentatives($user); $salerepobj = new User($this->db); $salerepobj->fetch($salereparray[0]['id']); if (!empty($salerepobj->signature)) { $notetoshow = dol_concatdesc($notetoshow, $salerepobj->signature); } } } if ($notetoshow) { $tab_top = 88 + $height_incoterms; $pdf->SetFont('', '', $default_font_size - 1); $pdf->writeHTMLCell(190, 3, $this->posxdesc - 1, $tab_top, dol_htmlentitiesbr($notetoshow), 0, 1); $nexY = $pdf->GetY(); $height_note = $nexY - $tab_top; // Rect prend une longueur en 3eme param $pdf->SetDrawColor(192, 192, 192); $pdf->Rect($this->marge_gauche, $tab_top - 1, $this->page_largeur - $this->marge_gauche - $this->marge_droite, $height_note + 1); $tab_height = $tab_height - $height_note; $tab_top = $nexY + 6; } else { $height_note = 0; } $iniY = $tab_top + 7; $curY = $tab_top + 7; $nexY = $tab_top + 7; // Loop on each lines for ($i = 0; $i < $nblignes; $i++) { $curY = $nexY; $pdf->SetFont('', '', $default_font_size - 1); // Into loop to work with multipage $pdf->SetTextColor(0, 0, 0); // Define size of image if we need it $imglinesize = array(); if (!empty($realpatharray[$i])) { $imglinesize = pdf_getSizeForImage($realpatharray[$i]); } $pdf->setTopMargin($tab_top_newpage); $pdf->setPageOrientation('', 1, $heightforfooter + $heightforfreetext + $heightforinfotot); // The only function to edit the bottom margin of current page to set it. $pageposbefore = $pdf->getPage(); $showpricebeforepagebreak = 1; $posYAfterImage = 0; $posYAfterDescription = 0; // We start with Photo of product line if (isset($imglinesize['width']) && isset($imglinesize['height']) && $curY + $imglinesize['height'] > $this->page_hauteur - ($heightforfooter + $heightforfreetext + $heightforinfotot)) { $pdf->AddPage('', '', true); if (!empty($tplidx)) { $pdf->useTemplate($tplidx); } if (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)) { $this->_pagehead($pdf, $object, 0, $outputlangs); } $pdf->setPage($pageposbefore + 1); $curY = $tab_top_newpage; $showpricebeforepagebreak = 0; } if (isset($imglinesize['width']) && isset($imglinesize['height'])) { $curX = $this->posxpicture - 1; $pdf->Image($realpatharray[$i], $curX + ($this->posxtva - $this->posxpicture - $imglinesize['width']) / 2, $curY, $imglinesize['width'], $imglinesize['height'], '', '', '', 2, 300); // Use 300 dpi // $pdf->Image does not increase value return by getY, so we save it manually $posYAfterImage = $curY + $imglinesize['height']; } // Description of product line $curX = $this->posxdesc - 1; $pdf->startTransaction(); pdf_writelinedesc($pdf, $object, $i, $outputlangs, $this->posxpicture - $curX, 3, $curX, $curY, $hideref, $hidedesc); $pageposafter = $pdf->getPage(); if ($pageposafter > $pageposbefore) { $pdf->rollbackTransaction(true); $pageposafter = $pageposbefore; //print $pageposafter.'-'.$pageposbefore;exit; $pdf->setPageOrientation('', 1, $heightforfooter); // The only function to edit the bottom margin of current page to set it. pdf_writelinedesc($pdf, $object, $i, $outputlangs, $this->posxpicture - $curX, 3, $curX, $curY, $hideref, $hidedesc); $pageposafter = $pdf->getPage(); $posyafter = $pdf->GetY(); //var_dump($posyafter); var_dump(($this->page_hauteur - ($heightforfooter+$heightforfreetext+$heightforinfotot))); exit; if ($posyafter > $this->page_hauteur - ($heightforfooter + $heightforfreetext + $heightforinfotot)) { if ($i == $nblignes - 1) { $pdf->AddPage('', '', true); if (!empty($tplidx)) { $pdf->useTemplate($tplidx); } if (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)) { $this->_pagehead($pdf, $object, 0, $outputlangs); } $pdf->setPage($pageposafter + 1); } } else { // We found a page break $showpricebeforepagebreak = 0; } } else { $pdf->commitTransaction(); } $posYAfterDescription = $pdf->GetY(); $nexY = $pdf->GetY(); $pageposafter = $pdf->getPage(); $pdf->setPage($pageposbefore); $pdf->setTopMargin($this->marge_haute); $pdf->setPageOrientation('', 1, 0); // The only function to edit the bottom margin of current page to set it. // We suppose that a too long description or photo were moved completely on next page if ($pageposafter > $pageposbefore && empty($showpricebeforepagebreak)) { $pdf->setPage($pageposafter); $curY = $tab_top_newpage; } $pdf->SetFont('', '', $default_font_size - 1); // On repositionne la police par defaut // VAT Rate if (empty($conf->global->MAIN_GENERATE_DOCUMENTS_WITHOUT_VAT)) { $vat_rate = pdf_getlinevatrate($object, $i, $outputlangs, $hidedetails); $pdf->SetXY($this->posxtva, $curY); $pdf->MultiCell($this->posxup - $this->posxtva - 0.8, 3, $vat_rate, 0, 'R'); } // Unit price before discount $up_excl_tax = pdf_getlineupexcltax($object, $i, $outputlangs, $hidedetails); $pdf->SetXY($this->posxup, $curY); $pdf->MultiCell($this->posxqty - $this->posxup - 0.8, 3, $up_excl_tax, 0, 'R', 0); // Quantity $qty = pdf_getlineqty($object, $i, $outputlangs, $hidedetails); $pdf->SetXY($this->posxqty, $curY); // Enough for 6 chars if ($conf->global->PRODUCT_USE_UNITS) { $pdf->MultiCell($this->posxunit - $this->posxqty - 0.8, 4, $qty, 0, 'R'); } else { $pdf->MultiCell($this->posxdiscount - $this->posxqty - 0.8, 4, $qty, 0, 'R'); } // Unit if ($conf->global->PRODUCT_USE_UNITS) { $unit = pdf_getlineunit($object, $i, $outputlangs, $hidedetails, $hookmanager); $pdf->SetXY($this->posxunit, $curY); $pdf->MultiCell($this->posxdiscount - $this->posxunit - 0.8, 4, $unit, 0, 'L'); } // Discount on line if ($object->lines[$i]->remise_percent) { $pdf->SetXY($this->posxdiscount - 2, $curY); $remise_percent = pdf_getlineremisepercent($object, $i, $outputlangs, $hidedetails); $pdf->MultiCell($this->posxprogress - $this->posxdiscount + 2, 3, $remise_percent, 0, 'R'); } if ($this->situationinvoice) { // Situation progress $progress = pdf_getlineprogress($object, $i, $outputlangs, $hidedetails); $pdf->SetXY($this->posxprogress, $curY); $pdf->MultiCell($this->postotalht - $this->posxprogress, 3, $progress, 0, 'R'); } // Total HT line $total_excl_tax = pdf_getlinetotalexcltax($object, $i, $outputlangs, $hidedetails); $pdf->SetXY($this->postotalht, $curY); $pdf->MultiCell($this->page_largeur - $this->marge_droite - $this->postotalht, 3, $total_excl_tax, 0, 'R', 0); // Collecte des totaux par valeur de tva dans $this->tva["taux"]=total_tva $prev_progress = $object->lines[$i]->get_prev_progress(); if ($prev_progress > 0) { if ($conf->multicurrency->enabled && $object->multicurrency_tx != 1) { $tvaligne = $object->lines[$i]->multicurrency_total_tva * ($object->lines[$i]->situation_percent - $prev_progress) / $object->lines[$i]->situation_percent; } else { $tvaligne = $object->lines[$i]->total_tva * ($object->lines[$i]->situation_percent - $prev_progress) / $object->lines[$i]->situation_percent; } } else { if ($conf->multicurrency->enabled && $object->multicurrency_tx != 1) { $tvaligne = $object->lines[$i]->multicurrency_total_tva; } else { $tvaligne = $object->lines[$i]->total_tva; } } $localtax1ligne = $object->lines[$i]->total_localtax1; $localtax2ligne = $object->lines[$i]->total_localtax2; $localtax1_rate = $object->lines[$i]->localtax1_tx; $localtax2_rate = $object->lines[$i]->localtax2_tx; $localtax1_type = $object->lines[$i]->localtax1_type; $localtax2_type = $object->lines[$i]->localtax2_type; if ($object->remise_percent) { $tvaligne -= $tvaligne * $object->remise_percent / 100; } if ($object->remise_percent) { $localtax1ligne -= $localtax1ligne * $object->remise_percent / 100; } if ($object->remise_percent) { $localtax2ligne -= $localtax2ligne * $object->remise_percent / 100; } $vatrate = (string) $object->lines[$i]->tva_tx; // Retrieve type from database for backward compatibility with old records if ((!isset($localtax1_type) || $localtax1_type == '' || !isset($localtax2_type) || $localtax2_type == '') && (!empty($localtax1_rate) || !empty($localtax2_rate))) { $localtaxtmp_array = getLocalTaxesFromRate($vatrate, 0, $object->thirdparty, $mysoc); $localtax1_type = $localtaxtmp_array[0]; $localtax2_type = $localtaxtmp_array[2]; } // retrieve global local tax if ($localtax1_type && $localtax1ligne != 0) { $this->localtax1[$localtax1_type][$localtax1_rate] += $localtax1ligne; } if ($localtax2_type && $localtax2ligne != 0) { $this->localtax2[$localtax2_type][$localtax2_rate] += $localtax2ligne; } if (($object->lines[$i]->info_bits & 0x1) == 0x1) { $vatrate .= '*'; } if (!isset($this->tva[$vatrate])) { $this->tva[$vatrate] = ''; } $this->tva[$vatrate] += $tvaligne; if ($posYAfterImage > $posYAfterDescription) { $nexY = $posYAfterImage; } // Add line if ($conf->global->MAIN_PDF_DASH_BETWEEN_LINES && $i < $nblignes - 1) { $pdf->setPage($pageposafter); $pdf->SetLineStyle(array('dash' => '1,1', 'color' => array(80, 80, 80))); //$pdf->SetDrawColor(190,190,200); $pdf->line($this->marge_gauche, $nexY + 1, $this->page_largeur - $this->marge_droite, $nexY + 1); $pdf->SetLineStyle(array('dash' => 0)); } $nexY += 2; // Passe espace entre les lignes // Detect if some page were added automatically and output _tableau for past pages while ($pagenb < $pageposafter) { $pdf->setPage($pagenb); if ($pagenb == 1) { $this->_tableau($pdf, $tab_top, $this->page_hauteur - $tab_top - $heightforfooter, 0, $outputlangs, 0, 1, $object->multicurrency_code); } else { $this->_tableau($pdf, $tab_top_newpage, $this->page_hauteur - $tab_top_newpage - $heightforfooter, 0, $outputlangs, 1, 1, $object->multicurrency_code); } $this->_pagefoot($pdf, $object, $outputlangs, 1); $pagenb++; $pdf->setPage($pagenb); $pdf->setPageOrientation('', 1, 0); // The only function to edit the bottom margin of current page to set it. if (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)) { $this->_pagehead($pdf, $object, 0, $outputlangs); } } if (isset($object->lines[$i + 1]->pagebreak) && $object->lines[$i + 1]->pagebreak) { if ($pagenb == 1) { $this->_tableau($pdf, $tab_top, $this->page_hauteur - $tab_top - $heightforfooter, 0, $outputlangs, 0, 1, $object->multicurrency_code); } else { $this->_tableau($pdf, $tab_top_newpage, $this->page_hauteur - $tab_top_newpage - $heightforfooter, 0, $outputlangs, 1, 1, $object->multicurrency_code); } $this->_pagefoot($pdf, $object, $outputlangs, 1); // New page $pdf->AddPage(); if (!empty($tplidx)) { $pdf->useTemplate($tplidx); } $pagenb++; if (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)) { $this->_pagehead($pdf, $object, 0, $outputlangs); } } } // Show square if ($pagenb == 1) { $this->_tableau($pdf, $tab_top, $this->page_hauteur - $tab_top - $heightforinfotot - $heightforfreetext - $heightforfooter, 0, $outputlangs, 0, 0, $object->multicurrency_code); $bottomlasttab = $this->page_hauteur - $heightforinfotot - $heightforfreetext - $heightforfooter + 1; } else { $this->_tableau($pdf, $tab_top_newpage, $this->page_hauteur - $tab_top_newpage - $heightforinfotot - $heightforfreetext - $heightforfooter, 0, $outputlangs, 1, 0, $object->multicurrency_code); $bottomlasttab = $this->page_hauteur - $heightforinfotot - $heightforfreetext - $heightforfooter + 1; } // Affiche zone infos $posy = $this->_tableau_info($pdf, $object, $bottomlasttab, $outputlangs); // Affiche zone totaux $posy = $this->_tableau_tot($pdf, $object, $deja_regle, $bottomlasttab, $outputlangs); // Affiche zone versements if ($deja_regle || $amount_credit_notes_included || $amount_deposits_included) { $posy = $this->_tableau_versements($pdf, $object, $posy, $outputlangs); } // Pied de page $this->_pagefoot($pdf, $object, $outputlangs); if (method_exists($pdf, 'AliasNbPages')) { $pdf->AliasNbPages(); } $pdf->Close(); $pdf->Output($file, 'F'); // Add pdfgeneration hook $hookmanager->initHooks(array('pdfgeneration')); $parameters = array('file' => $file, 'object' => $object, 'outputlangs' => $outputlangs); global $action; $reshook = $hookmanager->executeHooks('afterPDFCreation', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks if (!empty($conf->global->MAIN_UMASK)) { @chmod($file, octdec($conf->global->MAIN_UMASK)); } return 1; // Pas d'erreur } else { $this->error = $langs->trans("ErrorCanNotCreateDir", $dir); return 0; } } else { $this->error = $langs->trans("ErrorConstantNotDefined", "FAC_OUTPUTDIR"); return 0; } $this->error = $langs->trans("ErrorUnknown"); return 0; // Erreur par defaut }
/** * Function to build pdf onto disk * * @param Object $object Object to generate * @param Translate $outputlangs Lang output object * @param string $srctemplatepath Full path of source filename for generator using a template file * @param int $hidedetails Do not show line details * @param int $hidedesc Do not show desc * @param int $hideref Do not show ref * @return int 1=OK, 0=KO */ function write_file($object, $outputlangs, $srctemplatepath = '', $hidedetails = 0, $hidedesc = 0, $hideref = 0) { global $user, $langs, $conf, $mysoc, $db, $hookmanager; if (!is_object($outputlangs)) { $outputlangs = $langs; } // For backward compatibility with FPDF, force output charset to ISO, because FPDF expect text to be encoded in ISO if (!empty($conf->global->MAIN_USE_FPDF)) { $outputlangs->charset_output = 'ISO-8859-1'; } $outputlangs->load("main"); $outputlangs->load("dict"); $outputlangs->load("companies"); $outputlangs->load("bills"); $outputlangs->load("products"); $outputlangs->load("orders"); $outputlangs->load("deliveries"); $nblignes = count($object->lines); if ($conf->commande->dir_output) { $object->fetch_thirdparty(); $deja_regle = ""; // Definition of $dir and $file if ($object->specimen) { $dir = $conf->commande->dir_output; $file = $dir . "/SPECIMEN.pdf"; } else { $objectref = dol_sanitizeFileName($object->ref); $dir = $conf->commande->dir_output . "/" . $objectref; $file = $dir . "/" . $objectref . ".pdf"; } if (!file_exists($dir)) { if (dol_mkdir($dir) < 0) { $this->error = $langs->transnoentities("ErrorCanNotCreateDir", $dir); return 0; } } if (file_exists($dir)) { // Add pdfgeneration hook if (!is_object($hookmanager)) { include_once DOL_DOCUMENT_ROOT . '/core/class/hookmanager.class.php'; $hookmanager = new HookManager($this->db); } $hookmanager->initHooks(array('pdfgeneration')); $parameters = array('file' => $file, 'object' => $object, 'outputlangs' => $outputlangs); global $action; $reshook = $hookmanager->executeHooks('beforePDFCreation', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks // Create pdf instance $pdf = pdf_getInstance($this->format); $default_font_size = pdf_getPDFFontSize($outputlangs); // Must be after pdf_getInstance $heightforinfotot = 50; // Height reserved to output the info and total part $heightforfreetext = isset($conf->global->MAIN_PDF_FREETEXT_HEIGHT) ? $conf->global->MAIN_PDF_FREETEXT_HEIGHT : 5; // Height reserved to output the free text on last page $heightforfooter = $this->marge_basse + 8; // Height reserved to output the footer (value include bottom margin) $pdf->SetAutoPageBreak(1, 0); if (class_exists('TCPDF')) { $pdf->setPrintHeader(false); $pdf->setPrintFooter(false); } $pdf->SetFont(pdf_getPDFFont($outputlangs)); // Set path to the background PDF File if (empty($conf->global->MAIN_DISABLE_FPDI) && !empty($conf->global->MAIN_ADD_PDF_BACKGROUND)) { $pagecount = $pdf->setSourceFile($conf->mycompany->dir_output . '/' . $conf->global->MAIN_ADD_PDF_BACKGROUND); $tplidx = $pdf->importPage(1); } $pdf->Open(); $pagenb = 0; $pdf->SetDrawColor(128, 128, 128); $pdf->SetTitle($outputlangs->convToOutputCharset($object->ref)); $pdf->SetSubject($outputlangs->transnoentities("Order")); $pdf->SetCreator("Dolibarr " . DOL_VERSION); $pdf->SetAuthor($outputlangs->convToOutputCharset($user->getFullName($outputlangs))); $pdf->SetKeyWords($outputlangs->convToOutputCharset($object->ref) . " " . $outputlangs->transnoentities("Order")); if (!empty($conf->global->MAIN_DISABLE_PDF_COMPRESSION)) { $pdf->SetCompression(false); } $pdf->SetMargins($this->marge_gauche, $this->marge_haute, $this->marge_droite); // Left, Top, Right // Positionne $this->atleastonediscount si on a au moins une remise for ($i = 0; $i < $nblignes; $i++) { if ($object->lines[$i]->remise_percent) { $this->atleastonediscount++; } } if (empty($this->atleastonediscount)) { $this->posxpicture += $this->postotalht - $this->posxdiscount; $this->posxtva += $this->postotalht - $this->posxdiscount; $this->posxup += $this->postotalht - $this->posxdiscount; $this->posxqty += $this->postotalht - $this->posxdiscount; $this->posxdiscount += $this->postotalht - $this->posxdiscount; //$this->postotalht; } // New page $pdf->AddPage(); if (!empty($tplidx)) { $pdf->useTemplate($tplidx); } $pagenb++; $this->_pagehead($pdf, $object, 1, $outputlangs); $pdf->SetFont('', '', $default_font_size - 1); $pdf->MultiCell(0, 3, ''); // Set interline to 3 $pdf->SetTextColor(0, 0, 0); $tab_top = 90; $tab_top_newpage = empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD) ? 42 : 10; $tab_height = 130; $tab_height_newpage = 150; // Affiche notes $notetoshow = empty($object->note_public) ? '' : $object->note_public; if (!empty($conf->global->MAIN_ADD_SALE_REP_SIGNATURE_IN_NOTE)) { // Get first sale rep if (is_object($object->thirdparty)) { $salereparray = $object->thirdparty->getSalesRepresentatives($user); $salerepobj = new User($this->db); $salerepobj->fetch($salereparray[0]['id']); if (!empty($salerepobj->signature)) { $notetoshow = dol_concatdesc($notetoshow, $salerepobj->signature); } } } if ($notetoshow) { $tab_top = 88; $pdf->SetFont('', '', $default_font_size - 1); $pdf->writeHTMLCell(190, 3, $this->posxdesc - 1, $tab_top, dol_htmlentitiesbr($notetoshow), 0, 1); $nexY = $pdf->GetY(); $height_note = $nexY - $tab_top; // Rect prend une longueur en 3eme param $pdf->SetDrawColor(192, 192, 192); $pdf->Rect($this->marge_gauche, $tab_top - 1, $this->page_largeur - $this->marge_gauche - $this->marge_droite, $height_note + 1); $tab_height = $tab_height - $height_note; $tab_top = $nexY + 6; } else { $height_note = 0; } $iniY = $tab_top + 7; $curY = $tab_top + 7; $nexY = $tab_top + 7; $inPackage = false; $TPackageInfos = array(); $TChilds = array(); $package_qty = 0; $TStack = array(); // Loop on each lines for ($i = 0; $i < $nblignes; $i++) { $package_qty = $TStack[count($TStack) - 1]['package_qty']; $inPackage = count($TStack) > 0; // Ligne de titre if ($object->lines[$i]->product_type == 9 && $object->lines[$i]->qty < 97 && $object->lines[$i]->fk_product > 0) { $inPackage = true; if ($conf->global->SUBTOTAL_SHOW_QTY_ON_TITLES) { if (!empty($object->lines[$i]->fk_product)) { $product = new Product($db); $product->fetch($object->lines[$i]->fk_product); $TChilds = $product->getChildsArbo($product->id); $TStack[count($TStack)] = array('childs' => $TChilds, 'package' => array(), 'package_qty' => 0); // Si on se trouvait déjà dans un package, on rajoute ce produit à la liste des produits // du précédent package if (count($TStack) > 1) { $TStack[count($TStack) - 2]['package'][$object->lines[$i]->fk_product] += $object->lines[$i]->qty; } } } } if ($conf->global->SUBTOTAL_SHOW_QTY_ON_TITLES) { if ($inPackage && $object->lines[$i]->product_type != 9 && $object->lines[$i]->fk_product > 0) { $TStack[count($TStack) - 1]['package'][$object->lines[$i]->fk_product] += $object->lines[$i]->qty; } } // Ligne de sous-total if ($inPackage && $object->lines[$i]->product_type == 9 && $object->lines[$i]->qty >= 97) { if (count($TStack) <= 1) { $inPackage = false; } if ($conf->global->SUBTOTAL_SHOW_QTY_ON_TITLES) { // Comparaison pour déterminer la quantité de package $TProducts = array_keys($TStack[count($TStack) - 1]['package']); $TProductsChilds = array_keys($TStack[count($TStack) - 1]['childs']); if ($TProductsChilds == $TProducts) { // Il s'agit d'un package // On récupére la quantité $first_child_id = $TProducts[0]; $document_qty = $TStack[count($TStack) - 1]['package'][$first_child_id]; $base_qty = $TStack[count($TStack) - 1]['childs'][$first_child_id][1]; $TStack[count($TStack) - 1]['package_qty'] = $document_qty / $base_qty; $package_qty = $TStack[count($TStack) - 1]['package_qty']; } array_pop($TStack); } } $curY = $nexY; $pdf->SetFont('', '', $default_font_size - 1); // Into loop to work with multipage $pdf->SetTextColor(0, 0, 0); $pdf->setTopMargin($tab_top_newpage); $pdf->setPageOrientation('', 1, $heightforfooter + $heightforfreetext + $heightforinfotot); // The only function to edit the bottom margin of current page to set it. $pageposbefore = $pdf->getPage(); // Description of product line $curX = $this->posxdesc - 1; $showpricebeforepagebreak = 1; $pdf->startTransaction(); pdf_writelinedesc($pdf, $object, $i, $outputlangs, $this->posxtva - $curX, 3, $curX, $curY, $hideref, $hidedesc); $pageposafter = $pdf->getPage(); if ($pageposafter > $pageposbefore) { $pdf->rollbackTransaction(true); $pageposafter = $pageposbefore; //print $pageposafter.'-'.$pageposbefore;exit; $pdf->setPageOrientation('', 1, $heightforfooter); // The only function to edit the bottom margin of current page to set it. pdf_writelinedesc($pdf, $object, $i, $outputlangs, $this->posxtva - $curX, 4, $curX, $curY, $hideref, $hidedesc); $pageposafter = $pdf->getPage(); $posyafter = $pdf->GetY(); if ($posyafter > $this->page_hauteur - ($heightforfooter + $heightforfreetext + $heightforinfotot)) { if ($i == $nblignes - 1) { $pdf->AddPage('', '', true); if (!empty($tplidx)) { $pdf->useTemplate($tplidx); } if (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)) { $this->_pagehead($pdf, $object, 0, $outputlangs); } $pdf->setPage($pageposafter + 1); } } else { // We found a page break $showpricebeforepagebreak = 0; } } else { $pdf->commitTransaction(); } $nexY = $pdf->GetY(); $pageposafter = $pdf->getPage(); $pdf->setPage($pageposbefore); $pdf->setTopMargin($this->marge_haute); $pdf->setPageOrientation('', 1, 0); // The only function to edit the bottom margin of current page to set it. // We suppose that a too long description is moved completely on next page if ($pageposafter > $pageposbefore && empty($showpricebeforepagebreak)) { $pdf->setPage($pageposafter); $curY = $tab_top_newpage; } $pdf->SetFont('', '', $default_font_size - 1); // On repositionne la police par defaut // VAT Rate if (empty($conf->global->MAIN_GENERATE_DOCUMENTS_WITHOUT_VAT)) { // Si on ne doit masquer que les sous-produits if ($hidedetails && !$inPackage && $conf->global->SUBTOTAL_ONLY_HIDE_SUBPRODUCTS_PRICES) { $vat_rate = pdf_getlinevatrate($object, $i, $outputlangs, 0); } else { $vat_rate = pdf_getlinevatrate($object, $i, $outputlangs, $hidedetails); } $pdf->SetXY($this->posxtva, $curY); $pdf->MultiCell($this->posxup - $this->posxtva - 0.8, 3, $vat_rate, 0, 'R'); } // Unit price before discount if ($hidedetails && !$inPackage && $conf->global->SUBTOTAL_ONLY_HIDE_SUBPRODUCTS_PRICES) { $up_excl_tax = pdf_getlineupexcltax($object, $i, $outputlangs, 0); } else { $up_excl_tax = pdf_getlineupexcltax($object, $i, $outputlangs, $hidedetails); } $pdf->SetXY($this->posxup, $curY); $pdf->MultiCell($this->posxqty - $this->posxup - 0.8, 3, $up_excl_tax, 0, 'R', 0); // Booléen pour déterminer s'il s'agit d'une ligne de titre ou non $isTitle = false; // Quantity // Récupération de la quantité à afficher if ($conf->global->SUBTOTAL_IF_HIDE_PRICES_SHOW_QTY) { if ($conf->global->SUBTOTAL_SHOW_QTY_ON_TITLES && $package_qty > 0) { $qty = $package_qty; } else { $qty = pdf_getlineqty($object, $i, $outputlangs, 0); } } else { if ($conf->global->SUBTOTAL_SHOW_QTY_ON_TITLES && $package_qty > 0) { $qty = $package_qty; } else { $qty = pdf_getlineqty($object, $i, $outputlangs, $hidedetails); } } $pdf->SetXY($this->posxqty, $curY); $pdf->MultiCell($this->posxdiscount - $this->posxqty - 0.8, 3, $qty, 0, 'R'); // Enough for 6 chars // Discount on line if ($object->lines[$i]->remise_percent) { $pdf->SetXY($this->posxdiscount - 2, $curY); $remise_percent = pdf_getlineremisepercent($object, $i, $outputlangs, $hidedetails); $pdf->MultiCell($this->postotalht - $this->posxdiscount + 2, 3, $remise_percent, 0, 'R'); } // Total HT line if ($hidedetails && !$inPackage && $conf->global->SUBTOTAL_ONLY_HIDE_SUBPRODUCTS_PRICES) { $total_excl_tax = pdf_getlinetotalexcltax($object, $i, $outputlangs, 0); } else { $total_excl_tax = pdf_getlinetotalexcltax($object, $i, $outputlangs, $hidedetails); } $pdf->SetXY($this->postotalht, $curY); $pdf->MultiCell($this->page_largeur - $this->marge_droite - $this->postotalht, 3, $total_excl_tax, 0, 'R', 0); // Collecte des totaux par valeur de tva dans $this->tva["taux"]=total_tva $tvaligne = $object->lines[$i]->total_tva; $localtax1ligne = $object->lines[$i]->total_localtax1; $localtax2ligne = $object->lines[$i]->total_localtax2; $localtax1_rate = $object->lines[$i]->localtax1_tx; $localtax2_rate = $object->lines[$i]->localtax2_tx; $localtax1_type = $object->lines[$i]->localtax1_type; $localtax2_type = $object->lines[$i]->localtax2_type; if ($object->remise_percent) { $tvaligne -= $tvaligne * $object->remise_percent / 100; } if ($object->remise_percent) { $localtax1ligne -= $localtax1ligne * $object->remise_percent / 100; } if ($object->remise_percent) { $localtax2ligne -= $localtax2ligne * $object->remise_percent / 100; } $vatrate = (string) $object->lines[$i]->tva_tx; // Retrieve type from database for backward compatibility with old records if ((!isset($localtax1_type) || $localtax1_type == '' || !isset($localtax2_type) || $localtax2_type == '') && (!empty($localtax1_rate) || !empty($localtax2_rate))) { $localtaxtmp_array = getLocalTaxesFromRate($vatrate, 0, $object->thirdparty, $mysoc); $localtax1_type = $localtaxtmp_array[0]; $localtax2_type = $localtaxtmp_array[2]; } // retrieve global local tax if ($localtax1_type && $localtax1ligne != 0) { $this->localtax1[$localtax1_type][$localtax1_rate] += $localtax1ligne; } if ($localtax2_type && $localtax2ligne != 0) { $this->localtax2[$localtax2_type][$localtax2_rate] += $localtax2ligne; } if (($object->lines[$i]->info_bits & 0x1) == 0x1) { $vatrate .= '*'; } if (!isset($this->tva[$vatrate])) { $this->tva[$vatrate] = ''; } $this->tva[$vatrate] += $tvaligne; // Add line if (!empty($conf->global->MAIN_PDF_DASH_BETWEEN_LINES) && $i < $nblignes - 1) { $pdf->setPage($pageposafter); $pdf->SetLineStyle(array('dash' => '1,1', 'color' => array(210, 210, 210))); //$pdf->SetDrawColor(190,190,200); $pdf->line($this->marge_gauche, $nexY + 1, $this->page_largeur - $this->marge_droite, $nexY + 1); $pdf->SetLineStyle(array('dash' => 0)); } $nexY += 2; // Passe espace entre les lignes // Detect if some page were added automatically and output _tableau for past pages while ($pagenb < $pageposafter) { $pdf->setPage($pagenb); if ($pagenb == 1) { $this->_tableau($pdf, $tab_top, $this->page_hauteur - $tab_top - $heightforfooter, 0, $outputlangs, 0, 1); } else { $this->_tableau($pdf, $tab_top_newpage, $this->page_hauteur - $tab_top_newpage - $heightforfooter, 0, $outputlangs, 1, 1); } $this->_pagefoot($pdf, $object, $outputlangs, 1); $pagenb++; $pdf->setPage($pagenb); $pdf->setPageOrientation('', 1, 0); // The only function to edit the bottom margin of current page to set it. if (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)) { $this->_pagehead($pdf, $object, 0, $outputlangs); } } if (isset($object->lines[$i + 1]->pagebreak) && $object->lines[$i + 1]->pagebreak) { if ($pagenb == 1) { $this->_tableau($pdf, $tab_top, $this->page_hauteur - $tab_top - $heightforfooter, 0, $outputlangs, 0, 1); } else { $this->_tableau($pdf, $tab_top_newpage, $this->page_hauteur - $tab_top_newpage - $heightforfooter, 0, $outputlangs, 1, 1); } $this->_pagefoot($pdf, $object, $outputlangs, 1); // New page $pdf->AddPage(); if (!empty($tplidx)) { $pdf->useTemplate($tplidx); } $pagenb++; if (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)) { $this->_pagehead($pdf, $object, 0, $outputlangs); } } } // Show square if ($pagenb == 1) { $this->_tableau($pdf, $tab_top, $this->page_hauteur - $tab_top - $heightforinfotot - $heightforfreetext - $heightforfooter, 0, $outputlangs, 0, 0); $bottomlasttab = $this->page_hauteur - $heightforinfotot - $heightforfreetext - $heightforfooter + 1; } else { $this->_tableau($pdf, $tab_top_newpage, $this->page_hauteur - $tab_top_newpage - $heightforinfotot - $heightforfreetext - $heightforfooter, 0, $outputlangs, 1, 0); $bottomlasttab = $this->page_hauteur - $heightforinfotot - $heightforfreetext - $heightforfooter + 1; } // Affiche zone infos $posy = $this->_tableau_info($pdf, $object, $bottomlasttab, $outputlangs); if (!$conf->global->SUBTOTAL_HIDE_DOCUMENT_TOTAL) { // Affiche zone totaux $posy = $this->_tableau_tot($pdf, $object, $deja_regle, $bottomlasttab, $outputlangs); } // Affiche zone versements if ($deja_regle) { $posy = $this->_tableau_versements($pdf, $object, $posy, $outputlangs); } // Pied de page $this->_pagefoot($pdf, $object, $outputlangs); if (method_exists($pdf, 'AliasNbPages')) { $pdf->AliasNbPages(); } $pdf->Close(); $pdf->Output($file, 'F'); // Add pdfgeneration hook $hookmanager->initHooks(array('pdfgeneration')); $parameters = array('file' => $file, 'object' => $object, 'outputlangs' => $outputlangs); global $action; $reshook = $hookmanager->executeHooks('afterPDFCreation', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks if (!empty($conf->global->MAIN_UMASK)) { @chmod($file, octdec($conf->global->MAIN_UMASK)); } return 1; // Pas d'erreur } else { $this->error = $langs->trans("ErrorCanNotCreateDir", $dir); return 0; } } else { $this->error = $langs->trans("ErrorConstantNotDefined", "COMMANDE_OUTPUTDIR"); return 0; } $this->error = $langs->trans("ErrorUnknown"); return 0; // Erreur par defaut }