etchflow/module-order-email-editor

Admin module to edit the customer email on a placed sales order, with optional customer-record sync and an audit history. Hyva / Magento Open Source / Adobe Commerce compatible.

Maintainers

Package info

github.com/Hamza-khan09/etechflow_OrderEmailEditor

Type:magento2-module

pkg:composer/etchflow/module-order-email-editor

Statistics

Installs: 1

Dependents: 0

Suggesters: 0

Stars: 0

Open Issues: 0

1.0.0 2026-05-18 15:06 UTC

This package is auto-updated.

Last update: 2026-05-18 15:07:06 UTC


README

Magento 2 admin module that lets an admin edit the customer email address on a placed order, optionally sync the change to the linked customer account, and keep an audit history of every change.

Compatible with:

  • Magento Open Source 2.4+
  • Adobe Commerce 2.4+
  • Hyvä themes — the module is admin-only, so it has zero impact on Hyvä's stripped-down storefront. No RequireJS, no Knockout, no jQuery used by this module on any page.

Features

Edit misspelled email on a placed order
Update both billing + shipping address rows on the order
Auto-reindex Magento's order/invoice/shipment/creditmemo grid tables ✓ (via core observer on sales_order_save_after)
Optionally update the linked customer_entity.email ✓ (checkbox, disabled for guest orders)
Defensive quote-table sync if the original quote still exists
Audit log of every change with admin user, IP, timestamp
Standard Magento ACL — granular per-role permissions
No frontend dependencies (admin-only module)

Installation

Option A — Composer (recommended for production)

composer require etechflow/module-order-email-editor:^1.0
bin/magento module:enable Etechflow_OrderEmailEditor
bin/magento setup:upgrade
bin/magento setup:di:compile     # production mode only
bin/magento setup:static-content:deploy -f en_GB  # production mode only
bin/magento cache:flush

Option B — Manual drop-in

  1. Copy the whole Etechflow_OrderEmailEditor folder to app/code/Etechflow/OrderEmailEditor/.
  2. Run:
    bin/magento module:enable Etechflow_OrderEmailEditor
    bin/magento setup:upgrade
    bin/magento setup:di:compile           # production mode only
    bin/magento cache:flush

The setup:upgrade step creates one new database table: etechflow_email_change_history.

Permissions (ACL)

Two new resources appear under System → Permissions → User Roles → Role Resources → Sales → Operations → Orders:

  • Etechflow_OrderEmailEditor::edit_email — required to use the modal & POST to the update endpoint
  • Etechflow_OrderEmailEditor::view_history — required to view the history grid

By default both are granted to "All" / Admin role. Assign them granularly to limited roles as needed.

Usage

  1. Admin → Sales → Orders → pick any order.
  2. In the Order & Account Information panel you'll see an Edit Email button under the existing email.
  3. Click it. A modal opens with:
    • Current email shown for confirmation
    • New email input
    • "Also update the linked customer account" checkbox (hidden for guest orders)
  4. Submit. The modal returns a success message, the email on the page updates inline, and a new row is written to etechflow_email_change_history.

Viewing change history

Admin → Sales → Operations → Order Email Change History (or the URL /admin/order_email_editor/history/index).

Standard Magento UI Component grid with filterable columns: increment ID, old email, new email, admin who changed it, customer-record-updated flag, IP, timestamp.

What this module touches in the database

When the Change Email button is clicked, the module updates these tables in a single transaction:

