Complex classes like FactureFournisseur often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
While breaking up the class, it is a good idea to analyze how other classes use FactureFournisseur, and based on these observations, apply Extract Interface, too.
| 1 | <?php |
||
| 43 | class FactureFournisseur extends CommonInvoice |
||
| 44 | { |
||
| 45 | /** |
||
| 46 | * @var string ID to identify managed object |
||
| 47 | */ |
||
| 48 | public $element='invoice_supplier'; |
||
| 49 | |||
| 50 | /** |
||
| 51 | * @var string Name of table without prefix where object is stored |
||
| 52 | */ |
||
| 53 | public $table_element='facture_fourn'; |
||
| 54 | |||
| 55 | /** |
||
| 56 | * @var int Name of subtable line |
||
| 57 | */ |
||
| 58 | public $table_element_line='facture_fourn_det'; |
||
| 59 | |||
| 60 | /** |
||
| 61 | * @var int Field with ID of parent key if this field has a parent |
||
| 62 | */ |
||
| 63 | public $fk_element='fk_facture_fourn'; |
||
| 64 | |||
| 65 | public $picto='bill'; |
||
| 66 | |||
| 67 | /** |
||
| 68 | * 0=No test on entity, 1=Test with field entity, 2=Test with link by societe |
||
| 69 | * @var int |
||
| 70 | */ |
||
| 71 | public $ismultientitymanaged = 1; |
||
| 72 | |||
| 73 | /** |
||
| 74 | * 0=Default, 1=View may be restricted to sales representative only if no permission to see all or to company of external user if external user |
||
| 75 | * @var integer |
||
| 76 | */ |
||
| 77 | public $restrictiononfksoc = 1; |
||
| 78 | |||
| 79 | /** |
||
| 80 | * {@inheritdoc} |
||
| 81 | */ |
||
| 82 | protected $table_ref_field = 'ref'; |
||
| 83 | |||
| 84 | /** |
||
| 85 | * @var int ID |
||
| 86 | */ |
||
| 87 | public $rowid; |
||
| 88 | |||
| 89 | /** |
||
| 90 | * @var string Ref |
||
| 91 | */ |
||
| 92 | public $ref; |
||
| 93 | |||
| 94 | public $label; |
||
| 95 | public $libelle; // @deprecated |
||
| 96 | |||
| 97 | public $product_ref; |
||
| 98 | public $ref_supplier; |
||
| 99 | public $socid; |
||
| 100 | //Check constants for types |
||
| 101 | public $type = self::TYPE_STANDARD; |
||
| 102 | |||
| 103 | /** |
||
| 104 | * Supplier invoice status |
||
| 105 | * @var int |
||
| 106 | * @see FactureFournisseur::STATUS_DRAFT, FactureFournisseur::STATUS_VALIDATED, FactureFournisseur::STATUS_PAID, FactureFournisseur::STATUS_ABANDONED |
||
| 107 | */ |
||
| 108 | public $statut; |
||
| 109 | |||
| 110 | /** |
||
| 111 | * Set to 1 if the invoice is completely paid, otherwise is 0 |
||
| 112 | * @var int |
||
| 113 | * @deprecated Use statuses stored in self::statut |
||
| 114 | */ |
||
| 115 | public $paye; |
||
| 116 | |||
| 117 | public $author; |
||
| 118 | |||
| 119 | /** |
||
| 120 | * Date creation record (datec) |
||
| 121 | * |
||
| 122 | * @var integer |
||
| 123 | */ |
||
| 124 | public $datec; |
||
| 125 | |||
| 126 | /** |
||
| 127 | * Date modification record (tms) |
||
| 128 | * |
||
| 129 | * @var integer |
||
| 130 | */ |
||
| 131 | public $tms; |
||
| 132 | |||
| 133 | /** |
||
| 134 | * Invoice date (date) |
||
| 135 | * |
||
| 136 | * @var integer |
||
| 137 | */ |
||
| 138 | public $date; |
||
| 139 | |||
| 140 | /** |
||
| 141 | * Max payment date (date_echeance) |
||
| 142 | * |
||
| 143 | * @var integer |
||
| 144 | */ |
||
| 145 | public $date_echeance; |
||
| 146 | |||
| 147 | public $amount=0; |
||
| 148 | public $remise=0; |
||
| 149 | public $tva=0; |
||
| 150 | public $localtax1; |
||
| 151 | public $localtax2; |
||
| 152 | public $total_ht=0; |
||
| 153 | public $total_tva=0; |
||
| 154 | public $total_localtax1=0; |
||
| 155 | public $total_localtax2=0; |
||
| 156 | public $total_ttc=0; |
||
| 157 | |||
| 158 | /** |
||
| 159 | * @deprecated |
||
| 160 | * @see $note_private, $note_public |
||
| 161 | */ |
||
| 162 | public $note; |
||
| 163 | |||
| 164 | public $note_private; |
||
| 165 | public $note_public; |
||
| 166 | public $propalid; |
||
| 167 | public $cond_reglement_id; |
||
| 168 | public $cond_reglement_code; |
||
| 169 | |||
| 170 | /** |
||
| 171 | * @var int ID |
||
| 172 | */ |
||
| 173 | public $fk_account; |
||
| 174 | |||
| 175 | public $mode_reglement_id; |
||
| 176 | public $mode_reglement_code; |
||
| 177 | |||
| 178 | /** |
||
| 179 | * Invoice lines |
||
| 180 | * @var SupplierInvoiceLine[] |
||
| 181 | */ |
||
| 182 | public $lines = array(); |
||
| 183 | |||
| 184 | /** |
||
| 185 | * @deprecated |
||
| 186 | */ |
||
| 187 | public $fournisseur; |
||
| 188 | |||
| 189 | /** |
||
| 190 | * @var int ID Incorterms |
||
| 191 | */ |
||
| 192 | public $fk_incoterms; |
||
| 193 | |||
| 194 | public $location_incoterms; |
||
| 195 | public $label_incoterms; //Used into tooltip |
||
| 196 | |||
| 197 | public $extraparams=array(); |
||
| 198 | |||
| 199 | // Multicurrency |
||
| 200 | /** |
||
| 201 | * @var int ID |
||
| 202 | */ |
||
| 203 | public $fk_multicurrency; |
||
| 204 | |||
| 205 | public $multicurrency_code; |
||
| 206 | public $multicurrency_tx; |
||
| 207 | public $multicurrency_total_ht; |
||
| 208 | public $multicurrency_total_tva; |
||
| 209 | public $multicurrency_total_ttc; |
||
| 210 | //! id of source var_dump($$this);invoice if replacement invoice or credit note |
||
| 211 | /** |
||
| 212 | * @var int ID |
||
| 213 | */ |
||
| 214 | public $fk_facture_source; |
||
| 215 | |||
| 216 | /** |
||
| 217 | * Standard invoice |
||
| 218 | */ |
||
| 219 | const TYPE_STANDARD = 0; |
||
| 220 | |||
| 221 | /** |
||
| 222 | * Replacement invoice |
||
| 223 | */ |
||
| 224 | const TYPE_REPLACEMENT = 1; |
||
| 225 | |||
| 226 | /** |
||
| 227 | * Credit note invoice |
||
| 228 | */ |
||
| 229 | const TYPE_CREDIT_NOTE = 2; |
||
| 230 | |||
| 231 | /** |
||
| 232 | * Deposit invoice |
||
| 233 | */ |
||
| 234 | const TYPE_DEPOSIT = 3; |
||
| 235 | |||
| 236 | /** |
||
| 237 | * Draft |
||
| 238 | */ |
||
| 239 | const STATUS_DRAFT = 0; |
||
| 240 | |||
| 241 | /** |
||
| 242 | * Validated (need to be paid) |
||
| 243 | */ |
||
| 244 | const STATUS_VALIDATED = 1; |
||
| 245 | |||
| 246 | /** |
||
| 247 | * Classified paid. |
||
| 248 | * If paid partially, $this->close_code can be: |
||
| 249 | * - CLOSECODE_DISCOUNTVAT |
||
| 250 | * - CLOSECODE_BADDEBT |
||
| 251 | * If paid completelly, this->close_code will be null |
||
| 252 | */ |
||
| 253 | const STATUS_CLOSED = 2; |
||
| 254 | |||
| 255 | /** |
||
| 256 | * Classified abandoned and no payment done. |
||
| 257 | * $this->close_code can be: |
||
| 258 | * - CLOSECODE_BADDEBT |
||
| 259 | * - CLOSECODE_ABANDONED |
||
| 260 | * - CLOSECODE_REPLACED |
||
| 261 | */ |
||
| 262 | const STATUS_ABANDONED = 3; |
||
| 263 | |||
| 264 | const CLOSECODE_DISCOUNTVAT = 'discount_vat'; |
||
| 265 | const CLOSECODE_BADCREDIT = 'badsupplier'; |
||
| 266 | const CLOSECODE_ABANDONED = 'abandon'; |
||
| 267 | const CLOSECODE_REPLACED = 'replaced'; |
||
| 268 | |||
| 269 | /** |
||
| 270 | * Constructor |
||
| 271 | * |
||
| 272 | * @param DoliDB $db Database handler |
||
| 273 | */ |
||
| 274 | public function __construct($db) |
||
| 275 | { |
||
| 276 | $this->db = $db; |
||
| 277 | |||
| 278 | $this->products = array(); |
||
| 279 | } |
||
| 280 | |||
| 281 | /** |
||
| 282 | * Create supplier invoice into database |
||
| 283 | * |
||
| 284 | * @param User $user object utilisateur qui cree |
||
| 285 | * @return int Id invoice created if OK, < 0 if KO |
||
| 286 | */ |
||
| 287 | public function create($user) |
||
| 288 | { |
||
| 289 | global $langs,$conf,$hookmanager; |
||
| 290 | |||
| 291 | $error=0; |
||
| 292 | $now=dol_now(); |
||
| 293 | |||
| 294 | // Clean parameters |
||
| 295 | if (isset($this->ref_supplier)) $this->ref_supplier=trim($this->ref_supplier); |
||
| 296 | if (empty($this->type)) $this->type = self::TYPE_STANDARD; |
||
| 297 | if (empty($this->date)) $this->date=$now; |
||
| 298 | |||
| 299 | $socid = $this->socid; |
||
| 300 | $ref_supplier = $this->ref_supplier; |
||
| 301 | $amount = $this->amount; |
||
| 302 | $remise = $this->remise; |
||
| 303 | |||
| 304 | // Multicurrency (test on $this->multicurrency_tx because we should take the default rate only if not using origin rate) |
||
| 305 | if (!empty($this->multicurrency_code) && empty($this->multicurrency_tx)) list($this->fk_multicurrency,$this->multicurrency_tx) = MultiCurrency::getIdAndTxFromCode($this->db, $this->multicurrency_code); |
||
| 306 | else $this->fk_multicurrency = MultiCurrency::getIdFromCode($this->db, $this->multicurrency_code); |
||
| 307 | if (empty($this->fk_multicurrency)) |
||
| 308 | { |
||
| 309 | $this->multicurrency_code = $conf->currency; |
||
| 310 | $this->fk_multicurrency = 0; |
||
| 311 | $this->multicurrency_tx = 1; |
||
| 312 | } |
||
| 313 | |||
| 314 | $this->db->begin(); |
||
| 315 | |||
| 316 | if (! $remise) $remise = 0 ; |
||
| 317 | |||
| 318 | $sql = "INSERT INTO ".MAIN_DB_PREFIX."facture_fourn ("; |
||
| 319 | $sql.= "ref"; |
||
| 320 | $sql.= ", ref_supplier"; |
||
| 321 | $sql.= ", entity"; |
||
| 322 | $sql.= ", type"; |
||
| 323 | $sql.= ", libelle"; |
||
| 324 | $sql.= ", fk_soc"; |
||
| 325 | $sql.= ", datec"; |
||
| 326 | $sql.= ", datef"; |
||
| 327 | $sql.= ", fk_projet"; |
||
| 328 | $sql.= ", fk_cond_reglement"; |
||
| 329 | $sql.= ", fk_mode_reglement"; |
||
| 330 | $sql.= ", fk_account"; |
||
| 331 | $sql.= ", note_private"; |
||
| 332 | $sql.= ", note_public"; |
||
| 333 | $sql.= ", fk_user_author"; |
||
| 334 | $sql.= ", date_lim_reglement"; |
||
| 335 | $sql.= ", fk_incoterms, location_incoterms"; |
||
| 336 | $sql.= ", fk_multicurrency"; |
||
| 337 | $sql.= ", multicurrency_code"; |
||
| 338 | $sql.= ", multicurrency_tx"; |
||
| 339 | $sql.= ", fk_facture_source"; |
||
| 340 | $sql.= ")"; |
||
| 341 | $sql.= " VALUES ("; |
||
| 342 | $sql.= "'(PROV)'"; |
||
| 343 | $sql.= ", '".$this->db->escape($this->ref_supplier)."'"; |
||
| 344 | $sql.= ", ".$conf->entity; |
||
| 345 | $sql.= ", '".$this->db->escape($this->type)."'"; |
||
| 346 | $sql.= ", '".$this->db->escape($this->label?$this->label:$this->libelle)."'"; |
||
| 347 | $sql.= ", ".$this->socid; |
||
| 348 | $sql.= ", '".$this->db->idate($now)."'"; |
||
| 349 | $sql.= ", '".$this->db->idate($this->date)."'"; |
||
| 350 | $sql.= ", ".($this->fk_project > 0 ? $this->fk_project:"null"); |
||
| 351 | $sql.= ", ".($this->cond_reglement_id > 0 ? $this->cond_reglement_id:"null"); |
||
| 352 | $sql.= ", ".($this->mode_reglement_id > 0 ? $this->mode_reglement_id:"null"); |
||
| 353 | $sql.= ", ".($this->fk_account>0?$this->fk_account:'NULL'); |
||
| 354 | $sql.= ", '".$this->db->escape($this->note_private)."'"; |
||
| 355 | $sql.= ", '".$this->db->escape($this->note_public)."'"; |
||
| 356 | $sql.= ", ".$user->id.","; |
||
| 357 | $sql.= $this->date_echeance!=''?"'".$this->db->idate($this->date_echeance)."'":"null"; |
||
| 358 | $sql.= ", ".(int) $this->fk_incoterms; |
||
| 359 | $sql.= ", '".$this->db->escape($this->location_incoterms)."'"; |
||
| 360 | $sql.= ", ".(int) $this->fk_multicurrency; |
||
| 361 | $sql.= ", '".$this->db->escape($this->multicurrency_code)."'"; |
||
| 362 | $sql.= ", ".(double) $this->multicurrency_tx; |
||
| 363 | $sql.= ", ".(isset($this->fk_facture_source)?$this->fk_facture_source:"NULL"); |
||
| 364 | $sql.= ")"; |
||
| 365 | |||
| 366 | dol_syslog(get_class($this)."::create", LOG_DEBUG); |
||
| 367 | $resql=$this->db->query($sql); |
||
| 368 | if ($resql) |
||
| 369 | { |
||
| 370 | $this->id = $this->db->last_insert_id(MAIN_DB_PREFIX.'facture_fourn'); |
||
| 371 | |||
| 372 | // Update ref with new one |
||
| 373 | $this->ref='(PROV'.$this->id.')'; |
||
| 374 | $sql = 'UPDATE '.MAIN_DB_PREFIX."facture_fourn SET ref='".$this->db->escape($this->ref)."' WHERE rowid=".$this->id; |
||
| 375 | |||
| 376 | dol_syslog(get_class($this)."::create", LOG_DEBUG); |
||
| 377 | $resql=$this->db->query($sql); |
||
| 378 | if (! $resql) $error++; |
||
| 379 | |||
| 380 | if (! empty($this->linkedObjectsIds) && empty($this->linked_objects)) // To use new linkedObjectsIds instead of old linked_objects |
||
| 381 | { |
||
| 382 | $this->linked_objects = $this->linkedObjectsIds; // TODO Replace linked_objects with linkedObjectsIds |
||
| 383 | } |
||
| 384 | |||
| 385 | // Add object linked |
||
| 386 | if (! $error && $this->id && is_array($this->linked_objects) && ! empty($this->linked_objects)) |
||
| 387 | { |
||
| 388 | foreach($this->linked_objects as $origin => $tmp_origin_id) |
||
| 389 | { |
||
| 390 | if (is_array($tmp_origin_id)) // New behaviour, if linked_object can have several links per type, so is something like array('contract'=>array(id1, id2, ...)) |
||
| 391 | { |
||
| 392 | foreach($tmp_origin_id as $origin_id) |
||
| 393 | { |
||
| 394 | $ret = $this->add_object_linked($origin, $origin_id); |
||
| 395 | if (! $ret) |
||
| 396 | { |
||
| 397 | dol_print_error($this->db); |
||
| 398 | $error++; |
||
| 399 | } |
||
| 400 | } |
||
| 401 | } |
||
| 402 | else // Old behaviour, if linked_object has only one link per type, so is something like array('contract'=>id1)) |
||
| 403 | { |
||
| 404 | $origin_id = $tmp_origin_id; |
||
| 405 | $ret = $this->add_object_linked($origin, $origin_id); |
||
| 406 | if (! $ret) |
||
| 407 | { |
||
| 408 | dol_print_error($this->db); |
||
| 409 | $error++; |
||
| 410 | } |
||
| 411 | } |
||
| 412 | } |
||
| 413 | } |
||
| 414 | |||
| 415 | // Add linked object (deprecated, use ->linkedObjectsIds instead) |
||
| 416 | if (! $error && $this->id && ! empty($this->origin) && ! empty($this->origin_id)) |
||
| 417 | { |
||
| 418 | $ret = $this->add_object_linked(); |
||
| 419 | if (! $ret) |
||
| 420 | { |
||
| 421 | dol_print_error($this->db); |
||
| 422 | $error++; |
||
| 423 | } |
||
| 424 | } |
||
| 425 | |||
| 426 | if (count($this->lines) && is_object($this->lines[0])) // If this->lines is array of InvoiceLines (preferred mode) |
||
| 427 | { |
||
| 428 | dol_syslog("There is ".count($this->lines)." lines that are invoice lines objects"); |
||
| 429 | foreach ($this->lines as $i => $val) |
||
| 430 | { |
||
| 431 | $sql = 'INSERT INTO '.MAIN_DB_PREFIX.'facture_fourn_det (fk_facture_fourn, special_code)'; |
||
| 432 | $sql .= ' VALUES ('.$this->id.','.intval($this->lines[$i]->special_code).')'; |
||
| 433 | |||
| 434 | $resql_insert=$this->db->query($sql); |
||
| 435 | if ($resql_insert) |
||
| 436 | { |
||
| 437 | $idligne = $this->db->last_insert_id(MAIN_DB_PREFIX.'facture_fourn_det'); |
||
| 438 | |||
| 439 | $this->updateline( |
||
| 440 | $idligne, |
||
| 441 | $this->lines[$i]->description, |
||
| 442 | $this->lines[$i]->pu_ht, |
||
|
1 ignored issue
–
show
|
|||
| 443 | $this->lines[$i]->tva_tx, |
||
| 444 | $this->lines[$i]->localtax1_tx, |
||
| 445 | $this->lines[$i]->localtax2_tx, |
||
| 446 | $this->lines[$i]->qty, |
||
| 447 | $this->lines[$i]->fk_product, |
||
| 448 | 'HT', |
||
| 449 | (! empty($this->lines[$i]->info_bits)?$this->lines[$i]->info_bits:''), |
||
| 450 | $this->lines[$i]->product_type, |
||
| 451 | $this->lines[$i]->remise_percent, |
||
| 452 | false, |
||
| 453 | $this->lines[$i]->date_start, |
||
| 454 | $this->lines[$i]->date_end, |
||
| 455 | $this->lines[$i]->array_options, |
||
| 456 | $this->lines[$i]->fk_unit, |
||
| 457 | $this->lines[$i]->pu_ht_devise |
||
| 458 | ); |
||
| 459 | } |
||
| 460 | else |
||
| 461 | { |
||
| 462 | $this->error=$this->db->lasterror(); |
||
| 463 | $this->db->rollback(); |
||
| 464 | return -5; |
||
| 465 | } |
||
| 466 | } |
||
| 467 | } |
||
| 468 | else // If this->lines is an array of invoice line arrays |
||
| 469 | { |
||
| 470 | dol_syslog("There is ".count($this->lines)." lines that are array lines"); |
||
| 471 | foreach ($this->lines as $i => $val) |
||
| 472 | { |
||
| 473 | $line = $this->lines[$i]; |
||
| 474 | |||
| 475 | // Test and convert into object this->lines[$i]. When coming from REST API, we may still have an array |
||
| 476 | //if (! is_object($line)) $line=json_decode(json_encode($line), false); // convert recursively array into object. |
||
| 477 | if (! is_object($line)) $line = (object) $line; |
||
| 478 | |||
| 479 | $sql = 'INSERT INTO '.MAIN_DB_PREFIX.'facture_fourn_det (fk_facture_fourn, special_code)'; |
||
| 480 | $sql .= ' VALUES ('.$this->id.','.intval($this->lines[$i]->special_code).')'; |
||
| 481 | |||
| 482 | $resql_insert=$this->db->query($sql); |
||
| 483 | if ($resql_insert) |
||
| 484 | { |
||
| 485 | $idligne = $this->db->last_insert_id(MAIN_DB_PREFIX.'facture_fourn_det'); |
||
| 486 | |||
| 487 | $this->updateline( |
||
| 488 | $idligne, |
||
| 489 | $line->description, |
||
| 490 | $line->pu_ht, |
||
| 491 | $line->tva_tx, |
||
| 492 | $line->localtax1_tx, |
||
| 493 | $line->localtax2_tx, |
||
| 494 | $line->qty, |
||
| 495 | $line->fk_product, |
||
| 496 | 'HT', |
||
| 497 | (! empty($line->info_bits)?$line->info_bits:''), |
||
| 498 | $line->product_type |
||
| 499 | ); |
||
| 500 | } |
||
| 501 | else |
||
| 502 | { |
||
| 503 | $this->error=$this->db->lasterror(); |
||
| 504 | $this->db->rollback(); |
||
| 505 | return -5; |
||
| 506 | } |
||
| 507 | } |
||
| 508 | } |
||
| 509 | |||
| 510 | // Update total price |
||
| 511 | $result=$this->update_price(); |
||
| 512 | if ($result > 0) |
||
| 513 | { |
||
| 514 | // Actions on extra fields |
||
| 515 | if (empty($conf->global->MAIN_EXTRAFIELDS_DISABLED)) // For avoid conflicts if trigger used |
||
| 516 | { |
||
| 517 | $result=$this->insertExtraFields(); // This also set $this->error or $this->errors if errors are found |
||
| 518 | if ($result < 0) |
||
| 519 | { |
||
| 520 | $error++; |
||
| 521 | } |
||
| 522 | } |
||
| 523 | |||
| 524 | if (! $error) |
||
| 525 | { |
||
| 526 | // Call trigger |
||
| 527 | $result=$this->call_trigger('BILL_SUPPLIER_CREATE', $user); |
||
| 528 | if ($result < 0) $error++; |
||
| 529 | // End call triggers |
||
| 530 | } |
||
| 531 | |||
| 532 | if (! $error) |
||
| 533 | { |
||
| 534 | $this->db->commit(); |
||
| 535 | return $this->id; |
||
| 536 | } |
||
| 537 | else |
||
| 538 | { |
||
| 539 | $this->db->rollback(); |
||
| 540 | return -4; |
||
| 541 | } |
||
| 542 | } |
||
| 543 | else |
||
| 544 | { |
||
| 545 | $this->error=$langs->trans('FailedToUpdatePrice'); |
||
| 546 | $this->db->rollback(); |
||
| 547 | return -3; |
||
| 548 | } |
||
| 549 | } |
||
| 550 | else |
||
| 551 | { |
||
| 552 | if ($this->db->errno() == 'DB_ERROR_RECORD_ALREADY_EXISTS') |
||
| 553 | { |
||
| 554 | $this->error=$langs->trans('ErrorRefAlreadyExists'); |
||
| 555 | $this->db->rollback(); |
||
| 556 | return -1; |
||
| 557 | } |
||
| 558 | else |
||
| 559 | { |
||
| 560 | $this->error=$this->db->lasterror(); |
||
| 561 | $this->db->rollback(); |
||
| 562 | return -2; |
||
| 563 | } |
||
| 564 | } |
||
| 565 | } |
||
| 566 | |||
| 567 | /** |
||
| 568 | * Load object in memory from database |
||
| 569 | * |
||
| 570 | * @param int $id Id supplier invoice |
||
| 571 | * @param string $ref Ref supplier invoice |
||
| 572 | * @return int <0 if KO, >0 if OK, 0 if not found |
||
| 573 | */ |
||
| 574 | public function fetch($id = '', $ref = '') |
||
| 728 | } |
||
| 729 | } |
||
| 730 | |||
| 731 | |||
| 732 | // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps |
||
| 733 | /** |
||
| 734 | * Load this->lines |
||
| 735 | * |
||
| 736 | * @return int 1 si ok, < 0 si erreur |
||
| 737 | */ |
||
| 738 | public function fetch_lines() |
||
| 739 | { |
||
| 740 | // phpcs:enable |
||
| 741 | $this->lines = array(); |
||
| 742 | |||
| 743 | $sql = 'SELECT f.rowid, f.ref as ref_supplier, f.description, f.date_start, f.date_end, f.pu_ht, f.pu_ttc, f.qty, f.remise_percent, f.vat_src_code, f.tva_tx'; |
||
| 744 | $sql.= ', f.localtax1_tx, f.localtax2_tx, f.localtax1_type, f.localtax2_type, f.total_localtax1, f.total_localtax2, f.fk_facture_fourn '; |
||
| 745 | $sql.= ', f.total_ht, f.tva as total_tva, f.total_ttc, f.fk_product, f.product_type, f.info_bits, f.rang, f.special_code, f.fk_parent_line, f.fk_unit'; |
||
| 746 | $sql.= ', p.rowid as product_id, p.ref as product_ref, p.label as label, p.description as product_desc'; |
||
| 747 | $sql.= ', f.fk_multicurrency, f.multicurrency_code, f.multicurrency_subprice, f.multicurrency_total_ht, f.multicurrency_total_tva, f.multicurrency_total_ttc'; |
||
| 748 | $sql.= ' FROM '.MAIN_DB_PREFIX.'facture_fourn_det as f'; |
||
| 749 | $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'product as p ON f.fk_product = p.rowid'; |
||
| 750 | $sql.= ' WHERE fk_facture_fourn='.$this->id; |
||
| 751 | $sql.= ' ORDER BY f.rang, f.rowid'; |
||
| 752 | |||
| 753 | dol_syslog(get_class($this)."::fetch_lines", LOG_DEBUG); |
||
| 754 | $resql_rows = $this->db->query($sql); |
||
| 755 | if ($resql_rows) |
||
| 756 | { |
||
| 757 | $num_rows = $this->db->num_rows($resql_rows); |
||
| 758 | if ($num_rows) |
||
| 759 | { |
||
| 760 | $i = 0; |
||
| 761 | while ($i < $num_rows) |
||
| 762 | { |
||
| 763 | $obj = $this->db->fetch_object($resql_rows); |
||
| 764 | |||
| 765 | $line = new SupplierInvoiceLine($this->db); |
||
| 766 | |||
| 767 | $line->id = $obj->rowid; |
||
| 768 | $line->rowid = $obj->rowid; |
||
| 769 | $line->description = $obj->description; |
||
| 770 | $line->date_start = $obj->date_start; |
||
| 771 | $line->date_end = $obj->date_end; |
||
| 772 | |||
| 773 | $line->product_ref = $obj->product_ref; |
||
| 774 | $line->ref = $obj->product_ref; |
||
| 775 | $line->ref_supplier = $obj->ref_supplier; |
||
| 776 | $line->libelle = $obj->label; |
||
| 777 | $line->label = $obj->label; |
||
| 778 | $line->product_desc = $obj->product_desc; |
||
| 779 | $line->subprice = $obj->pu_ht; |
||
| 780 | $line->pu_ht = $obj->pu_ht; |
||
| 781 | $line->pu_ttc = $obj->pu_ttc; |
||
| 782 | |||
| 783 | $line->vat_src_code = $obj->vat_src_code; |
||
| 784 | $line->tva_tx = $obj->tva_tx; |
||
| 785 | $line->localtax1_tx = $obj->localtax1_tx; |
||
| 786 | $line->localtax2_tx = $obj->localtax2_tx; |
||
| 787 | $line->localtax1_type = $obj->localtax1_type; |
||
| 788 | $line->localtax2_type = $obj->localtax2_type; |
||
| 789 | $line->qty = $obj->qty; |
||
| 790 | $line->remise_percent = $obj->remise_percent; |
||
| 791 | $line->tva = $obj->total_tva; // deprecated |
||
| 792 | $line->total_ht = $obj->total_ht; |
||
| 793 | $line->total_ttc = $obj->total_ttc; |
||
| 794 | $line->total_tva = $obj->total_tva; |
||
| 795 | $line->total_localtax1 = $obj->total_localtax1; |
||
| 796 | $line->total_localtax2 = $obj->total_localtax2; |
||
| 797 | $line->fk_facture_fourn = $obj->fk_facture_fourn; |
||
| 798 | $line->fk_product = $obj->fk_product; |
||
| 799 | $line->product_type = $obj->product_type; |
||
| 800 | $line->product_label = $obj->label; |
||
| 801 | $line->info_bits = $obj->info_bits; |
||
| 802 | $line->fk_parent_line = $obj->fk_parent_line; |
||
| 803 | $line->special_code = $obj->special_code; |
||
| 804 | $line->rang = $obj->rang; |
||
| 805 | $line->fk_unit = $obj->fk_unit; |
||
| 806 | |||
| 807 | // Multicurrency |
||
| 808 | $line->fk_multicurrency = $obj->fk_multicurrency; |
||
| 809 | $line->multicurrency_code = $obj->multicurrency_code; |
||
| 810 | $line->multicurrency_subprice = $obj->multicurrency_subprice; |
||
| 811 | $line->multicurrency_total_ht = $obj->multicurrency_total_ht; |
||
| 812 | $line->multicurrency_total_tva = $obj->multicurrency_total_tva; |
||
| 813 | $line->multicurrency_total_ttc = $obj->multicurrency_total_ttc; |
||
| 814 | |||
| 815 | $this->lines[$i] = $line; |
||
| 816 | |||
| 817 | $i++; |
||
| 818 | } |
||
| 819 | } |
||
| 820 | $this->db->free($resql_rows); |
||
| 821 | return 1; |
||
| 822 | } |
||
| 823 | else |
||
| 824 | { |
||
| 825 | $this->error=$this->db->error(); |
||
| 826 | return -3; |
||
| 827 | } |
||
| 828 | } |
||
| 829 | |||
| 830 | |||
| 831 | /** |
||
| 832 | * Update database |
||
| 833 | * |
||
| 834 | * @param User $user User that modify |
||
| 835 | * @param int $notrigger 0=launch triggers after, 1=disable triggers |
||
| 836 | * @return int <0 if KO, >0 if OK |
||
| 837 | */ |
||
| 838 | public function update($user = null, $notrigger = 0) |
||
| 839 | { |
||
| 840 | global $conf, $langs; |
||
| 841 | $error=0; |
||
| 842 | |||
| 843 | // Clean parameters |
||
| 844 | if (empty($this->type)) $this->type= self::TYPE_STANDARD; |
||
| 845 | if (isset($this->ref)) $this->ref=trim($this->ref); |
||
| 846 | if (isset($this->ref_supplier)) $this->ref_supplier=trim($this->ref_supplier); |
||
| 847 | if (isset($this->entity)) $this->entity=trim($this->entity); |
||
| 848 | if (isset($this->type)) $this->type=trim($this->type); |
||
| 849 | if (isset($this->fk_soc)) $this->fk_soc=trim($this->fk_soc); |
||
| 850 | if (isset($this->label)) $this->label=trim($this->label); |
||
| 851 | if (isset($this->libelle)) $this->libelle=trim($this->libelle); // deprecated |
||
| 852 | if (isset($this->paye)) $this->paye=trim($this->paye); |
||
| 853 | if (isset($this->amount)) $this->amount=trim($this->amount); |
||
| 854 | if (isset($this->remise)) $this->remise=trim($this->remise); |
||
| 855 | if (isset($this->close_code)) $this->close_code=trim($this->close_code); |
||
| 856 | if (isset($this->close_note)) $this->close_note=trim($this->close_note); |
||
| 857 | if (isset($this->tva)) $this->tva=trim($this->tva); |
||
| 858 | if (isset($this->localtax1)) $this->localtax1=trim($this->localtax1); |
||
| 859 | if (isset($this->localtax2)) $this->localtax2=trim($this->localtax2); |
||
| 860 | if (empty($this->total_ht)) $this->total_ht=0; |
||
| 861 | if (empty($this->total_tva)) $this->total_tva=0; |
||
| 862 | // if (isset($this->total_localtax1)) $this->total_localtax1=trim($this->total_localtax1); |
||
| 863 | // if (isset($this->total_localtax2)) $this->total_localtax2=trim($this->total_localtax2); |
||
| 864 | if (isset($this->total_ttc)) $this->total_ttc=trim($this->total_ttc); |
||
| 865 | if (isset($this->statut)) $this->statut=(int) $this->statut; |
||
| 866 | if (isset($this->author)) $this->author=trim($this->author); |
||
| 867 | if (isset($this->fk_user_valid)) $this->fk_user_valid=trim($this->fk_user_valid); |
||
| 868 | if (isset($this->fk_facture_source)) $this->fk_facture_source=trim($this->fk_facture_source); |
||
| 869 | if (isset($this->fk_project)) $this->fk_project=trim($this->fk_project); |
||
| 870 | if (isset($this->cond_reglement_id)) $this->cond_reglement_id=trim($this->cond_reglement_id); |
||
| 871 | if (isset($this->note_private)) $this->note=trim($this->note_private); |
||
| 872 | if (isset($this->note_public)) $this->note_public=trim($this->note_public); |
||
| 873 | if (isset($this->model_pdf)) $this->model_pdf=trim($this->model_pdf); |
||
| 874 | if (isset($this->import_key)) $this->import_key=trim($this->import_key); |
||
| 875 | |||
| 876 | |||
| 877 | // Check parameters |
||
| 878 | // Put here code to add control on parameters values |
||
| 879 | |||
| 880 | // Update request |
||
| 881 | $sql = "UPDATE ".MAIN_DB_PREFIX."facture_fourn SET"; |
||
| 882 | $sql.= " ref=".(isset($this->ref)?"'".$this->db->escape($this->ref)."'":"null").","; |
||
| 883 | $sql.= " ref_supplier=".(isset($this->ref_supplier)?"'".$this->db->escape($this->ref_supplier)."'":"null").","; |
||
| 884 | $sql.= " entity=".(isset($this->entity)?$this->entity:"null").","; |
||
| 885 | $sql.= " type=".(isset($this->type)?$this->type:"null").","; |
||
| 886 | $sql.= " fk_soc=".(isset($this->fk_soc)?$this->fk_soc:"null").","; |
||
| 887 | $sql.= " datec=".(dol_strlen($this->datec)!=0 ? "'".$this->db->idate($this->datec)."'" : 'null').","; |
||
| 888 | $sql.= " datef=".(dol_strlen($this->date)!=0 ? "'".$this->db->idate($this->date)."'" : 'null').","; |
||
| 889 | if (dol_strlen($this->tms) != 0) $sql.= " tms=".(dol_strlen($this->tms)!=0 ? "'".$this->db->idate($this->tms)."'" : 'null').","; |
||
| 890 | $sql.= " libelle=".(isset($this->label)?"'".$this->db->escape($this->label)."'":"null").","; |
||
| 891 | $sql.= " paye=".(isset($this->paye)?$this->paye:"null").","; |
||
| 892 | $sql.= " amount=".(isset($this->amount)?$this->amount:"null").","; |
||
| 893 | $sql.= " remise=".(isset($this->remise)?$this->remise:"null").","; |
||
| 894 | $sql.= " close_code=".(isset($this->close_code)?"'".$this->db->escape($this->close_code)."'":"null").","; |
||
| 895 | $sql.= " close_note=".(isset($this->close_note)?"'".$this->db->escape($this->close_note)."'":"null").","; |
||
| 896 | $sql.= " tva=".(isset($this->tva)?$this->tva:"null").","; |
||
| 897 | $sql.= " localtax1=".(isset($this->localtax1)?$this->localtax1:"null").","; |
||
| 898 | $sql.= " localtax2=".(isset($this->localtax2)?$this->localtax2:"null").","; |
||
| 899 | $sql.= " total_ht=".(isset($this->total_ht)?$this->total_ht:"null").","; |
||
| 900 | $sql.= " total_tva=".(isset($this->total_tva)?$this->total_tva:"null").","; |
||
| 901 | $sql.= " total_ttc=".(isset($this->total_ttc)?$this->total_ttc:"null").","; |
||
| 902 | $sql.= " fk_statut=".(isset($this->statut)?$this->statut:"null").","; |
||
| 903 | $sql.= " fk_user_author=".(isset($this->author)?$this->author:"null").","; |
||
| 904 | $sql.= " fk_user_valid=".(isset($this->fk_user_valid)?$this->fk_user_valid:"null").","; |
||
| 905 | $sql.= " fk_facture_source=".(isset($this->fk_facture_source)?$this->fk_facture_source:"null").","; |
||
| 906 | $sql.= " fk_projet=".(isset($this->fk_project)?$this->fk_project:"null").","; |
||
| 907 | $sql.= " fk_cond_reglement=".(isset($this->cond_reglement_id)?$this->cond_reglement_id:"null").","; |
||
| 908 | $sql.= " date_lim_reglement=".(dol_strlen($this->date_echeance)!=0 ? "'".$this->db->idate($this->date_echeance)."'" : 'null').","; |
||
| 909 | $sql.= " note_private=".(isset($this->note_private)?"'".$this->db->escape($this->note_private)."'":"null").","; |
||
| 910 | $sql.= " note_public=".(isset($this->note_public)?"'".$this->db->escape($this->note_public)."'":"null").","; |
||
| 911 | $sql.= " model_pdf=".(isset($this->model_pdf)?"'".$this->db->escape($this->model_pdf)."'":"null").","; |
||
| 912 | $sql.= " import_key=".(isset($this->import_key)?"'".$this->db->escape($this->import_key)."'":"null").""; |
||
| 913 | $sql.= " WHERE rowid=".$this->id; |
||
| 914 | |||
| 915 | $this->db->begin(); |
||
| 916 | |||
| 917 | dol_syslog(get_class($this)."::update", LOG_DEBUG); |
||
| 918 | $resql = $this->db->query($sql); |
||
| 919 | |||
| 920 | if (!$resql) { |
||
| 921 | $error++; |
||
| 922 | |||
| 923 | if ($this->db->errno() == 'DB_ERROR_RECORD_ALREADY_EXISTS') { |
||
| 924 | $this->errors[] = $langs->trans('ErrorRefAlreadyExists'); |
||
| 925 | } else { |
||
| 926 | $this->errors[] = "Error ".$this->db->lasterror(); |
||
| 927 | } |
||
| 928 | } |
||
| 929 | |||
| 930 | if (! $error) |
||
| 931 | { |
||
| 932 | if (! $notrigger) |
||
| 933 | { |
||
| 934 | // Call trigger |
||
| 935 | $result=$this->call_trigger('BILL_SUPPLIER_UPDATE', $user); |
||
| 936 | if ($result < 0) $error++; |
||
| 937 | // End call triggers |
||
| 938 | } |
||
| 939 | } |
||
| 940 | |||
| 941 | // Commit or rollback |
||
| 942 | if ($error) |
||
| 943 | { |
||
| 944 | foreach($this->errors as $errmsg) |
||
| 945 | { |
||
| 946 | dol_syslog(get_class($this)."::update ".$errmsg, LOG_ERR); |
||
| 947 | $this->error.=($this->error?', '.$errmsg:$errmsg); |
||
| 948 | } |
||
| 949 | $this->db->rollback(); |
||
| 950 | return -1*$error; |
||
| 951 | } |
||
| 952 | else |
||
| 953 | { |
||
| 954 | $this->db->commit(); |
||
| 955 | return 1; |
||
| 956 | } |
||
| 957 | } |
||
| 958 | |||
| 959 | // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps |
||
| 960 | /** |
||
| 961 | * Add a discount line into an invoice (as an invoice line) using an existing absolute discount (Consume the discount) |
||
| 962 | * |
||
| 963 | * @param int $idremise Id of absolute discount |
||
| 964 | * @return int >0 if OK, <0 if KO |
||
| 965 | */ |
||
| 966 | public function insert_discount($idremise) |
||
| 967 | { |
||
| 968 | // phpcs:enable |
||
| 969 | global $langs; |
||
| 970 | |||
| 971 | include_once DOL_DOCUMENT_ROOT.'/core/lib/price.lib.php'; |
||
| 972 | include_once DOL_DOCUMENT_ROOT.'/core/class/discount.class.php'; |
||
| 973 | |||
| 974 | $this->db->begin(); |
||
| 975 | |||
| 976 | $remise=new DiscountAbsolute($this->db); |
||
| 977 | $result=$remise->fetch($idremise); |
||
| 978 | |||
| 979 | if ($result > 0) |
||
| 980 | { |
||
| 981 | if ($remise->fk_invoice_supplier) // Protection against multiple submission |
||
| 982 | { |
||
| 983 | $this->error=$langs->trans("ErrorDiscountAlreadyUsed"); |
||
| 984 | $this->db->rollback(); |
||
| 985 | return -5; |
||
| 986 | } |
||
| 987 | |||
| 988 | $facligne=new SupplierInvoiceLine($this->db); |
||
| 989 | $facligne->fk_facture_fourn=$this->id; |
||
| 990 | $facligne->fk_remise_except=$remise->id; |
||
| 991 | $facligne->desc=$remise->description; // Description ligne |
||
| 992 | $facligne->vat_src_code=$remise->vat_src_code; |
||
| 993 | $facligne->tva_tx=$remise->tva_tx; |
||
| 994 | $facligne->subprice = -$remise->amount_ht; |
||
| 995 | $facligne->fk_product=0; // Id produit predefini |
||
| 996 | $facligne->product_type=0; |
||
| 997 | $facligne->qty=1; |
||
| 998 | $facligne->remise_percent=0; |
||
| 999 | $facligne->rang=-1; |
||
| 1000 | $facligne->info_bits=2; |
||
| 1001 | |||
| 1002 | // Get buy/cost price of invoice that is source of discount |
||
| 1003 | if ($remise->fk_invoice_supplier_source > 0) |
||
| 1004 | { |
||
| 1005 | $srcinvoice=new FactureFournisseur($this->db); |
||
| 1006 | $srcinvoice->fetch($remise->fk_invoice_supplier_source); |
||
| 1007 | $totalcostpriceofinvoice=0; |
||
| 1008 | include_once DOL_DOCUMENT_ROOT.'/core/class/html.formmargin.class.php'; // TODO Move this into commonobject |
||
| 1009 | $formmargin=new FormMargin($this->db); |
||
| 1010 | $arraytmp=$formmargin->getMarginInfosArray($srcinvoice, false); |
||
| 1011 | $facligne->pa_ht = $arraytmp['pa_total']; |
||
| 1012 | } |
||
| 1013 | |||
| 1014 | $facligne->total_ht = -$remise->amount_ht; |
||
| 1015 | $facligne->total_tva = -$remise->amount_tva; |
||
| 1016 | $facligne->total_ttc = -$remise->amount_ttc; |
||
| 1017 | |||
| 1018 | $facligne->multicurrency_subprice = -$remise->multicurrency_subprice; |
||
| 1019 | $facligne->multicurrency_total_ht = -$remise->multicurrency_total_ht; |
||
| 1020 | $facligne->multicurrency_total_tva = -$remise->multicurrency_total_tva; |
||
| 1021 | $facligne->multicurrency_total_ttc = -$remise->multicurrency_total_ttc; |
||
| 1022 | |||
| 1023 | $lineid=$facligne->insert(); |
||
| 1024 | if ($lineid > 0) |
||
| 1025 | { |
||
| 1026 | $result=$this->update_price(1); |
||
| 1027 | if ($result > 0) |
||
| 1028 | { |
||
| 1029 | // Create link between discount and invoice line |
||
| 1030 | $result=$remise->link_to_invoice($lineid, 0, 'supplier'); |
||
| 1031 | if ($result < 0) |
||
| 1032 | { |
||
| 1033 | $this->error=$remise->error; |
||
| 1034 | $this->db->rollback(); |
||
| 1035 | return -4; |
||
| 1036 | } |
||
| 1037 | |||
| 1038 | $this->db->commit(); |
||
| 1039 | return 1; |
||
| 1040 | } |
||
| 1041 | else |
||
| 1042 | { |
||
| 1043 | $this->error=$facligne->error; |
||
| 1044 | $this->db->rollback(); |
||
| 1045 | return -1; |
||
| 1046 | } |
||
| 1047 | } |
||
| 1048 | else |
||
| 1049 | { |
||
| 1050 | $this->error=$facligne->error; |
||
| 1051 | $this->db->rollback(); |
||
| 1052 | return -2; |
||
| 1053 | } |
||
| 1054 | } |
||
| 1055 | else |
||
| 1056 | { |
||
| 1057 | $this->db->rollback(); |
||
| 1058 | return -3; |
||
| 1059 | } |
||
| 1060 | } |
||
| 1061 | |||
| 1062 | |||
| 1063 | /** |
||
| 1064 | * Delete invoice from database |
||
| 1065 | * |
||
| 1066 | * @param User $user User object |
||
| 1067 | * @param int $notrigger 1=Does not execute triggers, 0= execute triggers |
||
| 1068 | * @return int <0 if KO, >0 if OK |
||
| 1069 | */ |
||
| 1070 | public function delete(User $user, $notrigger = 0) |
||
| 1071 | { |
||
| 1072 | global $langs,$conf; |
||
| 1073 | |||
| 1074 | $rowid=$this->id; |
||
| 1075 | |||
| 1076 | dol_syslog("FactureFournisseur::delete rowid=".$rowid, LOG_DEBUG); |
||
| 1077 | |||
| 1078 | // TODO Test if there is at least on payment. If yes, refuse to delete. |
||
| 1079 | |||
| 1080 | $error=0; |
||
| 1081 | $this->db->begin(); |
||
| 1082 | |||
| 1083 | if (! $error && ! $notrigger) |
||
| 1084 | { |
||
| 1085 | // Call trigger |
||
| 1086 | $result=$this->call_trigger('BILL_SUPPLIER_DELETE', $user); |
||
| 1087 | if ($result < 0) |
||
| 1088 | { |
||
| 1089 | $this->db->rollback(); |
||
| 1090 | return -1; |
||
| 1091 | } |
||
| 1092 | // Fin appel triggers |
||
| 1093 | } |
||
| 1094 | |||
| 1095 | if (! $error) { |
||
| 1096 | // If invoice was converted into a discount not yet consumed, we remove discount |
||
| 1097 | $sql = 'DELETE FROM ' . MAIN_DB_PREFIX . 'societe_remise_except'; |
||
| 1098 | $sql .= ' WHERE fk_invoice_supplier_source = ' . $rowid; |
||
| 1099 | $sql .= ' AND fk_invoice_supplier_line IS NULL'; |
||
| 1100 | $resql = $this->db->query($sql); |
||
| 1101 | |||
| 1102 | // If invoice has consumned discounts |
||
| 1103 | $this->fetch_lines(); |
||
| 1104 | $list_rowid_det = array (); |
||
| 1105 | foreach ($this->lines as $key => $invoiceline) { |
||
| 1106 | $list_rowid_det[] = $invoiceline->rowid; |
||
| 1107 | } |
||
| 1108 | |||
| 1109 | // Consumned discounts are freed |
||
| 1110 | if (count($list_rowid_det)) { |
||
| 1111 | $sql = 'UPDATE ' . MAIN_DB_PREFIX . 'societe_remise_except'; |
||
| 1112 | $sql .= ' SET fk_invoice_supplier = NULL, fk_invoice_supplier_line = NULL'; |
||
| 1113 | $sql .= ' WHERE fk_invoice_supplier_line IN (' . join(',', $list_rowid_det) . ')'; |
||
| 1114 | |||
| 1115 | dol_syslog(get_class($this) . "::delete", LOG_DEBUG); |
||
| 1116 | if (! $this->db->query($sql)) { |
||
| 1117 | $error ++; |
||
| 1118 | } |
||
| 1119 | } |
||
| 1120 | } |
||
| 1121 | |||
| 1122 | if (! $error) |
||
| 1123 | { |
||
| 1124 | $sql = 'DELETE FROM '.MAIN_DB_PREFIX.'facture_fourn_det WHERE fk_facture_fourn = '.$rowid.';'; |
||
| 1125 | dol_syslog(get_class($this)."::delete", LOG_DEBUG); |
||
| 1126 | $resql = $this->db->query($sql); |
||
| 1127 | if ($resql) |
||
| 1128 | { |
||
| 1129 | $sql = 'DELETE FROM '.MAIN_DB_PREFIX.'facture_fourn WHERE rowid = '.$rowid; |
||
| 1130 | dol_syslog(get_class($this)."::delete", LOG_DEBUG); |
||
| 1131 | $resql2 = $this->db->query($sql); |
||
| 1132 | if (! $resql2) { |
||
| 1133 | $error++; |
||
| 1134 | } |
||
| 1135 | } |
||
| 1136 | else { |
||
| 1137 | $error++; |
||
| 1138 | } |
||
| 1139 | } |
||
| 1140 | |||
| 1141 | if (! $error) |
||
| 1142 | { |
||
| 1143 | // Delete linked object |
||
| 1144 | $res = $this->deleteObjectLinked(); |
||
| 1145 | if ($res < 0) $error++; |
||
| 1146 | } |
||
| 1147 | |||
| 1148 | if (! $error) |
||
| 1149 | { |
||
| 1150 | // Delete linked object |
||
| 1151 | $res = $this->deleteObjectLinked(); |
||
| 1152 | if ($res < 0) $error++; |
||
| 1153 | } |
||
| 1154 | |||
| 1155 | if (! $error) |
||
| 1156 | { |
||
| 1157 | // We remove directory |
||
| 1158 | if ($conf->fournisseur->facture->dir_output) |
||
| 1159 | { |
||
| 1160 | include_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; |
||
| 1161 | |||
| 1162 | $ref = dol_sanitizeFileName($this->ref); |
||
| 1163 | $dir = $conf->fournisseur->facture->dir_output.'/'.get_exdir($this->id, 2, 0, 0, $this, 'invoive_supplier').$ref; |
||
| 1164 | $file = $dir . "/" . $ref . ".pdf"; |
||
| 1165 | if (file_exists($file)) |
||
| 1166 | { |
||
| 1167 | if (! dol_delete_file($file, 0, 0, 0, $this)) // For triggers |
||
| 1168 | { |
||
| 1169 | $this->error='ErrorFailToDeleteFile'; |
||
| 1170 | $error++; |
||
| 1171 | } |
||
| 1172 | } |
||
| 1173 | if (file_exists($dir)) |
||
| 1174 | { |
||
| 1175 | $res=@dol_delete_dir_recursive($dir); |
||
| 1176 | |||
| 1177 | if (! $res) |
||
| 1178 | { |
||
| 1179 | $this->error='ErrorFailToDeleteDir'; |
||
| 1180 | $error++; |
||
| 1181 | } |
||
| 1182 | } |
||
| 1183 | } |
||
| 1184 | } |
||
| 1185 | |||
| 1186 | // Remove extrafields |
||
| 1187 | if ((! $error) && (empty($conf->global->MAIN_EXTRAFIELDS_DISABLED))) // For avoid conflicts if trigger used |
||
| 1188 | { |
||
| 1189 | $result=$this->deleteExtraFields(); |
||
| 1190 | if ($result < 0) |
||
| 1191 | { |
||
| 1192 | $error++; |
||
| 1193 | dol_syslog(get_class($this)."::delete error -4 ".$this->error, LOG_ERR); |
||
| 1194 | } |
||
| 1195 | } |
||
| 1196 | |||
| 1197 | if (! $error) |
||
| 1198 | { |
||
| 1199 | dol_syslog(get_class($this)."::delete $this->id by $user->id", LOG_DEBUG); |
||
| 1200 | $this->db->commit(); |
||
| 1201 | return 1; |
||
| 1202 | } |
||
| 1203 | else |
||
| 1204 | { |
||
| 1205 | $this->error=$this->db->lasterror(); |
||
| 1206 | $this->db->rollback(); |
||
| 1207 | return -$error; |
||
| 1208 | } |
||
| 1209 | } |
||
| 1210 | |||
| 1211 | |||
| 1212 | // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps |
||
| 1213 | /** |
||
| 1214 | * Tag invoice as a payed invoice |
||
| 1215 | * |
||
| 1216 | * @param User $user Object user |
||
| 1217 | * @param string $close_code Code renseigne si on classe a payee completement alors que paiement incomplet. Not implementd yet. |
||
| 1218 | * @param string $close_note Commentaire renseigne si on classe a payee alors que paiement incomplet. Not implementd yet. |
||
| 1219 | * @return int <0 si ko, >0 si ok |
||
| 1220 | */ |
||
| 1221 | public function set_paid($user, $close_code = '', $close_note = '') |
||
| 1222 | { |
||
| 1223 | // phpcs:enable |
||
| 1224 | global $conf,$langs; |
||
| 1225 | $error=0; |
||
| 1226 | |||
| 1227 | $this->db->begin(); |
||
| 1228 | |||
| 1229 | $sql = 'UPDATE '.MAIN_DB_PREFIX.'facture_fourn'; |
||
| 1230 | $sql.= ' SET paye = 1, fk_statut=2'; |
||
| 1231 | $sql.= ' WHERE rowid = '.$this->id; |
||
| 1232 | |||
| 1233 | dol_syslog("FactureFournisseur::set_paid", LOG_DEBUG); |
||
| 1234 | $resql = $this->db->query($sql); |
||
| 1235 | if ($resql) |
||
| 1236 | { |
||
| 1237 | // Call trigger |
||
| 1238 | $result=$this->call_trigger('BILL_SUPPLIER_PAYED', $user); |
||
| 1239 | if ($result < 0) $error++; |
||
| 1240 | // End call triggers |
||
| 1241 | } |
||
| 1242 | else |
||
| 1243 | { |
||
| 1244 | $error++; |
||
| 1245 | $this->error=$this->db->error(); |
||
| 1246 | dol_print_error($this->db); |
||
| 1247 | } |
||
| 1248 | |||
| 1249 | if (! $error) |
||
| 1250 | { |
||
| 1251 | $this->db->commit(); |
||
| 1252 | return 1; |
||
| 1253 | } |
||
| 1254 | else |
||
| 1255 | { |
||
| 1256 | $this->db->rollback(); |
||
| 1257 | return -1; |
||
| 1258 | } |
||
| 1259 | } |
||
| 1260 | |||
| 1261 | |||
| 1262 | // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps |
||
| 1263 | /** |
||
| 1264 | * Tag la facture comme non payee completement + appel trigger BILL_UNPAYED |
||
| 1265 | * Fonction utilisee quand un paiement prelevement est refuse, |
||
| 1266 | * ou quand une facture annulee et reouverte. |
||
| 1267 | * |
||
| 1268 | * @param User $user Object user that change status |
||
| 1269 | * @return int <0 si ok, >0 si ok |
||
| 1270 | */ |
||
| 1271 | public function set_unpaid($user) |
||
| 1272 | { |
||
| 1273 | // phpcs:enable |
||
| 1274 | global $conf,$langs; |
||
| 1275 | $error=0; |
||
| 1276 | |||
| 1277 | $this->db->begin(); |
||
| 1278 | |||
| 1279 | $sql = 'UPDATE '.MAIN_DB_PREFIX.'facture_fourn'; |
||
| 1280 | $sql.= ' SET paye=0, fk_statut=1, close_code=null, close_note=null'; |
||
| 1281 | $sql.= ' WHERE rowid = '.$this->id; |
||
| 1282 | |||
| 1283 | dol_syslog("FactureFournisseur::set_unpaid", LOG_DEBUG); |
||
| 1284 | $resql = $this->db->query($sql); |
||
| 1285 | if ($resql) |
||
| 1286 | { |
||
| 1287 | // Call trigger |
||
| 1288 | $result=$this->call_trigger('BILL_SUPPLIER_UNPAYED', $user); |
||
| 1289 | if ($result < 0) $error++; |
||
| 1290 | // End call triggers |
||
| 1291 | } |
||
| 1292 | else |
||
| 1293 | { |
||
| 1294 | $error++; |
||
| 1295 | $this->error=$this->db->lasterror(); |
||
| 1296 | dol_syslog("FactureFournisseur::set_unpaid ".$this->error); |
||
| 1297 | } |
||
| 1298 | |||
| 1299 | if (! $error) |
||
| 1300 | { |
||
| 1301 | $this->db->commit(); |
||
| 1302 | return 1; |
||
| 1303 | } |
||
| 1304 | else |
||
| 1305 | { |
||
| 1306 | $this->db->rollback(); |
||
| 1307 | return -1; |
||
| 1308 | } |
||
| 1309 | } |
||
| 1310 | |||
| 1311 | /** |
||
| 1312 | * Tag invoice as validated + call trigger BILL_VALIDATE |
||
| 1313 | * |
||
| 1314 | * @param User $user Object user that validate |
||
| 1315 | * @param string $force_number Reference to force on invoice |
||
| 1316 | * @param int $idwarehouse Id of warehouse for stock change |
||
| 1317 | * @param int $notrigger 1=Does not execute triggers, 0= execute triggers |
||
| 1318 | * @return int <0 if KO, =0 if nothing to do, >0 if OK |
||
| 1319 | */ |
||
| 1320 | public function validate($user, $force_number = '', $idwarehouse = 0, $notrigger = 0) |
||
| 1321 | { |
||
| 1322 | global $conf,$langs; |
||
| 1323 | |||
| 1324 | require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; |
||
| 1325 | |||
| 1326 | $now=dol_now(); |
||
| 1327 | |||
| 1328 | $error=0; |
||
| 1329 | dol_syslog(get_class($this).'::validate user='.$user->id.', force_number='.$force_number.', idwarehouse='.$idwarehouse); |
||
| 1330 | |||
| 1331 | // Force to have object complete for checks |
||
| 1332 | $this->fetch_thirdparty(); |
||
| 1333 | $this->fetch_lines(); |
||
| 1334 | |||
| 1335 | // Check parameters |
||
| 1336 | if ($this->statut > self::STATUS_DRAFT) // This is to avoid to validate twice (avoid errors on logs and stock management) |
||
| 1337 | { |
||
| 1338 | dol_syslog(get_class($this)."::validate no draft status", LOG_WARNING); |
||
| 1339 | return 0; |
||
| 1340 | } |
||
| 1341 | if (preg_match('/^'.preg_quote($langs->trans("CopyOf").' ').'/', $this->ref_supplier)) |
||
| 1342 | { |
||
| 1343 | $langs->load("errors"); |
||
| 1344 | $this->error=$langs->trans("ErrorFieldFormat", $langs->transnoentities("RefSupplier")).'. '.$langs->trans('RemoveString', $langs->transnoentitiesnoconv("CopyOf")); |
||
| 1345 | return -1; |
||
| 1346 | } |
||
| 1347 | if (count($this->lines) <= 0) |
||
| 1348 | { |
||
| 1349 | $langs->load("errors"); |
||
| 1350 | $this->error=$langs->trans("ErrorObjectMustHaveLinesToBeValidated", $this->ref); |
||
| 1351 | return -1; |
||
| 1352 | } |
||
| 1353 | |||
| 1354 | $this->db->begin(); |
||
| 1355 | |||
| 1356 | // Define new ref |
||
| 1357 | if ($force_number) |
||
| 1358 | { |
||
| 1359 | $num = $force_number; |
||
| 1360 | } |
||
| 1361 | elseif (preg_match('/^[\(]?PROV/i', $this->ref) || empty($this->ref)) // empty should not happened, but when it occurs, the test save life |
||
| 1362 | { |
||
| 1363 | $num = $this->getNextNumRef($this->thirdparty); |
||
| 1364 | } |
||
| 1365 | else |
||
| 1366 | { |
||
| 1367 | $num = $this->ref; |
||
| 1368 | } |
||
| 1369 | $this->newref = $num; |
||
| 1370 | |||
| 1371 | $sql = "UPDATE ".MAIN_DB_PREFIX."facture_fourn"; |
||
| 1372 | $sql.= " SET ref='".$num."', fk_statut = 1, fk_user_valid = ".$user->id.", date_valid = '".$this->db->idate($now)."'"; |
||
| 1373 | $sql.= " WHERE rowid = ".$this->id; |
||
| 1374 | |||
| 1375 | dol_syslog(get_class($this)."::validate", LOG_DEBUG); |
||
| 1376 | $resql = $this->db->query($sql); |
||
| 1377 | if ($resql) |
||
| 1378 | { |
||
| 1379 | // Si on incrémente le produit principal et ses composants à la validation de facture fournisseur |
||
| 1380 | if (! $error && ! empty($conf->stock->enabled) && ! empty($conf->global->STOCK_CALCULATE_ON_SUPPLIER_BILL)) |
||
| 1381 | { |
||
| 1382 | require_once DOL_DOCUMENT_ROOT.'/product/stock/class/mouvementstock.class.php'; |
||
| 1383 | $langs->load("agenda"); |
||
| 1384 | |||
| 1385 | $cpt=count($this->lines); |
||
| 1386 | for ($i = 0; $i < $cpt; $i++) |
||
| 1387 | { |
||
| 1388 | if ($this->lines[$i]->fk_product > 0) |
||
| 1389 | { |
||
| 1390 | $this->line = $this->lines[$i]; |
||
| 1391 | $mouvP = new MouvementStock($this->db); |
||
| 1392 | $mouvP->origin = &$this; |
||
| 1393 | // We increase stock for product |
||
| 1394 | $up_ht_disc=$this->lines[$i]->pu_ht; |
||
| 1395 | if (! empty($this->lines[$i]->remise_percent) && empty($conf->global->STOCK_EXCLUDE_DISCOUNT_FOR_PMP)) $up_ht_disc=price2num($up_ht_disc * (100 - $this->lines[$i]->remise_percent) / 100, 'MU'); |
||
| 1396 | if ($this->type == FactureFournisseur::TYPE_CREDIT_NOTE) $result=$mouvP->livraison($user, $this->lines[$i]->fk_product, $idwarehouse, $this->lines[$i]->qty, $up_ht_disc, $langs->trans("InvoiceValidatedInDolibarr", $num)); |
||
| 1397 | else $result=$mouvP->reception($user, $this->lines[$i]->fk_product, $idwarehouse, $this->lines[$i]->qty, $up_ht_disc, $langs->trans("InvoiceValidatedInDolibarr", $num)); |
||
| 1398 | if ($result < 0) { $error++; } |
||
| 1399 | unset($this->line); |
||
| 1400 | } |
||
| 1401 | } |
||
| 1402 | } |
||
| 1403 | |||
| 1404 | // Triggers call |
||
| 1405 | if (! $error && empty($notrigger)) |
||
| 1406 | { |
||
| 1407 | // Call trigger |
||
| 1408 | $result=$this->call_trigger('BILL_SUPPLIER_VALIDATE', $user); |
||
| 1409 | if ($result < 0) $error++; |
||
| 1410 | // End call triggers |
||
| 1411 | } |
||
| 1412 | |||
| 1413 | if (! $error) |
||
| 1414 | { |
||
| 1415 | $this->oldref = $this->ref; |
||
| 1416 | |||
| 1417 | // Rename directory if dir was a temporary ref |
||
| 1418 | if (preg_match('/^[\(]?PROV/i', $this->ref)) |
||
| 1419 | { |
||
| 1420 | // Now we rename also files into index |
||
| 1421 | $sql = 'UPDATE '.MAIN_DB_PREFIX."ecm_files set filename = CONCAT('".$this->db->escape($this->newref)."', SUBSTR(filename, ".(strlen($this->ref)+1).")), filepath = 'fournisseur/facture/".get_exdir($this->id, 2, 0, 0, $this, 'invoice_supplier').$this->db->escape($this->newref)."'"; |
||
| 1422 | $sql.= " WHERE filename LIKE '".$this->db->escape($this->ref)."%' AND filepath = 'fournisseur/facture/".get_exdir($this->id, 2, 0, 0, $this, 'invoice_supplier').$this->db->escape($this->ref)."' and entity = ".$conf->entity; |
||
| 1423 | $resql = $this->db->query($sql); |
||
| 1424 | if (! $resql) { $error++; $this->error = $this->db->lasterror(); } |
||
| 1425 | |||
| 1426 | // We rename directory ($this->ref = old ref, $num = new ref) in order not to lose the attachments |
||
| 1427 | $oldref = dol_sanitizeFileName($this->ref); |
||
| 1428 | $newref = dol_sanitizeFileName($num); |
||
| 1429 | $dirsource = $conf->fournisseur->facture->dir_output.'/'.get_exdir($this->id, 2, 0, 0, $this, 'invoice_supplier').$oldref; |
||
| 1430 | $dirdest = $conf->fournisseur->facture->dir_output.'/'.get_exdir($this->id, 2, 0, 0, $this, 'invoice_supplier').$newref; |
||
| 1431 | if (! $error && file_exists($dirsource)) |
||
| 1432 | { |
||
| 1433 | dol_syslog(get_class($this)."::validate rename dir ".$dirsource." into ".$dirdest); |
||
| 1434 | |||
| 1435 | if (@rename($dirsource, $dirdest)) |
||
| 1436 | { |
||
| 1437 | dol_syslog("Rename ok"); |
||
| 1438 | // Rename docs starting with $oldref with $newref |
||
| 1439 | $listoffiles=dol_dir_list($conf->fournisseur->facture->dir_output.'/'.get_exdir($this->id, 2, 0, 0, $this, 'invoice_supplier').$newref, 'files', 1, '^'.preg_quote($oldref, '/')); |
||
| 1440 | foreach($listoffiles as $fileentry) |
||
| 1441 | { |
||
| 1442 | $dirsource=$fileentry['name']; |
||
| 1443 | $dirdest=preg_replace('/^'.preg_quote($oldref, '/').'/', $newref, $dirsource); |
||
| 1444 | $dirsource=$fileentry['path'].'/'.$dirsource; |
||
| 1445 | $dirdest=$fileentry['path'].'/'.$dirdest; |
||
| 1446 | @rename($dirsource, $dirdest); |
||
|
1 ignored issue
–
show
|
|||
| 1447 | } |
||
| 1448 | } |
||
| 1449 | } |
||
| 1450 | } |
||
| 1451 | } |
||
| 1452 | |||
| 1453 | // Set new ref and define current statut |
||
| 1454 | if (! $error) |
||
| 1455 | { |
||
| 1456 | $this->ref = $num; |
||
| 1457 | $this->statut=self::STATUS_VALIDATED; |
||
| 1458 | //$this->date_validation=$now; this is stored into log table |
||
| 1459 | } |
||
| 1460 | |||
| 1461 | if (! $error) |
||
| 1462 | { |
||
| 1463 | $this->db->commit(); |
||
| 1464 | return 1; |
||
| 1465 | } |
||
| 1466 | else |
||
| 1467 | { |
||
| 1468 | $this->db->rollback(); |
||
| 1469 | return -1; |
||
| 1470 | } |
||
| 1471 | } |
||
| 1472 | else |
||
| 1473 | { |
||
| 1474 | $this->error=$this->db->error(); |
||
| 1475 | $this->db->rollback(); |
||
| 1476 | return -1; |
||
| 1477 | } |
||
| 1478 | } |
||
| 1479 | |||
| 1480 | /** |
||
| 1481 | * Set draft status |
||
| 1482 | * |
||
| 1483 | * @param User $user Object user that modify |
||
| 1484 | * @param int $idwarehouse Id warehouse to use for stock change. |
||
| 1485 | * @return int <0 if KO, >0 if OK |
||
| 1486 | */ |
||
| 1487 | public function setDraft($user, $idwarehouse = -1) |
||
| 1488 | { |
||
| 1489 | // phpcs:enable |
||
| 1490 | global $conf,$langs; |
||
| 1491 | |||
| 1492 | $error=0; |
||
| 1493 | |||
| 1494 | if ($this->statut == self::STATUS_DRAFT) |
||
| 1495 | { |
||
| 1496 | dol_syslog(__METHOD__." already draft status", LOG_WARNING); |
||
| 1497 | return 0; |
||
| 1498 | } |
||
| 1499 | |||
| 1500 | dol_syslog(__METHOD__, LOG_DEBUG); |
||
| 1501 | |||
| 1502 | $this->db->begin(); |
||
| 1503 | |||
| 1504 | $sql = "UPDATE ".MAIN_DB_PREFIX."facture_fourn"; |
||
| 1505 | $sql.= " SET fk_statut = ".self::STATUS_DRAFT; |
||
| 1506 | $sql.= " WHERE rowid = ".$this->id; |
||
| 1507 | |||
| 1508 | $result=$this->db->query($sql); |
||
| 1509 | if ($result) |
||
| 1510 | { |
||
| 1511 | if (! $error) |
||
| 1512 | { |
||
| 1513 | $this->oldcopy= clone $this; |
||
| 1514 | } |
||
| 1515 | |||
| 1516 | // Si on incremente le produit principal et ses composants a la validation de facture fournisseur, on decremente |
||
| 1517 | if ($result >= 0 && ! empty($conf->stock->enabled) && ! empty($conf->global->STOCK_CALCULATE_ON_SUPPLIER_BILL)) |
||
| 1518 | { |
||
| 1519 | require_once DOL_DOCUMENT_ROOT.'/product/stock/class/mouvementstock.class.php'; |
||
| 1520 | $langs->load("agenda"); |
||
| 1521 | |||
| 1522 | $cpt=count($this->lines); |
||
| 1523 | for ($i = 0; $i < $cpt; $i++) |
||
| 1524 | { |
||
| 1525 | if ($this->lines[$i]->fk_product > 0) |
||
| 1526 | { |
||
| 1527 | $mouvP = new MouvementStock($this->db); |
||
| 1528 | $mouvP->origin = &$this; |
||
| 1529 | // We increase stock for product |
||
| 1530 | if ($this->type == FactureFournisseur::TYPE_CREDIT_NOTE) $result=$mouvP->reception($user, $this->lines[$i]->fk_product, $idwarehouse, $this->lines[$i]->qty, $this->lines[$i]->subprice, $langs->trans("InvoiceBackToDraftInDolibarr", $this->ref)); |
||
| 1531 | else $result=$mouvP->livraison($user, $this->lines[$i]->fk_product, $idwarehouse, $this->lines[$i]->qty, $this->lines[$i]->subprice, $langs->trans("InvoiceBackToDraftInDolibarr", $this->ref)); |
||
| 1532 | } |
||
| 1533 | } |
||
| 1534 | } |
||
| 1535 | // Triggers call |
||
| 1536 | if (! $error && empty($notrigger)) |
||
| 1537 | { |
||
| 1538 | // Call trigger |
||
| 1539 | $result=$this->call_trigger('BILL_SUPPLIER_UNVALIDATE', $user); |
||
| 1540 | if ($result < 0) $error++; |
||
| 1541 | // End call triggers |
||
| 1542 | } |
||
| 1543 | if ($error == 0) |
||
| 1544 | { |
||
| 1545 | $this->db->commit(); |
||
| 1546 | return 1; |
||
| 1547 | } |
||
| 1548 | else |
||
| 1549 | { |
||
| 1550 | $this->db->rollback(); |
||
| 1551 | return -1; |
||
| 1552 | } |
||
| 1553 | } |
||
| 1554 | else |
||
| 1555 | { |
||
| 1556 | $this->error=$this->db->error(); |
||
| 1557 | $this->db->rollback(); |
||
| 1558 | return -1; |
||
| 1559 | } |
||
| 1560 | } |
||
| 1561 | |||
| 1562 | |||
| 1563 | /** |
||
| 1564 | * Ajoute une ligne de facture (associe a aucun produit/service predefini) |
||
| 1565 | * Les parametres sont deja cense etre juste et avec valeurs finales a l'appel |
||
| 1566 | * de cette methode. Aussi, pour le taux tva, il doit deja avoir ete defini |
||
| 1567 | * par l'appelant par la methode get_default_tva(societe_vendeuse,societe_acheteuse,idprod) |
||
| 1568 | * et le desc doit deja avoir la bonne valeur (a l'appelant de gerer le multilangue). |
||
| 1569 | * |
||
| 1570 | * @param string $desc Description de la ligne |
||
| 1571 | * @param double $pu Prix unitaire (HT ou TTC selon price_base_type, > 0 even for credit note) |
||
| 1572 | * @param double $txtva Force Vat rate to use, -1 for auto. |
||
| 1573 | * @param double $txlocaltax1 LocalTax1 Rate |
||
| 1574 | * @param double $txlocaltax2 LocalTax2 Rate |
||
| 1575 | * @param double $qty Quantite |
||
| 1576 | * @param int $fk_product Product/Service ID predefined |
||
| 1577 | * @param double $remise_percent Percentage discount of the line |
||
| 1578 | * @param integer $date_start Date de debut de validite du service |
||
| 1579 | * @param integer $date_end Date de fin de validite du service |
||
| 1580 | * @param string $ventil Code de ventilation comptable |
||
| 1581 | * @param int $info_bits Bits de type de lines |
||
| 1582 | * @param string $price_base_type HT ou TTC |
||
| 1583 | * @param int $type Type of line (0=product, 1=service) |
||
| 1584 | * @param int $rang Position of line |
||
| 1585 | * @param int $notrigger Disable triggers |
||
| 1586 | * @param array $array_options extrafields array |
||
| 1587 | * @param string $fk_unit Code of the unit to use. Null to use the default one |
||
| 1588 | * @param int $origin_id id origin document |
||
| 1589 | * @param double $pu_ht_devise Amount in currency |
||
| 1590 | * @param string $ref_supplier Supplier ref |
||
| 1591 | * @param string $special_code Special code |
||
| 1592 | * @return int >0 if OK, <0 if KO |
||
| 1593 | */ |
||
| 1594 | public function addline($desc, $pu, $txtva, $txlocaltax1, $txlocaltax2, $qty, $fk_product = 0, $remise_percent = 0, $date_start = '', $date_end = '', $ventil = 0, $info_bits = '', $price_base_type = 'HT', $type = 0, $rang = -1, $notrigger = false, $array_options = 0, $fk_unit = null, $origin_id = 0, $pu_ht_devise = 0, $ref_supplier = '', $special_code = '') |
||
| 1595 | { |
||
| 1596 | global $langs, $mysoc, $conf; |
||
| 1597 | |||
| 1598 | dol_syslog(get_class($this)."::addline $desc,$pu,$qty,$txtva,$fk_product,$remise_percent,$date_start,$date_end,$ventil,$info_bits,$price_base_type,$type,$fk_unit", LOG_DEBUG); |
||
| 1599 | include_once DOL_DOCUMENT_ROOT.'/core/lib/price.lib.php'; |
||
| 1600 | |||
| 1601 | if ($this->statut == self::STATUS_DRAFT) |
||
| 1602 | { |
||
| 1603 | // Clean parameters |
||
| 1604 | if (empty($remise_percent)) $remise_percent=0; |
||
| 1605 | if (empty($qty)) $qty=0; |
||
| 1606 | if (empty($info_bits)) $info_bits=0; |
||
| 1607 | if (empty($rang)) $rang=0; |
||
| 1608 | if (empty($ventil)) $ventil=0; |
||
| 1609 | if (empty($txtva)) $txtva=0; |
||
| 1610 | if (empty($txlocaltax1)) $txlocaltax1=0; |
||
| 1611 | if (empty($txlocaltax2)) $txlocaltax2=0; |
||
| 1612 | |||
| 1613 | $remise_percent=price2num($remise_percent); |
||
| 1614 | $qty=price2num($qty); |
||
| 1615 | $pu=price2num($pu); |
||
| 1616 | $txlocaltax1=price2num($txlocaltax1); |
||
| 1617 | $txlocaltax2=price2num($txlocaltax2); |
||
| 1618 | if (!preg_match('/\((.*)\)/', $txtva)) { |
||
| 1619 | $txtva = price2num($txtva); // $txtva can have format '5,1' or '5.1' or '5.1(XXX)', we must clean only if '5,1' |
||
| 1620 | } |
||
| 1621 | |||
| 1622 | if ($date_start && $date_end && $date_start > $date_end) { |
||
| 1623 | $langs->load("errors"); |
||
| 1624 | $this->error=$langs->trans('ErrorStartDateGreaterEnd'); |
||
| 1625 | return -1; |
||
| 1626 | } |
||
| 1627 | |||
| 1628 | $this->db->begin(); |
||
| 1629 | |||
| 1630 | if ($fk_product > 0) |
||
| 1631 | { |
||
| 1632 | if (! empty($conf->global->SUPPLIER_INVOICE_WITH_PREDEFINED_PRICES_ONLY)) |
||
| 1633 | { |
||
| 1634 | // Check quantity is enough |
||
| 1635 | dol_syslog(get_class($this)."::addline we check supplier prices fk_product=".$fk_product." qty=".$qty." ref_supplier=".$ref_supplier); |
||
| 1636 | $prod = new Product($this->db, $fk_product); |
||
|
1 ignored issue
–
show
|
|||
| 1637 | if ($prod->fetch($fk_product) > 0) |
||
| 1638 | { |
||
| 1639 | $product_type = $prod->type; |
||
| 1640 | $label = $prod->label; |
||
| 1641 | $fk_prod_fourn_price = 0; |
||
| 1642 | |||
| 1643 | // We use 'none' instead of $ref_supplier, because $ref_supplier may not exists anymore. So we will take the first supplier price ok. |
||
| 1644 | // If we want a dedicated supplier price, we must provide $fk_prod_fourn_price. |
||
| 1645 | $result=$prod->get_buyprice($fk_prod_fourn_price, $qty, $fk_product, 'none', ($this->fk_soc?$this->fk_soc:$this->socid)); // Search on couple $fk_prod_fourn_price/$qty first, then on triplet $qty/$fk_product/$ref_supplier/$this->fk_soc |
||
| 1646 | if ($result > 0) |
||
| 1647 | { |
||
| 1648 | $pu = $prod->fourn_pu; // Unit price supplier price set by get_buyprice |
||
| 1649 | $ref_supplier = $prod->ref_supplier; // Ref supplier price set by get_buyprice |
||
| 1650 | // is remise percent not keyed but present for the product we add it |
||
| 1651 | if ($remise_percent == 0 && $prod->remise_percent !=0) |
||
| 1652 | $remise_percent =$prod->remise_percent; |
||
| 1653 | } |
||
| 1654 | if ($result == 0) // If result == 0, we failed to found the supplier reference price |
||
| 1655 | { |
||
| 1656 | $langs->load("errors"); |
||
| 1657 | $this->error = "Ref " . $prod->ref . " " . $langs->trans("ErrorQtyTooLowForThisSupplier"); |
||
| 1658 | $this->db->rollback(); |
||
| 1659 | dol_syslog(get_class($this)."::addline we did not found supplier price, so we can't guess unit price"); |
||
| 1660 | //$pu = $prod->fourn_pu; // We do not overwrite unit price |
||
| 1661 | //$ref = $prod->ref_fourn; // We do not overwrite ref supplier price |
||
| 1662 | return -1; |
||
| 1663 | } |
||
| 1664 | if ($result == -1) |
||
| 1665 | { |
||
| 1666 | $langs->load("errors"); |
||
| 1667 | $this->error = "Ref " . $prod->ref . " " . $langs->trans("ErrorQtyTooLowForThisSupplier"); |
||
| 1668 | $this->db->rollback(); |
||
| 1669 | dol_syslog(get_class($this)."::addline result=".$result." - ".$this->error, LOG_DEBUG); |
||
| 1670 | return -1; |
||
| 1671 | } |
||
| 1672 | if ($result < -1) |
||
| 1673 | { |
||
| 1674 | $this->error=$prod->error; |
||
| 1675 | $this->db->rollback(); |
||
| 1676 | dol_syslog(get_class($this)."::addline result=".$result." - ".$this->error, LOG_ERR); |
||
| 1677 | return -1; |
||
| 1678 | } |
||
| 1679 | } |
||
| 1680 | else |
||
| 1681 | { |
||
| 1682 | $this->error=$prod->error; |
||
| 1683 | $this->db->rollback(); |
||
| 1684 | return -1; |
||
| 1685 | } |
||
| 1686 | } |
||
| 1687 | } |
||
| 1688 | else |
||
| 1689 | { |
||
| 1690 | $product_type = $type; |
||
| 1691 | } |
||
| 1692 | |||
| 1693 | if ($conf->multicurrency->enabled && $pu_ht_devise > 0) { |
||
| 1694 | $pu = 0; |
||
| 1695 | } |
||
| 1696 | |||
| 1697 | $localtaxes_type=getLocalTaxesFromRate($txtva, 0, $mysoc, $this->thirdparty); |
||
| 1698 | |||
| 1699 | // Clean vat code |
||
| 1700 | $vat_src_code=''; |
||
| 1701 | if (preg_match('/\((.*)\)/', $txtva, $reg)) |
||
| 1702 | { |
||
| 1703 | $vat_src_code = $reg[1]; |
||
| 1704 | $txtva = preg_replace('/\s*\(.*\)/', '', $txtva); // Remove code into vatrate. |
||
| 1705 | } |
||
| 1706 | |||
| 1707 | // Calcul du total TTC et de la TVA pour la ligne a partir de |
||
| 1708 | // qty, pu, remise_percent et txtva |
||
| 1709 | // TRES IMPORTANT: C'est au moment de l'insertion ligne qu'on doit stocker |
||
| 1710 | // la part ht, tva et ttc, et ce au niveau de la ligne qui a son propre taux tva. |
||
| 1711 | |||
| 1712 | $tabprice = calcul_price_total($qty, $pu, $remise_percent, $txtva, $txlocaltax1, $txlocaltax2, 0, $price_base_type, $info_bits, $type, $this->thirdparty, $localtaxes_type, 100, $this->multicurrency_tx, $pu_ht_devise); |
||
| 1713 | $total_ht = $tabprice[0]; |
||
| 1714 | $total_tva = $tabprice[1]; |
||
| 1715 | $total_ttc = $tabprice[2]; |
||
| 1716 | $total_localtax1 = $tabprice[9]; |
||
| 1717 | $total_localtax2 = $tabprice[10]; |
||
| 1718 | $pu_ht = $tabprice[3]; |
||
| 1719 | |||
| 1720 | // MultiCurrency |
||
| 1721 | $multicurrency_total_ht = $tabprice[16]; |
||
| 1722 | $multicurrency_total_tva = $tabprice[17]; |
||
| 1723 | $multicurrency_total_ttc = $tabprice[18]; |
||
| 1724 | $pu_ht_devise = $tabprice[19]; |
||
| 1725 | |||
| 1726 | // Check parameters |
||
| 1727 | if ($type < 0) return -1; |
||
| 1728 | |||
| 1729 | if ($rang < 0) |
||
| 1730 | { |
||
| 1731 | $rangmax = $this->line_max(); |
||
| 1732 | $rang = $rangmax + 1; |
||
| 1733 | } |
||
| 1734 | |||
| 1735 | // Insert line |
||
| 1736 | $this->line=new SupplierInvoiceLine($this->db); |
||
| 1737 | |||
| 1738 | $this->line->context = $this->context; |
||
| 1739 | |||
| 1740 | $this->line->fk_facture_fourn=$this->id; |
||
| 1741 | //$this->line->label=$label; // deprecated |
||
| 1742 | $this->line->desc=$desc; |
||
| 1743 | $this->line->ref_supplier=$ref_supplier; |
||
| 1744 | |||
| 1745 | $this->line->qty= ($this->type==self::TYPE_CREDIT_NOTE?abs($qty):$qty); // For credit note, quantity is always positive and unit price negative |
||
| 1746 | $this->line->subprice= ($this->type==self::TYPE_CREDIT_NOTE?-abs($pu_ht):$pu_ht); // For credit note, unit price always negative, always positive otherwise |
||
| 1747 | |||
| 1748 | $this->line->vat_src_code=$vat_src_code; |
||
| 1749 | $this->line->tva_tx=$txtva; |
||
| 1750 | $this->line->localtax1_tx=($total_localtax1?$localtaxes_type[1]:0); |
||
| 1751 | $this->line->localtax2_tx=($total_localtax2?$localtaxes_type[3]:0); |
||
| 1752 | $this->line->localtax1_type = $localtaxes_type[0]; |
||
| 1753 | $this->line->localtax2_type = $localtaxes_type[2]; |
||
| 1754 | |||
| 1755 | $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 |
||
| 1756 | $this->line->total_tva= (($this->type==self::TYPE_CREDIT_NOTE||$qty<0)?-abs($total_tva):$total_tva); |
||
| 1757 | $this->line->total_localtax1=(($this->type==self::TYPE_CREDIT_NOTE||$qty<0)?-abs($total_localtax1):$total_localtax1); |
||
| 1758 | $this->line->total_localtax2=(($this->type==self::TYPE_CREDIT_NOTE||$qty<0)?-abs($total_localtax2):$total_localtax2); |
||
| 1759 | $this->line->total_ttc= (($this->type==self::TYPE_CREDIT_NOTE||$qty<0)?-abs($total_ttc):$total_ttc); |
||
| 1760 | |||
| 1761 | $this->line->fk_product=$fk_product; |
||
| 1762 | $this->line->product_type=$type; |
||
| 1763 | $this->line->remise_percent=$remise_percent; |
||
| 1764 | $this->line->date_start=$date_start; |
||
| 1765 | $this->line->date_end=$date_end; |
||
| 1766 | $this->line->ventil=$ventil; |
||
| 1767 | $this->line->rang=$rang; |
||
| 1768 | $this->line->info_bits=$info_bits; |
||
| 1769 | |||
| 1770 | $this->line->special_code=((string) $special_code != '' ? $special_code : $this->special_code); |
||
| 1771 | $this->line->fk_parent_line=$this->fk_parent_line; |
||
| 1772 | $this->line->origin=$this->origin; |
||
| 1773 | $this->line->origin_id=$origin_id; |
||
| 1774 | $this->line->fk_unit=$fk_unit; |
||
| 1775 | |||
| 1776 | // Multicurrency |
||
| 1777 | $this->line->fk_multicurrency = $this->fk_multicurrency; |
||
| 1778 | $this->line->multicurrency_code = $this->multicurrency_code; |
||
| 1779 | $this->line->multicurrency_subprice = $pu_ht_devise; |
||
| 1780 | $this->line->multicurrency_total_ht = $multicurrency_total_ht; |
||
| 1781 | $this->line->multicurrency_total_tva = $multicurrency_total_tva; |
||
| 1782 | $this->line->multicurrency_total_ttc = $multicurrency_total_ttc; |
||
| 1783 | |||
| 1784 | if (is_array($array_options) && count($array_options)>0) { |
||
| 1785 | $this->line->array_options=$array_options; |
||
| 1786 | } |
||
| 1787 | |||
| 1788 | $result=$this->line->insert($notrigger); |
||
| 1789 | if ($result > 0) |
||
| 1790 | { |
||
| 1791 | // Reorder if child line |
||
| 1792 | if (! empty($fk_parent_line)) $this->line_order(true, 'DESC'); |
||
| 1793 | |||
| 1794 | // Mise a jour informations denormalisees au niveau de la facture meme |
||
| 1795 | $result=$this->update_price(1, 'auto', 0, $this->thirdparty); // The addline method is designed to add line from user input so total calculation with update_price must be done using 'auto' mode. |
||
| 1796 | if ($result > 0) |
||
| 1797 | { |
||
| 1798 | $this->db->commit(); |
||
| 1799 | return $this->line->id; |
||
| 1800 | } |
||
| 1801 | else |
||
| 1802 | { |
||
| 1803 | $this->error=$this->db->error(); |
||
| 1804 | $this->db->rollback(); |
||
| 1805 | return -1; |
||
| 1806 | } |
||
| 1807 | } |
||
| 1808 | else |
||
| 1809 | { |
||
| 1810 | $this->error=$this->line->error; |
||
| 1811 | $this->errors=$this->line->errors; |
||
| 1812 | $this->db->rollback(); |
||
| 1813 | return -2; |
||
| 1814 | } |
||
| 1815 | } |
||
| 1816 | else |
||
| 1817 | { |
||
| 1818 | return 0; |
||
| 1819 | } |
||
| 1820 | } |
||
| 1821 | |||
| 1822 | /** |
||
| 1823 | * Update a line detail into database |
||
| 1824 | * |
||
| 1825 | * @param int $id Id of line invoice |
||
| 1826 | * @param string $desc Description of line |
||
| 1827 | * @param double $pu Prix unitaire (HT ou TTC selon price_base_type) |
||
| 1828 | * @param double $vatrate VAT Rate (Can be '8.5', '8.5 (ABC)') |
||
| 1829 | * @param double $txlocaltax1 LocalTax1 Rate |
||
| 1830 | * @param double $txlocaltax2 LocalTax2 Rate |
||
| 1831 | * @param double $qty Quantity |
||
| 1832 | * @param int $idproduct Id produit |
||
| 1833 | * @param double $price_base_type HT or TTC |
||
| 1834 | * @param int $info_bits Miscellaneous informations of line |
||
| 1835 | * @param int $type Type of line (0=product, 1=service) |
||
| 1836 | * @param double $remise_percent Percentage discount of the line |
||
| 1837 | * @param int $notrigger Disable triggers |
||
| 1838 | * @param integer $date_start Date start of service |
||
| 1839 | * @param integer $date_end Date end of service |
||
| 1840 | * @param array $array_options extrafields array |
||
| 1841 | * @param string $fk_unit Code of the unit to use. Null to use the default one |
||
| 1842 | * @param double $pu_ht_devise Amount in currency |
||
| 1843 | * @param string $ref_supplier Supplier ref |
||
| 1844 | * @return int <0 if KO, >0 if OK |
||
| 1845 | */ |
||
| 1846 | public 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, $pu_ht_devise = 0, $ref_supplier = '') |
||
| 1971 | } |
||
| 1972 | |||
| 1973 | /** |
||
| 1974 | * Delete a detail line from database |
||
| 1975 | * |
||
| 1976 | * @param int $rowid Id of line to delete |
||
| 1977 | * @param int $notrigger 1=Does not execute triggers, 0= execute triggers |
||
| 1978 | * @return int <0 if KO, >0 if OK |
||
| 1979 | */ |
||
| 1980 | public function deleteline($rowid, $notrigger = 0) |
||
| 1981 | { |
||
| 1982 | if (!$rowid) { |
||
| 1983 | $rowid = $this->id; |
||
| 1984 | } |
||
| 1985 | |||
| 1986 | $this->db->begin(); |
||
| 1987 | |||
| 1988 | // Libere remise liee a ligne de facture |
||
| 1989 | $sql = 'UPDATE ' . MAIN_DB_PREFIX . 'societe_remise_except'; |
||
| 1990 | $sql .= ' SET fk_invoice_supplier_line = NULL'; |
||
| 1991 | $sql .= ' WHERE fk_invoice_supplier_line = ' . $rowid; |
||
| 1992 | |||
| 1993 | dol_syslog(get_class($this) . "::deleteline", LOG_DEBUG); |
||
| 1994 | $result = $this->db->query($sql); |
||
| 1995 | if (! $result) |
||
| 1996 | { |
||
| 1997 | $this->error = $this->db->error(); |
||
| 1998 | $this->db->rollback(); |
||
| 1999 | return - 2; |
||
| 2000 | } |
||
| 2001 | |||
| 2002 | $line = new SupplierInvoiceLine($this->db); |
||
| 2003 | |||
| 2004 | if ($line->fetch($rowid) < 1) { |
||
| 2005 | return -1; |
||
| 2006 | } |
||
| 2007 | |||
| 2008 | $res = $line->delete($notrigger); |
||
| 2009 | |||
| 2010 | if ($res < 1) { |
||
| 2011 | $this->errors[] = $line->error; |
||
| 2012 | $this->db->rollback(); |
||
| 2013 | return - 3; |
||
| 2014 | } else { |
||
| 2015 | $res = $this->update_price(); |
||
| 2016 | |||
| 2017 | if ($res > 0) |
||
| 2018 | { |
||
| 2019 | $this->db->commit(); |
||
| 2020 | return 1; |
||
| 2021 | } |
||
| 2022 | else |
||
| 2023 | { |
||
| 2024 | $this->db->rollback(); |
||
| 2025 | $this->error = $this->db->lasterror(); |
||
| 2026 | return - 4; |
||
| 2027 | } |
||
| 2028 | } |
||
| 2029 | } |
||
| 2030 | |||
| 2031 | |||
| 2032 | /** |
||
| 2033 | * Charge les informations d'ordre info dans l'objet facture |
||
| 2034 | * |
||
| 2035 | * @param int $id Id de la facture a charger |
||
| 2036 | * @return void |
||
| 2037 | */ |
||
| 2038 | public function info($id) |
||
| 2079 | } |
||
| 2080 | } |
||
| 2081 | |||
| 2082 | // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps |
||
| 2083 | /** |
||
| 2084 | * Renvoi liste des factures remplacables |
||
| 2085 | * Statut validee ou abandonnee pour raison autre + non payee + aucun paiement + pas deja remplacee |
||
| 2086 | * |
||
| 2087 | * @param int $socid Id societe |
||
| 2088 | * @return array|int Tableau des factures ('id'=>id, 'ref'=>ref, 'status'=>status, 'paymentornot'=>0/1) |
||
| 2089 | * <0 if error |
||
| 2090 | */ |
||
| 2091 | public function list_replacable_supplier_invoices($socid = 0) |
||
| 2092 | { |
||
| 2093 | // phpcs:enable |
||
| 2094 | global $conf; |
||
| 2095 | |||
| 2096 | $return = array(); |
||
| 2097 | |||
| 2098 | $sql = "SELECT f.rowid as rowid, f.ref, f.fk_statut,"; |
||
| 2099 | $sql.= " ff.rowid as rowidnext"; |
||
| 2100 | $sql.= " FROM ".MAIN_DB_PREFIX."facture_fourn as f"; |
||
| 2101 | $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."paiementfourn_facturefourn as pf ON f.rowid = pf.fk_facturefourn"; |
||
| 2102 | $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."facture_fourn as ff ON f.rowid = ff.fk_facture_source"; |
||
| 2103 | $sql.= " WHERE (f.fk_statut = ".self::STATUS_VALIDATED." OR (f.fk_statut = ".self::STATUS_ABANDONED." AND f.close_code = '".self::CLOSECODE_ABANDONED."'))"; |
||
| 2104 | $sql.= " AND f.entity = ".$conf->entity; |
||
| 2105 | $sql.= " AND f.paye = 0"; // Pas classee payee completement |
||
| 2106 | $sql.= " AND pf.fk_paiementfourn IS NULL"; // Aucun paiement deja fait |
||
| 2107 | $sql.= " AND ff.fk_statut IS NULL"; // Renvoi vrai si pas facture de remplacement |
||
| 2108 | if ($socid > 0) $sql.=" AND f.fk_soc = ".$socid; |
||
| 2109 | $sql.= " ORDER BY f.ref"; |
||
| 2110 | |||
| 2111 | dol_syslog(get_class($this)."::list_replacable_supplier_invoices", LOG_DEBUG); |
||
| 2112 | $resql=$this->db->query($sql); |
||
| 2113 | if ($resql) |
||
| 2114 | { |
||
| 2115 | while ($obj=$this->db->fetch_object($resql)) |
||
| 2116 | { |
||
| 2117 | $return[$obj->rowid]=array( |
||
| 2118 | 'id' => $obj->rowid, |
||
| 2119 | 'ref' => $obj->ref, |
||
| 2120 | 'status' => $obj->fk_statut |
||
| 2121 | ); |
||
| 2122 | } |
||
| 2123 | //print_r($return); |
||
| 2124 | return $return; |
||
| 2125 | } |
||
| 2126 | else |
||
| 2127 | { |
||
| 2128 | $this->error=$this->db->error(); |
||
| 2129 | return -1; |
||
| 2130 | } |
||
| 2131 | } |
||
| 2132 | |||
| 2133 | // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps |
||
| 2134 | /** |
||
| 2135 | * Renvoi liste des factures qualifiables pour correction par avoir |
||
| 2136 | * Les factures qui respectent les regles suivantes sont retournees: |
||
| 2137 | * (validee + paiement en cours) ou classee (payee completement ou payee partiellement) + pas deja remplacee + pas deja avoir |
||
| 2138 | * |
||
| 2139 | * @param int $socid Id societe |
||
| 2140 | * @return array|int Tableau des factures ($id => array('ref'=>,'paymentornot'=>,'status'=>,'paye'=>) |
||
| 2141 | * <0 if error |
||
| 2142 | */ |
||
| 2143 | public function list_qualified_avoir_supplier_invoices($socid = 0) |
||
| 2144 | { |
||
| 2145 | // phpcs:enable |
||
| 2146 | global $conf; |
||
| 2147 | |||
| 2148 | $return = array(); |
||
| 2149 | |||
| 2150 | $sql = "SELECT f.rowid as rowid, f.ref, f.fk_statut, f.type, f.paye, pf.fk_paiementfourn"; |
||
| 2151 | $sql.= " FROM ".MAIN_DB_PREFIX."facture_fourn as f"; |
||
| 2152 | $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."paiementfourn_facturefourn as pf ON f.rowid = pf.fk_facturefourn"; |
||
| 2153 | $sql.= " WHERE f.entity = ".$conf->entity; |
||
| 2154 | $sql.= " AND f.fk_statut in (".self::STATUS_VALIDATED.",".self::STATUS_CLOSED.")"; |
||
| 2155 | $sql.= " AND NOT EXISTS (SELECT rowid from ".MAIN_DB_PREFIX."facture_fourn as ff WHERE f.rowid = ff.fk_facture_source"; |
||
| 2156 | $sql.= " AND ff.type=".self::TYPE_REPLACEMENT.")"; |
||
| 2157 | $sql.= " AND f.type != ".self::TYPE_CREDIT_NOTE; // Type non 2 si facture non avoir |
||
| 2158 | if ($socid > 0) $sql.=" AND f.fk_soc = ".$socid; |
||
| 2159 | $sql.= " ORDER BY f.ref"; |
||
| 2160 | |||
| 2161 | dol_syslog(get_class($this)."::list_qualified_avoir_supplier_invoices", LOG_DEBUG); |
||
| 2162 | $resql=$this->db->query($sql); |
||
| 2163 | if ($resql) |
||
| 2164 | { |
||
| 2165 | while ($obj=$this->db->fetch_object($resql)) |
||
| 2166 | { |
||
| 2167 | $qualified=0; |
||
| 2168 | if ($obj->fk_statut == self::STATUS_VALIDATED) $qualified=1; |
||
| 2169 | if ($obj->fk_statut == self::STATUS_CLOSED) $qualified=1; |
||
| 2170 | if ($qualified) |
||
| 2171 | { |
||
| 2172 | $paymentornot=($obj->fk_paiementfourn?1:0); |
||
| 2173 | $return[$obj->rowid]=array('ref'=>$obj->ref,'status'=>$obj->fk_statut,'type'=>$obj->type,'paye'=>$obj->paye,'paymentornot'=>$paymentornot); |
||
| 2174 | } |
||
| 2175 | } |
||
| 2176 | |||
| 2177 | return $return; |
||
| 2178 | } |
||
| 2179 | else |
||
| 2180 | { |
||
| 2181 | $this->error=$this->db->error(); |
||
| 2182 | return -1; |
||
| 2183 | } |
||
| 2184 | } |
||
| 2185 | |||
| 2186 | // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps |
||
| 2187 | /** |
||
| 2188 | * Load indicators for dashboard (this->nbtodo and this->nbtodolate) |
||
| 2189 | * |
||
| 2190 | * @param User $user Object user |
||
| 2191 | * @return WorkboardResponse|int <0 if KO, WorkboardResponse if OK |
||
| 2192 | */ |
||
| 2193 | public function load_board($user) |
||
| 2194 | { |
||
| 2195 | // phpcs:enable |
||
| 2196 | global $conf, $langs; |
||
| 2197 | |||
| 2198 | $sql = 'SELECT ff.rowid, ff.date_lim_reglement as datefin, ff.fk_statut'; |
||
| 2199 | $sql.= ' FROM '.MAIN_DB_PREFIX.'facture_fourn as ff'; |
||
| 2200 | if (!$user->rights->societe->client->voir && !$user->societe_id) $sql.= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; |
||
|
1 ignored issue
–
show
|
|||
| 2201 | $sql.= ' WHERE ff.paye=0'; |
||
| 2202 | $sql.= ' AND ff.fk_statut > 0'; |
||
| 2203 | $sql.= " AND ff.entity = ".$conf->entity; |
||
| 2204 | if ($user->societe_id) $sql.=' AND ff.fk_soc = '.$user->societe_id; |
||
|
1 ignored issue
–
show
|
|||
| 2205 | if (!$user->rights->societe->client->voir && !$user->societe_id) $sql.= " AND ff.fk_soc = sc.fk_soc AND sc.fk_user = ".$user->id; |
||
|
1 ignored issue
–
show
|
|||
| 2206 | |||
| 2207 | $resql=$this->db->query($sql); |
||
| 2208 | if ($resql) |
||
| 2209 | { |
||
| 2210 | $langs->load("bills"); |
||
| 2211 | $now=dol_now(); |
||
| 2212 | |||
| 2213 | $response = new WorkboardResponse(); |
||
| 2214 | $response->warning_delay=$conf->facture->fournisseur->warning_delay/60/60/24; |
||
| 2215 | $response->label=$langs->trans("SupplierBillsToPay"); |
||
| 2216 | |||
| 2217 | $response->url=DOL_URL_ROOT.'/fourn/facture/list.php?search_status=1&mainmenu=billing&leftmenu=suppliers_bills'; |
||
| 2218 | $response->img=img_object($langs->trans("Bills"), "bill"); |
||
| 2219 | |||
| 2220 | $facturestatic = new FactureFournisseur($this->db); |
||
| 2221 | |||
| 2222 | while ($obj=$this->db->fetch_object($resql)) |
||
| 2223 | { |
||
| 2224 | $response->nbtodo++; |
||
| 2225 | |||
| 2226 | $facturestatic->date_echeance = $this->db->jdate($obj->datefin); |
||
| 2227 | $facturestatic->statut = $obj->fk_statut; |
||
| 2228 | |||
| 2229 | if ($facturestatic->hasDelay()) { |
||
| 2230 | $response->nbtodolate++; |
||
| 2231 | } |
||
| 2232 | } |
||
| 2233 | $this->db->free($resql); |
||
| 2234 | return $response; |
||
| 2235 | } |
||
| 2236 | else |
||
| 2237 | { |
||
| 2238 | dol_print_error($this->db); |
||
| 2239 | $this->error=$this->db->error(); |
||
| 2240 | return -1; |
||
| 2241 | } |
||
| 2242 | } |
||
| 2243 | |||
| 2244 | |||
| 2245 | /** |
||
| 2246 | * Return clicable name (with picto eventually) |
||
| 2247 | * |
||
| 2248 | * @param int $withpicto 0=No picto, 1=Include picto into link, 2=Only picto |
||
| 2249 | * @param string $option Where point the link |
||
| 2250 | * @param int $max Max length of shown ref |
||
| 2251 | * @param int $short 1=Return just URL |
||
| 2252 | * @param string $moretitle Add more text to title tooltip |
||
| 2253 | * @param int $notooltip 1=Disable tooltip |
||
| 2254 | * @param int $save_lastsearch_value -1=Auto, 0=No save of lastsearch_values when clicking, 1=Save lastsearch_values whenclicking |
||
| 2255 | * @return string String with URL |
||
| 2256 | */ |
||
| 2257 | public function getNomUrl($withpicto = 0, $option = '', $max = 0, $short = 0, $moretitle = '', $notooltip = 0, $save_lastsearch_value = -1) |
||
| 2258 | { |
||
| 2259 | global $langs, $conf; |
||
| 2260 | |||
| 2261 | $result=''; |
||
| 2262 | |||
| 2263 | if ($option == 'document') $url = DOL_URL_ROOT.'/fourn/facture/document.php?facid='.$this->id; |
||
| 2264 | else $url = DOL_URL_ROOT.'/fourn/facture/card.php?facid='.$this->id; |
||
| 2265 | |||
| 2266 | if ($short) return $url; |
||
| 2267 | |||
| 2268 | if ($option !== 'nolink') |
||
| 2269 | { |
||
| 2270 | // Add param to save lastsearch_values or not |
||
| 2271 | $add_save_lastsearch_values=($save_lastsearch_value == 1 ? 1 : 0); |
||
| 2272 | if ($save_lastsearch_value == -1 && preg_match('/list\.php/', $_SERVER["PHP_SELF"])) $add_save_lastsearch_values=1; |
||
| 2273 | if ($add_save_lastsearch_values) $url.='&save_lastsearch_values=1'; |
||
| 2274 | } |
||
| 2275 | |||
| 2276 | $picto=$this->picto; |
||
| 2277 | if ($this->type == self::TYPE_REPLACEMENT) $picto.='r'; // Replacement invoice |
||
| 2278 | if ($this->type == self::TYPE_CREDIT_NOTE) $picto.='a'; // Credit note |
||
| 2279 | if ($this->type == self::TYPE_DEPOSIT) $picto.='d'; // Deposit invoice |
||
| 2280 | |||
| 2281 | $label = '<u>' . $langs->trans("ShowSupplierInvoice") . '</u>'; |
||
| 2282 | if (! empty($this->ref)) |
||
| 2283 | $label .= '<br><b>' . $langs->trans('Ref') . ':</b> ' . $this->ref; |
||
| 2284 | if (! empty($this->ref_supplier)) |
||
| 2285 | $label.= '<br><b>' . $langs->trans('RefSupplier') . ':</b> ' . $this->ref_supplier; |
||
| 2286 | if (! empty($this->label)) |
||
| 2287 | $label.= '<br><b>' . $langs->trans('Label') . ':</b> ' . $this->label; |
||
| 2288 | if (! empty($this->date)) |
||
| 2289 | $label .= '<br><b>' . $langs->trans('Date') . ':</b> ' . dol_print_date($this->date, 'day'); |
||
| 2290 | if (! empty($this->total_ht)) |
||
| 2291 | $label.= '<br><b>' . $langs->trans('AmountHT') . ':</b> ' . price($this->total_ht, 0, $langs, 0, -1, -1, $conf->currency); |
||
| 2292 | if (! empty($this->total_tva)) |
||
| 2293 | $label.= '<br><b>' . $langs->trans('VAT') . ':</b> ' . price($this->total_tva, 0, $langs, 0, -1, -1, $conf->currency); |
||
| 2294 | if (! empty($this->total_ttc)) |
||
| 2295 | $label.= '<br><b>' . $langs->trans('AmountTTC') . ':</b> ' . price($this->total_ttc, 0, $langs, 0, -1, -1, $conf->currency); |
||
| 2296 | if ($this->type == self::TYPE_REPLACEMENT) $label=$langs->transnoentitiesnoconv("ShowInvoiceReplace").': '.$this->ref; |
||
| 2297 | elseif ($this->type == self::TYPE_CREDIT_NOTE) $label=$langs->transnoentitiesnoconv("ShowInvoiceAvoir").': '.$this->ref; |
||
| 2298 | elseif ($this->type == self::TYPE_DEPOSIT) $label=$langs->transnoentitiesnoconv("ShowInvoiceDeposit").': '.$this->ref; |
||
| 2299 | if ($moretitle) $label.=' - '.$moretitle; |
||
| 2300 | |||
| 2301 | $ref=$this->ref; |
||
| 2302 | if (empty($ref)) $ref=$this->id; |
||
| 2303 | |||
| 2304 | $linkclose=''; |
||
| 2305 | if (empty($notooltip)) |
||
| 2306 | { |
||
| 2307 | if (! empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) |
||
| 2308 | { |
||
| 2309 | $label=$langs->trans("ShowSupplierInvoice"); |
||
| 2310 | $linkclose.=' alt="'.dol_escape_htmltag($label, 1).'"'; |
||
| 2311 | } |
||
| 2312 | $linkclose.= ' title="'.dol_escape_htmltag($label, 1).'"'; |
||
| 2313 | $linkclose.=' class="classfortooltip"'; |
||
| 2314 | } |
||
| 2315 | |||
| 2316 | $linkstart = '<a href="'.$url.'"'; |
||
| 2317 | $linkstart.=$linkclose.'>'; |
||
| 2318 | $linkend='</a>'; |
||
| 2319 | |||
| 2320 | $result .= $linkstart; |
||
| 2321 | if ($withpicto) $result.=img_object(($notooltip?'':$label), $picto, ($notooltip?(($withpicto != 2) ? 'class="paddingright"' : ''):'class="'.(($withpicto != 2) ? 'paddingright ' : '').'classfortooltip"'), 0, 0, $notooltip?0:1); |
||
| 2322 | if ($withpicto != 2) $result.= ($max?dol_trunc($ref, $max):$ref); |
||
| 2323 | $result .= $linkend; |
||
| 2324 | |||
| 2325 | return $result; |
||
| 2326 | } |
||
| 2327 | |||
| 2328 | /** |
||
| 2329 | * Return next reference of supplier invoice not already used (or last reference) |
||
| 2330 | * according to numbering module defined into constant INVOICE_SUPPLIER_ADDON_NUMBER |
||
| 2331 | * |
||
| 2332 | * @param Societe $soc Thirdparty object |
||
| 2333 | * @param string $mode 'next' for next value or 'last' for last value |
||
| 2334 | * @return string free ref or last ref |
||
| 2335 | */ |
||
| 2336 | public function getNextNumRef($soc, $mode = 'next') |
||
| 2337 | { |
||
| 2338 | global $db, $langs, $conf; |
||
| 2339 | $langs->load("orders"); |
||
| 2340 | |||
| 2341 | // Clean parameters (if not defined or using deprecated value) |
||
| 2342 | if (empty($conf->global->INVOICE_SUPPLIER_ADDON_NUMBER)) $conf->global->INVOICE_SUPPLIER_ADDON_NUMBER='mod_facture_fournisseur_cactus'; |
||
| 2343 | |||
| 2344 | $mybool=false; |
||
| 2345 | |||
| 2346 | $file = $conf->global->INVOICE_SUPPLIER_ADDON_NUMBER.".php"; |
||
| 2347 | $classname = $conf->global->INVOICE_SUPPLIER_ADDON_NUMBER; |
||
| 2348 | |||
| 2349 | // Include file with class |
||
| 2350 | $dirmodels = array_merge(array('/'), (array) $conf->modules_parts['models']); |
||
| 2351 | |||
| 2352 | foreach ($dirmodels as $reldir) { |
||
| 2353 | |||
| 2354 | $dir = dol_buildpath($reldir."core/modules/supplier_invoice/"); |
||
| 2355 | |||
| 2356 | // Load file with numbering class (if found) |
||
| 2357 | $mybool|=@include_once $dir.$file; |
||
| 2358 | } |
||
| 2359 | |||
| 2360 | if ($mybool === false) { |
||
| 2361 | dol_print_error('', "Failed to include file ".$file); |
||
| 2362 | return ''; |
||
| 2363 | } |
||
| 2364 | |||
| 2365 | $obj = new $classname(); |
||
| 2366 | $numref = ""; |
||
| 2367 | $numref = $obj->getNumRef($soc, $this, $mode); |
||
| 2368 | |||
| 2369 | if ($numref != "") |
||
| 2370 | { |
||
| 2371 | return $numref; |
||
| 2372 | } |
||
| 2373 | else |
||
| 2374 | { |
||
| 2375 | $this->error=$obj->error; |
||
| 2376 | //dol_print_error($db,get_class($this)."::getNextNumRef ".$obj->error); |
||
| 2377 | return false; |
||
| 2378 | } |
||
| 2379 | } |
||
| 2380 | |||
| 2381 | |||
| 2382 | /** |
||
| 2383 | * Initialise an instance with random values. |
||
| 2384 | * Used to build previews or test instances. |
||
| 2385 | * id must be 0 if object instance is a specimen. |
||
| 2386 | * |
||
| 2387 | * @param string $option ''=Create a specimen invoice with lines, 'nolines'=No lines |
||
| 2388 | * @return void |
||
| 2389 | */ |
||
| 2390 | public function initAsSpecimen($option = '') |
||
| 2483 | } |
||
| 2484 | |||
| 2485 | // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps |
||
| 2486 | /** |
||
| 2487 | * Load indicators for dashboard (this->nbtodo and this->nbtodolate) |
||
| 2488 | * |
||
| 2489 | * @return int <0 if KO, >0 if OK |
||
| 2490 | */ |
||
| 2491 | public function load_state_board() |
||
| 2492 | { |
||
| 2493 | // phpcs:enable |
||
| 2494 | global $conf, $user; |
||
| 2495 | |||
| 2496 | $this->nb=array(); |
||
| 2497 | |||
| 2498 | $clause = "WHERE"; |
||
| 2499 | |||
| 2500 | $sql = "SELECT count(f.rowid) as nb"; |
||
| 2501 | $sql.= " FROM ".MAIN_DB_PREFIX."facture_fourn as f"; |
||
| 2502 | $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."societe as s ON f.fk_soc = s.rowid"; |
||
| 2503 | if (!$user->rights->societe->client->voir && !$user->societe_id) |
||
| 2504 | { |
||
| 2505 | $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."societe_commerciaux as sc ON s.rowid = sc.fk_soc"; |
||
| 2506 | $sql.= " WHERE sc.fk_user = " .$user->id; |
||
| 2507 | $clause = "AND"; |
||
| 2508 | } |
||
| 2509 | $sql.= " ".$clause." f.entity = ".$conf->entity; |
||
| 2510 | |||
| 2511 | $resql=$this->db->query($sql); |
||
| 2512 | if ($resql) |
||
| 2513 | { |
||
| 2514 | while ($obj=$this->db->fetch_object($resql)) |
||
| 2515 | { |
||
| 2516 | $this->nb["supplier_invoices"]=$obj->nb; |
||
| 2517 | } |
||
| 2518 | $this->db->free($resql); |
||
| 2519 | return 1; |
||
| 2520 | } |
||
| 2521 | else |
||
| 2522 | { |
||
| 2523 | dol_print_error($this->db); |
||
| 2524 | $this->error=$this->db->error(); |
||
| 2525 | return -1; |
||
| 2526 | } |
||
| 2527 | } |
||
| 2528 | |||
| 2529 | /** |
||
| 2530 | * Load an object from its id and create a new one in database |
||
| 2531 | * |
||
| 2532 | * @param User $user User that clone |
||
| 2533 | * @param int $fromid Id of object to clone |
||
| 2534 | * @param int $invertdetail Reverse sign of amounts for lines |
||
| 2535 | * @return int New id of clone |
||
| 2536 | */ |
||
| 2537 | public function createFromClone(User $user, $fromid, $invertdetail = 0) |
||
| 2538 | { |
||
| 2539 | global $langs; |
||
| 2540 | |||
| 2541 | $error=0; |
||
| 2542 | |||
| 2543 | $object=new FactureFournisseur($this->db); |
||
| 2544 | |||
| 2545 | $this->db->begin(); |
||
| 2546 | |||
| 2547 | // Load source object |
||
| 2548 | $object->fetch($fromid); |
||
| 2549 | $object->id=0; |
||
| 2550 | $object->statut=self::STATUS_DRAFT; |
||
| 2551 | |||
| 2552 | // Clear fields |
||
| 2553 | $object->ref_supplier = (empty($this->ref_supplier) ? $langs->trans("CopyOf").' '.$object->ref_supplier : $this->ref_supplier); |
||
| 2554 | $object->author = $user->id; |
||
| 2555 | $object->user_valid = ''; |
||
| 2556 | $object->fk_facture_source = 0; |
||
| 2557 | $object->date_creation = ''; |
||
| 2558 | $object->date_validation = ''; |
||
| 2559 | $object->date = (empty($this->date) ? '' : $this->date); |
||
|
1 ignored issue
–
show
|
|||
| 2560 | $object->date_echeance = ''; |
||
|
1 ignored issue
–
show
|
|||
| 2561 | $object->ref_client = ''; |
||
| 2562 | $object->close_code = ''; |
||
| 2563 | $object->close_note = ''; |
||
| 2564 | |||
| 2565 | // Loop on each line of new invoice |
||
| 2566 | foreach($object->lines as $i => $line) |
||
| 2567 | { |
||
| 2568 | if (isset($object->lines[$i]->info_bits) && ($object->lines[$i]->info_bits & 0x02) == 0x02) // We do not clone line of discounts |
||
| 2569 | { |
||
| 2570 | unset($object->lines[$i]); |
||
| 2571 | } |
||
| 2572 | } |
||
| 2573 | |||
| 2574 | // Create clone |
||
| 2575 | $object->context['createfromclone'] = 'createfromclone'; |
||
| 2576 | $result=$object->create($user); |
||
| 2577 | |||
| 2578 | // Other options |
||
| 2579 | if ($result < 0) |
||
| 2580 | { |
||
| 2581 | $this->error=$object->error; |
||
| 2582 | $error++; |
||
| 2583 | } |
||
| 2584 | |||
| 2585 | if (! $error) |
||
| 2586 | { |
||
| 2587 | |||
| 2588 | } |
||
| 2589 | |||
| 2590 | unset($object->context['createfromclone']); |
||
| 2591 | |||
| 2592 | // End |
||
| 2593 | if (! $error) |
||
| 2594 | { |
||
| 2595 | $this->db->commit(); |
||
| 2596 | return $object->id; |
||
| 2597 | } |
||
| 2598 | else |
||
| 2599 | { |
||
| 2600 | $this->db->rollback(); |
||
| 2601 | return -1; |
||
| 2602 | } |
||
| 2603 | } |
||
| 2604 | |||
| 2605 | /** |
||
| 2606 | * Create a document onto disk according to template model. |
||
| 2607 | * |
||
| 2608 | * @param string $modele Force template to use ('' to not force) |
||
| 2609 | * @param Translate $outputlangs Object lang a utiliser pour traduction |
||
| 2610 | * @param int $hidedetails Hide details of lines |
||
| 2611 | * @param int $hidedesc Hide description |
||
| 2612 | * @param int $hideref Hide ref |
||
| 2613 | * @param null|array $moreparams Array to provide more information |
||
| 2614 | * @return int <0 if KO, 0 if nothing done, >0 if OK |
||
| 2615 | */ |
||
| 2616 | public function generateDocument($modele, $outputlangs, $hidedetails = 0, $hidedesc = 0, $hideref = 0, $moreparams = null) |
||
| 2617 | { |
||
| 2618 | global $conf, $user, $langs; |
||
| 2619 | |||
| 2620 | $langs->load("suppliers"); |
||
| 2621 | |||
| 2622 | // Set the model on the model name to use |
||
| 2623 | if (empty($modele)) |
||
| 2624 | { |
||
| 2625 | if (! empty($conf->global->INVOICE_SUPPLIER_ADDON_PDF)) |
||
| 2626 | { |
||
| 2627 | $modele = $conf->global->INVOICE_SUPPLIER_ADDON_PDF; |
||
| 2628 | } |
||
| 2629 | else |
||
| 2630 | { |
||
| 2631 | $modele = ''; // No default value. For supplier invoice, we allow to disable all PDF generation |
||
| 2632 | } |
||
| 2633 | } |
||
| 2634 | |||
| 2635 | if (empty($modele)) |
||
| 2636 | { |
||
| 2637 | return 0; |
||
| 2638 | } |
||
| 2639 | else |
||
| 2640 | { |
||
| 2641 | $modelpath = "core/modules/supplier_invoice/pdf/"; |
||
| 2642 | |||
| 2643 | return $this->commonGenerateDocument($modelpath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref, $moreparams); |
||
| 2644 | } |
||
| 2645 | } |
||
| 2646 | |||
| 2647 | /** |
||
| 2648 | * Returns the rights used for this class |
||
| 2649 | * @return stdClass |
||
| 2650 | */ |
||
| 2651 | public function getRights() |
||
| 2652 | { |
||
| 2653 | global $user; |
||
| 2654 | |||
| 2655 | return $user->rights->fournisseur->facture; |
||
| 2656 | } |
||
| 2657 | |||
| 2658 | /** |
||
| 2659 | * Function used to replace a thirdparty id with another one. |
||
| 2660 | * |
||
| 2661 | * @param DoliDB $db Database handler |
||
| 2662 | * @param int $origin_id Old thirdparty id |
||
| 2663 | * @param int $dest_id New thirdparty id |
||
| 2664 | * @return bool |
||
| 2665 | */ |
||
| 2666 | public static function replaceThirdparty(DoliDB $db, $origin_id, $dest_id) |
||
| 2673 | } |
||
| 2674 | |||
| 2675 | /** |
||
| 2676 | * Is the payment of the supplier invoice having a delay? |
||
| 2677 | * |
||
| 2678 | * @return bool |
||
| 2679 | */ |
||
| 2680 | public function hasDelay() |
||
| 2681 | { |
||
| 2682 | global $conf; |
||
| 2683 | |||
| 2684 | $now = dol_now(); |
||
| 2691 | } |
||
| 2692 | } |
||
| 2693 | |||
| 2694 | |||
| 2695 | |||
| 2696 | /** |
||
| 3266 |
This property has been deprecated. The supplier of the class has supplied an explanatory message.
The explanatory message should give you some clue as to whether and when the property will be removed from the class and what other property to use instead.