add unified address-table and handling for models

This commit is contained in:
Florian Bosdorff 2020-04-16 21:13:19 +02:00
parent cce548f2cd
commit 5a9dfd8561
7 changed files with 322 additions and 78 deletions

View File

@ -48,7 +48,7 @@ class Cart extends Model implements CartContract
*/
public function billing_address()
{
return $this->addresses()->where('address_type', 'billing');
return $this->addresses()->where('address_type', CartAddress::ADDRESS_TYPE_BILLING);
}
/**
@ -64,7 +64,7 @@ class Cart extends Model implements CartContract
*/
public function shipping_address()
{
return $this->addresses()->where('address_type', 'shipping');
return $this->addresses()->where('address_type', CartAddress::ADDRESS_TYPE_SHIPPING);
}
/**

View File

@ -2,29 +2,29 @@
namespace Webkul\Checkout\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Builder;
use Webkul\Checkout\Contracts\CartAddress as CartAddressContract;
use Webkul\Core\Models\Address;
class CartAddress extends Model implements CartAddressContract
class CartAddress extends Address implements CartAddressContract
{
protected $table = 'cart_address';
public const ADDRESS_TYPE_SHIPPING = 'cart_address_shipping';
public const ADDRESS_TYPE_BILLING = 'cart_address_billing';
protected $fillable = [
'first_name',
'last_name',
'email',
'company_name',
'vat_id',
'address1',
'city',
'state',
'postcode',
'country',
'phone',
'address_type',
'cart_id',
'customer_id',
];
/**
* The "booted" method of the model.
*
* @return void
*/
protected static function booted()
{
static::addGlobalScope('address_type', function (Builder $builder) {
$builder->whereIn('address_type', [
self::ADDRESS_TYPE_BILLING,
self::ADDRESS_TYPE_SHIPPING
]);
});
}
/**
* Get the shipping rates for the cart address.
@ -35,10 +35,10 @@ class CartAddress extends Model implements CartAddressContract
}
/**
* Get all of the attributes for the attribute groups.
* Get the cart record associated with the address.
*/
public function getNameAttribute()
public function cart()
{
return $this->first_name . ' ' . $this->last_name;
return $this->belongsTo(Cart::class);
}
}

View File

@ -0,0 +1,215 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Schema;
class AddTableAddresses extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('addresses', function (Blueprint $table) {
$table->increments('id');
$table->string('address_type');
$table->unsignedInteger('customer_id')->nullable()->comment('null if guest checkout');
$table->unsignedInteger('cart_id')->nullable()->comment('only for cart_addresses');
$table->unsignedInteger('order_id')->nullable()->comment('only for order_addresses');
$table->string('first_name');
$table->string('last_name');
$table->string('gender')->nullable();
$table->string('company_name')->nullable();
$table->string('address1');
$table->string('address2')->nullable();
$table->string('postcode');
$table->string('city');
$table->string('state');
$table->string('country');
$table->string('email')->nullable();
$table->string('phone')->nullable();
$table->string('vat_id')->nullable();
$table->boolean('default_address')
->default(false)
->comment('only for customer_addresses');
$table->timestamps();
$table->foreign(['customer_id'])->references('id')->on('customers');
$table->foreign(['cart_id'])->references('id')->on('cart');
$table->foreign(['order_id'])->references('id')->on('orders');
});
$this->insertCustomerAddresses();
$this->insertCartAddresses();
$this->insertOrderAddresses();
Schema::drop('customer_addresses');
Schema::drop('cart_address');
Schema::drop('order_address');
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
throw new Exception('you cannot revert this migration: data would be lost');
}
private function insertCustomerAddresses(): void
{
$dbPrefix = DB::getTablePrefix();
$insertCustomerAddresses = <<< SQL
INSERT INTO ${dbPrefix}addresses(
address_type,
customer_id,
first_name,
last_name,
gender,
company_name,
address1,
address2,
postcode,
city,
state,
country,
email,
phone,
default_address,
created_at,
updated_at
)
SELECT
"customer",
customer_id,
first_name,
last_name,
(SELECT gender FROM customers c WHERE c.id=ca.customer_id),
company_name,
address1,
address2,
postcode,
city,
state,
country,
null,
phone,
default_address,
created_at,
updated_at
FROM customer_addresses ca;
SQL;
DB::unprepared($insertCustomerAddresses);
}
private function insertCartAddresses(): void
{
$dbPrefix = DB::getTablePrefix();
$insertCustomerAddresses = <<< SQL
INSERT INTO ${dbPrefix}addresses(
address_type,
customer_id,
cart_id,
first_name,
last_name,
gender,
company_name,
address1,
address2,
postcode,
city,
state,
country,
email,
phone,
default_address,
created_at,
updated_at
)
SELECT
(CASE ca.address_type='billing' THEN "cart_address_billing" ELSE "cart_address_shipping" END),
customer_id,
cart_id,
first_name,
last_name,
(SELECT gender FROM customers c WHERE c.id=ca.customer_id),
company_name,
address1,
address2,
postcode,
city,
state,
country,
email,
phone,
default_address,
created_at,
updated_at
FROM cart_address ca;
SQL;
DB::unprepared($insertCustomerAddresses);
}
private function insertOrderAddresses(): void
{
$dbPrefix = DB::getTablePrefix();
$insertCustomerAddresses = <<< SQL
INSERT INTO ${dbPrefix}addresses(
address_type,
customer_id,
order_id,
first_name,
last_name,
gender,
company_name,
address1,
address2,
postcode,
city,
state,
country,
email,
phone,
default_address,
created_at,
updated_at
)
SELECT
(CASE ca.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),
company_name,
address1,
address2,
postcode,
city,
state,
country,
email,
phone,
default_address,
created_at,
updated_at
FROM order_address oa;
SQL;
DB::unprepared($insertCustomerAddresses);
}
}

