From 28cc16580da5f0e2ca5ca1df695394c7014246fb Mon Sep 17 00:00:00 2001
From: Michael Danielczok <michael@pcsg.de>
Date: Tue, 9 Jul 2024 13:20:19 +0200
Subject: [PATCH] feat: show product images in basket setting

Related: brassberg/tickets#244
---
 bin/css/order.css                             |  15 ++
 bin/css/variables.css                         |   5 +
 locale.xml                                    |   9 +
 .../QUI/ERP/Order/Controls/Basket/Basket.html | 242 ++++++++++++++++++
 settings.xml                                  |  17 ++
 src/QUI/TemplateCologne/Utils.php             |  35 +++
 6 files changed, 323 insertions(+)
 create mode 100644 quiqqer/order/src/QUI/ERP/Order/Controls/Basket/Basket.html

diff --git a/bin/css/order.css b/bin/css/order.css
index b4e912f..57c86f0 100644
--- a/bin/css/order.css
+++ b/bin/css/order.css
@@ -69,6 +69,21 @@ th.quiqqer-order-basket-articles-header-price {
     width: 60px;
 }
 
+.quiqqer-order-basket-articles-header-image {
+    width: var(--_qui-order-basket-articles-image-width);
+}
+
+.quiqqer-order-basket-articles-article-image {
+    width: var(--_qui-order-basket-articles-image-width-width);
+    text-align: center;
+}
+
+.quiqqer-order-basket-articles-article-image__img {
+    width: var(--_qui-order-basket-articles-image-width);
+    height: var(--_qui-order-basket-articles-image-height);
+    object-fit: contain;
+}
+
 .quiqqer-order-basket-articles-article-quantity {
     text-align: center;
     width: 100px;
diff --git a/bin/css/variables.css b/bin/css/variables.css
index 9cc5728..a0ba096 100644
--- a/bin/css/variables.css
+++ b/bin/css/variables.css
@@ -16,4 +16,9 @@
     /* background */
     --bg-primary: #ddd;
     --bg-secondary: #f5f5f5;
+
+
+    /* ecoyn / ecommerce */
+    --_qui-order-basket-articles-image-width: var(--qui-order-basket-articles-image-width, 100px);
+    --_qui-order-basket-articles-image-height: var(--qui-order-basket-articles-image-height, 100px);
 }
\ No newline at end of file
diff --git a/locale.xml b/locale.xml
index f8b0033..59b53ca 100644
--- a/locale.xml
+++ b/locale.xml
@@ -500,6 +500,15 @@
                 <en><![CDATA[Compact (only icon)]]></en>
             </locale>
 
+        <locale name="settings.shop.order.basket.showImages">
+            <de><![CDATA[Produktbilder im Warenkorb anzeigen]]></de>
+            <en><![CDATA[Show product images in basket]]></en>
+        </locale>
+        <locale name="settings.shop.order.basket.showImages.desc">
+            <de><![CDATA[Wenn aktiviert, werden in Warenkorb und Bestellung die Produktbilder angezeigt.]]></de>
+            <en><![CDATA[If the option ist enabled, the product images are displayed in the shopping basket and order.]]></en>
+        </locale>
+
         <!-- basket open -->
         <locale name="settings.shop.basketOpen">
             <de><![CDATA[Aktion bei Klick auf Warenkorb]]></de>
