diff --git a/htdocs/public/recruitment/index.php b/htdocs/public/recruitment/index.php
new file mode 100644
index 00000000000..0797ff20735
--- /dev/null
+++ b/htdocs/public/recruitment/index.php
@@ -0,0 +1,457 @@
+
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+/**
+ * \file htdocs/public/recruitment/index.php
+ * \ingroup recruitment
+ * \brief Public file to list jobs
+ */
+
+if (!defined('NOCSRFCHECK')) {
+ define('NOCSRFCHECK', '1');
+}
+// Do not check anti CSRF attack test
+if (!defined('NOREQUIREMENU')) {
+ define('NOREQUIREMENU', '1');
+}
+// If there is no need to load and show top and left menu
+if (!defined("NOLOGIN")) {
+ define("NOLOGIN", '1');
+}
+// If this page is public (can be called outside logged session)
+
+require '../../main.inc.php';
+require_once DOL_DOCUMENT_ROOT.'/recruitment/class/recruitmentjobposition.class.php';
+require_once DOL_DOCUMENT_ROOT.'/core/class/CMailFile.class.php';
+require_once DOL_DOCUMENT_ROOT.'/core/lib/security.lib.php';
+require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php';
+
+// Load translation files required by the page
+$langs->loadLangs(array("companies", "other", "recruitment"));
+
+// Get parameters
+$action = GETPOST('action', 'aZ09');
+$email = GETPOST('email', 'alpha');
+
+$object = new RecruitmentJobPosition($db);
+
+
+
+
+/*
+ * Actions
+ */
+
+// None
+
+
+
+/*
+ * View
+ */
+
+$form = new Form($db);
+$user_assign = new User($db);
+$user_create = new User($db);
+
+if (!$conf->global->RECRUITMENT_ENABLE_PUBLIC_INTERFACE) {
+ print '
';
+
+$display_ticket_list = 1;
+
+print '
';
+if ($display_ticket_list) {
+ // Filters
+ $search_fk_status = GETPOST("search_fk_status", 'alpha');
+ $search_subject = GETPOST("search_subject", 'alpha');
+ $search_type = GETPOST("search_type", 'alpha');
+ $search_category = GETPOST("search_category", 'alpha');
+ $search_severity = GETPOST("search_severity", 'alpha');
+ $search_fk_user_create = GETPOST("search_fk_user_create", 'int');
+ $search_fk_user_assign = GETPOST("search_fk_user_assign", 'int');
+
+ // Store current page url
+ $url_page_current = dol_buildpath('/public/ticket/list.php', 1);
+
+ // Do we click on purge search criteria ?
+ if (GETPOST("button_removefilter_x")) {
+ $search_fk_status = '';
+ $search_subject = '';
+ $search_type = '';
+ $search_category = '';
+ $search_severity = '';
+ $search_fk_user_create = '';
+ $search_fk_user_assign = '';
+ }
+
+ // fetch optionals attributes and labels
+ $extrafields = new ExtraFields($db);
+ $extrafields->fetch_name_optionals_label($object->table_element);
+
+ $search_array_options = $extrafields->getOptionalsFromPost($object->table_element, '', 'search_');
+
+ $filter = array();
+ $param = 'action=viewlist';
+
+ // Definition of fields for list
+ $arrayfields = array(
+ 't.datec' => array('label' => $langs->trans("Date"), 'checked' => 1),
+ 't.date_read' => array('label' => $langs->trans("TicketReadOn"), 'checked' => 0),
+ 't.date_close' => array('label' => $langs->trans("TicketCloseOn"), 'checked' => 0),
+ 't.ref' => array('label' => $langs->trans("Ref"), 'checked' => 1),
+ //'t.track_id' => array('label' => $langs->trans("IDTracking"), 'checked' => 0),
+ 't.fk_statut' => array('label' => $langs->trans("Status"), 'checked' => 1),
+ 't.subject' => array('label' => $langs->trans("Subject"), 'checked' => 1),
+ 'type.code' => array('label' => $langs->trans("Type"), 'checked' => 1),
+ 'category.code' => array('label' => $langs->trans("Category"), 'checked' => 1),
+ 'severity.code' => array('label' => $langs->trans("Severity"), 'checked' => 1),
+ 't.progress' => array('label' => $langs->trans("Progression"), 'checked' => 0),
+ //'t.fk_contract' => array('label' => $langs->trans("Contract"), 'checked' => 0),
+ 't.fk_user_create' => array('label' => $langs->trans("Author"), 'checked' => 1),
+ 't.fk_user_assign' => array('label' => $langs->trans("AssignedTo"), 'checked' => 0),
+
+ //'t.entity'=>array('label'=>$langs->trans("Entity"), 'checked'=>1, 'enabled'=>(! empty($conf->multicompany->enabled) && empty($conf->multicompany->transverse_mode))),
+ //'t.datec' => array('label' => $langs->trans("DateCreation"), 'checked' => 0, 'position' => 500),
+ //'t.tms' => array('label' => $langs->trans("DateModificationShort"), 'checked' => 0, 'position' => 2)
+ //'t.statut'=>array('label'=>$langs->trans("Status"), 'checked'=>1, 'position'=>1000),
+ );
+
+ // Extra fields
+ if (is_array($extrafields->attributes[$object->table_element]['label']) && count($extrafields->attributes[$object->table_element]['label'])) {
+ foreach ($extrafields->attributes[$object->table_element]['label'] as $key => $val) {
+ if ($extrafields->attributes[$object->table_element]['type'][$key] != 'separate') {
+ $arrayfields["ef.".$key] = array('label' => $extrafields->attributes[$object->table_element]['label'][$key], 'checked' => ($extrafields->attributes[$object->table_element]['list'][$key] < 0) ? 0 : 1, 'position' => $extrafields->attributes[$object->table_element]['pos'][$key], 'enabled' =>(abs($extrafields->attributes[$object->table_element]['list'][$key]) != 3) && $extrafields->attributes[$object->table_element]['perms'][$key]);
+ }
+ }
+ }
+ if (!empty($search_subject)) {
+ $filter['t.subject'] = $search_subject;
+ $param .= '&search_subject='.urlencode($search_subject);
+ }
+ if (!empty($search_type)) {
+ $filter['t.type_code'] = $search_type;
+ $param .= '&search_type='.urlencode($search_type);
+ }
+ if (!empty($search_category)) {
+ $filter['t.category_code'] = $search_category;
+ $param .= '&search_category='.urlencode($search_category);
+ }
+ if (!empty($search_severity)) {
+ $filter['t.severity_code'] = $search_severity;
+ $param .= '&search_severity='.urlencode($search_severity);
+ }
+ if (!empty($search_fk_user_assign)) {
+ // -1 value = all so no filter
+ if ($search_fk_user_assign > 0) {
+ $filter['t.fk_user_assign'] = $search_fk_user_assign;
+ $param .= '&search_fk_user_assign='.urlencode($search_fk_user_assign);
+ }
+ }
+ if (!empty($search_fk_user_create)) {
+ // -1 value = all so no filter
+ if ($search_fk_user_create > 0) {
+ $filter['t.fk_user_create'] = $search_fk_user_create;
+ $param .= '&search_fk_user_create='.urlencode($search_fk_user_create);
+ }
+ }
+ if ((isset($search_fk_status) && $search_fk_status != '') && $search_fk_status != '-1' && $search_fk_status != 'non_closed') {
+ $filter['t.fk_statut'] = $search_fk_status;
+ $param .= '&search_fk_status='.urlencode($search_fk_status);
+ }
+ if (isset($search_fk_status) && $search_fk_status == 'non_closed') {
+ $filter['t.fk_statut'] = array(0, 1, 3, 4, 5, 6);
+ $param .= '&search_fk_status=non_closed';
+ }
+
+ require DOL_DOCUMENT_ROOT.'/core/actions_changeselectedfields.inc.php';
+
+ $sortfield = GETPOST("sortfield", 'alpha');
+ $sortorder = GETPOST("sortorder", 'alpha');
+
+ if (!$sortfield) {
+ $sortfield = 't.datec';
+ }
+ if (!$sortorder) {
+ $sortorder = 'DESC';
+ }
+
+ $limit = $conf->liste_limit;
+
+ $page = GETPOSTISSET('pageplusone') ? (GETPOST('pageplusone') - 1) : GETPOST("page", 'int');
+ if (empty($page) || $page == -1) { $page = 0; } // If $page is not defined, or '' or -1
+ $offset = $limit * $page;
+ $pageprev = $page - 1;
+ $pagenext = $page + 1;
+
+ // Request SQL
+ $sql = "SELECT DISTINCT";
+ $sql .= " t.rowid,";
+ $sql .= " t.ref,";
+ $sql .= " t.track_id,";
+ $sql .= " t.fk_soc,";
+ $sql .= " t.fk_project,";
+ $sql .= " t.origin_email,";
+ $sql .= " t.fk_user_create, uc.lastname as user_create_lastname, uc.firstname as user_create_firstname,";
+ $sql .= " t.fk_user_assign, ua.lastname as user_assign_lastname, ua.firstname as user_assign_firstname,";
+ $sql .= " t.subject,";
+ $sql .= " t.message,";
+ $sql .= " t.fk_statut,";
+ $sql .= " t.resolution,";
+ $sql .= " t.progress,";
+ $sql .= " t.timing,";
+ $sql .= " t.type_code,";
+ $sql .= " t.category_code,";
+ $sql .= " t.severity_code,";
+ $sql .= " t.datec,";
+ $sql .= " t.date_read,";
+ $sql .= " t.date_close,";
+ $sql .= " t.tms,";
+ $sql .= " type.label as type_label, category.label as category_label, severity.label as severity_label";
+ // Add fields for extrafields
+ if (is_array($extrafields->attributes[$object->table_element]['label']) && count($extrafields->attributes[$object->table_element]['label'])) {
+ foreach ($extrafields->attributes[$object->table_element]['label'] as $key => $val)
+ $sql .= ($extrafields->attributes[$object->table_element]['type'][$key] != 'separate' ? ", ef.".$key.' as options_'.$key : '');
+ }
+ $sql .= " FROM ".MAIN_DB_PREFIX."recruitment_recruitmentjobposition as t";
+ $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."societe as s ON s.rowid=t.fk_soc";
+ $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."user as uc ON uc.rowid=t.fk_user_create";
+ if (is_array($extrafields->attributes[$object->table_element]['label']) && count($extrafields->attributes[$object->table_element]['label'])) {
+ $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."recruitment_recruitmentjobposition_extrafields as ef on (t.rowid = ef.fk_object)";
+ }
+ $sql .= " WHERE t.entity IN (".getEntity('recruitmentjobposition').")";
+ // Manage filter
+ if (!empty($filter)) {
+ foreach ($filter as $key => $value) {
+ if (strpos($key, 'date')) { // To allow $filter['YEAR(s.dated)']=>$year
+ $sql .= ' AND '.$key.' = \''.$value.'\'';
+ } elseif ($key == 't.fk_statut') {
+ if (is_array($value) && count($value) > 0) {
+ $sql .= 'AND '.$key.' IN ('.implode(',', $value).')';
+ } else {
+ $sql .= ' AND '.$key.' = '.$db->escape($value);
+ }
+ } else {
+ $sql .= ' AND '.$key.' LIKE \'%'.$value.'%\'';
+ }
+ }
+ }
+ $sql .= " ORDER BY ".$sortfield.' '.$sortorder;
+
+ $resql = $db->query($sql);
+ if ($resql) {
+ $num_total = $db->num_rows($resql);
+ if (!empty($limit)) {
+ $sql .= ' '.$db->plimit($limit + 1, $offset);
+ }
+
+ $resql = $db->query($sql);
+ if ($resql) {
+ $num = $db->num_rows($resql);
+ print_barre_liste($langs->trans('JobList'), $page, 'public/recruitment/list.php', $param, $sortfield, $sortorder, '', $num, $num_total, 'ticket');
+
+ // Search bar
+ print '
';
+
+ print '
";
+ print '';
+ }
+ }
+} else {
+ print '
';
+}
+
+
+print "
";
+
+// End of page
+htmlPrintOnlinePaymentFooter($mysoc, $langs, 0, $suffix, $object);
+
+llxFooter('', 'public');
+
+$db->close();
diff --git a/htdocs/public/recruitment/view.php b/htdocs/public/recruitment/view.php
new file mode 100644
index 00000000000..b4d13747d3f
--- /dev/null
+++ b/htdocs/public/recruitment/view.php
@@ -0,0 +1,319 @@
+
+ * Copyright (C) 2018 Frédéric France