Skip to main content

Mage2Plenty v2.2 - Enhanced Address Handling & SKU Resolution

· 8 min read
Soft Commerce Team
Mage2Plenty Development Team

We're excited to announce Mage2Plenty v2.2, a focused update that brings significant improvements to address synchronization, introduces a new validated SKU resolver, and adds powerful diagnostic tools for troubleshooting. This release addresses real-world challenges our enterprise clients face with complex order and address workflows.

What's New in v2.2​

Building on v2.1's automation features, this release delivers comprehensive address handling improvements that ensure reliable mapping between Magento and PlentyONE addresses, a new validated SKU resolver for accurate product identification, cron health monitoring for proactive issue detection, and diagnostic CLI commands for troubleshooting address-related issues.

Order Address Handling Improvements​

The Challenge​

Address synchronization between Magento and PlentyONE presents unique challenges:

  • Order-only addresses (guest checkouts) need different handling than saved customer addresses
  • Address ID collisions occur when order address IDs overlap with customer address IDs
  • Content matching is needed when IDs don't provide reliable mapping
  • Missing mappings make it difficult to trace addresses back to original Magento records

The Solution: Reliable Address Mapping​

v2.2 introduces a complete overhaul of address handling with multiple improvements:

New ORDER_ADDRESS_ID Option​

Every order address now includes a dedicated ORDER_ADDRESS_ID option that stores the sales_order_address.entity_id:

Address Options:
├─ EXTERNAL_ADDRESS_ID: customer_address_id (or 0 for order-only)
├─ ORDER_ADDRESS_ID: sales_order_address.entity_id (always unique)
└─ ADDRESS_TYPE_ID: [1, 2] (billing, delivery)

Why This Matters:

  • Reliable mapping back to Magento order addresses
  • Works for both saved and order-only addresses
  • Eliminates ID collision issues
  • Enables accurate address audit and recovery

Smart Address Matching​

The address generator now uses priority-based matching:

Address Match Priority:
1. ID + Content Match (most specific)
└─ Matches both address ID AND content fields
2. Content-Only Match (fallback)
└─ Matches address content when IDs don't align

This ensures addresses are correctly identified even when:

  • Orders use addresses modified since customer creation
  • Address IDs don't directly correspond between systems
  • Multiple orders reference the same customer address

Order Relation Enrichment​

New OrderRelationEnricher properly resolves Magento address IDs during collection:

// Enriches order relations with sales_order_address.entity_id
// from the ORDER_ADDRESS_ID option stored in PlentyONE

This enables:

  • Accurate address-to-order mapping during imports
  • Reliable identification of which Magento order an address belongs to
  • Proper handling of order relations separate from customer relations

Address Relation Refactoring​

The address collection system has been refactored with a pluggable enricher pattern:

Address Relation Enrichers:
├─ ContactRelationEnricher
│ └─ Resolves customer_address_id from EXTERNAL_ADDRESS_ID
└─ OrderRelationEnricher
└─ Resolves sales_order_address.entity_id from ORDER_ADDRESS_ID

Benefits:

  • Extensible architecture for custom relation types
  • Clear separation between customer and order address handling
  • Improved testability and maintainability

Validated SKU to Item/Variation Resolver​

The Challenge​

Resolving Magento SKUs to PlentyONE item/variation IDs has multiple data sources:

  • Product entity attributes (plenty_item_id, plenty_variation_id)
  • Variation entity table (plenty_variation_entity)
  • Product mapping strategy configurations
  • Property-based mappings
  • External API lookups

Without validation, stale or incorrect IDs in product attributes can cause export failures or data corruption.

The Solution: Multi-Step Validated Resolution​

v2.2 introduces SkuToItemVariationResolver with comprehensive validation:

Resolution Pipeline:
1. Product Entity (Candidate IDs)
└─ Get plenty_item_id/plenty_variation_id from catalog_product_entity
2. Entity Table Validation (Source of Truth)
└─ Validate IDs exist in plenty_variation_entity
3. Direct Number Lookup
└─ Search by variation number in entity table
4. Mapping Strategy
└─ Use ProductMappingStrategy for custom mappings
5. SKU Property Search
└─ Search plenty_property_relation for custom mapping
6. External API (Optional)
└─ Query PlentyONE API as last resort

Resolution Result Object​

The resolver returns a rich result object with metadata:

interface VariationResolutionResultInterface
{
public function getItemId(): ?int;
public function getVariationId(): ?int;
public function getMainVariationId(): ?int;
public function getResolvedVia(): string; // Source of resolution
public function isValidated(): bool; // Confirmed in entity table
public function isResolved(): bool; // Has valid variation ID
}

Batch Resolution​

Optimized batch processing for multiple SKUs:

// Resolve multiple SKUs in one call
$results = $resolver->resolveMultiple(['SKU-001', 'SKU-002', 'SKU-003']);

// Each result includes resolution metadata
foreach ($results as $sku => $result) {
if ($result->isResolved()) {
echo "{$sku}: Item {$result->getItemId()}, Variation {$result->getVariationId()}";
echo " (resolved via {$result->getResolvedVia()})";
}
}

Performance Features:

  • In-memory caching for repeated lookups
  • Batch database queries for multiple SKUs
  • Efficient fallback chain with early exit
  • Cache invalidation support for long-running processes

Cron Health Monitoring​

CronHeartbeat Service​

New service to monitor Magento's cron system health:

