Skip to content

Commit

Permalink
Merge pull request #9374 from adobe-commerce-tier-4/PR-11-19-2024
Browse files Browse the repository at this point in the history
[Support Tier-4 chittima] 11-19-2024 Regular delivery of bugfixes and improvements
internal-magento-queue-manager[bot] authored Nov 21, 2024

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
2 parents 7939bd0 + 7677eb6 commit 88660e7
Showing 13 changed files with 908 additions and 181 deletions.
218 changes: 83 additions & 135 deletions app/code/Magento/Catalog/view/adminhtml/web/js/category-checkbox-tree.js
Original file line number Diff line number Diff line change
@@ -10,24 +10,6 @@ define([
], function ($) {
'use strict';

/**
* Recursively adds the 'lastNode' property to the nodes in the nested object.
*
* @param {Array} nodes
* @returns {Array}
*/
function addLastNodeProperty(nodes) {
return nodes.map(node => {
return node.children ? {
...node,
children: addLastNodeProperty(node.children)
} : {
...node,
lastNode: true
};
});
}

/**
* Main function that creates the jstree
*
@@ -48,142 +30,93 @@ define([
rootId: config.rootId,
expanded: config.expanded,
categoryId: config.categoryId,
treeJson: addLastNodeProperty(config.treeJson)
treeJson: config.treeJson
},
checkedNodes = [];
initialSelection = [];

/**
* Get the jstree element by its ID
*/
const treeId = $('#' + options.divId);

/**
* Function to check child nodes based on the checkedNodes array
*
* @param {Object} node
* @return {Element}
*/
function getCheckedNodeIds(node) {
if (node.children_d && node.children_d.length > 0) {
const selectChildrenNodes = node.children_d.filter(item => checkedNodes.includes(item));

if (selectChildrenNodes.length > 0) {
treeId.jstree(false).select_node(selectChildrenNodes);
}
}
function getTargetInput() {
return options.jsFormObject.updateElement;
}

/**
* Initialize the jstree with configuration options
*/
treeId.jstree({
core: {
data: options.treeJson,
check_callback: true
},
plugins: ['checkbox'],
checkbox: {
three_state: false
}
});

/**
* Event handler for 'loaded.jstree' event
* Recursively marks nodes which children are not loaded.
*
* @param {Array} nodes
* @returns {Array}
*/
treeId.on('loaded.jstree', function () {
function prepareNodes(nodes) {
return nodes.map(
function (node) {
let obj = {...node, state: {}};

if (Array.isArray(obj.children)) {
if (obj.children.length > 0) {
obj.children = prepareNodes(obj.children);
} else {
obj.children = true;
}
}

/**
* Get each node in the tree
*/
$(treeId.jstree().get_json('#', {
flat: false
})).each(function () {
let node = treeId.jstree().get_node(this.id, false);
if (obj.expanded) {
obj.state.opened = true;
}

if (node.original.expanded) {
treeId.jstree(true).open_node(node);
}
if (initialSelection.includes(obj.id)) {
obj.state.selected = true;
}

if (options.jsFormObject.updateElement.defaultValue) {
checkedNodes = options.jsFormObject.updateElement.defaultValue.split(',');
return obj;
}
});
});

/**
* Event handler for 'load_node.jstree' event
*/
treeId.on('load_node.jstree', function (e, data) {
getCheckedNodeIds(data.node);
});

/**
* Add lastNode property to child who doesn't have children property
*
* @param {Object} treeData
*/
function addLastNodeFlag(treeData) {
if (treeData.children) {
treeData.children.forEach((child) => addLastNodeFlag(child));
} else {
treeData.lastNode = true;
}
);
}

/**
* Function to handle the 'success' callback of the AJAX request
* Load the node and execute the callback function
*
* @param {Array} response
* @param {Object} childNode
* @param {Object} data
* @param {Object} node
* @param {Function} callback
*/
function handleSuccessResponse(response, childNode, data) {
if (response.length > 0) {
response.forEach(function (newNode) {
addLastNodeFlag(newNode);

/**
* Create the new node and execute node callback
*/
data.instance.create_node(childNode, newNode, 'last', function (node) {
if (checkedNodes.includes(node.id)) {
treeId.jstree(false).select_node(node.id);
}
getCheckedNodeIds(node);
});
function load(node, callback) {
let target = getTargetInput(),
instance = this;

if (node.id === $.jstree.root) {
callback.call(instance, prepareNodes(options.treeJson));
} else if (Array.isArray(node.children) && node.children.length === 0) {
$.ajax({
url: options.dataUrl,
data: {
id: node.id,
selected: target.value
},
dataType: 'json',
success: function (response) {
callback.call(instance, prepareNodes(response));
},
error: function (jqXHR, status, error) {
console.log(status + ': ' + error + '\nResponse text:\n' + jqXHR.responseText);
}
});
} else {
callback.call(instance, false);
}
}

/**
* Event handler for 'open_node.jstree' event
* Event handler for 'init.jstree' event
*/
treeId.on('open_node.jstree', function (e, data) {
let parentNode = data.node;

if (parentNode.children.length > 0) {
let childNode = data.instance.get_node(parentNode.children, false);

/**
* Check if the child node has no children (is not yet loaded)
*/
if (childNode.children && childNode.children.length === 0
&& childNode.original && !childNode.original.lastNode) {
$.ajax({
url: options.dataUrl,
data: {
id: childNode.id,
selected: options.jsFormObject.updateElement.value
},
dataType: 'json',
success: function (response) {
handleSuccessResponse(response, childNode, data);
},
error: function (jqXHR, status, error) {
console.log(status + ': ' + error + '\nResponse text:\n' + jqXHR.responseText);
}
});
}
}
treeId.on('init.jstree', function () {
let target = getTargetInput();

initialSelection = target.value ? target.value.split(',').map(id => id.trim()) : [];
});

/**
@@ -193,19 +126,34 @@ define([
if (data.action === 'ready') {
return;
}
const clickedNodeID = data.node.id, currentCheckedNodes = data.instance.get_checked();

if (data.action === 'select_node' && !checkedNodes.includes(clickedNodeID)) {
checkedNodes = currentCheckedNodes;
} else if (data.action === 'deselect_node') {
checkedNodes = currentCheckedNodes.filter((nodeID) => nodeID !== clickedNodeID);
}
checkedNodes.sort((a, b) => a - b);

/**
* Update the value of the corresponding form element with the checked node IDs
*
* keep the checked nodes that are not in the tree yet,
* and merge them with the currently checked nodes
* then sort the resulted array
*/
options.jsFormObject.updateElement.value = checkedNodes.join(', ');
let target = getTargetInput(),
selected = initialSelection
.filter(node => data.instance.get_node(node) === false)
.concat(data.instance.get_checked());

target.value = [...new Set(selected)].sort((a, b) => a - b).join(',');
});

/**
* Initialize the jstree with configuration options
*/
treeId.jstree({
core: {
data: load,
check_callback: true
},
plugins: ['checkbox'],
checkbox: {
three_state: false
}
});
};
});
9 changes: 2 additions & 7 deletions app/code/Magento/Quote/Model/Quote/Item/Compare.php
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
* Copyright 2014 Adobe
* All Rights Reserved.
*/
namespace Magento\Quote\Model\Quote\Item;

@@ -68,14 +68,9 @@ protected function getOptionValues($value)
*/
public function compare(Item $target, Item $compared)
{
if ($target->getSku() !== null && $target->getSku() === $compared->getSku()) {
return true;
}

if ($target->getProductId() != $compared->getProductId()) {
return false;
}

$targetOptionByCode = $target->getOptionsByCode();
$comparedOptionsByCode = $compared->getOptionsByCode();
if (!$target->compareOptions($targetOptionByCode, $comparedOptionsByCode)) {
19 changes: 2 additions & 17 deletions app/code/Magento/Quote/Test/Unit/Model/Quote/Item/CompareTest.php
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
* Copyright 2014 Adobe
* All Rights Reserved.
*/
declare(strict_types=1);

@@ -236,19 +236,4 @@ public function testCompareItemWithoutOptionWithCompared()
->willReturn([]);
$this->assertFalse($this->helper->compare($this->itemMock, $this->comparedMock));
}

/**
* test compare two items- when configurable products has assigned sku of its selected variant
*/
public function testCompareConfigurableProductAndItsVariant()
{
$this->itemMock->expects($this->exactly(2))
->method('getSku')
->willReturn('cr1-r');
$this->comparedMock->expects($this->once())
->method('getSku')
->willReturn('cr1-r');

$this->assertTrue($this->helper->compare($this->itemMock, $this->comparedMock));
}
}
Original file line number Diff line number Diff line change
@@ -1,20 +1,19 @@
<?php
/**
*
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
* Copyright 2011 Adobe
* All Rights Reserved.
*/
declare(strict_types=1);

namespace Magento\Reports\Controller\Adminhtml\Report\Product;

use Magento\Backend\Block\Widget\Grid\ExportInterface;
use Magento\Framework\App\Action\HttpPostActionInterface;
use Magento\Framework\App\Action\HttpGetActionInterface;
use Magento\Framework\App\ResponseInterface;
use Magento\Framework\App\Filesystem\DirectoryList;
use Magento\Reports\Controller\Adminhtml\Report\Product;

class ExportSoldCsv extends Product implements HttpPostActionInterface
class ExportSoldCsv extends Product implements HttpGetActionInterface
{
/**
* Authorization level of a basic admin session
Original file line number Diff line number Diff line change
@@ -1,20 +1,19 @@
<?php
/**
*
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
* Copyright 2011 Adobe
* All Rights Reserved.
*/
declare(strict_types=1);

namespace Magento\Reports\Controller\Adminhtml\Report\Product;

use Magento\Backend\Block\Widget\Grid\ExportInterface;
use Magento\Framework\App\Action\HttpPostActionInterface;
use Magento\Framework\App\Action\HttpGetActionInterface;
use Magento\Framework\App\ResponseInterface;
use Magento\Framework\App\Filesystem\DirectoryList;
use Magento\Reports\Controller\Adminhtml\Report\Product;

class ExportSoldExcel extends Product implements HttpPostActionInterface
class ExportSoldExcel extends Product implements HttpGetActionInterface
{
/**
* Authorization level of a basic admin session
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<?php
/**
* Copyright 2024 Adobe
* All Rights Reserved.
*/
declare(strict_types=1);

namespace Magento\Reports\Test\Integration\Controller\Adminhtml\Report\Product;

use Magento\TestFramework\TestCase\AbstractBackendController;

/**
* @magentoAppArea adminhtml
*/
class ExportSoldCsvTest extends AbstractBackendController
{
public function testExecute() : void
{
$this->dispatch('backend/reports/report_product/exportSoldCsv');
$this->assertEquals(302, $this->getResponse()->getHttpResponseCode());
}
}
Loading

0 comments on commit 88660e7

Please sign in to comment.