Added ability to add/edit note fields in Magento Admin.

This commit is contained in:
shopkeeperdev
2025-10-07 18:57:28 -04:00
parent 44c5b511a3
commit fcc8697c75
5 changed files with 186 additions and 38 deletions

View File

@@ -0,0 +1,41 @@
<?php
namespace Shopkeeper\VendorNotes\Block\Adminhtml\Form\Field;
use Magento\Config\Block\System\Config\Form\Field\FieldArray\AbstractFieldArray;
use Magento\Framework\DataObject;
class VendorMapping extends AbstractFieldArray
{
/**
* Prepare rendering the new field by adding all the needed columns
*/
protected function _prepareToRender()
{
$this->addColumn('vendor_name', [
'label' => __('Vendor Name'),
'class' => 'required-entry',
'style' => 'width:200px'
]);
$this->addColumn('note', [
'label' => __('Note'),
'class' => 'required-entry',
'style' => 'width:400px'
]);
$this->_addAfter = false;
$this->_addButtonLabel = __('Add Vendor Note');
}
/**
* Prepare existing row data object
*
* @param DataObject $row
* @throws \Magento\Framework\Exception\LocalizedException
*/
protected function _prepareArrayRow(DataObject $row): void
{
$options = [];
$row->setData('option_extra_attrs', $options);
}
}

View File

