I’m working on displaying two specific options, compound_id and medication_id, in the checkout data within Magento. At present, I’ve managed to display mif in the cart data, but that’s outside the scope of what I’m trying to achieve. My goal is to ensure that both compound_id and medication_id are visible in the checkout data. These are text fields in the product’s admin section, where some products have IDs and others do not. I can successfully retrieve and display these IDs when checking out with a simple product. However, I encounter issues with configurable products because I need to fetch this data from the child product of the configurable product, which is not individually visible. It seems I’m unable to access the child data of configurable products, which is where I’m stuck. Here is the code snippet I’m working on:
appcodeCheckoutProcessIntakeControllerBlockFetch.php
<?php
namespace CheckoutProcessIntakeControllerBlock;
use MagentoFrameworkAppActionAction;
use MagentoFrameworkAppActionContext;
use MagentoFrameworkControllerResultJsonFactory;
use MagentoCmsBlockBlock;
class Fetch extends Action
{
protected $resultJsonFactory;
protected $block;
public function __construct(
Context $context,
JsonFactory $resultJsonFactory,
Block $block
) {
$this->resultJsonFactory = $resultJsonFactory;
$this->block = $block;
parent::__construct($context);
}
public function execute()
{
$blockId = $this->getRequest()->getParam('block_id');
$blockHtml = $this->block->setBlockId($blockId)->toHtml();
$result = $this->resultJsonFactory->create();
return $result->setData(['content' => $blockHtml]);
}
}
appcodeCheckoutProcessIntakeetcfrontenddi.xml
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
<type name="MagentoQuoteModelQuoteItem">
<plugin name="add_mif_attribute_to_quote_item" type="CheckoutProcessIntakePluginAddMifAttributeToQuoteItem" />
</type>
</config>
appcodeCheckoutProcessIntakeetcfrontendroutes.xml
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:App/etc/routes.xsd">
<router id="standard">
<route id="intake" frontName="intake">
<module name="CheckoutProcess_Intake" />
</route>
</router>
</config>
appcodeCheckoutProcessIntakeetccatalog_attributes.xml
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/catalog_attributes.xsd">
<group name="quote_item">
<attribute name="mif"/>
<attribute name="medication_id"/>
<attribute name="compound_id"/>
</group>
</config>
appcodeCheckoutProcessIntakeetcmodule.xml
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
<module name="CheckoutProcess_Intake" setup_version="1.0.0">
<sequence>
<module name="Magento_Checkout"/>
</sequence>
</module>
</config>
appcodeCheckoutProcessIntakePluginAddMifAttributeToQuoteItem.php
<?php
namespace CheckoutProcessIntakePlugin;
class AddMifAttributeToQuoteItem
{
public function afterGetItemData(MagentoQuoteModelQuoteItem $subject, $result)
{
$mifValue = $subject->getProduct()->getCustomAttribute('mif')->getValue();
$result['mif'] = $mifValue;
$medicationId = $subject->getProduct()->getCustomAttribute('medication_id')->getValue();
$result['medication_id'] = $medicationId;
$compoundId = $subject->getProduct()->getCustomAttribute('compound_id')->getValue();
$result['compound_id'] = $compoundId;
return $result;
}
}
appcodeCheckoutProcessIntakeviewfrontendlayoutcheckout_index_index.xml
<?xml version="1.0"?>
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
<body>
<referenceBlock name="checkout.root">
<arguments>
<argument name="jsLayout" xsi:type="array">
<item name="components" xsi:type="array">
<item name="checkout" xsi:type="array">
<item name="children" xsi:type="array">
<item name="steps" xsi:type="array">
<item name="children" xsi:type="array">
<item name="intake-step" xsi:type="array">
<item name="component" xsi:type="string">CheckoutProcess_Intake/js/view/intake-step</item>
</item>
</item>
</item>
</item>
</item>
</item>
</argument>
</arguments>
</referenceBlock>
</body>
</page>
appcodeCheckoutProcessIntakeviewfrontendwebjsviewintake-step.js
define([
'ko',
'jquery',
'uiComponent',
'Magento_Checkout/js/model/step-navigator',
'Magento_Checkout/js/model/quote',
'Magento_Ui/js/model/messageList'
], function (ko, $, Component, stepNavigator, quote, messageList) {
'use strict';
return Component.extend({
defaults: {
template: 'CheckoutProcess_Intake/intake-step'
},
isVisible: ko.observable(false),
cmsBlockContent: ko.observable(''),
cmsBlockQueue: ko.observableArray([]),
initialize: function () {
this._super();
this.checkCustomOption();
this.setupEventListener();
return this;
},
navigate: function () {
this.isVisible(true);
this.loadNextCmsBlock();
},
checkCustomOption: function () {
const self = this;
const items = quote.getItems();
let relevantOptionsFound = false;
//console.log('Quote items:', items);
const cmsBlockMapping = {
'ED': 4,
'Skin': 29,
'BirthControl': 2,
'Clomid': 3,
'Estrace': 14,
'Excess Sweating': 15,
'Hairloss': 16,
'Herpes': 17,
'Ibutamoren': 18,
'Ladyv': 19,
'MensHealth': 20,
'Oxytocin': 22,
'PT141': 24,
'PainCream': 23,
'RectalRocket': 25,
'Sti': 30,
'Thymosin': 31,
'Weight Loss': 32,
'Rx': 27,
'Obagi': 29,
'L-ED' : 4,
'L-Herpes': 17,
'L-Weight Loss': 32,
'L-RectalRocket': 25,
};
items.forEach(function (item) {
//console.log('Processing item:', item);
const mifValue = item.product.mif_value;
const medicationId = item.product.medication_id;
const compoundId = item.product.compound_id;
const productOptions = item.options;
//console.log('Medication ID:', medicationId);
//console.log('Compound ID:', compoundId);
// Checking for specific mif values regardless of the options selected
if (['Rx', 'Obagi', 'L-ED', 'L-Weight Loss', 'L-Herpes', 'L-RectalRocket'].includes(mifValue)) {
relevantOptionsFound = true;
self.cmsBlockQueue.push(cmsBlockMapping[mifValue]);
}
// Checking for options and loading corresponding CMS blocks
if (productOptions && productOptions.length > 0) {
productOptions.forEach(function (option) {
if (option.value === "I need an Rx from an online MD" && cmsBlockMapping[mifValue]) {
relevantOptionsFound = true;
self.cmsBlockQueue.push(cmsBlockMapping[mifValue]);
} else if (option.value === "I have an Rx from my MD") {
relevantOptionsFound = true;
self.cmsBlockQueue.push(28);
} else if (option.value === "I have refills") {
relevantOptionsFound = true;
self.cmsBlockQueue.push(26);
}
});
}
});
if (relevantOptionsFound) {
stepNavigator.registerStep(
'intake_step',
null,
'Patient Intake',
this.isVisible,
_.bind(this.navigate, this),
0.5
);
}
},
loadNextCmsBlock: function() {
if (this.cmsBlockQueue().length > 0) {
this.loadCmsBlock(this.cmsBlockQueue.shift());
} else {
this.navigateToNextStep();
}
},
loadCmsBlock: function(blockId) {
const self = this;
return $.ajax({
url: '/intake/block/fetch',
type: 'GET',
data: { block_id: blockId },
dataType: 'json',
success: function(response) {
if (response.content) {
self.cmsBlockContent(response.content);
}
}
});
},
navigateToNextStep: function () {
if (this.cmsBlockQueue().length > 0) {
this.loadNextCmsBlock();
} else {
stepNavigator.next();
}
},
setupEventListener: function() {
const self = this;
document.addEventListener('navigateToNextStep', function() {
self.navigateToNextStep();
});
}
});
});