Files
old-wiaas-legacy/api-wiaas/server/components/v1/orders/InstallationScheduling.php
2018-06-11 11:09:35 +02:00

1329 lines
49 KiB
PHP

<?php
class InstallationScheduling{
const ID_ADDITONAL_TYPE = 3;
const CUSTOMER_ACCEPTANCE_DAYS_INTERVAL = 15;
const ID_INSTALLATION_CATEGORY = 2;
/**
* get all installation companies for the order and package selected
* @param Int $idOrder id of the order
* @param Int $idPackage id of the package
* @return Array array with all the installation companies
*/
public function getInstallCompaniesForPackage($idOrder, $idPackage) {
global $database, $user;
$idOrder = $database->escapeValue($idOrder);
$idPackage = $database->escapeValue($idPackage);
$whereSql = '';
$installationSelectedArray = [];
$installationSelected = [];
$isMyInstallationCompany = false;
$extraWhere = '';
$extraJoin = '';
if(!$idOrder) {
return [];
}
if($user->getUserType() === USER_TYPES['SUPPLIER']) {
$extraWhere = "AND u.id = ".$user->getUserId();
$extraJoin = "INNER JOIN ".TABLES['installation_company_selections']." ics
ON ics.idProduct = rpp.idProduct
AND ics.idPackage = rpp.idPackage
AND ics.idOrder = rop.idOrder
AND ics.isActive = 1";
}
$whereSql = $idPackage != 0 ? "AND os.idPackage = $idPackage" : "";
$sql = "
SELECT
scp.idProduct AS id,
scp.idSupplier,
scp.productName AS name
FROM
".TABLES['order_selections']." os
INNER JOIN ".TABLES['suppliers_countries_products']." scp
ON scp.idProduct = os.idProduct
INNER JOIN ".TABLES['suppliers']." s
ON s.id = scp.idSupplier
INNER JOIN ".TABLES['users']." u
ON u.id = s.idUser
WHERE os.idOrder = $idOrder
$whereSql
AND os.selectionFor = 'installation'
$extraWhere
LIMIT 1
";
$installationSelectedArray = $database->fetchResultArray($sql);
if(count($installationSelectedArray) > 0) {
$installationSelected = $installationSelectedArray;
$isMyInstallationCompany = true;
}
$whereSql = $idPackage != 0 ? "AND rpp.idPackage = $idPackage" : "";
$sql = "
SELECT
scp.idProduct AS id,
scp.idSupplier,
scp.productName AS name
FROM
".TABLES['rel_package_products']." rpp
INNER JOIN ".TABLES['rel_order_packages']." rop
ON rop.idPackage = rpp.idPackage
AND rpp.packageInstance = rop.packageInstance
INNER JOIN ".TABLES['suppliers_countries_products']." scp
ON scp.idProduct = rpp.idProduct
INNER JOIN ".TABLES['product_categories']." pc
ON pc.id = scp.idProductCategory
INNER JOIN ".TABLES['product_types']." pt
ON pt.id = pc.idType
INNER JOIN ".TABLES['suppliers']." s
ON s.id = scp.idSupplier
INNER JOIN ".TABLES['users']." u
ON u.id = s.idUser
$extraJoin
WHERE pt.type = 'installation'
AND rop.idOrder = $idOrder
$whereSql
$extraWhere
";
$availableCompanies = $database->fetchResultArray($sql);
if(count($availableCompanies) === 1) {
$installationSelected = $availableCompanies;
if(!$isMyInstallationCompany) {
$isMyInstallationCompany = true;
}
}
return [
'available' => $availableCompanies,
'selected' => $installationSelected,
'isMyInstallationCompany' => $isMyInstallationCompany
];
}
/**
* save the installation company
* @param [type] $idOrder [description]
* @param [type] $idPackage [description]
* @param [type] $idInstallation [description]
* @return [type] [description]
*/
public function saveInstallationCompany($idOrder, $idPackage, $idInstallation) {
global $database;
$idOrder = $database->escapeValue($idOrder);
$idPackage = $database->escapeValue($idPackage);
$idInstallation = $database->escapeValue($idInstallation);
$installationScheduling = new InstallationScheduling();
if(!$idOrder || !$idPackage || !$idInstallation) {
$data['messages'][] = [
'code' => 'error',
'message' => 'DATA_NOT_SET'
];
return $data;
}
$sqlSelect = "
SELECT idProduct
FROM ".TABLES['order_selections']."
WHERE idOrder = $idOrder
AND idPackage = $idPackage
";
$result = $database->query($sqlSelect);
if($database->numRows($result) > 0) {
$sql = "
UPDATE
".TABLES['order_selections']."
SET
idProduct = $idInstallation
WHERE idOrder = $idOrder AND idPackage = $idPackage";
} else {
$sql = "
INSERT INTO ".TABLES['order_selections']."
(idOrder, idPackage, idProduct, selectionFor)
VALUES
($idOrder, $idPackage, $idInstallation, 'installation')
";
}
$result = $database->query($sql);
$data = self::changeInstallationCompany($idOrder, $idPackage, $idInstallation);
$data['messages'][] = self::setSchedulingFlagForCustomer($idOrder, $idPackage, 1);
return $data;
}
/**
* customer change acceptance status for a package
* @param INT $idOrder id for the order
* @param INT $idPackage id for the packages
* @param String $actionType accept or decline the installation
* @param String $declineReason the reason why the customer declined the installation
* @return Array update message
*/
public function acceptDeclineInstallation($idOrder, $idPackage, $actionType, $declineReason){
global $database;
$idOrder = $database->escapeValue($idOrder);
$idPackage = $database->escapeValue($idPackage);
$actionType = trim($database->escapeValue($actionType));
$declineReason = trim($database->escapeValue($declineReason));
$data = [];
$customerAcceptanceStatus = 1;
$successMessage = 'INSTALLATION_ACCEPTED';
if($actionType === 'decline') {
if(!$declineReason) {
$data['messages'][] = [
'code' => 'error',
'message' => 'DECLINE_REASON_EMPTY'
];
return $data;
}
$customerAcceptanceStatus = -1;
$successMessage = 'INSTALLATION_DECLINED';
}
$sql = "UPDATE ".TABLES['rel_order_packages']."
SET customerAccepted=$customerAcceptanceStatus,
customerDeclineReason='$declineReason'
WHERE idOrder=$idOrder AND idPackage=$idPackage";
$query = $database->query($sql);
if($database->affectedRows() > 0){
$data['messages'][] = [
'code' => 'success',
'message' => $successMessage
];
}else{
$data['messages'][] = [
'code' => 'warning',
'message' => 'ACCEPTANCE_NOT_UPDATED'
];
}
return $data;
}
/**
* sets the earliest installation date in DB
* @param Int $idOrder id of the order
* @param Int $idPackage id of the package
* @param String $maxDeliveryDate maximumDeliveryDate
* @return Array id of the order and package of the row inserted
*/
public function setEarliestInstallationDateInDb($idOrder, $idPackage, $maxDeliveryDate) {
global $database, $user;
$idOrder = $database->escapeValue($idOrder);
$idPackage = $database->escapeValue($idPackage);
$maxDeliveryDate = $database->escapeValue($maxDeliveryDate);
$whereSql = $idPackage != 0 ? "AND idPackage = $idPackage" : "";
$rowsAffected = 0;
$data = [];
if(!$idOrder) {
$data['messages'][] = [
'code' => 'error',
'message' => 'ORDER_NOT_SET'
];
}
if(empty($maxDeliveryDate)) {
$data['messages'][] = [
'code' => 'error',
'message' => 'DATE_NOT_SET'
];
}
if(isset($data['messages'])) {
return $data;
}
if($maxDeliveryDate === 'remove'){
$sql = "
UPDATE ".TABLES['rel_order_packages']."
SET
earliestInstallationDate = null
WHERE idOrder = $idOrder $whereSql";
$result = $database->query($sql);
$rowsAffected = $database->affectedRows();
if($rowsAffected > 0) {
$data = [
'idOrder' => $idOrder,
'idPackage' => $idPackage
];
}
$data['messages'][] = $this->removeInstallationDates($idOrder, $idPackage);
$data['messages'][] = self::setSchedulingFlagForCustomer($idOrder, $idPackage, 0);
return $data;
}
/*if($user->getUserType() !== USER_TYPES['BROKER']) {
$sql = "SELECT rope.idProduct,
rope.estimatedDate,
rope.confirmedDate,
s.id AS idSupplier
FROM ".TABLES['rel_order_products_estimation']." rope
INNER JOIN ".TABLES['suppliers_countries_products']." scp
ON scp.idProduct=rope.idProduct
INNER JOIN ".TABLES['suppliers']." s
ON s.id=scp.idSupplier
WHERE idOrder=$idOrder
$whereSql
AND scp.idProductCategory!=".self::ID_INSTALLATION_CATEGORY."
ORDER BY s.id,
scp.productName";
$query = $database->query($sql);
while($row = $database->fetchArray($query)){
if(!$row['estimatedDate'] || !$row['confirmedDate']) {
return $data;
}
}
}*/
$sql = "SELECT
p.additionalInstallDays,
p.id AS idPackage,
c.code AS countryCode
FROM
".TABLES['packages']." p
INNER JOIN ".TABLES['countries']." c
ON c.id = p.idCountry
INNER JOIN ".TABLES['rel_order_packages']." rop
ON rop.idPackage=p.id
WHERE rop.idOrder=$idOrder $whereSql";
$query = $database->query($sql);
$rowsAffected = 0;
while($row = $database->fetchArray($query)){
$additionalDays = intval($row['additionalInstallDays']);
$interval = 'P'.$additionalDays.'D';
$packageMaxDeliveryDate = new DateTime($maxDeliveryDate);
$packageMaxDeliveryDate->add(new DateInterval($interval));
$earliestInstallationDate = $packageMaxDeliveryDate->format('Y-m-d');
$sql = "
UPDATE ".TABLES['rel_order_packages']."
SET
earliestInstallationDate = '$earliestInstallationDate'
WHERE idOrder = $idOrder AND idPackage=".$row['idPackage'];
$result = $database->query($sql);
$rowsAffected += $database->affectedRows();
if($rowsAffected > 0) {
$data = self::checkIfInstallationDateIsValid($idOrder, $row['idPackage'], $earliestInstallationDate);
$data['idOrder'] = $idOrder;
$data['idPackage'] = $row['idPackage'];
if(array_key_exists('messages', $data)) {
$data['callConfirmationInstallationDatesFct'] = true;
}
$data['messages'][] = self::sendMailIfSchedulingEnabledForCustomer($idOrder, $row['idPackage']);
}
}
return $data;
}
/**
* verifies if the installation dates are still valid after changing the earliest installation date
* @param Int $idOrder id of the order
* @param Int $idPackage id of the package
* @param String $earliestInstallationDate empty if not passed or the earliest installation date set
* @return Array array with update messages
*/
public function checkIfInstallationDateIsValid($idOrder, $idPackage, $earliestInstallationDate = '') {
global $database;
$idOrder = $database->escapeValue($idOrder);
$idPackage = $database->escapeValue($idPackage);
$earliestInstallationDate = $database->escapeValue($earliestInstallationDate);
$invalidDates = [];
$revalidDates = [];
$acceptedDate = '';
$data = [];
if(!$earliestInstallationDate) {
$earliestInstallationDate = self::getInstallationScheduleEID($idOrder, $idPackage);
}
$installationDates = $this->getInstallationDates($idOrder, $idPackage);
foreach ($installationDates as $installDate => $details) {
if($installDate < $earliestInstallationDate && $details['lastStatus'] !== 'invalid') {
array_push($invalidDates, $installDate);
if($details['lastStatus'] === 'accepted') {
$acceptedDate = $installDate;
}
} else if($installDate > $earliestInstallationDate && $details['lastStatus'] === 'invalid') {
array_push($revalidDates, $installDate);
}
}
if(count($invalidDates)) {
if($message = $this->changeInstallationDatesStatus($idOrder, $idPackage, $invalidDates, 'invalid')) {
$data['messages'][] = $message;
}
if($acceptedDate) {
$mailDetails = [
'idOrder' => $idOrder,
'acceptedDate' => $acceptedDate
];
$mailTitle = 'Installation date not valid anymore';
$templateUrl = 'installationDateInvalidTemplate.php';
$data['messages'][] = self::sendInstallationSchedulingMail($mailDetails, $mailTitle, $templateUrl);
}
}
if(count($revalidDates)) {
if($message = $this->changeInstallationDatesStatus($idOrder, $idPackage, $revalidDates, 'proposed')) {
$data['messages'][] = $message;
}
}
return $data;
}
/**
* changes the installation dates statuses if the earliest installation date has changed
* @param Int $idOrder id of the order
* @param Int $idPackage id of the package
* @param Array $dates array with the dates that need a status change
* @param String $status the future status for the selected installation dates
* @return Array update messages
*/
private function changeInstallationDatesStatus($idOrder, $idPackage, $dates, $status) {
global $database, $user;
$extraWhere = '';
if($idPackage) {
$extraWhere = " AND idPackage=$idPackage";
}
if(count($dates)) {
$statusUpdated = 0;
foreach($dates as $installationDate) {
$sql = "INSERT INTO ".TABLES['installation_schedule_dates']." (
idCompanySelection,
idUser,
date,
status
)
(SELECT
id,
".$user->getUserId().",
'".$installationDate."',
'".$status."'
FROM
".TABLES['installation_company_selections']."
WHERE idOrder = $idOrder
$extraWhere)";
$query = $database->query($sql);
$statusUpdated += $database->affectedRows();
}
if(count($dates) === $statusUpdated) {
return [
'code' => 'success',
'message' => 'INSTALLATION_DATES_STATUS_CHANGED'
];
}
}
return;
}
/**
* returns the earliest installation date based on the maximum delivery date plus the additional days
* @param Int $idOrder the id of the order
* @param Int $idPackage the id of the package
* @return Array the earliest installation date or error message
*/
public function getEarliestInstallationDate($idOrder, $idPackage) {
global $database;
$idOrder = $database->escapeValue($idOrder);
$idPackage = $database->escapeValue($idPackage);
$data = [];
$earliestInstallationDate = self::getInstallationScheduleEID($idOrder, $idPackage);
$data = [
'earliestInstallationDate' => $earliestInstallationDate,
'idOrder' => $idOrder,
'idPackage' => $idPackage
];
return $data;
}
/**
* returns an update message
* @param Int $idOrder the id of the order
* @param Int $idPackage the id of the package
* @return Array update messages
*/
private function removeInstallationDates($idOrder, $idPackage) {
global $database;
$idOrder = $database->escapeValue($idOrder);
$idPackage = $database->escapeValue($idPackage);
$whereSql = $idPackage != 0 ? "AND idPackage = $idPackage" : "";
$data = [];
$sql = "
DELETE
isd
FROM
".TABLES['installation_schedule_dates']." isd
INNER JOIN ".TABLES['installation_company_selections']." ics
ON isd.idCompanySelection = ics.id
AND idOrder = $idOrder
$whereSql
AND isActive = 1";
$query = $database->query($sql);
if($database->affectedRows()) {
$data['messages'][] = [
'code' => 'success',
'message' => 'INSTALLATION_DATES_REMOVED'
];
}
return $data;
}
/**
* 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){
global $database, $user;
$data = [];
$idOrder = $database->escapeValue($idOrder);
$idPackage = $database->escapeValue($idPackage);
$whereSql = $idPackage != 0 ? "AND ics.idPackage = $idPackage" : "";
$sql = "
SELECT
isd.date,
isd.status,
isd.idUser,
isd.currentDate,
u.username,
ut.type AS userType
FROM
".TABLES['installation_schedule_dates']." isd
INNER JOIN ".TABLES['installation_company_selections']." ics
ON isd.idCompanySelection = ics.id
INNER JOIN ".TABLES['users']." u
ON u.id = isd.idUser
INNER JOIN ".TABLES['rel_user_type']." rut
ON rut.idUser = u.id
INNER JOIN ".TABLES['user_types']." ut
ON ut.id = rut.idType
WHERE ics.idOrder = $idOrder $whereSql AND ics.isActive = 1
ORDER BY isd.date, isd.currentDate
";
$result = $database->query($sql);
while($row = $database->fetchArray($result)) {
$data[$row['date']]['isProposedByMe'] = intval($row['idUser']) === intval($user->getUserId());
unset($row['idUser']);
$data[$row['date']]['details'][] = $row;
$data[$row['date']]['lastStatus'] = $row['status'];
}
return $data;
}
/**
* 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) {
global $database, $user;
$idOrder = $database->escapeValue($idOrder);
$idPackage = $database->escapeValue($idPackage);
$newDate = $database->escapeValue($newDate);
$status = $database->escapeValue($status);
$data = [];
$userType = $user->getUserType();
$mailTitle = '';
$templateUrl = '';
if(!$newDate) {
$data['messages'][] = [
'code' => 'error',
'message' => 'INSTALLATION_DATE_EMPTY'
];
return $data;
}
$checkDate = $database->invalidDate('INVALID_DATE_ESTIMATED', $newDate);
if($checkDate){
$data['messages'][] = $checkDate;
return $data;
}
if(!$status) {
$data['messages'][] = [
'code' => 'error',
'message' => 'STATUS_NOT_SET'
];
return $data;
}
$earliestInstallationDate = self::getInstallationScheduleEID($idOrder, $idPackage);
if(!$earliestInstallationDate) {
$data['messages'][] = [
'code' => 'error',
'message' => 'EID_NOT_SET'
];
return $data;
}
$idCompanySelection = $this->getActiveInstallationCompanyId($idOrder, $idPackage);
if(!$idCompanySelection) {
$data['messages'][] = [
'code' => 'error',
'message' => 'RELATION_NOT_FOUND'
];
return $data;
}
if($userType === USER_TYPES['CUSTOMER']) {
$brokerMails = (array) UtilsModel::getBrokersMail();
$supplierMail = (array) $this->getSupplierMail($idCompanySelection);
$mail = array_merge($brokerMails, $supplierMail);
} else if($userType === USER_TYPES['SUPPLIER']){
$mail = self::getCustomerMail($idOrder);
} else {
$customerMail = (array) self::getCustomerMail($idOrder);
$supplierMail = (array) self::getSupplierMail($idCompanySelection);
$mail = array_merge($customerMail, $supplierMail);
}
$mailDetails = [
'idOrder' => $idOrder,
'idCompanySelection' => $idCompanySelection,
'orderNumber' => UtilsModel::getOrderNumberById($idOrder),
'acceptedDate' => $newDate,
'proposedDate' => $newDate,
'actionDoneBy' => $user->getUserFullName(),
'mail' => $mail
];
if($status === 'proposed') {
$mailTitle = 'New installation date proposed';
$templateUrl = 'installationProposedTemplate.php';
if($newDate < $earliestInstallationDate) {
$data['messages'][] = [
'code' => 'error',
'message' => 'PAST_DATE',
'key' => $earliestInstallationDate
];
return $data;
}
$sql = "
SELECT id
FROM ".TABLES['installation_schedule_dates']."
WHERE idCompanySelection = $idCompanySelection
AND date='$newDate' AND status='proposed'";
$result = $database->query($sql);
if($database->numRows($result) === 1) {
$data['messages'][] = [
'code' => 'error',
'message' => 'PROPOSED_DATE_EXISTS'
];
return $data;
}
if($userType === USER_TYPES['BROKER']) {
$earliestInstallationDate = new DateTime($earliestInstallationDate);
$maxSLAInstallDate = $earliestInstallationDate->add(new DateInterval('P'.ADDITIONAL_MAX_INSTALL_DAYS.'D'));
$maxSLAInstallDate = $maxSLAInstallDate->format('Y-m-d');
if($maxSLAInstallDate < $newDate) {
$data['messages'][] = [
'code' => 'warning',
'message' => 'MAX_SLA_EXCEEDED',
'key' => $maxSLAInstallDate
];
}
}
}
$lastStatuses = $this->getInstallationDateLastStatus($idCompanySelection);
if($status === 'accepted') {
$mailTitle = 'Installation date accepted';
$templateUrl = 'installationAcceptedTemplate.php';
$isinstallationAccepted = $this->installationDateIsAlreadyAccepted($lastStatuses, $newDate, $idCompanySelection);
if($isinstallationAccepted) {
$message = [
'code' => 'success',
'message' => 'INSTALLATION_ALREADY_ACCEPTED'
];
}
$sql = "UPDATE ".TABLES['orders']."
SET acceptanceDueDate=DATE_ADD('$newDate', INTERVAL ".self::CUSTOMER_ACCEPTANCE_DAYS_INTERVAL." DAY)
WHERE id=$idOrder";
$query = $database->query($sql);
}
$database->beginTransaction();
$sql = "
INSERT INTO ".TABLES['installation_schedule_dates']." (
idCompanySelection,
idUser,
date,
status
)
VALUES(
$idCompanySelection,
".$user->getUserId().",
'$newDate',
'$status'
)";
$query = $database->query($sql);
if($query){
$database->commit();
$message = [
'code' => 'success',
'message' => 'INSTALLATION_DATE_UPDATED'
];
}else{
$database->rollback();
$message = [
'code' => 'error',
'message' => 'SERVER_ERROR'
];
}
$data['messages'][] = $message;
if($status === 'declined') {
$confirmationDates = $this->getInstallationDates($idOrder, $idPackage);
if($confirmationDates) {
if(count($confirmationDates) > 0) {
$allDatesDeclined = true;
forEach($confirmationDates as $date => $details) {
if($details['lastStatus'] !== 'declined') {
$allDatesDeclined = false;
}
}
if($allDatesDeclined) {
$mailTitle = 'Installation dates declined';
$templateUrl = 'installationDeclinedTemplate.php';
}
}
}
}
if($mailTitle && $templateUrl) {
$data['messages'][] = self::sendInstallationSchedulingMail($mailDetails, $mailTitle, $templateUrl);
}
return $data;
}
/**
* returns the id of the installation company active for order and package
* @param Int $idOrder id of the order
* @param Int $idPackage id of the package
* @return Int id of the relation
*/
private function getActiveInstallationCompanyId($idOrder, $idPackage) {
global $database;
$sql = "
SELECT
ics.id AS selectionId
FROM
".TABLES['installation_company_selections']." ics
WHERE ics.idOrder = $idOrder AND ics.idPackage = $idPackage AND ics.isActive = 1";
$data = $database->fetchResultArray($sql);
if($data && $data[0]['selectionId']) {
return $data[0]['selectionId'];
}
return 0;
}
/**
* checks if an installation date is already accepted, and puts it in canceled state if so
* @param Array $lastStatuses the last status for each date
* @param String $newDate the date to be updated
* @param Int $idCompanySelected id of the installation company selected
* @return Boolean true or false if the installation date is accepted for the order package
*/
private function installationDateIsAlreadyAccepted($lastStatuses, $newDate, $idCompanySelected) {
global $database, $user;
$dateCanceled = 0;
foreach($lastStatuses as $installationDate => $lastStatus) {
if($installationDate !== $newDate && $lastStatus === 'accepted') {
$sql = "INSERT INTO ".TABLES['installation_schedule_dates']."
(idCompanySelection, idUser, date, status)
VALUES (
$idCompanySelected,
".$user->getUserId().",
'$installationDate',
'canceled'
)
";
$result = $database->query($sql);
if($database->affectedRows()) {
$dateCanceled++;
}
}
}
return false;
}
/**
* checks if there is at least one already accepted installation date
* @param Int $idOrder the id of the order
* @param Int $idPackage the id of the package
* @return Boolean true or false if the installation has an already accepted date
*/
public function checkIfDateAlreadyAccepted($idOrder, $idPackage) {
global $database;
$idCompanySelection = $this->getActiveInstallationCompanyId($idOrder, $idPackage);
$installationDateLastStatuses = $this->getInstallationDateLastStatus($idCompanySelection);
foreach($installationDateLastStatuses as $status) {
if($status === 'accepted') {
return true;
}
}
return false;
}
/**
* 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) {
global $database;
$idOrder = $database->escapeValue($idOrder);
$idPackage = $database->escapeValue($idPackage);
$installationDate = $database->escapeValue($installationDate);
if(!$installationDate) {
$data['messages'][] = [
'code' => 'error',
'message' => 'INSTALLATION_DATE_EMPTY'
];
return $data;
}
$idCompanySelection = $this->getActiveInstallationCompanyId($idOrder, $idPackage);
if(!$idCompanySelection) {
$data['messages'][] = [
'code' => 'error',
'message' => 'RELATION_NOT_FOUND'
];
return $data;
}
$lastStatus = $this->getInstallationDateLastStatus($idCompanySelection);
if($lastStatus[$installationDate] !== 'proposed') {
$data['messages'][] = [
'code' => 'error',
'message' => 'INSTALLATION_DATE_NOT_REMOVED'
];
return $data;
}
$sql = "
DELETE
FROM
".TABLES['installation_schedule_dates']."
WHERE idCompanySelection = $idCompanySelection
AND date = '$installationDate'";
$result = $database->query($sql);
if($database->affectedRows() === 1) {
$data['messages'][] = [
'code' => 'success',
'message' => 'INSTALLATION_DATE_REMOVED'
];
} else {
$data['messages'][] = [
'code' => 'error',
'message' => 'INSTALLATION_DATE_REMOVE_ERROR'
];
}
return $data;
}
/**
* gets the lastest status of the earliest installation date for an order
* @param Int $idCompanySelected the id of the insatllation company selected
* @return String the latest status or empty string
*/
private function getInstallationDateLastStatus($idCompanySelected) {
global $database;
$data = [];
$sql = "
SELECT
isd.date AS installationDate,
isd.status AS lastStatus
FROM
".TABLES['installation_schedule_dates']." isd
INNER JOIN
(SELECT
isdd.date AS installationDate,
MAX(isdd.currentDate) AS maxDate
FROM
".TABLES['installation_schedule_dates']." isdd
WHERE isdd.idCompanySelection = $idCompanySelected
GROUP BY isdd.date) installations_max_dates
ON installations_max_dates.installationDate = isd.date
AND installations_max_dates.maxDate = isd.currentDate
WHERE isd.idCompanySelection = $idCompanySelected
ORDER BY isd.date";
$query = $database->query($sql);
while($row = $database->fetchArray($query)) {
$data[$row['installationDate']] = $row['lastStatus'];
}
return $data;
}
/**
* checks if the user logged is the owner of the product
* @param Int $idProduct the id of the product
* @return boolean true if the user is the owner of the product
*/
private function isProductOwner($idProduct){
global $user, $database;
if($user->getUserType() === USER_TYPES['BROKER']){
return true;
}else if($user->getUserType() === USER_TYPES['SUPPLIER']){
$sql = "SELECT s.id
FROM ".TABLES['suppliers']." s
INNER JOIN ".TABLES['suppliers_countries_products']." scp
ON scp.idSupplier=s.id
WHERE s.idUser=".$user->getUserId();
$query = $database->query($sql);
return $database->numRows($query) > 0;
}
return false;
}
/**
* change the installation company for the order and package selected
* @param Int $idOrder id of the order
* @param Int $idPackage id of the package
* @param Int $idInstallationCompany id of the installation company product
* @return Array update messages
*/
public function changeInstallationCompany($idOrder, $idPackage, $idInstallationCompany) {
global $database;
$idOrder = $database->escapeValue($idOrder);
$idPackage = $database->escapeValue($idPackage);
$idInstallationCompany = $database->escapeValue($idInstallationCompany);
$rowsAffected = 0;
$sqlSelectProduct = "
SELECT
ics.id AS idCompany
FROM
".TABLES['installation_company_selections']." ics
WHERE ics.idOrder = $idOrder AND ics.idPackage = $idPackage";
$data = $database->fetchResultArray($sqlSelectProduct);
if(count($data)) {
$idScheduleInfo = $data[0]['idCompany'];
$sqlUpdateCompanyStatus = "
UPDATE
".TABLES['installation_company_selections']."
SET
isActive = 0
WHERE idOrder = $idOrder AND idPackage = $idPackage";
$query = $database->query($sqlUpdateCompanyStatus);
}
$sqlInsertUpdateCompany = "
INSERT INTO
".TABLES['installation_company_selections']." (
idProduct,
idOrder,
idPackage
)
VALUES
($idInstallationCompany, $idOrder, $idPackage)
ON DUPLICATE KEY UPDATE
isActive = 1";
$result = $database->query($sqlInsertUpdateCompany);
$rowsAffected += $database->affectedRows();
if($rowsAffected) {
$data['messages'][] = [
'code' => 'success',
'message' => 'INSTALLATION_SAVED'
];
$data['messages'][] = self::sendMailIfSchedulingEnabledForCustomer($idOrder, $idPackage);
} else {
$data['messages'][] = [
'code' => 'error',
'message' => 'INSTALLATION_NOT_SAVED'
];
}
return $data;
}
/**
* returns the id of the installation info
* @param Int $idOrder id of the order
* @param Int $idPackage id of the package
* @return Array or Int error messages or id of the package
*/
public function getInstallationScheduleEID($idOrder, $idPackage) {
global $database;
$whereSql = $idPackage != 0 ? "AND idPackage = $idPackage" : "";
$data = [];
if(!$idOrder) {
$data['messages'][] = [
'code' => 'error',
'message' => 'ORDER_NOT_SET'
];
return $data;
}
$sql = "SELECT MAX(earliestInstallationDate) AS earliestInstallationDate
FROM
(SELECT
IFNULL(earliestInstallationDate, '-') AS earliestInstallationDate
FROM
".TABLES['rel_order_packages']."
WHERE idOrder = $idOrder
$whereSql) eid
";
$result = $database->fetchResultArray($sql);
return $result && $result[0] ? $result[0]['earliestInstallationDate'] : '';
}
/**
* send mail if scheduling is enabled for customer
* @param Int $idOrder id of the order
* @param Int $idPackage id of the package
* @return Array
*/
public function sendMailIfSchedulingEnabledForCustomer($idOrder, $idPackage) {
global $database;
$data = [];
$idOrderPackagePair = $idOrder . '-' . $idPackage;
$stepsName = json_encode([
'firstStepEnabled' => 5,
'lastStepEnabled' => 6
]);
$orderExtraActions = new orderExtraActions();
$installationScheduling = new InstallationScheduling();
$isSchedulingAlreadyEnabled = self::checkIfSchedulingAlreadyEnabledForCustomer($idOrder, $idPackage);
if(!intval($isSchedulingAlreadyEnabled)) {
$installCompanySelected = $installationScheduling->getInstallCompaniesForPackage($idOrder, $idPackage)['selected'];
$earliestInstallationDate = self::getInstallationScheduleEID($idOrder, $idPackage);
$isNextStepWanted = $orderExtraActions->checkIfIsNextStepWanted($idOrder, $stepsName);
if($installCompanySelected && count($installCompanySelected) > 0 &&
$earliestInstallationDate &&
$isNextStepWanted === false) {
$message = self::setSchedulingFlagForCustomer($idOrder, $idPackage, 1);
if($message['code'] === 'warning') {
return;
}
$customerInfo = UtilsModel::getDataForMailToCustomer($idOrder);
$sqlPackageInfo = "
SELECT
p.name AS packageName,
s.name AS supplierName
FROM ".TABLES['packages']." p
INNER JOIN ".TABLES['rel_order_packages']." rop
ON rop.idPackage = p.id
AND rop.idOrder = $idOrder
AND rop.idPackage = $idPackage
INNER JOIN ".TABLES['installation_company_selections']." ics
ON ics.idOrder = rop.idOrder
INNER JOIN ".TABLES['suppliers_countries_products']." scp
ON scp.idProduct = ics.idProduct
INNER JOIN ".TABLES['suppliers']." s
ON s.id = scp.idSupplier";
$query = $database->query($sqlPackageInfo);
$packageInfo = $database->fetchArray($query);
$params = [
'wiaas' => WIAAS_URL,
'ordersUrl' => WIAAS_URL.'/orders/'.$idOrder,
'orderNumber' => $customerInfo['orderNumber'],
'packageName' => $packageInfo['packageName'],
'supplierName' => $packageInfo['supplierName']
];
$response = Mail::sendMail($customerInfo['mail'], 'Schedule installation function is now enabled', 'customerScheduleInstallationEnabled.php', $params);
if($response){
$data = [
'code' => 'success',
'message' => 'SCHEDULING_ENABLED_MAIL'
];
} else {
$data = [
'code' => 'error',
'message' => 'ERROR_MAIL_SENT'
];
}
}
}
return $data;
}
/**
* check if the scheduling is already available for customer
* @param INT $idOrder id of the order
* @param INT $idPackage id of the package
* @return Bool 1 if the scheduling is already enabled
*/
public function checkIfSchedulingAlreadyEnabledForCustomer($idOrder, $idPackage) {
global $database;
$extraWhere = '';
if($idPackage) {
$extraWhere = " AND rop.idPackage = $idPackage";
}
$sql = "SELECT
rop.isSchedulingEnabledForCustomer
FROM
".TABLES['rel_order_packages']." rop
WHERE rop.idOrder = $idOrder
$extraWhere";
$result = $database->fetchResultArray($sql);
return $result ? $result[0]['isSchedulingEnabledForCustomer'] : 0;
}
/**
* sets the scheduling available or not available for customer
* @param INT $idOrder id of the order
* @param INT $idPackage id of the package
* @return Bool 1 if the scheduling is already enabled
*/
public function setSchedulingFlagForCustomer($idOrder, $idPackage, $flag) {
global $database;
$flag = intval($database->escapeValue($flag));
$extraWhere = '';
$message = [];
if($flag !== 0 && $flag !== 1) {
return [
'code' => 'error',
'message' => 'FLAG_NOT_AVAILABLE'
];
}
if($idPackage) {
$extraWhere = " AND idPackage = $idPackage";
}
$sql = "UPDATE
".TABLES['rel_order_packages']."
SET
isSchedulingEnabledForCustomer = $flag
WHERE idOrder = $idOrder
$extraWhere";
$result = $database->query($sql);
$affectedRows = $database->affectedRows();
if($affectedRows > 0) {
$message = [
'code' => 'success',
'key' => $flag ? 'enabled' : 'disabled',
'message' => 'SCHEDULE_FLAG_UPDATED'
];
}
if($flag === 0) {
$mailTitle = 'Installation scheduling is disabled';
$templateUrl = 'installationSchedulingDisabled.php';
$mailDetails = [
'idOrder' => $idOrder
];
$message = self::sendInstallationSchedulingMail($mailDetails, $mailTitle, $templateUrl);
}
return count($message) ? $message : [
'code' => 'warning',
'message' => 'SCHEDULE_FLAG_NO_UPDATE'
];
}
/**
* send mail for installation scheduling functionality
* @param Array $info array with all neccessary data about the order
* @param String $mailTitle the title of the mail
* @param String $templateUrl the mail template to be sent
* @return Array update message
*/
public function sendInstallationSchedulingMail($info, $mailTitle, $templateUrl) {
global $user;
$userType = $user->getUserType();
$idOrder = array_key_exists('idOrder', $info) ? $info['idOrder'] : 0;
$idCompanySelection = array_key_exists('idCompanySelection', $info) ? $info['idCompanySelection'] : 0;
$orderNumber = array_key_exists('orderNumber', $info) ? $info['orderNumber'] : 0;
$acceptedDate = array_key_exists('acceptedDate', $info) ? $info['acceptedDate'] : '';
$proposedDate = array_key_exists('proposedDate', $info) ? $info['proposedDate'] : '';
$actionDoneBy = array_key_exists('actionDoneBy', $info) ? $info['actionDoneBy'] : '-';
if(!$idOrder) {
return [
'code' => 'error',
'message' => 'ID_ORDER_NOT_SET'
];
}
if(!$orderNumber) {
$orderNumber = UtilsModel::getOrderNumberById($idOrder);
}
if(array_key_exists('mail', $info)) {
$mail = $info['mail'];
} else {
if($userType === USER_TYPES['CUSTOMER']) {
$brokerMails = (array) UtilsModel::getBrokersMail();
$supplierMail = (array) self::getSupplierMail($idCompanySelection);
$mail = array_merge($brokerMails, $supplierMail);
} else {
$mail = self::getCustomerMail($idOrder);
}
}
if($acceptedDate && $proposedDate) {
$acceptedDate = new DateTime($acceptedDate);
$acceptedDate = $acceptedDate->format('jS M, Y');
$proposedDate = new DateTime($proposedDate);
$proposedDate = $proposedDate->format('jS M, Y');
}
$params = [
'wiaas' => $userType === USER_TYPES['CUSTOMER'] ? WIAAS_URL.'/api-wiaas' : WIAAS_URL,
'ordersUrl' => $userType === USER_TYPES['CUSTOMER'] ? WIAAS_URL.'/api-wiaas/orders?subModule=orders_steps&idOrder='.$idOrder.'&orderNumber='.$orderNumber : WIAAS_URL.'/orders/'.$idOrder,
'orderNumber' => $orderNumber,
'acceptedDate' => $acceptedDate,
'proposedDate' => $proposedDate,
'actionDoneBy' => $actionDoneBy
];
$response = Mail::sendMail($mail, $mailTitle, $templateUrl, $params);
if($response){
$message = [
'code' => 'success',
'message' => 'MAIL_SENT'
];
} else {
$message = [
'code' => 'error',
'message' => 'ERROR_MAIL_SENT'
];
}
return $message;
}
/**
* return the mail of the supplier of the installation company
* @param Int $idCompanySelection the id of the company selection (install company-order-package)
* @return Array the email of the supplier for th installation company per order package
*/
public function getSupplierMail($idCompanySelection) {
global $database;
$sql = "
SELECT
u.mail
FROM
".TABLES['users']." u
INNER JOIN ".TABLES['suppliers']." s
ON s.idUser = u.id
INNER JOIN ".TABLES['suppliers_countries_products']." scp
ON scp.idSupplier = s.id
INNER JOIN ".TABLES['installation_company_selections']." ics
ON ics.idProduct = scp.idProduct
AND ics.id = $idCompanySelection";
$mail = $database->fetchResultArray($sql);
return count($mail) ? $mail[0]['mail'] : '';
}
/**
* returns the customer mail for the order selected
* @param Int $idOrder id of the order
* @return Array
*/
public function getCustomerMail($idOrder) {
global $database;
$sql = "
SELECT
u.mail
FROM
".TABLES['users']." u
INNER JOIN ".TABLES['customers']." c
ON c.idUser = u.id
INNER JOIN ".TABLES['rel_commercial_lead_customers']." rclc
ON rclc.idCustomer = c.id
INNER JOIN ".TABLES['orders']." o
ON o.idCustomerInstance = rclc.id
AND o.id = $idOrder";
$mail = $database->fetchResultArray($sql);
return count($mail) ? $mail[0]['mail'] : '';
}
}