Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Orders Order Laravel Package

baks-dev/orders-order

Laravel/Symfony модуль системных заказов: статусы заказов через OrderStatusInterface и тег baks.order.status, асинхронная обработка через Messenger воркер orders-order, интеграция с Centrifugo, миграции Doctrine, установка ресурсов baks:assets:install.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Install Dependencies:

    composer require baks-dev/orders-order baks-dev/payment baks-dev/users-address baks-dev/contacts-region baks-dev/centrifugo baks-dev/products-stocks baks-dev/delivery phpoffice/phpspreadsheet
    

    Note: Ensure php >= 8.4 and Laravel 10+ compatibility.

  2. Run Asset Installation:

    php bin/console baks:assets:install
    

    Purpose: Installs default configurations, migrations, and resources.

  3. Set Up Database:

    php bin/console doctrine:migrations:diff
    php bin/console doctrine:migrations:migrate
    

    Verify: Check migrations/ for generated SQL and inspect the orders table structure.

  4. Launch Messenger Worker:

    php bin/console messenger:consume orders-order
    

    Why: Async processing for order events (e.g., status changes, inventory updates).

  5. Test a Basic Order:

    use BaksDev\Orders\Order\Application\Service\OrderService;
    
    $orderService = app(OrderService::class);
    $order = $orderService->create([
        'user_id' => 1,
        'items' => [['product_id' => 1, 'quantity' => 2]],
    ]);
    

    Expected: Order created with default status (e.g., pending).


First Use Case: Custom Status Workflow

Goal: Add a "Hold for Approval" status to orders requiring manual review.

  1. Create a Status Class:

    // app/Orders/OrderStatus/ApprovalHoldStatus.php
    namespace App\Orders\OrderStatus;
    
    use BaksDev\Orders\Order\Type\Status\OrderStatus\OrderStatusInterface;
    use Symfony\Component\DependencyInjection\Attribute\AutoconfigureTag;
    
    #[AutoconfigureTag('baks.order.status')]
    class ApprovalHoldStatus implements OrderStatusInterface
    {
        public function getName(): string
        {
            return 'approval_hold';
        }
    
        public function canTransitionTo(string $toStatus): bool
        {
            // Allow transitions to 'approved' or 'cancelled'
            return in_array($toStatus, ['approved', 'cancelled']);
        }
    
        public function getTransitions(): array
        {
            return [
                'approved' => 'Approve Order',
                'cancelled' => 'Cancel Order',
            ];
        }
    }
    
  2. Trigger the Status:

    $orderService->transitionStatus($order->getId(), 'approval_hold');
    

    Verify: Check the database for the new status and ensure transitions are enforced.


Key Starting Points

  • Service Layer: BaksDev\Orders\Order\Application\Service\OrderService (core CRUD + workflows).
  • Status Logic: BaksDev\Orders\Order\Type\Status\OrderStatus (interfaces and base implementations).
  • Events: BaksDev\Orders\Order\Domain\Event (listen for OrderCreated, StatusChanged, etc.).
  • Centrifugo: BaksDev\Centrifugo\Client (real-time updates; see config/centrifugo.php).

Implementation Patterns

Core Workflow: Order Lifecycle

  1. Creation:

    $order = $orderService->create([
        'user_id' => $userId,
        'items' => [
            ['product_id' => 1, 'quantity' => 3],
            ['product_id' => 2, 'quantity' => 1],
        ],
        'delivery_address_id' => $addressId,
    ]);
    

    Triggers: OrderCreated event → async inventory reservation (products-stocks).

  2. Status Transitions:

    // Sync transition
    $orderService->transitionStatus($orderId, 'shipped');
    
    // Async transition (recommended for long-running tasks)
    $orderService->transitionStatusAsync($orderId, 'shipped');
    

    Hooks: Use event listeners (e.g., OrderStatusChanged) to notify users or update delivery systems.

  3. Cancellation:

    $orderService->cancel($orderId, 'Customer requested cancellation');
    

    Behavior: Releases inventory, refunds payments (if integrated with baks-dev/payment), and notifies stakeholders.


Integration Patterns

1. Inventory Sync

Leverage the products-stocks dependency to auto-reserve/release stock:

// Listen for OrderCreated
event(new OrderCreated($order));

// In the event handler:
$stockService = app(\BaksDev\Products\Stocks\Application\Service\StockService::class);
foreach ($order->getItems() as $item) {
    $stockService->reserve(
        $item->getProductId(),
        $item->getQuantity(),
        $order->getId()
    );
}

