Skip to content

Commit

Permalink
Added the default_billing_address_id & `default_shipping_address_id…
Browse files Browse the repository at this point in the history
…` fields to the customer table
  • Loading branch information
fulopattila122 committed Oct 18, 2023
1 parent b7ac09a commit 6c72deb
Show file tree
Hide file tree
Showing 5 changed files with 164 additions and 3 deletions.
10 changes: 9 additions & 1 deletion Changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,19 @@
##### 2023-XX-YY

- BC: Changed the `CustomerType` interface so that it now extends the `EnumInterface`
- BC: Added the `addresses()` method to the Customer interface
- BC: Added the following methods to the Customer interface:
- `addresses()`
- `hasDefaultBillingAddress()`
- `hasDefaultShippingAddress()`
- `defaultBillingAddress()`
- `defaultShippingAddress()`
- `setDefaultShippingAddress()`
- `setDefaultBillingAddress()`
- BC: Changed the `Address::addresses()` method from `BelongsToMany` to `MorphToMany` - the two are very compatible, but aren't the same
- Dropped the `customer_addresses` table in favor of the Address module's `model()` polymorphic properties (migration included)
- Dropped Laravel 9 support
- Dropped PHP 8.0 support
- Added the `default_billing_address_id` and the `default_shipping_address_id` fields to the customer table/model
- Added the registration of `customer` to the relation morph map
- Changed minimum version requirements to:
- Enum v4.1
Expand Down
13 changes: 13 additions & 0 deletions src/Contracts/Customer.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
namespace Konekt\Customer\Contracts;

use Illuminate\Database\Eloquent\Relations\MorphMany;
use Konekt\Address\Contracts\Address;

interface Customer
{
Expand All @@ -23,4 +24,16 @@ interface Customer
public function getName(): string;

public function addresses(): MorphMany;

public function hasDefaultBillingAddress(): bool;

public function hasDefaultShippingAddress(): bool;

public function defaultBillingAddress(): ?Address;

public function defaultShippingAddress(): ?Address;

public function setDefaultShippingAddress(Address|int|null $address): void;

public function setDefaultBillingAddress(Address|int|null $address): void;
}
47 changes: 45 additions & 2 deletions src/Models/Customer.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,10 @@
namespace Konekt\Customer\Models;

use Carbon\Carbon;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\MorphMany;
use Konekt\Address\Contracts\Address;
use Konekt\Address\Models\AddressProxy;
use Konekt\Customer\Contracts\Customer as CustomerContract;
use Konekt\Customer\Events\CustomerTypeWasChanged;
Expand All @@ -39,6 +41,12 @@
* @property bool $is_active
* @property float $ltv
* @property Carbon|null $last_purchase_at
* @property int|null $default_billing_address_id
* @property int|null $default_shipping_address_id
*
* @property-read Collection|Address[] $addresses
* @property-read Address|null $default_billing_address
* @property-read Address|null $default_shipping_address
*
* @method static Customer create(array $attributes)
*/
Expand Down Expand Up @@ -74,6 +82,38 @@ public function getName(): string
return sprintf('%s %s', $this->firstname, $this->lastname);
}

public function hasDefaultBillingAddress(): bool
{
return null !== $this->default_billing_address_id;
}

public function hasDefaultShippingAddress(): bool
{
return null !== $this->default_shipping_address_id;
}

public function defaultBillingAddress(): ?Address
{
return $this->default_billing_address;
}

public function defaultShippingAddress(): ?Address
{
return $this->default_shipping_address;
}

public function setDefaultShippingAddress(Address|int|null $address): void
{
$value = $address instanceof Address ? $address->id : $address;
$this->update(['default_shipping_address_id' => $value]);
}

public function setDefaultBillingAddress(Address|int|null $address): void
{
$value = $address instanceof Address ? $address->id : $address;
$this->update(['default_billing_address_id' => $value]);
}

