Skip to content
77 changes: 77 additions & 0 deletions app/code/Magento/Sales/Test/Fixture/InvoiceComment.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
<?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
declare(strict_types=1);

namespace Magento\Sales\Test\Fixture;

use Magento\Framework\DataObject;
use Magento\Sales\Api\Data\CommentInterface;
use Magento\Sales\Api\Data\EntityInterface;
use Magento\Sales\Api\Data\InvoiceCommentInterface;
use Magento\Sales\Api\InvoiceCommentRepositoryInterface;
use Magento\TestFramework\Fixture\Api\ServiceFactory;
use Magento\TestFramework\Fixture\RevertibleDataFixtureInterface;

class InvoiceComment implements RevertibleDataFixtureInterface
{
private const DEFAULT_DATA = [
InvoiceCommentInterface::IS_CUSTOMER_NOTIFIED => 0,
InvoiceCommentInterface::PARENT_ID => 0,
CommentInterface::COMMENT => 'Test Comment',
CommentInterface::IS_VISIBLE_ON_FRONT => 0,
EntityInterface::ENTITY_ID => 0,
EntityInterface::CREATED_AT => "0000-00-00 00:00:00",
];

/**
* @var ServiceFactory
*/
private $serviceFactory;

/**
* @var InvoiceCommentRepositoryInterface
*/
private $invoiceCommentRepository;

/**
* @param ServiceFactory $serviceFactory
* @param InvoiceCommentRepositoryInterface $invoiceCommentRepository
*/
public function __construct(
ServiceFactory $serviceFactory,
InvoiceCommentRepositoryInterface $invoiceCommentRepository
) {
$this->serviceFactory = $serviceFactory;
$this->invoiceCommentRepository = $invoiceCommentRepository;
}

public function apply(array $data = []): ?DataObject
{
$service = $this->serviceFactory->create(InvoiceCommentRepositoryInterface::class, 'save');
$invoiceComment = $service->execute($this->prepareData($data));

return $this->invoiceCommentRepository->get($invoiceComment->getId());
}

public function revert(DataObject $data): void
{
$invoice = $this->invoiceCommentRepository->get($data->getId());
$this->invoiceCommentRepository->delete($invoice);
}

/**
* Prepare invoice data
*
* @param array $data
* @return array
*/
private function prepareData(array $data): array
{
$data['entity'] = array_merge(self::DEFAULT_DATA, $data);

return $data;
}
}
21 changes: 21 additions & 0 deletions app/code/Magento/SalesGraphQl/Model/Resolver/Invoices.php
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,31 @@ public function resolve(
$invoices[] = [
'id' => base64_encode($invoice->getEntityId()),
'number' => $invoice['increment_id'],
'comments' => $this->getInvoiceComments($invoice),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually invoices should not expose comments
They are not in luma and we should deprecate comments in invoice graphql and don't do this fix

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@cpartica are you sure they're not present in Luma?

<block class="Magento\Sales\Block\Order\Comments" name="invoice_comments" template="Magento_Sales::order/comments.phtml"/>

<?= $block->getInvoiceCommentsHtml($_invoice) ?>

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also:

public function getInvoiceCommentsHtml($invoice)
{
$html = '';
$comments = $this->getChildBlock('invoice_comments');
if ($comments) {
$comments->setEntity($invoice)->setTitle($this->escapeHtmlAttr(__('About Your Invoice')));
$html = $comments->toHtml();
}
return $html;
}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@cpartica I have confirmed that invoice comments are indeed visible in Luma - please see screenshot below taken from a fresh 2.4-develop instance.
image

Comments missing from the GraphQL response is clearly a bug, and I'm not sure why it's taking so long for this very simple PR to be merged - it's been over 4 months now since it was approved.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @cpartica, indeed the invoice comments are shown on Luma. Probably you missed the following checkbox, which makes the comment visible on the storefront.

image

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey @cpartica! Looks like @aligent-lturner is right and invoice comments are available to view on the storefront (magento has a visibility modifier for the comments).

'model' => $invoice,
'order' => $orderModel
];
}
return $invoices;
}