View File

@ -0,0 +1,52 @@
<?php
namespace Webkul\Core\Models;
use Illuminate\Database\Eloquent\Model;
use Webkul\Customer\Models\Customer;
abstract class Address extends Model
{
protected $guarded = [
'id',
'created_at',
'updated_at',
];
protected $fillable = [
'customer_id',
'cart_id',
'order_id',
'first_name',
'last_name',
'gender',
'company_name',
'address1',
'address2',
'postcode',
'city',
'state',
'country',
'email',
'phone',
'default_address',
];
/**
* Get all of the attributes for the attribute groups.
*/
public function getNameAttribute()
{
return $this->first_name . ' ' . $this->last_name;
}
/**
* Get the customer record associated with the address.
*/
public function customer()
{
return $this->belongsTo(Customer::class);
}
}

View File

@ -2,34 +2,23 @@
namespace Webkul\Customer\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Builder;
use Webkul\Core\Models\Address;
use Webkul\Customer\Contracts\CustomerAddress as CustomerAddressContract;
class CustomerAddress extends Model implements CustomerAddressContract
class CustomerAddress extends Address implements CustomerAddressContract
{
protected $table = 'customer_addresses';
protected $fillable = [
'customer_id',
'company_name',
'vat_id',
'address1',
'address2',
'country',
'state',
'city',
'postcode',
'phone',
'default_address',
'first_name',
'last_name',
];
public const ADDRESS_TYPE = 'customer';
/**
* Get the customer address full name.
* The "booted" method of the model.
*
* @return void
*/
public function getNameAttribute()
protected static function booted()
{
return $this->first_name . ' ' . $this->last_name;
static::addGlobalScope('address_type', function (Builder $builder) {
$builder->where('address_type', self::ADDRESS_TYPE);
});
}
}

View File

@ -140,7 +140,7 @@ class Order extends Model implements OrderContract
*/
public function billing_address()
{
return $this->addresses()->where('address_type', 'billing');
return $this->addresses()->where('address_type', OrderAddress::ADDRESS_TYPE_BILLING);
}
/**
@ -156,7 +156,7 @@ class Order extends Model implements OrderContract
*/
public function shipping_address()
{
return $this->addresses()->where('address_type', 'shipping');
return $this->addresses()->where('address_type', OrderAddress::ADDRESS_TYPE_SHIPPING);
}
/**

View File

@ -2,47 +2,35 @@
namespace Webkul\Sales\Models;
use Illuminate\Database\Eloquent\Model;
use Webkul\Customer\Models\Customer;
use Webkul\Core\Models\Address;
use Webkul\Sales\Contracts\OrderAddress as OrderAddressContract;
use Illuminate\Database\Eloquent\Builder;
class OrderAddress extends Model implements OrderAddressContract
class OrderAddress extends Address implements OrderAddressContract
{
protected $table = 'order_address';
protected $guarded = ['id', 'created_at', 'updated_at'];
protected $fillable = [
'first_name',
'last_name',
'email',
'company_name',
'vat_id',
'address1',
'address2',
'city',
'state',
'postcode',
'country',
'phone',
'address_type',
'cart_id',
'customer_id',
];
public const ADDRESS_TYPE_SHIPPING = 'order_address_shipping';
public const ADDRESS_TYPE_BILLING = 'order_address_billing';
/**
* Get of the customer fullname.
* The "booted" method of the model.
*
* @return void
*/
public function getNameAttribute()
protected static function booted()
{
return $this->first_name . ' ' . $this->last_name;
static::addGlobalScope('address_type', function (Builder $builder) {
$builder->whereIn('address_type', [
self::ADDRESS_TYPE_BILLING,
self::ADDRESS_TYPE_SHIPPING
]);
});
}
/**
* Get the customer record associated with the order.
* Get the order record associated with the address.
*/
public function customer()
public function order()
{
return $this->belongsTo(Customer::class);
return $this->belongsTo(Order::class);
}
}