]> _ Git - cubeextranet.git/commitdiff
Wait #5345 @4
authorstephen@cubedesigners.com <stephen@cubedesigners.com@f5622870-0f3c-0410-866d-9cb505b7a8ef>
Tue, 12 Jul 2022 16:56:31 +0000 (16:56 +0000)
committerstephen@cubedesigners.com <stephen@cubedesigners.com@f5622870-0f3c-0410-866d-9cb505b7a8ef>
Tue, 12 Jul 2022 16:56:31 +0000 (16:56 +0000)
inc/ws/Controlleur/class.ws.services.php
inc/ws/Util/html5/master/class.ws.html5.compiler.php
inc/ws/Util/html5/master/class.ws.html5.links.php

index 62a2cb1c39e68bf7bec1cce5be3cf99133ce93a6..61dd47867be8f148d75e458ca428c92480064b81 100644 (file)
@@ -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
index 7aa78be1b1e6d8816ab4d6e0a09a653512166c9d..76ce91d970ee5fe4afe201623fa8c948c39c5d65 100644 (file)
@@ -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;
             }
index 2d1af34d6447bbff411022da5cdc170933158dba..b18924d3b77564374401c17abec2cec458c6346e 100644 (file)
@@ -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()