interface CronHeartbeatInterface
{
// Check if cron has run within threshold (default 10 minutes)
public function isActive(int $thresholdMinutes = 10): bool;

// Get timestamp of last successful execution
public function getLastExecutionTime(): ?string;
}

Use Cases:

  • Validate cron is running before scheduling sync operations
  • Alert administrators when cron stops functioning
  • Diagnose synchronization delays caused by cron issues
  • Health check endpoints for monitoring systems

Implementation:

  • Queries cron_schedule table for recent successful executions
  • Runtime caching to avoid repeated queries within same request
  • Configurable threshold for different use cases
  • Lightweight with minimal performance impact

Diagnostic CLI Commands​

Address Audit Command​

Comprehensive diagnostic tool for analyzing address mapping issues:

bin/magento plenty:order:audit-addresses \
--from="2025-01-01" \
--to="2025-12-31" \
--format=table

Capabilities:

  • Identify orders with missing address mappings
  • Detect address ID mismatches between systems
  • Analyze external ID assignment patterns
  • Generate reports in multiple formats (table, CSV, JSON)
  • Filter by date range for targeted analysis

Purge External IDs Command​

Clean up invalid external address IDs:

bin/magento plenty:address:purge-external-ids \
--dry-run \
--older-than=30

Features:

  • Identifies and removes stale external ID references
  • Dry-run mode for safe preview
  • Age-based filtering
  • Detailed logging of actions taken

Resolve Address Assignment Command​

Fix address assignment issues automatically:

bin/magento plenty:order:resolve-address-assignment \
--order-id=000000123 \
--verbose

Capabilities:

  • Analyze specific orders for address issues
  • Attempt automatic resolution using content matching
  • Detailed verbose output for troubleshooting
  • Batch processing support for multiple orders

Contact Export Improvements​

Duplicate Email Handling​

The contact export processor now intelligently handles duplicate email scenarios:

Contact Export Flow:
1. Attempt to create/update contact
2. If "contactWithEmailExists" error:
├─ Search for existing contact by email
├─ Link Magento customer to existing PlentyONE contact
└─ Log linking action with audit trail
3. Continue with address export

Benefits:

  • Prevents export failures from duplicate emails
  • Automatically links to existing contacts
  • Maintains data integrity across systems
  • Clear audit trail of linking actions

Email Validation on Collection​

Contacts without valid emails are now skipped during collection:

// Skip contacts without email (PlentyONE allows manual entry without email)
// but Magento requires email for customer sync
if ($email === '' || !str_contains($email, '@')) {
continue;
}

This prevents sync errors when PlentyONE contains manually-entered contacts without email addresses.

Bug Fixes​

Address Option Type Constants​

Fixed duplicate constant values in address option types:

// Before (incorrect - values 11, 11, 11)
public const OPTION_TYPE_TITLE = 11;
public const OPTION_TYPE_CONTACT_PERSON = 11;
public const OPTION_TYPE_EXTERNAL_CUSTOMER_ID = 11;

// After (correct - values 11, 12, 13)
public const OPTION_TYPE_TITLE = 11;
public const OPTION_TYPE_CONTACT_PERSON = 12;
public const OPTION_TYPE_EXTERNAL_CUSTOMER_ID = 13;

Time Duration Formatting​

Fixed potential type errors in duration formatting:

// Before (could cause type errors with floats)
$remainingSeconds = $seconds % 60;

// After (proper float handling)
$remainingSeconds = fmod($seconds, 60);
return sprintf('%dm %ds', (int) $minutes, (int) round($remainingSeconds));

Type Safety Improvements​

  • Added string cast for SKU in reservation source processing
  • Fixed return type consistency in order address retrieval
  • Added null check for format value in UI metadata component

Address Type ID Handling​

Fixed setOptionAddressTypeId() to properly replace existing type options:

// Now removes existing type option before adding new one
// Prevents duplicate type assignments
$options = array_filter($this->getOptions(), function ($item) use ($typeId) {
return !isset($item[HttpClient::TYPE_ID])
|| $item[HttpClient::TYPE_ID] != $typeId;
});

Upgrade Guide​

Prerequisites​

  • Magento 2.4.6+ (2.4.8 recommended)
  • PHP 8.1+ (8.3 or 8.4 recommended)
  • Mage2Plenty v2.1.x

Quick Upgrade​

# Update via Composer
composer require softcommerce/mage2plenty-os:^2.2

# Run Magento updates
bin/magento setup:upgrade
bin/magento setup:di:compile
bin/magento cache:flush

# Optional: Run address audit to check current state
bin/magento plenty:order:audit-addresses --format=table

Post-Upgrade Recommendations​

  1. Run Address Audit:

    bin/magento plenty:order:audit-addresses --from="2025-01-01"
  2. Review Audit Results:

    • Check for orders with missing address mappings
    • Identify any patterns in problematic orders
  3. Resolve Issues (if needed):

    bin/magento plenty:order:resolve-address-assignment --dry-run
  4. Monitor Cron Health: The new CronHeartbeat service will automatically be available for health monitoring.

By the Numbers​

v2.2 Development Stats​

  • 4,500+ lines of new code
  • 25 files added or modified
  • 8 modules updated
  • 3 diagnostic commands added
  • 1 new resolver with 5-step validation pipeline
  • 1 new health service for cron monitoring
  • 5 bug fixes for type safety and constants

Resources​

Documentation​

Support Channels​


Ready to improve your address synchronization? Upgrade to v2.2 today!