35 require_once DOL_DOCUMENT_ROOT.
'/core/class/commonobject.class.php';
36 require_once DOL_DOCUMENT_ROOT.
"/core/class/commonobjectline.class.php";
37 require_once DOL_DOCUMENT_ROOT.
'/core/lib/price.lib.php';
38 require_once DOL_DOCUMENT_ROOT.
'/margin/lib/margins.lib.php';
48 public $element =
'contrat';
53 public $table_element =
'contrat';
58 public $table_element_line =
'contratdet';
63 public $fk_element =
'fk_contrat';
68 public $picto =
'contract';
74 public $ismultientitymanaged = 1;
79 public $isextrafieldmanaged = 1;
85 public $restrictiononfksoc = 1;
102 public $ref_supplier;
129 public $fk_user_author;
136 public $user_author_id;
141 public $user_creation;
146 public $user_cloture;
151 public $date_creation;
156 public $date_modification;
161 public $date_validation;
166 public $date_contrat;
168 public $commercial_signature_id;
169 public $commercial_suivi_id;
177 public $extraparams = array();
182 public $lines = array();
184 public $nbofservices;
185 public $nbofserviceswait;
186 public $nbofservicesopened;
187 public $nbofservicesexpired;
195 protected $lines_id_index_mapper = array();
226 public $fields = array(
227 'rowid' =>array(
'type'=>
'integer',
'label'=>
'TechnicalID',
'enabled'=>1,
'visible'=>-1,
'notnull'=>1,
'position'=>10),
228 'ref' =>array(
'type'=>
'varchar(50)',
'label'=>
'Ref',
'enabled'=>1,
'visible'=>-1,
'showoncombobox'=>1,
'position'=>15),
229 'ref_ext' =>array(
'type'=>
'varchar(255)',
'label'=>
'Ref ext',
'enabled'=>1,
'visible'=>0,
'position'=>20),
230 'ref_supplier' =>array(
'type'=>
'varchar(50)',
'label'=>
'Ref supplier',
'enabled'=>1,
'visible'=>-1,
'position'=>25),
231 'entity' =>array(
'type'=>
'integer',
'label'=>
'Entity',
'default'=>1,
'enabled'=>1,
'visible'=>-2,
'notnull'=>1,
'position'=>30,
'index'=>1),
232 'tms' =>array(
'type'=>
'timestamp',
'label'=>
'DateModification',
'enabled'=>1,
'visible'=>-1,
'notnull'=>1,
'position'=>35),
233 'datec' =>array(
'type'=>
'datetime',
'label'=>
'DateCreation',
'enabled'=>1,
'visible'=>-1,
'position'=>40),
234 'date_contrat' =>array(
'type'=>
'datetime',
'label'=>
'Date contrat',
'enabled'=>1,
'visible'=>-1,
'position'=>45),
235 'fk_soc' =>array(
'type'=>
'integer:Societe:societe/class/societe.class.php',
'label'=>
'ThirdParty',
'enabled'=>
'$conf->societe->enabled',
'visible'=>-1,
'notnull'=>1,
'position'=>70),
236 'fk_projet' =>array(
'type'=>
'integer:Project:projet/class/project.class.php:1:fk_statut=1',
'label'=>
'Project',
'enabled'=>
'$conf->project->enabled',
'visible'=>-1,
'position'=>75),
237 'fk_commercial_signature' =>array(
'type'=>
'integer:User:user/class/user.class.php',
'label'=>
'SaleRepresentative Signature',
'enabled'=>1,
'visible'=>-1,
'position'=>80),
238 'fk_commercial_suivi' =>array(
'type'=>
'integer:User:user/class/user.class.php',
'label'=>
'SaleRepresentative follower',
'enabled'=>1,
'visible'=>-1,
'position'=>85),
239 'fk_user_author' =>array(
'type'=>
'integer:User:user/class/user.class.php',
'label'=>
'UserAuthor',
'enabled'=>1,
'visible'=>-1,
'notnull'=>1,
'position'=>90),
240 'note_public' =>array(
'type'=>
'text',
'label'=>
'NotePublic',
'enabled'=>1,
'visible'=>0,
'position'=>105),
241 'note_private' =>array(
'type'=>
'text',
'label'=>
'NotePrivate',
'enabled'=>1,
'visible'=>0,
'position'=>110),
242 'model_pdf' =>array(
'type'=>
'varchar(255)',
'label'=>
'Model pdf',
'enabled'=>1,
'visible'=>0,
'position'=>115),
243 'import_key' =>array(
'type'=>
'varchar(14)',
'label'=>
'ImportId',
'enabled'=>1,
'visible'=>-2,
'position'=>120),
244 'extraparams' =>array(
'type'=>
'varchar(255)',
'label'=>
'Extraparams',
'enabled'=>1,
'visible'=>-1,
'position'=>125),
245 'ref_customer' =>array(
'type'=>
'varchar(50)',
'label'=>
'Ref customer',
'enabled'=>1,
'visible'=>-1,
'position'=>130),
246 'fk_user_modif' =>array(
'type'=>
'integer:User:user/class/user.class.php',
'label'=>
'UserModif',
'enabled'=>1,
'visible'=>-2,
'notnull'=>-1,
'position'=>135),
247 'last_main_doc' =>array(
'type'=>
'varchar(255)',
'label'=>
'Last main doc',
'enabled'=>1,
'visible'=>-1,
'position'=>140),
248 'statut' =>array(
'type'=>
'smallint(6)',
'label'=>
'Statut',
'enabled'=>1,
'visible'=>-1,
'position'=>500,
'notnull'=>1,
'arrayofkeyval'=>array(0=>
'Draft', 1=>
'Validated', 2=>
'Closed'))
252 const STATUS_DRAFT = 0;
253 const STATUS_VALIDATED = 1;
254 const STATUS_CLOSED = 2;
276 global $db, $langs, $conf;
277 $langs->load(
"contracts");
279 if (!empty($conf->global->CONTRACT_ADDON)) {
282 $file = $conf->global->CONTRACT_ADDON.
".php";
283 $classname = $conf->global->CONTRACT_ADDON;
286 $dirmodels = array_merge(array(
'/'), (array) $conf->modules_parts[
'models']);
288 foreach ($dirmodels as $reldir) {
292 $mybool |= @include_once $dir.$file;
300 $obj =
new $classname();
301 $numref = $obj->getNextValue($soc, $this);
306 $this->error = $obj->error;
311 $langs->load(
"errors");
312 print $langs->trans(
"Error").
" ".$langs->trans(
"ErrorModuleSetupNotComplete", $langs->transnoentitiesnoconv(
"Contract"));
328 public function active_line($user, $line_id, $date, $date_end =
'', $comment =
'')
331 $result = $this->lines[$this->lines_id_index_mapper[$line_id]]->active_line($user, $date, $date_end, $comment);
333 $this->error = $this->lines[$this->lines_id_index_mapper[$line_id]]->error;
334 $this->errors = $this->lines[$this->lines_id_index_mapper[$line_id]]->errors;
350 public function close_line($user, $line_id, $date_end, $comment =
'')
353 $result = $this->lines[$this->lines_id_index_mapper[$line_id]]->close_line($user, $date_end, $comment);
355 $this->error = $this->lines[$this->lines_id_index_mapper[$line_id]]->error;
356 $this->errors = $this->lines[$this->lines_id_index_mapper[$line_id]]->errors;
372 public function activateAll($user, $date_start =
'', $notrigger = 0, $comment =
'')
374 if (empty($date_start)) {
385 foreach ($this->lines as $contratline) {
387 if ($contratline->statut != ContratLigne::STATUS_OPEN) {
388 $contratline->context = $this->context;
390 $result = $contratline->active_line($user, $date_start, -1, $comment);
393 $this->error = $contratline->error;
394 $this->errors = $contratline->errors;
400 if (!$error && $this->statut == 0) {
401 $result = $this->
validate($user,
'', $notrigger);
411 $this->
db->rollback();
436 foreach ($this->lines as $contratline) {
438 if ($contratline->statut != ContratLigne::STATUS_CLOSED) {
439 $contratline->date_end_real = $now;
440 $contratline->date_cloture = $now;
441 $contratline->fk_user_cloture = $user->id;
442 $contratline->statut = ContratLigne::STATUS_CLOSED;
443 $result = $contratline->close_line($user, $now, $comment, $notrigger);
446 $this->error = $contratline->error;
447 $this->errors = $contratline->errors;
453 if (!$error && $this->statut == 0) {
454 $result = $this->
validate($user,
'', $notrigger);
464 $this->
db->rollback();
477 public function validate(
User $user, $force_number =
'', $notrigger = 0)
479 require_once DOL_DOCUMENT_ROOT.
'/core/lib/files.lib.php';
480 global $langs, $conf;
485 dol_syslog(get_class($this).
'::validate user='.$user->id.
', force_number='.$force_number);
493 if (empty($conf->global->CONTRACT_DISABLE_AUTOSET_AS_CLIENT_ON_CONTRACT_VALIDATION)) {
494 $result = $this->thirdparty->set_as_client();
499 $num = $force_number;
500 } elseif (!$error && (preg_match(
'/^[\(]?PROV/i', $this->
ref) || empty($this->
ref))) {
508 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"contrat SET ref = '".$this->
db->escape($num).
"', statut = 1";
510 $sql .=
" WHERE rowid = ".((int) $this->
id).
" AND statut = 0";
512 dol_syslog(get_class($this).
"::validate", LOG_DEBUG);
517 $this->error = $this->
db->lasterror();
521 if (!$error && !$notrigger) {
523 $result = $this->
call_trigger(
'CONTRACT_VALIDATE', $user);
531 $this->oldref = $this->ref;
534 if (preg_match(
'/^[\(]?PROV/i', $this->
ref)) {
536 $sql =
'UPDATE '.MAIN_DB_PREFIX.
"ecm_files set filename = CONCAT('".$this->
db->escape($this->newref).
"', SUBSTR(filename, ".(strlen($this->
ref) + 1).
")), filepath = 'contract/".$this->
db->escape($this->newref).
"'";
537 $sql .=
" WHERE filename LIKE '".$this->db->escape($this->
ref).
"%' AND filepath = 'contract/".$this->
db->escape($this->
ref).
"' and entity = ".$conf->entity;
540 $error++; $this->error = $this->
db->lasterror();
546 $dirsource = $conf->contract->dir_output.
'/'.$oldref;
547 $dirdest = $conf->contract->dir_output.
'/'.$newref;
548 if (!$error && file_exists($dirsource)) {
549 dol_syslog(get_class($this).
"::validate rename dir ".$dirsource.
" into ".$dirdest);
551 if (@rename($dirsource, $dirdest)) {
554 $listoffiles =
dol_dir_list($conf->contract->dir_output.
'/'.$newref,
'files', 1,
'^'.preg_quote($oldref,
'/'));
555 foreach ($listoffiles as $fileentry) {
556 $dirsource = $fileentry[
'name'];
557 $dirdest = preg_replace(
'/^'.preg_quote($oldref,
'/').
'/', $newref, $dirsource);
558 $dirsource = $fileentry[
'path'].
'/'.$dirsource;
559 $dirdest = $fileentry[
'path'].
'/'.$dirdest;
560 @rename($dirsource, $dirdest);
571 $this->brouillon = 0;
572 $this->date_validation = $now;
582 $this->
db->rollback();
594 public function reopen($user, $notrigger = 0)
596 require_once DOL_DOCUMENT_ROOT.
'/core/lib/files.lib.php';
597 global $langs, $conf;
602 dol_syslog(get_class($this).
'::reopen user='.$user->id);
608 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"contrat SET statut = 0";
610 $sql .=
" WHERE rowid = ".((int) $this->
id).
" AND statut = 1";
612 dol_syslog(get_class($this).
"::validate", LOG_DEBUG);
617 $this->error = $this->
db->lasterror();
621 if (!$error && !$notrigger) {
623 $result = $this->
call_trigger(
'CONTRACT_REOPEN', $user);
633 $this->brouillon = 1;
634 $this->date_validation = $now;
641 $this->
db->rollback();
655 public function fetch($id, $ref =
'', $ref_customer =
'', $ref_supplier =
'')
657 $sql =
"SELECT rowid, statut, ref, fk_soc,";
658 $sql .=
" ref_supplier, ref_customer,";
661 $sql .=
" date_contrat as datecontrat,";
662 $sql .=
" fk_user_author,";
663 $sql .=
" fk_projet as fk_project,";
664 $sql .=
" fk_commercial_signature, fk_commercial_suivi,";
665 $sql .=
" note_private, note_public, model_pdf, extraparams";
666 $sql .=
" FROM ".MAIN_DB_PREFIX.
"contrat";
668 $sql .=
" WHERE entity IN (".getEntity(
'contract').
")";
670 $sql .=
" WHERE rowid=".(int) $id;
673 $sql .=
" AND ref_customer = '".$this->db->escape($ref_customer).
"'";
676 $sql .=
" AND ref_supplier = '".$this->db->escape($ref_supplier).
"'";
679 $sql .=
" AND ref='".$this->db->escape($ref).
"'";
682 dol_syslog(get_class($this).
"::fetch", LOG_DEBUG);
687 $this->error =
'Fetch found several records.';
691 $obj = $this->
db->fetch_object(
$resql);
693 $this->
id = $obj->rowid;
694 $this->
ref = (!isset($obj->ref) || !$obj->ref) ? $obj->rowid : $obj->ref;
695 $this->ref_customer = $obj->ref_customer;
696 $this->ref_supplier = $obj->ref_supplier;
697 $this->ref_ext = $obj->ref_ext;
698 $this->entity = $obj->entity;
699 $this->statut = $obj->statut;
701 $this->date_contrat = $this->db->jdate($obj->datecontrat);
702 $this->date_creation = $this->
db->jdate($obj->datecontrat);
704 $this->user_author_id = $obj->fk_user_author;
706 $this->commercial_signature_id = $obj->fk_commercial_signature;
707 $this->commercial_suivi_id = $obj->fk_commercial_suivi;
709 $this->note_private = $obj->note_private;
710 $this->note_public = $obj->note_public;
711 $this->model_pdf = $obj->model_pdf;
712 $this->modelpdf = $obj->model_pdf;
714 $this->fk_projet = $obj->fk_project;
715 $this->fk_project = $obj->fk_project;
717 $this->socid = $obj->fk_soc;
718 $this->fk_soc = $obj->fk_soc;
720 $this->extraparams = (array) json_decode($obj->extraparams,
true);
731 $this->error = $this->
db->lasterror();
738 dol_syslog(get_class($this).
"::fetch Contract not found");
739 $this->error =
"Contract not found";
743 dol_syslog(get_class($this).
"::fetch Error searching contract");
744 $this->error = $this->
db->error();
758 public function fetch_lines($only_services = 0, $loadalsotranslation = 0)
761 global $langs, $conf;
763 $this->nbofservices = 0;
764 $this->nbofserviceswait = 0;
765 $this->nbofservicesopened = 0;
766 $this->nbofservicesexpired = 0;
767 $this->nbofservicesclosed = 0;
775 $this->lines = array();
779 $sql =
"SELECT p.label as product_label, p.description as product_desc, p.ref as product_ref, p.fk_product_type as product_type,";
780 $sql .=
" d.rowid, d.fk_contrat, d.statut, d.description, d.price_ht, d.vat_src_code, d.tva_tx, d.localtax1_tx, d.localtax2_tx, d.localtax1_type, d.localtax2_type, d.qty, d.remise_percent, d.subprice, d.fk_product_fournisseur_price as fk_fournprice, d.buy_price_ht as pa_ht,";
781 $sql .=
" d.total_ht,";
782 $sql .=
" d.total_tva,";
783 $sql .=
" d.total_localtax1,";
784 $sql .=
" d.total_localtax2,";
785 $sql .=
" d.total_ttc,";
786 $sql .=
" d.info_bits, d.fk_product,";
787 $sql .=
" d.date_ouverture_prevue, d.date_ouverture,";
788 $sql .=
" d.date_fin_validite, d.date_cloture,";
789 $sql .=
" d.fk_user_author,";
790 $sql .=
" d.fk_user_ouverture,";
791 $sql .=
" d.fk_user_cloture,";
792 $sql .=
" d.fk_unit,";
793 $sql .=
" d.product_type as type";
794 $sql .=
" FROM ".MAIN_DB_PREFIX.
"contratdet as d LEFT JOIN ".MAIN_DB_PREFIX.
"product as p ON d.fk_product = p.rowid";
795 $sql .=
" WHERE d.fk_contrat = ".((int) $this->
id);
796 if ($only_services == 1) {
797 $sql .=
" AND d.product_type = 1";
799 $sql .=
" ORDER by d.rowid ASC";
801 dol_syslog(get_class($this).
"::fetch_lines", LOG_DEBUG);
802 $result = $this->
db->query($sql);
804 $num = $this->
db->num_rows($result);
808 $objp = $this->
db->fetch_object($result);
812 $line->id = $objp->rowid;
813 $line->ref = $objp->rowid;
814 $line->fk_contrat = $objp->fk_contrat;
815 $line->desc = $objp->description;
816 $line->qty = $objp->qty;
817 $line->vat_src_code = $objp->vat_src_code;
818 $line->tva_tx = $objp->tva_tx;
819 $line->localtax1_tx = $objp->localtax1_tx;
820 $line->localtax2_tx = $objp->localtax2_tx;
821 $line->localtax1_type = $objp->localtax1_type;
822 $line->localtax2_type = $objp->localtax2_type;
823 $line->subprice = $objp->subprice;
824 $line->statut = $objp->statut;
825 $line->remise_percent = $objp->remise_percent;
826 $line->price_ht = $objp->price_ht;
827 $line->price = $objp->price_ht;
828 $line->total_ht = $objp->total_ht;
829 $line->total_tva = $objp->total_tva;
830 $line->total_localtax1 = $objp->total_localtax1;
831 $line->total_localtax2 = $objp->total_localtax2;
832 $line->total_ttc = $objp->total_ttc;
833 $line->fk_product = (($objp->fk_product > 0) ? $objp->fk_product : 0);
834 $line->info_bits = $objp->info_bits;
835 $line->type = $objp->type;
837 $line->fk_fournprice = $objp->fk_fournprice;
838 $marginInfos =
getMarginInfos($objp->subprice, $objp->remise_percent, $objp->tva_tx, $objp->localtax1_tx, $objp->localtax2_tx, $objp->fk_fournprice, $objp->pa_ht);
839 $line->pa_ht = $marginInfos[0];
841 $line->fk_user_author = $objp->fk_user_author;
842 $line->fk_user_ouverture = $objp->fk_user_ouverture;
843 $line->fk_user_cloture = $objp->fk_user_cloture;
844 $line->fk_unit = $objp->fk_unit;
846 $line->ref = $objp->product_ref;
847 $line->product_ref = $objp->product_ref;
848 $line->product_type = $objp->product_type;
849 $line->product_desc = $objp->product_desc;
850 $line->product_label = $objp->product_label;
852 $line->description = $objp->description;
854 $line->date_start = $this->
db->jdate($objp->date_ouverture_prevue);
855 $line->date_start_real = $this->
db->jdate($objp->date_ouverture);
856 $line->date_end = $this->
db->jdate($objp->date_fin_validite);
857 $line->date_end_real = $this->
db->jdate($objp->date_cloture);
859 $line->date_ouverture_prevue = $this->
db->jdate($objp->date_ouverture_prevue);
860 $line->date_ouverture = $this->
db->jdate($objp->date_ouverture);
861 $line->date_fin_validite = $this->
db->jdate($objp->date_fin_validite);
862 $line->date_cloture = $this->
db->jdate($objp->date_cloture);
863 $line->date_debut_prevue = $this->
db->jdate($objp->date_ouverture_prevue);
864 $line->date_debut_reel = $this->
db->jdate($objp->date_ouverture);
865 $line->date_fin_prevue = $this->
db->jdate($objp->date_fin_validite);
866 $line->date_fin_reel = $this->
db->jdate($objp->date_cloture);
870 $line->fetch_optionals();
873 if (!empty($conf->global->MAIN_MULTILANGS) && !empty($objp->fk_product) && !empty($loadalsotranslation)) {
875 $tmpproduct->fetch($objp->fk_product);
876 $tmpproduct->getMultiLangs();
878 $line->multilangs = $tmpproduct->multilangs;
881 $this->lines[$pos] = $line;
883 $this->lines_id_index_mapper[$line->id] = $pos;
888 if ($line->statut == ContratLigne::STATUS_INITIAL) {
889 $this->nbofserviceswait++;
891 if ($line->statut == ContratLigne::STATUS_OPEN && (empty($line->date_fin_prevue) || $line->date_fin_prevue >= $now)) {
892 $this->nbofservicesopened++;
894 if ($line->statut == ContratLigne::STATUS_OPEN && (!empty($line->date_fin_prevue) && $line->date_fin_prevue < $now)) {
895 $this->nbofservicesexpired++;
897 if ($line->statut == ContratLigne::STATUS_CLOSED) {
898 $this->nbofservicesclosed++;
901 $total_ttc += $objp->total_ttc;
902 $total_vat += $objp->total_tva;
903 $total_ht += $objp->total_ht;
908 $this->
db->free($result);
910 dol_syslog(get_class($this).
"::Fetch Error when reading lines of contracts linked to products");
915 $this->nbofservices = count($this->lines);
916 $this->total_ttc =
price2num($total_ttc);
917 $this->total_tva =
price2num($total_vat);
931 global $conf, $langs, $mysoc;
935 if ($this->commercial_signature_id <= 0) {
936 $langs->load(
"commercial");
937 $this->error .= $langs->trans(
"ErrorFieldRequired", $langs->transnoentitiesnoconv(
"SalesRepresentativeSignature"));
940 if ($this->commercial_suivi_id <= 0) {
941 $langs->load(
"commercial");
942 $this->error .= ($this->error ?
"<br>" :
'');
943 $this->error .= $langs->trans(
"ErrorFieldRequired", $langs->transnoentitiesnoconv(
"SalesRepresentativeFollowUp"));
956 $sql =
"INSERT INTO ".MAIN_DB_PREFIX.
"contrat (datec, fk_soc, fk_user_author, date_contrat,";
957 $sql .=
" fk_commercial_signature, fk_commercial_suivi, fk_projet,";
958 $sql .=
" ref, entity, note_private, note_public, ref_customer, ref_supplier, ref_ext)";
959 $sql .=
" VALUES ('".$this->db->idate($now).
"', ".((int) $this->socid).
", ".((int) $user->id);
960 $sql .=
", ".(dol_strlen($this->date_contrat) != 0 ?
"'".$this->db->idate($this->date_contrat).
"'" :
"NULL");
961 $sql .=
",".($this->commercial_signature_id > 0 ? ((int) $this->commercial_signature_id) :
"NULL");
962 $sql .=
",".($this->commercial_suivi_id > 0 ? ((int) $this->commercial_suivi_id) :
"NULL");
963 $sql .=
",".($this->fk_project > 0 ? ((int) $this->fk_project) :
"NULL");
964 $sql .=
", ".(dol_strlen($this->
ref) <= 0 ?
"null" :
"'".$this->db->escape($this->
ref).
"'");
965 $sql .=
", ".((int) $conf->entity);
966 $sql .=
", ".(!empty($this->note_private) ? (
"'".$this->db->escape($this->note_private).
"'") :
"NULL");
967 $sql .=
", ".(!empty($this->note_public) ? (
"'".$this->db->escape($this->note_public).
"'") :
"NULL");
968 $sql .=
", ".(!empty($this->ref_customer) ? (
"'".$this->db->escape($this->ref_customer).
"'") :
"NULL");
969 $sql .=
", ".(!empty($this->ref_supplier) ? (
"'".$this->db->escape($this->ref_supplier).
"'") :
"NULL");
970 $sql .=
", ".(!empty($this->ref_ext) ? (
"'".$this->db->escape($this->ref_ext).
"'") :
"NULL");
977 $this->
id = $this->
db->last_insert_id(MAIN_DB_PREFIX.
"contrat");
980 $module = (!empty($conf->global->CONTRACT_ADDON) ? $conf->global->CONTRACT_ADDON :
'mod_contract_serpis');
981 if (substr($module, 0, 13) ==
'mod_contract_' && substr($module, -3) ==
'php') {
982 $module = substr($module, 0,
dol_strlen($module) - 4);
986 $modCodeContract =
new $module();
988 if (!empty($modCodeContract->code_auto)) {
990 $sql =
'UPDATE '.MAIN_DB_PREFIX.
"contrat SET ref='(PROV".$this->
id.
")' WHERE rowid=".((int) $this->
id);
991 if ($this->
db->query($sql)) {
993 $this->
ref =
"(PROV".$this->id.
")";
1008 $result = $this->
add_contact($this->commercial_signature_id,
'SALESREPSIGN',
'internal');
1016 $result = $this->
add_contact($this->commercial_suivi_id,
'SALESREPFOLL',
'internal');
1023 if (!empty($this->linkedObjectsIds) && empty($this->linked_objects)) {
1024 $this->linked_objects = $this->linkedObjectsIds;
1028 if (!$error && $this->
id && !empty($this->linked_objects) && is_array($this->linked_objects)) {
1029 foreach ($this->linked_objects as $origin => $tmp_origin_id) {
1030 if (is_array($tmp_origin_id)) {
1031 foreach ($tmp_origin_id as $origin_id) {
1034 $this->error = $this->
db->lasterror();
1040 $origin_id = $tmp_origin_id;
1043 $this->error = $this->
db->lasterror();
1050 if (!$error && $this->
id && !empty($conf->global->MAIN_PROPAGATE_CONTACTS_FROM_ORIGIN) && !empty($this->origin) && !empty($this->origin_id)) {
1051 $originforcontact = $this->origin;
1052 $originidforcontact = $this->origin_id;
1053 if ($originforcontact ==
'shipping') {
1054 require_once DOL_DOCUMENT_ROOT.
'/expedition/class/expedition.class.php';
1056 $exp->fetch($this->origin_id);
1057 $exp->fetchObjectLinked();
1058 if (count($exp->linkedObjectsIds[
'commande']) > 0) {
1059 foreach ($exp->linkedObjectsIds[
'commande'] as $key => $value) {
1060 $originforcontact =
'commande';
1061 $originidforcontact = $value;
1067 $sqlcontact =
"SELECT ctc.code, ctc.source, ec.fk_socpeople FROM ".MAIN_DB_PREFIX.
"element_contact as ec, ".MAIN_DB_PREFIX.
"c_type_contact as ctc";
1068 $sqlcontact .=
" WHERE element_id = ".((int) $originidforcontact).
" AND ec.fk_c_type_contact = ctc.rowid AND ctc.element = '".$this->
db->escape($originforcontact).
"'";
1070 $resqlcontact = $this->
db->query($sqlcontact);
1071 if ($resqlcontact) {
1072 while ($objcontact = $this->
db->fetch_object($resqlcontact)) {
1073 if ($objcontact->source ==
'internal' && in_array($objcontact->code, array(
'SALESREPSIGN',
'SALESREPFOLL'))) {
1078 $this->
add_contact($objcontact->fk_socpeople, $objcontact->code, $objcontact->source);
1088 $result = $this->
call_trigger(
'CONTRACT_CREATE', $user);
1095 $this->
db->commit();
1098 dol_syslog(get_class($this).
"::create - 30 - ".$this->error, LOG_ERR);
1099 $this->
db->rollback();
1103 $this->error =
"Failed to add contract";
1104 dol_syslog(get_class($this).
"::create - 20 - ".$this->error, LOG_ERR);
1105 $this->
db->rollback();
1109 $this->error = $langs->trans(
"UnknownError: ".$this->
db->error().
" -", LOG_DEBUG);
1111 $this->
db->rollback();
1123 public function delete($user)
1125 global $conf, $langs;
1126 require_once DOL_DOCUMENT_ROOT.
'/core/lib/files.lib.php';
1133 $result = $this->
call_trigger(
'CONTRACT_DELETE', $user);
1143 dol_syslog(get_class($this).
"::delete error", LOG_ERR);
1163 $sql =
"SELECT cdl.rowid as cdlrowid ";
1164 $sql .=
" FROM ".MAIN_DB_PREFIX.
"contratdet_log as cdl, ".MAIN_DB_PREFIX.
"contratdet as cd";
1165 $sql .=
" WHERE cdl.fk_contratdet=cd.rowid AND cd.fk_contrat=".((int) $this->
id);
1167 dol_syslog(get_class($this).
"::delete contratdet_log", LOG_DEBUG);
1170 $this->error = $this->
db->error();
1173 $numressql = $this->
db->num_rows(
$resql);
1174 if (!$error && $numressql) {
1175 $tab_resql = array();
1176 for ($i = 0; $i < $numressql; $i++) {
1177 $objresql = $this->
db->fetch_object(
$resql);
1178 $tab_resql[] = $objresql->cdlrowid;
1182 $sql =
"DELETE FROM ".MAIN_DB_PREFIX.
"contratdet_log ";
1183 $sql .=
" WHERE ".MAIN_DB_PREFIX.
"contratdet_log.rowid IN (".$this->
db->sanitize(implode(
",", $tab_resql)).
")";
1185 dol_syslog(get_class($this).
"::delete contratdet_log", LOG_DEBUG);
1188 $this->error = $this->
db->error();
1197 $main = MAIN_DB_PREFIX.
'contratdet';
1198 $ef = $main.
"_extrafields";
1199 $sql =
"DELETE FROM ".$ef.
" WHERE fk_object IN (SELECT rowid FROM ".$main.
" WHERE fk_contrat = ".((int) $this->
id).
")";
1201 dol_syslog(get_class($this).
"::delete contratdet_extrafields", LOG_DEBUG);
1204 $this->error = $this->
db->error();
1211 $sql =
"DELETE FROM ".MAIN_DB_PREFIX.
"contratdet";
1212 $sql .=
" WHERE fk_contrat=".((int) $this->
id);
1214 dol_syslog(get_class($this).
"::delete contratdet", LOG_DEBUG);
1217 $this->error = $this->
db->error();
1224 $sql =
'DELETE FROM '.MAIN_DB_PREFIX.
"ecm_files WHERE src_object_type = '".$this->
db->escape($this->table_element.(empty($this->module) ?
"" :
"@".$this->module)).
"' AND src_object_id = ".((
int) $this->id);
1227 $this->error = $this->
db->lasterror();
1228 $this->errors[] = $this->error;
1235 $sql =
"DELETE FROM ".MAIN_DB_PREFIX.
"contrat";
1236 $sql .=
" WHERE rowid=".((int) $this->
id);
1238 dol_syslog(get_class($this).
"::delete contrat", LOG_DEBUG);
1241 $this->error = $this->
db->error();
1251 dol_syslog(get_class($this).
"::delete error -3 ".$this->error, LOG_ERR);
1258 if ($conf->contrat->dir_output) {
1259 $dir = $conf->contrat->multidir_output[$this->entity].
"/".$ref;
1260 if (file_exists($dir)) {
1263 $this->error =
'ErrorFailToDeleteDir';
1271 $this->
db->commit();
1274 $this->error = $this->
db->lasterror();
1275 $this->
db->rollback();
1287 public function update($user, $notrigger = 0)
1289 global $conf, $langs;
1293 if (empty($this->fk_commercial_signature) && $this->commercial_signature_id > 0) {
1294 $this->fk_commercial_signature = $this->commercial_signature_id;
1296 if (empty($this->fk_commercial_suivi) && $this->commercial_suivi_id > 0) {
1297 $this->fk_commercial_suivi = $this->commercial_suivi_id;
1299 if (empty($this->fk_soc) && $this->socid > 0) {
1300 $this->fk_soc = (int) $this->socid;
1302 if (empty($this->fk_project) && $this->projet > 0) {
1303 $this->fk_project = (int) $this->projet;
1306 if (isset($this->
ref)) {
1307 $this->
ref = trim($this->
ref);
1309 if (isset($this->ref_customer)) {
1310 $this->ref_customer = trim($this->ref_customer);
1312 if (isset($this->ref_supplier)) {
1313 $this->ref_supplier = trim($this->ref_supplier);
1315 if (isset($this->ref_ext)) {
1316 $this->ref_ext = trim($this->ref_ext);
1318 if (isset($this->entity)) {
1319 $this->entity = (int) $this->entity;
1321 if (isset($this->statut)) {
1322 $this->statut = (int) $this->statut;
1324 if (isset($this->fk_soc)) {
1325 $this->fk_soc = (int) $this->fk_soc;
1327 if (isset($this->fk_commercial_signature)) {
1328 $this->fk_commercial_signature = trim($this->fk_commercial_signature);
1330 if (isset($this->fk_commercial_suivi)) {
1331 $this->fk_commercial_suivi = trim($this->fk_commercial_suivi);
1333 if (isset($this->note_private)) {
1334 $this->note_private = trim($this->note_private);
1336 if (isset($this->note_public)) {
1337 $this->note_public = trim($this->note_public);
1339 if (isset($this->import_key)) {
1340 $this->import_key = trim($this->import_key);
1348 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"contrat SET";
1349 $sql .=
" ref=".(isset($this->
ref) ?
"'".$this->db->escape($this->
ref).
"'" :
"null").
",";
1350 $sql .=
" ref_customer=".(isset($this->ref_customer) ?
"'".$this->db->escape($this->ref_customer).
"'" :
"null").
",";
1351 $sql .=
" ref_supplier=".(isset($this->ref_supplier) ?
"'".$this->db->escape($this->ref_supplier).
"'" :
"null").
",";
1352 $sql .=
" ref_ext=".(isset($this->ref_ext) ?
"'".$this->db->escape($this->ref_ext).
"'" :
"null").
",";
1353 $sql .=
" entity=".$conf->entity.
",";
1354 $sql .=
" date_contrat=".(dol_strlen($this->date_contrat) != 0 ?
"'".$this->db->idate($this->date_contrat).
"'" :
'null').
",";
1355 $sql .=
" statut=".(isset($this->statut) ? $this->statut :
"null").
",";
1356 $sql .=
" fk_soc=".($this->fk_soc > 0 ? $this->fk_soc :
"null").
",";
1357 $sql .=
" fk_projet=".($this->fk_project > 0 ? $this->fk_project :
"null").
",";
1358 $sql .=
" fk_commercial_signature=".(isset($this->fk_commercial_signature) ? $this->fk_commercial_signature :
"null").
",";
1359 $sql .=
" fk_commercial_suivi=".(isset($this->fk_commercial_suivi) ? $this->fk_commercial_suivi :
"null").
",";
1360 $sql .=
" note_private=".(isset($this->note_private) ?
"'".$this->db->escape($this->note_private).
"'" :
"null").
",";
1361 $sql .=
" note_public=".(isset($this->note_public) ?
"'".$this->db->escape($this->note_public).
"'" :
"null").
",";
1362 $sql .=
" import_key=".(isset($this->import_key) ?
"'".$this->db->escape($this->import_key).
"'" :
"null").
"";
1364 $sql .=
" WHERE rowid=".((int) $this->
id);
1370 $error++; $this->errors[] =
"Error ".$this->db->lasterror();
1380 if (!$error && !$notrigger) {
1382 $result = $this->
call_trigger(
'CONTRACT_MODIFY', $user);
1391 foreach ($this->errors as $errmsg) {
1392 dol_syslog(get_class($this).
"::update ".$errmsg, LOG_ERR);
1393 $this->error .= ($this->error ?
', '.$errmsg : $errmsg);
1395 $this->
db->rollback();
1398 $this->
db->commit();
1427 public function addline($desc, $pu_ht, $qty, $txtva, $txlocaltax1, $txlocaltax2, $fk_product, $remise_percent, $date_start, $date_end, $price_base_type =
'HT', $pu_ttc = 0.0, $info_bits = 0, $fk_fournprice =
null, $pa_ht = 0, $array_options = 0, $fk_unit =
null, $rang = 0)
1429 global $user, $langs, $conf, $mysoc;
1432 dol_syslog(get_class($this).
"::addline $desc, $pu_ht, $qty, $txtva, $txlocaltax1, $txlocaltax2, $fk_product, $remise_percent, $date_start, $date_end, $price_base_type, $pu_ttc, $info_bits, $rang");
1435 if ($fk_product <= 0 && empty($desc)) {
1436 $this->error =
"ErrorDescRequiredForFreeProductLines";
1440 if ($this->statut >= 0) {
1449 if (preg_match(
'/\((.*)\)/', $txtva, $reg)) {
1450 $vat_src_code = $reg[1];
1451 $txtva = preg_replace(
'/\s*\(.*\)/',
'', $txtva);
1457 $remise_percent =
price2num($remise_percent);
1462 if (empty($info_bits)) {
1465 if (empty($pu_ht) || !is_numeric($pu_ht)) {
1468 if (empty($pu_ttc)) {
1471 if (empty($txtva) || !is_numeric($txtva)) {
1474 if (empty($txlocaltax1) || !is_numeric($txlocaltax1)) {
1477 if (empty($txlocaltax2) || !is_numeric($txlocaltax2)) {
1481 if ($price_base_type ==
'HT') {
1488 if (empty($remise_percent)) {
1489 $remise_percent = 0;
1492 if ($date_start && $date_end && $date_start > $date_end) {
1493 $langs->load(
"errors");
1494 $this->error = $langs->trans(
'ErrorStartDateGreaterEnd');
1500 $localtaxes_type =
getLocalTaxesFromRate($txtva.($vat_src_code ?
' ('.$vat_src_code.
')' :
''), 0, $this->societe, $mysoc);
1507 $tabprice =
calcul_price_total($qty, $pu, $remise_percent, $txtva, $txlocaltax1, $txlocaltax2, 0, $price_base_type, $info_bits, 1, $mysoc, $localtaxes_type);
1508 $total_ht = $tabprice[0];
1509 $total_tva = $tabprice[1];
1510 $total_ttc = $tabprice[2];
1511 $total_localtax1 = $tabprice[9];
1512 $total_localtax2 = $tabprice[10];
1514 $localtax1_type = $localtaxes_type[0];
1515 $localtax2_type = $localtaxes_type[2];
1522 $remise = round(($pu_ht * $remise_percent / 100), 2);
1523 $price = $pu_ht - $remise;
1526 if (empty($pa_ht)) {
1532 if ($this->pa_ht == 0) {
1533 if (($result = $this->
defineBuyPrice($pu_ht, $remise_percent, $fk_product)) < 0) {
1541 $sql =
"INSERT INTO ".MAIN_DB_PREFIX.
"contratdet";
1542 $sql .=
" (fk_contrat, label, description, fk_product, qty, tva_tx, vat_src_code,";
1543 $sql .=
" localtax1_tx, localtax2_tx, localtax1_type, localtax2_type, remise_percent, subprice,";
1544 $sql .=
" total_ht, total_tva, total_localtax1, total_localtax2, total_ttc,";
1545 $sql .=
" info_bits,";
1546 $sql .=
" price_ht, remise, fk_product_fournisseur_price, buy_price_ht";
1547 if ($date_start > 0) {
1548 $sql .=
",date_ouverture_prevue";
1550 if ($date_end > 0) {
1551 $sql .=
",date_fin_validite";
1553 $sql .=
", fk_unit";
1554 $sql .=
") VALUES (";
1555 $sql .= $this->
id.
", '', '".$this->
db->escape($desc).
"',";
1556 $sql .= ($fk_product > 0 ? $fk_product :
"null").
",";
1557 $sql .=
" ".((float) $qty).
",";
1558 $sql .=
" ".((float) $txtva).
",";
1559 $sql .=
" ".($vat_src_code ?
"'".$this->db->escape($vat_src_code).
"'" :
"null").
",";
1560 $sql .=
" ".((float) $txlocaltax1).
",";
1561 $sql .=
" ".((float) $txlocaltax2).
",";
1562 $sql .=
" '".$this->db->escape($localtax1_type).
"',";
1563 $sql .=
" '".$this->db->escape($localtax2_type).
"',";
1564 $sql .=
" ".price2num($remise_percent).
",";
1565 $sql .=
" ".price2num($pu_ht).
",";
1567 $sql .=
" '".$this->db->escape($info_bits).
"',";
1568 $sql .=
" ".price2num($price).
",".
price2num($remise).
",";
1569 if (isset($fk_fournprice)) {
1570 $sql .=
' '.((int) $fk_fournprice).
',';
1574 if (isset($pa_ht)) {
1575 $sql .=
' '.price2num($pa_ht);
1579 if ($date_start > 0) {
1580 $sql .=
",'".$this->db->idate($date_start).
"'";
1582 if ($date_end > 0) {
1583 $sql .=
",'".$this->db->idate($date_end).
"'";
1585 $sql .=
", ".($fk_unit ?
"'".$this->db->escape($fk_unit).
"'" :
"null");
1590 $contractlineid = $this->
db->last_insert_id(MAIN_DB_PREFIX.
"contratdet");
1594 $contractline->array_options = $array_options;
1595 $contractline->id = $contractlineid;
1596 $result = $contractline->insertExtraFields();
1598 $this->error[] = $contractline->error;
1603 if (empty($error)) {
1605 $result = $this->
call_trigger(
'LINECONTRACT_INSERT', $user);
1613 $this->
db->rollback();
1616 $this->
db->commit();
1617 return $contractlineid;
1620 $this->
db->rollback();
1621 $this->error = $this->
db->error().
" sql=".$sql;
1625 dol_syslog(get_class($this).
"::addline ErrorTryToAddLineOnValidatedContract", LOG_ERR);
1653 public function updateline($rowid, $desc, $pu, $qty, $remise_percent, $date_start, $date_end, $tvatx, $localtax1tx = 0.0, $localtax2tx = 0.0, $date_debut_reel =
'', $date_fin_reel =
'', $price_base_type =
'HT', $info_bits = 0, $fk_fournprice =
null, $pa_ht = 0, $array_options = 0, $fk_unit =
null)
1655 global $user, $conf, $langs, $mysoc;
1661 $desc = trim($desc);
1662 $desc = trim($desc);
1668 if (empty($fk_fournprice)) {
1675 $remise = round(($pu * $remise_percent / 100), 2);
1676 $price = $pu - $remise;
1678 $remise_percent = 0;
1681 if ($date_start && $date_end && $date_start > $date_end) {
1682 $langs->load(
"errors");
1683 $this->error = $langs->trans(
'ErrorStartDateGreaterEnd');
1687 dol_syslog(get_class($this).
"::updateline $rowid, $desc, $pu, $qty, $remise_percent, $date_start, $date_end, $date_debut_reel, $date_fin_reel, $tvatx, $localtax1tx, $localtax2tx, $price_base_type, $info_bits");
1697 $tvatx = preg_replace(
'/\s*\(.*\)/',
'', $tvatx);
1699 $tabprice =
calcul_price_total($qty, $pu, $remise_percent, $tvatx, $localtax1tx, $localtax2tx, 0, $price_base_type, $info_bits, 1, $mysoc, $localtaxes_type);
1700 $total_ht = $tabprice[0];
1701 $total_tva = $tabprice[1];
1702 $total_ttc = $tabprice[2];
1703 $total_localtax1 = $tabprice[9];
1704 $total_localtax2 = $tabprice[10];
1706 $localtax1_type = (empty($localtaxes_type[0]) ?
'' : $localtaxes_type[0]);
1707 $localtax2_type = (empty($localtaxes_type[2]) ?
'' : $localtaxes_type[2]);
1714 $remise = round(($pu * $remise_percent / 100), 2);
1715 $price = $pu - $remise;
1718 if (empty($pa_ht)) {
1723 if ($this->pa_ht == 0) {
1724 if (($result = $this->
defineBuyPrice($pu, $remise_percent)) < 0) {
1731 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"contratdet set description = '".$this->
db->escape($desc).
"'";
1732 $sql .=
",price_ht = ".((float)
price2num($price));
1733 $sql .=
",subprice = ".((float)
price2num($subprice));
1734 $sql .=
",remise = ".((float)
price2num($remise));
1735 $sql .=
",remise_percent = ".((float)
price2num($remise_percent));
1736 $sql .=
",qty = ".((float) $qty);
1737 $sql .=
",tva_tx = ".((float)
price2num($tvatx));
1738 $sql .=
",localtax1_tx = ".((float)
price2num($localtax1tx));
1739 $sql .=
",localtax2_tx = ".((float)
price2num($localtax2tx));
1740 $sql .=
",localtax1_type='".$this->db->escape($localtax1_type).
"'";
1741 $sql .=
",localtax2_type='".$this->db->escape($localtax2_type).
"'";
1742 $sql .=
", total_ht = ".((float)
price2num($total_ht));
1743 $sql .=
", total_tva = ".((float)
price2num($total_tva));
1744 $sql .=
", total_localtax1 = ".((float)
price2num($total_localtax1));
1745 $sql .=
", total_localtax2 = ".((float)
price2num($total_localtax2));
1746 $sql .=
", total_ttc = ".((float)
price2num($total_ttc));
1747 $sql .=
", fk_product_fournisseur_price=".($fk_fournprice > 0 ? $fk_fournprice :
"null");
1748 $sql .=
", buy_price_ht = ".((float)
price2num($pa_ht));
1749 if ($date_start > 0) {
1750 $sql .=
",date_ouverture_prevue = '".$this->db->idate($date_start).
"'";
1752 $sql .=
",date_ouverture_prevue = null";
1754 if ($date_end > 0) {
1755 $sql .=
",date_fin_validite = '".$this->db->idate($date_end).
"'";
1757 $sql .=
",date_fin_validite = null";
1759 if ($date_debut_reel > 0) {
1760 $sql .=
",date_ouverture = '".$this->db->idate($date_debut_reel).
"'";
1762 $sql .=
",date_ouverture = null";
1764 if ($date_fin_reel > 0) {
1765 $sql .=
",date_cloture = '".$this->db->idate($date_fin_reel).
"'";
1767 $sql .=
",date_cloture = null";
1769 $sql .=
", fk_unit = ".($fk_unit > 0 ? ((int) $fk_unit) :
"null");
1770 $sql .=
" WHERE rowid = ".((int) $rowid);
1772 dol_syslog(get_class($this).
"::updateline", LOG_DEBUG);
1773 $result = $this->
db->query($sql);
1775 if (is_array($array_options) && count($array_options) > 0) {
1777 $contractline->fetch($rowid);
1780 foreach ($array_options as $key => $value) {
1781 $contractline->array_options[$key] = $array_options[$key];
1784 $result = $contractline->insertExtraFields();
1786 $this->error[] = $contractline->error;
1791 if (empty($error)) {
1793 $result = $this->
call_trigger(
'LINECONTRACT_MODIFY', $user);
1795 $this->
db->rollback();
1800 $this->
db->commit();
1804 $this->
db->rollback();
1805 $this->error = $this->
db->error();
1806 dol_syslog(get_class($this).
"::updateline Erreur -1");
1820 global $conf, $langs;
1824 if ($this->statut >= 0) {
1826 $result = $this->
call_trigger(
'LINECONTRACT_DELETE', $user);
1834 $sql =
"DELETE FROM ".MAIN_DB_PREFIX.$this->table_element_line;
1835 $sql .=
" WHERE rowid = ".((int) $idline);
1837 dol_syslog(get_class($this).
"::deleteline", LOG_DEBUG);
1840 $this->error =
"Error ".$this->db->lasterror();
1847 $contractline->id = $idline;
1848 $result = $contractline->deleteExtraFields();
1851 $this->error =
"Error ".get_class($this).
"::deleteline deleteExtraFields error -4 ".$contractline->error;
1855 if (empty($error)) {
1856 $this->
db->commit();
1859 dol_syslog(get_class($this).
"::deleteline ERROR:".$this->error, LOG_ERR);
1860 $this->
db->rollback();
1864 $this->error =
'ErrorDeleteLineNotAllowedByObjectStatus';
1881 dol_syslog(__METHOD__.
" is deprecated", LOG_WARNING);
1884 if ($this->statut == 0) {
1909 return $this->
LibStatut($this->statut, $mode);
1925 if (empty($this->labelStatus) || empty($this->labelStatusShort)) {
1927 $langs->load(
"contracts");
1928 $this->labelStatus[self::STATUS_DRAFT] = $langs->transnoentitiesnoconv(
'ContractStatusDraft');
1929 $this->labelStatus[self::STATUS_VALIDATED] = $langs->transnoentitiesnoconv(
'ContractStatusValidated');
1930 $this->labelStatus[self::STATUS_CLOSED] = $langs->transnoentitiesnoconv(
'ContractStatusClosed');
1931 $this->labelStatusShort[self::STATUS_DRAFT] = $langs->transnoentitiesnoconv(
'ContractStatusDraft');
1932 $this->labelStatusShort[self::STATUS_VALIDATED] = $langs->transnoentitiesnoconv(
'ContractStatusValidated');
1933 $this->labelStatusShort[self::STATUS_CLOSED] = $langs->transnoentitiesnoconv(
'ContractStatusClosed');
1936 $statusType =
'status'.$status;
1937 if ($status == self::STATUS_VALIDATED) {
1938 $statusType =
'status6';
1941 if ($mode == 4 || $mode == 6 || $mode == 7) {
1944 $text =
'<span class="hideonsmartphone">';
1945 $text .= ($this->nbofserviceswait + $this->nbofservicesopened + $this->nbofservicesexpired + $this->nbofservicesclosed);
1946 $text .=
' '.$langs->trans(
"Services");
1947 $text .=
': ';
1950 $text .= ($mode == 7 ?
'<span class="nowraponall">' :
'');
1951 $text .= ($mode != 7 || $this->nbofserviceswait > 0) ? ($this->nbofserviceswait.ContratLigne::LibStatut(0, 3, -1,
'class="marginleft2"')).(($mode != 7 || $this->nbofservicesopened || $this->nbofservicesexpired || $this->nbofservicesclosed) ?
' ' :
'') :
'';
1952 $text .= ($mode == 7 ?
'</span><span class="nowraponall">' :
'');
1953 $text .= ($mode != 7 || $this->nbofservicesopened > 0) ? ($this->nbofservicesopened.ContratLigne::LibStatut(4, 3, 0,
'class="marginleft2"')).(($mode != 7 || $this->nbofservicesexpired || $this->nbofservicesclosed) ?
' ' :
'') :
'';
1954 $text .= ($mode == 7 ?
'</span><span class="nowraponall">' :
'');
1955 $text .= ($mode != 7 || $this->nbofservicesexpired > 0) ? ($this->nbofservicesexpired.ContratLigne::LibStatut(4, 3, 1,
'class="marginleft2"')).(($mode != 7 || $this->nbofservicesclosed) ?
' ' :
'') :
'';
1956 $text .= ($mode == 7 ?
'</span><span class="nowraponall">' :
'');
1957 $text .= ($mode != 7 || $this->nbofservicesclosed > 0) ? ($this->nbofservicesclosed.ContratLigne::LibStatut(5, 3, -1,
'class="marginleft2"')) :
'';
1958 $text .= ($mode == 7 ?
'</span>' :
'');
1961 return dolGetStatus($this->labelStatus[$status], $this->labelStatusShort[$status],
'', $statusType, $mode);
1975 public function getNomUrl($withpicto = 0, $maxlength = 0, $notooltip = 0, $save_lastsearch_value = -1)
1977 global $conf, $langs, $user, $hookmanager;
1981 $url = DOL_URL_ROOT.
'/contrat/card.php?id='.$this->id;
1986 $add_save_lastsearch_values = ($save_lastsearch_value == 1 ? 1 : 0);
1987 if ($save_lastsearch_value == -1 && preg_match(
'/list\.php/', $_SERVER[
"PHP_SELF"])) {
1988 $add_save_lastsearch_values = 1;
1990 if ($add_save_lastsearch_values) {
1991 $url .=
'&save_lastsearch_values=1';
1997 if ($user->rights->contrat->lire) {
1998 $label =
img_picto(
'', $this->picto).
' <u class="paddingrightonly">'.$langs->trans(
"Contract").
'</u>';
2003 $label .=
'<br><b>'.$langs->trans(
'Ref').
':</b> '.($this->
ref ? $this->
ref : $this->id);
2004 $ref_customer = (!empty($this->ref_customer) ? $this->ref_customer : (empty($this->ref_client) ?
'' : $this->ref_client));
2005 $label .=
'<br><b>'.$langs->trans(
'RefCustomer').
':</b> '.$ref_customer;
2006 $label .=
'<br><b>'.$langs->trans(
'RefSupplier').
':</b> '.$this->ref_supplier;
2007 if (!empty($this->total_ht)) {
2008 $label .=
'<br><b>'.$langs->trans(
'AmountHT').
':</b> '.
price($this->total_ht, 0, $langs, 0, -1, -1, $conf->currency);
2010 if (!empty($this->total_tva)) {
2011 $label .=
'<br><b>'.$langs->trans(
'VAT').
':</b> '.
price($this->total_tva, 0, $langs, 0, -1, -1, $conf->currency);
2013 if (!empty($this->total_ttc)) {
2014 $label .=
'<br><b>'.$langs->trans(
'AmountTTC').
':</b> '.
price($this->total_ttc, 0, $langs, 0, -1, -1, $conf->currency);
2019 if (empty($notooltip) && $user->rights->contrat->lire) {
2020 if (!empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) {
2021 $label = $langs->trans(
"ShowOrder");
2022 $linkclose .=
' alt="'.dol_escape_htmltag($label, 1).
'"';
2024 $linkclose .=
' title="'.dol_escape_htmltag($label, 1).
'"';
2025 $linkclose .=
' class="classfortooltip"';
2028 $linkstart =
'<a href="'.$url.
'"';
2029 $linkstart .= $linkclose.
'>';
2032 $result .= $linkstart;
2034 $result .=
img_object(($notooltip ?
'' : $label), $this->picto, ($notooltip ? (($withpicto != 2) ?
'class="paddingright"' :
'') :
'class="'.(($withpicto != 2) ?
'paddingright ' :
'').
'classfortooltip"'), 0, 0, $notooltip ? 0 : 1);
2036 if ($withpicto != 2) {
2037 $result .= ($this->
ref ? $this->
ref : $this->id);
2039 $result .= $linkend;
2042 $hookmanager->initHooks(array(
'contractdao'));
2043 $parameters = array(
'id'=>$this->
id,
'getnomurl' => &$result);
2044 $reshook = $hookmanager->executeHooks(
'getNomUrl', $parameters, $this, $action);
2046 $result = $hookmanager->resPrint;
2048 $result .= $hookmanager->resPrint;
2062 $sql =
"SELECT c.rowid, c.ref, c.datec,";
2063 $sql .=
" c.tms as date_modification,";
2064 $sql .=
" fk_user_author";
2065 $sql .=
" FROM ".MAIN_DB_PREFIX.
"contrat as c";
2066 $sql .=
" WHERE c.rowid = ".((int) $id);
2068 $result = $this->
db->query($sql);
2070 if ($this->
db->num_rows($result)) {
2071 $obj = $this->
db->fetch_object($result);
2073 $this->
id = $obj->rowid;
2075 if ($obj->fk_user_author) {
2076 $cuser =
new User($this->
db);
2077 $cuser->fetch($obj->fk_user_author);
2078 $this->user_creation = $cuser;
2081 $this->
ref = (!$obj->ref) ? $obj->rowid : $obj->ref;
2082 $this->date_creation = $this->db->jdate($obj->datec);
2083 $this->date_modification = $this->
db->jdate($obj->date_modification);
2086 $this->
db->free($result);
2104 $sql =
"SELECT cd.rowid";
2105 $sql .=
" FROM ".MAIN_DB_PREFIX.
"contratdet as cd";
2106 $sql .=
" WHERE fk_contrat =".((int) $this->
id);
2108 $sql .=
" AND statut = ".((int) $status);
2111 dol_syslog(get_class($this).
"::array_detail()", LOG_DEBUG);
2114 $num = $this->
db->num_rows(
$resql);
2117 $obj = $this->
db->fetch_object(
$resql);
2118 $tab[$i] = $obj->rowid;
2123 $this->error = $this->
db->error();
2137 public function getListOfContracts($option =
'all', $status = [], $product_categories = [], $line_status = [])
2141 $sql =
"SELECT c.rowid";
2142 $sql .=
" FROM ".MAIN_DB_PREFIX.
"contrat as c";
2143 if (!empty($product_categories)) {
2144 $sql .=
" LEFT JOIN ".MAIN_DB_PREFIX.
"contratdet as cd ON cd.fk_contrat = c.rowid";
2145 $sql .=
" INNER JOIN ".MAIN_DB_PREFIX.
"categorie_product as cp ON cp.fk_product = cd.fk_product AND cp.fk_categorie IN (".$this->
db->sanitize(implode(
', ', $product_categories)).
")";
2147 $sql .=
" WHERE c.fk_soc =".((int) $this->socid);
2148 $sql .= ($option ==
'others') ?
" AND c.rowid <> ".((
int) $this->id) :
"";
2149 $sql .= (!empty($status)) ?
" AND c.statut IN (".$this->
db->sanitize(implode(
', ', $status)).
")" :
"";
2150 $sql .= (!empty($line_status)) ?
" AND cd.statut IN (".$this->
db->sanitize(implode(
', ', $line_status)).
")" :
"";
2151 $sql .=
" GROUP BY c.rowid";
2153 dol_syslog(get_class($this).
"::getOtherContracts()", LOG_DEBUG);
2156 $num = $this->
db->num_rows(
$resql);
2159 $obj = $this->
db->fetch_object(
$resql);
2161 $contrat->fetch($obj->rowid);
2162 $tab[$contrat->id] = $contrat;
2167 $this->error = $this->
db->lasterror();
2184 global $conf, $langs;
2186 $this->from =
" FROM ".MAIN_DB_PREFIX.
"contrat as c";
2187 $this->from .=
", ".MAIN_DB_PREFIX.
"contratdet as cd";
2188 $this->from .=
", ".MAIN_DB_PREFIX.
"societe as s";
2189 if (empty($user->rights->societe->client->voir) && !$user->socid) {
2190 $this->from .=
", ".MAIN_DB_PREFIX.
"societe_commerciaux as sc";
2193 if ($mode ==
'inactive') {
2194 $sql =
"SELECT cd.rowid, cd.date_ouverture_prevue as datefin";
2195 $sql .= $this->from;
2196 $sql .=
" WHERE c.statut = 1";
2197 $sql .=
" AND c.rowid = cd.fk_contrat";
2198 $sql .=
" AND cd.statut = 0";
2199 } elseif ($mode ==
'expired') {
2200 $sql =
"SELECT cd.rowid, cd.date_fin_validite as datefin";
2201 $sql .= $this->from;
2202 $sql .=
" WHERE c.statut = 1";
2203 $sql .=
" AND c.rowid = cd.fk_contrat";
2204 $sql .=
" AND cd.statut = 4";
2205 $sql .=
" AND cd.date_fin_validite < '".$this->db->idate(
dol_now()).
"'";
2206 } elseif ($mode ==
'active') {
2207 $sql =
"SELECT cd.rowid, cd.date_fin_validite as datefin";
2208 $sql .= $this->from;
2209 $sql .=
" WHERE c.statut = 1";
2210 $sql .=
" AND c.rowid = cd.fk_contrat";
2211 $sql .=
" AND cd.statut = 4";
2215 $sql .=
" AND c.fk_soc = s.rowid";
2216 $sql .=
" AND c.entity = ".((int) $conf->entity);
2218 $sql .=
" AND c.fk_soc = ".((int) $user->socid);
2220 if (empty($user->rights->societe->client->voir) && !$user->socid) {
2221 $sql .=
" AND c.fk_soc = sc.fk_soc AND sc.fk_user = ".((int) $user->id);
2226 $langs->load(
"contracts");
2229 if ($mode ==
'inactive') {
2230 $warning_delay = $conf->contrat->services->inactifs->warning_delay;
2231 $label = $langs->trans(
"BoardNotActivatedServices");
2232 $labelShort = $langs->trans(
"BoardNotActivatedServicesShort");
2233 $url = DOL_URL_ROOT.
'/contrat/services_list.php?mainmenu=commercial&leftmenu=contracts&mode=0&sortfield=cd.date_fin_validite&sortorder=asc';
2234 } elseif ($mode ==
'expired') {
2235 $warning_delay = $conf->contrat->services->expires->warning_delay;
2236 $url = DOL_URL_ROOT.
'/contrat/services_list.php?mainmenu=commercial&leftmenu=contracts&mode=4&filter=expired&sortfield=cd.date_fin_validite&sortorder=asc';
2237 $label = $langs->trans(
"BoardExpiredServices");
2238 $labelShort = $langs->trans(
"BoardExpiredServicesShort");
2240 $warning_delay = $conf->contrat->services->expires->warning_delay;
2241 $url = DOL_URL_ROOT.
'/contrat/services_list.php?mainmenu=commercial&leftmenu=contracts&mode=4&sortfield=cd.date_fin_validite&sortorder=asc';
2244 $label = $langs->trans(
"BoardRunningServices");
2245 $labelShort = $langs->trans(
"BoardRunningServicesShort");
2249 $response->warning_delay = $warning_delay / 60 / 60 / 24;
2250 $response->label = $label;
2251 $response->labelShort = $labelShort;
2252 $response->url = $url;
2255 while ($obj = $this->
db->fetch_object(
$resql)) {
2256 $response->nbtodo++;
2258 if ($obj->datefin && $this->db->jdate($obj->datefin) < ($now - $warning_delay)) {
2259 $response->nbtodolate++;
2266 $this->error = $this->
db->error();
2280 global $conf, $user;
2282 $this->nb = array();
2285 $sql =
"SELECT count(c.rowid) as nb";
2286 $sql .=
" FROM ".MAIN_DB_PREFIX.
"contrat as c";
2287 $sql .=
" LEFT JOIN ".MAIN_DB_PREFIX.
"societe as s ON c.fk_soc = s.rowid";
2288 if (empty($user->rights->societe->client->voir) && !$user->socid) {
2289 $sql .=
" LEFT JOIN ".MAIN_DB_PREFIX.
"societe_commerciaux as sc ON s.rowid = sc.fk_soc";
2290 $sql .=
" WHERE sc.fk_user = ".((int) $user->id);
2293 $sql .=
" ".$clause.
" c.entity = ".$conf->entity;
2297 while ($obj = $this->
db->fetch_object(
$resql)) {
2298 $this->nb[
"contracts"] = $obj->nb;
2304 $this->error = $this->
db->error();
2342 global $user, $langs, $conf;
2347 $sql =
"SELECT rowid";
2348 $sql .=
" FROM ".MAIN_DB_PREFIX.
"product";
2349 $sql .=
" WHERE entity IN (".getEntity(
'product').
")";
2350 $sql .=
" AND tosell = 1";
2351 $sql .= $this->
db->plimit(100);
2355 $num_prods = $this->
db->num_rows(
$resql);
2357 while ($i < $num_prods) {
2359 $row = $this->
db->fetch_row(
$resql);
2360 $prodids[$i] = $row[0];
2366 $this->specimen = 1;
2368 $this->
ref =
'SPECIMEN';
2369 $this->ref_customer =
'SPECIMENCUST';
2370 $this->ref_supplier =
'SPECIMENSUPP';
2373 $this->date_creation = (
dol_now() - 3600 * 24 * 7);
2374 $this->date_contrat =
dol_now();
2375 $this->commercial_signature_id = 1;
2376 $this->commercial_suivi_id = 1;
2377 $this->note_private =
'This is a comment (private)';
2378 $this->note_public =
'This is a comment (public)';
2379 $this->fk_projet = 0;
2383 while ($xnbp < $nbp) {
2386 $line->subprice = 100;
2388 $line->tva_tx = 19.6;
2389 $line->remise_percent = 10;
2390 $line->total_ht = 90;
2391 $line->total_ttc = 107.64;
2392 $line->total_tva = 17.64;
2393 $line->date_start =
dol_now() - 500000;
2394 $line->date_start_real =
dol_now() - 200000;
2395 $line->date_end =
dol_now() + 500000;
2396 $line->date_end_real =
dol_now() - 100000;
2397 if ($num_prods > 0) {
2398 $prodid = mt_rand(1, $num_prods);
2399 $line->fk_product = $prodids[$prodid];
2401 $this->lines[$xnbp] = $line;
2428 public function generateDocument($modele, $outputlangs, $hidedetails = 0, $hidedesc = 0, $hideref = 0, $moreparams =
null)
2430 global $conf, $langs;
2432 $langs->load(
"contracts");
2433 $outputlangs->load(
"products");
2438 if (!empty($this->model_pdf)) {
2439 $modele = $this->model_pdf;
2440 } elseif (!empty($this->modelpdf)) {
2441 $modele = $this->modelpdf;
2442 } elseif (!empty($conf->global->CONTRACT_ADDON_PDF)) {
2443 $modele = $conf->global->CONTRACT_ADDON_PDF;
2447 $modelpath =
"core/modules/contract/doc/";
2449 return $this->
commonGenerateDocument($modelpath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref, $moreparams);
2496 global $db, $langs, $conf, $hookmanager, $extrafields;
2502 $this->
fetch($this->
id);
2505 $clonedObj = clone $this;
2506 $clonedObj->socid = $socid;
2512 $objsoc->fetch($clonedObj->socid);
2515 $clonedObj->statut = 0;
2517 if (is_array($clonedObj->array_options) && count($clonedObj->array_options) > 0) {
2518 $extrafields->fetch_name_optionals_label($this->table_element);
2519 foreach ($clonedObj->array_options as $key => $option) {
2520 $shortkey = preg_replace(
'/options_/',
'', $key);
2522 if (!empty($extrafields->attributes[$this->element][
'unique'][$shortkey])) {
2524 unset($clonedObj->array_options[$key]);
2529 if (empty($conf->global->CONTRACT_ADDON) || !is_readable(DOL_DOCUMENT_ROOT.
"/core/modules/contract/".$conf->global->CONTRACT_ADDON.
".php")) {
2530 $this->error =
'ErrorSetupNotComplete';
2536 require_once DOL_DOCUMENT_ROOT.
"/core/modules/contract/".$conf->global->CONTRACT_ADDON.
'.php';
2537 $obj = $conf->global->CONTRACT_ADDON;
2538 $modContract =
new $obj();
2539 $clonedObj->ref = $modContract->getNextValue($objsoc, $clonedObj);
2542 foreach ($this->lines as $line) {
2543 $line->fetch_optionals($line->id);
2547 $clonedObj->context[
'createfromclone'] =
'createfromclone';
2548 $result = $clonedObj->create($user);
2551 $this->error = $clonedObj->error;
2552 $this->errors[] = $clonedObj->error;
2555 if ($this->socid == $clonedObj->socid) {
2556 if ($clonedObj->copy_linked_contact($this,
'external') < 0) {
2563 foreach ($this->lines as $line) {
2564 $result = $clonedObj->addline($line->description, $line->subprice, $line->qty, $line->tva_tx, $line->localtax1_tx, $line->localtax2_tx, $line->fk_product, $line->remise_percent, $line->date_ouverture, $line->date_cloture,
'HT', 0, $line->info_bits, $line->fk_fournprice, $line->pa_ht, $line->array_options, $line->fk_unit);
2567 $this->error = $clonedObj->error;
2568 $this->errors[] = $clonedObj->error;
2575 if (is_object($hookmanager)) {
2576 $parameters = array(
2578 'clonedObj' => $clonedObj
2581 $reshook = $hookmanager->executeHooks(
'createFrom', $parameters, $clonedObj, $action);
2583 $this->errors += $hookmanager->errors;
2584 $this->error = $hookmanager->error;
2590 unset($clonedObj->context[
'createfromclone']);
2594 $this->
db->commit();
2595 return $clonedObj->id;
2597 $this->
db->rollback();
2612 public $element =
'contratdet';
2617 public $table_element =
'contratdet';
2622 public $element_for_permission =
'contrat';
2664 public $description;
2666 public $product_type;
2667 public $product_ref;
2668 public $product_label;
2670 public $date_commande;
2673 public $date_start_real;
2675 public $date_end_real;
2695 public $vat_src_code;
2696 public $localtax1_tx;
2697 public $localtax2_tx;
2698 public $localtax1_type;
2699 public $localtax2_type;
2701 public $remise_percent;
2707 public $fk_remise_except;
2722 public $total_localtax1;
2723 public $total_localtax2;
2729 public $fk_fournprice;
2738 public $fk_user_author;
2743 public $fk_user_ouverture;
2748 public $fk_user_cloture;
2750 public $commentaire;
2753 const STATUS_INITIAL = 0;
2754 const STATUS_OPEN = 4;
2755 const STATUS_CLOSED = 5;
2762 public $fields = array(
2763 'rowid' =>array(
'type'=>
'integer',
'label'=>
'TechnicalID',
'enabled'=>1,
'visible'=>-1,
'notnull'=>1,
'position'=>10),
2764 'entity' =>array(
'type'=>
'integer',
'label'=>
'Entity',
'default'=>1,
'enabled'=>1,
'visible'=>-2,
'notnull'=>1,
'position'=>30,
'index'=>1),
2765 'tms' =>array(
'type'=>
'timestamp',
'label'=>
'DateModification',
'enabled'=>1,
'visible'=>-1,
'notnull'=>1,
'position'=>35),
2766 'qty' =>array(
'type'=>
'integer',
'label'=>
'Quantity',
'enabled'=>1,
'visible'=>-1,
'notnull'=>1,
'position'=>35,
'isameasure'=>1),
2767 'total_ht' =>array(
'type'=>
'integer',
'label'=>
'AmountHT',
'enabled'=>1,
'visible'=>-1,
'notnull'=>1,
'position'=>36,
'isameasure'=>1),
2768 'total_tva' =>array(
'type'=>
'integer',
'label'=>
'AmountVAT',
'enabled'=>1,
'visible'=>-1,
'notnull'=>1,
'position'=>37,
'isameasure'=>1),
2769 'total_ttc' =>array(
'type'=>
'integer',
'label'=>
'AmountTTC',
'enabled'=>1,
'visible'=>-1,
'notnull'=>1,
'position'=>38,
'isameasure'=>1),
2772 'fk_contrat' =>array(
'type'=>
'integer:Contrat:contrat/class/contrat.class.php',
'label'=>
'Contract',
'enabled'=>1,
'visible'=>-1,
'notnull'=>1,
'position'=>70),
2773 'fk_product' =>array(
'type'=>
'integer:Product:product/class/product.class.php:1',
'label'=>
'Product',
'enabled'=>1,
'visible'=>-1,
'position'=>75),
2775 'note_private' =>array(
'type'=>
'text',
'label'=>
'NotePublic',
'enabled'=>1,
'visible'=>0,
'position'=>105),
2776 'note_public' =>array(
'type'=>
'text',
'label'=>
'NotePrivate',
'enabled'=>1,
'visible'=>0,
'position'=>110),
2780 'fk_user_ouverture' =>array(
'type'=>
'integer:User:user/class/user.class.php',
'label'=>
'UserStartingService',
'enabled'=>1,
'visible'=>-2,
'notnull'=>-1,
'position'=>135),
2781 'fk_user_cloture' =>array(
'type'=>
'integer:User:user/class/user.class.php',
'label'=>
'UserClosingService',
'enabled'=>1,
'visible'=>-2,
'notnull'=>-1,
'position'=>135),
2782 'statut' =>array(
'type'=>
'smallint(6)',
'label'=>
'Statut',
'enabled'=>1,
'visible'=>-1,
'position'=>500,
'arrayofkeyval'=>array(0=>
'Draft', 4=>
'Open', 5=>
'Closed'))
2806 return $this->
LibStatut($this->statut, $mode, ((!empty($this->date_fin_validite)) ? ($this->date_fin_validite <
dol_now() ? 1 : 0) : -1));
2819 public static function LibStatut($status, $mode, $expired = -1, $moreatt =
'')
2823 $langs->load(
"contracts");
2825 if ($status == self::STATUS_INITIAL) {
2826 $labelStatus = $langs->transnoentities(
"ServiceStatusInitial");
2827 $labelStatusShort = $langs->transnoentities(
"ServiceStatusInitial");
2828 } elseif ($status == self::STATUS_OPEN && $expired == -1) {
2829 $labelStatus = $langs->transnoentities(
"ServiceStatusRunning");
2830 $labelStatusShort = $langs->transnoentities(
"ServiceStatusRunning");
2831 } elseif ($status == self::STATUS_OPEN && $expired == 0) {
2832 $labelStatus = $langs->transnoentities(
"ServiceStatusNotLate");
2833 $labelStatusShort = $langs->transnoentities(
"ServiceStatusNotLateShort");
2834 } elseif ($status == self::STATUS_OPEN && $expired == 1) {
2835 $labelStatus = $langs->transnoentities(
"ServiceStatusLate");
2836 $labelStatusShort = $langs->transnoentities(
"ServiceStatusLateShort");
2837 } elseif ($status == self::STATUS_CLOSED) {
2838 $labelStatus = $langs->transnoentities(
"ServiceStatusClosed");
2839 $labelStatusShort = $langs->transnoentities(
"ServiceStatusClosed");
2842 $statusType =
'status'.$status;
2843 if ($status == self::STATUS_OPEN && $expired == 1) {
2844 $statusType =
'status1';
2846 if ($status == self::STATUS_CLOSED) {
2847 $statusType =
'status6';
2850 $params = array(); $reg = array();
2851 if (preg_match(
'/class="(.*)"/', $moreatt, $reg)) {
2852 $params = array(
'badgeParams'=>array(
'css' => $reg[1]));
2854 return dolGetStatus($labelStatus, $labelStatusShort,
'', $statusType, $mode,
'', $params);
2869 $label = $langs->trans(
"ShowContractOfService").
': '.$this->label;
2870 if (empty($label)) {
2871 $label = $this->description;
2874 $link =
'<a href="'.DOL_URL_ROOT.
'/contrat/card.php?id='.$this->fk_contrat.
'" title="'.
dol_escape_htmltag($label, 1).
'" class="classfortooltip">';
2878 if ($this->
type == 0) {
2883 $result .= ($link.img_object($label, $picto,
'class="classfortooltip"').$linkend);
2885 if ($withpicto && $withpicto != 2) {
2888 if ($withpicto != 2) {
2889 $result .= $link.($this->product_ref ? $this->product_ref.
' ' :
'').($this->label ? $this->label : $this->
description).$linkend;
2904 if (empty($id) && empty($ref)) {
2909 $sql .=
" t.rowid,";
2911 $sql .=
" t.fk_contrat,";
2912 $sql .=
" t.fk_product,";
2913 $sql .=
" t.statut,";
2914 $sql .=
" t.label,";
2915 $sql .=
" p.ref as product_ref,";
2916 $sql .=
" p.label as product_label,";
2917 $sql .=
" p.description as product_desc,";
2918 $sql .=
" p.fk_product_type as product_type,";
2919 $sql .=
" t.description,";
2920 $sql .=
" t.date_commande,";
2921 $sql .=
" t.date_ouverture_prevue as date_ouverture_prevue,";
2922 $sql .=
" t.date_ouverture as date_ouverture,";
2923 $sql .=
" t.date_fin_validite as date_fin_validite,";
2924 $sql .=
" t.date_cloture as date_cloture,";
2925 $sql .=
" t.tva_tx,";
2926 $sql .=
" t.vat_src_code,";
2927 $sql .=
" t.localtax1_tx,";
2928 $sql .=
" t.localtax2_tx,";
2929 $sql .=
" t.localtax1_type,";
2930 $sql .=
" t.localtax2_type,";
2932 $sql .=
" t.remise_percent,";
2933 $sql .=
" t.remise,";
2934 $sql .=
" t.fk_remise_except,";
2935 $sql .=
" t.subprice,";
2936 $sql .=
" t.price_ht,";
2937 $sql .=
" t.total_ht,";
2938 $sql .=
" t.total_tva,";
2939 $sql .=
" t.total_localtax1,";
2940 $sql .=
" t.total_localtax2,";
2941 $sql .=
" t.total_ttc,";
2942 $sql .=
" t.fk_product_fournisseur_price as fk_fournprice,";
2943 $sql .=
" t.buy_price_ht as pa_ht,";
2944 $sql .=
" t.info_bits,";
2945 $sql .=
" t.fk_user_author,";
2946 $sql .=
" t.fk_user_ouverture,";
2947 $sql .=
" t.fk_user_cloture,";
2948 $sql .=
" t.commentaire,";
2949 $sql .=
" t.fk_unit";
2950 $sql .=
" FROM ".MAIN_DB_PREFIX.
"contratdet as t LEFT JOIN ".MAIN_DB_PREFIX.
"product as p ON p.rowid = t.fk_product";
2952 $sql .=
" WHERE t.rowid = ".((int) $id);
2955 $sql .=
" WHERE t.rowid = '".$this->db->escape($ref).
"'";
2958 dol_syslog(get_class($this).
"::fetch", LOG_DEBUG);
2962 $obj = $this->
db->fetch_object(
$resql);
2964 $this->
id = $obj->rowid;
2965 $this->
ref = $obj->rowid;
2967 $this->tms = $this->
db->jdate($obj->tms);
2968 $this->fk_contrat = $obj->fk_contrat;
2969 $this->fk_product = $obj->fk_product;
2970 $this->statut = $obj->statut;
2971 $this->product_ref = $obj->product_ref;
2972 $this->product_label = $obj->product_label;
2973 $this->product_description = $obj->product_description;
2974 $this->product_type = $obj->product_type;
2975 $this->label = $obj->label;
2977 $this->date_commande = $this->
db->jdate($obj->date_commande);
2979 $this->date_start = $this->
db->jdate($obj->date_ouverture_prevue);
2980 $this->date_start_real = $this->
db->jdate($obj->date_ouverture);
2981 $this->date_end = $this->
db->jdate($obj->date_fin_validite);
2982 $this->date_end_real = $this->
db->jdate($obj->date_cloture);
2984 $this->date_ouverture_prevue = $this->
db->jdate($obj->date_ouverture_prevue);
2985 $this->date_ouverture = $this->
db->jdate($obj->date_ouverture);
2986 $this->date_fin_validite = $this->
db->jdate($obj->date_fin_validite);
2987 $this->date_cloture = $this->
db->jdate($obj->date_cloture);
2989 $this->tva_tx = $obj->tva_tx;
2990 $this->vat_src_code = $obj->vat_src_code;
2991 $this->localtax1_tx = $obj->localtax1_tx;
2992 $this->localtax2_tx = $obj->localtax2_tx;
2993 $this->localtax1_type = $obj->localtax1_type;
2994 $this->localtax2_type = $obj->localtax2_type;
2995 $this->qty = $obj->qty;
2996 $this->remise_percent = $obj->remise_percent;
2997 $this->fk_remise_except = $obj->fk_remise_except;
2998 $this->subprice = $obj->subprice;
2999 $this->price_ht = $obj->price_ht;
3000 $this->total_ht = $obj->total_ht;
3001 $this->total_tva = $obj->total_tva;
3002 $this->total_localtax1 = $obj->total_localtax1;
3003 $this->total_localtax2 = $obj->total_localtax2;
3004 $this->total_ttc = $obj->total_ttc;
3005 $this->info_bits = $obj->info_bits;
3006 $this->fk_user_author = $obj->fk_user_author;
3007 $this->fk_user_ouverture = $obj->fk_user_ouverture;
3008 $this->fk_user_cloture = $obj->fk_user_cloture;
3009 $this->commentaire = $obj->commentaire;
3010 $this->fk_fournprice = $obj->fk_fournprice;
3012 $marginInfos =
getMarginInfos($obj->subprice, $obj->remise_percent, $obj->tva_tx, $obj->localtax1_tx, $obj->localtax2_tx, $this->fk_fournprice, $obj->pa_ht);
3013 $this->pa_ht = $marginInfos[0];
3014 $this->fk_unit = $obj->fk_unit;
3023 $this->error =
"Error ".$this->db->lasterror();
3036 public function update($user, $notrigger = 0)
3038 global $conf, $langs, $mysoc;
3043 $this->fk_contrat = (int) $this->fk_contrat;
3044 $this->fk_product = (int) $this->fk_product;
3045 $this->statut = (int) $this->statut;
3046 $this->label = trim($this->label);
3048 $this->vat_src_code = trim($this->vat_src_code);
3049 $this->tva_tx = trim($this->tva_tx);
3050 $this->localtax1_tx = trim($this->localtax1_tx);
3051 $this->localtax2_tx = trim($this->localtax2_tx);
3052 $this->qty = trim($this->qty);
3053 $this->remise_percent = trim($this->remise_percent);
3054 $this->fk_remise_except = (int) $this->fk_remise_except;
3055 $this->subprice =
price2num($this->subprice);
3056 $this->price_ht =
price2num($this->price_ht);
3057 $this->total_ht = trim($this->total_ht);
3058 $this->total_tva = trim($this->total_tva);
3059 $this->total_localtax1 = trim($this->total_localtax1);
3060 $this->total_localtax2 = trim($this->total_localtax2);
3061 $this->total_ttc = trim($this->total_ttc);
3062 $this->info_bits = trim($this->info_bits);
3063 $this->fk_user_author = (int) $this->fk_user_author;
3064 $this->fk_user_ouverture = (int) $this->fk_user_ouverture;
3065 $this->fk_user_cloture = (int) $this->fk_user_cloture;
3066 $this->commentaire = trim($this->commentaire);
3068 if (empty($this->price_ht)) {
3069 $this->price_ht = 0;
3071 if (empty($this->total_ht)) {
3072 $this->total_ht = 0;
3074 if (empty($this->total_tva)) {
3075 $this->total_tva = 0;
3077 if (empty($this->total_ttc)) {
3078 $this->total_ttc = 0;
3080 if (empty($this->localtax1_tx)) {
3081 $this->localtax1_tx = 0;
3083 if (empty($this->localtax2_tx)) {
3084 $this->localtax2_tx = 0;
3086 if (empty($this->remise_percent)) {
3087 $this->remise_percent = 0;
3090 if (empty($this->date_start)) {
3093 if (empty($this->date_start_real)) {
3096 if (empty($this->date_end)) {
3099 if (empty($this->date_end_real)) {
3113 $tabprice =
calcul_price_total($this->qty, $this->price_ht, $this->remise_percent, $this->tva_tx, $this->localtax1_tx, $this->localtax2_tx, 0,
'HT', 0, 1, $mysoc, $localtaxes_type);
3114 $this->total_ht = $tabprice[0];
3115 $this->total_tva = $tabprice[1];
3116 $this->total_ttc = $tabprice[2];
3117 $this->total_localtax1 = $tabprice[9];
3118 $this->total_localtax2 = $tabprice[10];
3120 if (empty($this->pa_ht)) {
3125 if ($this->pa_ht == 0) {
3126 if (($result = $this->
defineBuyPrice($this->subprice, $this->remise_percent, $this->fk_product)) < 0) {
3129 $this->pa_ht = $result;
3137 $this->oldcopy->fetch($this->
id);
3140 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"contratdet SET";
3141 $sql .=
" fk_contrat=".((int) $this->fk_contrat).
",";
3142 $sql .=
" fk_product=".($this->fk_product ?
"'".$this->db->escape($this->fk_product).
"'" :
'null').
",";
3143 $sql .=
" statut=".((int) $this->statut).
",";
3144 $sql .=
" label='".$this->db->escape($this->label).
"',";
3145 $sql .=
" description='".$this->db->escape($this->
description).
"',";
3146 $sql .=
" date_commande=".($this->date_commande !=
'' ?
"'".$this->db->idate($this->date_commande).
"'" :
"null").
",";
3147 $sql .=
" date_ouverture_prevue=".($this->date_ouverture_prevue !=
'' ?
"'".$this->db->idate($this->date_ouverture_prevue).
"'" :
"null").
",";
3148 $sql .=
" date_ouverture=".($this->date_ouverture !=
'' ?
"'".$this->db->idate($this->date_ouverture).
"'" :
"null").
",";
3149 $sql .=
" date_fin_validite=".($this->date_fin_validite !=
'' ?
"'".$this->db->idate($this->date_fin_validite).
"'" :
"null").
",";
3150 $sql .=
" date_cloture=".($this->date_cloture !=
'' ?
"'".$this->db->idate($this->date_cloture).
"'" :
"null").
",";
3151 $sql .=
" vat_src_code='".$this->db->escape($this->vat_src_code).
"',";
3152 $sql .=
" tva_tx=".price2num($this->tva_tx).
",";
3153 $sql .=
" localtax1_tx=".price2num($this->localtax1_tx).
",";
3154 $sql .=
" localtax2_tx=".price2num($this->localtax2_tx).
",";
3155 $sql .=
" qty=".price2num($this->qty).
",";
3156 $sql .=
" remise_percent=".price2num($this->remise_percent).
",";
3157 $sql .=
" remise=".($this->remise ?
price2num($this->remise) :
"null").
",";
3158 $sql .=
" fk_remise_except=".($this->fk_remise_except > 0 ? $this->fk_remise_except :
"null").
",";
3159 $sql .=
" subprice=".($this->subprice !=
'' ? $this->subprice :
"null").
",";
3160 $sql .=
" price_ht=".($this->price_ht !=
'' ? $this->price_ht :
"null").
",";
3161 $sql .=
" total_ht=".$this->total_ht.
",";
3162 $sql .=
" total_tva=".$this->total_tva.
",";
3163 $sql .=
" total_localtax1=".$this->total_localtax1.
",";
3164 $sql .=
" total_localtax2=".$this->total_localtax2.
",";
3165 $sql .=
" total_ttc=".$this->total_ttc.
",";
3166 $sql .=
" fk_product_fournisseur_price=".(!empty($this->fk_fournprice) ? $this->fk_fournprice :
"NULL").
",";
3167 $sql .=
" buy_price_ht='".price2num($this->pa_ht).
"',";
3168 $sql .=
" info_bits='".$this->db->escape($this->info_bits).
"',";
3169 $sql .=
" fk_user_author=".($this->fk_user_author >= 0 ? $this->fk_user_author :
"NULL").
",";
3170 $sql .=
" fk_user_ouverture=".($this->fk_user_ouverture > 0 ? $this->fk_user_ouverture :
"NULL").
",";
3171 $sql .=
" fk_user_cloture=".($this->fk_user_cloture > 0 ? $this->fk_user_cloture :
"NULL").
",";
3172 $sql .=
" commentaire='".$this->db->escape($this->commentaire).
"',";
3173 $sql .=
" fk_unit=".(!$this->fk_unit ?
'NULL' : $this->fk_unit);
3174 $sql .=
" WHERE rowid=".((int) $this->
id);
3176 dol_syslog(get_class($this).
"::update", LOG_DEBUG);
3179 $this->error =
"Error ".$this->db->lasterror();
3191 if (!$error && !empty($conf->global->CONTRACT_SYNC_PLANNED_DATE_OF_SERVICES)) {
3192 if ($this->date_ouverture_prevue != $this->oldcopy->date_ouverture_prevue) {
3193 $sql =
'UPDATE '.MAIN_DB_PREFIX.
'contratdet SET';
3194 $sql .=
" date_ouverture_prevue = ".($this->date_ouverture_prevue !=
'' ?
"'".$this->db->idate($this->date_ouverture_prevue).
"'" :
"null");
3195 $sql .=
" WHERE fk_contrat = ".((int) $this->fk_contrat);
3200 $this->error =
"Error ".$this->db->lasterror();
3203 if ($this->date_fin_validite != $this->oldcopy->date_fin_validite) {
3204 $sql =
'UPDATE '.MAIN_DB_PREFIX.
'contratdet SET';
3205 $sql .=
" date_fin_validite = ".($this->date_fin_validite !=
'' ?
"'".$this->db->idate($this->date_fin_validite).
"'" :
"null");
3206 $sql .=
" WHERE fk_contrat = ".((int) $this->fk_contrat);
3211 $this->error =
"Error ".$this->db->lasterror();
3216 if (!$error && !$notrigger) {
3218 $result = $this->
call_trigger(
'LINECONTRACT_MODIFY', $user);
3221 $this->
db->rollback();
3227 $this->
db->commit();
3230 $this->
db->rollback();
3231 $this->errors[] = $this->error;
3250 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"contratdet SET";
3251 $sql .=
" total_ht=".price2num($this->total_ht,
'MT').
"";
3252 $sql .=
",total_tva=".price2num($this->total_tva,
'MT').
"";
3253 $sql .=
",total_localtax1=".price2num($this->total_localtax1,
'MT').
"";
3254 $sql .=
",total_localtax2=".price2num($this->total_localtax2,
'MT').
"";
3255 $sql .=
",total_ttc=".price2num($this->total_ttc,
'MT').
"";
3256 $sql .=
" WHERE rowid = ".((int) $this->
id);
3258 dol_syslog(get_class($this).
"::update_total", LOG_DEBUG);
3262 $this->
db->commit();
3265 $this->error = $this->
db->error();
3266 $this->
db->rollback();
3280 global $conf, $user;
3285 $sql =
"INSERT INTO ".MAIN_DB_PREFIX.
"contratdet";
3286 $sql .=
" (fk_contrat, label, description, fk_product, qty, vat_src_code, tva_tx,";
3287 $sql .=
" localtax1_tx, localtax2_tx, localtax1_type, localtax2_type, remise_percent, subprice,";
3288 $sql .=
" total_ht, total_tva, total_localtax1, total_localtax2, total_ttc,";
3289 $sql .=
" info_bits,";
3290 $sql .=
" price_ht, remise, fk_product_fournisseur_price, buy_price_ht";
3291 if ($this->date_ouverture_prevue > 0) {
3292 $sql .=
",date_ouverture_prevue";
3294 if ($this->date_fin_validite > 0) {
3295 $sql .=
",date_fin_validite";
3297 $sql .=
") VALUES ($this->fk_contrat, '', '".$this->db->escape($this->
description).
"',";
3298 $sql .= ($this->fk_product > 0 ? $this->fk_product :
"null").
",";
3299 $sql .=
" '".$this->db->escape($this->qty).
"',";
3300 $sql .=
" '".$this->db->escape($this->vat_src_code).
"',";
3301 $sql .=
" '".$this->db->escape($this->tva_tx).
"',";
3302 $sql .=
" '".$this->db->escape($this->localtax1_tx).
"',";
3303 $sql .=
" '".$this->db->escape($this->localtax2_tx).
"',";
3304 $sql .=
" '".$this->db->escape($this->localtax1_type).
"',";
3305 $sql .=
" '".$this->db->escape($this->localtax2_type).
"',";
3306 $sql .=
" ".price2num($this->remise_percent).
",".
price2num($this->subprice).
",";
3307 $sql .=
" ".price2num($this->total_ht).
",".
price2num($this->total_tva).
",".
price2num($this->total_localtax1).
",".
price2num($this->total_localtax2).
",".
price2num($this->total_ttc).
",";
3308 $sql .=
" '".$this->db->escape($this->info_bits).
"',";
3309 $sql .=
" ".price2num($this->price_ht).
",".
price2num($this->remise).
",";
3310 if ($this->fk_fournprice > 0) {
3311 $sql .=
' '.((int) $this->fk_fournprice).
',';
3315 if ($this->pa_ht > 0) {
3316 $sql .=
' '.((float)
price2num($this->pa_ht));
3320 if ($this->date_ouverture > 0) {
3321 $sql .=
",'".$this->db->idate($this->date_ouverture).
"'";
3323 if ($this->date_cloture > 0) {
3324 $sql .=
",'".$this->db->idate($this->date_cloture).
"'";
3328 dol_syslog(get_class($this).
"::insert", LOG_DEBUG);
3332 $this->
id = $this->
db->last_insert_id(MAIN_DB_PREFIX.
'contratdet');
3338 $this->
db->rollback();
3345 $result = $this->
call_trigger(
'LINECONTRACT_INSERT', $user);
3347 $this->
db->rollback();
3353 $this->
db->commit();
3356 $this->
db->rollback();
3357 $this->error = $this->
db->error().
" sql=".$sql;
3372 public function active_line($user, $date, $date_end =
'', $comment =
'')
3375 global $langs, $conf;
3381 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"contratdet SET statut = ".ContratLigne::STATUS_OPEN.
",";
3382 $sql .=
" date_ouverture = ".(dol_strlen($date) != 0 ?
"'".$this->db->idate($date).
"'" :
"null").
",";
3383 if ($date_end >= 0) {
3384 $sql .=
" date_fin_validite = ".(dol_strlen($date_end) != 0 ?
"'".$this->db->idate($date_end).
"'" :
"null").
",";
3386 $sql .=
" fk_user_ouverture = ".((int) $user->id).
",";
3387 $sql .=
" date_cloture = null,";
3388 $sql .=
" commentaire = '".$this->db->escape($comment).
"'";
3389 $sql .=
" WHERE rowid = ".((int) $this->
id).
" AND (statut = ".ContratLigne::STATUS_INITIAL.
" OR statut = ".ContratLigne::STATUS_CLOSED.
")";
3391 dol_syslog(get_class($this).
"::active_line", LOG_DEBUG);
3395 $result = $this->
call_trigger(
'LINECONTRACT_ACTIVATE', $user);
3402 $this->statut = ContratLigne::STATUS_OPEN;
3403 $this->date_ouverture = $date;
3404 $this->date_fin_validite = $date_end;
3405 $this->fk_user_ouverture = $user->id;
3406 $this->date_cloture =
null;
3407 $this->commentaire = $comment;
3409 $this->
db->commit();
3412 $this->
db->rollback();
3416 $this->error = $this->
db->lasterror();
3417 $this->
db->rollback();
3432 public function close_line($user, $date_end, $comment =
'', $notrigger = 0)
3435 global $langs, $conf;
3438 $this->date_cloture = $date_end;
3439 $this->fk_user_cloture = $user->id;
3440 $this->commentaire = $comment;
3448 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"contratdet SET statut = ".((int) ContratLigne::STATUS_CLOSED).
",";
3449 $sql .=
" date_cloture = '".$this->db->idate($date_end).
"',";
3450 $sql .=
" fk_user_cloture = ".((int) $user->id).
",";
3451 $sql .=
" commentaire = '".$this->db->escape($comment).
"'";
3452 $sql .=
" WHERE rowid = ".((int) $this->
id).
" AND statut = ".((int) ContratLigne::STATUS_OPEN);
3458 $result = $this->
call_trigger(
'LINECONTRACT_CLOSE', $user);
3461 $this->
db->rollback();
3467 $this->
db->commit();
3470 $this->error = $this->
db->lasterror();
3471 $this->
db->rollback();