Orders
Models, Enums
Order
Fields
Name | Type | Notes |
---|---|---|
id | autoinc | |
number | string(32) | See Order Number Generators |
status | OrderStatus | enum |
user_id | int (User object via the user relation) |
|
billpayer_id | int (BillPayer via the billPayer relation |
|
shipping_address_id | int (ShippingAddress via the shippingAddress relation) |
|
notes | text |
OrderItem
Name | Type | Notes |
---|---|---|
id | autoinc | |
order_id | int (Order via the order relation |
|
product_type | string | |
product_id | int | |
name | string | The product name at the moment of buying |
quantity | integer | |
price | decimal(15, 4) |
The product object (Buyable
) can be retrieved via the product
relationship which is a
Laravel morphTo
type:
$orderItem->product
OrderStatus
This is an enum, with these values out of the box:
OrderStatus::values();
//=> [
// "pending", <- default
// "completed",
// "cancelled",
// ]
Beginning with v2.1, it is possible to obtain whether an order status is open:
$order->status->isOpen();
// true if `pending`, false otherwise
The order status class can also give you a list of open statuses:
OrderStatus::getOpenStatuses();
// => ["pending"]
Creating Orders Using Models
Orders can be created simply by creating the appropriate eloquent models. This gives you a complete control over the creation process.
use Vanilo\Product\Model\Product;
use Vanilo\Order\Model\Order;
$order = Order::create([
'number' => 'PO123456'
]);
$order->getAttributes();
//=> [
// "status" => "pending",
// "number" => "PO123456",
// "updated_at" => "2017-12-10 13:47:40",
// "created_at" => "2017-12-10 13:47:40",
// "id" => 1,
// ]
$product = Product::findBySku('DLL-74237');
$order->items()->create([
'product_type' => 'product',
'product_id' => $product->id,
'price' => $product->price,
'name' => $product->name,
'quantity' => 1,
]);
dump($order->items);
//=> Illuminate\Database\Eloquent\Collection {#1074
// all: [
// Vanilo\Order\Models\OrderItem {#1072
// id: 1,
// order_id: 1,
// product_type: "product",
// product_id: 2,
// name: "Dell Latitude E7240 Laptop",
// quantity: 1,
// price: "799.0000",
// created_at: "2017-12-10 13:52:59",
// updated_at: "2017-12-10 13:52:59",
// },
// ],
// }
Creating Orders With Factory
Compared to simple model based order creation, order factory handles all the underlying details of orders so that you only have to pass an array of attributes.
The most minimalistic way of creating an order:
use Vanilo\Order\Contracts\OrderFactory;
use Vanilo\Product\Model\Product;
// Let Laravel to create the factory from the interface:
$factory = app(OrderFactory::class);
$factory->createFromDataArray([], [
[
'product' => Product::find(1)
]
]);
The createFromDataArray(array $data, array $items)
method takes two
arrays: $data
with order's data and the $items
.
Setting Order Data
The $data
parameter accepts any attribute the Order
model has.
Order Number Generation
Order numbers are generated by service classes. The order module
contains 2 generators (time_hash
and sequential_number
) out of the
box, but you can easily add your own implementation as well.
Use the vanilo.order.number.generator
configuration to select the generator.
Sequential Number
Generates a sequential order number like PO-0001.
To use it set: config('vanilo.order.number.generator', 'sequential_number');
Settings:
config('vanilo.order.number.sequential_number', [
'start_sequence_from' => 1,
'prefix' => 'PO-',
'pad_length' => 4,
'pad_string' => '0'
]);
Time Hash
This generates a unique sequence of letters based on the current (micro)time like 4ob-1hau-bzf4.
To use it set: config('vanilo.order.number.generator', 'time_hash');
Settings:
config('vanilo.order.number.time_hash', [
'high_variance' => false, // generates a longer number, use when orders/sec > 20
'start_base_date' => '2000-01-01',
'uppercase' => false
]);
Setting Order Status
If you omit setting an order status then the default value will be used, that
comes from the OrderStatus
enum class:
echo OrderStatus::defaultValue();
// "pending"
To change the default status, refer to the enums page.
If you want to set the status you need to use one of the possible values
of the OrderStatus
enum:
$orderData = [
'status' => OrderStatus::COMPLETED
];
$factory->createFromDataArray($orderData, $items);
// OrderStatus objects are accepted as well:
$orderData = [
'status' => new OrderStatus(OrderStatus::CANCELLED)
];
$factory->createFromDataArray($orderData, $items);
Customizing Order Statuses
To customize order statuses, refer to the enums page.
Additionally, you can tell the class if the new order status you added represents an open status,
by adding it to the static $openStatuses
array in your new class:
class MyOrderStatus extends OrderStatus
{
const CONFIRMED = 'confirmed';
protected static $openStatuses = [self::PENDING, self::CONFIRMED];
}
Setting The User
In case you don't pass user_id
in the array, the currently
authenticated user's id will automatically be inserted.
Setting Order Items
The $items
parameter expects an array of items. Each item in the array
should consist of an array with the OrderItem
model's attributes.
$item = [
'product_type' => 'product',
'product_id' => 1,
'price' => 799.70,
'name' => 'Dell Latitude E7240 Laptop',
'quantity' => 1,
];
$factory->createFromDataArray([], [$item]);
If you omit quantity
, it'll default to 1.
Instead of passing all the item details, you can also directly pass a
product object (any Buyable
actually) with the product
key:
$product = Product::findBySku('DLL-74237');
$item = [
'product' => $product,
'quantity' => 2
];
$factory->createFromDataArray([], [$item]);
Events
If you create an order with the factory, an OrderWasCreated
event gets
fired. The underlying order can be obtained as follows:
$event->getOrder();
The OrderWasCreated
event DOESN'T GET FIRED if you simply create
an order with the models. Make sure you fire the event in such cases:
event(new OrderWasCreated($order));
Further events (added with v0.4):
-
OrderWasCompleted
-
OrderWasCancelled