| Server IP : 172.173.179.141 / Your IP : 216.73.216.196 Web Server : Apache System : Linux mail.lomejor.cr 6.8.0-1059-azure #65~22.04.1-Ubuntu SMP Thu May 28 16:59:19 UTC 2026 x86_64 User : www-data ( 33) PHP Version : 8.2.31 Disable Function : NONE MySQL : OFF | cURL : ON | WGET : OFF | Perl : OFF | Python : OFF | Sudo : OFF | Pkexec : OFF Directory : /var/www/erp/htdocs/custom/prospectingmap/ |
Upload File : |
<?php
/* Copyright (C) 2001-2004 Rodolphe Quiedeville <rodolphe@quiedeville.org>
* Copyright (C) 2004-2016 Laurent Destailleur <eldy@users.sourceforge.net>
* Copyright (C) 2005-2012 Regis Houssin <regis.houssin@capnetworks.com>
* Copyright (C) 2012 Marcos García <marcosgdf@gmail.com>
* Copyright (C) 2013-2015 Raphaël Doursenaud <rdoursenaud@gpcsolutions.fr>
* Copyright (C) 2015 Florian Henry <florian.henry@open-concept.pro>
* Copyright (C) 2016 Josep Lluis Amador <joseplluis@lliuretic.cat>
* Copyright (C) 2016 Ferran Marcet <fmarcet@2byte.es>
* Copyright (C) 2017 Juanjo Menent <jmenent@2byte.es>
*
* 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 <http://www.gnu.org/licenses/>.
*/
/**
* \file htdocs/prospectingmap/map.php
* \ingroup prospectingmap
* \brief Page to show map of prospects
*/
// Change this following line to use the correct relative path (../, ../../, etc)
$res=0;
if (! $res && file_exists("../main.inc.php")) $res=@include '../main.inc.php'; // to work if your module directory is into a subdir of root htdocs directory
if (! $res && file_exists("../../main.inc.php")) $res=@include '../../main.inc.php'; // to work if your module directory is into a subdir of root htdocs directory
if (! $res) die("Include of main fails");
include_once DOL_DOCUMENT_ROOT.'/contact/class/contact.class.php';
require_once DOL_DOCUMENT_ROOT.'/core/class/html.formother.class.php';
require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php';
require_once DOL_DOCUMENT_ROOT.'/core/class/html.formcompany.class.php';
require_once DOL_DOCUMENT_ROOT.'/societe/class/client.class.php';
dol_include_once('/prospectingmap/lib/prospectingmap.lib.php');
dol_include_once('/advancedictionaries/class/html.formdictionary.class.php');
dol_include_once('/advancedictionaries/class/dictionary.class.php');
$langs->loadLangs(array("companies", "commercial", "customers", "suppliers", "bills", "compta", "categories", "prospectingmap@prospectingmap"));
// Security check
$socid = GETPOST('socid','int');
if ($user->societe_id) $socid=$user->societe_id;
$result = restrictedArea($user,'societe',$socid,'');
$search_sale = GETPOST("search_sale",'array');
$search_stcomm = GETPOST('search_stcomm','array');
$search_type = GETPOST('search_type','array');
$search_state = GETPOST("search_state",'array');
// Initialize technical object to manage hooks of page. Note that conf->hooks_modules contains array of hook context
$hookmanager->initHooks(array('prospectmap'));
$object = new Societe($db);
/*
* Actions
*/
if (GETPOST('cancel')) { $action='list'; $massaction=''; }
if (! GETPOST('confirmmassaction') && $massaction != 'presend' && $massaction != 'confirm_presend') { $massaction=''; }
$parameters=array();
$reshook=$hookmanager->executeHooks('doActions',$parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
if ($reshook < 0) setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
if (empty($reshook)) {
// Did we click on purge search criteria ?
if (GETPOST('button_removefilter_x', 'alpha') || GETPOST('button_removefilter.x', 'alpha') || GETPOST('button_removefilter', 'alpha')) // All tests are required to be compatible with all browsers
{
$search_sale = array();
$search_stcomm = array();
$search_type = array();
$search_state = array();
}
}
/*
* View
*/
/*
REM: Rules on permissions to see thirdparties
Internal or External user + No permission to see customers => See nothing
Internal user socid=0 + Permission to see ALL customers => See all thirdparties
Internal user socid=0 + No permission to see ALL customers => See only thirdparties linked to user that are sale representative
External user socid=x + Permission to see ALL customers => Can see only himself
External user socid=x + No permission to see ALL customers => Can see only himself
*/
$form=new Form($db);
$formother=new FormOther($db);
$companystatic=new Societe($db);
$formcompany=new FormCompany($db);
$prospectstatic=new Client($db);
$prospectstatic->client=2;
$prospectstatic->loadCacheOfProspStatus();
$formdictionary = new FormDictionary($db);
$stcomm_dictionary = Dictionary::getDictionary($db, 'prospectingmap', 'prospectingmapstcomm');
$stcomm_dictionary->fetch_lines();
$title = $langs->trans("ProspectingMapMapOfProspects");
$sql = "SELECT s.rowid, s.nom as name, s.name_alias, s.town, s.zip, ";
$sql.= " st.libelle as stcomm, s.fk_stcomm as stcomm_id, s.fk_prospectlevel, s.prefix_comm, s.client, s.fournisseur, s.canvas, s.status as status,";
$sql.= " s.email, s.phone, s.fk_pays,";
$sql.= " s.address,";
$sql.= " state.code_departement as state_code, state.nom as state_name,";
$sql.= " pmc.longitude, pmc.latitude";
// Add fields from hooks
$parameters=array();
$reshook=$hookmanager->executeHooks('printFieldListSelect',$parameters); // Note that $action and $object may have been modified by hook
$sql.=$hookmanager->resPrint;
$sql.= " FROM ".MAIN_DB_PREFIX."societe as s";
$sql.= " LEFT JOIN ".MAIN_DB_PREFIX."c_country as country on (country.rowid = s.fk_pays)";
$sql.= " LEFT JOIN ".MAIN_DB_PREFIX."c_departements as state on (state.rowid = s.fk_departement)";
$sql.= " LEFT JOIN ".MAIN_DB_PREFIX."prospectingmap_coordinate as pmc on (pmc.fk_soc = s.rowid)";
if (!empty($search_state)) {
$sql .= " ," . MAIN_DB_PREFIX . "c_prospectingmap_region as cpmr";
$sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "c_prospectingmap_region_cbl_department as cpmrcd on (cpmrcd.fk_line = cpmr.rowid)";
$sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "c_departements as cpmd on (cpmd.rowid = cpmrcd.fk_target)";
$sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "c_regions as cr on (cpmd.fk_region = cr.code_region)";
}
$sql.= " ,".MAIN_DB_PREFIX."c_stcomm as st";
// We'll need this table joined to the select in order to filter by sale
if ($search_sale || (!$user->rights->societe->client->voir && !$socid)) $sql.= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc";
$sql.= " WHERE s.fk_stcomm = st.id";
$sql.= " AND s.entity IN (".getEntity('societe').")";
if ($search_sale || (!$user->rights->societe->client->voir && !$socid)) $sql .= " AND s.rowid = sc.fk_soc"; // Join for the needed table to filter by sale
if (!$user->rights->societe->client->voir && !$socid) $sql.= " AND sc.fk_user = " .$user->id;
if (!empty($search_sale)) $sql .= " AND sc.fk_user IN (" . implode(',', $search_sale) . ")";
if (!empty($search_state)) {
$sql .= 'AND cpmr.rowid IN (' . implode(',', $search_state) . ')';
$sql .= 'AND (cpmrcd.fk_target = s.fk_departement OR (cr.fk_pays = s.fk_pays AND s.zip LIKE CONCAT(cpmd.code_departement, \'%\')))';
}
// Filter on type of thirdparty
if (!empty($search_type)) {
$types_list = array();
foreach ($search_type as $type) {
$types_list = array_merge($types_list, explode(';', $type));
}
$or_stm = array();
if (in_array('4', $types_list)) {
$types_list = array_diff($types_list, array('4'));
$or_stm[] = "s.fournisseur = 1";
}
if (in_array('0', $types_list)) {
$types_list = array_diff($types_list, array('0'));
$or_stm[] = "(s.client = 0 AND s.fournisseur = 0)";
}
if (count($types_list) > 0) $or_stm[] = "s.client IN (".implode(',', $types_list).")";
$sql .= ' AND (' . implode(' OR ', $or_stm) . ')';
}
if (!empty($search_stcomm)) $sql .= " AND s.fk_stcomm IN (" . implode(',', $search_stcomm) . ")";
// Add where from hooks
$parameters=array();
$reshook=$hookmanager->executeHooks('printFieldListWhere',$parameters); // Note that $action and $object may have been modified by hook
$sql.=$hookmanager->resPrint;
$sql.= ' GROUP BY s.rowid, s.nom, s.name_alias, s.town, s.zip, ';
$sql.= " st.libelle, s.fk_stcomm, s.fk_prospectlevel, s.prefix_comm, s.client, s.fournisseur, s.canvas, s.status,";
$sql.= " s.email, s.phone, s.fk_pays,";
$sql.= " s.address,";
$sql.= " state.code_departement, state.nom,";
$sql.= " pmc.longitude, pmc.latitude";
// Add fields from hooks
$parameters=array();
$reshook=$hookmanager->executeHooks('printFieldListGroupBy',$parameters); // Note that $action and $object may have been modified by hook
$sql.=$hookmanager->resPrint;
$sql.= $db->order('s.rowid', 'ASC');
$resql = $db->query($sql);
if (! $resql) {
dol_print_error($db);
exit;
}
$num = $db->num_rows($resql);
llxHeader('', $title);
print '<form method="post" action="'.$_SERVER["PHP_SELF"].'" name="formfilter">';
print '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">';
print '<input type="hidden" name="formfilteraction" id="formfilteraction" value="list">';
print_barre_liste($title, '', $_SERVER["PHP_SELF"], '', '', '', '', '', $num, 'title_companies');
$moreforfilter = '';
// Sales representatives
$moreforfilter.='<div class="divsearchfield">';
$moreforfilter.=$langs->trans('SalesRepresentatives'). ': ';
$moreforfilter.=multiselect_javascript_code($search_sale, 'search_sale');
$save_conf = $conf->use_javascript_ajax;
$conf->use_javascript_ajax = 0;
$moreforfilter.=$formother->select_salesrepresentatives('','search_sale',$user, 0, 0, 'minwidth300 maxwidth300');
$conf->use_javascript_ajax = $save_conf;
$moreforfilter.='</div>';
// States
$moreforfilter.='<div class="divsearchfield">';
$moreforfilter.=$langs->trans('ProspectingMapRegion'). ': ';
$moreforfilter.=multiselect_javascript_code($search_state, 'search_state');
$save_conf = $conf->use_javascript_ajax;
$conf->use_javascript_ajax = 0;
$moreforfilter.=$formdictionary->select_dictionary('prospectingmap', 'prospectingmapregion', '', 'search_state', '', 'rowid', '{{label}}', array(), array('label'=>'ASC'), 0, array(), 0, 0, 'minwidth300 maxwidth300');
$conf->use_javascript_ajax = $save_conf;
$moreforfilter.='</div>';
// Type company
$moreforfilter.='<div class="divsearchfield">';
$moreforfilter.=$langs->trans('Type'). ': ';
$moreforfilter.=multiselect_javascript_code($search_type, 'search_type');
$moreforfilter.='<select class="flat minwidth300 maxwidth300" id="search_type" name="search_type">';
if (empty($conf->global->SOCIETE_DISABLE_CUSTOMERS)) $moreforfilter.= '<option value="1;3">'.$langs->trans('Customer').'</option>';
if (empty($conf->global->SOCIETE_DISABLE_PROSPECTS)) $moreforfilter.= '<option value="2;3">'.$langs->trans('Prospect').'</option>';
$moreforfilter.='<option value="4">'.$langs->trans('Supplier').'</option>';
$moreforfilter.='<option value="0">'.$langs->trans('Others').'</option>';
$moreforfilter.='</select>';
$moreforfilter.='</div>';
// Prospect status
$arraystcomm=array();
foreach($prospectstatic->cacheprospectstatus as $key => $val) {
$arraystcomm[$val['id']] = ($langs->trans("StatusProspect" . $val['id']) != "StatusProspect" . $val['id'] ? $langs->trans("StatusProspect" . $val['id']) : $val['label']);
}
$moreforfilter.='<div class="divsearchfield">';
$moreforfilter.=$langs->trans('StatusProsp'). ': ';
$moreforfilter.=multiselect_javascript_code($search_stcomm, 'search_stcomm');
$save_conf = $conf->use_javascript_ajax;
$conf->use_javascript_ajax = 0;
$moreforfilter.=$form->selectarray('search_stcomm', $arraystcomm, '', 0, 0, 0, '', 0, 0, 0, '','minwidth300 maxwidth300');
$conf->use_javascript_ajax = $save_conf;
$moreforfilter.='</div>';
$parameters = array();
$reshook = $hookmanager->executeHooks('printFieldPreListTitle', $parameters); // Note that $action and $object may have been modified by hook
if (empty($reshook)) $moreforfilter .= $hookmanager->resPrint;
else $moreforfilter = $hookmanager->resPrint;
if (!empty($moreforfilter)) {
print '<div class="liste_titre liste_titre_bydiv centpercent">';
print $moreforfilter;
print '<div class="divsearchfield">';
print $form->showFilterButtons();
print '</div>';
print '</div>';
}
print '</form>';
$coordinates_metrics = empty($conf->global->PROSPECTINGMAP_COORDINATES_METRICS) ? 'EPSG:3857' : $conf->global->PROSPECTINGMAP_COORDINATES_METRICS;
/**
* Build geoJSON datas.
*/
$icon = dol_buildpath('/prospectingmap/img/dot.png', 1);
$stcomm_list = [];
$features = [];
while ($obj = $db->fetch_object($resql)) {
$stcomm_id = isset($obj->stcomm_id) ? $obj->stcomm_id : 0;
$companystatic->id = $obj->rowid;
$companystatic->name = $obj->name;
$companystatic->name_alias = $obj->name_alias;
$companystatic->address = $obj->address;
$companystatic->town = $obj->town;
$companystatic->zip = $obj->zip;
$companystatic->state_name = $obj->state_name;
$companystatic->fk_pays = $obj->fk_pays;
$companystatic->phone = $obj->phone;
// Description of the popup
//------------------------------
$address = $companystatic->getFullAddress();
$description = $companystatic->getNomUrl(1, '', 0, 1) .
(!empty($address) ? '<br>' . $address : '') .
(!empty($companystatic->phone) ? '<br>' . dol_print_phone($companystatic->phone) : '') .
(!empty($companystatic->email) ? '<br>' . dol_print_email($companystatic->email) : '');
// Get Colors
//------------------------------
if (!isset($stcomm_list[$stcomm_id])) {
$stcomm = $stcomm_dictionary->lines[$stcomm_id];
$stcomm_list[$stcomm_id] = !empty($stcomm->fields['color']) ? $stcomm->fields['color'] : '#FFFFFF';
}
// Coordinates in projection format: "EPSG:3857"
//------------------------------
$longitude = !empty($obj->longitude) ? $obj->longitude : 0;
$latitude = !empty($obj->latitude) ? $obj->latitude : 0;
// Add geoJSON point
//------------------------------
$features[] = [
'type' => 'Feature',
'geometry' => [
'type' => 'Point',
'coordinates' => [$longitude, $latitude],
],
'properties' => [
'desc' => $description,
'stcomm' => $stcomm_id,
],
];
}
?>
<script src="https://cdn.polyfill.io/v2/polyfill.min.js?features=requestAnimationFrame,Element.prototype.classList"></script>
<script src="https://cdn.jsdelivr.net/gh/openlayers/openlayers.github.io@master/en/v6.11.0/build/ol.js"></script>
<style>
.ol-popup {
position: absolute;
background-color: white;
-webkit-filter: drop-shadow(0 1px 4px rgba(0,0,0,0.2));
filter: drop-shadow(0 1px 4px rgba(0,0,0,0.2));
padding: 15px;
border-radius: 10px;
border: 1px solid #cccccc;
bottom: 12px;
left: -50px;
min-width: 280px;
}
.ol-popup:after, .ol-popup:before {
top: 100%;
border: solid transparent;
content: " ";
height: 0;
width: 0;
position: absolute;
pointer-events: none;
}
.ol-popup:after {
border-top-color: white;
border-width: 10px;
left: 48px;
margin-left: -10px;
}
.ol-popup:before {
border-top-color: #cccccc;
border-width: 11px;
left: 48px;
margin-left: -11px;
}
.ol-popup-closer {
text-decoration: none;
position: absolute;
top: 2px;
right: 8px;
}
.ol-popup-closer:after {
content: "✖";
}
</style>
<div id="map" class="map"></div>
<div id="popup" class="ol-popup">
<a href="#" id="popup-closer" class="ol-popup-closer"></a>
<div id="popup-content"></div>
</div>
<script type="text/javascript">
/**
* Set map height.
*/
var _map = $('#map');
var _map_pos = _map.position();
var h = Math.max(document.documentElement.clientHeight, window.innerHeight || 0);
_map.height(h - _map_pos.top - 20);
/**
* Prospect markers geoJSON.
*/
var geojsonProspectMarkers = {
"type": "FeatureCollection",
"crs": {
"type": "name",
"properties": {
"name": "<?php print $coordinates_metrics ?>"
}
},
"features": []
};
<?php
$result = inject_map_features($features, 500);
if ($result < 0) {
setEventMessage($langs->trans('ProspectingMapErrorMapFeatureEncoding'), 'errors');
}
?>
console.log("Prospecting Map: <?php print $coordinates_metrics ?>");
console.log("Prospecting Map: " + geojsonProspectMarkers.features.length + " map features loaded.");
/**
* Prospect markers styles.
*/
var markerStyles = {};
$.map(<?php print json_encode($stcomm_list) ?>, function (value, key) {
if (!(key in markerStyles)) {
markerStyles[key] = new ol.style.Style({
image: new ol.style.Icon(/** @type {module:ol/style/Icon~Options} */ ({
anchor: [0.5, 1],
color: value,
crossOrigin: 'anonymous',
src: '<?php print $icon ?>'
}))
});
}
});
var styleFunction = function(feature) {
return markerStyles[feature.get('stcomm')];
};
/**
* Prospect markers source.
*/
var prospectSource = new ol.source.Vector({
features: (new ol.format.GeoJSON()).readFeatures(geojsonProspectMarkers)
});
/**
* Prospect markers layer.
*/
var prospectLayer = new ol.layer.Vector({
source: prospectSource,
style: styleFunction
});
/**
* Open Street Map layer.
*/
var osmLayer = new ol.layer.Tile({
source: new ol.source.OSM()
});
/**
* Elements that make up the popup.
*/
var popupContainer = document.getElementById('popup');
var popupContent = document.getElementById('popup-content');
var popupCloser = document.getElementById('popup-closer');
/**
* Create an overlay to anchor the popup to the map.
*/
var popupOverlay = new ol.Overlay({
element: popupContainer,
autoPan: true,
autoPanAnimation: {
duration: 250
}
});
/**
* Add a click handler to hide the popup.
* @return {boolean} Don't follow the href.
*/
popupCloser.onclick = function() {
popupOverlay.setPosition(undefined);
popupCloser.blur();
return false;
};
/**
* View of the map.
*/
var mapView = new ol.View({
projection: '<?php print $coordinates_metrics ?>'
});
if (<?php print $num ?> == 1) {
var feature = prospectSource.getFeatures()[0];
var coordinates = feature.getGeometry().getCoordinates();
mapView.setCenter(coordinates);
mapView.setZoom(17);
} else {
mapView.setCenter([0, 0]);
mapView.setZoom(1);
}
/**
* Create the map.
*/
var map = new ol.Map({
target: 'map',
layers: [osmLayer, prospectLayer],
overlays: [popupOverlay],
view: mapView
});
/**
* Fit map for markers.
*/
if (<?php print $num ?> > 1) {
var extent = prospectSource.getExtent();
mapView.fit(extent, {padding: [50, 50, 50, 50], constrainResolution: false});
}
/**
* Add a click handler to the map to render the popup.
*/
map.on('singleclick', function(evt) {
var feature = map.forEachFeatureAtPixel(evt.pixel, function (feature) {
return feature;
});
if (feature) {
var coordinates = feature.getGeometry().getCoordinates();
popupContent.innerHTML = feature.get('desc');
popupOverlay.setPosition(coordinates);
} else {
popupCloser.click();
}
});
</script>
<?php
$db->free($resql);
llxFooter();
$db->close();