Files
old-wiaas-legacy/api-wiaas/server/components/v2/orders/OrdersModel.php
2018-07-09 20:14:00 +02:00

1449 lines
60 KiB
PHP

<?php
class OrdersModel{
const ID_ADDITONAL_TYPE = 3;
const CUSTOMER_ACCEPTANCE_DAYS_INTERVAL = 15;
const ID_INSTALLATION_CATEGORY = 2;
private $headersHelper;
function __construct(){
$this->headersHelper = new HeadersHelper();
}
/**
* get the list of orders
* @return Array array of orders
*/
public function getActiveOrders(){
global $database, $user;
$userType = $user->getUserType();
$idUser = $user->getUserId();
$headersSql = $this->getActiveOrdersHeaders('sql')['headers'];
$whereSql = "WHERE o.status!='production' AND o.status!='canceled' AND o.status!='end-of-life'";
$extraSql = "";
$orders = [];
$isCustomer = false;
$isCommercialLead = false;
switch($userType){
case 'broker' :
$extraSql .= "LEFT OUTER JOIN ".TABLES['brokers']." b
ON b.id=o.assignedTo";
break;
case 'customer' :
$extraSql .= "INNER JOIN ".TABLES['users']." ucust
ON ucust.idCompany = uc.idCompany
AND ucust.id = $idUser";
$isCustomer = true;
break;
case 'commercial_lead':
$extraSql .= "INNER JOIN ".TABLES['users']." uclCompany
ON uclCompany.idCompany = ucl.idCompany
AND uclCompany.id = $idUser";
$isCommercialLead = true;
break;
case 'supplier' :
$extraSql .= "INNER JOIN ".TABLES['rel_package_products']." rpp
ON rpp.idPackage=rop.idPackage AND rop.packageInstance=rpp.packageInstance
INNER JOIN ".TABLES['suppliers_countries_products']." scp
ON scp.idProduct=rpp.idProduct
INNER JOIN ".TABLES['suppliers']." s
ON s.id=scp.idSupplier";
$whereSql .= " AND s.idUser=$idUser AND o.status='in-progress'";
break;
}
$sql = "SELECT
$headersSql
FROM
".TABLES['orders']." o
INNER JOIN ".TABLES['rel_commercial_lead_customers']." rclc
ON o.idCustomerInstance = rclc.id
INNER JOIN ".TABLES['customers']." cust
ON cust.id = rclc.idCustomer
INNER JOIN ".TABLES['commercial_leads']." cl
ON cl.id = rclc.idCommercialLead
INNER JOIN ".TABLES['rel_order_packages']." rop
ON rop.idOrder=o.id
INNER JOIN ".TABLES['users']." ucl
ON ucl.id = cl.idUser
INNER JOIN ".TABLES['users']." uc
ON uc.id = cust.idUser
$extraSql
$whereSql
GROUP BY o.id
ORDER BY o.orderNumber DESC";
$orderPackages = $this->getOrderPackages(0, 'ongoing');
$query = $database->query($sql);
while($row = $database->fetchArray($query)){
$row['packages'] = isset($orderPackages[$row['id']]) ? $orderPackages[$row['id']] : [];
$row['orderCurrency'] = isset($orderPackages[$row['id']]) ? $orderPackages[$row['id']][0]['packageCurrency'] : '';
if($isCustomer) {
$row['isMyOrder'] = $idUser === $row['idCustomerUser'] ? true : false;
}
if($isCommercialLead) {
$row['isMyOrder'] = $idUser === $row['idCommercialLeadUser'] ? true : false;
}
array_push($orders, $row);
}
return ['orders' => $orders];
}
/**
* Get the headers requried for the orders
* @param string $type type of the headere, posible values array or sql
* @return string|array returns the sql header or the array of for the headers
*/
private function getActiveOrdersHeaders( $type = 'array'){
global $user;
$userType = $user->getUserType();
$data = [];
switch($userType){
case 'broker' :
$headers = [
'o.id' => 'id',
'o.orderNumber' => 'orderNumber',
'o.status' => 'status',
'o.reference' => 'reference',
'o.idCustomerInstance' => 'idCustomerInstance',
'rclc.IdCustomer' => 'idCustomer',
'cust.name' => 'customer',
'o.billingFirstName' => 'billingFirstName',
'o.billingLastName' => 'billingLastName',
'o.billingMail' => 'billingMail',
'o.billingAddress' => 'billingAddress',
'rclc.idCommercialLead' => 'idCommercialLead',
'cl.name' => 'commercialLead',
'IFNULL(b.name, \'\')' => 'assignedTo',
'o.orderDate' => 'orderDate',
'o.estimatedDeliveryDate' => 'estimatedDeliveryDate',
'\'\'' => 'orderItems',
'SUM(rop.packageFixedPrice * rop.units)' => 'orderTotalPrice',
'o.deliveryAddress' => 'deliveryAddress',
'cust.phone' => 'customerPhone',
'uc.mail' => 'customerMail',
'cl.phone' => 'commercialLeadPhone',
'ucl.mail' => 'commercialLeadMail',
];
break;
case 'customer' :
$headers = [
'o.id' => 'id',
'o.orderNumber' => 'orderNumber',
'o.status' => 'status',
'o.reference' => 'reference',
'rclc.idCommercialLead' => 'idCommercialLead',
'uc.id' => 'idCustomerUser',
'cust.name' => 'customerName',
'o.billingFirstName' => 'billingFirstName',
'o.billingLastName' => 'billingLastName',
'o.billingMail' => 'billingMail',
'o.billingAddress' => 'billingAddress',
'cust.phone' => 'phone',
'uc.mail' => 'mail',
'cl.contactName' => 'clContactName',
'cl.name' => 'clName',
'DATE_FORMAT(o.orderDate, \'%D %b, %Y\')' => 'orderDate',
'DATE_FORMAT(o.estimatedDeliveryDate, \'%D %b, %Y\')' => 'estimatedDeliveryDate',
'\'\'' => 'orderItems',
'SUM(rop.packageFixedPrice * rop.units)' => 'orderTotalPrice',
'o.deliveryAddress' => 'deliveryAddress',
'cl.phone' => 'commercialLeadPhone',
'ucl.mail' => 'commercialLeadMail'
];
break;
case 'commercial_lead' :
$headers = [
'o.id' => 'id',
'o.orderNumber' => 'orderNumber',
'o.status' => 'status',
'o.reference' => 'reference',
'cl.idUser' => 'idCommercialLeadUser',
'cl.name' => 'commercialLeadName',
'o.idCustomerInstance' => 'idCustomerInstance',
'rclc.IdCustomer' => 'idCustomer',
'cust.name' => 'customer',
'o.billingFirstName' => 'billingFirstName',
'o.billingLastName' => 'billingLastName',
'o.billingMail' => 'billingMail',
'o.billingAddress' => 'billingAddress',
'o.orderDate' => 'orderDate',
'o.estimatedDeliveryDate' => 'estimatedDeliveryDate',
'\'\'' => 'orderItems',
'SUM(rop.packageFixedPrice * rop.units)' => 'orderTotalPrice',
'o.deliveryAddress' => 'deliveryAddress',
'cust.phone' => 'customerPhone',
'uc.mail' => 'customerMail'
];
break;
case 'supplier' :
$headers = [
'o.id' => 'id',
'o.orderNumber' => 'orderNumber',
'o.status' => 'status',
'o.orderDate' => 'orderDate',
'\'\'' => 'orderItems',
'o.deliveryAddress' => 'deliveryAddress',
'cust.phone' => 'customerPhone',
'uc.mail' => 'customerMail'
];
break;
default :
$headers = [
'o.id' => 'id',
'o.orderNumber' => 'orderNumber',
'o.status' => 'status'
];
}
$data['headers'] = $this->headersHelper->getHeader($headers, $type);
if($userType === USER_TYPES['BROKER']){
$data['brokers'] = $this->getBrokers();
}
return $data;
}
/**
* return id and name of the brokers from the system
* @return Array of id and name for brokers
*/
public function getBrokers(){
global $database, $user;
$userType = $user->getUserType();
if($userType !== USER_TYPES['BROKER']){
return [];
}
$idUser = $user->getUserId();
$sql = " SELECT b.id as idBroker,
CASE WHEN b.idUser=$idUser THEN 'Me' ELSE b.name END as brokerName
FROM ".TABLES['brokers']." b
ORDER BY b.name";
return $database->fetchResultArray($sql);
}
/**
* get the list of orders history
* @return Array array of orders
*/
public function getHistoryOrders(){
global $database;
global $user;
$userType = $user->getUserType();
$idUser = $user->getUserId();
$headersSql = $this->getHistoryOrdersHeaders('sql');
$extraSql = '';
$whereSql = "WHERE (o.status='production' OR o.status='canceled' OR o.status='end-of-life')";
$orders = [];
$isCustomer = false;
$isCommercialLead = false;
switch($userType){
case 'customer' :
$extraSql .= "
INNER JOIN ".TABLES['users']." ucust
ON ucust.idCompany = uc.idCompany
AND ucust.id = $idUser";
$isCustomer = true;
break;
case 'commercial_lead':
$extraSql .= "
INNER JOIN ".TABLES['users']." uclCompany
ON uclCompany.idCompany = ucl.idCompany
AND uclCompany.id = $idUser";
$isCommercialLead = true;
break;
}
$sql = "SELECT
$headersSql,
SUM(rop.packageFixedPrice * rop.units) AS fixedPrice,
SUM((rop.packageRecuringPrice * rop.units) + (rop.packageServicePrice * rop.units)) AS recurringPrice
FROM
".TABLES['orders']." o
INNER JOIN ".TABLES['rel_commercial_lead_customers']." rclc
ON o.idCustomerInstance=rclc.id
INNER JOIN ".TABLES['customers']." cust
ON cust.id=rclc.idCustomer
INNER JOIN ".TABLES['commercial_leads']." cl
ON cl.id=rclc.idCommercialLead
INNER JOIN ".TABLES['rel_order_packages']." rop
ON rop.idOrder=o.id
INNER JOIN ".TABLES['users']." ucl
ON ucl.id = cl.idUser
INNER JOIN ".TABLES['users']." uc
ON uc.id = cust.idUser
$extraSql
$whereSql
GROUP BY o.id
ORDER BY o.orderNumber DESC";
$orderPackages = $this->getOrderPackages(0, 'history');
$query = $database->query($sql);
while($row = $database->fetchArray($query)){
$row['packages'] = isset($orderPackages[$row['id']]) ? $orderPackages[$row['id']] : [];
$row['orderCurrency'] = isset($orderPackages[$row['id']]) ? $orderPackages[$row['id']][0]['packageCurrency'] : '';
if($isCustomer) {
$row['isMyOrder'] = $idUser === $row['idCustomerUser'] ? true : false;
}
if($isCommercialLead) {
$row['isMyOrder'] = $idUser === $row['idCommercialLeadUser'] ? true : false;
}
array_push($orders, $row);
}
return ['orders' => $orders];
}
/**
* Get the headers requried for the orders history
* @param string $type type of the headere, posible values array or sql
* @return string|array returns the sql header or the array of for the headers
*/
private function getHistoryOrdersHeaders( $type = 'array'){
global $user;
$userType = $user->getUserType();
switch($userType){
case 'broker' :
$headers = [
'o.id' => 'id',
'o.orderNumber' => 'orderNumber',
'o.status' => 'status',
'o.reference' => 'reference',
'o.idCustomerInstance' => 'idCustomerInstance',
'rclc.IdCustomer' => 'idCustomer',
'cust.name' => 'customer',
'o.billingFirstName' => 'billingFirstName',
'o.billingLastName' => 'billingLastName',
'o.billingMail' => 'billingMail',
'o.billingAddress' => 'billingAddress',
'rclc.idCommercialLead' => 'idCommercialLead',
'cl.name' => 'commercialLead',
'o.orderDate' => 'orderDate',
'o.estimatedDeliveryDate' => 'estimatedDeliveryDate',
'o.deliveryDate' => 'deliveryDate',
'MAX(rop.endOfLife)' => 'endOfLife',
'\'\'' => 'orderItems',
'SUM(rop.packageFixedPrice * rop.units)' => 'orderTotalPrice',
'o.deliveryAddress' => 'deliveryAddress',
'cust.phone' => 'customerPhone',
'uc.mail' => 'customerMail',
'cl.phone' => 'commercialLeadPhone',
'ucl.mail' => 'commercialLeadMail'
];
break;
case 'customer' :
$headers = [
'o.id' => 'id',
'o.orderNumber' => 'orderNumber',
'o.status' => 'status',
'o.reference' => 'reference',
'o.tender' => 'tender',
'rclc.idCommercialLead' => 'idCommercialLead',
'uc.id' => 'idCustomerUser',
'cust.name' => 'customerName',
'o.billingFirstName' => 'billingFirstName',
'o.billingLastName' => 'billingLastName',
'o.billingMail' => 'billingMail',
'o.billingAddress' => 'billingAddress',
'cust.phone' => 'phone',
'uc.mail' => 'mail',
'cl.name' => 'clName',
'cl.contactName' => 'clContactName',
'DATE_FORMAT(o.orderDate, \'%D %b, %Y\')' => 'orderDate',
'DATE_FORMAT(o.estimatedDeliveryDate, \'%D %b, %Y\')' => 'estimatedDeliveryDate',
'DATE_FORMAT(o.deliveryDate, \'%D %b, %Y\')' => 'deliveryDate',
'DATE_FORMAT(MAX(rop.endOfLife), \'%D %b, %Y\')' => 'endOfLife',
'\'\'' => 'orderItems',
'SUM(rop.packageFixedPrice * rop.units)' => 'orderTotalPrice',
'o.deliveryAddress' => 'deliveryAddress',
'cl.phone' => 'commercialLeadPhone',
'ucl.mail' => 'commercialLeadMail'
];
break;
case 'commercial_lead' :
$headers = [
'o.id' => 'id',
'o.orderNumber' => 'orderNumber',
'o.status' => 'status',
'o.reference' => 'reference',
'cl.idUser' => 'idCommercialLeadUser',
'cl.name' => 'commercialLeadName',
'o.idCustomerInstance' => 'idCustomerInstance',
'rclc.IdCustomer' => 'idCustomer',
'cust.name' => 'customer',
'o.billingFirstName' => 'billingFirstName',
'o.billingLastName' => 'billingLastName',
'o.billingMail' => 'billingMail',
'o.billingAddress' => 'billingAddress',
'o.orderDate' => 'orderDate',
'o.estimatedDeliveryDate' => 'estimatedDeliveryDate',
'o.deliveryDate' => 'deliveryDate',
'MAX(rop.endOfLife)' => 'endOfLife',
'\'\'' => 'orderItems',
'SUM(rop.packageFixedPrice * rop.units)' => 'orderTotalPrice',
'o.deliveryAddress' => 'deliveryAddress',
'cust.phone' => 'customerPhone',
'uc.mail' => 'customerMail'
];
break;
case 'supplier' :
$headers = [
'o.id' => 'id',
'o.orderNumber' => 'orderNumber',
'o.status' => 'status',
'o.reference' => 'reference',
'o.idCustomerInstance' => 'idCustomerInstance',
'rclc.IdCustomer' => 'idCustomer',
'cust.name' => 'customer',
'o.orderDate' => 'orderDate',
'o.estimatedDeliveryDate' => 'estimatedDeliveryDate',
'o.deliveryDate' => 'deliveryDate',
'MAX(rop.endOfLife)' => 'endOfLife',
'\'\'' => 'orderItems',
'SUM(rop.packageFixedPrice * rop.units)' => 'orderTotalPrice',
'o.deliveryAddress' => 'deliveryAddress',
'cust.phone' => 'customerPhone',
'uc.mail' => 'customerMail'
];
break;
}
return $this->headersHelper->getHeader($headers, $type);
}
/**
* get packages for the order
* @param INT $idOrder id for order
* @return Array packages array
*/
private function getOrderPackages($idOrder = 0, $forOrders){
global $database, $user;
$countries = new Countries();
$whereSql = $idOrder === 0 ? "WHERE 1=1 " : "WHERE rop.idOrder=$idOrder ";
$extraJoin = "";
$extraFields = "";
$userType = $user->getUserType();
if($forOrders === 'history'){
$whereSql .= "AND (o.status='production' OR o.status='canceled' OR o.status='end-of-life')";
$extraFields = "IFNULL(DATE_FORMAT(rop.endOfLife, '%D %b, %Y'), '') as endOfLife,
rop.units,
rop.packageFixedPrice,
rop.packageRecuringPrice,
rop.packageServicePrice,
rop.status,
pt.packagePayPeriod,
pt.servicesContractPeriod,
pt.maxContractPeriod,
pt.periodUnit,";
} else if($forOrders === 'ongoing'){
if($userType === USER_TYPES['BROKER']){
$extraJoin = "LEFT OUTER JOIN
(SELECT
rops.idOrder,
rops.idPackage,
ps.shortDesc
FROM
".TABLES['rel_order_process_step']." rops
INNER JOIN ".TABLES['rel_process_steps']." rps
ON rps.id = rops.idProcessStep
INNER JOIN ".TABLES['process_step']." ps
ON ps.id = rps.idStep
WHERE
rops.status = 'in-progress'
) ongoing_steps
ON ongoing_steps.idOrder = rop.idOrder AND ongoing_steps.idPackage = rop.idPackage";
$extraFields = "IFNULL(ongoing_steps.shortDesc, rop.status) AS shortDesc,
rop.units,
rop.packageFixedPrice,
rop.packageRecuringPrice,
rop.packageServicePrice,
rop.status,
pt.packagePayPeriod,
pt.servicesContractPeriod,
pt.maxContractPeriod,
pt.periodUnit,";
} else if($userType === USER_TYPES['SUPPLIER']){
$extraJoin = "INNER JOIN
(SELECT
rops.idOrder,
rops.idPackage,
ps.shortDesc
FROM
".TABLES['rel_order_process_step']." rops
INNER JOIN ".TABLES['rel_process_steps']." rps
ON rps.id = rops.idProcessStep
INNER JOIN ".TABLES['process_step']." ps
ON ps.id = rps.idStep
INNER JOIN ".TABLES['process_step_actions']." psa
ON psa.id=ps.idActionCode
WHERE
rops.status ='in-progress' AND psa.actionCode='procurement'
) ongoing_steps
ON ongoing_steps.idOrder = rop.idOrder AND ongoing_steps.idPackage = rop.idPackage";
$extraFields = "IFNULL(ongoing_steps.shortDesc, rop.status) AS shortDesc,
rop.units,
rop.status,";
} else {
$extraJoin = "LEFT OUTER JOIN
( SELECT
done_steps.idOrder,
done_steps.idPackage,
ps.shortDesc
FROM
(SELECT
rops.idOrder,
rops.idPackage,
MAX(rops.idProcessStep) AS idProcessStep
FROM
".TABLES['rel_order_process_step']." rops
INNER JOIN ".TABLES['rel_process_steps']." rps ON rps.id = rops.idProcessStep
INNER JOIN ".TABLES['process_step']." ps ON ps.id = rps.idStep
WHERE
(rops.status = 'done'
OR rops.status = 'in-progress')
AND ps.isVisibleForCustomer = 1
GROUP BY rops.idOrder , rops.idPackage) AS done_steps
INNER JOIN
".TABLES['rel_process_steps']." rps ON rps.id = done_steps.idProcessStep
INNER JOIN
".TABLES['process_step']." ps ON ps.id = rps.idStep
) ongoing_steps
ON ongoing_steps.idOrder = rop.idOrder AND ongoing_steps.idPackage = rop.idPackage";
$extraFields = "IFNULL(ongoing_steps.shortDesc, rop.status) AS shortDesc,
rop.units,
rop.packageFixedPrice,
rop.packageRecuringPrice,
rop.packageServicePrice,
rop.status,
pt.packagePayPeriod,
pt.servicesContractPeriod,
pt.maxContractPeriod,
pt.periodUnit,";
}
$whereSql .= "AND (o.status!='production' AND o.status!='canceled' AND o.status!='end-of-life')";
}else{
$extraFields = "IFNULL(rop.endOfLife, '') as endOfLife,
rop.units,
rop.packageFixedPrice,
rop.packageRecuringPrice,
rop.packageServicePrice,
rop.status,
pt.packagePayPeriod,
pt.servicesContractPeriod,
pt.maxContractPeriod,
pt.periodUnit,";
}
$sql = "SELECT
$extraFields
pt.payType AS paymentType,
rop.idOrder,
pkg.id AS idPackage,
pkg.name AS packageName
FROM ".TABLES['packages']." pkg
INNER JOIN ".TABLES['rel_order_packages']." rop
ON rop.idPackage=pkg.id
INNER JOIN ".TABLES['orders']." o
ON o.id=rop.idOrder
INNER JOIN ".TABLES['payment_types']." pt
ON pt.id=rop.idPaymentTerm
$extraJoin
$whereSql";
$data = [];
$query = $database->query($sql);
while($row = $database->fetchArray($query)){
$row['packageCurrency'] = $countries->getCurrencyForPackage($row['idPackage']);
$data[$row['idOrder']][] = $row;
}
return $data;
}
/**
* get products for packages in an order
* @param INT $idOrder id for the order
* @return array array with all products grouped by package and category
*/
private function getOrderProducts($idOrder){
global $database;
$sql = "SELECT rcp.productName, pc.category, rpp.idPackage
FROM ".TABLES['suppliers_countries_products']." rcp
INNER JOIN product_categories pc
ON pc.id=rcp.idProductCategory
INNER JOIN ".TABLES['rel_package_products']." rpp
ON rpp.idProduct=rcp.idProduct
INNER JOIN ".TABLES['rel_order_packages']." rop
ON rop.idPackage=rpp.idPackage AND rop.packageInstance=rpp.packageInstance
WHERE rop.idOrder=$idOrder
";
$query = $database->query($sql);
$data = [];
while($row = $database->fetchArray($query)){
$data[$row['idPackage']][$row['category']][] = $row;
}
return $data;
}
private function getOrderSelections($idOrder){
global $database;
$data = [];
$sql = "SELECT
scp.productName,
os.idPackage,
pc.category
FROM ".TABLES['suppliers_countries_products']." scp
INNER JOIN ".TABLES['order_selections']." os
ON os.idProduct=scp.idProduct
INNER JOIN ".TABLES['product_categories']." pc
ON pc.id=scp.idProductCategory
WHERE os.idOrder=$idOrder";
$query = $database->query($sql);
while($row = $database->fetchArray($query)){
$data[$row['idPackage']][$row['category']][] = $row;
}
return $data;
}
/**
* get all comments for a specific order
* @param INT $idOrder id of the order
* @return Array Array of commnets for the order
*/
private function getOrderComments($idOrder){
global $database, $user;
$sql = "SELECT c.comment,
DATE_FORMAT(c.addDate, '%D %b, %y') as addDate,
u.username,
u.id=".$user->getUserId()." AS isOwner
FROM ".TABLES['rel_order_comments']." c
INNER JOIN ".TABLES['users']." u
ON u.id=c.idUser
WHERE c.idOrder=$idOrder
ORDER BY c.addDate DESC";
return $database->fetchResultArray($sql);
}
/**
* get all options linked to a package in an order
* @param INT $idOrder id for the order
* @return Array list of options grouped by packages
*/
private function getOrderOptions($idOrder){
global $database;
$data = [];
$sql = "SELECT
roep.idPackage,
p.name AS packageName,
pog.name AS groupName
FROM ".TABLES['rel_order_extra_packages']." roep
INNER JOIN ".TABLES['packages']." p
ON p.id=roep.idExtraPackage
INNER JOIN ".TABLES['rel_group_options']." rgo
ON rgo.idOptionPackage=roep.idExtraPackage
INNER JOIN ".TABLES['package_option_groups']." pog
ON pog.id=rgo.idGroup and pog.idPackage=roep.idPackage
WHERE roep.idOrder=$idOrder";
$query = $database->query($sql);
while($row = $database->fetchArray($query)){
$data[$row['idPackage']][] = $row;
}
return $data;
}
private function getOrderAdditionalPackages($idOrder){
global $database;
$data = [];
$sql = "SELECT
roep.idPackage,
p.name AS packageName
FROM ".TABLES['rel_order_extra_packages']." roep
INNER JOIN ".TABLES['packages']." p
ON p.id=roep.idExtraPackage
WHERE roep.idOrder=$idOrder AND p.idPackageType=".self::ID_ADDITONAL_TYPE;
$query = $database->query($sql);
while($row = $database->fetchArray($query)){
$data[$row['idPackage']][] = $row;
}
return $data;
}
/**
* check if user has rights to see a specific order
* @param INT $idOrder id of the order
* @return Boolean retruns true if the user can see the order
*/
private function checkOrderOwner($idOrder){
global $database, $user;
$idUser = $user->getUserId();
$extraWhere = " AND u.idUser=$idUser";
$isCompanyAdmin = UtilsModel::checkIfUserIsCompanyAdmin();
if($user->getUserType() === USER_TYPES['BROKER']){
return true;
}else if($user->getUserType() === USER_TYPES['CUSTOMER']){
$extraJoin = " INNER JOIN ".TABLES['rel_commercial_lead_customers']." rclc
ON rclc.id=o.idCustomerInstance
INNER JOIN ".TABLES['customers']." u
ON u.id=rclc.idCustomer
INNER JOIN ".TABLES['users']." us
ON us.id = u.idUser";
if($isCompanyAdmin) {
$extraJoin .= " INNER JOIN ".TABLES['users']." uc
ON uc.idCompany = us.idCompany
AND uc.id=$idUser";
$extraWhere = '';
}
}else if($user->getUserType() === USER_TYPES['COMMERCIAL_LEAD']){
$extraJoin = "INNER JOIN ".TABLES['rel_commercial_lead_customers']." rclc
ON rclc.id=o.idCustomerInstance
INNER JOIN ".TABLES['commercial_leads']." u
ON u.id=rclc.idCommercialLead
INNER JOIN ".TABLES['users']." us
ON us.id = u.idUser";
if($isCompanyAdmin) {
$extraJoin .= " INNER JOIN ".TABLES['users']." ucl
ON ucl.idCompany = us.idCompany
AND ucl.id=$idUser";
$extraWhere = '';
}
}else if($user->getUserType() === USER_TYPES['SUPPLIER']){
$extraJoin = "INNER JOIN ".TABLES['rel_order_products_estimation']." rope
ON rope.idOrder=o.id
INNER JOIN ".TABLES['suppliers_countries_products']." scp
ON scp.idProduct=rope.idProduct
OR scp.idProductCategory = ".self::ID_INSTALLATION_CATEGORY."
INNER JOIN ".TABLES['suppliers']." u
ON u.id=scp.idSupplier";
}else{
return false;
}
$sql = "SELECT o.id
FROM ".TABLES['orders']." o
$extraJoin
WHERE o.id=$idOrder
$extraWhere
LIMIT 1";
$query = $database->query($sql);
return $database->numRows($query) === 1;
}
/**
* get info for orders (details, packages, available processes)
* @param INT $idOrder id for the order
* @return HashArray array containtg info, packages, availableProcesses
*/
public function getOrderInfo($idOrder){
global $database;
$data = [];
$idOrder = $database->escapeValue($idOrder);
$isCompanyAdmin = UtilsModel::checkIfUserIsCompanyAdmin();
$orderProcessHelper = new OrderProcessHelper();
$orderDocuments = new OrderDocuments();
if(!$this->checkOrderOwner($idOrder, $isCompanyAdmin)){
return [];
}
$sql = "SELECT o.id,
o.orderNumber,
DATE_FORMAT(o.orderDate, '%D %b, %y') as orderDate,
o.estimatedDeliveryDate,
o.billingFirstName,
o.billingLastName,
o.billingMail,
o.billingAddress,
o.status,
o.reference,
o.tender,
o.idTerms,
o.idProject,
IFNULL(op.name, '') as projectName,
IFNULL(b.name, 'Unassigned') as assignedTo,
cust.name AS customer,
cust.phone,
u.mail,
cl.id AS idCommercialLead,
cl.name AS commercialLead,
MAX(rop.endOfLife) AS endOfLife
FROM
".TABLES['orders']." o
LEFT OUTER JOIN ".TABLES['brokers']." b
ON b.id=o.assignedTo
INNER JOIN ".TABLES['rel_commercial_lead_customers']." rclc
ON o.idCustomerInstance=rclc.id
INNER JOIN ".TABLES['customers']." cust
ON cust.id=rclc.idCustomer
INNER JOIN ".TABLES['users']." u
ON u.id = cust.idUser
INNER JOIN ".TABLES['commercial_leads']." cl
ON cl.id=rclc.idCommercialLead
INNER JOIN ".TABLES['rel_order_packages']." rop
ON rop.idOrder=o.id
LEFT OUTER JOIN ".TABLES['order_projects']." op
ON op.id=o.idProject
WHERE o.id=$idOrder
GROUP BY o.id
LIMIT 1";
$data['info'] = $database->fetchResultArray($sql);
$data['info'] = isset($data['info'][0]) ? $data['info'][0] : [];
$data['products'] = $this->getOrderProducts($idOrder);
$data['packages'] = $this->getOrderPackages($idOrder, 'all')[$idOrder];
$data['process'] = $orderProcessHelper->getOrderSteps($idOrder);
$documents = $orderDocuments->getOrderDocuments($idOrder);
$options = $this->getOrderOptions($idOrder);
$additionalPackages = $this->getOrderAdditionalPackages($idOrder);
foreach($data['packages'] as &$package){
$package['documents'] = isset($documents[$package['idPackage']]) ? $documents[$package['idPackage']] : [];
$package['options'] = isset($options[$package['idPackage']]) ? $options[$package['idPackage']] : [];
$package['additionalPackages'] = isset($additionalPackages[$package['idPackage']]) ? $additionalPackages[$package['idPackage']] : [];
}
$data['orderDocuments'] = isset($documents[0]) ? $documents[0] : [];
$data['selections'] = $this->getOrderSelections($idOrder);
$data['orderComments'] = $this->getOrderComments($idOrder);
$data['availableProcesses'] = [];
return $data;
}
/**
* returns an array with all the system allowed languages
* @return Array all the system language allowed
*/
public function getSystemAllowedLanguages() {
global $database;
$data = [];
$sql = "
SELECT
sal.languageCode AS languageCode,
sal.language AS language
FROM
".TABLES['system_allowed_languages']." sal";
$query = $database->query($sql);
while($row = $database->fetchArray($query)) {
$data['code'][] = $row['languageCode'];
$data['languages'][] = $row['language'];
}
return $data;
}
/**
* get the language of the comment added or array if error
* @param String $comment the comment added by the user
* @return Array the language detected or error
*/
private function getLanguageDetectResponse($comment) {
$data = [];
$ch = curl_init();
$plainText = html_entity_decode(strip_tags($comment));
$plainTextComment = urlencode($plainText);
$url = DETECT_LANGUAGE_API_URL.'?q='.$plainTextComment.'&key='.DETECT_LANGUAGE_API_KEY;
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HEADER, false);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
$response = json_decode(curl_exec($ch));
if(curl_errno($ch)){
$data['error'] = 'Curl error: ' . curl_error($ch);
}
curl_close($ch);
if(gettype($response) === 'object' && $response->data && $response->data->detections) {
$firstLanguageDetected = $response->data->detections[0];
if($firstLanguageDetected->isReliable) {
$data['language'] = $firstLanguageDetected->language;
} else {
$data['languageNotReliable'] = true;
}
}
return $data;
}
/**
* returns the mail addresses for cl and customer involved in the order process
* @param String $customerName customer's name
* @param String $commercialLeadName commercial lead's name
* @return Array mails of the customer and commercial lead
*/
private function orderParticipantsMails($idOrder) {
global $database, $user;
$mailArray = [];
$sql = "
SELECT
c.idUser,
u.mail,
'customer' AS type
FROM
".TABLES['customers']." c
INNER JOIN ".TABLES['rel_commercial_lead_customers']." rclc
ON rclc.idCustomer=c.id
INNER JOIN ".TABLES['orders']." o
ON o.idCustomerInstance=rclc.id
INNER JOIN ".TABLES['users']." u
ON u.id = c.idUser
WHERE o.id=$idOrder
UNION
SELECT
cl.idUser,
u.mail,
'other' AS type
FROM
".TABLES['commercial_leads']." cl
INNER JOIN ".TABLES['rel_commercial_lead_customers']." rclc
ON rclc.idCommercialLead=cl.id
INNER JOIN ".TABLES['orders']." o
ON o.idCustomerInstance=rclc.id
INNER JOIN ".TABLES['users']." u
ON u.id = cl.idUser
WHERE o.id=$idOrder
UNION
SELECT
b.idUser,
u.mail,
'other' AS type
FROM
".TABLES['brokers']." b
INNER JOIN ".TABLES['orders']." o
ON CASE WHEN o.assignedTo is NULL THEN 1=1 ELSE o.assignedTo=b.id END
INNER JOIN ".TABLES['users']." u
ON u.id = b.idUser
WHERE o.id=$idOrder
";
$result = $database->query($sql);
while($row = $database->fetchArray($result)) {
if($row['mail'] !== '') {
if($row['idUser'] != $user->getUserId()) {
$mailArray[$row['type']][] = $row['mail'];
}
}
}
return $mailArray;
}
/**
* checks parameters and sends mail based on the action made
* @param String $mailType the action for which to send the mail
* @param Json string $orderData the details regarding the order for which to send the mail
* @return Array confirmation message
*/
private function sendConfirmationMail($mailType, $orderData) {
global $database, $user;
$mailType = $database->escapeValue($mailType);
$commentMessage = array_key_exists('commentMessage', $orderData) ? $orderData['commentMessage'] : '';
foreach($orderData as $orderKey => $orderDetail) {
$orderData[$orderKey] = $database->escapeValue($orderDetail);
}
$data = [];
$idOrder = array_key_exists('idOrder', $orderData) ? $orderData['idOrder'] : 0;
$orderNumber = array_key_exists('orderNumber', $orderData) ? $orderData['orderNumber'] : UtilsModel::getOrderNumberById($idOrder);
if(!$mailType) {
return [
'code' => 'error',
'message' => 'ACTION_NOT_SET'
];
}
if(count($orderData) < 1) {
return [
'code' => 'error',
'message' => 'ORDER_DATA_NOT_SET'
];
}
if(!$idOrder) {
return [
'code' => 'error',
'message' => 'ID_ORDER_NOT_SET'
];
}
if(!$orderNumber) {
return [
'code' => 'error',
'message' => 'ORDER_NUMBER_NOT_SET'
];
}
$currentDate = new DateTime();
$currentDate = $currentDate->format('d-m-Y H:i');
$params = [
'apiOrderUrl' => WIAAS_URL.'/api-wiaas/orders?subModule=orders_steps&idOrder='.$idOrder.'&orderNumber='.$orderNumber,
'orderUrl' => WIAAS_URL.'/orders/'.$idOrder,
'mailType' => $mailType,
'currentDate' => $currentDate,
'idOrder' => $idOrder,
'orderNumber' => $orderNumber
];
switch($mailType) {
case 'orderCommentAdded':
$mailTitle = "New comment for order $orderNumber ($currentDate)";
$mailAddresses = $this->orderParticipantsMails($idOrder);
$params['commentMessage'] = $commentMessage;
$params['userLoggedIn'] = $user->getUserFullName();
break;
default:
return $data;
}
return UtilsModel::sendOrderUpdateMail($mailType, $params, $mailTitle, $mailAddresses);
}
/**
* add a new commnet for an order
* @param INT $idOrder Id of the order
* @param String $comment commnet text
* @return array update message
*/
public function addOrderComment($idOrder, $comment){
global $database, $user;
$data = [];
$idOrder = $database->escapeValue($idOrder);
$idUser = $user->getUserId();
$ordersDetailsMail = ['idOrder' => $idOrder];
$checkMessage = $database->isEmpty('comment', $comment);
if($checkMessage){
$data['messages'][] = $checkMessage;
}
$checkMessage = $database->invalidLength('comment',$comment, 1700);
if($checkMessage){
$data['messages'][] = $checkMessage;
}
if($data) {
return $data;
}
$allowedLanguages = $this->getSystemAllowedLanguages();
if(count($allowedLanguages) === 0) {
$data['messages'][] = [
'code' => 'error',
'message' => 'SYSTEM_ALLOWED_LANGUAGES_EMPTY'
];
}
$languageDetected = $this->getLanguageDetectResponse($comment);
$allowedLang = implode(', ', $allowedLanguages['languages']);
if(array_key_exists('language', $languageDetected)) {
if(!in_array($languageDetected['language'], $allowedLanguages['code'])) {
$data['messages'][] = [
'code' => 'error',
'message' => 'ALLOWED_LANGUAGE',
'key' => $allowedLang
];
}
} else if(array_key_exists('languageNotReliable', $languageDetected)) {
$data['messages'][] = [
'code' => 'warning',
'message' => 'ALLOWED_LANGUAGE',
'key' => $allowedLang
];
} else {
$data['messages'][] = [
'code' => 'error',
'message' => 'ALLOWED_LANGUAGE_ERROR',
'additionalMessage' => $languageDetected['error']
];
return $data;
}
$sql = "INSERT INTO ".TABLES['rel_order_comments']."
(idOrder, idUser, comment)
VALUES ($idOrder, $idUser, '".$database->escapeValue($comment)."')";
$query = $database->query($sql);
if(!$query){
$err_mes = [
'code' => 'error',
'message' => 'SERVER_ERROR'
];
$data['messages'][] = $err_mes;
}
if($database->affectedRows() === 1){
$message = [
'code' => 'success',
'message' => 'ORDER_COMMENT_ADDED'
];
$data['messages'][] = $message;
$ordersDetailsMail['commentMessage'] = $comment;
$data['messages'][] = $this->sendConfirmationMail('orderCommentAdded', $ordersDetailsMail);
}
return $data;
}
/**
* checks if the next step is the one needed for enabling the component
* @param Int $idOrder id of the order
* @param Int $idPackage id of the package
* @param Array $stepIds actions id of the steps between which the step should be enabled
* @return bool true if the next step should enable the component
*/
public function checkIfIsNextStepWanted($idOrder, $idPackage, $stepIds) {
$installationScheduling = new InstallationScheduling();
return $installationScheduling->checkIfIsNextStepWanted($idOrder, $idPackage, $stepIds);
}
/**
* returns the earliest installation date based on the maximum delivery date plus the additional days
* @param Int $idOrder the id of the order
* @return Array the earliest installation date or error message
*/
public function getEarliestInstallationDateForOrder($idOrder) {
$installationScheduling = new InstallationScheduling();
return $installationScheduling->getInstallationScheduleEID($idOrder);
}
/**
* get installation dates for each package in order
* @param INT $idOrder id for the order
* @param INT $idPackage id for the package
* @return Array array of installation dates
*/
public function getInstallationDates($idOrder, $idPackage){
$installationScheduling = new InstallationScheduling();
return $installationScheduling->getInstallationDates($idOrder, $idPackage);
}
/**
* get all installation companies for the order selected
* @param Int $idOrder id of the order
* @return Array array with all the installation companies
*/
public function getInstallCompaniesForOrder($idOrder) {
$installationScheduling = new InstallationScheduling();
return $installationScheduling->getInstallCompaniesForOrder($idOrder);
}
/**
* Update the estimation date for the installation
* @param Int $idOrder Id of the order to be modified
* @param Int $idPackage id of the package to be modified
* @param String $newDate the date set by the user for the installation
* @param String $status the status of the date to be added
* @return array response message for the update
*/
public function updateInstallationDate($idOrder, $idPackage, $newDate, $status) {
$installationScheduling = new InstallationScheduling();
return $installationScheduling->updateInstallationDate($idOrder, $idPackage, $newDate, $status);
}
/**
* remove the date from the order package
* @param Int $idOrder id of the order
* @param Int $idPackage id of the package
* @param String $installationDate the installation date to be removed
* @return Array confirmation messages
*/
public function removeMyDate($idOrder, $idPackage, $installationDate) {
$installationScheduling = new InstallationScheduling();
return $installationScheduling->removeMyDate($idOrder, $idPackage, $installationDate);
}
/**
* get customer questionaires / installation protocol for a specific order
* @param INT $idOrder id for the order
* @param INT $idPackage id for the pacakge
* @param String $documentType the type of the documents needed - Order Questionaire or Installation protocol
* @return Array array of documents
*/
public function getOrderDocumentsPerType($idOrder, $documentType){
$orderExtraActions = new orderExtraActions();
return $orderExtraActions->getOrderDocumentsPerType($idOrder, $documentType);
}
/**
* upload again quesionnaire
* @param INT $idOrder id for the order
* @param INT $idPackage id for the package
* @param INT $idDocument id for the document
* @param file $file file to be uploaded
* @return Array update message
*/
public function reUploadQuestionaire($idOrder, $idPackage, $idDocument, $file){
$orderExtraActions = new orderExtraActions();
return $orderExtraActions->reUploadQuestionaire($idOrder, $idPackage, $idDocument, $file);
}
/**
* get comments by type e.g stepComment, invalidQuestionaireComment, ...
* @param Int $idOrder the id of the order
* @param Int $idPackage the id of the package
* @param Int $idProcessStep the id of the process step
* @param String $type the type of the comment: stepComment, invalidQuestionaireComment
* @return Array the comments wanted
*/
public function getCommentsByType($idOrder, $idPackage, $idProcessStep, $type) {
$orderExtraActions = new orderExtraActions();
return $orderExtraActions->getCommentsByType($idOrder, $idPackage, $idProcessStep, $type);
}
/**
* get info for customer acceptance
* @param INT $idOrder id for the order
* @return Array custoemr acceptance info
*/
public function getCustomerAcceptance($idOrder){
$customerAcceptance = new CustomerAcceptance();
return $customerAcceptance->getCustomerAcceptance($idOrder);
}
/**
* upload customer acceptance document
* @param INT $idOrder id for the order
* @param FILE $file file to be uploaded
* @return Array upload status
*/
public function uploadAcceptanceDocument($idOrder, $file){
$customerAcceptance = new CustomerAcceptance();
return $customerAcceptance->uploadAcceptanceDocument($idOrder, $file);
}
/**
* customer change acceptance status for a package
* @param INT $idOrder id for the order
* @param String $actionType accept or decline the installation
* @param String $declineReason the reason for why the customer doesn't accept the installation
* @return Array update message
*/
public function acceptDeclineInstallation($idOrder, $actionType, $declineReason){
$customerAcceptance = new CustomerAcceptance();
return $customerAcceptance->acceptDeclineInstallation($idOrder, $actionType, $declineReason);
}
/**
* send an email to the support team from the customer
* @param Array $ordersInfo the order informations like orderNumber, so on
* @param Array $orderPackages the packages contained in the order
* @param String $userText the text writen by the customer
* @return Array confirmation message
*/
public function sendSupportMail($ordersInfo, $orderPackages, $userText) {
global $database, $user;
$ordersInfo = (array) $ordersInfo;
$orderPackages = $orderPackages;
$userText = $database->escapeValue($userText);
$mailSubject = "";
if($user->getUserType() !== USER_TYPES['CUSTOMER']) {
$data['messages'][] = [
'code' => 'error',
'message' => 'MAIL_NOT_AUTHORIZED'
];
return $data;
}
if(empty($userText)) {
$data['messages'][] = [
'code' => 'error',
'message' => 'MAIL_TEXT_EMPTY'
];
return $data;
}
$orderItems = '<div class="order-details-item">';
foreach($orderPackages as $package) {
$orderItems .= '<div class="send-support-mail-details">
<span class="glyphicon glyphicon-shopping-cart"></span>
' . $package['units'] . ' x ' . $package['packageName'] . '
</div>
<div class="package-item-info">
<div class="send-support-mail-details">
<b>Price: </b>
'. $this->calculatePrice([$package['packageFixedPrice']], $package['units']) . '
( ' . $this->calculatePrice([$package['packageRecuringPrice'], $package['packageServicePrice']], $package['units']) . '/ ' . $package['periodUnit'] . ')
</div>
<div class="prices-info">';
if($package['packagePayPeriod'] > 0) {
$orderItems .= '<div class="send-support-mail-details">
Package recurent price: ' . $package['units'] . ' x ' . $package['packageRecuringPrice'] . ' / ' . $package['periodUnit'] .'
for ' . $package['packagePayPeriod'] . ' ' . $package['periodUnit'] . '
</div>';
}
$orderItems .= ' <div class="send-support-mail-details">
<b>Services and support</b>
' . $package['units'] . ' x ' . $package['packageServicePrice'] . ' / ' . $package['periodUnit'];
if($package['servicesContractPeriod'] > 0) {
$orderItems .= '<span>for ' . $package['servicesContractPeriod'] . ' ' . $package['periodUnit'] . '</span>';
}
$orderItems .= 'with possibility to extend each ' . $package['periodUnit'] . ' (Max ' . $package['maxContractPeriod'] . ')
</div>
</div>';
if(intval($package['packagePayPeriod']) > 0 || intval($package['servicesContractPeriod']) > 0) {
$orderItems .= '<div class="send-support-mail-details">
<b>Agreement period: </b>';
if(intval($package['packagePayPeriod']) > 0) {
$orderItems .= '<div class="order-info-box">
<b>Agreement for package: </b>
' . $package['packagePayPeriod'] . ' ' . $package['periodUnit'] . '
</div>';
}
if(intval($package['servicesContractPeriod']) > 0) {
$orderItems .= '<div class="order-info-box">
<b>Agreement for services and support: </b>
' . $package['servicesContractPeriod'] . ' ' . $package['periodUnit'] . '
</div>';
}
$orderItems .= '</div>';
}
if(array_key_exists('shortDesc', $package) && $package['shortDesc']) {
$orderItems .= '<div class="send-support-mail-details">
<b>Delivery active step: </b> ' . $package['shortDesc'] . '
</div>';
}
if($package['endOfLife']) {
$orderItems .= '<div class="send-support-mail-details">
<b>End of life: </b> ' . $package['endOfLife'] . '
</div>';
}
$orderItems .= '<div class="package-item-status order-status-{{package.status}}">
<b>Status: </b> '. $package['status'] . '
</div>';
}
$orderItems .= '</div><br />';
$params = [
'orderNumber' => $ordersInfo['orderNumber'],
'idOrder' => $ordersInfo['id'],
'customerName' => $ordersInfo['customerName'],
'customerMail' => $ordersInfo['mail'],
'customerPhone' => $ordersInfo['phone'],
'reference' => $ordersInfo['reference'] ? $ordersInfo['reference'] : '-',
'tender' => $ordersInfo['tender'] ? $ordersInfo['tender'] : '-',
'commercialLead' => $ordersInfo['clName'],
'orderItems' => $orderItems,
'userText' => preg_replace('#(\\\r|\\\r\\\n|\\\n)#', '<br/>', $userText)
];
$currentDate = new DateTime();
$currentDate = $currentDate->format('d-m-Y H:i');
$mailSubject = "Support needed for " . $ordersInfo['orderNumber'] . " from " . $ordersInfo['customerName'] . "(" . $currentDate . ")";
$response = Mail::sendMail(SUPPORT_MAIL_LIST, $mailSubject, 'supportMailTemplate.php', $params);
if($response){
$data['messages'][] = [
'code' => 'success',
'message' => 'SUPPORT_MAIL_SENT'
];
} else {
$data['messages'][] = [
'code' => 'error',
'message' => 'ERROR_MAIL_SENT'
];
}
return $data;
}
/**
* calculates the total price of given package and units
* @param Array $packagePrice the prices for each package in order
* @param Int $units the quantity of same packages in order
* @return Float the total price for the order
*/
private function calculatePrice($packagePrice, $units) {
$total = 0;
forEach($packagePrice as $val) {
$total += (float) $val;
}
return $units ? ($total * intval($units)) : 0;
}
/**
* get all installation data for order
* @param Int $idOrder id of the order
* @param Array $stepIds actions id of the steps between which the step should be enabled
* @param String $fileType the type of the documents needed - Order Questionaire or Installation protocol
* @return Array array with all data needed for the installation scheduling
*/
public function getAllDataForInstallation($idOrder, $stepIds, $fileType) {
$installationScheduling = new InstallationScheduling();
return $installationScheduling->getAllDataForInstallation($idOrder, $stepIds, $fileType);
}
}