diff --git a/htdocs/admin/notification.php b/htdocs/admin/notification.php index bc1c95aa688..ff47db34030 100644 --- a/htdocs/admin/notification.php +++ b/htdocs/admin/notification.php @@ -33,7 +33,7 @@ require_once DOL_DOCUMENT_ROOT.'/core/lib/admin.lib.php'; require_once DOL_DOCUMENT_ROOT.'/core/triggers/interface_50_modNotification_Notification.class.php'; // Load translation files required by the page -$langs->loadLangs(array('admin', 'other', 'orders', 'propal', 'bills', 'errors', 'mails')); +$langs->loadLangs(array('admin', 'other', 'orders', 'propal', 'bills', 'errors', 'mails', 'contracts')); // Security check if (!$user->admin) { @@ -295,6 +295,8 @@ foreach ($listofnotifiedevents as $notifiedevent) { $elementLabel = $langs->trans('Shipping'); } elseif ($notifiedevent['elementtype'] == 'expensereport' || $notifiedevent['elementtype'] == 'expense_report') { $elementLabel = $langs->trans('ExpenseReport'); + } elseif ($notifiedevent['elementtype'] == 'contrat') { + $elementLabel = $langs->trans('Contract'); } if ($notifiedevent['elementtype'] == 'propal') { @@ -315,6 +317,8 @@ foreach ($listofnotifiedevents as $notifiedevent) { $model = 'invoice_supplier_send'; } elseif ($notifiedevent['elementtype'] == 'member') { $model = 'member'; + } elseif ($notifiedevent['elementtype'] == 'contrat') { + $model = 'contract_send'; } $constantes[$notifiedevent['code'].'_TEMPLATE'] = array('type'=>'emailtemplate:'.$model, 'label'=>$label); @@ -435,11 +439,14 @@ foreach ($listofnotifiedevents as $notifiedevent) { } elseif ($notifiedevent['elementtype'] == 'expensereport' || $notifiedevent['elementtype'] == 'expense_report') { $elementPicto = 'expensereport'; $elementLabel = $langs->trans('ExpenseReport'); + } elseif ($notifiedevent['elementtype'] == 'contrat') { + $elementPicto = 'contract'; + $elementLabel = $langs->trans('Contract'); } elseif ($notifiedevent['elementtype'] == 'agenda') { $elementPicto = 'action'; } - $labelfortrigger = 'AmountHT'; + $labelfortrigger = 'AmountHT'; $codehasnotrigger = 0; if (preg_match('/^(ACTION|HOLIDAY)/', $notifiedevent['code'])) { $codehasnotrigger++; diff --git a/htdocs/contrat/card.php b/htdocs/contrat/card.php index d79817ff836..f18e5daa63f 100644 --- a/htdocs/contrat/card.php +++ b/htdocs/contrat/card.php @@ -56,7 +56,7 @@ if (isModEnabled('project')) { require_once DOL_DOCUMENT_ROOT.'/core/class/extrafields.class.php'; // Load translation files required by the page -$langs->loadLangs(array("contracts", "orders", "companies", "bills", "products", 'compta')); +$langs->loadLangs(array("contracts", "orders", "companies", "bills", "products", 'compta', 'propal')); $action = GETPOST('action', 'aZ09'); $confirm = GETPOST('confirm', 'alpha'); @@ -175,6 +175,22 @@ if (empty($reshook)) { } else { setEventMessages($object->error, $object->errors, 'errors'); } + } elseif ($action == 'confirm_sign' && $confirm == 'yes' && $user->hasRight('contract', 'creer')) { + $result = $object->setSignedStatus($user, GETPOSTINT('signed_status'), 0, 'CONTRACT_MODIFY'); + if ($result >= 0) { + header('Location: ' . $_SERVER["PHP_SELF"] . '?id=' . $object->id); + exit; + } else { + $mesg = $object->error; + } + } elseif ($action == 'confirm_unsign' && $confirm == 'yes' && $user->hasRight('contract', 'creer')) { + $result = $object->setSignedStatus($user, $object::SIGNED_STATUSES['STATUS_NO_SIGNATURE'], 0, 'CONTRACT_MODIFY'); + if ($result >= 0) { + header('Location: ' . $_SERVER["PHP_SELF"] . '?id=' . $object->id); + exit; + } else { + $mesg = $object->error; + } } elseif ($action == 'confirm_closeline' && $confirm == 'yes' && $permissiontoactivate) { $date_end = ''; if (GETPOST('endmonth') && GETPOST('endday') && GETPOST('endyear')) { @@ -1363,6 +1379,31 @@ if ($action == 'create') { // Clone confirmation $formquestion = array(array('type' => 'other', 'name' => 'socid', 'label' => $langs->trans("SelectThirdParty"), 'value' => $form->select_company(GETPOSTINT('socid'), 'socid', $filter))); $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('ToClone'), $langs->trans('ConfirmCloneContract', $object->ref), 'confirm_clone', $formquestion, 'yes', 1); + } elseif ($action == 'sign') { + $text = $langs->trans('ConfirmSignContract'); + if (isModEnabled('notification')) { + require_once DOL_DOCUMENT_ROOT.'/core/class/notify.class.php'; + $notify = new Notify($db); + $text .= '
'; + $text .= $notify->confirmMessage('CONTRACT_MODIFY', $object->socid, $object); + } + $formquestion = []; + $formquestion[] = [ + 'type' => 'select', + 'name' => 'signed_status', + 'label' => ''.$langs->trans('SignStatus').'', + 'values' => $object->getSignedStatusLocalisedArray() + ]; + $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('SignContract'), $text, 'confirm_sign', $formquestion, 0, 1); + } elseif ($action == 'unsign') { + $text = $langs->trans('ConfirmUnsignContract'); + if (isModEnabled('notification')) { + require_once DOL_DOCUMENT_ROOT.'/core/class/notify.class.php'; + $notify = new Notify($db); + $text .= '
'; + $text .= $notify->confirmMessage('CONTRACT_MODIFY', $object->socid, $object); + } + $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('UnsignContract'), $text, 'confirm_unsign', '', 0, 1); } @@ -2246,6 +2287,15 @@ if ($action == 'create') { } } + // Sign + if ($object->status > Contrat::STATUS_DRAFT) { + if ($object->signed_status != Contrat::SIGNED_STATUSES['STATUS_SIGNED_ALL']) { + print '
' . $langs->trans("ContractSign") . '
'; + } else { + print '
' . $langs->trans("ContractUnsign") . '
'; + } + } + // Clone if ($user->hasRight('contrat', 'creer')) { unset($params['attr']['title']); diff --git a/htdocs/contrat/class/contrat.class.php b/htdocs/contrat/class/contrat.class.php index ba6a803d36e..741ee9f7197 100644 --- a/htdocs/contrat/class/contrat.class.php +++ b/htdocs/contrat/class/contrat.class.php @@ -238,7 +238,7 @@ class Contrat extends CommonObject 'tms' => array('type' => 'timestamp', 'label' => 'DateModification', 'enabled' => 1, 'visible' => -1, 'notnull' => 1, 'position' => 35), 'datec' => array('type' => 'datetime', 'label' => 'DateCreation', 'enabled' => 1, 'visible' => -1, 'position' => 40), 'date_contrat' => array('type' => 'datetime', 'label' => 'Date contrat', 'enabled' => 1, 'visible' => -1, 'position' => 45), - 'signed_status' => array('type' => 'smallint(6)', 'label' => 'SignedStatus', 'enabled' => 1, 'visible' => -1, 'position' => 50, 'arrayofkeyval' => array(0 => 'NoSignature', 1 => 'SignedSender', 2 => 'SignedReceiver', 9 => 'SignedAll')), + 'signed_status' => array('type' => 'smallint(6)', 'label' => 'SignedStatus', 'enabled' => 1, 'visible' => -1, 'position' => 50, 'arrayofkeyval' => array(0 => 'NoSignature', 1 => 'SignedSender', 2 => 'SignedReceiver', 3 => 'SignedReceiverOnline', 9 => 'SignedAll')), 'fk_soc' => array('type' => 'integer:Societe:societe/class/societe.class.php', 'label' => 'ThirdParty', 'enabled' => 'isModEnabled("societe")', 'visible' => -1, 'notnull' => 1, 'position' => 70), 'fk_projet' => array('type' => 'integer:Project:projet/class/project.class.php:1:(fk_statut:=:1)', 'label' => 'Project', 'enabled' => "isModEnabled('project')", 'visible' => -1, 'position' => 75), 'fk_commercial_signature' => array('type' => 'integer:User:user/class/user.class.php', 'label' => 'SaleRepresentative Signature', 'enabled' => 1, 'visible' => -1, 'position' => 80), @@ -259,26 +259,16 @@ class Contrat extends CommonObject const STATUS_VALIDATED = 1; const STATUS_CLOSED = 2; - /* - * No signature + /** + * Signed statuses dictionary. Label used as key for string localizations. */ - const STATUS_NO_SIGNATURE = 0; - - /* - * Signed by sender - */ - const STATUS_SIGNED_SENDER = 1; - - /* - * Signed by receiver - */ - const STATUS_SIGNED_RECEIVER = 2; - - /* - * Signed by all - */ - const STATUS_SIGNED_ALL = 9; // To handle future kind of signature (ex: tripartite contract) - + const SIGNED_STATUSES = [ + 'STATUS_NO_SIGNATURE' => 0, + 'STATUS_SIGNED_SENDER' => 1, + 'STATUS_SIGNED_RECEIVER' => 2, + 'STATUS_SIGNED_RECEIVER_ONLINE' => 3, + 'STATUS_SIGNED_ALL' => 9 // To handle future kind of signature (ex: tripartite contract) + ]; /** * Constructor @@ -697,6 +687,7 @@ class Contrat extends CommonObject $sql .= " ref_supplier, ref_customer,"; $sql .= " ref_ext,"; $sql .= " entity,"; + $sql .= " signed_status,"; $sql .= " date_contrat as datecontrat,"; $sql .= " fk_user_author,"; $sql .= " fk_projet as fk_project,"; @@ -738,6 +729,7 @@ class Contrat extends CommonObject $this->entity = $obj->entity; $this->statut = $obj->status; $this->status = $obj->status; + $this->signed_status = $obj->signed_status; $this->date_contrat = $this->db->jdate($obj->datecontrat); $this->date_creation = $this->db->jdate($obj->datecontrat); @@ -1017,7 +1009,7 @@ class Contrat extends CommonObject // Insert contract $sql = "INSERT INTO ".MAIN_DB_PREFIX."contrat (datec, fk_soc, fk_user_author, date_contrat,"; $sql .= " fk_commercial_signature, fk_commercial_suivi, fk_projet,"; - $sql .= " ref, entity, note_private, note_public, ref_customer, ref_supplier, ref_ext)"; + $sql .= " ref, entity, signed_status, note_private, note_public, ref_customer, ref_supplier, ref_ext)"; $sql .= " VALUES ('".$this->db->idate($now)."', ".((int) $this->socid).", ".((int) $user->id); $sql .= ", ".(dol_strlen($this->date_contrat) != 0 ? "'".$this->db->idate($this->date_contrat)."'" : "NULL"); $sql .= ",".($this->commercial_signature_id > 0 ? ((int) $this->commercial_signature_id) : "NULL"); @@ -1025,6 +1017,7 @@ class Contrat extends CommonObject $sql .= ",".($this->fk_project > 0 ? ((int) $this->fk_project) : "NULL"); $sql .= ", ".(dol_strlen($this->ref) <= 0 ? "null" : "'".$this->db->escape($this->ref)."'"); $sql .= ", ".((int) $conf->entity); + $sql .= ", ".((int) $this->signed_status); $sql .= ", ".(!empty($this->note_private) ? ("'".$this->db->escape($this->note_private)."'") : "NULL"); $sql .= ", ".(!empty($this->note_public) ? ("'".$this->db->escape($this->note_public)."'") : "NULL"); $sql .= ", ".(!empty($this->ref_customer) ? ("'".$this->db->escape($this->ref_customer)."'") : "NULL"); @@ -2001,6 +1994,7 @@ class Contrat extends CommonObject $text .= ($mode == 7 ? '' : ''); $text .= ($mode != 7 || $this->nbofservicesclosed > 0) ? ($this->nbofservicesclosed.ContratLigne::LibStatut(5, 3, -1, 'class="marginleft2"')) : ''; $text .= ($mode == 7 ? '' : ''); + $text .= $this->signed_status != '' ? ' '.$this->getLibSignedStatus(5) : ''; return $text; } else { return dolGetStatus($this->labelStatus[$status], $this->labelStatusShort[$status], '', $statusType, $mode); @@ -2934,8 +2928,6 @@ class Contrat extends CommonObject return $return; } - // @Todo getLibSignedStatus, LibSignedStatus - /** * Set signed status * @@ -2947,6 +2939,69 @@ class Contrat extends CommonObject */ public function setSignedStatus(User $user, int $status = 0, int $notrigger = 0, $triggercode = ''): int { + global $langs; + $langs->loadLangs(array('contracts', 'commercial')); + $this->signed_status = $status; + $this->context['signature'] = $status; + switch ($status) { + case 0: + $this->context['actionmsg2'] = $langs->transnoentitiesnoconv('ContractUnsignedInDolibarr'); + break; + case 1: + $this->context['actionmsg2'] = $langs->transnoentitiesnoconv('SignedSender'); + break; + case 2: + $this->context['actionmsg2'] = $langs->transnoentitiesnoconv('SignedReceiver'); + break; + case 3: + $this->context['actionmsg2'] = $langs->transnoentitiesnoconv('SignedReceiverOnline'); + break; + case 9: + $this->context['actionmsg2'] = $langs->transnoentitiesnoconv('SignedAll'); + break; + } return $this->setSignedStatusCommon($user, $status, $notrigger, $triggercode); } + + /** + * Returns the label for signed status + * + * @param int $mode 0=long label, 1=short label, 2=Picto + short label, 3=Picto, 4=Picto + long label, 5=Short label + Picto + * @return string Label + */ + public function getLibSignedStatus(int $mode = 0): string + { + global $langs; + $langs->load("commercial"); + $list_signed_status = $this->getSignedStatusLocalisedArray(); + $signed_status_label = $this->signed_status != '' ? $list_signed_status[$this->signed_status] : ''; + $signed_status_label_short = $this->signed_status != '' ? $list_signed_status[$this->signed_status] : ''; + $signed_status_code = 'status'.$this->signed_status; + return dolGetStatus($signed_status_label, $signed_status_label_short, '', $signed_status_code, $mode); + } + + /** + * Returns an array of signed statuses with associated localized labels + * + * @return array + */ + public function getSignedStatusLocalisedArray(): array + { + global $langs; + $langs->load("commercial"); + + $l10n_signed_status_labels = [ + self::SIGNED_STATUSES['STATUS_NO_SIGNATURE'] => 'NoSignature', + self::SIGNED_STATUSES['STATUS_SIGNED_SENDER'] => 'SignedSender', + self::SIGNED_STATUSES['STATUS_SIGNED_RECEIVER'] => 'SignedReceiver', + self::SIGNED_STATUSES['STATUS_SIGNED_RECEIVER_ONLINE'] => 'SignedReceiverOnline', + self::SIGNED_STATUSES['STATUS_SIGNED_ALL'] => 'SignedAll' + ]; + + $l10n_signed_status = []; + foreach (self::SIGNED_STATUSES as $signed_status_code) { + $l10n_signed_status[$signed_status_code] = $langs->transnoentitiesnoconv($l10n_signed_status_labels[$signed_status_code]); + } + return $l10n_signed_status; + } } diff --git a/htdocs/contrat/list.php b/htdocs/contrat/list.php index a79d3f31690..5760b6796ce 100644 --- a/htdocs/contrat/list.php +++ b/htdocs/contrat/list.php @@ -71,6 +71,7 @@ $search_ref_customer = GETPOST('search_ref_customer', 'alpha'); $search_ref_supplier = GETPOST('search_ref_supplier', 'alpha'); $search_all = (GETPOST('search_all', 'alphanohtml') != '') ? GETPOST('search_all', 'alphanohtml') : GETPOST('sall', 'alphanohtml'); $search_status = GETPOST('search_status', 'alpha'); +$search_signed_status = GETPOST('search_signed_status', 'alpha'); $search_user = GETPOST('search_user', 'intcomma'); $search_sale = GETPOST('search_sale', 'intcomma'); $search_product_category = GETPOST('search_product_category', 'intcomma'); @@ -194,6 +195,7 @@ $arrayfields = array( 'c.tms' => array('label' => $langs->trans("DateModificationShort"), 'checked' => 0, 'position' => 500), 'lower_planned_end_date' => array('label' => $langs->trans("LowerDateEndPlannedShort"), 'checked' => 1, 'position' => 900, 'help' => $langs->trans("LowerDateEndPlannedShort")), 'status' => array('label' => $langs->trans("Status"), 'checked' => 1, 'position' => 1000), + 'c.signed_status' =>array('label' => $langs->trans('SignedStatus'), 'checked' => 0, 'position' => 1001), ); // Extra fields include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_array_fields.tpl.php'; @@ -277,6 +279,7 @@ if (GETPOST('button_removefilter_x', 'alpha') || GETPOST('button_removefilter.x' $search_date_modif_endday = ""; $search_date_modif_end = ""; $search_status = ""; + $search_signed_status = ''; $toselect = array(); $search_type_thirdparty = ''; $searchCategoryCustomerList = array(); @@ -307,7 +310,7 @@ $now = dol_now(); $title = ""; $sql = 'SELECT'; -$sql .= " c.rowid, c.ref, c.datec as date_creation, c.tms as date_modification, c.date_contrat, c.statut, c.ref_customer, c.ref_supplier, c.note_private, c.note_public, c.entity,"; +$sql .= " c.rowid, c.ref, c.datec as date_creation, c.tms as date_modification, c.date_contrat, c.statut, c.ref_customer, c.ref_supplier, c.note_private, c.note_public, c.entity, c.signed_status,"; $sql .= ' s.rowid as socid, s.nom as name, s.name_alias, s.email, s.town, s.zip, s.fk_pays as country_id, s.client, s.code_client, s.status as company_status, s.logo as company_logo,'; $sql .= " typent.code as typent_code,"; $sql .= " state.code_departement as state_code, state.nom as state_name,"; @@ -489,6 +492,9 @@ if ($search_date_modif_start) { if ($search_date_modif_end) { $sql .= " AND c.tms <= '".$db->idate($search_date_modif_end)."'"; } +if ($search_signed_status != '' && $search_signed_status >= 0) { + $sql .= ' AND c.signed_status = '.urlencode($search_signed_status); +} // Add where from extra fields include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_sql.tpl.php'; @@ -713,6 +719,9 @@ if ($search_dfyear > 0) { if ($search_dfmonth > 0) { $param .= '&search_dfmonth='.urlencode((string) ($search_dfmonth)); } +if ($search_signed_status != '' && $search_signed_status >= 0) { + $param .= '&search_signed_status='.urlencode($search_signed_status); +} if ($search_sale > 0) { $param .= '&search_sale='.urlencode($search_sale); } @@ -933,6 +942,13 @@ if (!empty($arrayfields['c.date_contrat']['checked'])) { print ''; print ''; } +// Signed status +if (!empty($arrayfields['c.signed_status']['checked'])) { + print ''; + $list_signed_status = $object->getSignedStatusLocalisedArray(); + print $form->selectarray('search_signed_status', $list_signed_status, $search_signed_status, 1, 0, 0, '', 1, 0, 0, '', 'search_status'); + print ''; +} // Extra fields include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_input.tpl.php'; @@ -1045,6 +1061,10 @@ if (!empty($arrayfields['c.date_contrat']['checked'])) { print_liste_field_titre($arrayfields['c.date_contrat']['label'], $_SERVER["PHP_SELF"], "c.date_contrat", "", $param, '', $sortfield, $sortorder, 'center '); $totalarray['nbfield']++; // For the column action } +if (!empty($arrayfields['c.signed_status']['checked'])) { + print_liste_field_titre($arrayfields['c.signed_status']['label'], $_SERVER["PHP_SELF"], "c.signed_status", "", $param, '', $sortfield, $sortorder, 'center '); + $totalarray['nbfield']++; +} // Extra fields include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_title.tpl.php'; // Hook fields @@ -1103,6 +1123,7 @@ while ($i < $imaxinloop) { $contracttmp->nbofservicesopened = $obj->nb_running; $contracttmp->nbofservicesexpired = $obj->nb_expired; $contracttmp->nbofservicesclosed = $obj->nb_closed; + $contracttmp->signed_status = $obj->signed_status; $socstatic->id = $obj->socid; $socstatic->name = $obj->name; @@ -1296,6 +1317,13 @@ while ($i < $imaxinloop) { if (!empty($arrayfields['c.date_contrat']['checked'])) { print ''.dol_print_date($db->jdate($obj->date_contrat), 'day', 'tzserver').''; } + // Signed Status + if (!empty($arrayfields['c.signed_status']['checked'])) { + print ''.$contracttmp->getLibSignedStatus(5).''; + if (!$i) { + $totalarray['nbfield']++; + } + } // Extra fields include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_print_fields.tpl.php'; // Fields from hook diff --git a/htdocs/core/ajax/onlineSign.php b/htdocs/core/ajax/onlineSign.php index 9a5c32eb3ac..c87c4a5d74b 100644 --- a/htdocs/core/ajax/onlineSign.php +++ b/htdocs/core/ajax/onlineSign.php @@ -434,6 +434,8 @@ if ($action == "importSignature") { // Document format not supported to insert online signature. // We should just create an image file with the signature. } + $user = new User($db); + $object->setSignedStatus($user, $object::SIGNED_STATUSES['STATUS_SIGNED_RECEIVER_ONLINE'], 0, 'CONTRACT_MODIFY'); } } elseif ($mode == 'fichinter') { require_once DOL_DOCUMENT_ROOT . '/fichinter/class/fichinter.class.php'; diff --git a/htdocs/core/class/notify.class.php b/htdocs/core/class/notify.class.php index a4d31fb297a..9b0a0b952d9 100644 --- a/htdocs/core/class/notify.class.php +++ b/htdocs/core/class/notify.class.php @@ -149,7 +149,8 @@ class Notify 'EXPENSE_REPORT_APPROVE', 'HOLIDAY_VALIDATE', 'HOLIDAY_APPROVE', - 'ACTION_CREATE' + 'ACTION_CREATE', + 'CONTRACT_MODIFY' ); /** @@ -904,6 +905,13 @@ class Notify $object_type = 'action'; $mesg = $outputlangs->transnoentitiesnoconv("EMailTextActionAdded", $link); break; + case 'CONTRACT_MODIFY': + $link = ''.$newref.''; + $context_info = array_key_exists('signature', $object->context) ? $object->getLibSignedStatus() : ''; + $dir_output = $conf->contract->multidir_output; + $object_type = 'contract'; + $mesg = $outputlangs->transnoentitiesnoconv("EMailTextContractModified", $link, $context_info); + break; default: $object_type = $object->element; $dir_output = $conf->$object_type->multidir_output[$object->entity ? $object->entity : $conf->entity]."/".get_exdir(0, 0, 0, 1, $object, $object_type); @@ -1202,6 +1210,13 @@ class Notify $object_type = 'action'; $mesg = $langs->transnoentitiesnoconv("EMailTextActionAdded", $link); break; + case 'CONTRACT_MODIFY': + $link = ''.$newref.''; + $context_info = array_key_exists('signature', $object->context) ? $object->getLibSignedStatus() : ''; + $dir_output = $conf->contract->multidir_output; + $object_type = 'contrat'; + $mesg = $langs->transnoentitiesnoconv("EMailTextContractModified", $link, $context_info); + break; default: $object_type = $object->element; $dir_output = $conf->$object_type->multidir_output[$object->entity ? $object->entity : $conf->entity]."/".get_exdir(0, 0, 0, 1, $object, $object_type); diff --git a/htdocs/langs/en_US/contracts.lang b/htdocs/langs/en_US/contracts.lang index 7eb3335cd8f..bbf25bb2f0c 100644 --- a/htdocs/langs/en_US/contracts.lang +++ b/htdocs/langs/en_US/contracts.lang @@ -36,10 +36,18 @@ ActivateAllOnContract=Activate all services CloseAContract=Close a contract ConfirmDeleteAContract=Are you sure you want to delete this contract and all its services? ConfirmValidateContract=Are you sure you want to validate this contract under name %s? +ConfirmSignContract=Are you sure you want to set this contract as signed ? +ConfirmUnsignContract=Are you sure you want to set this contract as unsigned ? ConfirmActivateAllOnContract=This will open all services (not yet active). Are you sure you want to open all services? ConfirmCloseContract=This will close all services (expired or not). Are you sure you want to close this contract? ConfirmCloseService=Are you sure you want to close this service with date %s? ValidateAContract=Validate a contract +UnsignContract=Unsign contract +ContractSign=Set Signed +ContractUnsign=Set Unsigned +ContractSignedInDolibarr=Contract signed +ContractSignedOnline=Contract signed online +ContractUnsignedInDolibarr=Contract unsigned ActivateService=Activate service ConfirmActivateService=Are you sure you want to activate this service with date %s? RefContract=Contract reference diff --git a/htdocs/langs/en_US/other.lang b/htdocs/langs/en_US/other.lang index d711e30bdfc..8b8717414ba 100644 --- a/htdocs/langs/en_US/other.lang +++ b/htdocs/langs/en_US/other.lang @@ -70,6 +70,7 @@ Notify_BILL_SUPPLIER_VALIDATE=Vendor invoice validated Notify_BILL_SUPPLIER_PAYED=Vendor invoice paid Notify_BILL_SUPPLIER_SENTBYMAIL=Vendor invoice sent by mail Notify_BILL_SUPPLIER_CANCELED=Vendor invoice canceled +Notify_CONTRACT_MODIFY=Contract modified Notify_CONTRACT_VALIDATE=Contract validated Notify_FICHINTER_VALIDATE=Intervention validated Notify_FICHINTER_MODIFY=Intervention modified @@ -234,6 +235,7 @@ EMailTextExpenseReportApproved=Expense report %s has been approved. EMailTextHolidayValidated=Leave request %s has been validated. EMailTextHolidayApproved=Leave request %s has been approved. EMailTextActionAdded=The action %s has been added to the Agenda. +EMailTextContractModified=The contract %s has been modified. %s ImportedWithSet=Importation data set DolibarrNotification=Automatic notification ResizeDesc=Enter new width OR new height. Ratio will be kept during resizing...