2. Delivery Coordination

Use the delivery package to create shipments when orders are shipped:

// Listen for OrderStatusChanged
if ($event->getToStatus() === 'shipped') {
    $deliveryService = app(\BaksDev\Delivery\Application\Service\DeliveryService::class);
    $deliveryService->createShipment($order->getId(), $order->getDeliveryAddress());
}

3. Real-Time Updates

Push order status changes to clients via Centrifugo:

// In your OrderStatusChanged listener:
$centrifugo = app(\BaksDev\Centrifugo\Client);
$centrifugo->publish(
    "order_updates:{$order->getId()}",
    ['status' => $event->getToStatus(), 'timestamp' => now()]
);

Frontend: Subscribe to channels in your JS app:

const channel = centrifugo.newChannel('order_updates:123');
channel.on('update', (data) => {
    console.log('Order status:', data.status);
});

4. Async Processing

Offload heavy tasks (e.g., email notifications, ERP sync) to Messenger:

// Dispatch a job
$orderNotification = new SendOrderNotification($order);
app(\Symfony\Component\Messenger\MessageBusInterface::class)->dispatch($orderNotification);

Common Architectural Patterns

Domain-Driven Design (DDD) Alignment

  • Entities: Order, OrderItem, OrderStatus (immutable domain objects).
  • Value Objects: OrderId, Money, Address (encapsulated logic).
  • Repositories: OrderRepository (abstracts persistence; extend for custom queries).

Event-Driven Architecture

  • Events: OrderCreated, StatusChanged, PaymentProcessed.
  • Listeners: React to events for side effects (e.g., send SMS, log audit trail).
  • Example:
    // app/Listeners/OrderCreatedListener.php
    class OrderCreatedListener
    {
        public function __invoke(OrderCreated $event)
        {
            // Send welcome email, update analytics, etc.
        }
    }
    

Strategy Pattern for Statuses

Extend functionality via OrderStatusInterface:

// Custom status for subscriptions
class SubscriptionPauseStatus implements OrderStatusInterface
{
    public function getName(): string { return 'subscription_paused'; }

    public function canTransitionTo(string $toStatus): bool
    {
        return $toStatus === 'subscription_resumed' || $toStatus === 'cancelled';
    }
}

Testing Patterns

  1. Unit Tests:

    public function testApprovalHoldStatusTransitions()
    {
        $status = new ApprovalHoldStatus();
        $this->assertTrue($status->canTransitionTo('approved'));
        $this->assertFalse($status->canTransitionTo('shipped'));
    }
    
  2. Feature Tests:

    public function testOrderWorkflow()
    {
        $order = $this->createOrder();
        $this->assertEquals('pending', $order->getStatus());
    
        $this->transitionStatus($order, 'approval_hold');
        $this->assertEquals('approval_hold', $order->getStatus());
    
        $this->transitionStatus($order, 'approved');
        $this->assertEquals('approved', $order->getStatus());
    }
    
  3. Messenger Tests:

    public function testAsyncStatusTransition()
    {
        $this->artisan('messenger:consume orders-order --time-limit=1')
             ->expectsOutputToContain('Order status updated');
    
        $this->transitionStatusAsync($order, 'shipped');
        $this->assertDatabaseHas('orders', ['status' => 'shipped']);
    }
    

Gotchas and Tips

Pitfalls

1. Status Transition Logic Errors

  • Issue: Custom statuses may allow invalid transitions (e.g., pendingshipped without paid).
  • Fix: Override canTransitionTo() and test exhaustively:
    public function canTransitionTo(string $toStatus): bool
    {
        $
    
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
elnasnato/laraliveui
labrodev/rest-sdk
sampaui/sampaui
babelqueue/php-sdk
facebook/capi-param-builder-php
babelqueue/symfony
hamzi/corewatch
minionfactory/raw-hydrator
hexters/coinpayment
rjcodes/rjcms
act-training/laravel-permissions-manager
alimarchal/laravel-chart-of-accounts
babenkoivan/elastic-scout-driver
mkwebdesign/filament-watchdog-v5
renatomarinho/laravel-page-speed
zedmagdy/filament-business-hours
renatovdemoura/blade-elements-ui
devgeek/beacon-admin
benjamin-rqt/data-watcher-bundle
atriumphp/atrium