Skip to content

Commit

Permalink
Merge pull request #12 from n1crack/v2
Browse files Browse the repository at this point in the history
V2 release
  • Loading branch information
n1crack authored Nov 28, 2023
2 parents 212ed58 + cc01ff7 commit 5decd82
Show file tree
Hide file tree
Showing 42 changed files with 1,352 additions and 1,743 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@

All notable changes to `aurora` will be documented in this file.

## 2.0.0 - 2022-05-22
- 2.0 release

## 1.0.0 - 2022-05-22
- initial release

Expand Down
190 changes: 142 additions & 48 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,85 +4,179 @@
[![GitHub Tests Action Status](https://img.shields.io/github/actions/workflow/status/n1crack/aurora/run-tests.yml)](https://github.com/n1crack/aurora/actions)
[![GitHub](https://img.shields.io/github/license/n1crack/aurora)](https://github.com/n1crack/aurora/blob/main/LICENSE.md)

The Aurora Shopping Cart for Laravel package provides a convenient way to manage a shopping cart in your Laravel applications. It allows you to add, update, remove items, apply conditions, and calculate the total and subtotal amounts.
## Support us
Aurora Cart is a flexible and feature-rich shopping cart library for Laravel.

..
## Features

- **Cart Management**: Easily manage the shopping cart for both guest and authenticated users.
- **Item Addition**: Add items to the cart with quantity and options support.
- **Item Modification**: Adjust item quantity, remove items, and update options.
- **Calculators**: Implement custom calculators for shipping, tax, or any other additional costs.
- **MetaData**: Attach meta information to the entire cart or individual items.
- **Snapshot and Rollback**: Save and restore the cart state for scenarios like order creation.
- **Validation**: Validate the cart integrity using checksums.

## Installation

You can install the package via composer:
Install the package using Composer:

```bash
composer require ozdemir/aurora
```

You can publish the config file with:
## Configuration

To configure Aurora Cart, publish the configuration file:

```bash
php artisan vendor:publish --tag="aurora-config"
```
This will create a cart.php file in your config directory. Here's an example configuration file with explanations:

This is the contents of the published config file:

```php
<?php
// config/cart.php

return [
use Ozdemir\Aurora\Cart;
use Ozdemir\Aurora\Generators\GenerateChecksum;
use Ozdemir\Aurora\Generators\GenerateSessionKey;
use Ozdemir\Aurora\Storages\SessionStorage;
use Money\Money;

return [
'instance' => 'cart',

'storage' => \Ozdemir\Aurora\Storage\SessionStorage::class,
'cart_class' => Cart::class,

'storage' => SessionStorage::class,

'cache_store' => env('CART_STORE', config('cache.default')),

'monetary' => [
'precision' => env('CART_CURRENCY_PRECISION', 2),
],

'session_key_generator' => GenerateSessionKey::class,

'checksum_generator' => GenerateChecksum::class,

'calculate_using' => [
// Custom calculators go here
],
];
```

## Usage
## Basic Usage

```php
Cart::add([
'id' => 'some-product',
'name' => 'Some Product',
'quantity' => 1,
'price' => 15,
]);

$items = Cart::items(); // list of the items in the Cart
use Ozdemir\Aurora\CartItem;
use Ozdemir\Aurora\Facades\Cart;

// Adding an item to the cart
$product = new YourProductModel(); // Replace with your actual product model
$cartItem = new CartItem($product, quantity: 2);
Cart::add($cartItem);

// Retrieving cart information
$total = Cart::total();
$itemCount = Cart::count();
$items = Cart::items();

// Updating item quantity
Cart::update($cartItem, quantity: 3);

echo Cart::total();
// Removing an item from the cart
Cart::remove($cartItem);
```

### Methods
- add($data): Adds an item or items to the cart.
- update($key, $data): Updates an item in the cart.
- items(): Returns the collection of items in the cart.
- exists($key): Checks if an item exists in the cart.
- item($key): Retrieves an item from the cart by its key.
- remove($key): Removes an item from the cart.
- isEmpty(): Checks if the cart is empty.
- total(): Calculates the total amount of the cart, including conditions.
- subtotal(): Calculates the subtotal amount of the cart without conditions.
- quantity(): Calculates the total quantity of items in the cart.
- weight(): Calculates the total weight of the items in the cart.
- clear(): Clears the cart and removes all items.
- sync($data): Clears the cart and adds new items.
- condition($condition): Adds a condition to the cart.
- hasCondition($name): Checks if a condition exists in the cart.
- removeCondition($name): Removes a condition from the cart.
- itemConditions($type = null): Retrieves the item-level conditions in the cart.
- conditions($type = null): Retrieves the cart-level conditions.
- getConditionsOrder(): Gets the order of cart-level conditions.
- getItemConditionsOrder(): Gets the order of item-level conditions.
- setConditionsOrder(array $conditionsOrder): Sets the order of cart-level conditions.
- setItemConditionsOrder(array $itemConditionsOrder, $updateExisting = true): Sets the order of item-level conditions.
- serialize(): Serializes the cart instance.
- unserialize($string): Unserializes a serialized cart instance.

## Testing
Aurora Cart supports custom calculators for calculating totals. You can add your custom calculators to the config/cart.php file under the calculate_using key.

```bash
composer test
### Example
```php
return [
// ...
'calculate_using' => [
// discounts etc..
ShippingCalculator::class
TaxCalculator::class
],
];
```
```php
class ShippingCalculator
{
public function handle($payload, Closure $next)
{
[$price, $breakdowns] = $payload;

$shippingPrice = Shipping::first()->amount;

$price = $price + $shippingPrice;

$breakdowns[] = [
'type' => 'shipping',
'amount' => $shippingPrice,
// any additional values..
];

return $next([$price, $breakdowns]);
}
}
```

```php
class TaxCalculator
{
public function handle($payload, Closure $next)
{
[$price, $breakdowns] = $payload;

$taxPrice = Tax::first()->amount;

$price = $price + $taxPrice;

$breakdowns[] = [
'type' => 'tax',
'amount' => $taxPrice,
// any additional values..
];

return $next([$price, $breakdowns]);
}
}
```
Now, your cart will use these custom calculators to calculate totals, including shipping and tax. Adjust the logic in the calculators based on your specific business requirements.

## Breakdowns
You can retrieve the breakdowns of your cart using the Cart::breakdowns() method. Breakdowns provide a detailed summary of how the total amount is calculated, including contributions from various components such as shipping, tax, and any custom calculators you've added.

Example

```php
$breakdowns = Cart::breakdowns();

// Output the breakdowns
print_r($breakdowns);
```
The breakdowns() method returns an array where each element represents a breakdown item. Each breakdown item typically includes a label and value, providing transparency into how different factors contribute to the overall total.

Here's a hypothetical example output:

```php
Array (
[0] => Array (
[label] => Shipping
[value] => 10
)
[1] => Array (
[label] => Tax
[value] => 15
)
// Additional breakdown items based on your custom calculators
// ...
)
```
Adjust the output format and contents as needed for your specific use case.

## Changelog

Expand Down
26 changes: 16 additions & 10 deletions config/cart.php
Original file line number Diff line number Diff line change
@@ -1,22 +1,28 @@
<?php

return [
use Ozdemir\Aurora\Cart;
use Ozdemir\Aurora\Generators\GenerateChecksum;
use Ozdemir\Aurora\Generators\GenerateSessionKey;
use Ozdemir\Aurora\Storages\SessionStorage;

return [
'instance' => 'cart',

'storage' => \Ozdemir\Aurora\Storage\SessionStorage::class,
'cart_class' => Cart::class,

'cart_class' => \Ozdemir\Aurora\Cart::class,
'storage' => SessionStorage::class,

'cart_item' => \Ozdemir\Aurora\CartItem::class,
'cache_store' => env('CART_STORE', config('cache.default')),

'cache_store' => config('cache.default'),
'monetary' => [
'precision' => env('CART_CURRENCY_PRECISION', 2),
],

'precision' => 2,
'session_key_generator' => GenerateSessionKey::class,

'condition_order' => [
'cart' => ['discount', 'other', 'shipping', 'coupon', 'tax'],
'item' => ['discount', 'other', 'shipping', 'coupon', 'tax'],
],
'checksum_generator' => GenerateChecksum::class,

'calculate_using' => [
//
]
];
25 changes: 25 additions & 0 deletions src/CalculationResult.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<?php

namespace Ozdemir\Aurora;

class CalculationResult
{
protected float $total;
protected mixed $breakdowns;

public function __construct($total, $breakdowns)
{
$this->total = $total;
$this->breakdowns = $breakdowns;
}

public function total(): float
{
return $this->total;
}

public function breakdowns(): mixed
{
return $this->breakdowns;
}
}
41 changes: 41 additions & 0 deletions src/Calculator.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
<?php

namespace Ozdemir\Aurora;

use Illuminate\Support\Collection;

class Calculator
{
public ?string $skip = null;

private Collection $calculators;

public function __construct()
{
$this->calculators = new Collection(config('cart.calculate_using'));
}

public function calculators(): Collection
{
return $this->calculators;
}

public function calculate($price, $calculations = [])
{
return resolve('pipeline')
->send([$price, []])
->through(collect($calculations)->reject(fn ($calculation) => $calculation === $this->skip)->toArray())
->thenReturn();
}

public function skip($class, $callback): mixed
{
$this->skip = is_string($class) ? $class : get_class($class);

$value = $callback();

$this->skip = null;

return $value;
}
}
Loading

0 comments on commit 5decd82

Please sign in to comment.