/**
* Get invoice comments in proper format
*
* @param InvoiceInterface $invoice
* @return array
*/
private function getInvoiceComments(InvoiceInterface $invoice): array
{
$comments = [];
foreach ($invoice->getComments() as $comment) {
if ($comment->getIsVisibleOnFront()) {
$comments[] = [
'timestamp' => $comment->getCreatedAt(),
'message' => $comment->getComment()
];
}
}
return $comments;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,23 @@

namespace Magento\GraphQl\Sales;

use Magento\Catalog\Test\Fixture\Product as ProductFixture;
use Magento\Checkout\Test\Fixture\PlaceOrder as PlaceOrderFixture;
use Magento\Checkout\Test\Fixture\SetBillingAddress as SetBillingAddressFixture;
use Magento\Checkout\Test\Fixture\SetDeliveryMethod as SetDeliveryMethodFixture;
use Magento\Checkout\Test\Fixture\SetGuestEmail as SetGuestEmailFixture;
use Magento\Checkout\Test\Fixture\SetPaymentMethod as SetPaymentMethodFixture;
use Magento\Checkout\Test\Fixture\SetShippingAddress as SetShippingAddressFixture;
use Magento\Customer\Test\Fixture\Customer;
use Magento\Framework\Registry;
use Magento\Quote\Test\Fixture\AddProductToCart as AddProductToCartFixture;
use Magento\Quote\Test\Fixture\CustomerCart;
use Magento\Quote\Test\Fixture\GuestCart as GuestCartFixture;
use Magento\Sales\Api\OrderRepositoryInterface;
use Magento\Sales\Model\ResourceModel\Order\Collection;
use Magento\Sales\Test\Fixture\Invoice as InvoiceFixture;
use Magento\Sales\Test\Fixture\InvoiceComment as InvoiceCommentFixture ;
use Magento\TestFramework\Fixture\DataFixture;
use Magento\TestFramework\Helper\Bootstrap;
use Magento\TestFramework\TestCase\GraphQlAbstract;
use Magento\GraphQl\GetCustomerAuthenticationHeader;
Expand Down Expand Up @@ -410,6 +424,64 @@ public function testPartialInvoiceForCustomerWithTaxesAndDiscounts()
$this->deleteOrder();
}

#[
DataFixture(Customer::class, ['email' => 'customer@search.example.com'], as: 'customer'),
DataFixture(ProductFixture::class, as: 'product'),
DataFixture(CustomerCart::class, ['customer_id' => '$customer.id$'], as: 'cart'),
DataFixture(AddProductToCartFixture::class, ['cart_id' => '$cart.id$', 'product_id' => '$product.id$']),
DataFixture(SetBillingAddressFixture::class, ['cart_id' => '$cart.id$']),
DataFixture(SetShippingAddressFixture::class, ['cart_id' => '$cart.id$']),
DataFixture(SetGuestEmailFixture::class, ['cart_id' => '$cart.id$']),
DataFixture(SetDeliveryMethodFixture::class, ['cart_id' => '$cart.id$']),
DataFixture(SetPaymentMethodFixture::class, ['cart_id' => '$cart.id$']),
DataFixture(PlaceOrderFixture::class, ['cart_id' => '$cart.id$'], 'order'),
DataFixture(InvoiceFixture::class, ['order_id' => '$order.id$'], 'invoice'),
DataFixture(InvoiceCommentFixture::class, [
'parent_id' => '$invoice.id$',
'comment' => 'visible_comment',
'is_visible_on_front' => 1,
]),
DataFixture(InvoiceCommentFixture::class, [
'parent_id' => '$invoice.id$',
'comment' => 'non_visible_comment',
'is_visible_on_front' => 0,
]),
]
public function testInvoiceCommentsQuery()
{
$query =
<<<QUERY
{
customer {
orders {
items {
invoices {
comments {
message
timestamp
}
}
}
}
}
}
QUERY;

$currentEmail = 'customer@search.example.com';
$currentPassword = 'password';
$response = $this->graphQlQuery(
$query,
[],
'',
$this->customerAuthenticationHeader->execute($currentEmail, $currentPassword)
);

$invoice = $response['customer']['orders']['items'][0]['invoices'][0];
$this->assertCount(1, $invoice['comments']);
$this->assertEquals('visible_comment', $invoice['comments'][0]['message']);
$this->assertNotEmpty($invoice['comments'][0]['timestamp']);
}

/**
* Prepare invoice for the order
*
Expand Down