Table Column How
sales_order customer_email via OrderRepository::save() (clean)
sales_order_address email (both billing + shipping rows) via OrderRepository::save()
sales_order_grid customer_email auto (Magento's sales_order_save_after observer reindexes)
sales_invoice_grid customer_email auto, same observer
sales_creditmemo_grid customer_email auto, same observer
sales_shipment_grid customer_email auto, same observer
customer_entity email only if checkbox is on AND sales_order.customer_id is set
quote + quote_address customer_email / email defensive — only if the original quote row still exists
etechflow_email_change_history new row inserted with old/new email, admin info, IP

customer_grid_flat is rebuilt automatically by the customer indexer after the customer save.

Uninstall

bin/magento module:disable Etechflow_OrderEmailEditor
# Optionally drop the history table:
mysql -e "DROP TABLE IF EXISTS etechflow_email_change_history" $DB
# If installed via Composer:
composer remove etechflow/module-order-email-editor
rm -rf app/code/Etechflow/OrderEmailEditor   # if installed manually
bin/magento setup:upgrade
bin/magento cache:flush

Why this module is Hyvä-safe

Hyvä themes only replace the storefront — admin is untouched. This module has:

  • No view/frontend/ directory
  • No requirejs-config.js
  • No data-mage-init, no text/x-magento-init, no require([...]), no jQuery, no Knockout, no Magento UI Component on the storefront
  • Pure server-rendered admin templates + vanilla JS (fetch()) for the AJAX call

The admin UI uses standard Magento UI Components and admin layout XML — no Hyvä-specific patterns required.

Compatibility matrix

Platform Status
Magento Open Source 2.4.4 – 2.4.8 ✓ tested patterns
Adobe Commerce 2.4.4 – 2.4.8 ✓ (no commerce-only dependencies used)
Hyvä child theme (any version) ✓ (admin-only module)
PHP 8.1 / 8.2 / 8.3 / 8.4 ✓ (uses readonly constructor-promoted properties; composer.json pins `~8.1
MySQL 8 / MariaDB 10.6+

Verification (sanity check after install)

-- 1. Module enabled?
SELECT * FROM core_config_data WHERE path='setup_version' AND value LIKE '%OrderEmailEditor%';

-- 2. History table exists?
SHOW TABLES LIKE 'etechflow_email_change_history';

-- 3. After editing one order via the UI, check audit row:
SELECT * FROM etechflow_email_change_history ORDER BY changed_at DESC LIMIT 5;

-- 4. Verify the order email is updated everywhere:
SET @oid = <your order_id>;
SELECT customer_email FROM sales_order        WHERE entity_id   = @oid;
SELECT email          FROM sales_order_address WHERE parent_id  = @oid;
SELECT customer_email FROM sales_order_grid   WHERE entity_id   = @oid;
SELECT customer_email FROM sales_invoice_grid WHERE order_id    = @oid;

Module file layout

Etechflow_OrderEmailEditor/
├── registration.php
├── composer.json
├── LICENSE
├── README.md
├── etc/
│   ├── module.xml
│   ├── db_schema.xml
│   ├── di.xml
│   ├── acl.xml
│   └── adminhtml/
│       ├── routes.xml
│       └── menu.xml
├── Api/
│   ├── Data/EmailChangeHistoryInterface.php
│   └── EmailChangeHistoryRepositoryInterface.php
├── Model/
│   ├── EmailChangeHistory.php
│   ├── EmailChangeHistoryRepository.php
│   ├── ResourceModel/EmailChangeHistory.php
│   ├── ResourceModel/EmailChangeHistory/Collection.php
│   ├── ResourceModel/EmailChangeHistory/Grid/Collection.php
│   ├── Service/UpdateOrderEmail.php
│   └── Source/YesNo.php
├── Controller/
│   └── Adminhtml/
│       ├── Order/Update.php          # POST /admin/order_email_editor/order/update
│       └── History/Index.php         # GET  /admin/order_email_editor/history/index
├── view/
│   └── adminhtml/
│       ├── layout/
│       │   ├── sales_order_view.xml
│       │   └── order_email_editor_history_index.xml
│       ├── ui_component/
│       │   └── order_email_editor_history_listing.xml
│       ├── templates/
│       │   └── order/view/edit-email.phtml
│       └── web/
│           ├── css/edit-email.css
│           └── js/edit-email.js
└── i18n/
    └── en_GB.csv

License

MIT — see LICENSE.