4 Commits

11 changed files with 340 additions and 2 deletions

View File

@ -172,6 +172,7 @@ abstract class pdfdocumentsGeneric extends Base implements genericInterface
'oViewConf' => Registry::getConfig()->getActiveView()->getViewConfig(),
'shop' => Registry::getConfig()->getActiveShop(),
'lang' => Registry::getLang(),
'utilsUrl' => Registry::getUtilsUrl(),
'document' => $this,
];
}

View File

@ -0,0 +1,84 @@
<?php
/**
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*
* https://www.d3data.de
*
* @copyright (C) D3 Data Development (Inh. Thomas Dartsch)
* @author D3 Data Development - Daniel Seifert <info@shopmodule.com>
* @link https://www.oxidmodule.com
*/
declare(strict_types=1);
namespace D3\PdfDocuments\Application\Model\Documents;
use Assert\Assert;
use Assert\InvalidArgumentException;
use D3\PdfDocuments\Application\Model\AbstractClasses\pdfdocumentsGeneric;
use OxidEsales\Eshop\Application\Model\Article;
use OxidEsales\EshopCommunity\Internal\Container\ContainerFactory;
use OxidEsales\EshopCommunity\Internal\Framework\Templating\TemplateRendererBridge;
use OxidEsales\EshopCommunity\Internal\Framework\Templating\TemplateRendererBridgeInterface;
use OxidEsales\Twig\TwigEngine;
/**
* @codeCoverageIgnore
*/
class articleDataSheet extends pdfdocumentsGeneric
{
protected ?Article $article = null;
public function genPdf( string $filename, int $language = 0, string $target = self::PDF_DESTINATION_STDOUT ): ?string
{
/** @var TemplateRendererBridge $bridge */
$bridge = ContainerFactory::getInstance()->getContainer()->get(TemplateRendererBridgeInterface::class);
Assert::that($bridge->getTemplateRenderer()->getTemplateEngine())
->isInstanceOf(
TwigEngine::class,
<<<MSG
The article data sheet is only provided by the Twig Engine.
Please contact the author for further assistance.
MSG
);
return parent::genPdf( $filename, $language, $target );
}
public function setArticle(Article $article): void
{
$this->article = $article;
}
/**
* @throws InvalidArgumentException
*/
public function getArticle(): Article
{
Assert::that($this->article)->isInstanceOf(Article::class, 'no article for pdf generator set');
Assert::that($this->article->isLoaded())->true('given article is not loaded');
return $this->article;
}
public function getRequestId(): string
{
return 'article_datasheet';
}
public function getTitleIdent(): string
{
return "D3_PDFDOCUMENTS_ARTICLE_DATASHEET";
}
public function getTemplate(): string
{
return '@d3PdfDocuments/documents/article/datasheet';
}
public function getTypeForFilename(): string
{
return "article_datasheet";
}
}

View File

@ -78,5 +78,7 @@ return [
'D3_PDFDOCUMENTS_USTID' => 'Ust.-ID',
'D3_PDFDOCUMENTS_BANK_BANKCODE' => 'BIC/SWIFT-Code',
'D3_PDFDOCUMENTS_ARTICLE_DATASHEET' => 'Artikel Datenblatt',
];
// @codeCoverageIgnoreEnd

View File

@ -77,5 +77,7 @@ return [
'D3_PDFDOCUMENTS_USTID' => 'VAT ID',
'D3_PDFDOCUMENTS_BANK_BANKCODE' => 'BIC/SWIFT Code',
'D3_PDFDOCUMENTS_ARTICLE_DATASHEET' => 'Article data sheet',
];
// @codeCoverageIgnoreEnd

View File

@ -14,8 +14,12 @@
namespace D3\PdfDocuments\Modules\Application\Controller {
use OxidEsales\Eshop\Application\Controller\Admin\OrderOverview;
use OxidEsales\Eshop\Application\Controller\ArticleDetailsController;
class d3_overview_controller_pdfdocuments_parent extends OrderOverview
{
}
class ArticleDetailsController_pdfdocuments_parent extends ArticleDetailsController
{}
}

View File

@ -0,0 +1,35 @@
<?php
/**
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*
* https://www.d3data.de
*
* @copyright (C) D3 Data Development (Inh. Thomas Dartsch)
* @author D3 Data Development - Daniel Seifert <info@shopmodule.com>
* @link https://www.oxidmodule.com
*/
namespace D3\PdfDocuments\Modules\Application\Controller;
use D3\PdfDocuments\Application\Model\Documents\articleDataSheet;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\NotFoundExceptionInterface;
use Spipu\Html2Pdf\Exception\Html2PdfException;
class ArticleDetailsController_pdfdocuments extends ArticleDetailsController_pdfdocuments_parent
{
/**
* @return void
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
* @throws Html2PdfException
*/
public function generateDataSheet(): void
{
$document = oxNew(articleDataSheet::class);
$document->setArticle($this->getProduct());
$document->downloadPdf();
}
}