@@ -5,20 +5,24 @@ use Magento\Backend\Block\Template;
use Magento\Sales\Model\Order; use Magento\Sales\Model\Order;
use Magento\Framework\App\Config\ScopeConfigInterface; use Magento\Framework\App\Config\ScopeConfigInterface;
use Magento\Store\Model\ScopeInterface; use Magento\Store\Model\ScopeInterface;
use Magento\Framework\Serialize\Serializer\Json;
class VendorNotes extends Template class VendorNotes extends Template
{ {
protected $_order; protected $_order;
protected $_scopeConfig; protected $_scopeConfig;
protected $json;
public function __construct( public function __construct(
\Magento\Backend\Block\Template\Context $context, \Magento\Backend\Block\Template\Context $context,
\Magento\Sales\Model\Order $order, \Magento\Sales\Model\Order $order,
ScopeConfigInterface $scopeConfig, ScopeConfigInterface $scopeConfig,
Json $json,
array $data = [] array $data = []
) { ) {
$this->_order = $order; $this->_order = $order;
$this->_scopeConfig = $scopeConfig; $this->_scopeConfig = $scopeConfig;
$this->json = $json;
parent::__construct($context, $data); parent::__construct($context, $data);
} }
@@ -31,22 +35,34 @@ class VendorNotes extends Template
{ {
$order = $this->getOrder(); $order = $this->getOrder();
$notes = []; $notes = [];
$vendorConfigPaths = [
'Thermo Fisher' => 'vendor_notes/general/thermo_fisher_note', // Get the vendor mapping configuration
'Orion' => 'vendor_notes/general/orion_note', $vendorMapping = $this->getVendorMapping();
'Nalgene' => 'vendor_notes/general/nalgene_note',
'Thermo Fisher Parts' => 'vendor_notes/general/thermo_fisher_parts_note' if (empty($vendorMapping)) {
]; return $notes;
}
foreach ($order->getAllItems() as $item) { foreach ($order->getAllItems() as $item) {
$product = $item->getProduct(); $product = $item->getProduct();
$vendorId = $product->getData('vendor'); $vendorId = $product->getData('vendor');
if ($vendorId) { if ($vendorId) {
$vendorLabel = $product->getAttributeText('vendor'); $vendorLabel = $product->getAttributeText('vendor');
if (isset($vendorConfigPaths[$vendorLabel])) {
$note = $this->_scopeConfig->getValue($vendorConfigPaths[$vendorLabel], ScopeInterface::SCOPE_STORE); // Look for matching vendor in the mapping
if ($note && !in_array($note, $notes)) { foreach ($vendorMapping as $mapping) {
$notes[] = $note; if (isset($mapping['vendor_name']) &&
isset($mapping['note']) &&
$mapping['vendor_name'] === $vendorLabel) {
$note = $mapping['note'];
// Avoid duplicate notes
if ($note && !in_array($note, $notes)) {
$notes[] = $note;
}
break;
} }
} }
} }
@@ -54,4 +70,28 @@ class VendorNotes extends Template
return $notes; return $notes;
} }
/**
* Get vendor mapping from configuration
*
* @return array
*/
protected function getVendorMapping()
{
$config = $this->_scopeConfig->getValue(
'vendor_notes/general/vendor_mapping',
ScopeInterface::SCOPE_STORE
);
if (!$config) {
return [];
}
try {
$mapping = $this->json->unserialize($config);
return is_array($mapping) ? $mapping : [];
} catch (\Exception $e) {
return [];
}
}
} }

74
Setup/UpgradeData.php Normal file
View File

@@ -0,0 +1,74 @@
<?php
namespace Shopkeeper\VendorNotes\Setup;
use Magento\Framework\Setup\ModuleContextInterface;
use Magento\Framework\Setup\ModuleDataSetupInterface;
use Magento\Framework\Setup\UpgradeDataInterface;
use Magento\Framework\App\Config\Storage\WriterInterface;
use Magento\Framework\App\Config\ScopeConfigInterface;
use Magento\Framework\Serialize\Serializer\Json;
class UpgradeData implements UpgradeDataInterface
{
protected $configWriter;
protected $scopeConfig;
protected $json;
public function __construct(
WriterInterface $configWriter,
ScopeConfigInterface $scopeConfig,
Json $json
) {
$this->configWriter = $configWriter;
$this->scopeConfig = $scopeConfig;
$this->json = $json;
}
public function upgrade(ModuleDataSetupInterface $setup, ModuleContextInterface $context)
{
$setup->startSetup();
// Migrate from old individual fields to new dynamic rows format
if (version_compare($context->getVersion(), '1.1.0', '<')) {
$this->migrateToVendorMapping();
}
$setup->endSetup();
}
/**
* Migrate old configuration to new vendor mapping format
*/
protected function migrateToVendorMapping()
{
// Define the old configuration paths and their corresponding vendor names
$oldConfigs = [
'vendor_notes/general/thermo_fisher_note' => 'Thermo Fisher',
'vendor_notes/general/orion_note' => 'Orion',
'vendor_notes/general/nalgene_note' => 'Nalgene',
'vendor_notes/general/thermo_fisher_parts_note' => 'Thermo Fisher Parts'
];
$vendorMapping = [];
foreach ($oldConfigs as $configPath => $vendorName) {
$note = $this->scopeConfig->getValue($configPath);
if ($note) {
$vendorMapping[] = [
'vendor_name' => $vendorName,
'note' => $note
];
}
}
// Save the new mapping if we have data
if (!empty($vendorMapping)) {
$serializedMapping = $this->json->serialize($vendorMapping);
$this->configWriter->save(
'vendor_notes/general/vendor_mapping',
$serializedMapping
);
}
}
}

View File

@@ -9,38 +9,31 @@
<tab>shopkeeper</tab> <tab>shopkeeper</tab>
<resource>Shopkeeper_VendorNotes::config_vendor_notes</resource> <resource>Shopkeeper_VendorNotes::config_vendor_notes</resource>
<group id="general" translate="label" type="text" sortOrder="10" showInDefault="1" showInWebsite="1" showInStore="1"> <group id="general" translate="label" type="text" sortOrder="10" showInDefault="1" showInWebsite="1" showInStore="1">
<label>General</label> <label>Vendor Notes Configuration</label>
<comment><![CDATA[ <comment><![CDATA[
<div style="padding: 10px; background: #f0f0f0; border-left: 3px solid #1979c3; margin-bottom: 20px;"> <div style="padding: 10px; background: #f0f0f0; border-left: 3px solid #1979c3; margin-bottom: 20px;">
<strong>How to use Vendor Notes:</strong> <strong>How to use Vendor Notes:</strong>
<ul style="margin: 10px 0; padding-left: 20px;"> <ul style="margin: 10px 0; padding-left: 20px;">
<li>These notes will automatically appear on order pages when products with the corresponding vendor are in the order.</li> <li>Click "Add Row" to create a new vendor note configuration</li>
<li>You can use HTML formatting: <code>&lt;br&gt;</code> for line breaks, <code>&lt;a href="mailto:email@example.com"&gt;link text&lt;/a&gt;</code> for email links.</li> <li>Enter the <strong>exact vendor name</strong> as it appears in the Vendor attribute (Stores > Attributes > Product > Vendor)</li>
<li>Leave a field blank if you don't need notes for that vendor.</li> <li>Enter your note text - HTML is supported for links and formatting</li>
<li>Notes will automatically appear on order pages when products with the matching vendor are in the order</li>
</ul> </ul>
<strong>Need to add a new vendor?</strong> <strong>HTML Formatting Examples:</strong>
<ol style="margin: 10px 0; padding-left: 20px;"> <ul style="margin: 10px 0; padding-left: 20px;">
<li>Go to <strong>Stores > Attributes > Product</strong> and edit the <strong>Vendor</strong> attribute (attribute code: <code>vendor</code>)</li> <li>Line break: <code>&lt;br&gt;</code></li>
<li>Add your new vendor option in the <strong>Manage Options</strong> section</li> <li>Email link: <code>&lt;a href="mailto:support@example.com"&gt;support@example.com&lt;/a&gt;</code></li>
<li>Contact your developer to add the configuration field for the new vendor note</li> <li>Website link: <code>&lt;a href="https://example.com"&gt;Visit Website&lt;/a&gt;</code></li>
</ol> </ul>
<strong>Managing Vendors:</strong>
<p style="margin: 10px 0;">To add or edit vendor options, go to <strong>Stores > Attributes > Product</strong> and edit the <strong>Vendor</strong> attribute (code: <code>vendor</code>)</p>
</div> </div>
]]></comment> ]]></comment>
<field id="thermo_fisher_note" translate="label" type="textarea" sortOrder="10" showInDefault="1" showInWebsite="1" showInStore="1"> <field id="vendor_mapping" translate="label" sortOrder="10" showInDefault="1" showInWebsite="1" showInStore="1">
<label>Thermo Fisher Note</label> <label>Vendor Notes</label>
<comment>Enter notes here. Supports HTML for links and emails (e.g., &lt;a href="mailto:support@thermofisher.com"&gt;support@thermofisher.com&lt;/a&gt;).</comment> <frontend_model>Shopkeeper\VendorNotes\Block\Adminhtml\Form\Field\VendorMapping</frontend_model>
</field> <backend_model>Magento\Config\Model\Config\Backend\Serialized\ArraySerialized</backend_model>
<field id="orion_note" translate="label" type="textarea" sortOrder="20" showInDefault="1" showInWebsite="1" showInStore="1"> <comment>Add vendor names and their corresponding notes. The vendor name must match exactly as it appears in the product attribute.</comment>
<label>Orion Note</label>
<comment>Enter notes here. Supports HTML for links and emails.</comment>
</field>
<field id="nalgene_note" translate="label" type="textarea" sortOrder="30" showInDefault="1" showInWebsite="1" showInStore="1">
<label>Nalgene Note</label>
<comment>Enter notes here. Supports HTML for links and emails.</comment>
</field>
<field id="thermo_fisher_parts_note" translate="label" type="textarea" sortOrder="40" showInDefault="1" showInWebsite="1" showInStore="1">
<label>Thermo Fisher Parts Note</label>
<comment>Enter notes here. Supports HTML for links and emails.</comment>
</field> </field>
</group> </group>
</section> </section>

View File

@@ -1,4 +1,4 @@
<?xml version="1.0"?> <?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd"> <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
<module name="Shopkeeper_VendorNotes" setup_version="1.0.0"/> <module name="Shopkeeper_VendorNotes" setup_version="1.1.0"/>
</config> </config>