with('lines') ->where('id', $id->value) ->first(); if (! $eloquentOrder) { return null; } return $this->toEntity($eloquentOrder); } #[\Override] public function persist(DomainOrder $order): void { $eloquentOrder = Order::query() ->where('id', $order->id->value->toString()) ->firstOrNew(); $eloquentOrder->id = $order->id->value->toString(); $eloquentOrder->shop_id = $order->shopId->value->toString(); $eloquentOrder->reference = $order->reference; $eloquentOrder->employee = clone $order->employee; $eloquentOrder->delivery_address = clone $order->deliveryAddress; $eloquentOrder->pickup_day = Carbon::instance($order->pickupTimeSlot->getAt()); $eloquentOrder->status = $order->status; $eloquentOrder->total = clone $order->getTotal(); $eloquentOrder->save(); OrderLine::query() ->where('order_id', $order->id->value->toString()) ->delete(); $linesToInsert = []; $now = now(); foreach ($order->getLines() as $line) { $eloquentOrderLine = new OrderLine(); $eloquentOrderLine->order_id = $order->id->value->toString(); $eloquentOrderLine->product = clone $line->product; $eloquentOrderLine->quantity = $line->quantity; $eloquentOrderLine->total_ttc = clone $line->totalTtc; // Use values directly from the domain OrderLine $eloquentOrderLine->tax_rate = $line->product->taxRate; $eloquentOrderLine->unit_price = clone $line->unitPriceHt; $eloquentOrderLine->unit_tax = clone $line->unitTax; $eloquentOrderLine->unit_discount = clone $line->unitDiscount; $eloquentOrderLine->total_discount = clone $line->totalDiscount; $eloquentOrderLine->total_ht = clone $line->totalHt; $eloquentOrderLine->total_tax = clone $line->totalTax; $attributes = $eloquentOrderLine->getAttributes(); $attributes['created_at'] = $now; $attributes['updated_at'] = $now; $linesToInsert[] = $attributes; } if (! empty($linesToInsert)) { OrderLine::query()->insert($linesToInsert); } } #[\Override] public function delete(DomainOrder $order): void { Order::query() ->where('id', $order->id->value) ->delete(); } /** @return array */ public function getAll(): array { return Order::query() ->with('lines') ->get() ->map(fn (Order $eloquentOrder) => $this->toEntity($eloquentOrder)) ->all(); } private function toEntity(Order $model): DomainOrder { $lines = $model->lines->map(function (OrderLine $line) { return new DomainOrderLine( product: $line->product, quantity: $line->quantity, unitPriceHt: $line->unit_price, unitDiscount: $line->unit_discount, unitTax: $line->unit_tax, totalHt: $line->total_ht, totalDiscount: $line->total_discount, totalTax: $line->total_tax, totalTtc: $line->total_ttc ); })->all(); if ($model->shop === null) { throw new \UnexpectedValueException('Order missing shop'); } if ($model->employee === null) { throw new \UnexpectedValueException('Order missing employee'); } return new DomainOrder( id: $model->getId(), shopId: new ShopId(Uuid::fromString((string) $model->shop_id)), reference: $model->reference, employee: clone $model->employee, deliveryAddress: clone $model->delivery_address, pickupTimeSlot: new PickupTimeSlot( $model->pickup_day ? CarbonImmutable::instance($model->pickup_day) : CarbonImmutable::now(), CarbonInterval::minutes(PickupTimeSlot::LENGTH) ), status: $model->status, total: clone $model->total, lines: $lines ); } }