public function addresses(): MorphMany
{
return $this->morphMany(AddressProxy::modelClass(), 'model');
Expand All @@ -88,12 +128,15 @@ protected static function boot()
{
parent::boot();

static::resolveRelationUsing('default_shipping_address', fn($model) => $model->belongsTo(AddressProxy::modelClass(), 'default_shipping_address_id'));
static::resolveRelationUsing('default_billing_address', fn($model) => $model->belongsTo(AddressProxy::modelClass(), 'default_billing_address_id'));

static::updated(function ($customer) {
if ($customer->original['type'] != $customer->type) {
if ($customer->original['type'] ?? null !== $customer->type) {
event(
new CustomerTypeWasChanged(
$customer,
CustomerTypeProxy::create($customer->original['type']),
CustomerTypeProxy::create($customer->original['type'] ?? null),
$customer->original
)
);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<?php

declare(strict_types=1);

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

return new class extends Migration {
public function up(): void
{
Schema::table('customers', function (Blueprint $table) {
$table->unsignedBigInteger('default_billing_address_id')->nullable();
$table->unsignedBigInteger('default_shipping_address_id')->nullable();

$table->foreign('default_billing_address_id')->references('id')->on('addresses')->nullOnDelete();
$table->foreign('default_shipping_address_id')->references('id')->on('addresses')->nullOnDelete();
});
}

public function down(): void
{
Schema::table('customers', function (Blueprint $table) {
$table->dropForeign('customers_default_billing_address_id_foreign');
$table->dropForeign('customers_default_shipping_address_id_foreign');

$table->dropColumn('default_billing_address_id');
$table->dropColumn('default_shipping_address_id');
});
}
};
66 changes: 66 additions & 0 deletions tests/AddressDefaultsTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
<?php

declare(strict_types=1);

/**
* Contains the AddressDefaultsTest class.
*
* @copyright Copyright (c) 2023 Vanilo UG
* @author Attila Fulop
* @license MIT
* @since 2023-10-18
*
*/

namespace Konekt\Customer\Tests;

use Illuminate\Support\Collection;
use Konekt\Address\Models\Address;
use Konekt\Customer\Models\Customer;

class AddressDefaultsTest extends TestCase
{
/** @test */
public function customer_has_no_default_addresses_by_default()
{
$customer = Customer::create([]);

$this->assertFalse($customer->hasDefaultBillingAddress());
$this->assertFalse($customer->hasDefaultShippingAddress());

$this->assertNull($customer->defaultBillingAddress());
$this->assertNull($customer->defaultShippingAddress());

$this->assertNull($customer->default_billing_address_id);
$this->assertNull($customer->default_shipping_address_id);

$this->assertNull($customer->default_billing_address);
$this->assertNull($customer->default_shipping_address);
}

/** @test */
public function default_shipping_address_can_be_set()
{
$customer = Customer::create([])->fresh();
$address = Address::create(['name' => 'Xyz', 'country_id' => 'UK', 'address' => 'asdqwe']);
$customer->setDefaultShippingAddress($address);

$this->assertTrue($customer->hasDefaultShippingAddress());
$this->assertInstanceOf(Address::class, $customer->defaultShippingAddress());
$this->assertEquals($address->id, $customer->default_shipping_address_id);
$this->assertInstanceOf(Address::class, $customer->default_shipping_address);
}

/** @test */
public function default_billing_address_can_be_set()
{
$customer = Customer::create([])->fresh();
$address = Address::create(['name' => 'Xyz', 'country_id' => 'UK', 'address' => 'asdqwe']);
$customer->setDefaultBillingAddress($address);

$this->assertTrue($customer->hasDefaultBillingAddress());
$this->assertInstanceOf(Address::class, $customer->defaultBillingAddress());
$this->assertEquals($address->id, $customer->default_billing_address_id);
$this->assertInstanceOf(Address::class, $customer->default_billing_address);
}
}

0 comments on commit 6c72deb

Please sign in to comment.