mirror of
https://github.com/kevin-DL/LaravelShoppingcart.git
synced 2026-01-11 18:54:33 +00:00
Merge branch 'master' into fix_cart_database_timestamps
This commit is contained in:
65
README.md
65
README.md
@@ -7,7 +7,7 @@
|
|||||||
[](https://packagist.org/packages/bumbummen99/shoppingcart)
|
[](https://packagist.org/packages/bumbummen99/shoppingcart)
|
||||||
[](https://packagist.org/packages/bumbummen99/shoppingcart)
|
[](https://packagist.org/packages/bumbummen99/shoppingcart)
|
||||||
|
|
||||||
This is a fork of [Crisane's LaravelShoppingcart](https://github.com/Crinsane/LaravelShoppingcart) extended with minor features compatible with Laravel 5.8.
|
This is a fork of [Crinsane's LaravelShoppingcart](https://github.com/Crinsane/LaravelShoppingcart) extended with minor features compatible with Laravel 7. An example integration can be [found here](https://github.com/bumbummen99/LaravelShoppingcartDemo).
|
||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
@@ -24,6 +24,7 @@ Now you're ready to start using the shoppingcart in your application.
|
|||||||
## Table of Contents
|
## Table of Contents
|
||||||
Look at one of the following topics to learn more about LaravelShoppingcart
|
Look at one of the following topics to learn more about LaravelShoppingcart
|
||||||
|
|
||||||
|
* [Important note](#important-note)
|
||||||
* [Usage](#usage)
|
* [Usage](#usage)
|
||||||
* [Collections](#collections)
|
* [Collections](#collections)
|
||||||
* [Instances](#instances)
|
* [Instances](#instances)
|
||||||
@@ -33,6 +34,14 @@ Look at one of the following topics to learn more about LaravelShoppingcart
|
|||||||
* [Events](#events)
|
* [Events](#events)
|
||||||
* [Example](#example)
|
* [Example](#example)
|
||||||
|
|
||||||
|
## Important note
|
||||||
|
|
||||||
|
As all the shopping cart that calculate prices including taxes and discount, also this module could be affected by the "totals rounding issue" ([*](https://stackoverflow.com/questions/13529580/magento-tax-rounding-issue)) due to the decimal precision used for prices and for the results.
|
||||||
|
In order to avoid (or at least minimize) this issue, in the Laravel shoppingcart package the totals are calculated using the method **"per Row"** and returned already rounded based on the number format set as default in the config file (cart.php).
|
||||||
|
Due to this **WE DISCOURAGE TO SET HIGH PRECISION AS DEFAULT AND TO FORMAT THE OUTPUT RESULT USING LESS DECIMAL** Doing this can lead to the rounding issue.
|
||||||
|
|
||||||
|
The base price (product price) is left not rounded.
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|
||||||
The shoppingcart gives you the following methods to use:
|
The shoppingcart gives you the following methods to use:
|
||||||
@@ -41,16 +50,16 @@ The shoppingcart gives you the following methods to use:
|
|||||||
|
|
||||||
Adding an item to the cart is really simple, you just use the `add()` method, which accepts a variety of parameters.
|
Adding an item to the cart is really simple, you just use the `add()` method, which accepts a variety of parameters.
|
||||||
|
|
||||||
In its most basic form you can specify the id, name, quantity, price of the product you'd like to add to the cart.
|
In its most basic form you can specify the id, name, quantity, price and weight of the product you'd like to add to the cart.
|
||||||
|
|
||||||
```php
|
```php
|
||||||
Cart::add('293ad', 'Product 1', 1, 9.99);
|
Cart::add('293ad', 'Product 1', 1, 9.99, 550);
|
||||||
```
|
```
|
||||||
|
|
||||||
As an optional fifth parameter you can pass it options, so you can add multiple items with the same id, but with (for instance) a different size.
|
As an optional fifth parameter you can pass it options, so you can add multiple items with the same id, but with (for instance) a different size.
|
||||||
|
|
||||||
```php
|
```php
|
||||||
Cart::add('293ad', 'Product 1', 1, 9.99, 'weight' => 550, ['size' => 'large']);
|
Cart::add('293ad', 'Product 1', 1, 9.99, 550, ['size' => 'large']);
|
||||||
```
|
```
|
||||||
|
|
||||||
**The `add()` method will return an CartItem instance of the item you just added to the cart.**
|
**The `add()` method will return an CartItem instance of the item you just added to the cart.**
|
||||||
@@ -155,7 +164,7 @@ Cart::destroy();
|
|||||||
|
|
||||||
### Cart::weight()
|
### Cart::weight()
|
||||||
|
|
||||||
The `weight()` method can be used to get the weight total of all items in the cart, given there weight and quantity.
|
The `weight()` method can be used to get the weight total of all items in the cart, given their weight and quantity.
|
||||||
|
|
||||||
```php
|
```php
|
||||||
Cart::weight();
|
Cart::weight();
|
||||||
@@ -245,13 +254,15 @@ You can set the default number format in the config file.
|
|||||||
|
|
||||||
### Cart::initial()
|
### Cart::initial()
|
||||||
|
|
||||||
The `initial()` method can be used to get the total price of all items in the cart before discount.
|
The `initial()` method can be used to get the total price of all items in the cart before applying discount and taxes.
|
||||||
|
|
||||||
|
It could be deprecated in the future. **When rounded could be affected by the rounding issue**, use it carefully or use [Cart::priceTotal()](#Cart::priceTotal())
|
||||||
|
|
||||||
```php
|
```php
|
||||||
Cart::initial();
|
Cart::initial();
|
||||||
```
|
```
|
||||||
|
|
||||||
The method will automatically format the result, which you can tweak using the three optional parameters
|
The method will automatically format the result, which you can tweak using the three optional parameters.
|
||||||
|
|
||||||
```php
|
```php
|
||||||
Cart::initial($decimals, $decimalSeparator, $thousandSeparator);
|
Cart::initial($decimals, $decimalSeparator, $thousandSeparator);
|
||||||
@@ -259,6 +270,22 @@ Cart::initial($decimals, $decimalSeparator, $thousandSeparator);
|
|||||||
|
|
||||||
You can set the default number format in the config file.
|
You can set the default number format in the config file.
|
||||||
|
|
||||||
|
### Cart::priceTotal()
|
||||||
|
|
||||||
|
The `priceTotal()` method can be used to get the total price of all items in the cart before applying discount and taxes.
|
||||||
|
|
||||||
|
```php
|
||||||
|
Cart::priceTotal();
|
||||||
|
```
|
||||||
|
|
||||||
|
The method return the result rounded based on the default number format, but you can tweak using the three optional parameters
|
||||||
|
|
||||||
|
```php
|
||||||
|
Cart::priceTotal($decimals, $decimalSeparator, $thousandSeparator);
|
||||||
|
```
|
||||||
|
|
||||||
|
You can set the default number format in the config file.
|
||||||
|
|
||||||
**If you're not using the Facade, but use dependency injection in your (for instance) Controller, you can also simply get the subtotal property `$cart->initial`**
|
**If you're not using the Facade, but use dependency injection in your (for instance) Controller, you can also simply get the subtotal property `$cart->initial`**
|
||||||
|
|
||||||
### Cart::count()
|
### Cart::count()
|
||||||
@@ -306,8 +333,8 @@ $cart->setTax($rowId, 21);
|
|||||||
You can use the `setGlobalTax()` method to change the tax rate for all items in the cart. New items will receive the setGlobalTax as well.
|
You can use the `setGlobalTax()` method to change the tax rate for all items in the cart. New items will receive the setGlobalTax as well.
|
||||||
|
|
||||||
```php
|
```php
|
||||||
Cart::setGlobalDiscount(21);
|
Cart::setGlobalTax(21);
|
||||||
$cart->setGlobalDiscount(21);
|
$cart->setGlobalTax(21);
|
||||||
```
|
```
|
||||||
|
|
||||||
### Cart::setGlobalDiscount($discountRate)
|
### Cart::setGlobalDiscount($discountRate)
|
||||||
@@ -315,8 +342,8 @@ $cart->setGlobalDiscount(21);
|
|||||||
You can use the `setGlobalDiscount()` method to change the discount rate for all items in the cart. New items will receive the discount as well.
|
You can use the `setGlobalDiscount()` method to change the discount rate for all items in the cart. New items will receive the discount as well.
|
||||||
|
|
||||||
```php
|
```php
|
||||||
Cart::setGlobalDiscount(21);
|
Cart::setGlobalDiscount(50);
|
||||||
$cart->setGlobalDiscount(21);
|
$cart->setGlobalDiscount(50);
|
||||||
```
|
```
|
||||||
|
|
||||||
### Cart::setDiscount($rowId, $taxRate)
|
### Cart::setDiscount($rowId, $taxRate)
|
||||||
@@ -339,7 +366,7 @@ use Gloudemans\Shoppingcart\Contracts\Buyable;
|
|||||||
use Illuminate\Database\Eloquent\Model;
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
|
||||||
class Product extends Model implements Buyable {
|
class Product extends Model implements Buyable {
|
||||||
use Gloudemans\Shoppingcart\CanBeNought;
|
use Gloudemans\Shoppingcart\CanBeBought;
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -540,10 +567,18 @@ If you want to retrieve the cart from the database and restore it, all you have
|
|||||||
Cart::instance('wishlist')->restore('username');
|
Cart::instance('wishlist')->restore('username');
|
||||||
|
|
||||||
### Merge the cart
|
### Merge the cart
|
||||||
If you want to merge the cart with another one from the database, all you have to do is call the `merge($identifier)` where `$identifier` is the key you specified for the `store` method. You can also define if you want to keep the discount and tax rates of the items.
|
If you want to merge the cart with another one from the database, all you have to do is call the `merge($identifier)` where `$identifier` is the key you specified for the `store` method. You can also define if you want to keep the discount and tax rates of the items and if you want to dispatch "cart.added" events.
|
||||||
|
|
||||||
// Merge the contents of 'savedcart' into 'username'.
|
// Merge the contents of 'savedcart' into 'username'.
|
||||||
Cart::instance('username')->merge('savedcart', $keepDiscount, $keepTaxrate);
|
Cart::instance('username')->merge('savedcart', $keepDiscount, $keepTaxrate, $dispatchAdd);
|
||||||
|
|
||||||
|
### Erasing the cart
|
||||||
|
If you want to erase the cart from the database, all you have to do is call the `erase($identifier)` where `$identifier` is the key you specified for the `store` method.
|
||||||
|
|
||||||
|
Cart::erase('username');
|
||||||
|
|
||||||
|
// To erase a cart switching to an instance named 'wishlist'
|
||||||
|
Cart::instance('wishlist')->erase('username');
|
||||||
|
|
||||||
## Exceptions
|
## Exceptions
|
||||||
|
|
||||||
@@ -564,8 +599,10 @@ The cart also has events build in. There are five events available for you to li
|
|||||||
| cart.added | When an item was added to the cart. | The `CartItem` that was added. |
|
| cart.added | When an item was added to the cart. | The `CartItem` that was added. |
|
||||||
| cart.updated | When an item in the cart was updated. | The `CartItem` that was updated. |
|
| cart.updated | When an item in the cart was updated. | The `CartItem` that was updated. |
|
||||||
| cart.removed | When an item is removed from the cart. | The `CartItem` that was removed. |
|
| cart.removed | When an item is removed from the cart. | The `CartItem` that was removed. |
|
||||||
|
| cart.merged | When the content of a cart is merged | - |
|
||||||
| cart.stored | When the content of a cart was stored. | - |
|
| cart.stored | When the content of a cart was stored. | - |
|
||||||
| cart.restored | When the content of a cart was restored. | - |
|
| cart.restored | When the content of a cart was restored. | - |
|
||||||
|
| cart.erased | When the content of a cart was erased. | - |
|
||||||
|
|
||||||
## Example
|
## Example
|
||||||
|
|
||||||
|
|||||||
628
README_Idn.md
Normal file
628
README_Idn.md
Normal file
@@ -0,0 +1,628 @@
|
|||||||
|
## LaravelShoppingcart
|
||||||
|
[](https://travis-ci.org/bumbummen99/LaravelShoppingcart)
|
||||||
|
[](https://codecov.io/gh/bumbummen99/LaravelShoppingcart)
|
||||||
|
[](https://styleci.io/repos/152610878)
|
||||||
|
[](https://packagist.org/packages/bumbummen99/shoppingcart)
|
||||||
|
[](https://packagist.org/packages/bumbummen99/shoppingcart)
|
||||||
|
[](https://packagist.org/packages/bumbummen99/shoppingcart)
|
||||||
|
[](https://packagist.org/packages/bumbummen99/shoppingcart)
|
||||||
|
|
||||||
|
Ini adalah percabangan dari [Crinsane's LaravelShoppingcart](https://github.com/Crinsane/LaravelShoppingcart) dikembangkan dengan fitur-fitur minor yang kompatibel dengan Laravel 6
|
||||||
|
|
||||||
|
## Instalasi
|
||||||
|
|
||||||
|
Install paket(https://packagist.org/packages/bumbummen99/shoppingcart) menggunakan [Composer](http://getcomposer.org/).
|
||||||
|
|
||||||
|
Jalankan Composer dengan menggunakan perintah berikut:
|
||||||
|
|
||||||
|
composer require bumbummen99/shoppingcart
|
||||||
|
|
||||||
|
Sekarang Anda siap untuk mulai menggunakan shoppingcart di aplikasi Anda.
|
||||||
|
|
||||||
|
**Pada versi 2 dari paket ini memungkinkan untuk menggunakan injeksi dependensi untuk memasukkan instance Class Cart ke controller Anda atau Class lain**
|
||||||
|
|
||||||
|
## Gambaran
|
||||||
|
Lihat salah satu topik berikut untuk mempelajari lebih lanjut tentang LaravelShoppingcart
|
||||||
|
|
||||||
|
* [Usage](#usage)
|
||||||
|
* [Collections](#collections)
|
||||||
|
* [Instances](#instances)
|
||||||
|
* [Models](#models)
|
||||||
|
* [Database](#database)
|
||||||
|
* [Exceptions](#exceptions)
|
||||||
|
* [Events](#events)
|
||||||
|
* [Example](#example)
|
||||||
|
|
||||||
|
## Penggunaan
|
||||||
|
|
||||||
|
Shoppingcart memberi Anda metode berikut untuk digunakan:
|
||||||
|
|
||||||
|
### Cart::add()
|
||||||
|
|
||||||
|
Menambahkan item ke troli sangat sederhana, Anda cukup menggunakan metode `add ()`, yang menerima berbagai parameter.
|
||||||
|
|
||||||
|
Dalam bentuknya yang paling mendasar, Anda dapat menentukan id, nama, jumlah, harga, dan berat produk yang ingin Anda tambahkan ke troli.
|
||||||
|
|
||||||
|
```php
|
||||||
|
Cart::add('293ad', 'Product 1', 1, 9.99, 550);
|
||||||
|
```
|
||||||
|
|
||||||
|
Sebagai opsional parameter kelima, Anda dapat memberikan opsi, sehingga Anda dapat menambahkan beberapa item dengan id yang sama, tetapi dengan (instance) ukuran yang berbeda.
|
||||||
|
|
||||||
|
```php
|
||||||
|
Cart::add('293ad', 'Product 1', 1, 9.99, 550, ['size' => 'large']);
|
||||||
|
```
|
||||||
|
|
||||||
|
**Metode `add ()` akan mengembalikan instance CartItem dari item yang baru saja Anda tambahkan ke troli.**
|
||||||
|
|
||||||
|
Mungkin Anda lebih suka menambahkan item menggunakan array? Selama array berisi kunci yang diperlukan, Anda bisa meneruskannya ke metode. Tombol opsi adalah opsional.
|
||||||
|
|
||||||
|
```php
|
||||||
|
Cart::add(['id' => '293ad', 'name' => 'Product 1', 'qty' => 1, 'price' => 9.99, 'weight' => 550, 'options' => ['size' => 'large']]);
|
||||||
|
```
|
||||||
|
|
||||||
|
Baru dalam versi 2 paket ini adalah kemungkinan untuk bekerja dengan antarmuka [Buyable] (#buyable). Cara kerjanya adalah bahwa Anda memiliki model yang mengimplementasikan antarmuka [Buyable] (#buyable), yang akan membuat Anda menerapkan beberapa metode sehingga paket tahu bagaimana cara mendapatkan id, nama, dan harga dari model Anda.
|
||||||
|
Dengan cara ini Anda bisa meneruskan metode `add ()` model dan kuantitas dan secara otomatis akan menambahkannya ke troli.
|
||||||
|
|
||||||
|
**Sebagai bonus tambahan, itu akan secara otomatis mengaitkan model dengan CartItem**
|
||||||
|
|
||||||
|
```php
|
||||||
|
Cart::add($product, 1, ['size' => 'large']);
|
||||||
|
```
|
||||||
|
Sebagai parameter ketiga opsional, Anda dapat menambahkan opsi.
|
||||||
|
```php
|
||||||
|
Cart::add($product, 1, ['size' => 'large']);
|
||||||
|
```
|
||||||
|
|
||||||
|
Terakhir, Anda juga dapat menambahkan banyak item ke troli sekaligus.
|
||||||
|
Anda bisa meneruskan metode `add ()` sebuah array array, atau array yang dapat dibeli dan mereka akan ditambahkan ke troli.
|
||||||
|
|
||||||
|
**Saat menambahkan beberapa item ke troli, metode `add ()` akan mengembalikan array CartItems.**
|
||||||
|
|
||||||
|
```php
|
||||||
|
Cart::add([
|
||||||
|
['id' => '293ad', 'name' => 'Product 1', 'qty' => 1, 'price' => 10.00, 'weight' => 550],
|
||||||
|
['id' => '4832k', 'name' => 'Product 2', 'qty' => 1, 'price' => 10.00, 'weight' => 550, 'options' => ['size' => 'large']]
|
||||||
|
]);
|
||||||
|
|
||||||
|
Cart::add([$product1, $product2]);
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
### Cart::update()
|
||||||
|
|
||||||
|
Untuk memperbarui item di troli, Anda harus terlebih dahulu membutuhkan rowId item.
|
||||||
|
Selanjutnya Anda dapat menggunakan metode `update ()` untuk memperbaruinya.
|
||||||
|
|
||||||
|
Jika Anda hanya ingin memperbarui kuantitas, Anda akan melewati metode pembaruan rowId dan kuantitas baru:
|
||||||
|
|
||||||
|
```php
|
||||||
|
$rowId = 'da39a3ee5e6b4b0d3255bfef95601890afd80709';
|
||||||
|
|
||||||
|
Cart::update($rowId, 2); // Will update the quantity
|
||||||
|
```
|
||||||
|
Jika Anda ingin memperbarui lebih banyak atribut dari item, Anda dapat melewati metode pembaruan array atau `Dapat Dibeli` sebagai parameter kedua. Dengan cara ini Anda dapat memperbarui semua informasi item dengan rowId yang diberikan.
|
||||||
|
|
||||||
|
```php
|
||||||
|
Cart::update($rowId, ['name' => 'Product 1']); // Will update the name
|
||||||
|
|
||||||
|
Cart::update($rowId, $product); // Will update the id, name and price
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
### Cart::remove()
|
||||||
|
|
||||||
|
Untuk menghapus item untuk keranjang, Anda akan membutuhkan rowId lagi. Baris ini. Apakah Anda hanya meneruskan ke metode `hapus ()` dan itu akan menghapus item dari keranjang.
|
||||||
|
|
||||||
|
```php
|
||||||
|
$rowId = 'da39a3ee5e6b4b0d3255bfef95601890afd80709';
|
||||||
|
|
||||||
|
Cart::remove($rowId);
|
||||||
|
```
|
||||||
|
|
||||||
|
### Cart::get()
|
||||||
|
|
||||||
|
Jika Anda ingin mendapatkan item dari troli menggunakan rowId-nya, Anda bisa memanggil metode `get ()` di troli dan meneruskannya dengan rowId.
|
||||||
|
|
||||||
|
```php
|
||||||
|
$rowId = 'da39a3ee5e6b4b0d3255bfef95601890afd80709';
|
||||||
|
|
||||||
|
Cart::get($rowId);
|
||||||
|
```
|
||||||
|
|
||||||
|
### Cart::content()
|
||||||
|
|
||||||
|
Tentu saja Anda juga ingin mendapatkan konten gerobak. Di sinilah Anda akan menggunakan metode `konten`. Metode ini akan mengembalikan Koleksi CartItems yang dapat Anda ulangi dan tampilkan kontennya kepada pelanggan Anda.
|
||||||
|
|
||||||
|
```php
|
||||||
|
Cart::content();
|
||||||
|
```
|
||||||
|
Metode ini akan mengembalikan konten instance keranjang saat ini, jika Anda ingin konten instance lain, cukup lakukan panggilan.
|
||||||
|
|
||||||
|
```php
|
||||||
|
Cart::instance('wishlist')->content();
|
||||||
|
```
|
||||||
|
|
||||||
|
### Cart::destroy()
|
||||||
|
|
||||||
|
Jika Anda ingin menghapus konten keranjang sepenuhnya, Anda dapat memanggil metode penghancuran di kereta. Ini akan menghapus semua CartItems dari troli untuk instance troli saat ini.
|
||||||
|
|
||||||
|
```php
|
||||||
|
Cart::destroy();
|
||||||
|
```
|
||||||
|
|
||||||
|
### Cart::weight()
|
||||||
|
|
||||||
|
Metode `weight ()` dapat digunakan untuk mendapatkan total berat semua item di troli, mengingat berat dan kuantitasnya.
|
||||||
|
|
||||||
|
|
||||||
|
```php
|
||||||
|
Cart::weight();
|
||||||
|
```
|
||||||
|
|
||||||
|
Metode ini akan memformat hasilnya secara otomatis, yang dapat Anda atur menggunakan tiga parameter opsional
|
||||||
|
|
||||||
|
```php
|
||||||
|
Cart::weight($decimals, $decimalSeperator, $thousandSeperator);
|
||||||
|
```
|
||||||
|
|
||||||
|
Anda dapat mengatur format angka default dalam file konfigurasi.
|
||||||
|
|
||||||
|
**Jika Anda tidak menggunakan Facade, tetapi menggunakan injeksi ketergantungan pada Pengontrol Anda (misalnya), Anda juga bisa mendapatkan total properti `$ cart-> weight`**
|
||||||
|
|
||||||
|
### Cart::total()
|
||||||
|
|
||||||
|
Maka `total ()` dapat digunakan untuk mendapatkan total yang dihitung dari semua item dalam troli, mengingat ada harga dan kuantitas.
|
||||||
|
|
||||||
|
```php
|
||||||
|
Cart::total();
|
||||||
|
```
|
||||||
|
|
||||||
|
Metode ini akan memformat hasilnya secara otomatis, yang dapat Anda atur menggunakan tiga parameter opsional
|
||||||
|
|
||||||
|
```php
|
||||||
|
Cart::total($decimals, $decimalSeparator, $thousandSeparator);
|
||||||
|
```
|
||||||
|
|
||||||
|
Anda dapat mengatur format angka default dalam file konfigurasi.
|
||||||
|
|
||||||
|
|
||||||
|
**Jika Anda tidak menggunakan Facade, tetapi menggunakan injeksi ketergantungan pada Pengontrol Anda (misalnya), Anda juga bisa mendapatkan total properti `$ cart-> total`**
|
||||||
|
|
||||||
|
### Cart::tax()
|
||||||
|
|
||||||
|
Maka `tax ()` dapat digunakan untuk mendapatkan jumlah pajak yang dihitung untuk semua item di troli, mengingat ada harga dan kuantitas.
|
||||||
|
|
||||||
|
```php
|
||||||
|
Cart::tax();
|
||||||
|
```
|
||||||
|
|
||||||
|
Metode ini akan memformat hasilnya secara otomatis, yang dapat Anda atur menggunakan tiga parameter opsional
|
||||||
|
|
||||||
|
```php
|
||||||
|
Cart::tax($decimals, $decimalSeparator, $thousandSeparator);
|
||||||
|
```
|
||||||
|
|
||||||
|
Anda dapat mengatur format angka default dalam file konfigurasi.
|
||||||
|
|
||||||
|
**Jika Anda tidak menggunakan Facade, tetapi menggunakan injeksi ketergantungan pada Pengontrol Anda (misalnya), Anda juga bisa mendapatkan total properti `$ cart-> tax`**
|
||||||
|
|
||||||
|
### Cart::subtotal()
|
||||||
|
|
||||||
|
Maka `subtotal ()` dapat digunakan untuk mendapatkan total semua item dalam troli, dikurangi jumlah total pajak.
|
||||||
|
|
||||||
|
```php
|
||||||
|
Cart::subtotal();
|
||||||
|
```
|
||||||
|
|
||||||
|
Metode ini akan memformat hasilnya secara otomatis, yang dapat Anda atur menggunakan tiga parameter opsional
|
||||||
|
|
||||||
|
```php
|
||||||
|
Cart::subtotal($decimals, $decimalSeparator, $thousandSeparator);
|
||||||
|
```
|
||||||
|
|
||||||
|
Anda dapat mengatur format angka default dalam file konfigurasi.
|
||||||
|
|
||||||
|
**Jika Anda tidak menggunakan Facade, tetapi menggunakan injeksi ketergantungan pada Pengontrol Anda (misalnya), Anda juga bisa mendapatkan total properti `$ cart-> subtotal`**
|
||||||
|
|
||||||
|
### Cart::discount()
|
||||||
|
|
||||||
|
Maka `diskon ()` dapat digunakan untuk mendapatkan diskon total semua item di troli.
|
||||||
|
|
||||||
|
```php
|
||||||
|
Cart::discount();
|
||||||
|
```
|
||||||
|
|
||||||
|
Metode ini akan memformat hasilnya secara otomatis, yang dapat Anda atur menggunakan tiga parameter opsional
|
||||||
|
|
||||||
|
```php
|
||||||
|
Cart::discount($decimals, $decimalSeparator, $thousandSeparator);
|
||||||
|
```
|
||||||
|
|
||||||
|
Anda dapat mengatur format angka default dalam file konfigurasi.
|
||||||
|
|
||||||
|
**Jika Anda tidak menggunakan Facade, tetapi menggunakan injeksi ketergantungan pada Pengontrol Anda (misalnya), Anda juga bisa mendapatkan total properti `$ cart-> discount`**
|
||||||
|
|
||||||
|
### Cart::initial()
|
||||||
|
|
||||||
|
maka `initial ()` dapat digunakan untuk mendapatkan harga total semua item di troli sebelum diskon.
|
||||||
|
|
||||||
|
```php
|
||||||
|
Cart::initial();
|
||||||
|
```
|
||||||
|
|
||||||
|
Metode ini akan memformat hasilnya secara otomatis, yang dapat Anda atur menggunakan tiga parameter opsional
|
||||||
|
|
||||||
|
```php
|
||||||
|
Cart::initial($decimals, $decimalSeparator, $thousandSeparator);
|
||||||
|
```
|
||||||
|
|
||||||
|
Anda dapat mengatur format angka default dalam file konfigurasi.
|
||||||
|
|
||||||
|
**Jika Anda tidak menggunakan Facade, tetapi menggunakan injeksi ketergantungan pada Pengontrol Anda (misalnya), Anda juga bisa mendapatkan total properti `$ cart-> initial`**
|
||||||
|
|
||||||
|
### Cart::count()
|
||||||
|
|
||||||
|
Jika Anda ingin tahu berapa banyak item yang ada di troli Anda, Anda dapat menggunakan metode `count ()`. Metode ini akan mengembalikan jumlah total barang dalam kereta. Jadi, jika Anda telah menambahkan 2 buku dan 1 kemeja, itu akan mengembalikan 3 item.
|
||||||
|
|
||||||
|
```php
|
||||||
|
Cart::count();
|
||||||
|
$cart->count();
|
||||||
|
```
|
||||||
|
|
||||||
|
### Cart::search()
|
||||||
|
|
||||||
|
Untuk menemukan item di troli, Anda dapat menggunakan metode `search ()`.
|
||||||
|
|
||||||
|
**Metode ini diubah pada versi 2**
|
||||||
|
|
||||||
|
Di belakang layar, metode ini hanya menggunakan metode filter dari kelas Laravel Collection. Ini berarti Anda harus memberikannya suatu Penutupan di mana Anda akan menentukan istilah pencarian Anda.
|
||||||
|
|
||||||
|
Jika Anda misalnya ingin menemukan semua item dengan id 1:
|
||||||
|
|
||||||
|
```php
|
||||||
|
$cart->search(function ($cartItem, $rowId) {
|
||||||
|
return $cartItem->id === 1;
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
Seperti yang Anda lihat, Penutupan akan menerima dua parameter. Yang pertama adalah Item Keranjang untuk melakukan pemeriksaan terhadap. Parameter kedua adalah rowId dari CartItem ini.
|
||||||
|
|
||||||
|
** Metode ini akan mengembalikan Koleksi yang berisi semua CartItems yang ditemukan **
|
||||||
|
|
||||||
|
Cara pencarian ini memberi Anda kontrol total atas proses pencarian dan memberi Anda kemampuan untuk membuat pencarian yang sangat tepat dan spesifik.
|
||||||
|
|
||||||
|
### Cart :: setTax ($ rowId, $ taxRate)
|
||||||
|
|
||||||
|
Anda dapat menggunakan metode `setTax ()` untuk mengubah tarif pajak yang berlaku untuk CartItem. Ini akan menimpa nilai yang ditetapkan dalam file konfigurasi.
|
||||||
|
|
||||||
|
```php
|
||||||
|
Cart::setTax($rowId, 21);
|
||||||
|
$cart->setTax($rowId, 21);
|
||||||
|
```
|
||||||
|
|
||||||
|
### Cart::setGlobalTax($taxRate)
|
||||||
|
|
||||||
|
Anda dapat menggunakan metode `setGlobalTax ()` untuk mengubah tarif pajak untuk semua item di troli. Item baru juga akan menerima setGlobalTax.
|
||||||
|
|
||||||
|
```php
|
||||||
|
Cart::setGlobalTax(21);
|
||||||
|
$cart->setGlobalTax(21);
|
||||||
|
```
|
||||||
|
|
||||||
|
### Cart::setGlobalDiscount($discountRate)
|
||||||
|
|
||||||
|
Anda dapat menggunakan metode `setGlobalDiscount ()` untuk mengubah tingkat diskonto untuk semua item di troli. Barang baru akan menerima diskon juga.
|
||||||
|
|
||||||
|
```php
|
||||||
|
Cart::setGlobalDiscount(50);
|
||||||
|
$cart->setGlobalDiscount(50);
|
||||||
|
```
|
||||||
|
|
||||||
|
### Cart::setDiscount($rowId, $taxRate)
|
||||||
|
|
||||||
|
Anda dapat menggunakan metode `setDiscount ()` untuk mengubah tingkat diskonto yang menerapkan CartItem. Perlu diingat bahwa nilai ini akan berubah jika Anda menetapkan diskon global untuk Keranjang sesudahnya.
|
||||||
|
|
||||||
|
```php
|
||||||
|
Cart::setDiscount($rowId, 21);
|
||||||
|
$cart->setDiscount($rowId, 21);
|
||||||
|
```
|
||||||
|
|
||||||
|
### Buyable
|
||||||
|
|
||||||
|
Untuk kenyamanan menambahkan item yang lebih cepat ke troli dan asosiasi otomatisnya, model Anda harus mengimplementasikan antarmuka `Dapat Dibeli` Anda dapat menggunakan sifat `CanBeBought` untuk mengimplementasikan metode yang diperlukan tetapi perlu diingat bahwa ini akan menggunakan bidang yang telah ditentukan pada model Anda untuk nilai yang diperlukan.
|
||||||
|
|
||||||
|
```php
|
||||||
|
<?php
|
||||||
|
namespace App\Models;
|
||||||
|
|
||||||
|
use Gloudemans\Shoppingcart\Contracts\Buyable;
|
||||||
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
|
||||||
|
class Product extends Model implements Buyable {
|
||||||
|
use Gloudemans\Shoppingcart\CanBeBought;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Jika sifat tidak berfungsi pada model atau Anda tidak dapat memetakan bidang secara manual model harus menerapkan metode antarmuka `Buy Able`. Untuk melakukannya, ia harus mengimplementasikan fungsi-fungsi tersebut:
|
||||||
|
|
||||||
|
```php
|
||||||
|
public function getBuyableIdentifier(){
|
||||||
|
return $this->id;
|
||||||
|
}
|
||||||
|
public function getBuyableDescription(){
|
||||||
|
return $this->name;
|
||||||
|
}
|
||||||
|
public function getBuyablePrice(){
|
||||||
|
return $this->price;
|
||||||
|
}
|
||||||
|
public function getBuyableWeight(){
|
||||||
|
return $this->weight;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Contoh:
|
||||||
|
|
||||||
|
```php
|
||||||
|
<?php
|
||||||
|
namespace App\Models;
|
||||||
|
|
||||||
|
use Gloudemans\Shoppingcart\Contracts\Buyable;
|
||||||
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
|
||||||
|
class Product extends Model implements Buyable {
|
||||||
|
public function getBuyableIdentifier($options = null) {
|
||||||
|
return $this->id;
|
||||||
|
}
|
||||||
|
public function getBuyableDescription($options = null) {
|
||||||
|
return $this->name;
|
||||||
|
}
|
||||||
|
public function getBuyablePrice($options = null) {
|
||||||
|
return $this->price;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Collections
|
||||||
|
|
||||||
|
Dalam beberapa kasus, Keranjang akan mengembalikan kepada Anda Koleksi. Ini hanya Koleksi Laravel sederhana, sehingga semua metode yang dapat Anda panggil pada Koleksi Laravel juga tersedia pada hasilnya.
|
||||||
|
|
||||||
|
Sebagai contoh, Anda dapat dengan cepat mendapatkan jumlah produk unik dalam keranjang:
|
||||||
|
|
||||||
|
```php
|
||||||
|
Cart::content()->count();
|
||||||
|
```
|
||||||
|
|
||||||
|
Atau Anda dapat mengelompokkan konten berdasarkan id produk:
|
||||||
|
|
||||||
|
```php
|
||||||
|
Cart::content()->groupBy('id');
|
||||||
|
```
|
||||||
|
|
||||||
|
## Instances
|
||||||
|
|
||||||
|
Paket-paket mendukung beberapa instance dari kereta. Cara kerjanya seperti ini:
|
||||||
|
|
||||||
|
Anda dapat mengatur instance keranjang saat ini dengan memanggil `Cart :: instance ('newInstance')`. Mulai saat ini, instance aktif dari cart adalah `newInstance`, jadi ketika Anda menambah, menghapus, atau mendapatkan konten dari cart, Anda bekerja dengan instance` newInstance` dari cart.
|
||||||
|
Jika Anda ingin mengganti instance, Anda cukup memanggil `Cart :: instance ('otherInstance')` lagi, dan Anda bekerja dengan `otherInstance` lagi.
|
||||||
|
|
||||||
|
Contoh Kecil:
|
||||||
|
|
||||||
|
```php
|
||||||
|
Cart::instance('shopping')->add('192ao12', 'Product 1', 1, 9.99, 550);
|
||||||
|
|
||||||
|
// Get the content of the 'shopping' cart
|
||||||
|
Cart::content();
|
||||||
|
|
||||||
|
Cart::instance('wishlist')->add('sdjk922', 'Product 2', 1, 19.95, 550, ['size' => 'medium']);
|
||||||
|
|
||||||
|
// Get the content of the 'wishlist' cart
|
||||||
|
Cart::content();
|
||||||
|
|
||||||
|
// If you want to get the content of the 'shopping' cart again
|
||||||
|
Cart::instance('shopping')->content();
|
||||||
|
|
||||||
|
// And the count of the 'wishlist' cart again
|
||||||
|
Cart::instance('wishlist')->count();
|
||||||
|
```
|
||||||
|
|
||||||
|
Anda juga dapat menggunakan Kontrak `InstanceIdentifier` untuk memperpanjang Model yang diinginkan untuk menetapkan / membuat instance Cart untuknya. Ini juga memungkinkan untuk secara langsung mengatur diskon global.
|
||||||
|
```
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App;
|
||||||
|
...
|
||||||
|
use Illuminate\Foundation\Auth\User as Authenticatable;
|
||||||
|
use Gloudemans\Shoppingcart\Contracts\InstanceIdentifier;
|
||||||
|
|
||||||
|
class User extends Authenticatable implements InstanceIdentifier
|
||||||
|
{
|
||||||
|
...
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the unique identifier to load the Cart from
|
||||||
|
*
|
||||||
|
* @return int|string
|
||||||
|
*/
|
||||||
|
public function getInstanceIdentifier($options = null)
|
||||||
|
{
|
||||||
|
return $this->email;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the unique identifier to load the Cart from
|
||||||
|
*
|
||||||
|
* @return int|string
|
||||||
|
*/
|
||||||
|
public function getInstanceGlobalDiscount($options = null)
|
||||||
|
{
|
||||||
|
return $this->discountRate ?: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Inside Controller
|
||||||
|
$user = \Auth::user();
|
||||||
|
$cart = Cart::instance($user);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
**N.B. Ingatlah bahwa troli tetap berada di set instance terakhir selama Anda tidak menyetel yang berbeda selama eksekusi skrip.**
|
||||||
|
|
||||||
|
**N.B.2 Contoh cart default disebut `default`, jadi ketika Anda tidak menggunakan instance,` Cart :: konten (); `sama dengan` Cart :: instance ('default') -> konten () `.**
|
||||||
|
|
||||||
|
## Models
|
||||||
|
|
||||||
|
Karena sangat nyaman untuk dapat secara langsung mengakses model dari CartItem, apakah mungkin untuk mengaitkan model dengan barang-barang di dalam kereta. Katakanlah Anda memiliki model `Produk` di aplikasi Anda. Dengan metode `associate ()`, Anda dapat memberi tahu troli bahwa item di troli, terkait dengan model `Product`.
|
||||||
|
|
||||||
|
Dengan begitu Anda dapat mengakses model Anda langsung dari `CartItem`!
|
||||||
|
|
||||||
|
Model ini dapat diakses melalui properti `model` di CartItem.
|
||||||
|
|
||||||
|
**Jika model Anda mengimplementasikan antarmuka `Buy Able` dan Anda menggunakan model Anda untuk menambahkan item ke troli, itu akan dikaitkan secara otomatis.**
|
||||||
|
|
||||||
|
Berikut adalah contoh:
|
||||||
|
|
||||||
|
```php
|
||||||
|
|
||||||
|
// First we'll add the item to the cart.
|
||||||
|
$cartItem = Cart::add('293ad', 'Product 1', 1, 9.99, 550, ['size' => 'large']);
|
||||||
|
|
||||||
|
// Next we associate a model with the item.
|
||||||
|
Cart::associate($cartItem->rowId, 'Product');
|
||||||
|
|
||||||
|
// Or even easier, call the associate method on the CartItem!
|
||||||
|
$cartItem->associate('Product');
|
||||||
|
|
||||||
|
// You can even make it a one-liner
|
||||||
|
Cart::add('293ad', 'Product 1', 1, 9.99, 550, ['size' => 'large'])->associate('Product');
|
||||||
|
|
||||||
|
// Now, when iterating over the content of the cart, you can access the model.
|
||||||
|
foreach(Cart::content() as $row) {
|
||||||
|
echo 'You have ' . $row->qty . ' items of ' . $row->model->name . ' with description: "' . $row->model->description . '" in your cart.';
|
||||||
|
}
|
||||||
|
```
|
||||||
|
## Database
|
||||||
|
|
||||||
|
- [Config](#configuration)
|
||||||
|
- [Storing the cart](#storing-the-cart)
|
||||||
|
- [Restoring the cart](#restoring-the-cart)
|
||||||
|
|
||||||
|
### Konfigurasi
|
||||||
|
Untuk menyimpan keranjang ke dalam basis data sehingga Anda dapat mengambilnya nanti, paket perlu mengetahui koneksi basis data yang digunakan dan apa nama tabelnya.
|
||||||
|
Secara default paket akan menggunakan koneksi database default dan menggunakan tabel bernama `shoppingcart`.
|
||||||
|
Jika Anda ingin mengubah opsi ini, Anda harus menerbitkan file `config`.
|
||||||
|
|
||||||
|
php artisan vendor:publish --provider="Gloudemans\Shoppingcart\ShoppingcartServiceProvider" --tag="config"
|
||||||
|
|
||||||
|
Ini akan memberi Anda file konfigurasi `cart.php` di mana Anda dapat melakukan perubahan.
|
||||||
|
|
||||||
|
Untuk memudahkan hidup Anda, paket ini juga menyertakan `migration` yang siap digunakan yang dapat Anda terbitkan dengan menjalankan:
|
||||||
|
|
||||||
|
php artisan vendor:publish --provider="Gloudemans\Shoppingcart\ShoppingcartServiceProvider" --tag="migrations"
|
||||||
|
|
||||||
|
Ini akan menempatkan file migrasi tabel `shoppingcart` ke direktori` database / migrations`. Sekarang yang harus Anda lakukan adalah menjalankan `php artisan migrate` untuk memigrasi basis data Anda.
|
||||||
|
|
||||||
|
### Menyimpan ke Troli
|
||||||
|
Untuk menyimpan instance kereta ke dalam database, Anda harus memanggil metode `store ($ identifier)`. Di mana `$ identifier` adalah kunci acak, misalnya id atau nama pengguna pengguna.
|
||||||
|
|
||||||
|
Cart::store('username');
|
||||||
|
|
||||||
|
// To store a cart instance named 'wishlist'
|
||||||
|
Cart::instance('wishlist')->store('username');
|
||||||
|
|
||||||
|
### Mengembalikan ke Troli
|
||||||
|
Jika Anda ingin mengambil keranjang dari database dan mengembalikannya, yang harus Anda lakukan adalah memanggil `restore ($ identifier)` di mana `$ identifier` adalah kunci yang Anda tentukan untuk metode` store`.
|
||||||
|
|
||||||
|
Cart::restore('username');
|
||||||
|
|
||||||
|
// To restore a cart instance named 'wishlist'
|
||||||
|
Cart::instance('wishlist')->restore('username');
|
||||||
|
|
||||||
|
### Menggabungkan Troli
|
||||||
|
Jika Anda ingin menggabungkan keranjang dengan keranjang lain dari basis data, yang harus Anda lakukan adalah memanggil `gabungan ($ identifier)` di mana `$ identifier` adalah kunci yang Anda tentukan untuk metode` store`. Anda juga dapat menentukan apakah Anda ingin mempertahankan potongan harga dan tarif pajak item.
|
||||||
|
|
||||||
|
// Merge the contents of 'savedcart' into 'username'.
|
||||||
|
Cart::instance('username')->merge('savedcart', $keepDiscount, $keepTaxrate);
|
||||||
|
|
||||||
|
## Pengecualian
|
||||||
|
|
||||||
|
Paket Cart akan mengeluarkan pengecualian jika terjadi kesalahan. Dengan cara ini lebih mudah untuk men-debug kode Anda menggunakan paket Cart atau untuk menangani kesalahan berdasarkan pada jenis pengecualian. Paket-paket Cart dapat membuang pengecualian berikut:
|
||||||
|
|
||||||
|
| Exception | Reason |
|
||||||
|
| ---------------------------- | ---------------------------------------------------------------------------------- |
|
||||||
|
| *CartAlreadyStoredException* | Saat mencoba menyimpan keranjang yang sudah disimpan menggunakan pengenal yang ditentukan |
|
||||||
|
| *InvalidRowIDException* | Ketika rowId yang diteruskan tidak ada dalam instance troli saat ini |
|
||||||
|
| *UnknownModelException* | Saat Anda mencoba mengaitkan model yang tidak ada dengan Item Keranjang. |
|
||||||
|
|
||||||
|
## Events
|
||||||
|
|
||||||
|
Troli juga memiliki event. Ada lima event yang bisa Anda lakukan.
|
||||||
|
|
||||||
|
| Event | Fired | Parameter |
|
||||||
|
| ------------- | ---------------------------------------- | -------------------------------- |
|
||||||
|
| cart.added | Saat item ditambahkan ke troli. | The `CartItem` that was added. |
|
||||||
|
| cart.updated | Ketika item dalam troli diperbarui. | The `CartItem` that was updated. |
|
||||||
|
| cart.removed | Ketika item dalam troli dihapus. | The `CartItem` that was removed. |
|
||||||
|
| cart.stored | Ketika isi trol disimpan. | - |
|
||||||
|
| cart.restored | Ketika konten keranjang Dikembalikan. | - |
|
||||||
|
|
||||||
|
## Contoh
|
||||||
|
|
||||||
|
Di bawah ini adalah sedikit contoh cara membuat daftar isi keranjang dalam sebuah tabel:
|
||||||
|
|
||||||
|
```php
|
||||||
|
|
||||||
|
// Tambahkan beberapa item di Kontroler Anda.
|
||||||
|
Cart::add('192ao12', 'Product 1', 1, 9.99);
|
||||||
|
Cart::add('1239ad0', 'Product 2', 2, 5.95, ['size' => 'large']);
|
||||||
|
|
||||||
|
// Tampilkan konten dalam Tampilan.
|
||||||
|
<table>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Product</th>
|
||||||
|
<th>Qty</th>
|
||||||
|
<th>Price</th>
|
||||||
|
<th>Subtotal</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
|
||||||
|
<tbody>
|
||||||
|
|
||||||
|
<?php foreach(Cart::content() as $row) :?>
|
||||||
|
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<p><strong><?php echo $row->name; ?></strong></p>
|
||||||
|
<p><?php echo ($row->options->has('size') ? $row->options->size : ''); ?></p>
|
||||||
|
</td>
|
||||||
|
<td><input type="text" value="<?php echo $row->qty; ?>"></td>
|
||||||
|
<td>$<?php echo $row->price; ?></td>
|
||||||
|
<td>$<?php echo $row->total; ?></td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
<?php endforeach;?>
|
||||||
|
|
||||||
|
</tbody>
|
||||||
|
|
||||||
|
<tfoot>
|
||||||
|
<tr>
|
||||||
|
<td colspan="2"> </td>
|
||||||
|
<td>Subtotal</td>
|
||||||
|
<td><?php echo Cart::subtotal(); ?></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td colspan="2"> </td>
|
||||||
|
<td>Tax</td>
|
||||||
|
<td><?php echo Cart::tax(); ?></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td colspan="2"> </td>
|
||||||
|
<td>Total</td>
|
||||||
|
<td><?php echo Cart::total(); ?></td>
|
||||||
|
</tr>
|
||||||
|
</tfoot>
|
||||||
|
</table>
|
||||||
|
```
|
||||||
626
README_uk-UA.md
Normal file
626
README_uk-UA.md
Normal file
@@ -0,0 +1,626 @@
|
|||||||
|
## LaravelShoppingcart
|
||||||
|
[](https://travis-ci.org/bumbummen99/LaravelShoppingcart)
|
||||||
|
[](https://codecov.io/gh/bumbummen99/LaravelShoppingcart)
|
||||||
|
[](https://styleci.io/repos/152610878)
|
||||||
|
[](https://packagist.org/packages/bumbummen99/shoppingcart)
|
||||||
|
[](https://packagist.org/packages/bumbummen99/shoppingcart)
|
||||||
|
[](https://packagist.org/packages/bumbummen99/shoppingcart)
|
||||||
|
[](https://packagist.org/packages/bumbummen99/shoppingcart)
|
||||||
|
|
||||||
|
Цей репозиторій є відгалуженням [Crinsane's LaravelShoppingcart](https://github.com/Crinsane/LaravelShoppingcart) та містить додаткові незначні доповнення, сумісні з Laravel 6.
|
||||||
|
|
||||||
|
## Встановлення
|
||||||
|
|
||||||
|
Встановіть [пакет](https://packagist.org/packages/bumbummen99/shoppingcart) скориставшись [Завантажувачем](http://getcomposer.org/).
|
||||||
|
|
||||||
|
Для запуску Завантажувача, скористайтеся командою у Терміналі:
|
||||||
|
|
||||||
|
composer require bumbummen99/shoppingcart
|
||||||
|
|
||||||
|
Тепер ви готові розпочати користуватися кошиком у вашому застосунку.
|
||||||
|
|
||||||
|
**Починаючи з версії 2 даного пакету з'явилася можливість впровадження залежності для впровадження екземпляра класу Кошик (Cart) до вашого контролера або іншого класу**
|
||||||
|
|
||||||
|
## Огляд
|
||||||
|
Щоб детальніше ознайомитися LaravelShoppingcart, можете пройти за посиланнями
|
||||||
|
|
||||||
|
* [Застосування](#usage)
|
||||||
|
* [Колекції](#collections)
|
||||||
|
* [Екземпляри](#instances)
|
||||||
|
* [Моделі](#models)
|
||||||
|
* [База даних](#database)
|
||||||
|
* [Винятки](#exceptions)
|
||||||
|
* [Події](#events)
|
||||||
|
* [Приклад](#example)
|
||||||
|
|
||||||
|
## Застосування
|
||||||
|
|
||||||
|
Кошик (Cart) дозволяє вам скористатися наступними методами:
|
||||||
|
|
||||||
|
### Cart::add()
|
||||||
|
|
||||||
|
Додавати покупки у кошик дуже зручно - достатньо скористатися методом `add()`, який приймає різноманітні параметри.
|
||||||
|
|
||||||
|
У найпростішій формі метода достатньо вказати ідентифікатор товару, назву, кількість, ціну та вагу товару, який ви хочете додати у кошик.
|
||||||
|
|
||||||
|
```php
|
||||||
|
Cart::add('293ad', 'Product 1', 1, 9.99, 550);
|
||||||
|
```
|
||||||
|
|
||||||
|
У якості додаткового п'ятого параметра можна задати додаткові опції, наприклад, щоб додати декілька одиниць з однаковим ідентифікатором, але, наприклад, різного розміру.
|
||||||
|
|
||||||
|
```php
|
||||||
|
Cart::add('293ad', 'Product 1', 1, 9.99, 550, ['size' => 'large']);
|
||||||
|
```
|
||||||
|
|
||||||
|
**Метод `add()` повертає екземпляр CartItems того товару, який ви щойно додали у кошик.**
|
||||||
|
|
||||||
|
Можливо, вам більше до вподоби додавати товари, використовуючи масив? Якщо масив містить усі необхідні поля, ви можете передавати масив у цей метод. Поле із додатковими опціями є необов'язковим.
|
||||||
|
|
||||||
|
```php
|
||||||
|
Cart::add(['id' => '293ad', 'name' => 'Product 1', 'qty' => 1, 'price' => 9.99, 'weight' => 550, 'options' => ['size' => 'large']]);
|
||||||
|
```
|
||||||
|
|
||||||
|
У версії 2 пакета з'явилася нова можливість для роботи з інтерфейсом [Buyable](#buyable). Такий функціонал з'являється за рахунок того, що модель запускає інтерфейс [Buyable](#buyable), який дозволить імплементувати декілька методів, з яких пакет знатиме як отримати ідентифікатор, назву та ціну з вашої моделі.
|
||||||
|
Таким чином, ви можете передати метод `add()` та кількість одиниць товару до моделі, а вона автоматично додасть їх до кошика.
|
||||||
|
|
||||||
|
**Додатковий бонус інтерфейсу - автоматичне об'єднання моделі з CartItems**
|
||||||
|
|
||||||
|
```php
|
||||||
|
Cart::add($product, 1, ['size' => 'large']);
|
||||||
|
```
|
||||||
|
У якості додаткового параметра, ви можете внести опції.
|
||||||
|
```php
|
||||||
|
Cart::add($product, 1, ['size' => 'large']);
|
||||||
|
```
|
||||||
|
|
||||||
|
Нарешті, ви також можете додавати до кошика декілька одиниць водночас. Для цього потрібно передати у `add()` масив масивів або масив Buyables, і їх буде додано в кошик.
|
||||||
|
|
||||||
|
**Під час додавання декількох одиниць товару в кошик, метод `add()` повертає масив CartItems.**
|
||||||
|
|
||||||
|
```php
|
||||||
|
Cart::add([
|
||||||
|
['id' => '293ad', 'name' => 'Product 1', 'qty' => 1, 'price' => 10.00, 'weight' => 550],
|
||||||
|
['id' => '4832k', 'name' => 'Product 2', 'qty' => 1, 'price' => 10.00, 'weight' => 550, 'options' => ['size' => 'large']]
|
||||||
|
]);
|
||||||
|
|
||||||
|
Cart::add([$product1, $product2]);
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
### Cart::update()
|
||||||
|
|
||||||
|
Щоб оновити товар у кошику, вам знадобиться ідентифікатор рядка (rowId) даного товару.
|
||||||
|
Далі ви можете скористатися методом `update()` для того, щоб оновити його.
|
||||||
|
|
||||||
|
Якщо ви просто хочете оновити кількість товару, вам необхідно передати у метод `update()` rowId і оновлену кількість:
|
||||||
|
|
||||||
|
```php
|
||||||
|
$rowId = 'da39a3ee5e6b4b0d3255bfef95601890afd80709';
|
||||||
|
|
||||||
|
Cart::update($rowId, 2); // Will update the quantity
|
||||||
|
```
|
||||||
|
|
||||||
|
Якщо ви хочете оновити більше атрибутів товару, вам потрібно або передати у метод `update()` масив або `Buyable` у якості другого параметра. Таким чином, ви можете оновити всю інформацію про товар за заданим rowId.
|
||||||
|
|
||||||
|
```php
|
||||||
|
Cart::update($rowId, ['name' => 'Product 1']); // Will update the name
|
||||||
|
|
||||||
|
Cart::update($rowId, $product); // Will update the id, name and price
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
### Cart::remove()
|
||||||
|
|
||||||
|
Щоб вилучити товар з кошика, вам знову знадобиться rowId. Такий rowId потрібно передати у метод `remove()`, який автоматично вилучить товар із кошика.
|
||||||
|
|
||||||
|
```php
|
||||||
|
$rowId = 'da39a3ee5e6b4b0d3255bfef95601890afd80709';
|
||||||
|
|
||||||
|
Cart::remove($rowId);
|
||||||
|
```
|
||||||
|
|
||||||
|
### Cart::get()
|
||||||
|
|
||||||
|
Якщо ви хочете отримати товар із кошика, використовуючи його rowId, вам потрібно застосувати метод `get()` щодо кошика і передати в нього rowId.
|
||||||
|
|
||||||
|
```php
|
||||||
|
$rowId = 'da39a3ee5e6b4b0d3255bfef95601890afd80709';
|
||||||
|
|
||||||
|
Cart::get($rowId);
|
||||||
|
```
|
||||||
|
|
||||||
|
### Cart::content()
|
||||||
|
|
||||||
|
Вам також може знадобитися можливість отримати інформацію про вміст кошика. Для цього вам потрібно скористатися методом `content`. Такий метод повертає колекцію CartItems, ви можете перебирати вміст такої колекції і відобразити вміст кошика для ваших клієнтів.
|
||||||
|
|
||||||
|
```php
|
||||||
|
Cart::content();
|
||||||
|
```
|
||||||
|
|
||||||
|
Даний метод повертає вміст поточного екземпляра кошика, якщо ви хочете вміст іншого екземпляра, вам потрібно зв'язати виклики.
|
||||||
|
|
||||||
|
```php
|
||||||
|
Cart::instance('wishlist')->content();
|
||||||
|
```
|
||||||
|
|
||||||
|
### Cart::destroy()
|
||||||
|
|
||||||
|
Якщо ви хочете остаточно вилучити вміст кошика, ви можете застосувати метод `destroy()` щодо кошика. Даний метод вилучить всі CartItems з кошика для поточного екземпляра кошика.
|
||||||
|
|
||||||
|
```php
|
||||||
|
Cart::destroy();
|
||||||
|
```
|
||||||
|
|
||||||
|
### Cart::weight()
|
||||||
|
|
||||||
|
Метод `weight()` можна застосувати, щоб отримати розрахунок ваги усіх товарів у кошику, за умови, що задано вагу і кількість одиниць.
|
||||||
|
|
||||||
|
```php
|
||||||
|
Cart::weight();
|
||||||
|
```
|
||||||
|
|
||||||
|
Даний метод автоматично відформатує результат, який ви можете поправити за допомогою трьох додаткових параметрів.
|
||||||
|
|
||||||
|
```php
|
||||||
|
Cart::weight($decimals, $decimalSeperator, $thousandSeperator);
|
||||||
|
```
|
||||||
|
|
||||||
|
Ви можете задати формат чисел за замовчуванням у файлі з конфігураціями.
|
||||||
|
|
||||||
|
**Якщо ви не використовуєте Фасад, але застосовуєте впровадження залежності, наприклад, у вашому Контролері, ви також можете отримати інформацію про вагу товарів через `$cart->weight`**
|
||||||
|
|
||||||
|
### Cart::total()
|
||||||
|
|
||||||
|
Метод `total()` можна застосовувати, щоб отримати розрахунок вартості усіх товарів у кошику, за умови, що задані ціна і кількість одиниць.
|
||||||
|
|
||||||
|
```php
|
||||||
|
Cart::total();
|
||||||
|
```
|
||||||
|
|
||||||
|
Даний метод автоматично відформатує результат, який ви можете поправити за допомогою трьох додаткових параметрів.
|
||||||
|
|
||||||
|
```php
|
||||||
|
Cart::total($decimals, $decimalSeparator, $thousandSeparator);
|
||||||
|
```
|
||||||
|
|
||||||
|
Ви можете задати формат чисел за замовчуванням у файлі з конфігураціями.
|
||||||
|
|
||||||
|
**Якщо ви не використовуєте Фасад, але застосовуєте впровадження залежності, наприклад, у вашому Контролері, ви також можете отримати інформацію про вартість товарів через `$cart->total`**
|
||||||
|
|
||||||
|
### Cart::tax()
|
||||||
|
|
||||||
|
Метод `tax()` можна застосовувати, щоб отримати розрахунок суми податків для усіх товарів у кошику, за умови, що задані ціна і кількість одиниць.
|
||||||
|
|
||||||
|
```php
|
||||||
|
Cart::tax();
|
||||||
|
```
|
||||||
|
|
||||||
|
Даний метод автоматично відформатує результат, який ви можете поправити за допомогою трьох додаткових параметрів.
|
||||||
|
|
||||||
|
```php
|
||||||
|
Cart::tax($decimals, $decimalSeparator, $thousandSeparator);
|
||||||
|
```
|
||||||
|
|
||||||
|
Ви можете задати формат чисел за замовчуванням у файлі з конфігураціями.
|
||||||
|
|
||||||
|
**Якщо ви не використовуєте Фасад, але застосовуєте впровадження залежності, наприклад, у вашому Контролері, ви також можете отримати інформацію про суму податку на товари через `$cart->tax`**
|
||||||
|
|
||||||
|
### Cart::subtotal()
|
||||||
|
|
||||||
|
Метод `subtotal()` можна застосовувати, щоб отримати розрахунок вартості усіх товарів у кошику, без урахування суми податку.
|
||||||
|
|
||||||
|
```php
|
||||||
|
Cart::subtotal();
|
||||||
|
```
|
||||||
|
|
||||||
|
Даний метод автоматично відформатує результат, який ви можете поправити за допомогою трьох додаткових параметрів.
|
||||||
|
|
||||||
|
```php
|
||||||
|
Cart::subtotal($decimals, $decimalSeparator, $thousandSeparator);
|
||||||
|
```
|
||||||
|
|
||||||
|
Ви можете задати формат чисел за замовчуванням у файлі з конфігураціями.
|
||||||
|
|
||||||
|
**Якщо ви не використовуєте Фасад, але застосовуєте впровадження залежності, наприклад, у вашому Контролері, ви також можете отримати інформацію про вартість усіх товарів без урахування суми податків через `$cart->subtotal`**
|
||||||
|
|
||||||
|
### Cart::discount()
|
||||||
|
|
||||||
|
Метод `discount()` можна застосовувати, щоб отримати розрахунок знижки на усі товари у кошику.
|
||||||
|
|
||||||
|
```php
|
||||||
|
Cart::discount();
|
||||||
|
```
|
||||||
|
|
||||||
|
Даний метод автоматично відформатує результат, який ви можете поправити за допомогою трьох додаткових параметрів.
|
||||||
|
|
||||||
|
```php
|
||||||
|
Cart::discount($decimals, $decimalSeparator, $thousandSeparator);
|
||||||
|
```
|
||||||
|
|
||||||
|
Ви можете задати формат чисел за замовчуванням у файлі з конфігураціями.
|
||||||
|
|
||||||
|
**Якщо ви не використовуєте Фасад, але застосовуєте впровадження залежності, наприклад, у вашому Контролері, ви також можете отримати інформацію про вартість усіх товарів з урахуванням знижки `$cart->discount`**
|
||||||
|
|
||||||
|
### Cart::initial()
|
||||||
|
|
||||||
|
Метод `initial()` можна застосовувати, щоб отримати розрахунок вартості усіх товарів до застосування знижки.
|
||||||
|
|
||||||
|
```php
|
||||||
|
Cart::initial();
|
||||||
|
```
|
||||||
|
|
||||||
|
Даний метод автоматично відформатує результат, який ви можете поправити за допомогою трьох додаткових параметрів.
|
||||||
|
|
||||||
|
```php
|
||||||
|
Cart::initial($decimals, $decimalSeparator, $thousandSeparator);
|
||||||
|
```
|
||||||
|
|
||||||
|
Ви можете задати формат чисел за замовчуванням у файлі з конфігураціями.
|
||||||
|
|
||||||
|
**Якщо ви не використовуєте Фасад, але застосовуєте впровадження залежності, наприклад, у вашому Контролері, ви також можете отримати інформацію про вартість усіх товарів до застосування знижки `$cart->initial`**
|
||||||
|
|
||||||
|
### Cart::count()
|
||||||
|
|
||||||
|
Метод `count()` можна застосовувати, щоб дізнатися кількість одиниць товарів у кошику. Даний метод повертає загальну кількість одиниць товарів у кошику. Тобто якщо ви додали 2 книжки і 1 сорочку, цей метод поверне 3 одиниці.
|
||||||
|
|
||||||
|
```php
|
||||||
|
Cart::count();
|
||||||
|
$cart->count();
|
||||||
|
```
|
||||||
|
|
||||||
|
### Cart::search()
|
||||||
|
|
||||||
|
Метод `search()` можна застосовувати, щоб знайти одиницю товару у кошику.
|
||||||
|
|
||||||
|
**Даний метод було змінено у версії 2**
|
||||||
|
|
||||||
|
У своїй імплементації, цей метод застосовує метод фільтрування з класу Laravel Collection. Це означає, що вам потрібно передати замикання (Closure) для даного методу, де ви зазначите умови для пошуку.
|
||||||
|
|
||||||
|
Наприклад, якщо ви хочете знайти всі одиниці товару з ідентифікатором 1:
|
||||||
|
|
||||||
|
```php
|
||||||
|
$cart->search(function ($cartItem, $rowId) {
|
||||||
|
return $cartItem->id === 1;
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
Як ви можете побачити, замикання отримає 2 параметра. Перший - CartItem для здійснення перевірки щодо нього. Другий параметр - rowId даного CartItem.
|
||||||
|
|
||||||
|
**Даний метод повертає колекцію, яка вміщує всі CartItems, які було знайдено**
|
||||||
|
|
||||||
|
Такий спосіб пошуку надає вам повний контроль над процесом пошуку та дозволяє здійснювати дуже точні та конкретні пошуки.
|
||||||
|
|
||||||
|
### Cart::setTax($rowId, $taxRate)
|
||||||
|
|
||||||
|
Метод `setTax()` можна застосовувати, щоб змінювати ставку оподаткування, яка застосовується до CartItem. Така операція перезапише значення встановлене у файлі з конфігураціями.
|
||||||
|
|
||||||
|
```php
|
||||||
|
Cart::setTax($rowId, 21);
|
||||||
|
$cart->setTax($rowId, 21);
|
||||||
|
```
|
||||||
|
|
||||||
|
### Cart::setGlobalTax($taxRate)
|
||||||
|
|
||||||
|
Метод `setGlobalTax()` можна застосовувати, щоб змінити ставку оподаткування для усіх найменувать у кошику. Нові найменування отримають значення setGlobalTax також.
|
||||||
|
|
||||||
|
```php
|
||||||
|
Cart::setGlobalTax(21);
|
||||||
|
$cart->setGlobalTax(21);
|
||||||
|
```
|
||||||
|
|
||||||
|
### Cart::setGlobalDiscount($discountRate)
|
||||||
|
|
||||||
|
Метод `setGlobalDiscount()` можна застосовувати для заміни ставки знижки щодо усіх найменувань у кошику. Нові найменування також отримуватимуть таку знижку.
|
||||||
|
|
||||||
|
```php
|
||||||
|
Cart::setGlobalDiscount(50);
|
||||||
|
$cart->setGlobalDiscount(50);
|
||||||
|
```
|
||||||
|
|
||||||
|
### Cart::setDiscount($rowId, $taxRate)
|
||||||
|
|
||||||
|
Застосування методу `setDiscount()` полягає у заміні ставки знижки, яка застосовується до CartItem. Зверніть увагу, що дане значення ставки знижки буде змінено, якщо ви згодом встановите глобальну знижку для Кошика (Cart).
|
||||||
|
|
||||||
|
```php
|
||||||
|
Cart::setDiscount($rowId, 21);
|
||||||
|
$cart->setDiscount($rowId, 21);
|
||||||
|
```
|
||||||
|
|
||||||
|
### Buyable
|
||||||
|
|
||||||
|
Для зручного швидкого додавання товарів до кошика та їхнього автоматичного об'єднання, ваша модель повинна запустити інтерфейс `Buyable`. Ви можете застосовувати `CanBeBought` трейт для імплементації необхідних методів, але зверніть увагу, що такі методи застосовуватимуть попередньо визначені поля у вашій моделі для необхідних значень.
|
||||||
|
```php
|
||||||
|
<?php
|
||||||
|
namespace App\Models;
|
||||||
|
|
||||||
|
use Gloudemans\Shoppingcart\Contracts\Buyable;
|
||||||
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
|
||||||
|
class Product extends Model implements Buyable {
|
||||||
|
use Gloudemans\Shoppingcart\CanBeBought;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Якщо трейт не працює на вашій моделі або ви хочете вручну перенести (мапувати) поля, модель повинна запустити методи інтерфейсу `Buyable`. Для цього, модель повинна імплементувати наступні функції:
|
||||||
|
|
||||||
|
```php
|
||||||
|
public function getBuyableIdentifier(){
|
||||||
|
return $this->id;
|
||||||
|
}
|
||||||
|
public function getBuyableDescription(){
|
||||||
|
return $this->name;
|
||||||
|
}
|
||||||
|
public function getBuyablePrice(){
|
||||||
|
return $this->price;
|
||||||
|
}
|
||||||
|
public function getBuyableWeight(){
|
||||||
|
return $this->weight;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Приклад:
|
||||||
|
|
||||||
|
```php
|
||||||
|
<?php
|
||||||
|
namespace App\Models;
|
||||||
|
|
||||||
|
use Gloudemans\Shoppingcart\Contracts\Buyable;
|
||||||
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
|
||||||
|
class Product extends Model implements Buyable {
|
||||||
|
public function getBuyableIdentifier($options = null) {
|
||||||
|
return $this->id;
|
||||||
|
}
|
||||||
|
public function getBuyableDescription($options = null) {
|
||||||
|
return $this->name;
|
||||||
|
}
|
||||||
|
public function getBuyablePrice($options = null) {
|
||||||
|
return $this->price;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Колекції
|
||||||
|
|
||||||
|
Щодо багатьох екземплярів Кошик (Cart) повертає Колекцію, яка є простим видом Laravel Collection. Таким чином усі методи, які ви можете застосовувати щодо Laravel Collection, є також доступними у результаті операції.
|
||||||
|
|
||||||
|
Наприклад, ви можете швидко отримати кількість унікальних товарів у кошику:
|
||||||
|
|
||||||
|
```php
|
||||||
|
Cart::content()->count();
|
||||||
|
```
|
||||||
|
|
||||||
|
Або групувати вміст за ідентифікатором товару:
|
||||||
|
|
||||||
|
```php
|
||||||
|
Cart::content()->groupBy('id');
|
||||||
|
```
|
||||||
|
|
||||||
|
## Екземпляри
|
||||||
|
|
||||||
|
Пакет підтримує декілька екземплярів кошика. Як це працює:
|
||||||
|
|
||||||
|
Ви можете встановити поточний екземпляр кошика через виклик `Cart::instance('newInstance')`. З цього моменту, активний екземляр кошика буде `newInstance`, тому коли ви додаєте, вилучаєте або отримуєте інформацію щодо вмісту кошика, ви працюєте з екземпляром `newInstance` кошика.
|
||||||
|
Якщо ви хочете переключитися між екзмеплярами, ви можете викликати `Cart::instance('otherInstance')` ще раз, і ви знову працюватимете з `otherInstance`.
|
||||||
|
|
||||||
|
Короткий приклад:
|
||||||
|
|
||||||
|
```php
|
||||||
|
Cart::instance('shopping')->add('192ao12', 'Product 1', 1, 9.99, 550);
|
||||||
|
|
||||||
|
// Get the content of the 'shopping' cart
|
||||||
|
Cart::content();
|
||||||
|
|
||||||
|
Cart::instance('wishlist')->add('sdjk922', 'Product 2', 1, 19.95, 550, ['size' => 'medium']);
|
||||||
|
|
||||||
|
// Get the content of the 'wishlist' cart
|
||||||
|
Cart::content();
|
||||||
|
|
||||||
|
// If you want to get the content of the 'shopping' cart again
|
||||||
|
Cart::instance('shopping')->content();
|
||||||
|
|
||||||
|
// And the count of the 'wishlist' cart again
|
||||||
|
Cart::instance('wishlist')->count();
|
||||||
|
```
|
||||||
|
|
||||||
|
Ви також можете застосувати Контракт `InstanceIdentifier` для розширення бажаної моделі через призначення / створення екземпляру Кошика (Cart) для неї. Така дія також дозволить напряму встановлювати глобальну знижку.
|
||||||
|
```
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App;
|
||||||
|
...
|
||||||
|
use Illuminate\Foundation\Auth\User as Authenticatable;
|
||||||
|
use Gloudemans\Shoppingcart\Contracts\InstanceIdentifier;
|
||||||
|
|
||||||
|
class User extends Authenticatable implements InstanceIdentifier
|
||||||
|
{
|
||||||
|
...
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the unique identifier to load the Cart from
|
||||||
|
*
|
||||||
|
* @return int|string
|
||||||
|
*/
|
||||||
|
public function getInstanceIdentifier($options = null)
|
||||||
|
{
|
||||||
|
return $this->email;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the unique identifier to load the Cart from
|
||||||
|
*
|
||||||
|
* @return int|string
|
||||||
|
*/
|
||||||
|
public function getInstanceGlobalDiscount($options = null)
|
||||||
|
{
|
||||||
|
return $this->discountRate ?: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Inside Controller
|
||||||
|
$user = \Auth::user();
|
||||||
|
$cart = Cart::instance($user);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
**N.B. Зверніть увагу, що кошик залишається у стані останнього призначеного екземпляра, доки ви не встановите інший екземпляр протягом виконання скрипта.**
|
||||||
|
|
||||||
|
**N.B.2 За замовчуванням екземпляр кошика називається `default`, тому коли ви не використовуєте екземпляри, `Cart::content();` залишається таким самим як і `Cart::instance('default')->content()`.**
|
||||||
|
|
||||||
|
## Моделі
|
||||||
|
|
||||||
|
Через те, що можливість прямого доступу до моделі з CartItem може бути дуже зручною, виникає питання чи можливо об'єднати модель із товарами у кошику. Скажімо, у вашому застосунку є модель `Product`. Завдяки методу `associate()` ви можете вказати кошику, що товар у кошику об'єднаний з моделлю `Product`.
|
||||||
|
|
||||||
|
Таким чином ви можете отримати доступ до вашої моделі одразу з `CartItem`!
|
||||||
|
|
||||||
|
Доступ до моделі також можна отримати через властивість CartItem `model`.
|
||||||
|
|
||||||
|
**Якщо ваша модель запускає інтерфейс `Buyable` і ви використовували вашу модель для додавання товару до кошика, вони будуть об'єднані автоматично.**
|
||||||
|
|
||||||
|
Ось приклад:
|
||||||
|
|
||||||
|
```php
|
||||||
|
|
||||||
|
// First we'll add the item to the cart.
|
||||||
|
$cartItem = Cart::add('293ad', 'Product 1', 1, 9.99, 550, ['size' => 'large']);
|
||||||
|
|
||||||
|
// Next we associate a model with the item.
|
||||||
|
Cart::associate($cartItem->rowId, 'Product');
|
||||||
|
|
||||||
|
// Or even easier, call the associate method on the CartItem!
|
||||||
|
$cartItem->associate('Product');
|
||||||
|
|
||||||
|
// You can even make it a one-liner
|
||||||
|
Cart::add('293ad', 'Product 1', 1, 9.99, 550, ['size' => 'large'])->associate('Product');
|
||||||
|
|
||||||
|
// Now, when iterating over the content of the cart, you can access the model.
|
||||||
|
foreach(Cart::content() as $row) {
|
||||||
|
echo 'You have ' . $row->qty . ' items of ' . $row->model->name . ' with description: "' . $row->model->description . '" in your cart.';
|
||||||
|
}
|
||||||
|
```
|
||||||
|
## База даних
|
||||||
|
|
||||||
|
- [Конфігурації](#configuration)
|
||||||
|
- [Збереження кошика](#storing-the-cart)
|
||||||
|
- [Відновлення кошика](#restoring-the-cart)
|
||||||
|
|
||||||
|
### Конфігурації
|
||||||
|
Для збереження кошика до бази даних, щоб ви могли отримати його пізніше, пакет повинен знати яке підключення до бази даних використовувати і яка назва окремої таблиці.
|
||||||
|
За замовчуванням, пакет використовуватиме підключення до бази даних, яке вказане за замовчуванням, та використовуватиме таблицію `shoppingcart`.
|
||||||
|
Якщо ви хочете змінити ці значення, вам потрібно буде опублікувати файл з конфігураціями `config`.
|
||||||
|
|
||||||
|
php artisan vendor:publish --provider="Gloudemans\Shoppingcart\ShoppingcartServiceProvider" --tag="config"
|
||||||
|
|
||||||
|
Така дія створить вам файл з конфігураціями `cart.php`, в якому ви можете внести бажані зміни.
|
||||||
|
|
||||||
|
Щоб спростити ваше життя, пакет також включає готову до вжитку `migration`, яку можна опублікувати через запуск наступної команди:
|
||||||
|
|
||||||
|
php artisan vendor:publish --provider="Gloudemans\Shoppingcart\ShoppingcartServiceProvider" --tag="migrations"
|
||||||
|
|
||||||
|
Така дія розмістить файл з міграцією таблиці `shoppingcart` в директорію `database/migrations`. Все що вам залишається зробити, це запустити `php artisan migrate` для міграції вашої бази даних.
|
||||||
|
|
||||||
|
### Збереження кошика
|
||||||
|
Для збереження екземпляра кошика до бази даних, вам потрібно викликати метод `store($identifier) `. Де `$identifier` є випадковим ключем, наприклад, ідентифікатор або ім'я користувача.
|
||||||
|
|
||||||
|
Cart::store('username');
|
||||||
|
|
||||||
|
// To store a cart instance named 'wishlist'
|
||||||
|
Cart::instance('wishlist')->store('username');
|
||||||
|
|
||||||
|
### Відновлення кошика
|
||||||
|
Якщо ви хочете отримати кошик із бази даних і відновити його, вам знадобиться викликати метод `restore($identifier)`, де `$identifier` - це ключ, який ви зазначили у методі `store`.
|
||||||
|
|
||||||
|
Cart::restore('username');
|
||||||
|
|
||||||
|
// To restore a cart instance named 'wishlist'
|
||||||
|
Cart::instance('wishlist')->restore('username');
|
||||||
|
|
||||||
|
### Злиття кошиків
|
||||||
|
Якщо ви хочете злити кошик із іншим кошиком, збереженим у базі даних, вам знадобиться викликати метод `merge($identifier)`, де `$identifier` - це ключ, який ви зазначили у методі`store`. Ви також можете визначити чи хочете ви зберегти знижку і ставку оподаткування для товарів.
|
||||||
|
|
||||||
|
// Merge the contents of 'savedcart' into 'username'.
|
||||||
|
Cart::instance('username')->merge('savedcart', $keepDiscount, $keepTaxrate);
|
||||||
|
|
||||||
|
## Перехоплення
|
||||||
|
|
||||||
|
Пакет Кошик (Cart) видаватиме винятки/перехоплення у разі, якщо щось йде не за планом. Таким чином, вам буде простіше відлагоджувати (debug) ваш код, використовуючи пакет Кошик, або обробляти помилку за типом перехоплення. Пакети Кошика можуть видавати наступні перехоплення:
|
||||||
|
|
||||||
|
| Перехоплення | Пояснення |
|
||||||
|
| ---------------------------- | ---------------------------------------------------------------------------------- |
|
||||||
|
| *CartAlreadyStoredException* | ПерехопленняКошикВжеЗбережено Коли ви намагаєтеся зберегти кошик, який вже було збережено, застосовуючи вказаний ідентифікатор |
|
||||||
|
| *InvalidRowIDException* | ПерехопленняНеправильнийІдРядка Коли rowId, який було передано, не існує у поточному екземплярі кошика |
|
||||||
|
| *UnknownModelException* | ПерехопленняНевідомаМодель Коли ви намагаєтеся об'єднати неіснуючу модель з CartItem. |
|
||||||
|
|
||||||
|
## Події
|
||||||
|
|
||||||
|
Кошик також має вбудовані події. Існує п'ять подій, які можна очікувати.
|
||||||
|
|
||||||
|
| Подія | Видано | Параметр |
|
||||||
|
| ------------- | ---------------------------------------- | -------------------------------- |
|
||||||
|
| cart.added | Коли товар додано до кошика. | `CartItem`, який було додано. |
|
||||||
|
| cart.updated | Коли товар оновлено у кошику. | `CartItem`, який було оновлено. |
|
||||||
|
| cart.removed | Коли товар вилучено з кошика. | `CartItem`, який було вилучено. |
|
||||||
|
| cart.stored | Коли вміст кошика було збережено. | - |
|
||||||
|
| cart.restored | Коли вміст кошика було відновлено. | - |
|
||||||
|
|
||||||
|
## Приклад
|
||||||
|
|
||||||
|
Нижче наведено приклад як відобразити вміст кошика у таблиці:
|
||||||
|
|
||||||
|
```php
|
||||||
|
|
||||||
|
// Add some items in your Controller.
|
||||||
|
Cart::add('192ao12', 'Product 1', 1, 9.99);
|
||||||
|
Cart::add('1239ad0', 'Product 2', 2, 5.95, ['size' => 'large']);
|
||||||
|
|
||||||
|
// Display the content in a View.
|
||||||
|
<table>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Product</th>
|
||||||
|
<th>Qty</th>
|
||||||
|
<th>Price</th>
|
||||||
|
<th>Subtotal</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
|
||||||
|
<tbody>
|
||||||
|
|
||||||
|
<?php foreach(Cart::content() as $row) :?>
|
||||||
|
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<p><strong><?php echo $row->name; ?></strong></p>
|
||||||
|
<p><?php echo ($row->options->has('size') ? $row->options->size : ''); ?></p>
|
||||||
|
</td>
|
||||||
|
<td><input type="text" value="<?php echo $row->qty; ?>"></td>
|
||||||
|
<td>$<?php echo $row->price; ?></td>
|
||||||
|
<td>$<?php echo $row->total; ?></td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
<?php endforeach;?>
|
||||||
|
|
||||||
|
</tbody>
|
||||||
|
|
||||||
|
<tfoot>
|
||||||
|
<tr>
|
||||||
|
<td colspan="2"> </td>
|
||||||
|
<td>Subtotal</td>
|
||||||
|
<td><?php echo Cart::subtotal(); ?></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td colspan="2"> </td>
|
||||||
|
<td>Tax</td>
|
||||||
|
<td><?php echo Cart::tax(); ?></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td colspan="2"> </td>
|
||||||
|
<td>Total</td>
|
||||||
|
<td><?php echo Cart::total(); ?></td>
|
||||||
|
</tr>
|
||||||
|
</tfoot>
|
||||||
|
</table>
|
||||||
|
```
|
||||||
@@ -6,18 +6,20 @@
|
|||||||
"authors": [
|
"authors": [
|
||||||
{
|
{
|
||||||
"name": "Rob Gloudemans",
|
"name": "Rob Gloudemans",
|
||||||
"email": "info@robgloudemans.nl"
|
"email": "info@robgloudemans.nl",
|
||||||
|
"homepage": "http://robgloudemans.nl/"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Patrick Henninger",
|
"name": "Patrick Henninger",
|
||||||
"email": "privat@skyraptor.eu"
|
"email": "privat@skyraptor.eu",
|
||||||
|
"homepage": "https://skyraptor.eu/"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"require": {
|
"require": {
|
||||||
"illuminate/support": "5.1.*|5.2.*|5.3.*|5.4.*|5.5.*|5.6.*|5.7.*",
|
"illuminate/support": "5.4.*||5.5.*||5.6.*||5.7.*||5.8.*||^6.0||^7.0",
|
||||||
"illuminate/session": "5.1.*|5.2.*|5.3.*|5.4.*|5.5.*|5.6.*|5.7.*",
|
"illuminate/session": "5.4.*||5.5.*||5.6.*||5.7.*||5.8.*||^6.0||^7.0",
|
||||||
"illuminate/events": "5.1.*|5.2.*|5.3.*|5.4.*|5.5.*|5.6.*|5.7.*",
|
"illuminate/events": "5.4.*||5.5.*||5.6.*||5.7.*||5.8.*||^6.0||^7.0",
|
||||||
"nesbot/carbon": "^1.26.3 || ^2.0"
|
"nesbot/carbon": "~1.20||^1.26.3||^2.0"
|
||||||
},
|
},
|
||||||
"require-dev": {
|
"require-dev": {
|
||||||
"phpunit/phpunit": "~5.0||~6.0||~7.0||~8.0",
|
"phpunit/phpunit": "~5.0||~6.0||~7.0||~8.0",
|
||||||
|
|||||||
101
src/Cart.php
101
src/Cart.php
@@ -61,7 +61,7 @@ class Cart
|
|||||||
private $discount = 0;
|
private $discount = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Defines the discount percentage.
|
* Defines the tax rate.
|
||||||
*
|
*
|
||||||
* @var float
|
* @var float
|
||||||
*/
|
*/
|
||||||
@@ -120,11 +120,12 @@ class Cart
|
|||||||
* @param mixed $name
|
* @param mixed $name
|
||||||
* @param int|float $qty
|
* @param int|float $qty
|
||||||
* @param float $price
|
* @param float $price
|
||||||
|
* @param float $weight
|
||||||
* @param array $options
|
* @param array $options
|
||||||
*
|
*
|
||||||
* @return \Gloudemans\Shoppingcart\CartItem
|
* @return \Gloudemans\Shoppingcart\CartItem
|
||||||
*/
|
*/
|
||||||
public function add($id, $name = null, $qty = null, $price = null, array $options = [])
|
public function add($id, $name = null, $qty = null, $price = null, $weight = 0, array $options = [])
|
||||||
{
|
{
|
||||||
if ($this->isMulti($id)) {
|
if ($this->isMulti($id)) {
|
||||||
return array_map(function ($item) {
|
return array_map(function ($item) {
|
||||||
@@ -132,7 +133,7 @@ class Cart
|
|||||||
}, $id);
|
}, $id);
|
||||||
}
|
}
|
||||||
|
|
||||||
$cartItem = $this->createCartItem($id, $name, $qty, $price, $options);
|
$cartItem = $this->createCartItem($id, $name, $qty, $price, $weight, $options);
|
||||||
|
|
||||||
return $this->addCartItem($cartItem);
|
return $this->addCartItem($cartItem);
|
||||||
}
|
}
|
||||||
@@ -140,13 +141,14 @@ class Cart
|
|||||||
/**
|
/**
|
||||||
* Add an item to the cart.
|
* Add an item to the cart.
|
||||||
*
|
*
|
||||||
* @param \Gloudemans\Shoppingcart\CartItem $item Item to add to the Cart
|
* @param \Gloudemans\Shoppingcart\CartItem $item Item to add to the Cart
|
||||||
* @param bool $keepDiscount Keep the discount rate of the Item
|
* @param bool $keepDiscount Keep the discount rate of the Item
|
||||||
* @param bool $keepTax Keep the Tax rate of the Item
|
* @param bool $keepTax Keep the Tax rate of the Item
|
||||||
|
* @param bool $dispatchEvent
|
||||||
*
|
*
|
||||||
* @return \Gloudemans\Shoppingcart\CartItem The CartItem
|
* @return \Gloudemans\Shoppingcart\CartItem The CartItem
|
||||||
*/
|
*/
|
||||||
public function addCartItem($item, $keepDiscount = false, $keepTax = false)
|
public function addCartItem($item, $keepDiscount = false, $keepTax = false, $dispatchEvent = true)
|
||||||
{
|
{
|
||||||
if (!$keepDiscount) {
|
if (!$keepDiscount) {
|
||||||
$item->setDiscountRate($this->discount);
|
$item->setDiscountRate($this->discount);
|
||||||
@@ -164,7 +166,9 @@ class Cart
|
|||||||
|
|
||||||
$content->put($item->rowId, $item);
|
$content->put($item->rowId, $item);
|
||||||
|
|
||||||
$this->events->dispatch('cart.added', $item);
|
if ($dispatchEvent) {
|
||||||
|
$this->events->dispatch('cart.added', $item);
|
||||||
|
}
|
||||||
|
|
||||||
$this->session->put($this->instance, $content);
|
$this->session->put($this->instance, $content);
|
||||||
|
|
||||||
@@ -194,6 +198,8 @@ class Cart
|
|||||||
$content = $this->getContent();
|
$content = $this->getContent();
|
||||||
|
|
||||||
if ($rowId !== $cartItem->rowId) {
|
if ($rowId !== $cartItem->rowId) {
|
||||||
|
$itemOldIndex = $content->keys()->search($rowId);
|
||||||
|
|
||||||
$content->pull($rowId);
|
$content->pull($rowId);
|
||||||
|
|
||||||
if ($content->has($cartItem->rowId)) {
|
if ($content->has($cartItem->rowId)) {
|
||||||
@@ -207,7 +213,13 @@ class Cart
|
|||||||
|
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
$content->put($cartItem->rowId, $cartItem);
|
if (isset($itemOldIndex)) {
|
||||||
|
$content = $content->slice(0, $itemOldIndex)
|
||||||
|
->merge([$cartItem->rowId => $cartItem])
|
||||||
|
->merge($content->slice($itemOldIndex));
|
||||||
|
} else {
|
||||||
|
$content->put($cartItem->rowId, $cartItem);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->events->dispatch('cart.updated', $cartItem);
|
$this->events->dispatch('cart.updated', $cartItem);
|
||||||
@@ -378,7 +390,7 @@ class Cart
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the subtotal (total - tax) of the items in the cart.
|
* Get the discount of the items in the cart.
|
||||||
*
|
*
|
||||||
* @return float
|
* @return float
|
||||||
*/
|
*/
|
||||||
@@ -390,7 +402,7 @@ class Cart
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the subtotal (total - tax) of the items in the cart as formatted string.
|
* Get the discount of the items in the cart as formatted string.
|
||||||
*
|
*
|
||||||
* @param int $decimals
|
* @param int $decimals
|
||||||
* @param string $decimalPoint
|
* @param string $decimalPoint
|
||||||
@@ -404,7 +416,7 @@ class Cart
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the subtotal (total - tax) of the items in the cart.
|
* Get the price of the items in the cart (not rounded).
|
||||||
*
|
*
|
||||||
* @return float
|
* @return float
|
||||||
*/
|
*/
|
||||||
@@ -416,7 +428,7 @@ class Cart
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the subtotal (total - tax) of the items in the cart as formatted string.
|
* Get the price of the items in the cart as formatted string.
|
||||||
*
|
*
|
||||||
* @param int $decimals
|
* @param int $decimals
|
||||||
* @param string $decimalPoint
|
* @param string $decimalPoint
|
||||||
@@ -429,6 +441,32 @@ class Cart
|
|||||||
return $this->numberFormat($this->initialFloat(), $decimals, $decimalPoint, $thousandSeperator);
|
return $this->numberFormat($this->initialFloat(), $decimals, $decimalPoint, $thousandSeperator);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the price of the items in the cart (previously rounded).
|
||||||
|
*
|
||||||
|
* @return float
|
||||||
|
*/
|
||||||
|
public function priceTotalFloat()
|
||||||
|
{
|
||||||
|
return $this->getContent()->reduce(function ($initial, CartItem $cartItem) {
|
||||||
|
return $initial + $cartItem->priceTotal;
|
||||||
|
}, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the price of the items in the cart as formatted string.
|
||||||
|
*
|
||||||
|
* @param int $decimals
|
||||||
|
* @param string $decimalPoint
|
||||||
|
* @param string $thousandSeperator
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function priceTotal($decimals = null, $decimalPoint = null, $thousandSeperator = null)
|
||||||
|
{
|
||||||
|
return $this->numberFormat($this->priceTotalFloat(), $decimals, $decimalPoint, $thousandSeperator);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the total weight of the items in the cart.
|
* Get the total weight of the items in the cart.
|
||||||
*
|
*
|
||||||
@@ -643,8 +681,29 @@ class Cart
|
|||||||
$this->createdAt = Carbon::parse(data_get($stored, 'created_at'));
|
$this->createdAt = Carbon::parse(data_get($stored, 'created_at'));
|
||||||
$this->updatedAt = Carbon::parse(data_get($stored, 'updated_at'));
|
$this->updatedAt = Carbon::parse(data_get($stored, 'updated_at'));
|
||||||
|
|
||||||
$this->getConnection()->table($this->getTableName())
|
$this->getConnection()->table($this->getTableName())->where('identifier', $identifier)->delete();
|
||||||
->where('identifier', $identifier)->delete();
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Erase the cart with the given identifier.
|
||||||
|
*
|
||||||
|
* @param mixed $identifier
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function erase($identifier)
|
||||||
|
{
|
||||||
|
if ($identifier instanceof InstanceIdentifier) {
|
||||||
|
$identifier = $identifier->getInstanceIdentifier();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$this->storedCartWithIdentifierExists($identifier)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->getConnection()->table($this->getTableName())->where('identifier', $identifier)->delete();
|
||||||
|
|
||||||
|
$this->events->dispatch('cart.erased');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -653,10 +712,11 @@ class Cart
|
|||||||
* @param mixed $identifier Identifier of the Cart to merge with.
|
* @param mixed $identifier Identifier of the Cart to merge with.
|
||||||
* @param bool $keepDiscount Keep the discount of the CartItems.
|
* @param bool $keepDiscount Keep the discount of the CartItems.
|
||||||
* @param bool $keepTax Keep the tax of the CartItems.
|
* @param bool $keepTax Keep the tax of the CartItems.
|
||||||
|
* @param bool $dispatchAdd Flag to dispatch the add events.
|
||||||
*
|
*
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
public function merge($identifier, $keepDiscount = false, $keepTax = false)
|
public function merge($identifier, $keepDiscount = false, $keepTax = false, $dispatchAdd = true)
|
||||||
{
|
{
|
||||||
if (!$this->storedCartWithIdentifierExists($identifier)) {
|
if (!$this->storedCartWithIdentifierExists($identifier)) {
|
||||||
return false;
|
return false;
|
||||||
@@ -668,9 +728,11 @@ class Cart
|
|||||||
$storedContent = unserialize($stored->content);
|
$storedContent = unserialize($stored->content);
|
||||||
|
|
||||||
foreach ($storedContent as $cartItem) {
|
foreach ($storedContent as $cartItem) {
|
||||||
$this->addCartItem($cartItem, $keepDiscount, $keepTax);
|
$this->addCartItem($cartItem, $keepDiscount, $keepTax, $dispatchAdd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$this->events->dispatch('cart.merged');
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -716,11 +778,12 @@ class Cart
|
|||||||
* @param mixed $name
|
* @param mixed $name
|
||||||
* @param int|float $qty
|
* @param int|float $qty
|
||||||
* @param float $price
|
* @param float $price
|
||||||
|
* @param float $weight
|
||||||
* @param array $options
|
* @param array $options
|
||||||
*
|
*
|
||||||
* @return \Gloudemans\Shoppingcart\CartItem
|
* @return \Gloudemans\Shoppingcart\CartItem
|
||||||
*/
|
*/
|
||||||
private function createCartItem($id, $name, $qty, $price, array $options)
|
private function createCartItem($id, $name, $qty, $price, $weight, array $options)
|
||||||
{
|
{
|
||||||
if ($id instanceof Buyable) {
|
if ($id instanceof Buyable) {
|
||||||
$cartItem = CartItem::fromBuyable($id, $qty ?: []);
|
$cartItem = CartItem::fromBuyable($id, $qty ?: []);
|
||||||
@@ -730,7 +793,7 @@ class Cart
|
|||||||
$cartItem = CartItem::fromArray($id);
|
$cartItem = CartItem::fromArray($id);
|
||||||
$cartItem->setQuantity($id['qty']);
|
$cartItem->setQuantity($id['qty']);
|
||||||
} else {
|
} else {
|
||||||
$cartItem = CartItem::fromAttributes($id, $name, $price, $options);
|
$cartItem = CartItem::fromAttributes($id, $name, $price, $weight, $options);
|
||||||
$cartItem->setQuantity($qty);
|
$cartItem->setQuantity($qty);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
135
src/CartItem.php
135
src/CartItem.php
@@ -5,7 +5,20 @@ namespace Gloudemans\Shoppingcart;
|
|||||||
use Gloudemans\Shoppingcart\Contracts\Buyable;
|
use Gloudemans\Shoppingcart\Contracts\Buyable;
|
||||||
use Illuminate\Contracts\Support\Arrayable;
|
use Illuminate\Contracts\Support\Arrayable;
|
||||||
use Illuminate\Contracts\Support\Jsonable;
|
use Illuminate\Contracts\Support\Jsonable;
|
||||||
|
use Illuminate\Support\Arr;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @property-read mixed discount
|
||||||
|
* @property-read float discountTotal
|
||||||
|
* @property-read float priceTarget
|
||||||
|
* @property-read float priceNet
|
||||||
|
* @property-read float priceTotal
|
||||||
|
* @property-read float subtotal
|
||||||
|
* @property-read float taxTotal
|
||||||
|
* @property-read float tax
|
||||||
|
* @property-read float total
|
||||||
|
* @property-read float priceTax
|
||||||
|
*/
|
||||||
class CartItem implements Arrayable, Jsonable
|
class CartItem implements Arrayable, Jsonable
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
@@ -57,6 +70,13 @@ class CartItem implements Arrayable, Jsonable
|
|||||||
*/
|
*/
|
||||||
public $options;
|
public $options;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The tax rate for the cart item.
|
||||||
|
*
|
||||||
|
* @var int|float
|
||||||
|
*/
|
||||||
|
public $taxRate = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The FQN of the associated model.
|
* The FQN of the associated model.
|
||||||
*
|
*
|
||||||
@@ -64,13 +84,6 @@ class CartItem implements Arrayable, Jsonable
|
|||||||
*/
|
*/
|
||||||
private $associatedModel = null;
|
private $associatedModel = null;
|
||||||
|
|
||||||
/**
|
|
||||||
* The tax rate for the cart item.
|
|
||||||
*
|
|
||||||
* @var int|float
|
|
||||||
*/
|
|
||||||
private $taxRate = 0;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The discount rate for the cart item.
|
* The discount rate for the cart item.
|
||||||
*
|
*
|
||||||
@@ -84,6 +97,7 @@ class CartItem implements Arrayable, Jsonable
|
|||||||
* @param int|string $id
|
* @param int|string $id
|
||||||
* @param string $name
|
* @param string $name
|
||||||
* @param float $price
|
* @param float $price
|
||||||
|
* @param float $weight
|
||||||
* @param array $options
|
* @param array $options
|
||||||
*/
|
*/
|
||||||
public function __construct($id, $name, $price, $weight = 0, array $options = [])
|
public function __construct($id, $name, $price, $weight = 0, array $options = [])
|
||||||
@@ -97,6 +111,9 @@ class CartItem implements Arrayable, Jsonable
|
|||||||
if (strlen($price) < 0 || !is_numeric($price)) {
|
if (strlen($price) < 0 || !is_numeric($price)) {
|
||||||
throw new \InvalidArgumentException('Please supply a valid price.');
|
throw new \InvalidArgumentException('Please supply a valid price.');
|
||||||
}
|
}
|
||||||
|
if (strlen($weight) < 0 || !is_numeric($weight)) {
|
||||||
|
throw new \InvalidArgumentException('Please supply a valid weight.');
|
||||||
|
}
|
||||||
|
|
||||||
$this->id = $id;
|
$this->id = $id;
|
||||||
$this->name = $name;
|
$this->name = $name;
|
||||||
@@ -248,6 +265,20 @@ class CartItem implements Arrayable, Jsonable
|
|||||||
return $this->numberFormat($this->discountTotal, $decimals, $decimalPoint, $thousandSeperator);
|
return $this->numberFormat($this->discountTotal, $decimals, $decimalPoint, $thousandSeperator);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the formatted total price for this cart item.
|
||||||
|
*
|
||||||
|
* @param int $decimals
|
||||||
|
* @param string $decimalPoint
|
||||||
|
* @param string $thousandSeperator
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function priceTotal($decimals = null, $decimalPoint = null, $thousandSeperator = null)
|
||||||
|
{
|
||||||
|
return $this->numberFormat($this->priceTotal, $decimals, $decimalPoint, $thousandSeperator);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the quantity for this cart item.
|
* Set the quantity for this cart item.
|
||||||
*
|
*
|
||||||
@@ -274,7 +305,6 @@ class CartItem implements Arrayable, Jsonable
|
|||||||
$this->id = $item->getBuyableIdentifier($this->options);
|
$this->id = $item->getBuyableIdentifier($this->options);
|
||||||
$this->name = $item->getBuyableDescription($this->options);
|
$this->name = $item->getBuyableDescription($this->options);
|
||||||
$this->price = $item->getBuyablePrice($this->options);
|
$this->price = $item->getBuyablePrice($this->options);
|
||||||
$this->priceTax = $this->price + $this->tax;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -286,13 +316,12 @@ class CartItem implements Arrayable, Jsonable
|
|||||||
*/
|
*/
|
||||||
public function updateFromArray(array $attributes)
|
public function updateFromArray(array $attributes)
|
||||||
{
|
{
|
||||||
$this->id = array_get($attributes, 'id', $this->id);
|
$this->id = Arr::get($attributes, 'id', $this->id);
|
||||||
$this->qty = array_get($attributes, 'qty', $this->qty);
|
$this->qty = Arr::get($attributes, 'qty', $this->qty);
|
||||||
$this->name = array_get($attributes, 'name', $this->name);
|
$this->name = Arr::get($attributes, 'name', $this->name);
|
||||||
$this->price = array_get($attributes, 'price', $this->price);
|
$this->price = Arr::get($attributes, 'price', $this->price);
|
||||||
$this->weight = array_get($attributes, 'weight', $this->weight);
|
$this->weight = Arr::get($attributes, 'weight', $this->weight);
|
||||||
$this->priceTax = $this->price + $this->tax;
|
$this->options = new CartItemOptions(Arr::get($attributes, 'options', $this->options));
|
||||||
$this->options = new CartItemOptions(array_get($attributes, 'options', $this->options));
|
|
||||||
|
|
||||||
$this->rowId = $this->generateRowId($this->id, $this->options->all());
|
$this->rowId = $this->generateRowId($this->id, $this->options->all());
|
||||||
}
|
}
|
||||||
@@ -351,39 +380,69 @@ class CartItem implements Arrayable, Jsonable
|
|||||||
if (property_exists($this, $attribute)) {
|
if (property_exists($this, $attribute)) {
|
||||||
return $this->{$attribute};
|
return $this->{$attribute};
|
||||||
}
|
}
|
||||||
|
$decimals = config('cart.format.decimals', 2);
|
||||||
|
|
||||||
switch ($attribute) {
|
switch ($attribute) {
|
||||||
case 'discount':
|
|
||||||
return $this->price * ($this->discountRate / 100);
|
|
||||||
case 'priceTarget':
|
|
||||||
return $this->price - $this->discount;
|
|
||||||
case 'subtotal':
|
|
||||||
return $this->priceTarget * $this->qty;
|
|
||||||
case 'tax':
|
|
||||||
return $this->priceTarget * ($this->taxRate / 100);
|
|
||||||
case 'priceTax':
|
|
||||||
return $this->priceTarget + $this->tax;
|
|
||||||
case 'total':
|
|
||||||
return $this->priceTax * $this->qty;
|
|
||||||
case 'taxTotal':
|
|
||||||
return $this->tax * $this->qty;
|
|
||||||
case 'discountTotal':
|
|
||||||
return $this->discount * $this->qty;
|
|
||||||
case 'weightTotal':
|
|
||||||
return $this->weight * $this->qty;
|
|
||||||
|
|
||||||
case 'model':
|
case 'model':
|
||||||
if (isset($this->associatedModel)) {
|
if (isset($this->associatedModel)) {
|
||||||
return with(new $this->associatedModel())->find($this->id);
|
return with(new $this->associatedModel())->find($this->id);
|
||||||
}
|
}
|
||||||
|
|
||||||
case 'modelFQCN':
|
case 'modelFQCN':
|
||||||
if (isset($this->associatedModel)) {
|
if (isset($this->associatedModel)) {
|
||||||
return $this->associatedModel;
|
return $this->associatedModel;
|
||||||
}
|
}
|
||||||
|
case 'weightTotal':
|
||||||
|
return round($this->weight * $this->qty, $decimals);
|
||||||
|
}
|
||||||
|
|
||||||
default:
|
if (config('cart.gross_price')) {
|
||||||
return;
|
switch ($attribute) {
|
||||||
|
case 'priceNet':
|
||||||
|
return round($this->price / (1 + ($this->taxRate / 100)), $decimals);
|
||||||
|
case 'discount':
|
||||||
|
return $this->priceNet * ($this->discountRate / 100);
|
||||||
|
case 'tax':
|
||||||
|
return round($this->priceTarget * ($this->taxRate / 100), $decimals);
|
||||||
|
case 'priceTax':
|
||||||
|
return round($this->priceTarget + $this->tax, $decimals);
|
||||||
|
case 'discountTotal':
|
||||||
|
return round($this->discount * $this->qty, $decimals);
|
||||||
|
case 'priceTotal':
|
||||||
|
return round($this->priceNet * $this->qty, $decimals);
|
||||||
|
case 'subtotal':
|
||||||
|
return round($this->priceTotal - $this->discountTotal, $decimals);
|
||||||
|
case 'priceTarget':
|
||||||
|
return round(($this->priceTotal - $this->discountTotal) / $this->qty, $decimals);
|
||||||
|
case 'taxTotal':
|
||||||
|
return round($this->subtotal * ($this->taxRate / 100), $decimals);
|
||||||
|
case 'total':
|
||||||
|
return round($this->subtotal + $this->taxTotal, $decimals);
|
||||||
|
default:
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
switch ($attribute) {
|
||||||
|
case 'discount':
|
||||||
|
return $this->price * ($this->discountRate / 100);
|
||||||
|
case 'tax':
|
||||||
|
return round($this->priceTarget * ($this->taxRate / 100), $decimals);
|
||||||
|
case 'priceTax':
|
||||||
|
return round($this->priceTarget + $this->tax, $decimals);
|
||||||
|
case 'discountTotal':
|
||||||
|
return round($this->discount * $this->qty, $decimals);
|
||||||
|
case 'priceTotal':
|
||||||
|
return round($this->price * $this->qty, $decimals);
|
||||||
|
case 'subtotal':
|
||||||
|
return round($this->priceTotal - $this->discountTotal, $decimals);
|
||||||
|
case 'priceTarget':
|
||||||
|
return round(($this->priceTotal - $this->discountTotal) / $this->qty, $decimals);
|
||||||
|
case 'taxTotal':
|
||||||
|
return round($this->subtotal * ($this->taxRate / 100), $decimals);
|
||||||
|
case 'total':
|
||||||
|
return round($this->subtotal + $this->taxTotal, $decimals);
|
||||||
|
default:
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -409,7 +468,7 @@ class CartItem implements Arrayable, Jsonable
|
|||||||
*/
|
*/
|
||||||
public static function fromArray(array $attributes)
|
public static function fromArray(array $attributes)
|
||||||
{
|
{
|
||||||
$options = array_get($attributes, 'options', []);
|
$options = Arr::get($attributes, 'options', []);
|
||||||
|
|
||||||
return new self($attributes['id'], $attributes['name'], $attributes['price'], $attributes['weight'], $options);
|
return new self($attributes['id'], $attributes['name'], $attributes['price'], $attributes['weight'], $options);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,18 @@
|
|||||||
|
|
||||||
return [
|
return [
|
||||||
|
|
||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| Gross price as base price
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
| This default value is used to select the method to calculate prices and taxes
|
||||||
|
| If true the item price is managed as a gross price, so taxes will be calculated by separation/exclusion
|
||||||
|
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
'gross_price' => false,
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|--------------------------------------------------------------------------
|
|--------------------------------------------------------------------------
|
||||||
| Default tax rate
|
| Default tax rate
|
||||||
|
|||||||
@@ -30,6 +30,6 @@ class ShoppingcartServiceProvider extends ServiceProvider
|
|||||||
|
|
||||||
$this->publishes([
|
$this->publishes([
|
||||||
realpath(__DIR__.'/Database/migrations') => $this->app->databasePath().'/migrations',
|
realpath(__DIR__.'/Database/migrations') => $this->app->databasePath().'/migrations',
|
||||||
]);
|
], 'migrations');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -264,6 +264,19 @@ class CartTest extends TestCase
|
|||||||
$cart->add(1, 'Some title', 1, 'invalid');
|
$cart->add(1, 'Some title', 1, 'invalid');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @test
|
||||||
|
*/
|
||||||
|
public function it_will_validate_the_weight()
|
||||||
|
{
|
||||||
|
$this->expectException(\InvalidArgumentException::class);
|
||||||
|
$this->expectExceptionMessage('Please supply a valid weight');
|
||||||
|
|
||||||
|
$cart = $this->getCart();
|
||||||
|
|
||||||
|
$cart->add(1, 'Some title', 1, 10.00, 'invalid');
|
||||||
|
}
|
||||||
|
|
||||||
/** @test */
|
/** @test */
|
||||||
public function it_will_update_the_cart_if_the_item_already_exists_in_the_cart()
|
public function it_will_update_the_cart_if_the_item_already_exists_in_the_cart()
|
||||||
{
|
{
|
||||||
@@ -386,6 +399,21 @@ class CartTest extends TestCase
|
|||||||
$this->assertRowsInCart(1, $cart);
|
$this->assertRowsInCart(1, $cart);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @test */
|
||||||
|
public function it_will_keep_items_sequence_if_the_options_changed()
|
||||||
|
{
|
||||||
|
$cart = $this->getCart();
|
||||||
|
|
||||||
|
$cart->add(new BuyableProduct(), 1, ['color' => 'red']);
|
||||||
|
$cart->add(new BuyableProduct(), 1, ['color' => 'green']);
|
||||||
|
$cart->add(new BuyableProduct(), 1, ['color' => 'blue']);
|
||||||
|
|
||||||
|
$cart->update($cart->content()->values()[1]->rowId, ['options' => ['color' => 'yellow']]);
|
||||||
|
|
||||||
|
$this->assertRowsInCart(3, $cart);
|
||||||
|
$this->assertEquals('yellow', $cart->content()->values()[1]->options->color);
|
||||||
|
}
|
||||||
|
|
||||||
/** @test */
|
/** @test */
|
||||||
public function it_can_remove_an_item_from_the_cart()
|
public function it_can_remove_an_item_from_the_cart()
|
||||||
{
|
{
|
||||||
@@ -743,6 +771,20 @@ class CartTest extends TestCase
|
|||||||
$this->assertEquals('1.050,00', $cart->tax(2, ',', '.'));
|
$this->assertEquals('1.050,00', $cart->tax(2, ',', '.'));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @test */
|
||||||
|
public function it_can_access_tax_as_percentage()
|
||||||
|
{
|
||||||
|
$cart = $this->getCart();
|
||||||
|
|
||||||
|
$cart->add(new BuyableProduct(1, 'Some title', 10.00), 1);
|
||||||
|
|
||||||
|
$cart->setTax('027c91341fd5cf4d2579b49c4b6a90da', 19);
|
||||||
|
|
||||||
|
$cartItem = $cart->get('027c91341fd5cf4d2579b49c4b6a90da');
|
||||||
|
|
||||||
|
$this->assertEquals(19, $cartItem->taxRate);
|
||||||
|
}
|
||||||
|
|
||||||
/** @test */
|
/** @test */
|
||||||
public function it_can_return_the_subtotal()
|
public function it_can_return_the_subtotal()
|
||||||
{
|
{
|
||||||
@@ -917,6 +959,52 @@ class CartTest extends TestCase
|
|||||||
$this->assertEquals(11.90, $cartItem->total(2));
|
$this->assertEquals(11.90, $cartItem->total(2));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @test */
|
||||||
|
public function it_can_calculate_all_values_after_updating_from_array()
|
||||||
|
{
|
||||||
|
$cart = $this->getCartDiscount(50);
|
||||||
|
$cart->add(new BuyableProduct(1, 'First item', 10.00), 1);
|
||||||
|
|
||||||
|
$cart->update('027c91341fd5cf4d2579b49c4b6a90da', ['qty'=>2]);
|
||||||
|
|
||||||
|
$cartItem = $cart->get('027c91341fd5cf4d2579b49c4b6a90da');
|
||||||
|
|
||||||
|
$cart->setTax('027c91341fd5cf4d2579b49c4b6a90da', 19);
|
||||||
|
|
||||||
|
$this->assertEquals(10.00, $cartItem->price(2));
|
||||||
|
$this->assertEquals(5.00, $cartItem->discount(2));
|
||||||
|
$this->assertEquals(10.00, $cartItem->discountTotal(2));
|
||||||
|
$this->assertEquals(5.00, $cartItem->priceTarget(2));
|
||||||
|
$this->assertEquals(10.00, $cartItem->subtotal(2));
|
||||||
|
$this->assertEquals(0.95, $cartItem->tax(2));
|
||||||
|
$this->assertEquals(1.90, $cartItem->taxTotal(2));
|
||||||
|
$this->assertEquals(5.95, $cartItem->priceTax(2));
|
||||||
|
$this->assertEquals(11.90, $cartItem->total(2));
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @test */
|
||||||
|
public function it_can_calculate_all_values_after_updating_from_buyable()
|
||||||
|
{
|
||||||
|
$cart = $this->getCartDiscount(50);
|
||||||
|
$cart->add(new BuyableProduct(1, 'First item', 5.00), 2);
|
||||||
|
|
||||||
|
$cart->update('027c91341fd5cf4d2579b49c4b6a90da', new BuyableProduct(1, 'First item', 10.00));
|
||||||
|
|
||||||
|
$cartItem = $cart->get('027c91341fd5cf4d2579b49c4b6a90da');
|
||||||
|
|
||||||
|
$cart->setTax('027c91341fd5cf4d2579b49c4b6a90da', 19);
|
||||||
|
|
||||||
|
$this->assertEquals(10.00, $cartItem->price(2));
|
||||||
|
$this->assertEquals(5.00, $cartItem->discount(2));
|
||||||
|
$this->assertEquals(10.00, $cartItem->discountTotal(2));
|
||||||
|
$this->assertEquals(5.00, $cartItem->priceTarget(2));
|
||||||
|
$this->assertEquals(10.00, $cartItem->subtotal(2));
|
||||||
|
$this->assertEquals(0.95, $cartItem->tax(2));
|
||||||
|
$this->assertEquals(1.90, $cartItem->taxTotal(2));
|
||||||
|
$this->assertEquals(5.95, $cartItem->priceTax(2));
|
||||||
|
$this->assertEquals(11.90, $cartItem->total(2));
|
||||||
|
}
|
||||||
|
|
||||||
/** @test */
|
/** @test */
|
||||||
public function it_will_destroy_the_cart_when_the_user_logs_out_and_the_config_setting_was_set_to_true()
|
public function it_will_destroy_the_cart_when_the_user_logs_out_and_the_config_setting_was_set_to_true()
|
||||||
{
|
{
|
||||||
@@ -961,7 +1049,7 @@ class CartTest extends TestCase
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** @test */
|
/** @test */
|
||||||
public function cart_hast_no_rounding_errors()
|
public function cart_has_no_rounding_errors()
|
||||||
{
|
{
|
||||||
$cart = $this->getCart();
|
$cart = $this->getCart();
|
||||||
|
|
||||||
@@ -1149,6 +1237,135 @@ class CartTest extends TestCase
|
|||||||
$this->assertEquals(2.50, $cart->tax(2)); // tax of 5 Bucks
|
$this->assertEquals(2.50, $cart->tax(2)); // tax of 5 Bucks
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @test */
|
||||||
|
public function it_does_allow_adding_cart_items_with_weight_and_options()
|
||||||
|
{
|
||||||
|
// https://github.com/bumbummen99/LaravelShoppingcart/pull/5
|
||||||
|
$cart = $this->getCart();
|
||||||
|
|
||||||
|
$cartItem = $cart->add('293ad', 'Product 1', 1, 9.99, 550, ['size' => 'large']);
|
||||||
|
|
||||||
|
$this->assertEquals(550, $cartItem->weight);
|
||||||
|
$this->assertTrue($cartItem->options->has('size'));
|
||||||
|
$this->assertEquals('large', $cartItem->options->size);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @test */
|
||||||
|
public function it_can_merge_without_dispatching_add_events()
|
||||||
|
{
|
||||||
|
$this->artisan('migrate', [
|
||||||
|
'--database' => 'testing',
|
||||||
|
]);
|
||||||
|
|
||||||
|
$cart = $this->getCartDiscount(50);
|
||||||
|
$cart->add(new BuyableProduct(1, 'Item', 10.00), 1);
|
||||||
|
$cart->add(new BuyableProduct(2, 'Item 2', 10.00), 1);
|
||||||
|
$cart->store('test');
|
||||||
|
|
||||||
|
Event::fakeFor(function () {
|
||||||
|
$cart2 = $this->getCart();
|
||||||
|
$cart2->instance('test2');
|
||||||
|
$cart2->setGlobalTax(0);
|
||||||
|
$cart2->setGlobalDiscount(0);
|
||||||
|
|
||||||
|
$this->assertEquals('0', $cart2->countInstances());
|
||||||
|
|
||||||
|
$cart2->merge('test', null, null, false);
|
||||||
|
|
||||||
|
Event::assertNotDispatched('cart.added');
|
||||||
|
Event::assertDispatched('cart.merged');
|
||||||
|
|
||||||
|
$this->assertEquals('2', $cart2->countInstances());
|
||||||
|
$this->assertEquals(20, $cart2->totalFloat());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @test */
|
||||||
|
public function it_can_merge_dispatching_add_events()
|
||||||
|
{
|
||||||
|
$this->artisan('migrate', [
|
||||||
|
'--database' => 'testing',
|
||||||
|
]);
|
||||||
|
|
||||||
|
$cart = $this->getCartDiscount(50);
|
||||||
|
$cart->add(new BuyableProduct(1, 'Item', 10.00), 1);
|
||||||
|
$cart->add(new BuyableProduct(2, 'Item 2', 10.00), 1);
|
||||||
|
$cart->store('test');
|
||||||
|
|
||||||
|
Event::fakeFor(function () {
|
||||||
|
$cart2 = $this->getCart();
|
||||||
|
$cart2->instance('test2');
|
||||||
|
$cart2->setGlobalTax(0);
|
||||||
|
$cart2->setGlobalDiscount(0);
|
||||||
|
|
||||||
|
$this->assertEquals('0', $cart2->countInstances());
|
||||||
|
|
||||||
|
$cart2->merge('test');
|
||||||
|
|
||||||
|
Event::assertDispatched('cart.added', 2);
|
||||||
|
Event::assertDispatched('cart.merged');
|
||||||
|
$this->assertEquals('2', $cart2->countInstances());
|
||||||
|
$this->assertEquals(20, $cart2->totalFloat());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @test */
|
||||||
|
public function it_use_correctly_rounded_values_for_totals_and_cart_summary()
|
||||||
|
{
|
||||||
|
$this->setConfigFormat(2, ',', '');
|
||||||
|
|
||||||
|
$cart = $this->getCartDiscount(6);
|
||||||
|
|
||||||
|
$cartItem = $cart->add(new BuyableProduct(1, 'First item', 0.18929), 1000);
|
||||||
|
$cart->add(new BuyableProduct(2, 'Second item', 4.41632), 5);
|
||||||
|
$cart->add(new BuyableProduct(3, 'Third item', 0.37995), 25);
|
||||||
|
|
||||||
|
$cart->setGlobalTax(22);
|
||||||
|
|
||||||
|
// check total
|
||||||
|
$this->assertEquals('253,29', $cart->total());
|
||||||
|
|
||||||
|
// check that the sum of cart subvalues matches the total (in order to avoid cart summary to looks wrong)
|
||||||
|
$this->assertEquals($cart->totalFloat(), $cart->subtotalFloat() + $cart->taxFloat());
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @test */
|
||||||
|
public function it_use_gross_price_as_base_price()
|
||||||
|
{
|
||||||
|
$cart = $this->getCartDiscount(0);
|
||||||
|
config(['cart.gross_price' => true]);
|
||||||
|
|
||||||
|
$cartItem = $cart->add(new BuyableProduct(1, 'First item', 100), 2);
|
||||||
|
|
||||||
|
$cart->setGlobalTax(22);
|
||||||
|
|
||||||
|
// check net price
|
||||||
|
$this->assertEquals(81.97, round($cartItem->priceNet, 2));
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @test */
|
||||||
|
public function it_use_gross_price_and_it_use_correctly_rounded_values_for_totals_and_cart_summary()
|
||||||
|
{
|
||||||
|
$this->setConfigFormat(2, ',', '');
|
||||||
|
config(['cart.gross_price' => true]);
|
||||||
|
|
||||||
|
$cart = $this->getCartDiscount(6);
|
||||||
|
|
||||||
|
$cartItem = $cart->add(new BuyableProduct(1, 'First item', 0.23093), 1000);
|
||||||
|
$cart->add(new BuyableProduct(2, 'Second item', 5.38791), 5);
|
||||||
|
$cart->add(new BuyableProduct(3, 'Third item', 0.46354), 25);
|
||||||
|
|
||||||
|
$cart->setGlobalTax(22);
|
||||||
|
|
||||||
|
// check total
|
||||||
|
$this->assertEquals('254,12', $cart->total());
|
||||||
|
|
||||||
|
// check item price total
|
||||||
|
$this->assertEquals(190, $cartItem->priceTotal);
|
||||||
|
// check that the sum of cart subvalues matches the total (in order to avoid cart summary to looks wrong)
|
||||||
|
$this->assertEquals($cart->totalFloat(), $cart->subtotalFloat() + $cart->taxFloat());
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get an instance of the cart.
|
* Get an instance of the cart.
|
||||||
*
|
*
|
||||||
@@ -1165,12 +1382,14 @@ class CartTest extends TestCase
|
|||||||
/**
|
/**
|
||||||
* Get an instance of the cart with discount.
|
* Get an instance of the cart with discount.
|
||||||
*
|
*
|
||||||
|
* @param int $discount
|
||||||
|
*
|
||||||
* @return \Gloudemans\Shoppingcart\Cart
|
* @return \Gloudemans\Shoppingcart\Cart
|
||||||
*/
|
*/
|
||||||
private function getCartDiscount($discount = 0)
|
private function getCartDiscount($discount = 50)
|
||||||
{
|
{
|
||||||
$cart = $this->getCart();
|
$cart = $this->getCart();
|
||||||
$cart->setGlobalDiscount(50);
|
$cart->setGlobalDiscount($discount);
|
||||||
|
|
||||||
return $cart;
|
return $cart;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user