From: stephen@cubedesigners.com Date: Tue, 12 Jul 2022 16:56:31 +0000 (+0000) Subject: Wait #5345 @4 X-Git-Url: http://git.cubedesigners.com/?a=commitdiff_plain;h=db2937be08481770320fee54e13d762948a152ef;p=cubeextranet.git Wait #5345 @4 --- diff --git a/inc/ws/Controlleur/class.ws.services.php b/inc/ws/Controlleur/class.ws.services.php index 62a2cb1c3..61dd47867 100644 --- a/inc/ws/Controlleur/class.ws.services.php +++ b/inc/ws/Controlleur/class.ws.services.php @@ -1594,6 +1594,178 @@ class wsServices extends cubeFlashGateway echo json_encode($result); } + + // Endpoint for the Bastide Fluidbooks (custom cart) + public function bastide() + { + $this->outputXML = false; + + if (empty($_POST['cart_items'])) { + die('Error: invalid data received'); + } + + + // TODO >>> remove this once we have the destination address from the client (see line 1712) + die('Disabled until default delivery address is known. See Redmine ticket #5345'); + + + + $user_details = json_decode($_POST['user_details'], true); + $cart_items = json_decode($_POST['cart_items'], true); + $column_headings = json_decode($_POST['column_headings'], true); + + $excel = new PHPExcel(); + $excel->setActiveSheetIndex(0); + $defaultStyle = $excel->getDefaultStyle(); + $defaultStyle->getAlignment()->setVertical(PHPExcel_Style_Alignment::VERTICAL_CENTER); + $defaultStyle->getAlignment()->setWrapText(true); + $defaultStyle->getNumberFormat()->setFormatCode(PHPExcel_Style_NumberFormat::FORMAT_TEXT); + $sheet = $excel->getActiveSheet(); + $sheet->setTitle('Récapitulatif de commande'); + + // Setup column headings + $current_column_index = 0; + $current_row = 1; + foreach ($column_headings as $column_heading) { + $sheet->setCellValueByColumnAndRow($current_column_index, $current_row, $column_heading); + $cell_style = $sheet->getStyleByColumnAndRow($current_column_index, $current_row); + $cell_style->getFont()->setBold(true); + $cell_style->getBorders()->getBottom()->setBorderStyle(PHPExcel_Style_Border::BORDER_MEDIUM); + $current_column_index++; + } + + // Output cart data + foreach ($cart_items as $cart_item) { + $current_row++; + + // Look up the value by the column keys to ensure the correct order of values + foreach (array_keys($column_headings) as $column_index => $column_key) { + + $current_cell_style = $sheet->getStyleByColumnAndRow($column_index, $current_row); + + switch($column_key) { + case 'ARTICLE CODE': // Explicitly store ARTICLE CODE as text in order to preserve any leading zeros + $sheet->setCellValueExplicitByColumnAndRow($column_index, $current_row, $cart_item[$column_key], PHPExcel_Cell_DataType::TYPE_STRING); + break; + case 'QUANTITY': + $sheet->setCellValueByColumnAndRow($column_index, $current_row, $cart_item[$column_key]); + $current_cell_style->getNumberFormat()->setFormatCode(PHPExcel_Style_NumberFormat::FORMAT_NUMBER); + break; + default: + $sheet->setCellValueByColumnAndRow($column_index, $current_row, $cart_item[$column_key]); + } + + } + } + + // Autosize columns once the data has been added + for ($i = 0; $i < count($column_headings); $i++) { + $sheet->getColumnDimensionByColumn($i)->setAutoSize(true); + } + + //================================ + // Add user details in a new sheet + // The sheet must be added to the workbook before we can access the cell styles, otherwise it fails silently :( + $details_sheet = $excel->addSheet(new PHPExcel_Worksheet($excel, 'Coordonnées'), 0); // Setting index to zero will put this sheet first in the workbook + + $current_row = 1; + foreach ($user_details as $user_detail) { + // User details are displayed as Label: Value in the A & B columns + $details_label_style = $details_sheet->getStyleByColumnAndRow(0, $current_row); + $details_label_style->getFont()->setBold(true); + $details_label_style->getAlignment()->setWrapText(false); + $details_label_style->getAlignment()->setHorizontal(PHPExcel_Style_Alignment::HORIZONTAL_RIGHT); + $details_sheet->setCellValueByColumnAndRow(0, $current_row, $user_detail['label'] . ' :'); + + $details_sheet->setCellValueByColumnAndRow(1, $current_row, $user_detail['value']); + $details_sheet->getRowDimension($current_row)->setRowHeight(-1); // Auto row height from content + $current_row++; + } + + // Auto-size both columns + $details_sheet->getColumnDimensionByColumn(0)->setAutoSize(true); + $details_sheet->getColumnDimensionByColumn(1)->setAutoSize(true); + + //==== Save the Excel spreadsheet to disk temporarily + $writer = PHPExcel_IOFactory::createWriter($excel, 'Excel2007'); // .xlsx format + $xls_file = CubeIT_Files::tempnam(); + $writer->save($xls_file); + + //==== Prepare the e-mail + // The Fluidbook can pass on a parameter that overrides the default recipient + $recipient_code = $_POST['recipient_code'] ?? ''; + + switch(strtolower($recipient_code)) { + case 'guadeloupe': + $email_to = 'contact2@bastide-guadeloupe.com'; + break; + case 'commercial': + $email_to = 'commercial@bastide-guadeloupe.com'; + break; + case 'martinique': + $email_to = 'commercial2@bastide-martinique.com'; + break; + case 'réunion': + $email_to = 'info@bastide.re'; + break; + default: + $email_to = '?????'; #TODO: !!!! INSERT DEFAULT EMAIL !!!! + } + + $email_cc = [ + $user_details['email']['value'], + ]; + $return_address = 'postmaster@fluidbook.com'; + $email_from_name = "Bastide"; + $email_reply_to = $email_to; + $email_subject = 'Récapitulatif de votre commande Bastide'; + $email_body = "Bonjour,\n\nVotre commande est en cours de traitement (récapitulatif en pièce jointe). Nous vous recontacterons dans les meilleurs délais.\n\nCordialement,\n\nL'équipe Bastide"; + + // Send the email + $transport = new CubeIT_Mail_Transport_Mailjet(); + $mail = new CubeIT_Mail_Mailjet(); + $mail->setFrom($return_address, $email_from_name); + $mail->setReplyTo($email_reply_to, $email_from_name); + $mail->setReturnPath($return_address); + $mail->addTo($email_to); + foreach ($email_cc as $cc_recipient) { + $mail->addCc($cc_recipient); + } + $mail->setSubject($email_subject); + $mail->setBodyText($email_body); + + $attachment_filename = 'Bastide-' . date('YmdHis') . '.xlsx'; + + $mail->createAttachment( + file_get_contents($xls_file), + 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', + Zend_Mime::DISPOSITION_ATTACHMENT, + Zend_Mime::ENCODING_BASE64, + $attachment_filename + ); + + try { + print_r($mail->send($transport)); + $result['success'] = true; + } catch (Exception $e){ + error_log('#### Bastide: Failed sending message via Mailjet ####'); + error_log('ERROR: ' . $e->getMessage()); + $result['success'] = false; + } + + unlink($xls_file); // Tidy up temporary file after sending + + if ($result['success']) { + $result['message'] = 'Merci, votre commande a été bien reçue. Nous vous recontacterons dans les meilleurs délais.'; + } else { + $result['message'] = "Désolé, une erreur s'est produite. Veuillez réessayer ou contactez {$email_reply_to}."; + } + + header('Content-type: application/json'); + ob_end_clean(); + echo json_encode($result); + } + public static function searchGFXDevice($gpu, $raw, $gfxVersion = 40) { // First intention direct request diff --git a/inc/ws/Util/html5/master/class.ws.html5.compiler.php b/inc/ws/Util/html5/master/class.ws.html5.compiler.php index 7aa78be1b..76ce91d97 100644 --- a/inc/ws/Util/html5/master/class.ws.html5.compiler.php +++ b/inc/ws/Util/html5/master/class.ws.html5.compiler.php @@ -782,7 +782,7 @@ class wsHTML5Compiler if (file_exists($referencesFile) || CubeIT_Util_Url::isDistant($referencesFile)) { $raw_data = wsUtil::excelToArray($referencesFile); - $first_sheet_rows = reset($raw_data); // First row's data will be returned since it's the first array element + $first_sheet_rows = reset($raw_data); // First sheet's data will be returned since it's the first array element // Expected headings are: EXCLU, LIGNE, EAN, REF, DESIGNATION, COULEUR, QTE MINI, PRIX TTC $column_headings = array_shift($first_sheet_rows); // We assume the first row will be the headings, so we slice it off @@ -824,6 +824,59 @@ class wsHTML5Compiler $this->config->cartEmailSubject = $extra['email_subject'] ?? 'Récapitulatif de votre commande CFOC'; } + public function writeBastideCart() + { + + $this->lessVariables['import-cart-styles'] = 'bastide'; + + $this->addJsLib('bastide', 'js/libs/fluidbook/cart/fluidbook.cart.bastide.js'); + + // NOTE: $this->config->basketReferences initially contains the uploaded filename and if we don't + // modify it, the writeCartConfig() function will replace it with the extracted data from the spreadsheet 🤐 + // It would be much better if the extracted data had its own variable but it would break too many things to + // change it now, so we'll follow the same approach. + + if (!empty($this->config->basketReferences)) { + if (file_exists($this->config->basketReferences) || CubeIT_Util_Url::isDistant($this->config->basketReferences)) { + $referencesFile = $this->config->basketReferences; + } else { + $referencesFile = $this->wdir . 'commerce/' . $this->config->basketReferences; + } + } + + $references = []; + + if (file_exists($referencesFile) || CubeIT_Util_Url::isDistant($referencesFile)) { + $raw_data = wsUtil::excelToArray($referencesFile); + $first_sheet_rows = reset($raw_data); // First sheet's data will be returned since it's the first array element + + // Expected headings are: n° page, Chapitre, Article Code, Article, Conditionnement + $column_headings = array_shift($first_sheet_rows); // We assume the first row will be the headings, so we slice it off + $column_headings = array_map(function ($heading) { // Normalise the headings, removing extra spaces and line breaks + return trim(strtoupper(preg_replace('/\s+/', ' ', $heading))); + }, $column_headings); + + foreach ($first_sheet_rows as $row) { + + // First, trim values in case there are any stray spaces + $row = array_map('trim', $row); + + // Next, set the headings as keys to make it easier to refer to the row values by name + $row = array_combine($column_headings, $row); + + // The ARTICLE CODE is required, so if it doesn't exist, we can assume it's not a valid row + if (empty($row['ARTICLE CODE'])) { + continue; + } + + $references[$row['ARTICLE CODE']] = $row; + } + + } + + $this->config->basketReferences = $references; + } + public function writeCartConfig() { if ($this->book->parametres->cartLinkAppearance == 'overlay') { @@ -860,6 +913,9 @@ class wsHTML5Compiler case 'CFOC': $this->writeCFOCCart(); break; + case 'Bastide': + $this->writeBastideCart(); + break; default: break; } diff --git a/inc/ws/Util/html5/master/class.ws.html5.links.php b/inc/ws/Util/html5/master/class.ws.html5.links.php index 2d1af34d6..b18924d3b 100644 --- a/inc/ws/Util/html5/master/class.ws.html5.links.php +++ b/inc/ws/Util/html5/master/class.ws.html5.links.php @@ -182,6 +182,8 @@ class wsHTML5Link return new zoomProductLink($id, $init, $compiler); } switch ($compiler->book->parametres->basketManager) { + case 'Bastide': + return new BastideCartLink($id, $init, $compiler); case 'CFOC': return new CFOCCartLink($id, $init, $compiler); case 'GrandVision': @@ -1745,6 +1747,19 @@ class cartLink extends normalLink } } +class BastideCartLink extends normalLink +{ + public function getUrl() + { + return '#/cart/add/' . $this->to; + } + + public function getTooltip() + { + return 'Ajouter à ma sélection'; + } +} + class CFOCCartLink extends normalLink { public function getUrl()