1, 'ID_OPTION_TYPE' => 2, 'ID_ADDITONAL_TYPE' => 3 ]; const DOCUMENT_TYPES = [ 'ID_TEMPLATE_QUESIONNAIRE' => 1, 'ID_CUSTOMER_QUESTIONNAIRE' => 2, 'ID_TEMPLATE_AGREEMENT' => 6, 'ID_CUSTOMER_AGREEMENT' => 7 ]; const PRODUCT_CATEGORIES = [ 'ITEMS' => 1, 'INSTALLATION' => 2 ]; /** * get count of items in the cart * @return Object number of items in the cart */ public function getCartCount(){ global $database, $user; $sql = "SELECT COUNT(idPackage) as cartItemsCount FROM ".TABLES['web_shop_cart']." WHERE idUser=".$user->getUserId(); $data = $database->fetchResultArray($sql); return !empty($data) ? $data[0] : []; } /** * get items in cart * @return array list of items in the cart */ public function getCartItems(){ global $database, $user; $data = [ 'cartItems' => [] ]; $options = $this->getCartItemOptions(); $additionalPackages = $this->getCartAdditionalPackages(); $countries = new Countries(); $packages = new Packages(); $orderTypeInst = new OrderType(); $interestRate = new InterestRate(); $bidsHandler = new Bids(); $bids = $bidsHandler->getCartBids(); $sql = "SELECT cart.id as idCart, cart.idPackage, cart.idCustomerInstance, cart.idPrice, cart.packageInstance, cart.idBid as idSelectedBid, p.status, rclc.isLinkEnabled, p.name as packageName, cl.id AS idCommercialLead, cl.name as commercialLead, pt.payType, pt.periodUnit AS periodUnit, pt.id AS idPayType, cart.quantity FROM ".TABLES['web_shop_cart']." cart INNER JOIN ".TABLES['packages']." p ON p.id=cart.idPackage INNER JOIN ".TABLES['rel_commercial_lead_customers']." rclc ON rclc.id=cart.idCustomerInstance INNER JOIN ".TABLES['commercial_leads']." cl ON cl.id=rclc.idCommercialLead INNER JOIN ".TABLES['price_list_commercial_lead']." plcl ON plcl.id=cart.idPrice INNER JOIN ".TABLES['payment_types']." pt ON pt.id=plcl.idPaymentType INNER JOIN ".TABLES['price_list_broker']." plb ON plb.idPackage=plcl.idPackage AND plb.idPaymentType=plcl.idPaymentType WHERE cart.idUser=".$user->getUserId(); $query = $database->query($sql); while($row = $database->fetchArray($query)){ $prices = $packages->getPricesForPackages($row['idCommercialLead'], $row['idPackage'], self::PACKAGE_TYPES['ID_STANDARD_TYPE'], $row['idPayType']); if(count($prices[$row['idPackage']]) === 1){ $price = $prices[$row['idPackage']][0]; $row['fixedPrice'] = $price['fixedExtra']; $row['recurentPrice'] = $price['recurentExtra']; $row['servicesPrice'] = $price['servicesExtra']; $row['options'] = isset($options[$row['idCart']]) ? $options[$row['idCart']]['options'] : []; $row['areOptionsAvailable'] = isset($options[$row['idCart']]) ? $options[$row['idCart']]['areOptionsAvailable'] : true; $row['additionalPackages'] = isset($additionalPackages[$row['idCart']]) ? $additionalPackages[$row['idCart']]['additionalPackages'] : []; $row['areAdditionalAvailable'] = isset($additionalPackages[$row['idCart']]) ? $additionalPackages[$row['idCart']]['areAdditionalAvailable'] : true; $row['country'] = $countries->getCurrencyForPackage($row['idPackage']); $row['bids'] = isset($bids[$row['idPackage']]) ? $bids[$row['idPackage']] : []; $totalPackagePrice = $this->calculatePackageTotalPrice($row); $row['totalPrices'] = $totalPackagePrice; $data['cartItems'][] = $row; } } $data['totalPrice'] = $this->getCartTotalPrice($data['cartItems']); return $data; } /** * get options for items in the cart * @return Array list of options grouped by cart id */ private function getCartItemOptions(){ global $database, $user; $data = []; $packages = new Packages(); $sql = "SELECT wscep.idCart, p.name AS packageName, pog.name AS groupName, rgo.idOptionPackage, wsc.idPackage AS idParentPackage, rclc.idCommercialLead AS idCommercialLead, plcl.idPaymentType AS idPaymentType FROM ".TABLES['web_shop_cart_extra_packages']." wscep INNER JOIN ".TABLES['packages']." p ON p.id=wscep.idExtraPackage INNER JOIN ".TABLES['web_shop_cart']." wsc ON wsc.id=wscep.idCart INNER JOIN ".TABLES['rel_commercial_lead_customers']." rclc ON rclc.id=wsc.idCustomerInstance INNER JOIN ".TABLES['price_list_commercial_lead']." plcl ON wsc.idPrice = plcl.id INNER JOIN ".TABLES['rel_group_options']." rgo ON rgo.idOptionPackage=wscep.idExtraPackage INNER JOIN ".TABLES['package_option_groups']." pog ON pog.id=rgo.idGroup AND pog.idPackage=wsc.idPackage WHERE wsc.idUser=".$user->getUserId(); $query = $database->query($sql); while($row = $database->fetchArray($query)){ $packageOptionPrices = $packages->getPricesForPackages($row['idCommercialLead'], $row['idParentPackage'], self::PACKAGE_TYPES['ID_OPTION_TYPE']); $allPrices = isset($packageOptionPrices[$row['idOptionPackage']]) ? $packageOptionPrices[$row['idOptionPackage']] : []; $isPaymentTypePresent = array_search($row['idPaymentType'], array_column($allPrices, 'idPaymentType')); $priceByPaymentTypeKey = $isPaymentTypePresent !== false ? $isPaymentTypePresent : -1; $row['prices'] = $priceByPaymentTypeKey > -1 ? $allPrices[$priceByPaymentTypeKey] : []; $row['isAvailable'] = count($row['prices']) > 0; $data[$row['idCart']]['options'][] = $row; if(!isset($data[$row['idCart']]['areOptionsAvailable'])){ $data[$row['idCart']]['areOptionsAvailable'] = true; } $data[$row['idCart']]['areOptionsAvailable'] = ($data[$row['idCart']]['areOptionsAvailable'] && $row['isAvailable']); } return $data; } /** * returns the additional packages from the cart * @return [type] [description] */ private function getCartAdditionalPackages(){ global $database, $user; $packages = new Packages(); $data = []; $sql = "SELECT wscep.idCart, p.name AS packageName, wsc.idPackage AS idParentPackage, rclc.idCommercialLead AS idCommercialLead, plcl.idPaymentType AS idPaymentType, rap.idAdditionalPackage AS idAdditionalPackage FROM ".TABLES['web_shop_cart_extra_packages']." wscep INNER JOIN ".TABLES['packages']." p ON p.id=wscep.idExtraPackage INNER JOIN ".TABLES['web_shop_cart']." wsc ON wsc.id=wscep.idCart INNER JOIN ".TABLES['rel_commercial_lead_customers']." rclc ON rclc.id=wsc.idCustomerInstance INNER JOIN ".TABLES['price_list_commercial_lead']." plcl ON wsc.idPrice = plcl.id INNER JOIN ".TABLES['rel_additional_packages']." rap ON p.id=rap.idAdditionalPackage AND rap.idPackage=wsc.idPackage WHERE wsc.idUser=".$user->getUserId()." AND p.idPackageType=".self::PACKAGE_TYPES['ID_ADDITONAL_TYPE']; $query = $database->query($sql); while($row = $database->fetchArray($query)){ $additionalPackagesPrices = $packages->getPricesForPackages($row['idCommercialLead'], $row['idParentPackage'], self::PACKAGE_TYPES['ID_ADDITONAL_TYPE']); $allPrices = isset($additionalPackagesPrices[$row['idAdditionalPackage']]) ? $additionalPackagesPrices[$row['idAdditionalPackage']] : []; $isPaymentTypePresent = array_search($row['idPaymentType'], array_column($allPrices, 'idPaymentType')); $priceByPaymentTypeKey = $isPaymentTypePresent !== false ? $isPaymentTypePresent : -1; $row['prices'] = $priceByPaymentTypeKey > -1 ? $allPrices[$priceByPaymentTypeKey] : []; $row['isAvailable'] = count($row['prices']) > 0; $data[$row['idCart']]['additionalPackages'][] = $row; if(!isset($data[$row['idCart']]['areAdditionalAvailable'])){ $data[$row['idCart']]['areAdditionalAvailable'] = true; } $data[$row['idCart']]['areAdditionalAvailable'] = ($data[$row['idCart']]['areAdditionalAvailable'] && $row['isAvailable']); } return $data; } /** * calculates and returns the total price for the order * @param Array $cartItems all teh items in the cart with the details * @return String total and recurrent price with it's currency */ private function getCartTotalPrice($cartItems) { $totalPrice = 0; $totalRecurrentPrice = 0; $currency = ''; $periodUnit = ''; foreach($cartItems as $item) { $itemTotalPrice = $item['fixedPrice']; $itemTotalRecurrentPrice = $item['recurentPrice'] + $item['servicesPrice']; if(count($item['options'])) { foreach($item['options'] as $packageOption) { if(count($packageOption['prices'])) { $itemTotalPrice += (float) $packageOption['prices']['fixedExtra']; $itemTotalRecurrentPrice += (float) $packageOption['prices']['recurentExtra'] + (float) $packageOption['prices']['servicesExtra']; } } } if(count($item['additionalPackages'])) { foreach($item['additionalPackages'] as $additionalPackage) { if(count($additionalPackage['prices'])) { $itemTotalPrice += (float) $additionalPackage['prices']['fixedExtra']; $itemTotalRecurrentPrice += (float) $additionalPackage['prices']['recurentExtra'] + (float) $additionalPackage['prices']['servicesExtra']; } } } $itemTotalPrice *= $item['quantity']; $itemTotalRecurrentPrice *= $item['quantity']; $totalPrice += $itemTotalPrice; $totalRecurrentPrice += $itemTotalRecurrentPrice; $currency = $item['country']['currency']; $periodUnit = $item['periodUnit']; } return $totalPrice . ' ' . $currency . ' ( '. $totalRecurrentPrice . ' ' . $currency . ' / ' . $periodUnit .' )'; } /** * update the quantity in the cart for an item * @param INT $idPackage id for the package * @param INT $idCustomerInstance id for the customer instance based on linking to cl * @param INT $idPrice id for the price * @param INT $quantity quantity value * @return array update message */ public function updateQuantity($idPackage, $idCustomerInstance, $idPrice, $quantity){ global $database, $user; $data = []; $idPackage = $database->escapeValue($idPackage); $idPrice = $database->escapeValue($idPrice); $idCustomerInstance = $database->escapeValue($idCustomerInstance); $quantity = $database->escapeValue($quantity); if($database->invalidNumber('QUANTITY', $quantity, 1, 100)){ $err_mes = [ 'code' => 'error', 'message' => 'INVALID_QUANTITY' ]; $data['messages'][] = $err_mes; return $data; } $sqlUpd = "UPDATE ".TABLES['web_shop_cart']." SET quantity=$quantity WHERE idPackage=$idPackage AND idPrice=$idPrice AND idCustomerInstance=$idCustomerInstance AND idUser=".$user->getUserId()." "; $query = $database->query($sqlUpd); if($database->affectedRows() !== 1){ $err_mes = [ 'code' => 'warning', 'message' => 'NO_CHANGE' ]; $data['messages'][] = $err_mes; return $data; } $mes = [ 'code' => 'success', 'message' => 'QUANTITY_UPDATED' ]; $data['messages'][] = $mes; return $data; } /** * remove item from cart * @param INT $idCart id for the cart * @return array update message */ public function removeFromCart($idCart){ global $database, $user; $data = []; $idCart = $database->escapeValue($idCart); $sql = "DELETE FROM ".TABLES['web_shop_cart_extra_packages']." WHERE idCart=$idCart "; $query = $database->query($sql); $sql = "DELETE FROM ".TABLES['web_shop_cart']." WHERE id=$idCart AND idUser=".$user->getUserId(); $query = $database->query($sql); if($database->affectedRows() !== 1){ $err_mes = [ 'code' => 'error', 'message' => 'INVALID_PACKAGE_FOR_REMOVE' ]; $data['messages'][] = $err_mes; }else{ $message = [ 'code' => 'success', 'message' => 'PACKAGE_REMOVED_FROM_CART' ]; $data['messages'][] = $message; } return $data; } /** * upload questionaires for placing an order * @param Array $file uploaded file * @param String $idDocumentType type of the document * @param String $documentName the name to be set for the file in database * @param INT $idPackage id for the package * @return Array upload message */ public function uploadOrderDocument($file, $idDocumentType, $idPackage){ global $database, $user; $isReUpload = false; $fileManager = new FileManager(); $documentField = ''; if(intval($idDocumentType) === self::DOCUMENT_TYPES['ID_CUSTOMER_QUESTIONNAIRE']){ $documentField = 'idDocument'; $documentName = 'customerQuestionaire_'; }else{ $documentField = 'idAgreementDocument'; $documentName = 'customerAgreement_'; } $documentName .= $idPackage.'_'.date('Y_m_d'); $sql = "SELECT $documentField AS idDocument FROM ".TABLES['web_shop_cart']." WHERE idUser=".$user->getUserId()." AND idPackage=$idPackage AND $documentField IS NOT NULL"; $documents = $database->fetchResultArray($sql); if(count($documents) > 0){ $document = $documents[0]; $data = $fileManager->updateDocument($document['idDocument'], $file); $isReUpload = true; }else{ $uploadedBy = $user->getUserId(); $data = $fileManager->uploadFile($file, $idDocumentType, $documentName, $uploadedBy); $isReUpload = false; } if(isset($data['messages'])){ return $data; } if(!$isReUpload){ $idDocument = $data['idDocument']; $sql = "UPDATE ".TABLES['web_shop_cart']." SET $documentField=$idDocument WHERE idUser=".$user->getUserId()." AND idPackage=$idPackage"; $query = $database->query($sql); if($database->affectedRows() > 0){ $data['messages'][] = [ 'code' => 'success', 'message' => 'FILE_UPLOADED' ]; }else{ $data['messages'][] = [ 'code' => 'error', 'message' => 'NOT_LINKED_TO_CART' ]; } }else{ $data['messages'][] = [ 'code' => 'success', 'message' => 'FILE_UPLOADED' ]; } return $data; } /** * get files that have been uploaded before palcing an order and are found in the cart * @param INT $packages id of the package * @return Array array of uploaded documetns for a package */ private function getUploadedFilesForOrder($packages){ global $database, $user; $data = []; $sql = "SELECT doc.id as idDocument, doc.documentName, doc.extension, doc.idDocumentType, wsc.idPackage FROM ".TABLES['documents']." doc INNER JOIN ".TABLES['web_shop_cart']." wsc ON (doc.id=wsc.idDocument OR doc.id=wsc.idAgreementDocument) AND wsc.idUser=doc.uploadedBy WHERE wsc.idPackage IN($packages) AND wsc.idUser=".$user->getUserId().""; $query = $database->query($sql); while($row = $database->fetchArray($query)){ $data[$row['idDocumentType']][$row['idPackage']] = $row; } return $data; } /** * get required template documents to place an order * @param Array $packages ids for the packages in the cart * @return Array array of documents */ private function getTempalteDocuments($packages){ global $database; $data = []; $sql = "SELECT d.id as idDocument, d.documentName, d.documentPath, d.extension, p.id AS idPackage, p.name AS packageName, d.idDocumentType FROM ".TABLES['documents']." d INNER JOIN ".TABLES['rel_package_documents']." rpd ON rpd.idDocument=d.id INNER JOIN ".TABLES['packages']." p ON p.id=rpd.idPackage WHERE rpd.idPackage IN($packages) AND d.idDocumentType IN(".self::DOCUMENT_TYPES['ID_TEMPLATE_QUESIONNAIRE'].", ".self::DOCUMENT_TYPES['ID_TEMPLATE_AGREEMENT'].")"; $query = $database->query($sql); while($row = $database->fetchArray($query)){ $data[$row['idDocumentType']][$row['idPackage']] = $row; $idCustomerDocType = $row['idDocumentType'] == self::DOCUMENT_TYPES['ID_TEMPLATE_QUESIONNAIRE'] ? self::DOCUMENT_TYPES['ID_CUSTOMER_QUESTIONNAIRE'] : self::DOCUMENT_TYPES['ID_CUSTOMER_AGREEMENT']; $data['docsPackage'][$idCustomerDocType][$row['idPackage']] = $row; } return $data; } /** * get required documents to place an order * @param Array $packages ids for the packages in the cart * @return Array array of documents */ public function getCartDocuments($packages){ global $database; $data = []; $areFilesUploaded = true; $uploaded = []; $templates = []; $packages = implode(',', $packages); $packages = $database->escapeValue($packages); if($packages) { $uploaded = $this->getUploadedFilesForOrder($packages); $templates = $this->getTempalteDocuments($packages); } if(array_key_exists('docsPackage', $templates)) { foreach($templates['docsPackage'] as $idDocType => $templateDoc) { foreach ($templateDoc as $idPackage => $packageDocDetails) { if(!isset($uploaded[$idDocType]) || !isset($uploaded[$idDocType][$idPackage])){ $areFilesUploaded = false; break; } } } unset($templates['docsPackage']); } return ['templates' => $templates, 'uploaded' => $uploaded, 'areFilesUploaded' => $areFilesUploaded]; } /** * get details of the customer logged in * @return Array with neccessary details */ public function getCustomerDetails() { global $database, $user; $userId = $user->getUserId(); $data = []; $addresHelper = new AddressHelper(); $sqlVatCode = " SELECT c.vatCode, c.name AS companyName FROM ".TABLES['company']." c INNER JOIN ".TABLES['users']." u ON u.idCompany=c.id WHERE u.id = ".$userId." LIMIT 1"; $result = $database->fetchResultArray($sqlVatCode); $data['vat'] = $result ? $result[0]['vatCode'] : ''; $data['companyName'] = $result ? $result[0]['companyName'] : ''; $data['deliveryAddresses'] = $addresHelper->getDeliveryAddress(); $data['billing'] = $addresHelper->getBillingAddress(); if($result = $this->getReferenceAndTender()) { $data['details'] = $result[0]; } return ['customerDetails' => $data]; } /** * returns the reference and tender if exists * @return Array reference and tender for the order */ private function getReferenceAndTender() { global $database, $user; $sqlDetails = " SELECT reference, tender, idDeliveryAddress, idBillingAddress, idProject FROM ".TABLES['web_shop_cart']." wsc WHERE wsc.idUser = ".$user->getUserId(); return $database->fetchResultArray($sqlDetails); } /** * gets the country name for the id provided * @param Array $data all details * @param String $addressType delivery or billing address * @return String name of the country */ private function getCountryName($data, $addressType) { if(array_key_exists($addressType, $data)) { return $this->getCountryDetailsById($data[$addressType]['idCountrySelected'])[0]['countryName']; } return ''; } /** * returns the name and code of the country by it's id * @param int $idCountry id of the country * @return string the name of the country */ public function getCountryDetailsById($idCountry) { global $database; $countryName = ''; $sql = " SELECT name AS countryName, UPPER(code) AS countryCode FROM ".TABLES['countries']." WHERE id=$idCountry LIMIT 1"; return $database->fetchResultArray($sql); } /** * get all the countries * @return Array country names and ids */ public function getCountries() { global $database; $sql = "SELECT c.id, c.name FROM ".TABLES['countries']." c"; return ['countries' => $database->fetchResultArray($sql)]; } /** * checks whether the informations for the order are correct * @param Array $cartPackages the packages to be placed in the order * @param Array $deliveryInfo the delivery information for the order * @param Array $billingInfo the billing information for the order * @return Array error message ot empty */ private function validateOrderDetails($cartPackages, $deliveryInfo, $billingInfo, $details) { global $database; if(count($cartPackages) < 1) { return [ 'code' => 'error', 'message' => 'CART_EMPTY' ]; } if(empty($deliveryInfo)){ return [ 'code' => 'error', 'message' => 'NO_DELIVERY_ADDRESS' ]; } if(empty($billingInfo)){ return [ 'code' => 'error', 'message' => 'NO_BILLING_ADDRESS' ]; } return []; } /** * adds or updates the delivery address for the user logged in * @param Array $deliveryInfo contaions the delivery address * @return Int affected rows */ private function addUpdateOrderDeliveryAddress($deliveryInfo) { global $database, $user; foreach($deliveryInfo as $deliveryIndex => $detail) { $deliveryInfo[$deliveryIndex] = $database->escapeValue($detail); } $sql = " SELECT id FROM ".TABLES['delivery_addresses']." WHERE idUser = ".$user->getUserId()." AND idCountry = ".$deliveryInfo['idCountrySelected']." AND city = '".$deliveryInfo['city']."' AND detailedAddress = '".$deliveryInfo['detailedAddress']."' AND zip = '".$deliveryInfo['zipCode']."' "; $query = $database->query($sql); if($database->numRows($query) === 0) { $sqlDeliveryAddress = " INSERT INTO ".TABLES['delivery_addresses']." (idUser, idCountry, city, detailedAddress, zip) VALUES ( ".$user->getUserId().", ".$deliveryInfo['idCountrySelected'].", '".$deliveryInfo['city']."', '".$deliveryInfo['detailedAddress']."', '".$deliveryInfo['zipCode']."' ) "; $query = $database->query($sqlDeliveryAddress); return $database->affectedRows(); } return 0; } /** * adds or updates the billing information for the user * @param Array $billingInfo array of billing info - names and address * @return Int affected rows */ private function addUpdateOrderBillingAddress($billingInfo) { global $database, $user; foreach($billingInfo as $billingIndex => $detail) { $billingInfo[$billingIndex] = $database->escapeValue($detail); } $sql = " SELECT id FROM ".TABLES['billing_information']." WHERE idUser = ".$user->getUserId()." AND idCountry = ".$billingInfo['idCountrySelected']." AND company = '".$billingInfo['companyName']."' AND firstName = '".$billingInfo['firstName']."' AND lastname = '".$billingInfo['lastName']."' AND city = '".$billingInfo['city']."' AND detailedAddress = '".$billingInfo['detailedAddress']."' AND zip = '".$billingInfo['zipCode']."' "; $query = $database->query($sql); if($database->numRows($query) === 0) { $sqlBillingAddress = " INSERT INTO ".TABLES['billing_information']." (idUser, idCountry, company, firstName, lastName, city, detailedAddress, zip) VALUES ( ".$user->getUserId().", ".$billingInfo['idCountrySelected'].", '".$billingInfo['companyName']."', '".$billingInfo['firstName']."', '".$billingInfo['lastName']."', '".$billingInfo['city']."', '".$billingInfo['detailedAddress']."', '".$billingInfo['zipCode']."' ) "; $query = $database->query($sqlBillingAddress); return $database->affectedRows(); } return 0; } /** * returns the name and code of the country by it's id * @param array $details details of the order * @param array $items items from the cart * @return array update messages */ public function saveOrderDetails($details, $items) { global $database; $addressInserted = 0; $deliveryInfo = $details['delivery']; $billingInfo = $details['billing']; $orderDetails = $details['details']; $orderDetails['idDeliveryAddress'] = isset($deliveryInfo['id']) ? $deliveryInfo['id'] : 'null'; $orderDetails['idBillingAddress'] = isset($billingInfo['id']) ? $billingInfo['id'] : 'null'; if($data['messages'][] = $this->validateOrderDetails($items, $deliveryInfo, $billingInfo, $orderDetails)) { return $data; } if($this->updateCartInfo($orderDetails) > 0) { $addressInserted++; } if($addressInserted) { $data['messages'][] = [ 'code' => 'success', 'message' => 'ADDRESS_INSERTED' ]; } else { $data['messages'][] = [ 'code' => 'warning', 'message' => 'NO_ADDRESS_CHANGES' ]; } return $data; } /** * updates the reference and tender for the order to be placed * @param Array $details reference and tender * @return Int number of rows affected */ private function updateCartInfo($details) { global $database, $user; foreach($details as $key => $detail) { $details[$key] = $database->escapeValue($detail); } $idProject = isset($details['idProject']) && $details['idProject'] ? $details['idProject'] : 'NULL'; $sql = " UPDATE ".TABLES['web_shop_cart']." SET reference = '".$details['reference']."', tender = '".$details['tender']."', idDeliveryAddress = '".$details['idDeliveryAddress']."', idBillingAddress = '".$details['idBillingAddress']."', idProject = $idProject WHERE idUser = ".$user->getUserId(); $query = $database->query($sql); return $database->affectedRows(); } /** * calculate the packages total price * @param Array $cartPackage the details for the package in the cart * @return float the total price per package */ private function calculatePackageTotalPrice($cartPackage){ $totalPrice = [ 'fixedPrice' => 0, 'recurrentPrice' => 0, 'servicesPrice' => 0 ]; if(!empty($cartPackage['bids']) && $cartPackage['idSelectedBid']){ $selectedBid = null; foreach ($cartPackage['bids'] as $bid) { if($bid['idBid'] === $cartPackage['idSelectedBid']){ $selectedBid = $bid; break; } } $totalPrice['fixedPrice'] += $selectedBid ? $selectedBid['fixedPrice'] : $cartPackage['fixedPrice']; $totalPrice['recurrentPrice'] += $selectedBid ? $selectedBid['recurrentPrice'] : $cartPackage['recurentPrice']; $totalPrice['servicesPrice'] += $selectedBid ? $selectedBid['servicesPrice'] : $cartPackage['servicesPrice']; }else{ $totalPrice['fixedPrice'] += $cartPackage['fixedPrice']; $totalPrice['recurrentPrice'] += $cartPackage['recurentPrice']; $totalPrice['servicesPrice'] += $cartPackage['servicesPrice']; } if(isset($cartPackage['options'])){ foreach ($cartPackage['options'] as $option) { if(count($option) && array_key_exists('prices', $option) && count($option['prices'])) { $totalPrice['fixedPrice'] += $option['prices']['fixedExtra']; $totalPrice['recurrentPrice'] += $option['prices']['recurentExtra']; $totalPrice['servicesPrice'] += $option['prices']['servicesExtra']; } } } if(isset($cartPackage['additionalPackages'])){ foreach ($cartPackage['additionalPackages'] as $additionalPackage) { if(count($additionalPackage) && array_key_exists('prices', $additionalPackage) && count($additionalPackage['prices'])) { $totalPrice['fixedPrice'] += $additionalPackage['prices']['fixedExtra']; $totalPrice['recurrentPrice'] += $additionalPackage['prices']['recurentExtra']; $totalPrice['servicesPrice'] += $additionalPackage['prices']['servicesExtra']; } } } return $totalPrice; } /** * genereate the order number using the id * @param INT $idOrder id of the order * @return INT order number containg the id value */ private function generateOrderNumber($idOrder){ return 1000000000 + $idOrder; } /** * adds the relation between order and packages * @param Array $orderPackages all the details for packages in order * @param Int $idOrder the order id inserted * @return Int the number of packages inserted */ private function addOrderPackageRelation($orderPackages, $idOrder) { global $database; $insertValues = ''; $sql = " INSERT INTO ".TABLES['rel_order_packages']." (idOrder, idPackage, packageInstance, idPaymentTerm, units, packageFixedPrice, packageRecuringPrice, packageServicePrice, idBid) VALUES "; foreach($orderPackages as $packageInfo) { $totalPackagePrice = $this->calculatePackageTotalPrice($packageInfo); $isPriceInRange = $this->checkIfPriceInRange($totalPackagePrice); if($isPriceInRange) { return $isPriceInRange; } $packageInfo['idSelectedBid'] = $packageInfo['idSelectedBid'] ? $packageInfo['idSelectedBid'] : 'NULL'; $sqlPaymentType = " SELECT id FROM ".TABLES['payment_types']." pt WHERE pt.payType='".$packageInfo['payType']."'"; $result = $database->fetchResultArray($sqlPaymentType); $idPayType = $result && $result[0]['id'] ? $result[0]['id'] : 0; $insertValues .= "( $idOrder, '".$packageInfo['idPackage']."', '".$packageInfo['packageInstance']."', ".$packageInfo['idPayType'].", '".$packageInfo['quantity']."', '".$totalPackagePrice['fixedPrice']."', '".$totalPackagePrice['recurrentPrice']."', '".$totalPackagePrice['servicesPrice']."', ".$packageInfo['idSelectedBid']." ),"; } $insertValues = $insertValues ? rtrim($insertValues, ',') : ''; if($insertValues) { $sql .= $insertValues; $query = $database->query($sql); return $database->affectedRows(); } return 0; } /** * add order documents to relation table * @param Int $idOrder id of the order * @param Int $idCustomerInstance id customer instance * @return Int affected rows or 1 */ private function addOrderDocuments($idOrder, $idCustomerInstance){ global $database, $user; $getDocSql = "SELECT wsc.idDocument, wsc.idAgreementDocument, wsc.idPackage FROM ".TABLES['web_shop_cart']." wsc WHERE idCustomerInstance=$idCustomerInstance"; $query = $database->query($getDocSql); $vals = ""; while($row = $database->fetchArray($query)){ if($row['idDocument']){ $vals .= "(" . $idOrder . ", " . $row['idPackage'] . ", " . $row['idDocument'] . "),"; } if($row['idAgreementDocument']){ $vals .= "(" . $idOrder . ", " . $row['idPackage'] . ", " . $row['idAgreementDocument'] . "),"; } } ; if($vals){ $vals = rtrim($vals, ','); $sql = "INSERT INTO ".TABLES['rel_order_documents']." (idOrder, idPackage, idDocument) VALUES $vals"; $query = $database->query($sql); return $database->affectedRows(); } return 1; } /** * add extra option for order packages * @param INT $idOrder id for the ORDER * @return INT number of inserted elements */ private function addOrderExtraPackages($idOrder){ global $database, $user; $sql = "INSERT INTO ".TABLES['rel_order_extra_packages']." (idOrder, idPackage, idExtraPackage) SELECT $idOrder, wsc.idPackage, wscep.idExtraPackage FROM ".TABLES['web_shop_cart']." wsc INNER JOIN ".TABLES['web_shop_cart_extra_packages']." wscep ON wsc.id=wscep.idCart WHERE wsc.idUser=".$user->getUserId(); $query = $database->query($sql); return $database->affectedRows(); } /** * remove the packages from the web shop cart after placing the order * @param Int $idCustomerInstance id of the customer * @return Int number of rows deleted */ private function removePackagesFromCartAfterOrder($idCustomerInstance) { global $database; $sql = " DELETE FROM ".TABLES['web_shop_cart']." WHERE idCustomerInstance = $idCustomerInstance"; $result = $database->query($sql); return $database->affectedRows(); } /** * adds the installation company in the selection relations table * @param Array $cartPackages the packages from the cart * @param Int $idOrder the id of the order * @return Array with confirmation message */ private function addInstallationCompanySelection($cartPackages, $idOrder) { global $database; $message = []; foreach($cartPackages as $position => $package) { $sql = " SELECT rpp.idProduct FROM ".TABLES['rel_package_products']." rpp INNER JOIN ".TABLES['suppliers_countries_products']." scp ON scp.idProduct = rpp.idProduct INNER JOIN ".TABLES['product_categories']." pc ON scp.idProductCategory = pc.id WHERE pc.id = ".self::PRODUCT_CATEGORIES['INSTALLATION']." AND rpp.idPackage = ".$package['idPackage']." AND rpp.packageInstance = ".$package['packageInstance']; $products = $database->fetchResultArray($sql); if(count($products) === 1) { $installationScheduling = new InstallationScheduling(); $message = $installationScheduling->changeInstallationCompany($idOrder, $package['idPackage'], $products[0]['idProduct']); } } return $message; } /** * adds the order with the whole details * @param String $cartPackages Json string with object containing the packages to order * @param String $details Json string with object containing the details like refenrence or tender numbers * @return Array confirmation message */ public function placeOrder($cartItems, $orderDetails) { global $database, $user; $rowsAffected = 0; $deletedFromCart = 0; $totalFixedPrice = 0; $totalServicePrice = 0; $userId = $user->getUserId(); $newCartPackages = []; $packageToDisplay = ''; $unavailablePackageKey = ''; $idPackages = ''; $orderTypeInst = new OrderType(); $clCustomersInst = new ClCustomers(); $cartPackages = $cartItems; $deliveryInfo = $orderDetails['delivery']; $billingInfo = $orderDetails['billing']; $details = $orderDetails['details']; $options = $this->getCartItemOptions(); $additionalPackages = $this->getCartAdditionalPackages(); foreach($cartPackages as $packKey => $packageDetails) { $packageDetails = (array) $packageDetails; $areOptionsAvailable[$packageDetails['packageName']] = isset($options[$packageDetails['idCart']]) ? $options[$packageDetails['idCart']]['areOptionsAvailable'] : true; $areAdditionalAvailable[$packageDetails['packageName']] = isset($additionalPackages[$packageDetails['idCart']]) ? $additionalPackages[$packageDetails['idCart']]['areAdditionalAvailable'] : true; $packageNames[] = $packageDetails['packageName']; foreach($packageDetails as $packDetailKey => $packageDetail) { if(!is_array($packageDetail)){ $newCartPackages[$packKey][$packDetailKey] = $database->escapeValue($packageDetail); }else{ $newCartPackages[$packKey][$packDetailKey] = $packageDetail; } } $commercialLeadName = $packageDetails['commercialLead']; $idCommercialLead = $packageDetails['idCommercialLead']; $idPackages .= $packageDetails['idPackage'].','; } $unavailablePackageKey = $this->getNameIfPackageUnavailable($idPackages); $optionPackageKey = array_keys($areOptionsAvailable, false); if(count($optionPackageKey)) { $unavailablePackageKey = $optionPackageKey[0]; } else { $additionalPackageKey = array_keys($areAdditionalAvailable, false); if(count($additionalPackageKey)) { $unavailablePackageKey = $additionalPackageKey[0]; } } if($unavailablePackageKey) { $data['messages'][] = [ 'code' => 'error', 'message' => 'UNAVAILABLE_PACKAGE_IN_CART', 'key' => $unavailablePackageKey ]; return $data; } $cartPackages = $newCartPackages; foreach ($cartPackages as $position => $cartPackage) { $optionsToDisplay = ''; if(isset($cartPackage['options'])){ $optionsToDisplay .= '('; foreach ($cartPackage['options'] as $key => $option) { $optionsToDisplay .= $option['groupName'] . ' : ' . $option['packageName'] .','; } $optionsToDisplay = rtrim($optionsToDisplay, ','); $optionsToDisplay .= ')'; } if(isset($cartPackage['additionalPackages'])){ $optionsToDisplay .= '('; foreach ($cartPackage['additionalPackages'] as $key => $option) { $optionsToDisplay .= $option['packageName'] .', '; } $optionsToDisplay = rtrim($optionsToDisplay, ','); $optionsToDisplay .= ')'; } $packageTotalPrices = $this->calculatePackageTotalPrice($cartPackage); $packageToDisplay .= ($position + 1).'. '.$packageNames[$position].' '.$optionsToDisplay.'