diff --git a/quiqqer/order/src/QUI/ERP/Order/Controls/Basket/Basket.html b/quiqqer/order/src/QUI/ERP/Order/Controls/Basket/Basket.html
new file mode 100644
index 0000000..d06d528
--- /dev/null
+++ b/quiqqer/order/src/QUI/ERP/Order/Controls/Basket/Basket.html
@@ -0,0 +1,242 @@
+{template_event name="quiqqer::order::basket::begin" Basket=$Basket}
+
+{if $Products->count()}
+<table class="quiqqer-order-basket-articles">
+    <thead>
+    <tr class="quiqqer-order-basket-articles-header">
+        <th class="quiqqer-order-basket-articles-header-pos"
+            title="{locale group='quiqqer/erp' var='article.list.articles.header.pos'}"
+        >
+            {locale group="quiqqer/erp" var="article.list.articles.header.pos"}
+        </th>
+        {if QUI\TemplateCologne\Utils::getSetting('order.basket.showImages')}
+        <th class="quiqqer-order-basket-articles-header-image"
+            title="{locale group='quiqqer/erp' var='article.list.articles.header.image'}"
+        >
+            {locale group="quiqqer/erp" var="article.list.articles.header.image"}
+        </th>
+        {/if}
+        <th class="quiqqer-order-basket-articles-header-information"
+            title="{locale group='quiqqer/erp' var='article.list.articles.header.description'}"
+        >
+            {locale group="quiqqer/erp" var="article.list.articles.header.description"}
+        </th>
+        <th class="quiqqer-order-basket-articles-header-quantity"
+            title="{locale group='quiqqer/erp' var='article.list.articles.header.quantity'}"
+        >
+            {locale group="quiqqer/erp" var="article.list.articles.header.quantity"}
+        </th>
+        <th class="quiqqer-order-basket-articles-unitPrice"
+            title="{locale group='quiqqer/erp' var='article.list.articles.header.unitprice'}"
+        >
+            {locale group="quiqqer/erp" var="article.list.articles.header.unitprice"}
+        </th>
+        <th class="quiqqer-order-basket-articles-header-price"
+            title="{locale group='quiqqer/erp' var='article.list.articles.header.price'}"
+        >
+            {locale group="quiqqer/erp" var="article.list.articles.header.price"}
+        </th>
+        {if $this->getAttribute('editable')}
+        <th class="quiqqer-order-basket-articles-header-action"></th>
+        {/if}
+    </tr>
+    </thead>
+    <tbody>
+    {assign var=pos value=1}
+    {foreach $products as $product}
+    <tr class="quiqqer-order-basket-articles-article" data-pos="{$pos}">
+        <td class="quiqqer-order-basket-articles-article-pos"
+            data-label="{locale group='quiqqer/erp' var='article.list.articles.header.pos'}"
+        >
+            {$pos}
+        </td>
+        {if QUI\TemplateCologne\Utils::getSetting('order.basket.showImages')}
+        <td class="quiqqer-order-basket-articles-article-image"
+            data-label="{locale group='quiqqer/erp' var='article.list.articles.header.image'}"
+        >
+            {image src=$product.imageSrc width=300 height=300 class="quiqqer-order-basket-articles-article-image__img"}
+        </td>
+        {/if}
+        <td class="quiqqer-order-basket-articles-article-data"
+            data-label="{locale group='quiqqer/erp' var='article.list.articles.header.description'}"
+        >
+            <div class="quiqqer-order-basket-articles-article-title">{$product.title}</div>
+            <div class="quiqqer-order-basket-articles-article-description">
+                {$product.description}
+            </div>
+
+            <ul class="quiqqer-order-basket-articles-article-fields">
+                {foreach $product.attributes as $attribute}
+                <li class="quiqqer-order-basket-articles-article-fields-field">
+                    <span>{$attribute.title}:</span>
+                    <span>{$this->getValueText($attribute.valueText)}</span>
+                </li>
+                {/foreach}
+            </ul>
+
+            {if $showArticleNumber && !empty($product.productNo)}
+            <div class="quiqqer-order-basket-articles-article-productno">
+                {locale group="quiqqer/order" var="basket.articles.articleNo"} {$product.productNo}
+            </div>
+            {/if}
+        </td>
+        <td class="quiqqer-order-basket-articles-article-quantity"
+            data-label="{locale group='quiqqer/erp' var='article.list.articles.header.quantity'}"
+        >
+            {assign var=maxQuantity value=""}
+            {assign var=maxQuantityAttr value=""}
+            {if isset($product.maximumQuantity) && $product.maximumQuantity && $product.maximumQuantity !== true}
+            {assign var=maxQuantityAttr value=" max='{$product.maximumQuantity}'"}
+            {assign var=maxQuantity value=(int)$product.maximumQuantity}
+            {/if}
+
+            {if $Utils->isBasketProductEditable($product) && $this->getAttribute('editable') && $maxQuantity != 1}
+            <label>
+                <input type="number"
+                       name="quantity"
+                       min="0"
+                       value="{$product.quantity}"
+                       {$maxQuantityAttr}
+                />
+            </label>
+            {else}
+            <div class="quiqqer-order-basket-articles-article-quantity-value">
+                {$product.quantity}
+            </div>
+            {/if}
+        </td>
+        <td class="quiqqer-order-basket-articles-article-price"
+            data-label="{locale group='quiqqer/erp' var='article.list.articles.header.unitprice'}"
+        >
+            {if !isset($product.displayPrice) || $product.displayPrice}
+            {$product.price}
+            {/if}
+        </td>
+        <td class="quiqqer-order-basket-articles-article-sum"
+            data-label="{locale group='quiqqer/erp' var='article.list.articles.header.price'}"
+        >
+            {if !isset($product.displayPrice) || $product.displayPrice}
+            <span>{$product.sum}</span>
+            {/if}
+
+            {if !isset($product.hasOfferPrice) || $product.hasOfferPrice}
+            <span class="offer-original-price">
+                {$product.originalPrice}
+            </span>
+            {/if}
+        </td>
+        {if $this->getAttribute('editable')}
+        <td class="quiqqer-order-basket-articles-article-remove">
+            <button type="button">
+                <span class="fa fa-trash"></span>
+            </button>
+        </td>
+        {/if}
+    </tr>
+    {assign var=pos value=$pos+1}
+    {/foreach}
+    </tbody>
+</table>
+
+{template_event name="quiqqer::order::basket::middle" Basket=$Basket}
+
+<table class="quiqqer-order-basket-total">
+    <tr class="quiqqer-order-basket-total-subSum">
+        <td class="quiqqer-order-basket-total-firstCell">
+            <span class="quiqqer-order-basket-total-subSum-text">
+                {locale group="quiqqer/order" var="control.order.overview.subSum"}
+            </span>
+        </td>
+        <td class="quiqqer-order-basket-total-secondCell">
+            <span class="quiqqer-order-basket-total-subSum-value">
+                {$data.subSum}
+            </span>
+        </td>
+    </tr>
+
+    {foreach $data.attributes as $attribute}
+    <tr>
+        <td>
+            {$attribute.title} {if !empty($attribute.valueText)}({$attribute.valueText}){/if}
+        </td>
+        <td>
+            {$attribute.value}
+        </td>
+    </tr>
+    {/foreach}
+
+    {if count($data.attributes)}
+    <tr>
+        <td colspan="2"><br/></td>
+    </tr>
+    {/if}
+
+    {foreach $data.vat as $vat}
+    <tr>
+        <td>
+            {$vat.text}
+        </td>
+        <td>
+            {$vat.value}
+        </td>
+    </tr>
+    {/foreach}
+
+
+    {if isset($data.grandTotalFactors) && count($data.grandTotalFactors)}
+    <tr class="quiqqer-order-basket-total-grandSubSum">
+        <td class="quiqqer-order-basket-total-firstCell">
+            <span class="quiqqer-order-basket-total-grandSubSum-text">
+                {locale group="quiqqer/order" var="control.order.overview.grandSubSum"}
+            </span>
+        </td>
+        <td class="quiqqer-order-basket-total-secondCell">
+            <span class="quiqqer-order-basket-total-grandSubSum-value">
+                {$data.grandSubSum}
+            </span>
+        </td>
+    </tr>
+    {foreach $data.grandTotalFactors as $attribute}
+    <tr>
+        <td>
+            {$attribute.title} {if !empty($attribute.valueText) && $attribute.valueText !==
+            '-'}({$attribute.valueText}){/if}
+        </td>
+        <td>
+            {$attribute.value}
+        </td>
+    </tr>
+    {/foreach}
+    {/if}
+
+
+    {if count($data.attributes)}
+    <tr>
+        <td colspan="2"><br/></td>
+    </tr>
+    {/if}
+    <tr class="quiqqer-order-basket-total-sum">
+        <td>
+            <span class="quiqqer-order-basket-total-sum-text">
+                {locale group="quiqqer/order" var="control.order.overview.sum"}
+            </span>
+        </td>
+        <td>
+            <span class="quiqqer-order-basket-total-sum-value">
+                {$data.sum}
+            </span>
+        </td>
+    </tr>
+</table>
+
+{elseif $this->isGuest() && $this->isLoading()}
+<div class="quiqqer-order-basket-isLoading">
+    <span class="fa fa-spinner fa-spin"></span>
+</div>
+{else}
+<div class="quiqqer-order-basket-isEmpty">
+    {locale group="quiqqer/order" var="message.basket.is.empty"}
+</div>
+{/if}
+
+{template_event name="quiqqer::order::basket::end" Basket=$Basket}
diff --git a/settings.xml b/settings.xml
index 92d479b..479cd8f 100644
--- a/settings.xml
+++ b/settings.xml
@@ -36,6 +36,10 @@
                         <type><![CDATA[string]]></type>
                         <defaultvalue>full</defaultvalue>
                     </conf>
