Skip to content

Commit

Permalink
Added Promotion and Coupon models
Browse files Browse the repository at this point in the history
  • Loading branch information
kedves committed Jul 9, 2024
1 parent 6fdfc49 commit 72b5f70
Show file tree
Hide file tree
Showing 18 changed files with 555 additions and 1 deletion.
3 changes: 2 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,8 @@
"vanilo/properties": "self.version",
"vanilo/shipment": "self.version",
"vanilo/support": "self.version",
"vanilo/taxes": "self.version"
"vanilo/taxes": "self.version",
"vanilo/promotion": "self.version"
},
"autoload": {
"psr-4": {
Expand Down
6 changes: 6 additions & 0 deletions src/Promotion/.gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
* text=auto

/.github export-ignore
/Tests export-ignore
.gitattributes export-ignore
phpunit.xml export-ignore
13 changes: 13 additions & 0 deletions src/Promotion/.github/workflows/close-pull-request.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
name: Close Pull Request

on:
pull_request_target:
types: [opened]

jobs:
run:
runs-on: ubuntu-latest
steps:
- uses: superbrothers/close-pull-request@v3
with:
comment: "Thank you for your pull request. However, you have submitted this PR on a Vanilo sub-module which is a read-only split of `vanilo/framework`. Please submit your PR on the https://github.com/vanilophp/framework repository.<br><br>Thanks!"
28 changes: 28 additions & 0 deletions src/Promotion/.github/workflows/tests.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
name: tests

on: [push]

jobs:
build:
runs-on: ubuntu-latest
timeout-minutes: 10
strategy:
matrix:
php: ['8.2', '8.3']
laravel: ['10.43', '10.48', '11.0', '11.5']
name: PHP ${{ matrix.php }} Laravel ${{ matrix.laravel }}
steps:
- name: Checkout
uses: actions/checkout@master
- name: Installing PHP
uses: shivammathur/setup-php@master
with:
php-version: ${{ matrix.php }}
extensions: mbstring, json, sqlite3
tools: composer:v2
- name: Lock Laravel Version
run: composer require "illuminate/support:${{ matrix.laravel }}.*" --no-update -v && composer require "illuminate/console:${{ matrix.laravel }}.*" --no-update -v
- name: Composer Install
run: composer install --prefer-dist --no-progress --no-interaction
- name: Run Tests
run: php vendor/bin/phpunit --testdox
21 changes: 21 additions & 0 deletions src/Promotion/LICENSE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# The MIT License (MIT)

Copyright (c) 2019 Attila Fulop

> Permission is hereby granted, free of charge, to any person obtaining a copy
> of this software and associated documentation files (the "Software"), to deal
> in the Software without restriction, including without limitation the rights
> to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
> copies of the Software, and to permit persons to whom the Software is
> furnished to do so, subject to the following conditions:
>
> The above copyright notice and this permission notice shall be included in
> all copies or substantial portions of the Software.
>
> THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
> IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
> FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
> AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
> LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
> OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
> THE SOFTWARE.
33 changes: 33 additions & 0 deletions src/Promotion/Models/Coupon.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<?php

declare(strict_types=1);

namespace Vanilo\Promotion\Models;

use Carbon\Carbon;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;

/**
* @property int $id
* @property string $code
* @property ?int $usage_limit
* @property ?int $per_customer_usage_limit
* @property int $used
* @property ?Carbon $expires_at
*
* @property Promotion $promotion
*/
class Coupon extends Model
{
protected $guarded = ['id', 'created_at', 'updated_at'];

protected $casts = [
'expires_at' => 'datetime',
];

public function promotion(): BelongsTo
{
return $this->belongsTo(Promotion::class);
}
}
43 changes: 43 additions & 0 deletions src/Promotion/Models/Promotion.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
<?php

declare(strict_types=1);

namespace Vanilo\Promotion\Models;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Support\Carbon;
use Illuminate\Support\Collection;

/**
* @property int $id
* @property string $code
* @property string $name
* @property ?string $description
* @property int $priority
* @property bool $exclusive
* @property ?int $usage_limit
* @property int $used
* @property bool $coupon_based
* @property bool $applies_to_discounted
* @property ?Carbon $starts_at
* @property ?Carbon $ends_at
*
* @property Coupon[]|Collection $coupons
*/
class Promotion extends Model
{
protected $guarded = ['id', 'created_at', 'updated_at'];

protected $casts = [
'starts_at' => 'datetime',
'ends_at' => 'datetime',
'created_at' => 'datetime',
'updated_at' => 'datetime',
];

public function coupons(): HasMany
{
return $this->hasMany(Coupon::class);
}
}
11 changes: 11 additions & 0 deletions src/Promotion/Providers/ModuleServiceProvider.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?php

declare(strict_types=1);

namespace Vanilo\Promotion\Providers;

use Konekt\Concord\BaseModuleServiceProvider;

class ModuleServiceProvider extends BaseModuleServiceProvider
{
}
33 changes: 33 additions & 0 deletions src/Promotion/Tests/AAASmokeTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<?php

declare(strict_types=1);

namespace Vanilo\Promotion\Tests;

class AAASmokeTest extends TestCase
{
private const MIN_PHP_VERSION = '8.0.0';

/**
* @test
*/
public function smoke()
{
$this->assertTrue(true);
}

/**
* Test for minimum PHP version
*
* @depends smoke
* @test
*/
public function php_version_satisfies_requirements()
{
$this->assertFalse(
version_compare(PHP_VERSION, self::MIN_PHP_VERSION, '<'),
'PHP version ' . self::MIN_PHP_VERSION . ' or greater is required but only '
. PHP_VERSION . ' found.'
);
}
}
67 changes: 67 additions & 0 deletions src/Promotion/Tests/CouponTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
<?php

declare(strict_types=1);

namespace Vanilo\Promotion\Tests;

use Carbon\Carbon;
use Vanilo\Promotion\Models\Coupon;
use Vanilo\Promotion\Models\Promotion;

class CouponTest extends TestCase
{
/** @test */
public function all_mutable_fields_can_be_mass_assigned()
{
$coupon = Coupon::create([
'promotion_id' => factory(Promotion::class)->create()->id,
'code' => 'coupon',
'per_customer_usage_limit' => 2,
'usage_limit' => 4,
'used' => 4,
'expiresAt' => Carbon::now()->endOfDay()->toDateTimeString(),
]);

$this->assertEquals('coupon', $coupon->code);
$this->assertEquals(2, $coupon->per_customer_usage_limit);
$this->assertEquals(4, $coupon->usage_limit);
$this->assertEquals(4, $coupon->used);
$this->assertEquals(Carbon::now()->endOfDay()->toDateTimeString(), $coupon->expiresAt);
}

/** @test */
public function all_mutable_fields_can_be_set()
{
$coupon = new Coupon();

$coupon->code = 'coupon';
$coupon->per_customer_usage_limit = 1;
$coupon->usage_limit = 15;
$coupon->used = 4;
$coupon->expiresAt = Carbon::now()->endOfDay()->toDateTimeString();

$this->assertEquals('coupon', $coupon->code);
$this->assertEquals(1, $coupon->per_customer_usage_limit);
$this->assertEquals(15, $coupon->usage_limit);
$this->assertEquals(4, $coupon->used);
$this->assertEquals(Carbon::now()->endOfDay()->toDateTimeString(), $coupon->expiresAt);
}

/** @test */
public function code_must_be_unique()
{
$this->expectExceptionMessageMatches('/UNIQUE constraint failed/');

$c1 = Coupon::create([
'code' => 'coupon-1',
'promotion_id' => factory(Promotion::class)->create()->id,
]);

$c2 = Coupon::create([
'code' => 'coupon-1',
'promotion_id' => factory(Promotion::class)->create()->id,
]);

$this->assertNotEquals($c1->code, $c2->code);
}
}
97 changes: 97 additions & 0 deletions src/Promotion/Tests/PromotionTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
<?php

declare(strict_types=1);

namespace Vanilo\Promotion\Tests;

use Carbon\Carbon;
use Vanilo\Promotion\Models\Promotion;

class PromotionTest extends TestCase
{
/** @test */
public function all_mutable_fields_can_be_mass_assigned()
{
$now = Carbon::now()->startOfDay()->toDateTimeString();
$nextMonth = Carbon::now()->addMonths(1)->endOfDay()->toDateTimeString();

$promotion = Promotion::create([
'code' => 'PROMO-1',
'name' => 'Awesome promotion',
'description' => 'The description',
'priority' => 4,
'exclusive' => false,
'usage_limit' => 15,
'used' => 1,
'coupon_based' => false,
'starts_at' => $now,
'ends_at' => $nextMonth,
'applies_to_discounted' => false,

]);

$this->assertEquals('PROMO-1', $promotion->code);
$this->assertEquals('Awesome promotion', $promotion->name);
$this->assertEquals('The description', $promotion->description);
$this->assertEquals(4, $promotion->priority);
$this->assertFalse($promotion->exclusive);
$this->assertEquals(15, $promotion->usage_limit);
$this->assertEquals(1, $promotion->used);
$this->assertFalse($promotion->coupon_based);
$this->assertEquals($now, $promotion->starts_at);
$this->assertEquals($nextMonth, $promotion->ends_at);
$this->assertFalse($promotion->applies_to_discounted);
}

/** @test */
public function all_mutable_fields_can_be_set()
{
$now = Carbon::now()->startOfDay()->startOfDay()->toDateTimeString();
$nextMonth = Carbon::now()->addMonth()->endOfDay()->toDateTimeString();

$promotion = new Promotion();

$promotion->code = 'PROMO-1';
$promotion->name = 'Awesome promotion';
$promotion->description = 'The description';
$promotion->priority = 4;
$promotion->exclusive = false;
$promotion->usage_limit = 15;
$promotion->used = 1;
$promotion->coupon_based = false;
$promotion->applies_to_discounted = false;
$promotion->starts_at = $now;
$promotion->ends_at = $nextMonth;


$this->assertEquals('PROMO-1', $promotion->code);
$this->assertEquals('Awesome promotion', $promotion->name);
$this->assertEquals('The description', $promotion->description);
$this->assertEquals(4, $promotion->priority);
$this->assertFalse($promotion->exclusive);
$this->assertEquals(15, $promotion->usage_limit);
$this->assertEquals(1, $promotion->used);
$this->assertFalse($promotion->coupon_based);
$this->assertEquals($now, $promotion->starts_at->toDateTimeString());
$this->assertEquals($nextMonth, $promotion->ends_at->toDateTimeString());
$this->assertFalse($promotion->applies_to_discounted);
}

/** @test */
public function code_must_be_unique()
{
$this->expectExceptionMessageMatches('/UNIQUE constraint failed/');

$p1 = Promotion::create([
'name' => 'Promo 1',
'code' => 'PROMO-1',
]);

$p2 = Promotion::create([
'name' => 'Promo 2',
'code' => 'PROMO-1',
]);

$this->assertNotEquals($p1->code, $p2->code);
}
}
Loading

0 comments on commit 72b5f70

Please sign in to comment.