From fcc8697c75a1c1f55eaaff5788b7bb0067fe28bd Mon Sep 17 00:00:00 2001 From: shopkeeperdev Date: Tue, 7 Oct 2025 18:57:28 -0400 Subject: [PATCH] Added ability to add/edit note fields in Magento Admin. --- Block/Adminhtml/Form/Field/VendorMapping.php | 41 +++++++++++ Block/Adminhtml/Order/View/VendorNotes.php | 62 +++++++++++++--- Setup/UpgradeData.php | 74 ++++++++++++++++++++ etc/adminhtml/system.xml | 43 +++++------- etc/module.xml | 4 +- 5 files changed, 186 insertions(+), 38 deletions(-) create mode 100644 Block/Adminhtml/Form/Field/VendorMapping.php create mode 100644 Setup/UpgradeData.php diff --git a/Block/Adminhtml/Form/Field/VendorMapping.php b/Block/Adminhtml/Form/Field/VendorMapping.php new file mode 100644 index 0000000..35e3782 --- /dev/null +++ b/Block/Adminhtml/Form/Field/VendorMapping.php @@ -0,0 +1,41 @@ +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); + } +} \ No newline at end of file diff --git a/Block/Adminhtml/Order/View/VendorNotes.php b/Block/Adminhtml/Order/View/VendorNotes.php index 043557e..dd2ff9c 100644 --- a/Block/Adminhtml/Order/View/VendorNotes.php +++ b/Block/Adminhtml/Order/View/VendorNotes.php @@ -5,20 +5,24 @@ use Magento\Backend\Block\Template; use Magento\Sales\Model\Order; use Magento\Framework\App\Config\ScopeConfigInterface; use Magento\Store\Model\ScopeInterface; +use Magento\Framework\Serialize\Serializer\Json; class VendorNotes extends Template { protected $_order; protected $_scopeConfig; + protected $json; public function __construct( \Magento\Backend\Block\Template\Context $context, \Magento\Sales\Model\Order $order, ScopeConfigInterface $scopeConfig, + Json $json, array $data = [] ) { $this->_order = $order; $this->_scopeConfig = $scopeConfig; + $this->json = $json; parent::__construct($context, $data); } @@ -31,22 +35,34 @@ class VendorNotes extends Template { $order = $this->getOrder(); $notes = []; - $vendorConfigPaths = [ - 'Thermo Fisher' => 'vendor_notes/general/thermo_fisher_note', - 'Orion' => 'vendor_notes/general/orion_note', - 'Nalgene' => 'vendor_notes/general/nalgene_note', - 'Thermo Fisher Parts' => 'vendor_notes/general/thermo_fisher_parts_note' - ]; + + // Get the vendor mapping configuration + $vendorMapping = $this->getVendorMapping(); + + if (empty($vendorMapping)) { + return $notes; + } foreach ($order->getAllItems() as $item) { $product = $item->getProduct(); $vendorId = $product->getData('vendor'); + if ($vendorId) { $vendorLabel = $product->getAttributeText('vendor'); - if (isset($vendorConfigPaths[$vendorLabel])) { - $note = $this->_scopeConfig->getValue($vendorConfigPaths[$vendorLabel], ScopeInterface::SCOPE_STORE); - if ($note && !in_array($note, $notes)) { - $notes[] = $note; + + // Look for matching vendor in the mapping + foreach ($vendorMapping as $mapping) { + 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; } -} + + /** + * 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 []; + } + } +} \ No newline at end of file diff --git a/Setup/UpgradeData.php b/Setup/UpgradeData.php new file mode 100644 index 0000000..a5ffe22 --- /dev/null +++ b/Setup/UpgradeData.php @@ -0,0 +1,74 @@ +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 + ); + } + } +} \ No newline at end of file diff --git a/etc/adminhtml/system.xml b/etc/adminhtml/system.xml index 32f57ab..b9fafae 100644 --- a/etc/adminhtml/system.xml +++ b/etc/adminhtml/system.xml @@ -9,38 +9,31 @@ shopkeeper Shopkeeper_VendorNotes::config_vendor_notes - + How to use Vendor Notes:
    -
  • These notes will automatically appear on order pages when products with the corresponding vendor are in the order.
  • -
  • You can use HTML formatting: <br> for line breaks, <a href="mailto:email@example.com">link text</a> for email links.
  • -
  • Leave a field blank if you don't need notes for that vendor.
  • +
  • Click "Add Row" to create a new vendor note configuration
  • +
  • Enter the exact vendor name as it appears in the Vendor attribute (Stores > Attributes > Product > Vendor)
  • +
  • Enter your note text - HTML is supported for links and formatting
  • +
  • Notes will automatically appear on order pages when products with the matching vendor are in the order
- Need to add a new vendor? -
    -
  1. Go to Stores > Attributes > Product and edit the Vendor attribute (attribute code: vendor)
  2. -
  3. Add your new vendor option in the Manage Options section
  4. -
  5. Contact your developer to add the configuration field for the new vendor note
  6. -
+ HTML Formatting Examples: +
    +
  • Line break: <br>
  • +
  • Email link: <a href="mailto:support@example.com">support@example.com</a>
  • +
  • Website link: <a href="https://example.com">Visit Website</a>
  • +
+ Managing Vendors: +

To add or edit vendor options, go to Stores > Attributes > Product and edit the Vendor attribute (code: vendor)

]]>
- - - Enter notes here. Supports HTML for links and emails (e.g., <a href="mailto:support@thermofisher.com">support@thermofisher.com</a>). - - - - Enter notes here. Supports HTML for links and emails. - - - - Enter notes here. Supports HTML for links and emails. - - - - Enter notes here. Supports HTML for links and emails. + + + Shopkeeper\VendorNotes\Block\Adminhtml\Form\Field\VendorMapping + Magento\Config\Model\Config\Backend\Serialized\ArraySerialized + Add vendor names and their corresponding notes. The vendor name must match exactly as it appears in the product attribute.
diff --git a/etc/module.xml b/etc/module.xml index 3e61d6e..217558a 100644 --- a/etc/module.xml +++ b/etc/module.xml @@ -1,4 +1,4 @@ - - + + \ No newline at end of file