amsgames / laravel-shop

Laravel shop package
MIT License
482 stars 166 forks source link

Coupons #19

Open ghost opened 8 years ago

ghost commented 8 years ago

Hello!

how I can use Coupons with your package ?

amostajo commented 8 years ago

The coupons feature is in development.

ghost commented 8 years ago

Can say a date for publish it in develop ?

PSEAlex commented 8 years ago

I'm looking for this improvement too. Any ideas when it will be ready? Meanwhile, any tips on how can I implement this myself? Thanks!

amostajo commented 8 years ago

Depending how complex will your coupons be.

Locally the next push to dev will have:

Coupons with specific amount. Coupons with specific percentage discount. Coupons that only apply to certain SKUs. Coupons with expiration date. Coupons with usage limit. Coupons that only apply to certain users. On Dec 2, 2015 10:38 AM, "mbl-at" notifications@github.com wrote:

I'm looking for this improvement too. Any ideas when it will be ready? Meanwhile, any tips on how can I implement this myself? Thanks!

— Reply to this email directly or view it on GitHub https://github.com/amsgames/laravel-shop/issues/19#issuecomment-161357699 .

ghost commented 8 years ago

When u make this in the dev branch ? Do you have an date for me ?

ghost commented 8 years ago

Ok i span up a quick POC for how coupons would work initially. please note this is UNTESTED so use at your own risk. im sure @amostajo would be able to do a lot better job of this than me so i will wait for his feedback

Create a new migration: php artisan make:migration add_coupon_functionality

Add the following to the migration:

public function up()
    {
        Schema::create('coupon_links', function (Blueprint $table)
        {
            $table->integer('coupon_id');
            $table->integer('coupon_link_id');
            $table->string('coupon_link_type');
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::drop('coupon_links');
    }

In your Coupon Model:

    /**
     * Get all of the orders that are assigned this coupon.
     */
    public function orders()
    {
        return $this->morphedByMany(Config::get('shop.order'), 'coupon_link');
    }

    /**
     * Get all of the carts that are assigned this coupon.
     */
    public function carts()
    {
        return $this->morphedByMany(Config::get('shop.cart'), 'coupon_link');
    }

In your Order Model:

    /**
     * Get all of the coupons for the order.
     */
    public function coupons()
    {
        return $this->morphToMany(Config::get('shop.coupon'), 'coupon_link');
    }

In your Cart Model:

    /**
     * Get all of the coupons for the cart.
     */
    public function coupons()
    {
        return $this->morphToMany(Config::get('shop.coupon'), 'coupon_link');
    }

In ShopCalculationsTrait.php:

Add our getter @ line 86:

    public function getTotalDiscountAttribute()
    {
        if (empty($this->shopCalculations)) $this->runCalculations();

        return round($this->shopCalculations->totalDiscount, 2);
    }

Add our display getter @ line 137:

    public function getDisplayTotalDiscountAttribute()
    {
        return Shop::format($this->totalDiscount);
    }

Adjust the cart/order calculations @ line 189:

//Add total discount, edit totalPrice
        $PivotOn = $this->table == Config::get('shop . order_table') ? 'App\Order' : 'App\Cart';
        $Discounts = $this->calculateDiscounts($PivotOn, $this->attributes['id']);

        //Remove Cash Discount
        $this->shopCalculations->totalPrice -= $Discounts['cash'];

        //Remove % Discount
        $PercentageDiscount = $this->shopCalculations->totalPrice;
        $this->shopCalculations->totalPrice -= $this->shopCalculations->totalPrice * $Discounts['percent'];
        $PercentageDiscount -= $this->shopCalculations->totalPrice;

        $this->shopCalculations->CashDiscount = $Discounts['cash'];
        $this->shopCalculations->PercentDiscount = $Discounts['percent'];
        $this->shopCalculations->PercentCashDiscount = $PercentageDiscount;
        $this->shopCalculations->totalDiscount = $Discounts['cash'] + $PercentageDiscount;

Add additional function at the bottom:

    /**
     * Calculates the discount required on a class with a specified id
     * @param $PivotOn
     * @param $id
     * @return array
     */
    private function calculateDiscounts($PivotOn, $id)
    {
        $Class = new $PivotOn;
        $Coupons = $Class::find($id)->coupons;

        $Discount = [
            'cash'    => 0.00,
            'percent' => 0.00,
        ];
        foreach ($Coupons as $coupon)
        {
            if (!is_null($coupon->value))
                $Discount['cash'] += $coupon->value;
            else
                $Discount['percent'] += $coupon->discount;
        }

        return $Discount;
    }

When Using a flat cash discount (specified by value) you will see:

{#812
     +"totalPrice": 51.98,
     +"totalTax": "0.00",
     +"totalShipping": "3.00",
     +"CashDiscount": 20.0,
     +"PercentDiscount": 0.0,
     +"PercentCashDiscount": 0.0,
     +"totalDiscount": 20.0,
   }

When Using a percentage discount on the basket you will see:

{#812
     +"totalPrice": 64.782,
     +"totalTax": "0.00",
     +"totalShipping": "3.00",
     +"CashDiscount": 0.0,
     +"PercentDiscount": 0.1,
     +"PercentCashDiscount": 7.198,
     +"totalDiscount": 7.198,
   }