diff --git a/htdocs/admin/facture_situation.php b/htdocs/admin/facture_situation.php index ad6f858df20..dc3ec771b16 100644 --- a/htdocs/admin/facture_situation.php +++ b/htdocs/admin/facture_situation.php @@ -76,6 +76,12 @@ dol_fiche_head($head, 'situation', $langs->trans("InvoiceSituation"), -1, 'invoi print load_fiche_titre($langs->trans("InvoiceSituation"),'',''); $var=0; + +print '
'; +print ''; + +_updateBtn(); + print ''; @@ -94,17 +100,40 @@ _print_input_form_part('INVOICE_SITUATION_DEFAULT_RETAINED_WARRANTY_PERCENT',$la +// Conditions paiements +$inputCount = empty($inputCount)?1:($inputCount+1); +print ''; +print ''; +print ''; +print ''; + + +print '
'.$langs->trans('PaymentConditionsShortRetainedWarranty').' '; +print ''; +$form->select_conditions_paiements($conf->global->INVOICE_SITUATION_DEFAULT_RETAINED_WARRANTY_COND_ID, 'value'.$inputCount, -1, 1); +print '
'; + +_updateBtn(); + +print '
'; + dol_fiche_end(); // End of page llxFooter(); $db->close(); +function _updateBtn(){ + global $langs; + print '
'; + print ''; + print '
'; +} + function _print_on_off($confkey, $title = false, $desc ='') { - global $var, $bc, $langs, $conf; + global $var, $bc, $langs; $var=!$var; - print ''; print ''.($title?$title:$langs->trans($confkey)); if(!empty($desc)) @@ -113,25 +142,21 @@ function _print_on_off($confkey, $title = false, $desc ='') } print ''; print ' '; - print ''; - print '
'; - print ''; - print ''; + print ''; print ajax_constantonoff($confkey); - print '
'; print ''; } function _print_input_form_part($confkey, $title = false, $desc ='', $metas = array(), $type='input', $help = false) { - global $var, $bc, $langs, $conf, $db; + global $var, $bc, $langs, $conf, $db, $inputCount; $var=!$var; - + $inputCount = empty($inputCount)?1:($inputCount+1); $form=new Form($db); $defaultMetas = array( - 'name' => $confkey + 'name' => 'value'.$inputCount ); if($type!='textarea'){ @@ -165,17 +190,14 @@ function _print_input_form_part($confkey, $title = false, $desc ='', $metas = ar print ''; print ' '; print ''; - print '
'; - print ''; - print ''; + print ''; + + print ''; if($type=='textarea'){ print ''; } else { print ''; } - - print ''; - print '
'; print ''; } diff --git a/htdocs/compta/facture/card.php b/htdocs/compta/facture/card.php index 6415ef4cdcd..c9e14304954 100644 --- a/htdocs/compta/facture/card.php +++ b/htdocs/compta/facture/card.php @@ -289,6 +289,21 @@ if (empty($reshook)) dol_print_error($db, $object->error); } + else if ($action == 'setretainedwarrantyconditions' && $user->rights->facture->creer) + { + $object->fetch($id); + $object->retained_warranty_fk_cond_reglement = 0; // To clean property + $result = $object->setRetainedWarrantyPaymentTerms(GETPOST('retained_warranty_fk_cond_reglement', 'int')); + if ($result < 0) dol_print_error($db, $object->error); + + $old_rw_date_lim_reglement = $object->retained_warranty_date_limit; + $new_rw_date_lim_reglement = $object->calculate_date_lim_reglement($object->retained_warranty_fk_cond_reglement); + if ($new_rw_date_lim_reglement > $old_rw_date_lim_reglement) $object->retained_warranty_date_limit = $new_rw_date_lim_reglement; + if ($object->retained_warranty_date_limit < $object->date) $object->retained_warranty_date_limit = $object->date; + $result = $object->update($user); + if ($result < 0) dol_print_error($db, $object->error); + } + else if ($action == 'setretainedwarranty' && $user->rights->facture->creer) { $object->fetch($id); @@ -877,7 +892,7 @@ if (empty($reshook)) $object->location_incoterms = GETPOST('location_incoterms', 'alpha'); $object->multicurrency_code = GETPOST('multicurrency_code', 'alpha'); $object->multicurrency_tx = GETPOST('originmulticurrency_tx', 'int'); - + // Proprietes particulieres a facture de remplacement $object->fk_facture_source = $_POST['fac_replacement']; $object->type = Facture::TYPE_REPLACEMENT; @@ -1163,13 +1178,25 @@ if (empty($reshook)) $object->location_incoterms = GETPOST('location_incoterms', 'alpha'); $object->multicurrency_code = GETPOST('multicurrency_code', 'alpha'); $object->multicurrency_tx = GETPOST('originmulticurrency_tx', 'int'); + + + if (GETPOST('type') == Facture::TYPE_SITUATION) { $object->situation_counter = 1; $object->situation_final = 0; $object->situation_cycle_ref = $object->newCycle(); - $object->retained_warranty = !empty($conf->global->INVOICE_USE_SITUATION_RETAINED_WARRANTY)?$conf->global->INVOICE_USE_SITUATION_RETAINED_WARRANTY:0; + + + $object->retained_warranty = GETPOST('retained_warranty', 'int'); + $object->retained_warranty_fk_cond_reglement = GETPOST('retained_warranty_fk_cond_reglement', 'int'); + + $retained_warranty_date_limit = GETPOST('retained_warranty_date_limit'); + if(!empty($retained_warranty_date_limit) && $db->jdate($retained_warranty_date_limit)){ + $object->retained_warranty_date_limit = $db->jdate($retained_warranty_date_limit); + } + $object->retained_warranty_date_limit = !empty($object->retained_warranty_date_limit) ? $object->retained_warranty_date_limit : $object->calculate_date_lim_reglement($object->retained_warranty_fk_cond_reglement); } $object->fetch_thirdparty(); @@ -1583,7 +1610,7 @@ if (empty($reshook)) $object->mode_reglement_id = GETPOST('mode_reglement_id','int'); $object->remise_absolue = GETPOST('remise_absolue','int'); $object->remise_percent = GETPOST('remise_percent','int'); - + // Proprietes particulieres a facture de remplacement $object->situation_counter = $object->situation_counter + 1; @@ -3082,6 +3109,44 @@ if ($action == 'create') print '' . $langs->trans('PaymentConditionsShort') . ''; $form->select_conditions_paiements(isset($_POST['cond_reglement_id']) ? $_POST['cond_reglement_id'] : $cond_reglement_id, 'cond_reglement_id'); print ''; + + if (! empty($conf->global->INVOICE_USE_SITUATION)) + { + if($conf->global->INVOICE_USE_SITUATION_RETAINED_WARRANTY){ + + $rwStyle = 'display:none;'; + if(GETPOST('type', 'int') == Facture::TYPE_SITUATION){ + $rwStyle = ''; + } + + + $retained_warranty = GETPOST('retained_warranty', 'int'); + $retained_warranty = !empty($retained_warranty)?$retained_warranty:$conf->global->INVOICE_SITUATION_DEFAULT_RETAINED_WARRANTY_PERCENT; + print '' . $langs->trans('RetainedWarranty') . ''; + print '%'; + + // Retained warranty payment term + print '' . $langs->trans('PaymentConditionsShortRetainedWarranty') . ''; + $retained_warranty_fk_cond_reglement = GETPOST('retained_warranty_fk_cond_reglement', 'int'); + $retained_warranty_fk_cond_reglement = !empty($retained_warranty_fk_cond_reglement)? $retained_warranty_fk_cond_reglement : $conf->global->INVOICE_SITUATION_DEFAULT_RETAINED_WARRANTY_COND_ID; + $form->select_conditions_paiements($retained_warranty_fk_cond_reglement, 'retained_warranty_fk_cond_reglement'); + print ''; + + print ''; + } + } // Payment mode print '' . $langs->trans('PaymentMode') . ''; @@ -3937,12 +4002,27 @@ else if ($id > 0 || ! empty($ref)) print ''; } - - if($object->type == Facture::TYPE_SITUATION && (!empty($object->retained_warranty) || !empty($conf->global->INVOICE_USE_SITUATION_RETAINED_WARRANTY)) ) + $displayWarranty = false; + if( !empty($object->situation_final) + && ( $object->type == Facture::TYPE_SITUATION && (!empty($object->retained_warranty) || !empty($conf->global->INVOICE_USE_SITUATION_RETAINED_WARRANTY)) ) + ) { + // Check if this situation invoice is 100% for real + if(!empty($object->lines)){ + $displayWarranty = true; + foreach( $object->lines as $i => $line ){ + if($line->product_type < 2 && $line->situation_percent < 100){ + $displayWarranty = false; + break; + } + } + } + + + // Retained Warranty - print ''; - print '
'; + print '
'; + print ''; if ($action != 'editretainedwarranty' && $user->rights->facture->creer){ @@ -3953,7 +4033,7 @@ else if ($id > 0 || ! empty($ref)) print ''; - - // Retained Warranty payment date limit - print '
'; print $langs->trans('RetainedWarranty'); print ''; if ($action == 'editretainedwarranty') { - print '
'; + print ''; print ''; print ''; print ''; @@ -3966,14 +4046,13 @@ else if ($id > 0 || ! empty($ref)) } print '
'; - print ''; + + + + + if($displayWarranty) + { + // Retained Warranty payment date limit + print ''; + } + } @@ -4442,16 +4566,17 @@ else if ($id > 0 || ! empty($ref)) // Billed print ''; - if(!empty($object->retained_warranty)){ + // Retained warranty : usualy use on construction industry + if(!empty($object->situation_final) && !empty($object->retained_warranty) && $displayWarranty){ // Billed - retained warranty $retainedWarranty = $object->total_ttc * $object->retained_warranty / 100; $billedWithRetainedWarranty = $object->total_ttc - $retainedWarranty ; - print ''; + print ''; // retained warranty print ''; } diff --git a/htdocs/compta/facture/class/facture.class.php b/htdocs/compta/facture/class/facture.class.php index 9c387f6630a..e108b526576 100644 --- a/htdocs/compta/facture/class/facture.class.php +++ b/htdocs/compta/facture/class/facture.class.php @@ -165,6 +165,8 @@ class Facture extends CommonInvoice public $retained_warranty; public $retained_warranty_date_limit; + + public $retained_warranty_fk_cond_reglement; /** * Standard invoice @@ -345,8 +347,8 @@ class Facture extends CommonInvoice $this->note_private=trim($this->note_private); $this->note_private=dol_concatdesc($this->note_private, $langs->trans("GeneratedFromRecurringInvoice", $_facrec->ref)); - $this->retained_warranty = floatval($this->retained_warranty); + $this->array_options=$_facrec->array_options; //if (! $this->remise) $this->remise = 0; @@ -356,6 +358,7 @@ class Facture extends CommonInvoice $this->linked_objects = $_facrec->linkedObjectsIds; $forceduedate = $this->calculate_date_lim_reglement(); + // For recurring invoices, update date and number of last generation of recurring template invoice, before inserting new invoice if ($_facrec->frequency > 0) @@ -407,7 +410,7 @@ class Facture extends CommonInvoice // Define due date if not already defined $datelim=(empty($forceduedate)?$this->calculate_date_lim_reglement():$forceduedate); - + // Insert into database $socid = $this->socid; @@ -435,6 +438,7 @@ class Facture extends CommonInvoice $sql.= ", multicurrency_tx"; $sql.= ", retained_warranty"; $sql.= ", retained_warranty_date_limit"; + $sql.= ", retained_warranty_fk_cond_reglement"; $sql.= ")"; $sql.= " VALUES ("; $sql.= "'(PROV)'"; @@ -468,10 +472,11 @@ class Facture extends CommonInvoice $sql.= ", '".$this->db->escape($this->multicurrency_code)."'"; $sql.= ", ".(double) $this->multicurrency_tx; $sql.= ", ".(empty($this->retained_warranty)?"0":$this->db->escape($this->retained_warranty)); - $sql.= ", '".$this->db->idate($this->retained_warranty_date_limit)."'"; + $sql.= ", ".(!empty($this->retained_warranty_date_limit)?"'".$this->db->idate($this->retained_warranty_date_limit)."'":'NULL'); + $sql.= ", ".(int) $this->retained_warranty_fk_cond_reglement; $sql.=")"; - + $resql=$this->db->query($sql); if ($resql) { @@ -1288,7 +1293,7 @@ class Facture extends CommonInvoice $sql.= ', c.code as cond_reglement_code, c.libelle as cond_reglement_libelle, c.libelle_facture as cond_reglement_libelle_doc'; $sql.= ', f.fk_incoterms, f.location_incoterms'; $sql.= ", i.libelle as libelle_incoterms"; - $sql.= ", f.retained_warranty as retained_warranty, f.retained_warranty_date_limit as retained_warranty_date_limit"; + $sql.= ", f.retained_warranty as retained_warranty, f.retained_warranty_date_limit as retained_warranty_date_limit, f.retained_warranty_fk_cond_reglement as retained_warranty_fk_cond_reglement"; $sql.= ' FROM '.MAIN_DB_PREFIX.'facture as f'; $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_payment_term as c ON f.fk_cond_reglement = c.rowid'; $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_paiement as p ON f.fk_mode_reglement = p.id'; @@ -1356,8 +1361,9 @@ class Facture extends CommonInvoice $this->situation_cycle_ref = $obj->situation_cycle_ref; $this->situation_counter = $obj->situation_counter; $this->situation_final = $obj->situation_final; - $this->retained_warranty = $obj->retained_warranty; - $this->retained_warranty_date_limit = $this->db->jdate($obj->retained_warranty_date_limit); + $this->retained_warranty = $obj->retained_warranty; + $this->retained_warranty_date_limit = $this->db->jdate($obj->retained_warranty_date_limit); + $this->retained_warranty_fk_cond_reglement = $obj->retained_warranty_fk_cond_reglement; $this->extraparams = (array) json_decode($obj->extraparams, true); // Incoterms @@ -1628,7 +1634,8 @@ class Facture extends CommonInvoice $sql.= " situation_counter=".(empty($this->situation_counter)?"null":$this->db->escape($this->situation_counter)).","; $sql.= " situation_final=".(empty($this->situation_counter)?"0":$this->db->escape($this->situation_counter)).","; $sql.= " retained_warranty=".(empty($this->retained_warranty)?"0":$this->db->escape($this->retained_warranty)).","; - $sql.= " retained_warranty_date_limit=".(strval($this->retained_warranty_date_limit)!='' ? "'".$this->db->idate($this->retained_warranty_date_limit)."'" : 'null'); + $sql.= " retained_warranty_date_limit=".(strval($this->retained_warranty_date_limit)!='' ? "'".$this->db->idate($this->retained_warranty_date_limit)."'" : 'null').","; + $sql.= " retained_warranty_fk_cond_reglement=".(isset($this->retained_warranty_fk_cond_reglement)?intval($this->retained_warranty_fk_cond_reglement):"null"); $sql.= " WHERE rowid=".$this->id; $this->db->begin(); diff --git a/htdocs/core/class/commonobject.class.php b/htdocs/core/class/commonobject.class.php index 5e528f6a1d0..37f61e01f32 100644 --- a/htdocs/core/class/commonobject.class.php +++ b/htdocs/core/class/commonobject.class.php @@ -1906,6 +1906,43 @@ abstract class CommonObject return -2; } } + + /** + * Change the retained warranty payments terms + * + * @param int $id Id of new payment terms + * @return int >0 if OK, <0 if KO + */ + function setRetainedWarrantyPaymentTerms($id) + { + dol_syslog(get_class($this).'::setRetainedWarrantyPaymentTerms('.$id.')'); + if ($this->statut >= 0 || $this->element == 'societe') + { + $fieldname = 'retained_warranty_fk_cond_reglement'; + + $sql = 'UPDATE '.MAIN_DB_PREFIX.$this->table_element; + $sql .= ' SET '.$fieldname.' = '.$id; + $sql .= ' WHERE rowid='.$this->id; + + if ($this->db->query($sql)) + { + $this->retained_warranty_fk_cond_reglement = $id; + return 1; + } + else + { + dol_syslog(get_class($this).'::setRetainedWarrantyPaymentTerms Erreur '.$sql.' - '.$this->db->error()); + $this->error=$this->db->error(); + return -1; + } + } + else + { + dol_syslog(get_class($this).'::setRetainedWarrantyPaymentTerms, status of the object is incompatible'); + $this->error='Status of the object is incompatible '.$this->statut; + return -2; + } + } /** * Define delivery address diff --git a/htdocs/install/mysql/migration/8.0.0-9.0.0.sql b/htdocs/install/mysql/migration/8.0.0-9.0.0.sql index fb7db220138..3eb266d3559 100644 --- a/htdocs/install/mysql/migration/8.0.0-9.0.0.sql +++ b/htdocs/install/mysql/migration/8.0.0-9.0.0.sql @@ -53,5 +53,6 @@ ALTER TABLE llx_payment_salary ADD COLUMN fk_projet integer DEFAULT NULL after a ALTER TABLE llx_facture ADD COLUMN retained_warranty real DEFAULT NULL after situation_final; ALTER TABLE llx_facture ADD COLUMN retained_warranty_date_limit date DEFAULT NULL after retained_warranty; +ALTER TABLE llx_facture ADD COLUMN retained_warranty_fk_cond_reglement integer DEFAULT NULL after retained_warranty_date_limit; diff --git a/htdocs/install/mysql/tables/llx_facture.sql b/htdocs/install/mysql/tables/llx_facture.sql index abdefedc944..f18ec0f521c 100644 --- a/htdocs/install/mysql/tables/llx_facture.sql +++ b/htdocs/install/mysql/tables/llx_facture.sql @@ -86,8 +86,9 @@ create table llx_facture situation_counter smallint, -- situation counter situation_final smallint, -- is the situation final ? - retained_warranty real DEFAULT NULL, -- % of retained warranty - retained_warranty_date_limit date DEFAULT NULL, + retained_warranty real DEFAULT NULL, -- % of retained warranty + retained_warranty_date_limit date DEFAULT NULL, + retained_warranty_fk_cond_reglement integer DEFAULT NULL, -- payment condition of retained warranty import_key varchar(14), extraparams varchar(255), -- for other parameters with json format diff --git a/htdocs/langs/en_US/bills.lang b/htdocs/langs/en_US/bills.lang index c547f385be0..c9f966b2e2a 100644 --- a/htdocs/langs/en_US/bills.lang +++ b/htdocs/langs/en_US/bills.lang @@ -552,3 +552,10 @@ AutoFillDateToShort=Set end date MaxNumberOfGenerationReached=Max number of gen. reached ToPayOn=To pay on %s RetainedWarranty=Retained Warranty +PaymentConditionsShortRetainedWarranty=Retained warranty payment terms +DefaultPaymentConditionsRetainedWarranty=Default retained warranty payment terms +setPaymentConditionsShortRetainedWarranty=Set retained warranty payment terms +setretainedwarranty=Set retained warranty +setretainedwarrantyDateLimit=Set retained warranty date limit +RetainedWarrantyDateLimit=Retained warranty date limit +RetainedWarrantyNeed100Percent=The situation invoice need to be at 100%% progress to be displayed on PDF
'; - print $langs->trans('RetainedWarrantyDateLimit'); + // Retained warranty payment term + print '
'; + print ''; - if ($action != 'editretainedwarrantydatelimit' && $user->rights->facture->creer){ - print ''; + if ($action != 'editretainedwarrantypaymentterms' && $user->rights->facture->creer){ + print ''; } print '
'; + print $langs->trans('PaymentConditionsShortRetainedWarranty'); print 'id . '">' . img_edit($langs->trans('setretainedwarrantyDateLimit'), 1) . 'id . '">' . img_edit($langs->trans('setPaymentConditionsShortRetainedWarranty'), 1) . '
'; @@ -3983,21 +4062,66 @@ else if ($id > 0 || ! empty($ref)) $defaultDate = $object->date; } - if ($action == 'editretainedwarrantydatelimit') + if ($action == 'editretainedwarrantypaymentterms') { //date('Y-m-d',$object->date_lim_reglement) print ''; - print ''; + print ''; print ''; - print ''; + $retained_warranty_fk_cond_reglement = GETPOST('retained_warranty_fk_cond_reglement', 'int'); + $retained_warranty_fk_cond_reglement = !empty($retained_warranty_fk_cond_reglement)? $retained_warranty_fk_cond_reglement : $object->retained_warranty_fk_cond_reglement; + $retained_warranty_fk_cond_reglement = !empty($retained_warranty_fk_cond_reglement)? $retained_warranty_fk_cond_reglement : $conf->global->INVOICE_SITUATION_DEFAULT_RETAINED_WARRANTY_COND_ID; + $form->select_conditions_paiements($retained_warranty_fk_cond_reglement, 'retained_warranty_fk_cond_reglement'); print ''; print ''; } else { - print dol_print_date($defaultDate); + print $form->form_conditions_reglement($_SERVER['PHP_SELF'] . '?facid=' . $object->id, $object->retained_warranty_fk_cond_reglement, 'none'); + if(!$displayWarranty){ + print img_picto($langs->trans('RetainedWarrantyNeed100Percent'), 'warning.png', 'class="pictowarning valignmiddle"'.($moreatt ? ($moreatt == '1' ? ' style="float: right"' : ' '.$moreatt): '')); + } } print '
'; + print ''; + if ($action != 'editretainedwarrantydatelimit' && $user->rights->facture->creer){ + print ''; + } + + print '
'; + print $langs->trans('RetainedWarrantyDateLimit'); + print 'id . '">' . img_edit($langs->trans('setretainedwarrantyDateLimit'), 1) . '
'; + print '
'; + $defaultDate = !empty($object->retained_warranty_date_limit)?$object->retained_warranty_date_limit:strtotime('-1 years', $object->date_lim_reglement); + if($object->date > $defaultDate){ + $defaultDate = $object->date; + } + + if ($action == 'editretainedwarrantydatelimit') + { + //date('Y-m-d',$object->date_lim_reglement) + print '
'; + print ''; + print ''; + print ''; + print ''; + print '
'; + } + else + { + print dol_print_date($object->retained_warranty_date_limit, 'day'); + } + print '
' . $langs->trans("Billed") . ' :' . price($object->total_ttc) . ' 
' . $langs->trans("ToPayOn", dol_print_date($object->date_lim_reglement)) . ' :' . price($billedWithRetainedWarranty) . ' 
' . $langs->trans("ToPayOn", dol_print_date($object->date_lim_reglement, 'day')) . ' :' . price($billedWithRetainedWarranty) . ' 
'; print $langs->trans("RetainedWarranty") . ' ('.$object->retained_warranty.'%)'; - print !empty($object->retained_warranty_date_limit)?' '.$langs->trans("ToPayOn", dol_print_date($object->retained_warranty_date_limit)):''; + print !empty($object->retained_warranty_date_limit)?' '.$langs->trans("ToPayOn", dol_print_date($object->retained_warranty_date_limit, 'day')):''; print ' :' . price($retainedWarranty) . '