View File

@ -43,8 +43,9 @@ Detailed installation instructions can be found [online](https://docs.oxidmodule
## Credits:
- PDF logo made by Dimitriy Morilubov by www.flaticon.com
- PDF icon made by Dimitriy Morilubov by www.flaticon.com
- example company logo by https://www.logologo.com/
- background image of the article data sheet [designed by Harryarts / Freepik](http://www.freepik.com)
## License

View File

@ -43,8 +43,9 @@ Eine detaillierte Installationsanleitung finden Sie [online](https://docs.oxidmo
## Danksagung:
- PDF-Logo erstellt von Dimitriy Morilubov von www.flaticon.com
- PDF-Icon erstellt von Dimitriy Morilubov von www.flaticon.com
- Beispielfirmenlogo von https://www.logologo.com/
- Hintergrundgrafik des Artikeldatenblatts [designed by Harryarts / Freepik](http://www.freepik.com)
## Lizenz

BIN
assets/out/img/ads_bg.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 199 KiB

View File

@ -12,8 +12,10 @@
*/
use D3\PdfDocuments\Application\Model\Constants as Constants;
use D3\PdfDocuments\Modules\Application\Controller\ArticleDetailsController_pdfdocuments;
use D3\PdfDocuments\Modules\Application\Controller\d3_overview_controller_pdfdocuments;
use OxidEsales\Eshop\Application\Controller\Admin\OrderOverview;
use OxidEsales\Eshop\Application\Controller\ArticleDetailsController;
// @codeCoverageIgnoreStart
$sMetadataVersion = '2.1';
@ -29,6 +31,7 @@ $aModule = [
'email' => 'support@shopmodule.com',
'url' => 'https://www.oxidmodule.com/',
'extend' => [
ArticleDetailsController::class => ArticleDetailsController_pdfdocuments::class,
OrderOverview::class => d3_overview_controller_pdfdocuments::class,
],
'controllers' => [],

View File

@ -0,0 +1,205 @@
{% set pagePadding = "45,15,25,25"|split(",") %} {# top, right, bottom, left #}
{#{% set hideHeader = 2..100 %}#}
{#{% set hideFooter = 1..100 %}#}
{% set bgImage = oViewConf.getModulePath('d3PdfDocuments', 'out/img/ads_bg.jpg') %}
{% set showLogo = showLogo|default(1) %}
{% set pdfBlock_style %}
{% block pdfStyles %}
{% include "@d3PdfDocuments/assets/pdfStyling.css.twig" %}
.desc {
font-weight: bold;
font-size: 10pt;
}
.value {
padding-left: 5mm;
}
div.header {
position: absolute;
top: 0;
}
div.header img {
height: 20mm; {# smaller logo from page 2 #}
}
div.header-1 img {
height: inherit; {# default logo size on page 1 #}
}
div.header .address {
position: absolute; font-size: 3mm; top: 42mm; left: 155mm; text-align: center
}
div.header-2 .address {
font-size: 2.5mm; top: 33mm; left: 165mm
}
{% endblock %}
{% endset %}
{% set pdfBlock_header %}
{% block pdfHeader %}
{# {% include "@d3PdfDocuments/documents/inc/page/header.html.twig" with {showLogo: showLogo} %}#}
{% set article = document.getArticle() %}
<div style="position: relative; left: 25mm; top: 7mm; color: #FFF">
<h3>{{ article.getFieldData('oxtitle') }}</h3>
</div>
<div class="header header-[[page_cu]]">
{% if showLogo %}
{% block pdfHeaderLogo %}
{% set logoUrl = config.getConfigParam('d3PdfDocumentsLogoUrl') | default( oViewConf.getModulePath('d3PdfDocuments', 'out/img/clogo.jpg') ) %}
<img class="logo" alt="Logo" src="{{ logoUrl }}">
{% endblock %}
{% endif %}
<div class="address">
{{ shop.getFieldData('oxname') }}<br>
{{ shop.getFieldData('oxstreet') }}<br>
{{ shop.getFieldData('oxzip') }} {{ shop.getFieldData('oxcity') }}
</div>
</div>
{% endblock %}
{% endset %}
{% set pdfBlock_content %}
{# {% include "@d3PdfDocuments/documents/inc/helper/rulers.html.twig" with {pagePadding: pagePadding} %}#}
{% include "@d3PdfDocuments/documents/inc/elements/foldmarks.html.twig" with {pagePadding: pagePadding} %}
{% set article = document.getArticle() %}
<div style="position: relative; top: 0;">
{# <h3>{{ article.getFieldData('oxtitle') }}</h3>#}
<nobreak>
<p>
<div class="desc">
{{ translate({ ident: "ARTNUM", suffix: "COLON" }) }}
</div>
<div class="value">
{{ article.getFieldData('oxartnum') }}
</div>
</p>
</nobreak>
<nobreak>
<p>
<div class="desc">
{{ translate({ ident: "MANUFACTURER", suffix: "COLON" }) }}
</div>
<div class="value">
{{ article.getManufacturer().getTitle() }}
</div>
</p>
</nobreak>
<nobreak>
<p>
<div class="desc">
Link zum Shop:
</div>
<div class="value">
<a href="{{ utilsUrl.prepareUrlForNoSession(article.getLink()) }}">
{{ utilsUrl.prepareUrlForNoSession(article.getLink()) }}
</a>
</div>
</p>
</nobreak>
<qrcode value="{{ utilsUrl.prepareUrlForNoSession(article.getLink()) }}" style="position: absolute; top: 11mm; left: 133mm; width: 30mm; background-color: white; color: black;"></qrcode>
</div>
<hr>
<p>{{ article.getFieldData('oxshortdesc') }}</p>
<p style="text-align: center">
<img alt="{{ article.getFieldData('oxtitle') }}" style="width: 50%" src="{{ article.getThumbnailUrl() }}">
</p>
<p>{{ article.getLongDescription() }}</p>
<p>
{% set attributes = article.getAttributes() %}
{% if attributes %}
<h4 class="desc">Eigenschaften:</h4>
<div class="value">
<table>
{% for oAttr in attributes %}
<tr>
<td id="attrTitle_{{ loop.index }}">{{ oAttr.getFieldData('oxtitle') }}:</td>
<td id="attrValue_{{ loop.index }}">{{ oAttr.getFieldData('oxvalue') }}</td>
</tr>
{% endfor %}
</table>
</div>
{% endif %}
</p>
<nobreak>
<div class="desc">
Preis:
</div>
<div class="value">
{% if article.getPrice() %}
{% set sFrom = "" %}
{% set oPrice = article.getPrice() %}
{% if article.isParentNotBuyable() %}
{% set oPrice = article.getVarMinPrice() %}
{% if article.isRangePrice() %}
{% set sFrom = "PRICE_FROM"|translate %}
{% endif %}
{% endif %}
<span {% if article.getTPrice() %} class="text-danger"{% endif %}>
<span class="price-from">{{ sFrom }}</span>
<span class="price">{{ format_price(oPrice, { currency: currency }) }}</span>
</span>
{% endif %}
{% hasrights { ident: "SHOWARTICLEPRICE" } %}
{% set oUnitPrice = article.getUnitPrice() %}
{% if oUnitPrice %}
<div class="ppu" aria-label="{{ translate({ ident: "WEIGHT" }) }}">
{{ format_price(oUnitPrice, { currency: currency }) }}/{{ article.getUnitName() }}
</div>
{% endif %}
{% endhasrights %}
</div>
</nobreak>
<nobreak>
<h4 class="desc">Verf&uuml;gbarkeit:</h4>
<div class="value">
{% if article.getStockStatus() == -1 %}
<span class="text-danger">?</span>
{% if article.oxarticles__oxnostocktext.value %}
{{ article.oxarticles__oxnostocktext.value }}
{% elseif oViewConf.getStockOffDefaultMessage() %}
{{ translate({ ident: "MESSAGE_NOT_ON_STOCK" }) }}
{% endif %}
{% if article.getDeliveryDate() %}
{{ translate({ ident: "AVAILABLE_ON" }) }} {{ article.getDeliveryDate() }}
{% endif %}
{% elseif article.getStockStatus() == 1 %}
<span class="text-warning">?</span> {{ translate({ ident: "LOW_STOCK" }) }}
{% elseif article.getStockStatus() == 0 %}
<div style="width: 5mm; height: 5mm; background-color: darkgreen; float: left"></div>
{% if article.oxarticles__oxstocktext.value %}
{{ article.oxarticles__oxstocktext.value }}
{% elseif oViewConf.getStockOnDefaultMessage() %}
{{ translate({ ident: "READY_FOR_SHIPPING" }) }}
{% endif %}
{% endif %}
</div>
</nobreak>
<nobreak>
<p>
<h4 class="desc">Galerie</h4>
{% for picture in article.getPictureGallery().Pics %}
<span style="width: 25%; border: 1px solid silver">
<img style="width: 100%" src="{{ picture }}" alt="{{ article.getFieldData('oxtitle') }}">
</span>
{% endfor %}
</p>
</nobreak>
<p>
Vielen Dank f&uuml;r Ihr Interesse an unserem Sortiment.<br>
Kontaktieren Sie uns gern telefonisch oder nutzen Sie unsere Online-Shop unter <a href="{{ oViewConf.getShopUrl() }}">{{ oViewConf.getShopUrl() }}</a>.
</p>
{% endset %}
{% set pdfBlock_footer %}
{% block pdfFooter %}
<p style="position: absolute; bottom: 5mm; text-align: right; margin-right: 5mm; color: #FFF; font-size: 2.5mm">Stand: {{ "now"|date("d.m.Y H:i:s") }}</p>
{% endblock %}
{% endset %}
{% include "@d3PdfDocuments/documents/inc/page/base.html.twig" with {pagePadding: pagePadding} %}