+                    <conf name="order.basket.showImages">
+                        <type><![CDATA[bool]]></type>
+                        <defaultvalue>1</defaultvalue>
+                    </conf>
                     <conf name="basketOpen">
                         <type><![CDATA[integer]]></type>
                         <defaultvalue>2</defaultvalue>
@@ -437,6 +441,19 @@
                                 </option>
                             </select>
 
+                                <input conf="templateCologne.settings.order.basket.showImages" type="checkbox">
+                                <text>
+                                    <locale group="quiqqer/template-cologne"
+                                            var="settings.shop.order.basket.showImages"
+                                    />
+                                </text>
+                                <description>
+                                    <locale group="quiqqer/template-cologne"
+                                            var="settings.shop.order.basket.showImages.desc"
+                                    />
+                                </description>
+                            </input>
+
                             <!-- basket open (nothing order window, order page)-->
                             <select conf="templateCologne.settings.basketOpen">
                                 <text>
diff --git a/src/QUI/TemplateCologne/Utils.php b/src/QUI/TemplateCologne/Utils.php
index 81475da..7c8dcf0 100644
--- a/src/QUI/TemplateCologne/Utils.php
+++ b/src/QUI/TemplateCologne/Utils.php
@@ -690,4 +690,39 @@ public static function convertBrickCSSClass(array $classes)
 
         return $text;
     }
+
+    /**
+     * Get template setting for given string.
+     * By passing setting name you can omit template prefix setting name ("templateCologne.settings.")
+     *
+     * Usage:
+     *   QUI\TemplateCologne\Utils::getSettings('homeLink');
+     *   or
+     *   QUI\TemplateCologne\Utils::getSettings('templateCologne.settings.homeLink');
+     *
+     * @param string $settingName
+     * @return bool|array|int|string
+     */
+    public static function getSetting(string $settingName): bool|array|int|string
+    {
+        if (empty($settingName)) {
+            return false;
+        }
+
+        $a = strpos($settingName, 'templateCologne.settings.');
+        if (!str_contains($settingName, 'templateCologne.settings.')) {
+            $settingName = 'templateCologne.settings.' . $settingName;
+        }
+
+        try {
+            $Project = QUI::getRewrite()->getProject();
+
+            return $Project->getConfig($settingName);
+        } catch (\Exception $Exception) {
+            QUI\System\Log::writeException($Exception);
+
+            return '';
+        }
+
+    }
 }
-- 
GitLab