fix address_type at many places; add tests for address relations

This commit is contained in:
Florian Bosdorff 2020-04-17 11:09:59 +02:00
parent 5a9dfd8561
commit 01d4cb026f
21 changed files with 267 additions and 70 deletions

View File

@ -3,6 +3,7 @@
namespace Webkul\Admin\DataGrids;
use Illuminate\Support\Facades\DB;
use Webkul\Customer\Models\CustomerAddress;
use Webkul\Ui\DataGrid\DataGrid;
use Webkul\Customer\Repositories\CustomerRepository;
@ -43,10 +44,11 @@ class AddressDataGrid extends DataGrid
{
$customer = $this->customerRepository->find(request('id'));
$queryBuilder = DB::table('customer_addresses as ca')
$queryBuilder = DB::table('addresses as ca')
->leftJoin('countries', 'ca.country', '=', 'countries.code')
->leftJoin('customers as c', 'ca.customer_id', '=', 'c.id')
->addSelect('ca.id as address_id', 'ca.company_name', 'ca.address1', 'ca.country', DB::raw('' . DB::getTablePrefix() . 'countries.name as country_name'), 'ca.state', 'ca.city', 'ca.postcode', 'ca.phone', 'ca.default_address')
->where('ca.address_type', CustomerAddress::ADDRESS_TYPE)
->where('c.id', $customer->id);
$queryBuilder = $queryBuilder->leftJoin('country_states', function($qb) {

View File

@ -3,6 +3,7 @@
namespace Webkul\Admin\DataGrids;
use Illuminate\Support\Facades\DB;
use Webkul\Sales\Models\OrderAddress;
use Webkul\Ui\DataGrid\DataGrid;
class OrderDataGrid extends DataGrid
@ -14,13 +15,13 @@ class OrderDataGrid extends DataGrid
public function prepareQueryBuilder()
{
$queryBuilder = DB::table('orders')
->leftJoin('order_address as order_address_shipping', function($leftJoin) {
->leftJoin('addresses as order_address_shipping', function($leftJoin) {
$leftJoin->on('order_address_shipping.order_id', '=', 'orders.id')
->where('order_address_shipping.address_type', 'shipping');
->where('order_address_shipping.address_type', OrderAddress::ADDRESS_TYPE_SHIPPING);
})
->leftJoin('order_address as order_address_billing', function($leftJoin) {
->leftJoin('addresses as order_address_billing', function($leftJoin) {
$leftJoin->on('order_address_billing.order_id', '=', 'orders.id')
->where('order_address_billing.address_type', 'billing');
->where('order_address_billing.address_type', OrderAddress::ADDRESS_TYPE_BILLING);
})
->addSelect('orders.id','orders.increment_id', 'orders.base_sub_total', 'orders.base_grand_total', 'orders.created_at', 'channel_name', 'status')
->addSelect(DB::raw('CONCAT(' . DB::getTablePrefix() . 'order_address_billing.first_name, " ", ' . DB::getTablePrefix() . 'order_address_billing.last_name) as billed_to'))

View File

@ -3,6 +3,7 @@
namespace Webkul\Admin\DataGrids;
use Illuminate\Support\Facades\DB;
use Webkul\Sales\Models\OrderAddress;
use Webkul\Ui\DataGrid\DataGrid;
class OrderRefundDataGrid extends DataGrid
@ -16,9 +17,9 @@ class OrderRefundDataGrid extends DataGrid
$queryBuilder = DB::table('refunds')
->select('refunds.id', 'orders.increment_id', 'refunds.state', 'refunds.base_grand_total', 'refunds.created_at')
->leftJoin('orders', 'refunds.order_id', '=', 'orders.id')
->leftJoin('order_address as order_address_billing', function($leftJoin) {
->leftJoin('addresses as order_address_billing', function($leftJoin) {
$leftJoin->on('order_address_billing.order_id', '=', 'orders.id')
->where('order_address_billing.address_type', 'billing');
->where('order_address_billing.address_type', OrderAddress::ADDRESS_TYPE_BILLING);
})
->addSelect(DB::raw('CONCAT(' . DB::getTablePrefix() . 'order_address_billing.first_name, " ", ' . DB::getTablePrefix() . 'order_address_billing.last_name) as billed_to'));

View File

@ -3,6 +3,7 @@
namespace Webkul\Admin\DataGrids;
use Illuminate\Support\Facades\DB;
use Webkul\Sales\Models\OrderAddress;
use Webkul\Ui\DataGrid\DataGrid;
class OrderShipmentsDataGrid extends DataGrid
@ -14,9 +15,9 @@ class OrderShipmentsDataGrid extends DataGrid
public function prepareQueryBuilder()
{
$queryBuilder = DB::table('shipments')
->leftJoin('order_address as order_address_shipping', function($leftJoin) {
->leftJoin('addresses as order_address_shipping', function($leftJoin) {
$leftJoin->on('order_address_shipping.order_id', '=', 'shipments.order_id')
->where('order_address_shipping.address_type', 'shipping');
->where('order_address_shipping.address_type', OrderAddress::ADDRESS_TYPE_SHIPPING);
})
->leftJoin('orders as ors', 'shipments.order_id', '=', 'ors.id')
->leftJoin('inventory_sources as is', 'shipments.inventory_source_id', '=', 'is.id')

View File

@ -658,7 +658,7 @@ class Cart
if (! $cart = $this->getCart()) {
return;
}
Event::dispatch('checkout.cart.calculate.items.tax.before', $cart);
foreach ($cart->items()->get() as $item) {
@ -1199,21 +1199,21 @@ class Cart
} else {
if (isset($billingAddressData['use_for_shipping']) && $billingAddressData['use_for_shipping']) {
$this->cartAddressRepository->create(array_merge($billingAddressData,
['address_type' => 'shipping']));
['address_type' => CartAddress::ADDRESS_TYPE_SHIPPING]));
} else {
$this->cartAddressRepository->create(array_merge($shippingAddressData,
['address_type' => 'shipping']));
['address_type' => CartAddress::ADDRESS_TYPE_SHIPPING]));
}
}
}
} else {
$this->cartAddressRepository->create(array_merge($billingAddressData, ['address_type' => 'billing']));
$this->cartAddressRepository->create(array_merge($billingAddressData, ['address_type' => CartAddress::ADDRESS_TYPE_BILLING]));
if ($cart->haveStockableItems()) {
if (isset($billingAddressData['use_for_shipping']) && $billingAddressData['use_for_shipping']) {
$this->cartAddressRepository->create(array_merge($billingAddressData, ['address_type' => 'shipping']));
$this->cartAddressRepository->create(array_merge($billingAddressData, ['address_type' => CartAddress::ADDRESS_TYPE_SHIPPING]));
} else {
$this->cartAddressRepository->create(array_merge($shippingAddressData, ['address_type' => 'shipping']));
$this->cartAddressRepository->create(array_merge($shippingAddressData, ['address_type' => CartAddress::ADDRESS_TYPE_SHIPPING]));
}
}
}

View File

@ -6,14 +6,10 @@ use Faker\Generator as Faker;
use Webkul\Checkout\Models\CartAddress;
$factory->define(CartAddress::class, function (Faker $faker) {
$now = date("Y-m-d H:i:s");
return [
'first_name' => $faker->firstName(),
'last_name' => $faker->lastName,
'email' => $faker->email,
'created_at' => $now,
'updated_at' => $now,
'address_type' => 'billing',
'address_type' => CartAddress::ADDRESS_TYPE_BILLING,
];
});

View File

@ -11,6 +11,13 @@ class CartAddress extends Address implements CartAddressContract
public const ADDRESS_TYPE_SHIPPING = 'cart_address_shipping';
public const ADDRESS_TYPE_BILLING = 'cart_address_billing';
/**
* @var array default values
*/
protected $attributes = [
'address_type' => self::ADDRESS_TYPE_BILLING,
];
/**
* The "booted" method of the model.
*
@ -18,7 +25,7 @@ class CartAddress extends Address implements CartAddressContract
*/
protected static function booted()
{
static::addGlobalScope('address_type', function (Builder $builder) {
static::addGlobalScope('address_type', static function (Builder $builder) {
$builder->whereIn('address_type', [
self::ADDRESS_TYPE_BILLING,
self::ADDRESS_TYPE_SHIPPING

View File

@ -24,6 +24,7 @@ class CartShippingRate extends Model implements CartShippingRateContract
*/
public function shipping_address()
{
return $this->belongsTo(CartAddressProxy::modelClass());
return $this->belongsTo(CartAddressProxy::modelClass(), 'cart_address_id')
->where('address_type', CartAddress::ADDRESS_TYPE_SHIPPING);
}
}

View File

@ -4,6 +4,11 @@ use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Schema;
use Webkul\Checkout\Models\CartAddress;
use Webkul\Checkout\Models\CartShippingRate;
use Webkul\Sales\Models\Invoice;
use Webkul\Sales\Models\OrderAddress;
use Webkul\Sales\Models\Shipment;
class AddTableAddresses extends Migration
{
@ -14,6 +19,8 @@ class AddTableAddresses extends Migration
*/
public function up()
{
DB::beginTransaction();
Schema::create('addresses', function (Blueprint $table) {
$table->increments('id');
$table->string('address_type');
@ -39,6 +46,8 @@ class AddTableAddresses extends Migration
->default(false)
->comment('only for customer_addresses');
$table->json('additional')->nullable();
$table->timestamps();
$table->foreign(['customer_id'])->references('id')->on('customers');
@ -46,13 +55,17 @@ class AddTableAddresses extends Migration
$table->foreign(['order_id'])->references('id')->on('orders');
});
$this->insertCustomerAddresses();
$this->insertCartAddresses();
$this->insertOrderAddresses();
$this->migrateCustomerAddresses();
$this->migrateCartAddresses();
$this->migrateOrderAddresses();
$this->migrateForeignKeys();
Schema::drop('customer_addresses');
Schema::drop('cart_address');
Schema::drop('order_address');
DB::commit();
}
/**
@ -65,7 +78,7 @@ class AddTableAddresses extends Migration
throw new Exception('you cannot revert this migration: data would be lost');
}
private function insertCustomerAddresses(): void
private function migrateCustomerAddresses(): void
{
$dbPrefix = DB::getTablePrefix();
@ -86,6 +99,7 @@ class AddTableAddresses extends Migration
email,
phone,
default_address,
additional,
created_at,
updated_at
)
@ -105,6 +119,7 @@ class AddTableAddresses extends Migration
null,
phone,
default_address,
JSON_INSERT('{}', '$.old_customer_address_id', id),
created_at,
updated_at
FROM customer_addresses ca;
@ -113,7 +128,7 @@ SQL;
DB::unprepared($insertCustomerAddresses);
}
private function insertCartAddresses(): void
private function migrateCartAddresses(): void
{
$dbPrefix = DB::getTablePrefix();
@ -134,12 +149,12 @@ SQL;
country,
email,
phone,
default_address,
additional,
created_at,
updated_at
)
SELECT
(CASE ca.address_type='billing' THEN "cart_address_billing" ELSE "cart_address_shipping" END),
(CASE WHEN ca.address_type='billing' THEN "cart_address_billing" ELSE "cart_address_shipping" END),
customer_id,
cart_id,
first_name,
@ -154,7 +169,7 @@ SQL;
country,
email,
phone,
default_address,
JSON_INSERT('{}', '$.old_cart_address_id', id),
created_at,
updated_at
FROM cart_address ca;
@ -163,7 +178,7 @@ SQL;
DB::unprepared($insertCustomerAddresses);
}
private function insertOrderAddresses(): void
private function migrateOrderAddresses(): void
{
$dbPrefix = DB::getTablePrefix();
@ -184,17 +199,17 @@ SQL;
country,
email,
phone,
default_address,
additional,
created_at,
updated_at
)
SELECT
(CASE ca.address_type='billing' THEN "order_address_billing" ELSE "order_address_shipping" END),
(CASE WHEN oa.address_type='billing' THEN "order_address_billing" ELSE "order_address_shipping" END),
customer_id,
order_id,
first_name,
last_name,
(SELECT gender FROM customers c WHERE c.id=os.customer_id),
(SELECT gender FROM customers c WHERE c.id=oa.customer_id),
company_name,
address1,
address2,
@ -204,7 +219,7 @@ SQL;
country,
email,
phone,
default_address,
JSON_INSERT('{}', '$.old_Order_address_id', id),
created_at,
updated_at
FROM order_address oa;
@ -212,4 +227,49 @@ SQL;
DB::unprepared($insertCustomerAddresses);
}
private function migrateForeignKeys(): void
{
Schema::table('cart_shipping_rates', static function (Blueprint $table) {
$table->dropForeign(['cart_address_id']);
CartAddress::query()
->orderBy('id', 'asc') // for some reason each() needs an orderBy in before
->each(static function ($row) {
CartShippingRate::query()
->where('cart_address_id', $row->additional['old_cart_address_id'])
->update(['cart_address_id' => $row->id]);
});
$table->foreign(['cart_address_id'])->references('id')->on('addresses');
});
Schema::table('invoices', static function (Blueprint $table) {
$table->dropForeign(['order_address_id']);
OrderAddress::query()
->orderBy('id', 'asc') // for some reason each() needs an orderBy in before
->each(static function ($row) {
Invoice::query()
->where('order_address_id', $row->additional['old_order_address_id'])
->update(['order_address_id' => $row->id]);
});
$table->foreign(['order_address_id'])->references('id')->on('addresses');
});
Schema::table('shipments', static function (Blueprint $table) {
$table->dropForeign(['order_address_id']);
OrderAddress::query()
->orderBy('id', 'asc') // for some reason each() needs an orderBy in before
->each(static function ($row) {
Shipment::query()
->where('order_address_id', $row->additional['old_order_address_id'])
->update(['order_address_id' => $row->id]);
});
$table->foreign(['order_address_id'])->references('id')->on('addresses');
});
}
}

View File

@ -5,10 +5,13 @@ namespace Webkul\Core\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Webkul\Customer\Models\Customer;
abstract class Address extends Model
{
protected $table = 'addresses';
protected $guarded = [
'id',
'created_at',
@ -16,6 +19,7 @@ abstract class Address extends Model
];
protected $fillable = [
'address_type',
'customer_id',
'cart_id',
'order_id',
@ -32,12 +36,17 @@ abstract class Address extends Model
'email',
'phone',
'default_address',
'additional',
];
protected $casts = [
'additional' => 'array',
];
/**
* Get all of the attributes for the attribute groups.
*/
public function getNameAttribute()
public function getNameAttribute(): string
{
return $this->first_name . ' ' . $this->last_name;
}
@ -45,7 +54,7 @@ abstract class Address extends Model
/**
* Get the customer record associated with the address.
*/
public function customer()
public function customer(): BelongsTo
{
return $this->belongsTo(Customer::class);
}

View File

@ -7,8 +7,6 @@ use Webkul\Customer\Models\Customer;
use Webkul\Customer\Models\CustomerAddress;
$factory->define(CustomerAddress::class, function (Faker $faker) {
$now = date("Y-m-d H:i:s");
// use an locale from a country in europe so the vat id can be generated
$fakerIt = \Faker\Factory::create('it_IT');
@ -27,8 +25,7 @@ $factory->define(CustomerAddress::class, function (Faker $faker) {
'postcode' => $faker->postcode,
'phone' => $faker->e164PhoneNumber,
'default_address' => array_random([0, 1]),
'created_at' => $now,
'updated_at' => $now,
'address_type' => CustomerAddress::ADDRESS_TYPE,
];
});

View File

@ -10,6 +10,13 @@ class CustomerAddress extends Address implements CustomerAddressContract
{
public const ADDRESS_TYPE = 'customer';
/**
* @var array default values
*/
protected $attributes = [
'address_type' => self::ADDRESS_TYPE,
];
/**
* The "booted" method of the model.
*
@ -17,7 +24,7 @@ class CustomerAddress extends Address implements CustomerAddressContract
*/
protected static function booted()
{
static::addGlobalScope('address_type', function (Builder $builder) {
static::addGlobalScope('address_type', static function (Builder $builder) {
$builder->where('address_type', self::ADDRESS_TYPE);
});
}

View File

@ -22,7 +22,7 @@ $factory->define(OrderAddress::class, function (Faker $faker) {
'city' => $customerAddress->city,
'postcode' => $customerAddress->postcode,
'phone' => $customerAddress->phone,
'address_type' => 'billing',
'address_type' => OrderAddress::ADDRESS_TYPE_BILLING,
'order_id' => function () {
return factory(Order::class)->create()->id;
},
@ -30,5 +30,5 @@ $factory->define(OrderAddress::class, function (Faker $faker) {
});
$factory->state(OrderAddress::class, 'shipping', [
'address_type' => 'shipping',
'address_type' => OrderAddress::ADDRESS_TYPE_SHIPPING,
]);

View File

@ -34,7 +34,8 @@ class Invoice extends Model implements InvoiceContract
/**
* Get the invoice items record associated with the invoice.
*/
public function items() {
public function items()
{
return $this->hasMany(InvoiceItemProxy::modelClass())->whereNull('parent_id');
}
@ -59,6 +60,7 @@ class Invoice extends Model implements InvoiceContract
*/
public function address()
{
return $this->belongsTo(OrderAddressProxy::modelClass(), 'order_address_id');
return $this->belongsTo(OrderAddressProxy::modelClass(), 'order_address_id')
->where('address_type', OrderAddress::ADDRESS_TYPE_BILLING);
}
}

View File

@ -8,6 +8,14 @@ use Webkul\Sales\Contracts\Order as OrderContract;
class Order extends Model implements OrderContract
{
public const STATUS_PENDING = 'pending';
public const STATUS_PENDING_PAYMENT = 'pending_payment';
public const STATUS_PROCESSING = 'processing';
public const STATUS_COMPLETED = 'completed';
public const STATUS_CANCELED = 'canceled';
public const STATUS_CLOSED = 'closed';
public const STATUS_FRAUD = 'fraud';
protected $guarded = [
'id',
'items',
@ -21,13 +29,13 @@ class Order extends Model implements OrderContract
];
protected $statusLabel = [
'pending' => 'Pending',
'pending_payment' => 'Pending Payment',
'processing' => 'Processing',
'completed' => 'Completed',
'canceled' => 'Canceled',
'closed' => 'Closed',
'fraud' => 'Fraud',
self::STATUS_PENDING => 'Pending',
self::STATUS_PENDING_PAYMENT => 'Pending Payment',
self::STATUS_PROCESSING => 'Processing',
self::STATUS_COMPLETED => 'Completed',
self::STATUS_CANCELED => 'Canceled',
self::STATUS_CLOSED => 'Closed',
self::STATUS_FRAUD => 'Fraud',
];
/**
@ -180,7 +188,7 @@ class Order extends Model implements OrderContract
*
* @return boolean
*/
public function haveStockableItems()
public function haveStockableItems(): bool
{
foreach ($this->items as $item) {
if ($item->getTypeInstance()->isStockable()) {
@ -193,10 +201,12 @@ class Order extends Model implements OrderContract
/**
* Checks if new shipment is allow or not
*
* @return bool
*/
public function canShip()
public function canShip(): bool
{
if ($this->status == 'fraud') {
if ($this->status === self::STATUS_FRAUD) {
return false;
}
@ -211,10 +221,12 @@ class Order extends Model implements OrderContract
/**
* Checks if new invoice is allow or not
*
* @return bool
*/
public function canInvoice()
public function canInvoice(): bool
{
if ($this->status == 'fraud') {
if ($this->status === self::STATUS_FRAUD) {
return false;
}
@ -229,10 +241,12 @@ class Order extends Model implements OrderContract
/**
* Checks if order can be canceled or not
*
* @return bool
*/
public function canCancel()
public function canCancel(): bool
{
if ($this->status == 'fraud') {
if ($this->status === self::STATUS_FRAUD) {
return false;
}
@ -247,10 +261,12 @@ class Order extends Model implements OrderContract
/**
* Checks if order can be refunded or not
*
* @return bool
*/
public function canRefund()
public function canRefund(): bool
{
if ($this->status == 'fraud') {
if ($this->status === self::STATUS_FRAUD) {
return false;
}

View File

@ -11,6 +11,13 @@ class OrderAddress extends Address implements OrderAddressContract
public const ADDRESS_TYPE_SHIPPING = 'order_address_shipping';
public const ADDRESS_TYPE_BILLING = 'order_address_billing';
/**
* @var array default values
*/
protected $attributes = [
'address_type' => self::ADDRESS_TYPE_BILLING,
];
/**
* The "booted" method of the model.
*
@ -18,7 +25,7 @@ class OrderAddress extends Address implements OrderAddressContract
*/
protected static function booted()
{
static::addGlobalScope('address_type', function (Builder $builder) {
static::addGlobalScope('address_type', static function (Builder $builder) {
$builder->whereIn('address_type', [
self::ADDRESS_TYPE_BILLING,
self::ADDRESS_TYPE_SHIPPING

View File

@ -51,6 +51,7 @@ class Shipment extends Model implements ShipmentContract
*/
public function address()
{
return $this->belongsTo(OrderAddressProxy::modelClass(), 'order_address_id');
return $this->belongsTo(OrderAddressProxy::modelClass(), 'order_address_id')
->where('address_type', OrderAddress::ADDRESS_TYPE_SHIPPING);
}
}

View File

@ -23,7 +23,7 @@ class FlatRate extends AbstractShipping
/**
* Returns rate for flatrate
*
* @return array
* @return CartShippingRate|false
*/
public function calculate()
{

View File

@ -22,7 +22,7 @@ class Free extends AbstractShipping
/**
* Returns rate for flatrate
*
* @return array
* @return CartShippingRate|false
*/
public function calculate()
{

View File

@ -67,13 +67,13 @@ class OrderCest
$I->seeResponseCodeIsSuccessful();
$I->seeRecord(CartAddress::class, array_merge($addressData, [
'address_type' => 'shipping',
'address_type' => CartAddress::ADDRESS_TYPE_SHIPPING,
'cart_id' => $mocks['cart']->id,
'customer_id' => $mocks['customer']->id,
]));
$I->seeRecord(CartAddress::class, array_merge($addressData, [
'address_type' => 'billing',
'address_type' => CartAddress::ADDRESS_TYPE_BILLING,
'cart_id' => $mocks['cart']->id,
'customer_id' => $mocks['customer']->id,
]));
@ -128,13 +128,13 @@ class OrderCest
$I->seeRecord(OrderAddress::class, array_merge($addressData, [
'order_id' => $order->id,
'address_type' => 'shipping',
'address_type' => OrderAddress::ADDRESS_TYPE_SHIPPING,
'customer_id' => $mocks['customer']->id,
]));
$I->seeRecord(OrderAddress::class, array_merge($addressData, [
'order_id' => $order->id,
'address_type' => 'billing',
'address_type' => OrderAddress::ADDRESS_TYPE_BILLING,
'customer_id' => $mocks['customer']->id,
]));

View File

@ -0,0 +1,89 @@
<?php
namespace Tests\Unit\Core;
use UnitTester;
use Webkul\Checkout\Models\Cart;
use Webkul\Checkout\Models\CartAddress;
use Webkul\Checkout\Models\CartShippingRate;
use Webkul\Customer\Models\Customer;
use Webkul\Customer\Models\CustomerAddress;
use Webkul\Sales\Models\Invoice;
use Webkul\Sales\Models\Order;
use Webkul\Sales\Models\OrderAddress;
use Webkul\Sales\Models\Shipment;
use Webkul\Shipping\Carriers\Free;
class AddressCest
{
public function testCustomerAddressRelations(UnitTester $I): void
{
/** @var Customer $customer1 */
$customer1 = $I->have(Customer::class);
CustomerAddress::create(['customer_id' => $customer1->id]);
/** @var Customer $customer2 */
$customer2 = $I->have(Customer::class);
$address1 = CustomerAddress::create(['customer_id' => $customer2->id]);
$customer2->refresh();
$I->assertCount(1, $customer2->addresses);
$I->assertEquals($address1->id, $customer2->addresses[0]->id);
$I->assertNull($customer2->default_address);
$address2 = CustomerAddress::create(['customer_id' => $customer2->id, 'default_address' => true]);
$customer2->refresh();
$I->assertCount(2, $customer2->addresses);
$I->assertEquals($address2->id, $customer2->default_address->id);
}
public function testCartAddressRelations(UnitTester $I): void
{
/** @var Cart $cart */
$cart = $I->have(Cart::class);
$address1 = CartAddress::create(['cart_id' => $cart->id]);
$address2 = CartAddress::create([
'cart_id' => $cart->id,
'address_type' => CartAddress::ADDRESS_TYPE_SHIPPING
]);
$cart->refresh();
$I->assertNotNull($address1->address_type);
$I->assertEquals($address1->id, $cart->billing_address->id);
$I->assertEquals($address2->id, $cart->shipping_address->id);
/** @var CartShippingRate $freeShipping */
$freeShipping = (new Free())->calculate();
$freeShipping->cart_address_id = $address2->id;
$freeShipping->saveOrFail();
$freeShipping->refresh();
$I->assertEquals($address2->id, $freeShipping->shipping_address->id);
}
public function testOrderAddressRelations(UnitTester $I): void
{
/** @var Order $order */
$order = $I->have(Order::class);
$address1 = OrderAddress::create(['order_id' => $order->id]);
$address2 = OrderAddress::create([
'order_id' => $order->id,
'address_type' => OrderAddress::ADDRESS_TYPE_SHIPPING
]);
$order->refresh();
$I->assertNotNull($address1->address_type);
$I->assertEquals($address1->id, $order->billing_address->id);
$I->assertEquals($address2->id, $order->shipping_address->id);
/** @var Shipment $shipment */
$shipment = Shipment::create(['order_address_id' => $address2->id]);
$I->assertEquals($address2->id, $shipment->address->id);
/** @var Invoice $invoice */
$invoice = Invoice::create(['order_id' => $order->id, 'order_address_id' => $address1->id]);
$I->assertEquals($address1->id, $invoice->address->id);
}
}