Fetching 'Paid' Orders in Shopware 6: A Developer's Guide
As a software developer working with Shopware 6, one often encounters the need to retrieve orders based on their payment state—be it for generating reports, synchronizing with external systems, or just for administrative purposes. Today, I will walk you through a reliable method to get orders by a specific state, such as 'paid', using Shopware's robust Criteria API.
Understanding the Criteria API
Shopware 6 provides a flexible and efficient way to query data using its Criteria API. It is built to accommodate complex search requirements, enabling developers to construct detailed and specific queries. Leveraging this API allows us to filter orders by various conditions, such as payment state, order date, and more.
Setting Up the PHP Class
We'll create a class named MyLovelyClass
within our plugin's service namespace. This class is responsible for
interfacing with the EntityRepositoryInterface
to fetch the data. We're injecting both EntityRepositoryInterface
and LoggerInterface
into our class via the constructor. This sets us up with access to the order repository and
logging capabilities for debugging purposes.
<?php
namespace Plugin\Service\ScheduledTask;
use DateTime;
use Psr\Log\LoggerInterface;
use Shopware\Core\Framework\Context;
use Shopware\Core\Framework\DataAbstractionLayer\EntityRepositoryInterface;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\EqualsFilter;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\MultiFilter;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\RangeFilter;
class MyLovelyClass
{
private EntityRepositoryInterface $orderRepository;
private LoggerInterface $logger;
// Constructor and other methods...
}
Crafting the Query to Fetch Paid Orders
Within the MyLovelyClass
, I define a method called getAndExecutePaidOrders
which accepts the current Context
as a
parameter. The process begins by creating a DateTime
object to set our desired time range - in this case, the past six
weeks.
Next, I establish a Criteria
object which allows me to specify the details of the query. I add an association to
the orderCustomer
to gain access to related customer data if needed.
The core of our query lies within the addFilter
method, which uses a MultiFilter
to combine multiple conditions
using a logical AND. The first condition is a RangeFilter
on the orderDate
to ensure we're only looking at recent
orders. The second, and crucial one, is an EqualsFilter
that specifies the technicalName
of the payment state to
be 'paid'.
// Method within MyLovelyClass
public function getAndExecutePaidOrders(Context $context): void
{
// Random date for recent orders
$startDay = new DateTime();
$startDay->modify('-3 weeks');
$criteria->addFilter(
new MultiFilter(
MultiFilter::CONNECTION_AND,
[
/**
* A random other filter
*/
new RangeFilter(
'orderDate',
[RangeFilter::GTE => $startDay->format('Y-m-d H:i:s')]
),
/**
* The filter for the state of the payment
*/
new EqualsFilter(
'transactions.stateMachineState.technicalName',
'paid' // <-- state
)
]
)
);
// Simpler alternative: using the state filter without other filters:
// $criteria->addFilter(new EqualsFilter('transactions.stateMachineState.technicalName', 'paid'))
}
Paginating Through Results
Since performance is key, especially with large datasets, I apply pagination to our query using setLimit
. I've
initially set the batch size to 50, but this can be adjusted based on specific needs. With pagination in place, I
utilize a do-while loop to iterate through all the pages of results, calling a custom
method doSomethingWithSingleOrder
for each order that's been fetched. The loop continues until no more orders are left
to process.
// Pagination setup and loop within the method
$criteria->setLimit(50); // Adjust batch size as needed
$offset = 0;
do {
// Fetching orders and processing them
} while ($orders->count() > 0);
Conclusion
This walkthrough demonstrates how I leverage Shopware 6's Criteria API to retrieve orders based on their payment state. By applying precise filters and thoughtful pagination, I efficiently handle potentially large datasets while minimizing performance impacts.
Should you implement this in your own Shopware 6 environment, remember to adapt the batch size and time range to fit your use case. With these tools in hand, you're well-equipped to manage order data programmatically, allowing for a smooth and automated workflow.
I hope this guide has illuminated the process for you. Should you have any further questions on Shopware 6's API or need more complex examples, feel free to reach out or consult the Shopware