From 89a7ee7094b746e1470188c9eec75509a92beded Mon Sep 17 00:00:00 2001 From: asaf050 Date: Thu, 18 Jun 2015 02:41:18 +0300 Subject: [PATCH 01/51] Update INSTALLATION.md Change version for the composer file --- docs/INSTALLATION.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/INSTALLATION.md b/docs/INSTALLATION.md index dfb66ac8..88adac8e 100644 --- a/docs/INSTALLATION.md +++ b/docs/INSTALLATION.md @@ -32,7 +32,7 @@ Be sure to publish the configuration if you'd like to customize inventory: Add inventory to your `composer.json` file: - "stevebauman/inventory" : "1.6.*" + "stevebauman/inventory" : "1.7.*" Now perform a `composer update` on your project's source. From d73520239558ac2908a4843cc73349ee3ac37c41 Mon Sep 17 00:00:00 2001 From: Steve Bauman Date: Wed, 17 Jun 2015 20:29:39 -0400 Subject: [PATCH 02/51] Update correct install version --- docs/INSTALLATION.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/INSTALLATION.md b/docs/INSTALLATION.md index 88adac8e..4facd3b2 100644 --- a/docs/INSTALLATION.md +++ b/docs/INSTALLATION.md @@ -4,7 +4,7 @@ Add inventory to your `composer.json` file: - "stevebauman/inventory" : "1.6.*" + "stevebauman/inventory" : "1.7.*" Now perform a `composer update` on your project's source. From 870cd533ed36dacf1ba2fc4cd4edddde856227ad Mon Sep 17 00:00:00 2001 From: Steve Bauman Date: Wed, 17 Jun 2015 20:31:05 -0400 Subject: [PATCH 03/51] Added missing use trait --- docs/INSTALLATION.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/INSTALLATION.md b/docs/INSTALLATION.md index 4facd3b2..b4108a3b 100644 --- a/docs/INSTALLATION.md +++ b/docs/INSTALLATION.md @@ -117,6 +117,8 @@ Category: class Category extends Node { + use CategoryTrait; + protected $table = 'categories'; protected $scoped = ['belongs_to']; From f3a274869f33136c345d28cb90adcb3d95b90ba8 Mon Sep 17 00:00:00 2001 From: Steve Bauman Date: Wed, 17 Jun 2015 20:31:37 -0400 Subject: [PATCH 04/51] Small tab fix --- docs/INSTALLATION.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/INSTALLATION.md b/docs/INSTALLATION.md index b4108a3b..37f4d322 100644 --- a/docs/INSTALLATION.md +++ b/docs/INSTALLATION.md @@ -139,7 +139,7 @@ Supplier: protected $table = 'suppliers'; - public function items() + public function items() { return $this->belongsToMany('Inventory', 'inventory_suppliers', 'supplier_id')->withTimestamps(); } From 18129f0603176a821bd84a16d5208d8e18964bbe Mon Sep 17 00:00:00 2001 From: Steve Bauman Date: Fri, 19 Jun 2015 10:47:07 -0400 Subject: [PATCH 05/51] Lots of small changes - Added Helper class instead of public functions and excess traits - Removed helpers.php - Removed useless comments on top of classes - Added more documentation on some methods - Created CommonMethodsTrait to apply commonly used methods on each inventory trait - Removed DatabaseTransactionTrait in favor of CommonMethodsTrait - Use `setAttribute()` and `getAttribute()` instead of using dynamic property - Remove included models fillable attributes - Added type hinted Model parameters where applicable - Instead of calling the relationships create method, a new instance is created and attributes are set one by one - Removed unnecessary LocationTrait - Tweaked `getCurrentUserId()` method - Updated tests --- src/Helper.php | 85 ++++++++++++ src/InventoryServiceProvider.php | 5 - src/Models/BaseModel.php | 3 - src/Models/Category.php | 17 ++- src/Models/Inventory.php | 16 +-- src/Models/InventorySku.php | 13 +- src/Models/InventoryStock.php | 17 +-- src/Models/InventoryStockMovement.php | 17 +-- src/Models/InventoryTransaction.php | 16 +-- src/Models/InventoryTransactionHistory.php | 17 +-- src/Models/Location.php | 17 ++- src/Models/Metric.php | 8 +- src/Models/Supplier.php | 20 +-- src/Traits/AssemblyTrait.php | 7 +- src/Traits/CategoryTrait.php | 3 - ...VerifyTrait.php => CommonMethodsTrait.php} | 85 +++++++++++- src/Traits/DatabaseTransactionTrait.php | 55 -------- src/Traits/InventorySkuTrait.php | 3 - src/Traits/InventoryStockMovementTrait.php | 14 +- src/Traits/InventoryStockTrait.php | 91 ++++++------- src/Traits/InventoryTrait.php | 125 ++++++------------ .../InventoryTransactionHistoryTrait.php | 11 +- src/Traits/InventoryTransactionTrait.php | 44 +++--- src/Traits/InventoryVariantTrait.php | 3 - src/Traits/LocationTrait.php | 47 ------- src/Traits/SupplierTrait.php | 4 +- src/Traits/UserIdentificationTrait.php | 57 -------- src/helpers.php | 35 ----- tests/InventoryStockTest.php | 12 +- tests/InventoryTest.php | 1 + 30 files changed, 340 insertions(+), 508 deletions(-) create mode 100644 src/Helper.php rename src/Traits/{VerifyTrait.php => CommonMethodsTrait.php} (50%) delete mode 100644 src/Traits/DatabaseTransactionTrait.php delete mode 100644 src/Traits/LocationTrait.php delete mode 100644 src/Traits/UserIdentificationTrait.php delete mode 100644 src/helpers.php diff --git a/src/Helper.php b/src/Helper.php new file mode 100644 index 00000000..a888145f --- /dev/null +++ b/src/Helper.php @@ -0,0 +1,85 @@ +getAncestorsAndSelf(); + + foreach ($ancestors as $ancestor) { + if ($node->equals($ancestor) && $node->isRoot()) { + $html .= sprintf('%s', $ancestor->name); + } elseif ($node->equals($ancestor)) { + $html .= sprintf(' > %s', $ancestor->name); + } elseif ($ancestor->isRoot()) { + $html .= sprintf('%s', $ancestor->name); + } else { + $html .= sprintf(' > %s', $ancestor->name); + } + } + + return $html; + } + + return $node; + } + + /** + * Attempt to find the user id of the currently logged in user + * Supports Cartalyst Sentry/Sentinel based authentication, as well as stock Auth. + * + * @throws NoUserLoggedInException + * + * @return int|string|null + */ + public static function getCurrentUserId() + { + $separator = InventoryServiceProvider::$packageConfigSeparator; + + /* + * Check if we're allowed to return no user ID to the model, if so we'll return null. + */ + if (Config::get('inventory'.$separator.'allow_no_user')) { + return; + } + + /* + * Accountability is enabled, let's try and retrieve the current users ID + */ + try { + if (class_exists($class = '\Cartalyst\Sentry\Facades\Laravel\Sentry') || class_exists($class = '\Cartalyst\Sentinel\Laravel\Facades\Sentinel')) { + if ($class::check()) { + return $class::getUser()->id; + } + } elseif (Auth::check()) { + return Auth::user()->getAuthIdentifier(); + } + } catch (\Exception $e) { + } + + /* + * Couldn't get the current logged in users ID, throw exception + */ + $message = Lang::get('inventory::exceptions.NoUserLoggedInException'); + + throw new NoUserLoggedInException($message); + } +} diff --git a/src/InventoryServiceProvider.php b/src/InventoryServiceProvider.php index 1c4ed924..89a8ed56 100644 --- a/src/InventoryServiceProvider.php +++ b/src/InventoryServiceProvider.php @@ -117,11 +117,6 @@ public function register() 'inventory:check-schema', 'inventory:run-migrations', ]); - - /* - * Include the helpers file - */ - include __DIR__.'/helpers.php'; } /** diff --git a/src/Models/BaseModel.php b/src/Models/BaseModel.php index 0d0761e7..c4726674 100644 --- a/src/Models/BaseModel.php +++ b/src/Models/BaseModel.php @@ -4,9 +4,6 @@ use Illuminate\Database\Eloquent\Model as Eloquent; -/** - * Class BaseModel. - */ class BaseModel extends Eloquent { } diff --git a/src/Models/Category.php b/src/Models/Category.php index 138907d8..69a2db7c 100644 --- a/src/Models/Category.php +++ b/src/Models/Category.php @@ -5,19 +5,22 @@ use Stevebauman\Inventory\Traits\CategoryTrait; use Baum\Node; -/** - * Class Category. - */ class Category extends Node { use CategoryTrait; + /** + * The category table. + * + * @var string + */ protected $table = 'categories'; - protected $fillable = [ - 'name', - ]; - + /** + * The scoped category attrbiutes. + * + * @var array + */ protected $scoped = ['belongs_to']; /** diff --git a/src/Models/Inventory.php b/src/Models/Inventory.php index a98599ef..ff215832 100644 --- a/src/Models/Inventory.php +++ b/src/Models/Inventory.php @@ -6,25 +6,19 @@ use Stevebauman\Inventory\Traits\InventoryVariantTrait; use Stevebauman\Inventory\Traits\InventoryTrait; -/** - * Class Inventory. - */ class Inventory extends BaseModel { use InventoryTrait; use InventoryVariantTrait; use AssemblyTrait; + /** + * The inventories table. + * + * @var string + */ protected $table = 'inventories'; - protected $fillable = [ - 'user_id', - 'category_id', - 'metric_id', - 'name', - 'description', - ]; - /** * The hasOne category relationship. * diff --git a/src/Models/InventorySku.php b/src/Models/InventorySku.php index 08001d3d..718731bb 100644 --- a/src/Models/InventorySku.php +++ b/src/Models/InventorySku.php @@ -4,20 +4,17 @@ use Stevebauman\Inventory\Traits\InventorySkuTrait; -/** - * Class InventorySku. - */ class InventorySku extends BaseModel { use InventorySkuTrait; + /** + * The inventory SKU table. + * + * @var string + */ protected $table = 'inventory_skus'; - protected $fillable = [ - 'inventory_id', - 'code', - ]; - /** * The belongsTo item trait. * diff --git a/src/Models/InventoryStock.php b/src/Models/InventoryStock.php index 48b8f4ae..18cefa38 100644 --- a/src/Models/InventoryStock.php +++ b/src/Models/InventoryStock.php @@ -4,24 +4,17 @@ use Stevebauman\Inventory\Traits\InventoryStockTrait; -/** - * Class InventoryStock. - */ class InventoryStock extends BaseModel { use InventoryStockTrait; + /** + * The inventory stocks table. + * + * @var string + */ protected $table = 'inventory_stocks'; - protected $fillable = [ - 'inventory_id', - 'location_id', - 'quantity', - 'aisle', - 'row', - 'bin', - ]; - /** * The belongsTo inventory item relationship. * diff --git a/src/Models/InventoryStockMovement.php b/src/Models/InventoryStockMovement.php index 9d1fcb6c..cd59833d 100644 --- a/src/Models/InventoryStockMovement.php +++ b/src/Models/InventoryStockMovement.php @@ -4,24 +4,17 @@ use Stevebauman\Inventory\Traits\InventoryStockMovementTrait; -/** - * Class InventoryStockMovement. - */ class InventoryStockMovement extends BaseModel { use InventoryStockMovementTrait; + /** + * The inventory stock movements table. + * + * @var string + */ protected $table = 'inventory_stock_movements'; - protected $fillable = [ - 'stock_id', - 'user_id', - 'before', - 'after', - 'cost', - 'reason', - ]; - /** * The belongsTo stock relationship. * diff --git a/src/Models/InventoryTransaction.php b/src/Models/InventoryTransaction.php index 1e9c03c2..89bb11a1 100644 --- a/src/Models/InventoryTransaction.php +++ b/src/Models/InventoryTransaction.php @@ -5,23 +5,17 @@ use Stevebauman\Inventory\Traits\InventoryTransactionTrait; use Stevebauman\Inventory\Interfaces\StateableInterface; -/** - * Class InventoryTransaction. - */ class InventoryTransaction extends BaseModel implements StateableInterface { use InventoryTransactionTrait; + /** + * The inventory transactions table. + * + * @var string + */ protected $table = 'inventory_transactions'; - protected $fillable = [ - 'user_id', - 'stock_id', - 'name', - 'state', - 'quantity', - ]; - /** * The belongsTo stock relationship. * diff --git a/src/Models/InventoryTransactionHistory.php b/src/Models/InventoryTransactionHistory.php index d90e1674..1b390da8 100644 --- a/src/Models/InventoryTransactionHistory.php +++ b/src/Models/InventoryTransactionHistory.php @@ -4,24 +4,17 @@ use Stevebauman\Inventory\Traits\InventoryTransactionHistoryTrait; -/** - * Class InventoryTransactionPeriod. - */ class InventoryTransactionHistory extends BaseModel { use InventoryTransactionHistoryTrait; + /** + * The inventory transaction histories table. + * + * @var string + */ protected $table = 'inventory_transaction_histories'; - protected $fillable = [ - 'user_id', - 'transaction_id', - 'state_before', - 'state_after', - 'quantity_before', - 'quantity_after', - ]; - /** * The belongsTo transaction relationship. * diff --git a/src/Models/Location.php b/src/Models/Location.php index bace1c3c..7f6659ad 100644 --- a/src/Models/Location.php +++ b/src/Models/Location.php @@ -4,17 +4,20 @@ use Baum\Node; -/** - * Class Location. - */ class Location extends Node { + /** + * The locations table. + * + * @var string + */ protected $table = 'locations'; - protected $fillable = [ - 'name', - ]; - + /** + * The scoped location attributes. + * + * @var array + */ protected $scoped = ['belongs_to']; /** diff --git a/src/Models/Metric.php b/src/Models/Metric.php index 88645786..bd3a71dc 100644 --- a/src/Models/Metric.php +++ b/src/Models/Metric.php @@ -2,11 +2,13 @@ namespace Stevebauman\Inventory\Models; -/** - * Class Metric. - */ class Metric extends BaseModel { + /** + * The metrics table. + * + * @var string + */ protected $table = 'metrics'; /** diff --git a/src/Models/Supplier.php b/src/Models/Supplier.php index 32da24d5..b8495b23 100644 --- a/src/Models/Supplier.php +++ b/src/Models/Supplier.php @@ -8,23 +8,13 @@ class Supplier extends BaseModel { use SupplierTrait; + /** + * The suppliers table. + * + * @var string + */ protected $table = 'suppliers'; - protected $fillable = [ - 'name', - 'address', - 'postal_code', - 'zip_code', - 'region', - 'city', - 'country', - 'contact_title', - 'contact_name', - 'contact_phone', - 'contact_fax', - 'contact_email', - ]; - /** * The belongsToMany items relationship. * diff --git a/src/Traits/AssemblyTrait.php b/src/Traits/AssemblyTrait.php index 6cf9a402..2ecc135c 100644 --- a/src/Traits/AssemblyTrait.php +++ b/src/Traits/AssemblyTrait.php @@ -7,9 +7,6 @@ use Illuminate\Database\Query\Builder; use Illuminate\Database\Eloquent\Model; -/** - * Class AssemblyTrait. - */ trait AssemblyTrait { /** @@ -169,11 +166,11 @@ public function getAssemblyItemsList($recursive = true, $depth = 0) public function addAssemblyItem(Model $part, $quantity = 1, array $extra = []) { if ($this->isValidQuantity($quantity)) { - if (!$this->is_assembly) { + if (!$this->getAttribute('is_assembly')) { $this->makeAssembly(); } - if ($part->is_assembly) { + if ($part->getAttribute('is_assembly')) { $this->validatePart($part); } diff --git a/src/Traits/CategoryTrait.php b/src/Traits/CategoryTrait.php index aca72868..252babdf 100644 --- a/src/Traits/CategoryTrait.php +++ b/src/Traits/CategoryTrait.php @@ -2,9 +2,6 @@ namespace Stevebauman\Inventory\Traits; -/** - * Trait CategoryTrait. - */ trait CategoryTrait { /** diff --git a/src/Traits/VerifyTrait.php b/src/Traits/CommonMethodsTrait.php similarity index 50% rename from src/Traits/VerifyTrait.php rename to src/Traits/CommonMethodsTrait.php index b8e07166..bc5854d0 100644 --- a/src/Traits/VerifyTrait.php +++ b/src/Traits/CommonMethodsTrait.php @@ -2,14 +2,46 @@ namespace Stevebauman\Inventory\Traits; -use Stevebauman\Inventory\Exceptions\InvalidQuantityException; use Illuminate\Support\Facades\Lang; +use Illuminate\Support\Facades\DB; +use Illuminate\Support\Facades\Event; +use Stevebauman\Inventory\Exceptions\InvalidQuantityException; -/** - * Trait VerifyTrait. - */ -trait VerifyTrait +trait CommonMethodsTrait { + /** + * Returns the models identifier key. + * + * @return int|string + */ + abstract public function getKey(); + + /** + * Returns the models identifier key name. + * + * @return string + */ + abstract public function getKeyName(); + + /** + * Returns a attribute from the model. + * + * @param string $key + * + * @return mixed + */ + abstract public function getAttribute($key); + + /** + * Set a given attribute on the model. + * + * @param string $key + * @param mixed $value + * + * @return void + */ + abstract public function setAttribute($key, $value); + /** * Returns true if the specified quantity is valid, throws * InvalidQuantityException otherwise. @@ -33,6 +65,49 @@ public function isValidQuantity($quantity) throw new InvalidQuantityException($message); } + /** + * Alias for firing events easily that implement this trait. + * + * @param string $name + * @param array $args + * + * @return mixed + */ + protected function fireEvent($name, $args = []) + { + return Event::fire((string) $name, (array) $args); + } + + /** + * Alias for beginning a database transaction. + * + * @return mixed + */ + protected function dbStartTransaction() + { + return DB::beginTransaction(); + } + + /** + * Alias for committing a database transaction. + * + * @return mixed + */ + protected function dbCommitTransaction() + { + return DB::commit(); + } + + /** + * Alias for rolling back a transaction. + * + * @return mixed + */ + protected function dbRollbackTransaction() + { + return DB::rollback(); + } + /** * Returns true/false if the number specified is numeric. * diff --git a/src/Traits/DatabaseTransactionTrait.php b/src/Traits/DatabaseTransactionTrait.php deleted file mode 100644 index 0b290971..00000000 --- a/src/Traits/DatabaseTransactionTrait.php +++ /dev/null @@ -1,55 +0,0 @@ -user_id = static::getCurrentUserId(); + $record->user_id = Helper::getCurrentUserId(); }); } @@ -40,8 +36,6 @@ public static function bootInventoryStockMovementTrait() */ public function rollback($recursive = false) { - $stock = $this->stock; - - return $stock->rollback($this, $recursive); + return $this->stock->rollback($this, $recursive); } } diff --git a/src/Traits/InventoryStockTrait.php b/src/Traits/InventoryStockTrait.php index 7dcc63bc..f1743af1 100644 --- a/src/Traits/InventoryStockTrait.php +++ b/src/Traits/InventoryStockTrait.php @@ -6,35 +6,17 @@ use Stevebauman\Inventory\Exceptions\NotEnoughStockException; use Stevebauman\Inventory\Exceptions\InvalidMovementException; use Stevebauman\Inventory\Exceptions\InvalidQuantityException; +use Stevebauman\Inventory\Helper; use Illuminate\Database\Eloquent\Model; use Illuminate\Support\Facades\Config; use Illuminate\Support\Facades\Lang; -/** - * Trait InventoryStockTrait. - */ trait InventoryStockTrait { - /* - * Used for easily grabbing a specified location - */ - use LocationTrait; - /* * Verification helper functions */ - use VerifyTrait; - - /* - * Set's the models constructor method to automatically assign the - * user_id's attribute to the current logged in user - */ - use UserIdentificationTrait; - - /* - * Helpers for starting database transactions - */ - use DatabaseTransactionTrait; + use CommonMethodsTrait; /** * Stores the quantity before an update. @@ -86,13 +68,13 @@ abstract public function movements(); abstract public function transactions(); /** - * Overrides the models boot function to set the user ID automatically - * to every new record. + * Overrides the models boot function to set + * the user ID automatically to every new record. */ public static function bootInventoryStockTrait() { static::creating(function (Model $model) { - $model->user_id = $model->getCurrentUserId(); + $model->user_id = Helper::getCurrentUserId(); /* * Check if a reason has been set, if not @@ -239,14 +221,12 @@ public function put($quantity, $reason = '', $cost = 0) /** * Moves a stock to the specified location. * - * @param $location + * @param Model $location * * @return bool */ - public function moveTo($location) + public function moveTo(Model $location) { - $location = $this->getLocation($location); - return $this->processMoveOperation($location); } @@ -322,7 +302,7 @@ public function hasEnoughStock($quantity = 0) /** * Returns the last movement on the current stock record. * - * @return mixed + * @return bool|Model */ public function getLastMovement() { @@ -339,7 +319,7 @@ public function getLastMovement() * Returns a movement depending on the specified argument. If an object is supplied, it is checked if it * is an instance of an eloquent model. If a numeric value is entered, it is retrieved by it's ID. * - * @param mixed $movement + * @param int|string|Model $movement * * @throws InvalidMovementException * @@ -366,18 +346,15 @@ public function getMovement($movement) * * @param string $name * - * @return \Illuminate\Database\Eloquent\Model + * @return Model */ public function newTransaction($name = '') { - $transaction = $this->transactions()->getRelated(); + $transaction = $this->transactions()->getRelated()->newInstance(); - /* - * Set the transaction attributes so they don't - * need to be set manually - */ - $transaction->stock_id = $this->getKey(); - $transaction->name = $name; + // Set the transaction attributes so they don't need to be set manually + $transaction->setAttribute('stock_id', $this->getKey()); + $transaction->setAttribute('name', $name); return $transaction; } @@ -387,7 +364,7 @@ public function newTransaction($name = '') * * @param int|string $id * - * @return mixed + * @return null|Model */ private function getMovementById($id) { @@ -438,7 +415,7 @@ private function processTakeOperation($taking, $reason = '', $cost = 0) return $this; } - $this->quantity = $left; + $this->setAttribute('quantity', $left); $this->setReason($reason); @@ -556,7 +533,7 @@ private function processRollbackOperation(Model $movement, $recursive = false) return $this->processRecursiveRollbackOperation($movement); } - $this->quantity = $movement->before; + $this->setAttribute('quantity', $movement->getAttribute('before')); $reason = Lang::get('inventory::reasons.rollback', [ 'id' => $movement->getOriginal('id'), @@ -566,7 +543,7 @@ private function processRollbackOperation(Model $movement, $recursive = false) $this->setReason($reason); if ($this->rollbackCostEnabled()) { - $this->setCost($movement->cost); + $this->setCost($movement->getAttribute('cost')); $this->reverseCost(); } @@ -628,19 +605,23 @@ private function processRecursiveRollbackOperation(Model $movement) * @param string $reason * @param int|float|string $cost * - * @return \Illuminate\Database\Eloquent\Model + * @return bool|Model */ private function generateStockMovement($before, $after, $reason = '', $cost = 0) { - $insert = [ - 'stock_id' => $this->getKey(), - 'before' => $before, - 'after' => $after, - 'reason' => $reason, - 'cost' => $cost, - ]; - - return $this->movements()->create($insert); + $movement = $this->movements()->getRelated()->newInstance(); + + $movement->setAttribute('stock_id', $this->getKey()); + $movement->setAttribute('before', $before); + $movement->setAttribute('after', $after); + $movement->setAttribute('reason', $reason); + $movement->setAttribute('cost', $cost); + + if($movement->save()) { + return $movement; + } + + return false; } /** @@ -658,10 +639,12 @@ private function setCost($cost = 0) */ private function reverseCost() { - if ($this->isPositive($this->cost)) { - $this->setCost(-abs($this->cost)); + $cost = $this->getAttribute('cost'); + + if ($this->isPositive($cost)) { + $this->setCost(-abs($cost)); } else { - $this->setCost(abs($this->cost)); + $this->setCost(abs($cost)); } } diff --git a/src/Traits/InventoryTrait.php b/src/Traits/InventoryTrait.php index 87a57b90..f0963535 100644 --- a/src/Traits/InventoryTrait.php +++ b/src/Traits/InventoryTrait.php @@ -8,34 +8,16 @@ use Stevebauman\Inventory\Exceptions\StockNotFoundException; use Stevebauman\Inventory\Exceptions\StockAlreadyExistsException; use Stevebauman\Inventory\InventoryServiceProvider; +use Stevebauman\Inventory\Helper; use Illuminate\Support\Facades\Config; use Illuminate\Support\Facades\Lang; -/** - * Trait InventoryTrait. - */ trait InventoryTrait { /* - * Location helper functions + * Common Helper Methods */ - use LocationTrait; - - /* - * Verification helper functions - */ - use VerifyTrait; - - /* - * Set's the models constructor method to automatically assign the - * user_id's attribute to the current logged in user - */ - use UserIdentificationTrait; - - /* - * Helpers for starting database transactions - */ - use DatabaseTransactionTrait; + use CommonMethodsTrait; /** * The hasOne category relationship. @@ -83,7 +65,7 @@ public static function bootInventoryTrait() * is being created */ static::creating(function (Model $record) { - $record->user_id = static::getCurrentUserId(); + $record->user_id = Helper::getCurrentUserId(); }); /* @@ -222,12 +204,12 @@ public function isInStock() * Creates a stock record to the current inventory item. * * @param int|float|string $quantity - * @param $location + * @param Model $location * @param string $reason * @param int|float|string $cost - * @param null $aisle - * @param null $row - * @param null $bin + * @param string $aisle + * @param string $row + * @param string $bin * * @throws StockAlreadyExistsException * @throws StockNotFoundException @@ -236,14 +218,10 @@ public function isInStock() * * @return Model */ - public function createStockOnLocation($quantity, $location, $reason = '', $cost = 0, $aisle = null, $row = null, $bin = null) + public function createStockOnLocation($quantity, Model $location, $reason = '', $cost = 0, $aisle = null, $row = null, $bin = null) { - $location = $this->getLocation($location); - try { - /* - * We want to make sure stock doesn't exist on the specified location already - */ + // We want to make sure stock doesn't exist on the specified location already if ($this->getStockFromLocation($location)) { $message = Lang::get('inventory::exceptions.StockAlreadyExistsException', [ 'location' => $location->name, @@ -252,28 +230,19 @@ public function createStockOnLocation($quantity, $location, $reason = '', $cost throw new StockAlreadyExistsException($message); } } catch (StockNotFoundException $e) { - /* - * A stock record wasn't found on this location, we'll create one - */ - $insert = [ - 'inventory_id' => $this->getKey(), - 'location_id' => $location->getKey(), - 'quantity' => 0, - 'aisle' => $aisle, - 'row' => $row, - 'bin' => $bin, - ]; - - /* - * We'll perform a create so a 'first' movement is generated - */ - $stock = $this->stocks()->create($insert); - - /* - * Now we'll 'put' the inserted quantity onto the generated stock - * and return the results - */ - return $stock->put($quantity, $reason, $cost); + // A stock record wasn't found on this location, we'll create one. + $stock = $this->stocks()->getRelated()->newInstance(); + + $stock->setAttribute('inventory_id', $this->getKey()); + $stock->setAttribute('location_id', $location->getKey()); + $stock->setAttribute('quantity', 0); + $stock->setAttribute('aisle', $aisle); + $stock->setAttribute('row', $row); + $stock->setAttribute('bin', $bin); + + if($stock->save()) { + return $stock->put($quantity, $reason, $cost); + } } return false; @@ -283,17 +252,15 @@ public function createStockOnLocation($quantity, $location, $reason = '', $cost * Instantiates a new stock on the specified * location on the current item. * - * @param $location + * @param Model $location * * @throws StockAlreadyExistsException * @throws \Stevebauman\Inventory\Exceptions\InvalidLocationException * * @return \Illuminate\Database\Eloquent\Model */ - public function newStockOnLocation($location) + public function newStockOnLocation(Model $location) { - $location = $this->getLocation($location); - try { /* * We want to make sure stock doesn't exist on the specified location already @@ -306,17 +273,12 @@ public function newStockOnLocation($location) throw new StockAlreadyExistsException($message); } } catch (StockNotFoundException $e) { - /* - * Create a new stock model instance - */ - $stock = $this->stocks()->getRelated(); + // Create a new stock model instance + $stock = $this->stocks()->getRelated()->newInstance(); - /* - * Assign the known attributes - * so devs don't have to - */ - $stock->inventory_id = $this->getKey(); - $stock->location_id = $location->getKey(); + // Assign the known attributes so devs don't have to + $stock->setAttribute('inventory_id', $this->getKey()); + $stock->setAttribute('location_id', $location->getKey()); return $stock; } @@ -489,36 +451,32 @@ public function addToManyLocations($quantity, $locations = [], $reason = '', $co /** * Moves a stock from one location to another. * - * @param $fromLocation - * @param $toLocation + * @param Model $fromLocation + * @param Model $toLocation * * @throws StockNotFoundException * * @return mixed */ - public function moveStock($fromLocation, $toLocation) + public function moveStock(Model $fromLocation, Model $toLocation) { $stock = $this->getStockFromLocation($fromLocation); - $toLocation = $this->getLocation($toLocation); - return $stock->moveTo($toLocation); } /** * Retrieves an inventory stock from a given location. * - * @param $location + * @param Model $location * * @throws \Stevebauman\Inventory\Exceptions\InvalidLocationException * @throws StockNotFoundException * * @return mixed */ - public function getStockFromLocation($location) + public function getStockFromLocation(Model $location) { - $location = $this->getLocation($location); - $stock = $this->stocks() ->where('inventory_id', $this->getKey()) ->where('location_id', $location->getKey()) @@ -872,21 +830,20 @@ private function processSkuGeneration($inventoryId, $code) $this->dbStartTransaction(); try { - $insert = [ - 'inventory_id' => $inventoryId, - 'code' => $code, - ]; + $sku = $this->sku()->getRelated()->newInstance(); - $record = $this->sku()->create($insert); + $sku->setAttribute('inventory_id', $inventoryId); + $sku->setAttribute('code', $code); - if ($record) { + if ($sku->save()) { $this->dbCommitTransaction(); $this->fireEvent('inventory.sku.generated', [ 'item' => $this, + 'sku' => $sku, ]); - return $record; + return $sku; } } catch (\Exception $e) { $this->dbRollbackTransaction(); diff --git a/src/Traits/InventoryTransactionHistoryTrait.php b/src/Traits/InventoryTransactionHistoryTrait.php index 71fdbc4c..5d47a687 100644 --- a/src/Traits/InventoryTransactionHistoryTrait.php +++ b/src/Traits/InventoryTransactionHistoryTrait.php @@ -2,25 +2,18 @@ namespace Stevebauman\Inventory\Traits; +use Stevebauman\Inventory\Helper; use Illuminate\Database\Eloquent\Model; -/** - * Trait InventoryTransactionHistoryTrait. - */ trait InventoryTransactionHistoryTrait { - /* - * Provides user identification to the model - */ - use UserIdentificationTrait; - /** * Make sure we try and assign the current user if enabled. */ public static function bootInventoryTransactionHistoryTrait() { static::creating(function (Model $model) { - $model->user_id = static::getCurrentUserId(); + $model->user_id = Helper::getCurrentUserId(); }); } diff --git a/src/Traits/InventoryTransactionTrait.php b/src/Traits/InventoryTransactionTrait.php index a6cb3719..e02c25e4 100644 --- a/src/Traits/InventoryTransactionTrait.php +++ b/src/Traits/InventoryTransactionTrait.php @@ -7,28 +7,16 @@ use Stevebauman\Inventory\Exceptions\StockNotFoundException; use Stevebauman\Inventory\Exceptions\InvalidTransactionStateException; use Stevebauman\Inventory\InventoryServiceProvider; +use Stevebauman\Inventory\Helper; use Illuminate\Database\Eloquent\Model; use Illuminate\Support\Facades\Lang; -/** - * Trait InventoryTransactionTrait. - */ trait InventoryTransactionTrait { /* - * Provides user identification + * Common Inventory Helper Methods */ - use UserIdentificationTrait; - - /* - * Provides database transactions - */ - use DatabaseTransactionTrait; - - /* - * Provides some verification methods - */ - use VerifyTrait; + use CommonMethodsTrait; /** * Stores the state before an update. @@ -51,7 +39,7 @@ trait InventoryTransactionTrait public static function bootInventoryTransactionTrait() { static::creating(function (Model $model) { - $model->user_id = static::getCurrentUserId(); + $model->user_id = Helper::getCurrentUserId(); if (!$model->beforeState) { $model->beforeState = $model::STATE_OPENED; @@ -122,7 +110,7 @@ abstract public function stock(); /** * The hasMany histories relationship. * - * @return mixed + * @return \Illuminate\Database\Eloquent\Relations\HasMany */ abstract public function histories(); @@ -1361,19 +1349,23 @@ private function processSave($event = '') * @param int|float|string $quantityBefore * @param int|float|string $quantityAfter * - * @return mixed + * @return bool|Model */ private function generateTransactionHistory($stateBefore, $stateAfter, $quantityBefore = 0, $quantityAfter = 0) { - $insert = [ - 'transaction_id' => $this->getKey(), - 'state_before' => $stateBefore, - 'state_after' => $stateAfter, - 'quantity_before' => $quantityBefore, - 'quantity_after' => $quantityAfter, - ]; + $history = $this->histories()->getRelated()->newInstance(); + + $history->setAttribute('transaction_id', $this->getKey()); + $history->setAttribute('state_before', $stateBefore); + $history->setAttribute('state_after', $stateAfter); + $history->setAttribute('quantity_before', $quantityBefore); + $history->setAttribute('quantity_after', $quantityAfter); - return $this->histories()->create($insert); + if($history->save()) { + return $history; + } + + return false; } /** diff --git a/src/Traits/InventoryVariantTrait.php b/src/Traits/InventoryVariantTrait.php index 162493b6..1c8bbbbd 100644 --- a/src/Traits/InventoryVariantTrait.php +++ b/src/Traits/InventoryVariantTrait.php @@ -4,9 +4,6 @@ use Illuminate\Database\Eloquent\Model; -/** - * Trait InventoryVariantTrait. - */ trait InventoryVariantTrait { /** diff --git a/src/Traits/LocationTrait.php b/src/Traits/LocationTrait.php deleted file mode 100644 index ba30d713..00000000 --- a/src/Traits/LocationTrait.php +++ /dev/null @@ -1,47 +0,0 @@ -isLocation($location)) { - return $location; - } else { - $message = Lang::get('inventory::exceptions.InvalidLocationException', [ - 'location' => $location, - ]); - - throw new InvalidLocationException($message); - } - } - - /** - * Returns true or false if the specified location is an instance of a model. - * - * @param mixed $object - * - * @return bool - */ - private function isLocation($object) - { - return is_subclass_of($object, 'Illuminate\Database\Eloquent\Model'); - } -} diff --git a/src/Traits/SupplierTrait.php b/src/Traits/SupplierTrait.php index f4e70ec8..5dcb953d 100644 --- a/src/Traits/SupplierTrait.php +++ b/src/Traits/SupplierTrait.php @@ -10,9 +10,7 @@ */ trait SupplierTrait { - use DatabaseTransactionTrait; - - use VerifyTrait; + use CommonMethodsTrait; /** * The belongsToMany items relationship. diff --git a/src/Traits/UserIdentificationTrait.php b/src/Traits/UserIdentificationTrait.php deleted file mode 100644 index f265eea1..00000000 --- a/src/Traits/UserIdentificationTrait.php +++ /dev/null @@ -1,57 +0,0 @@ -id; - } - } elseif (class_exists('Illuminate\Auth') || class_exists('Illuminate\Support\Facades\Auth')) { - if (\Auth::check()) { - return \Auth::user()->getAuthIdentifier(); - } - } - } catch (\Exception $e) { - } - - /* - * Couldn't get the current logged in users ID, throw exception - */ - $message = Lang::get('inventory::exceptions.NoUserLoggedInException'); - - throw new NoUserLoggedInException($message); - } -} diff --git a/src/helpers.php b/src/helpers.php deleted file mode 100644 index 15bd378d..00000000 --- a/src/helpers.php +++ /dev/null @@ -1,35 +0,0 @@ -getAncestorsAndSelf(); - - foreach ($ancestors as $ancestor) { - if ($node->equals($ancestor) && $node->isRoot()) { - $html .= sprintf('%s', $ancestor->name); - } elseif ($node->equals($ancestor)) { - $html .= sprintf(' > %s', $ancestor->name); - } elseif ($ancestor->isRoot()) { - $html .= sprintf('%s', $ancestor->name); - } else { - $html .= sprintf(' > %s', $ancestor->name); - } - } - - return $html; - } - - return $node; - } -} diff --git a/tests/InventoryStockTest.php b/tests/InventoryStockTest.php index f83cbd09..1e8d0d3c 100644 --- a/tests/InventoryStockTest.php +++ b/tests/InventoryStockTest.php @@ -227,7 +227,7 @@ public function testInventoryGetTotalStock() $this->assertEquals(20, $item->getTotalStock()); } - public function testInventoryInvalidLocationException() + public function testInventoryGetStockFromLocationInvalidLocation() { $this->newInventoryStock(); @@ -235,9 +235,15 @@ public function testInventoryInvalidLocationException() Lang::shouldReceive('get')->once(); - $this->setExpectedException('Stevebauman\Inventory\Exceptions\InvalidLocationException'); + try { + $item->getStockFromLocation('testing'); - $item->getStockFromLocation('testing'); + $passes = false; + } catch (\Exception $e) { + $passes = true; + } + + $this->assertTrue($passes); } public function testInventoryStockNewTransaction() diff --git a/tests/InventoryTest.php b/tests/InventoryTest.php index 29490d3f..b09da35f 100644 --- a/tests/InventoryTest.php +++ b/tests/InventoryTest.php @@ -16,6 +16,7 @@ public function setUp() { parent::setUp(); + // Unguard Eloquent for easy mass assignment Eloquent::unguard(); } From f4dd40b55eb0294550ff04a91a244ca68ce159aa Mon Sep 17 00:00:00 2001 From: Steve Bauman Date: Fri, 19 Jun 2015 10:52:24 -0400 Subject: [PATCH 06/51] Removed more class comments, removed InvalidLocationException --- src/Commands/InstallCommand.php | 3 --- src/Commands/RunMigrationsCommand.php | 3 --- src/Commands/SchemaCheckCommand.php | 3 --- src/Exceptions/InvalidItemException.php | 3 --- src/Exceptions/InvalidLocationException.php | 10 ---------- src/Exceptions/InvalidMovementException.php | 3 --- src/Exceptions/InvalidPartException.php | 3 --- src/Exceptions/InvalidQuantityException.php | 3 --- src/Exceptions/InvalidSupplierException.php | 3 --- src/Exceptions/InvalidTransactionStateException.php | 3 --- src/Exceptions/NoUserLoggedInException.php | 3 --- src/Exceptions/NotEnoughStockException.php | 3 --- src/Exceptions/SkuAlreadyExistsException.php | 3 --- src/Exceptions/StockAlreadyExistsException.php | 3 --- src/Exceptions/StockNotFoundException.php | 3 --- 15 files changed, 52 deletions(-) delete mode 100644 src/Exceptions/InvalidLocationException.php diff --git a/src/Commands/InstallCommand.php b/src/Commands/InstallCommand.php index 1676d595..8f9552cb 100644 --- a/src/Commands/InstallCommand.php +++ b/src/Commands/InstallCommand.php @@ -4,9 +4,6 @@ use Illuminate\Console\Command; -/** - * Class InstallCommand. - */ class InstallCommand extends Command { /** diff --git a/src/Commands/RunMigrationsCommand.php b/src/Commands/RunMigrationsCommand.php index 1877c5fa..5a011649 100644 --- a/src/Commands/RunMigrationsCommand.php +++ b/src/Commands/RunMigrationsCommand.php @@ -4,9 +4,6 @@ use Illuminate\Console\Command; -/** - * Class RunMigrationsCommand. - */ class RunMigrationsCommand extends Command { /** diff --git a/src/Commands/SchemaCheckCommand.php b/src/Commands/SchemaCheckCommand.php index 930ed6f4..b550c02f 100644 --- a/src/Commands/SchemaCheckCommand.php +++ b/src/Commands/SchemaCheckCommand.php @@ -7,9 +7,6 @@ use Illuminate\Support\Facades\Schema; use Illuminate\Console\Command; -/** - * Class SchemaCheckCommand. - */ class SchemaCheckCommand extends Command { /** diff --git a/src/Exceptions/InvalidItemException.php b/src/Exceptions/InvalidItemException.php index 165af04d..1a30f871 100644 --- a/src/Exceptions/InvalidItemException.php +++ b/src/Exceptions/InvalidItemException.php @@ -2,9 +2,6 @@ namespace Stevebauman\Inventory\Exceptions; -/** - * Class InvalidItemException. - */ class InvalidItemException extends \Exception { } diff --git a/src/Exceptions/InvalidLocationException.php b/src/Exceptions/InvalidLocationException.php deleted file mode 100644 index 0f2d0645..00000000 --- a/src/Exceptions/InvalidLocationException.php +++ /dev/null @@ -1,10 +0,0 @@ - Date: Fri, 19 Jun 2015 11:12:56 -0400 Subject: [PATCH 07/51] Removed ability to insert many locations into single methods - locations inserted into `takeFromLocation()` and `putToLocation()` must now be instances of a laravel Model --- src/Traits/InventoryTrait.php | 33 +++++++++------------------------ src/lang/en/exceptions.php | 2 -- 2 files changed, 9 insertions(+), 26 deletions(-) diff --git a/src/Traits/InventoryTrait.php b/src/Traits/InventoryTrait.php index f0963535..68ce6a58 100644 --- a/src/Traits/InventoryTrait.php +++ b/src/Traits/InventoryTrait.php @@ -213,7 +213,6 @@ public function isInStock() * * @throws StockAlreadyExistsException * @throws StockNotFoundException - * @throws \Stevebauman\Inventory\Exceptions\InvalidLocationException * @throws \Stevebauman\Inventory\Exceptions\NoUserLoggedInException * * @return Model @@ -255,7 +254,6 @@ public function createStockOnLocation($quantity, Model $location, $reason = '', * @param Model $location * * @throws StockAlreadyExistsException - * @throws \Stevebauman\Inventory\Exceptions\InvalidLocationException * * @return \Illuminate\Database\Eloquent\Model */ @@ -288,27 +286,19 @@ public function newStockOnLocation(Model $location) * Takes the specified amount ($quantity) of stock from specified stock location. * * @param int|float|string $quantity - * @param $location + * @param Model $location * @param string $reason * * @throws StockNotFoundException * * @return array */ - public function takeFromLocation($quantity, $location, $reason = '') + public function takeFromLocation($quantity, Model $location, $reason = '') { - /* - * If the specified location is an array, we must be taking from - * multiple locations - */ - if (is_array($location)) { - return $this->takeFromManyLocations($quantity, $location, $reason); - } else { - $stock = $this->getStockFromLocation($location); + $stock = $this->getStockFromLocation($location); - if ($stock->take($quantity, $reason)) { - return $this; - } + if ($stock && $stock->take($quantity, $reason)) { + return $this; } return false; @@ -367,7 +357,7 @@ public function removeFromManyLocations($quantity, $locations = [], $reason = '' } /** - * Puts the specified amount ($quantity) of stock into the specified stock location(s). + * Puts the specified amount ($quantity) of stock into the specified stock location. * * @param int|float|string $quantity * @param $location @@ -380,14 +370,10 @@ public function removeFromManyLocations($quantity, $locations = [], $reason = '' */ public function putToLocation($quantity, $location, $reason = '', $cost = 0) { - if (is_array($location)) { - return $this->putToManyLocations($quantity, $location); - } else { - $stock = $this->getStockFromLocation($location); + $stock = $this->getStockFromLocation($location); - if ($stock->put($quantity, $reason, $cost)) { - return $this; - } + if ($stock && $stock->put($quantity, $reason, $cost)) { + return $this; } return false; @@ -470,7 +456,6 @@ public function moveStock(Model $fromLocation, Model $toLocation) * * @param Model $location * - * @throws \Stevebauman\Inventory\Exceptions\InvalidLocationException * @throws StockNotFoundException * * @return mixed diff --git a/src/lang/en/exceptions.php b/src/lang/en/exceptions.php index 3d3ba03b..df714ac5 100644 --- a/src/lang/en/exceptions.php +++ b/src/lang/en/exceptions.php @@ -7,8 +7,6 @@ */ return [ - 'InvalidLocationException' => 'Location :location is invalid', - 'InvalidMovementException' => 'Movement :movement is invalid', 'InvalidSupplierException' => 'Supplier :supplier is invalid', From 4d3c6df4c5f09d9d62b475e66cafdf19b8c6d81a Mon Sep 17 00:00:00 2001 From: Steve Bauman Date: Fri, 19 Jun 2015 11:22:57 -0400 Subject: [PATCH 08/51] Updated comments and more use of `getAttribute()` instead of accessing dynamic attributes --- src/Traits/InventoryTrait.php | 73 +++++++++++++---------------------- 1 file changed, 27 insertions(+), 46 deletions(-) diff --git a/src/Traits/InventoryTrait.php b/src/Traits/InventoryTrait.php index 68ce6a58..d9d19fe3 100644 --- a/src/Traits/InventoryTrait.php +++ b/src/Traits/InventoryTrait.php @@ -360,7 +360,7 @@ public function removeFromManyLocations($quantity, $locations = [], $reason = '' * Puts the specified amount ($quantity) of stock into the specified stock location. * * @param int|float|string $quantity - * @param $location + * @param Model $location * @param string $reason * @param int|float|string $cost * @@ -368,7 +368,7 @@ public function removeFromManyLocations($quantity, $locations = [], $reason = '' * * @return array */ - public function putToLocation($quantity, $location, $reason = '', $cost = 0) + public function putToLocation($quantity, Model $location, $reason = '', $cost = 0) { $stock = $this->getStockFromLocation($location); @@ -414,7 +414,7 @@ public function putToManyLocations($quantity, $locations = [], $reason = '', $co * * @return array */ - public function addToLocation($quantity, $location, $reason = '', $cost = 0) + public function addToLocation($quantity, Model $location, $reason = '', $cost = 0) { return $this->putToLocation($quantity, $location, $reason, $cost); } @@ -471,7 +471,7 @@ public function getStockFromLocation(Model $location) return $stock; } else { $message = Lang::get('inventory::exceptions.StockNotFoundException', [ - 'location' => $location->name, + 'location' => $location->getAttribute('name'), ]); throw new StockNotFoundException($message); @@ -486,7 +486,7 @@ public function getStockFromLocation(Model $location) public function getSku() { if ($this->hasSku()) { - return $this->sku->code; + return $this->sku->getAttribute('code'); } return; @@ -527,20 +527,22 @@ public function generateSku() return $this->sku; } + $separator = InventoryServiceProvider::$packageConfigSeparator; + /* * Get the set SKU code length from the configuration file */ - $codeLength = Config::get('inventory'.InventoryServiceProvider::$packageConfigSeparator.'sku_code_length'); + $codeLength = Config::get('inventory'.$separator.'sku_code_length'); /* * Get the set SKU prefix length from the configuration file */ - $prefixLength = Config::get('inventory'.InventoryServiceProvider::$packageConfigSeparator.'sku_prefix_length'); + $prefixLength = Config::get('inventory'.$separator.'sku_prefix_length'); /* * Get the set SKU separator */ - $skuSeparator = Config::get('inventory'.InventoryServiceProvider::$packageConfigSeparator.'sku_separator'); + $skuSeparator = Config::get('inventory'.$separator.'sku_separator'); /* * Make sure we trim empty spaces in the separator if it's a string, otherwise we'll @@ -552,7 +554,7 @@ public function generateSku() * Trim the category name to remove blank spaces, then * grab the first 3 letters of the string, and uppercase them */ - $prefix = strtoupper(substr(trim($this->category->name), 0, intval($prefixLength))); + $prefix = strtoupper(substr(trim($this->category->getAttribute('name')), 0, intval($prefixLength))); /* * We'll make sure the prefix length is greater than zero before we try and @@ -590,37 +592,25 @@ public function regenerateSku() $sku = $this->sku()->first(); if ($sku) { - /* - * Capture current SKU - */ + // Capture current SKU $previousSku = $sku; - /* - * Delete current SKU - */ + // Delete current SKU $sku->delete(); - /* - * Try to generate a new SKU - */ + // Try to generate a new SKU $newSku = $this->generateSku(); - /* - * New sku generation successful, return it - */ + // New sku generation successful, return it if ($newSku) { return $newSku; } - /* - * Failed generating a new sku, we'll restore the old one - */ + // Failed generating a new sku, we'll restore the old one return $this->processSkuGeneration($this->getKey(), $previousSku->code); } - /* - * Always generate an SKU if one doesn't exist - */ + // Always generate an SKU if one doesn't exist return $this->generateSku(); } @@ -645,25 +635,18 @@ public function createSku($code, $overwrite = false) $sku = $this->sku()->first(); if ($sku) { - /* - * The dev doesn't want the SKU overridden, - * we'll thrown an exception - */ + // The dev doesn't want the SKU overridden, we'll thrown an exception if (!$overwrite) { $message = Lang::get('inventory::exceptions.SkuAlreadyExistsException'); throw new SkuAlreadyExistsException($message); } - /* - * Overwrite is true, lets update the current SKU - */ + // Overwrite is true, lets update the current SKU return $this->updateSku($code, $sku); } - /* - * No SKU exists, lets create one - */ + // No SKU exists, lets create one return $this->processSkuGeneration($this->getKey(), $code); } @@ -678,9 +661,7 @@ public function createSku($code, $overwrite = false) */ public function updateSku($code, $sku = null) { - /* - * Get the current SKU record if one isn't supplied - */ + // Get the current SKU record if one isn't supplied if (!$sku) { $sku = $this->sku()->first(); } @@ -793,13 +774,13 @@ public function getSupplier($supplier) return $this->getSupplierById($supplier); } elseif ($this->isModel($supplier)) { return $supplier; - } else { - $message = Lang::get('inventory::exceptions.InvalidSupplierException', [ - 'supplier' => $supplier, - ]); - - throw new InvalidSupplierException($message); } + + $message = Lang::get('inventory::exceptions.InvalidSupplierException', [ + 'supplier' => $supplier, + ]); + + throw new InvalidSupplierException($message); } /** From 577033879a1fa29153381508ee2b5a45256a2cba Mon Sep 17 00:00:00 2001 From: Steve Bauman Date: Fri, 19 Jun 2015 11:24:15 -0400 Subject: [PATCH 09/51] Make sure we're comparing identical types --- src/Traits/AssemblyTrait.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Traits/AssemblyTrait.php b/src/Traits/AssemblyTrait.php index 2ecc135c..59f39d5d 100644 --- a/src/Traits/AssemblyTrait.php +++ b/src/Traits/AssemblyTrait.php @@ -378,7 +378,7 @@ private function validatePart(Model $part) */ private function validatePartAgainstList($value, $key) { - if ($key === $this->getKeyName()) { + if ((string) $key === (string) $this->getKeyName()) { if ((int) $value === (int) $this->getKey()) { $message = 'The inserted part exists inside the assembly tree. An item cannot be an assembly of itself.'; From f8b0fa5edd443170e2827272ea5a8c16a601594f Mon Sep 17 00:00:00 2001 From: Steve Bauman Date: Fri, 19 Jun 2015 11:26:30 -0400 Subject: [PATCH 10/51] Compare quantities strictly --- src/Traits/InventoryStockTrait.php | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/Traits/InventoryStockTrait.php b/src/Traits/InventoryStockTrait.php index f1743af1..1d3bb2e0 100644 --- a/src/Traits/InventoryStockTrait.php +++ b/src/Traits/InventoryStockTrait.php @@ -283,17 +283,15 @@ public function rollbackMovement($movement, $recursive = false) */ public function hasEnoughStock($quantity = 0) { - /* - * Using double equals for validation of complete value only, not variable type. For example: - * '20' (string) equals 20 (int) - */ - if ($this->quantity == $quantity || $this->quantity > $quantity) { + $available = $this->getAttribute('quantity'); + + if ((float) $available === (float) $quantity || $available > $quantity) { return true; } $message = Lang::get('inventory::exceptions.NotEnoughStockException', [ 'quantity' => $quantity, - 'available' => $this->quantity, + 'available' => $available, ]); throw new NotEnoughStockException($message); From c446e2a5a93902d67b8215c191ae3704ca9fd1b7 Mon Sep 17 00:00:00 2001 From: Steve Bauman Date: Fri, 19 Jun 2015 11:49:05 -0400 Subject: [PATCH 11/51] Compare quantities strictly and save as float --- src/Traits/InventoryStockTrait.php | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/Traits/InventoryStockTrait.php b/src/Traits/InventoryStockTrait.php index 1d3bb2e0..1e595d77 100644 --- a/src/Traits/InventoryStockTrait.php +++ b/src/Traits/InventoryStockTrait.php @@ -402,14 +402,16 @@ private function processUpdateQuantityOperation($quantity, $reason = '', $cost = */ private function processTakeOperation($taking, $reason = '', $cost = 0) { - $left = $this->quantity - $taking; + $available = $this->getAttribute('quantity'); + + $left = (float) $available - (float) $taking; /* * If the updated total and the beginning total are the same, we'll check if * duplicate movements are allowed. We'll return the current record if * they aren't. */ - if ($left == $this->quantity && !$this->allowDuplicateMovementsEnabled()) { + if ((float) $left === (float) $available && !$this->allowDuplicateMovementsEnabled()) { return $this; } @@ -449,15 +451,15 @@ private function processTakeOperation($taking, $reason = '', $cost = 0) */ private function processPutOperation($putting, $reason = '', $cost = 0) { - $before = $this->quantity; + $current = $this->getAttribute('quantity'); - $total = $putting + $before; + $total = (float) $putting + (float) $current; /* * If the updated total and the beginning total are the same, * we'll check if duplicate movements are allowed */ - if ($total == $this->quantity && !$this->allowDuplicateMovementsEnabled()) { + if ((float) $total === (float) $current && !$this->allowDuplicateMovementsEnabled()) { return $this; } @@ -629,7 +631,7 @@ private function generateStockMovement($before, $after, $reason = '', $cost = 0) */ private function setCost($cost = 0) { - $this->cost = $cost; + $this->cost = (float) $cost; } /** From 4f8fa755e49dbfb096e6ff3a6d942d1780c87ed2 Mon Sep 17 00:00:00 2001 From: Steve Bauman Date: Fri, 19 Jun 2015 11:49:58 -0400 Subject: [PATCH 12/51] Transaction updates - Use `getAttribute()` and `setAttribute()` when applicable - Compare quantities strictly and save quantities as float type --- src/Traits/InventoryTransactionTrait.php | 116 +++++++++++------------ 1 file changed, 56 insertions(+), 60 deletions(-) diff --git a/src/Traits/InventoryTransactionTrait.php b/src/Traits/InventoryTransactionTrait.php index e02c25e4..f0cf66e0 100644 --- a/src/Traits/InventoryTransactionTrait.php +++ b/src/Traits/InventoryTransactionTrait.php @@ -404,12 +404,9 @@ public function returned($quantity = 0, $reason = '', $cost = 0) */ public function returnedPartial($quantity, $reason = '', $cost = 0) { - /* - * If the inserted quantity is equal to or greater than - * the quantity inside the transaction, - * they must be returning all of the stock - */ - if ($quantity == $this->quantity || $quantity > $this->quantity) { + $current = $this->getAttribute('quantity'); + + if ((float) $quantity === (float) $current || $quantity > $current) { return $this->returnedAll($reason, $cost); } @@ -424,22 +421,16 @@ public function returnedPartial($quantity, $reason = '', $cost = 0) $this::STATE_COMMERCE_RETURNED_PARTIAL, ], $this::STATE_COMMERCE_RETURNED_PARTIAL); - /* - * Retrieve the previous state for returning the transaction - * to it's original state - */ - $previousState = $this->state; + // Retrieve the previous state for returning the transaction to it's original state + $previousState = $this->getAttribute('state'); - /* - * Set a new state so a history record is created - */ - $this->state = $this::STATE_COMMERCE_RETURNED_PARTIAL; + // Set a new state so a history record is created + $this->setAttribute('state', $this::STATE_COMMERCE_RETURNED_PARTIAL); - /* - * Set the new left-over quantity from removing - * the amount returned - */ - $this->quantity = $this->quantity - $quantity; + // Set the new left-over quantity from removing the amount returned + $left = (float) $current - (float) $quantity; + + $this->setAttribute('quantity', $left); if (!$reason) { $reason = $this->getTransactionReason('returned-partial'); @@ -476,24 +467,22 @@ public function returnedAll($reason = '', $cost = 0) $this::STATE_COMMERCE_RETURNED_PARTIAL, ], $this::STATE_COMMERCE_RETURNED); - /* - * Set the state to returned - */ - $this->state = $this::STATE_COMMERCE_RETURNED; + // Set the state to returned + $this->setAttribute('state', $this::STATE_COMMERCE_RETURNED); - $originalQuantity = $this->quantity; + $current = $this->getAttribute('quantity'); /* * Set the quantity to zero because we are * returning all of the stock */ - $this->quantity = 0; + $this->setAttribute('quantity', 0); if (!$reason) { $reason = $this->getTransactionReason('returned'); } - return $this->processStockPutAndSave($originalQuantity, 'inventory.transaction.removed', $reason, $cost); + return $this->processStockPutAndSave($current, 'inventory.transaction.removed', $reason, $cost); } /** @@ -720,28 +709,25 @@ public function receivedAll($reason = '', $cost = 0) */ public function receivedPartial($quantity, $reason = '', $cost = 0) { - if ($quantity == $this->quantity || $quantity > $this->quantity) { + $current = $this->getAttribute('quantity'); + + if ((float) $quantity === (float) $current || $quantity > $current) { return $this->receivedAll($reason, $cost); } - /* - * Only allow the previous state of ordered - */ + // Only allow the previous state of ordered $this->validatePreviousState([ $this::STATE_ORDERED_PENDING, ], $this::STATE_ORDERED_RECEIVED_PARTIAL); - /* - * Get the left over amount of quantity still to - * be received - */ - $left = $this->quantity - $quantity; + // Get the left over amount of quantity still to be received + $left = (float) $current - (float) $quantity; - $this->quantity = $left; + $this->setAttribute('quantity', $left); - $previousState = $this->state; + $previousState = $this->getAttribute('state'); - $this->state = $this::STATE_ORDERED_RECEIVED_PARTIAL; + $this->setAttribute('state', $this::STATE_ORDERED_RECEIVED_PARTIAL); if (!$reason) { $reason = $this->getTransactionReason('received-partial'); @@ -774,9 +760,9 @@ public function hold($quantity, $reason = '', $cost = 0) $this::STATE_OPENED, ], $this::STATE_INVENTORY_ON_HOLD); - $this->quantity = $quantity; + $this->setAttribute('quantity', $quantity); - $this->state = $this::STATE_INVENTORY_ON_HOLD; + $this->setAttribute('state', $this::STATE_INVENTORY_ON_HOLD); if (!$reason) { $reason = $this->getTransactionReason('hold'); @@ -858,7 +844,9 @@ public function releaseAll($reason = '', $cost = 0) */ public function releasePartial($quantity, $reason = '', $cost = 0) { - if ($quantity == $this->quantity || $quantity > $this->quantity) { + $current = $this->getAttribute('quantity'); + + if ((float) $quantity === (float) $current || $quantity > $current) { return $this->releaseAll($reason, $cost); } @@ -866,11 +854,13 @@ public function releasePartial($quantity, $reason = '', $cost = 0) $this::STATE_INVENTORY_ON_HOLD, ], $this::STATE_INVENTORY_RELEASED); - $this->quantity = $this->quantity - $quantity; + $left = (float) $current - (float) $quantity; - $previousState = $this->state; + $this->setAttribute('quantity', $left); - $this->state = $this::STATE_INVENTORY_RELEASED_PARTIAL; + $previousState = $this->getAttribute('state'); + + $this->setAttribute('state', $this::STATE_INVENTORY_RELEASED_PARTIAL); if (!$reason) { $reason = $this->getTransactionReason('released-partial'); @@ -961,7 +951,9 @@ public function removePartial($quantity, $reason = '', $cost = 0) * a transaction for removing a quantity from the current stock */ if ($this->isOnHold()) { - if ($quantity == $this->quantity || $quantity > $this->quantity) { + $current = $this->getAttribute('quantity'); + + if ((float) $quantity === (float) $current || $quantity > $current) { return $this->removeAll(); } @@ -969,11 +961,13 @@ public function removePartial($quantity, $reason = '', $cost = 0) $this::STATE_INVENTORY_ON_HOLD, ], $this::STATE_INVENTORY_REMOVED_PARTIAL); - $this->quantity = $this->quantity - $quantity; + $left = (float) $current - (float) $quantity; - $previousState = $this->state; + $this->setAttribute('quantity', $left); - $this->state = $this::STATE_INVENTORY_REMOVED_PARTIAL; + $previousState = $this->getAttribute('state'); + + $this->setAttribute('state', $this::STATE_INVENTORY_REMOVED_PARTIAL); if ($this->processSave('inventory.transaction.removed.partial')) { return $this->returnToPreviousState($previousState); @@ -988,9 +982,9 @@ public function removePartial($quantity, $reason = '', $cost = 0) $this::STATE_OPENED, ], $this::STATE_INVENTORY_REMOVED); - $this->state = $this::STATE_INVENTORY_REMOVED; + $this->setAttribute('state', $this::STATE_INVENTORY_REMOVED); - $this->quantity = $quantity; + $this->setAttribute('quantity', (float) $quantity); if (!$reason) { $reason = $this->getTransactionReason('removed'); @@ -1030,11 +1024,11 @@ public function cancel($reason = '', $cost = 0) $this::STATE_INVENTORY_ON_HOLD, ], $this::STATE_CANCELLED); - $beforeQuantity = $this->quantity; - $beforeState = $this->state; + $beforeQuantity = $this->getAttribute('quantity'); + $beforeState = $this->getAttribute('state'); - $this->quantity = 0; - $this->state = $this::STATE_CANCELLED; + $this->setAttribute('quantity', 0); + $this->setAttribute('state', $this::STATE_CANCELLED); $event = 'inventory.transaction.cancelled'; @@ -1172,7 +1166,7 @@ private function returnToPreviousState($previousState) */ private function reservedFromCheckout() { - $this->state = $this::STATE_COMMERCE_RESERVED; + $this->setAttribute('state', $this::STATE_COMMERCE_RESERVED); return $this->processSave('inventory.transaction.reserved'); } @@ -1185,7 +1179,7 @@ private function reservedFromCheckout() */ private function checkoutFromReserved() { - $this->state = $this::STATE_COMMERCE_CHECKOUT; + $this->setAttribute('state', $this::STATE_COMMERCE_CHECKOUT); return $this->processSave('inventory.transaction.checkout'); } @@ -1203,8 +1197,10 @@ private function checkoutFromReserved() */ private function validatePreviousState($allowedStates = [], $toState) { - if (!in_array($this->state, $allowedStates)) { - $fromState = (!$this->state ? 'NULL' : $this->state); + $state = $this->getAttribute('state'); + + if (!in_array($state, $allowedStates)) { + $fromState = (!$state ? 'NULL' : $state); $message = "Transaction state: $fromState cannot be changed to a: $toState state."; @@ -1291,7 +1287,7 @@ private function processStockTakeAndSave($quantity, $event = '', $reason = '', $ $stock->isValidQuantity($quantity); - $stock->hasEnoughStock($this->quantity); + $stock->hasEnoughStock($this->getAttribute('quantity')); $this->dbStartTransaction(); From 060726d85635a1e8a2d726b0e6d6789cb31dcde3 Mon Sep 17 00:00:00 2001 From: Steve Bauman Date: Fri, 19 Jun 2015 11:50:42 -0400 Subject: [PATCH 13/51] Small comment update --- src/Traits/InventoryTrait.php | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/Traits/InventoryTrait.php b/src/Traits/InventoryTrait.php index d9d19fe3..61ee4c32 100644 --- a/src/Traits/InventoryTrait.php +++ b/src/Traits/InventoryTrait.php @@ -629,9 +629,7 @@ public function regenerateSku() */ public function createSku($code, $overwrite = false) { - /* - * Get the current SKU record - */ + // Get the current SKU record $sku = $this->sku()->first(); if ($sku) { From 5eaa9da908b305301cb552015a8bab8ffbe03ec9 Mon Sep 17 00:00:00 2001 From: Steve Bauman Date: Fri, 19 Jun 2015 12:22:20 -0400 Subject: [PATCH 14/51] More getting / setting use --- src/Traits/InventoryStockMovementTrait.php | 2 +- src/Traits/InventoryStockTrait.php | 142 +++++++++--------- src/Traits/InventoryTrait.php | 2 +- .../InventoryTransactionHistoryTrait.php | 2 +- src/Traits/InventoryTransactionTrait.php | 92 +++++------- 5 files changed, 109 insertions(+), 131 deletions(-) diff --git a/src/Traits/InventoryStockMovementTrait.php b/src/Traits/InventoryStockMovementTrait.php index 7d3cc421..fdd1eae1 100644 --- a/src/Traits/InventoryStockMovementTrait.php +++ b/src/Traits/InventoryStockMovementTrait.php @@ -23,7 +23,7 @@ abstract public function stock(); public static function bootInventoryStockMovementTrait() { static::creating(function (Model $record) { - $record->user_id = Helper::getCurrentUserId(); + $record->setAttribute('user_id', Helper::getCurrentUserId()); }); } diff --git a/src/Traits/InventoryStockTrait.php b/src/Traits/InventoryStockTrait.php index 1e595d77..d28708dd 100644 --- a/src/Traits/InventoryStockTrait.php +++ b/src/Traits/InventoryStockTrait.php @@ -18,13 +18,6 @@ trait InventoryStockTrait */ use CommonMethodsTrait; - /** - * Stores the quantity before an update. - * - * @var int|float|string - */ - private $beforeQuantity = 0; - /** * Stores the reason for updating / creating a stock. * @@ -39,6 +32,13 @@ trait InventoryStockTrait */ public $cost = 0; + /** + * Stores the quantity before an update. + * + * @var int|float|string + */ + private $beforeQuantity = 0; + /** * The hasOne location relationship. * @@ -74,7 +74,7 @@ abstract public function transactions(); public static function bootInventoryStockTrait() { static::creating(function (Model $model) { - $model->user_id = Helper::getCurrentUserId(); + $model->setAttribute('user_id', Helper::getCurrentUserId()); /* * Check if a reason has been set, if not @@ -110,19 +110,11 @@ public static function bootInventoryStockTrait() } /** - * Generates a stock movement on the creation of a stock. + * Generates a stock movement after a stock is created. */ public function postCreate() { - /* - * Only create a first record movement if one isn't created already - */ - if (!$this->getLastMovement()) { - /* - * Generate the movement - */ - $this->generateStockMovement(0, $this->quantity, $this->reason, $this->cost); - } + $this->generateStockMovement(0, $this->getAttribute('quantity'), $this->reason, $this->cost); } /** @@ -130,7 +122,7 @@ public function postCreate() */ public function postUpdate() { - $this->generateStockMovement($this->beforeQuantity, $this->quantity, $this->reason, $this->cost); + $this->generateStockMovement($this->beforeQuantity, $this->getAttribute('quantity'), $this->reason, $this->cost); } /** @@ -181,9 +173,7 @@ public function remove($quantity, $reason = '', $cost = 0) */ public function take($quantity, $reason = '', $cost = 0) { - if ($this->isValidQuantity($quantity) && $this->hasEnoughStock($quantity)) { - return $this->processTakeOperation($quantity, $reason, $cost); - } + return $this->processTakeOperation($quantity, $reason, $cost); } /** @@ -213,9 +203,7 @@ public function add($quantity, $reason = '', $cost = 0) */ public function put($quantity, $reason = '', $cost = 0) { - if ($this->isValidQuantity($quantity)) { - return $this->processPutOperation($quantity, $reason, $cost); - } + return $this->processPutOperation($quantity, $reason, $cost); } /** @@ -380,12 +368,14 @@ private function getMovementById($id) */ private function processUpdateQuantityOperation($quantity, $reason = '', $cost = 0) { - if ($quantity > $this->quantity) { - $putting = $quantity - $this->quantity; + $current = $this->getAttribute('quantity'); + + if ($quantity > $current) { + $putting = $quantity - $current; return $this->put($putting, $reason, $cost); } else { - $taking = $this->quantity - $quantity; + $taking = $current - $quantity; return $this->take($taking, $reason, $cost); } @@ -402,39 +392,41 @@ private function processUpdateQuantityOperation($quantity, $reason = '', $cost = */ private function processTakeOperation($taking, $reason = '', $cost = 0) { - $available = $this->getAttribute('quantity'); + if($this->isValidQuantity($taking) && $this->hasEnoughStock($taking)) { + $available = $this->getAttribute('quantity'); - $left = (float) $available - (float) $taking; + $left = (float) $available - (float) $taking; - /* - * If the updated total and the beginning total are the same, we'll check if - * duplicate movements are allowed. We'll return the current record if - * they aren't. - */ - if ((float) $left === (float) $available && !$this->allowDuplicateMovementsEnabled()) { - return $this; - } + /* + * If the updated total and the beginning total are the same, we'll check if + * duplicate movements are allowed. We'll return the current record if + * they aren't. + */ + if ((float) $left === (float) $available && !$this->allowDuplicateMovementsEnabled()) { + return $this; + } - $this->setAttribute('quantity', $left); + $this->setAttribute('quantity', $left); - $this->setReason($reason); + $this->setReason($reason); - $this->setCost($cost); + $this->setCost($cost); - $this->dbStartTransaction(); + $this->dbStartTransaction(); - try { - if ($this->save()) { - $this->dbCommitTransaction(); + try { + if ($this->save()) { + $this->dbCommitTransaction(); - $this->fireEvent('inventory.stock.taken', [ - 'stock' => $this, - ]); + $this->fireEvent('inventory.stock.taken', [ + 'stock' => $this, + ]); - return $this; + return $this; + } + } catch (\Exception $e) { + $this->dbRollbackTransaction(); } - } catch (\Exception $e) { - $this->dbRollbackTransaction(); } return false; @@ -451,38 +443,40 @@ private function processTakeOperation($taking, $reason = '', $cost = 0) */ private function processPutOperation($putting, $reason = '', $cost = 0) { - $current = $this->getAttribute('quantity'); + if($this->isValidQuantity($putting)) { + $current = $this->getAttribute('quantity'); - $total = (float) $putting + (float) $current; + $total = (float) $putting + (float) $current; - /* - * If the updated total and the beginning total are the same, - * we'll check if duplicate movements are allowed - */ - if ((float) $total === (float) $current && !$this->allowDuplicateMovementsEnabled()) { - return $this; - } + /* + * If the updated total and the beginning total are the same, + * we'll check if duplicate movements are allowed + */ + if ((float) $total === (float) $current && !$this->allowDuplicateMovementsEnabled()) { + return $this; + } - $this->quantity = $total; + $this->quantity = $total; - $this->setReason($reason); + $this->setReason($reason); - $this->setCost($cost); + $this->setCost($cost); - $this->dbStartTransaction(); + $this->dbStartTransaction(); - try { - if ($this->save()) { - $this->dbCommitTransaction(); + try { + if ($this->save()) { + $this->dbCommitTransaction(); - $this->fireEvent('inventory.stock.added', [ - 'stock' => $this, - ]); + $this->fireEvent('inventory.stock.added', [ + 'stock' => $this, + ]); - return $this; + return $this; + } + } catch (\Exception $e) { + $this->dbRollbackTransaction(); } - } catch (\Exception $e) { - $this->dbRollbackTransaction(); } return false; @@ -498,7 +492,7 @@ private function processPutOperation($putting, $reason = '', $cost = 0) */ private function processMoveOperation(Model $location) { - $this->location_id = $location->getKey(); + $this->setAttribute('location_id', $location->getKey()); $this->dbStartTransaction(); diff --git a/src/Traits/InventoryTrait.php b/src/Traits/InventoryTrait.php index 61ee4c32..9b92f5aa 100644 --- a/src/Traits/InventoryTrait.php +++ b/src/Traits/InventoryTrait.php @@ -65,7 +65,7 @@ public static function bootInventoryTrait() * is being created */ static::creating(function (Model $record) { - $record->user_id = Helper::getCurrentUserId(); + $record->setAttribute('user_id', Helper::getCurrentUserId()); }); /* diff --git a/src/Traits/InventoryTransactionHistoryTrait.php b/src/Traits/InventoryTransactionHistoryTrait.php index 5d47a687..d00b5509 100644 --- a/src/Traits/InventoryTransactionHistoryTrait.php +++ b/src/Traits/InventoryTransactionHistoryTrait.php @@ -13,7 +13,7 @@ trait InventoryTransactionHistoryTrait public static function bootInventoryTransactionHistoryTrait() { static::creating(function (Model $model) { - $model->user_id = Helper::getCurrentUserId(); + $model->setAttribute('user_id', Helper::getCurrentUserId()); }); } diff --git a/src/Traits/InventoryTransactionTrait.php b/src/Traits/InventoryTransactionTrait.php index f0cf66e0..845e24e4 100644 --- a/src/Traits/InventoryTransactionTrait.php +++ b/src/Traits/InventoryTransactionTrait.php @@ -39,7 +39,7 @@ trait InventoryTransactionTrait public static function bootInventoryTransactionTrait() { static::creating(function (Model $model) { - $model->user_id = Helper::getCurrentUserId(); + $model->setAttribute('user_id', Helper::getCurrentUserId()); if (!$model->beforeState) { $model->beforeState = $model::STATE_OPENED; @@ -83,13 +83,7 @@ public static function getByState($state) */ public function postCreate() { - /* - * Make sure the transaction does not already have a history record - * before creating one - */ - if (!$this->getLastHistoryRecord()) { - $this->generateTransactionHistory($this->beforeState, $this->state, 0, $this->quantity); - } + $this->generateTransactionHistory($this->beforeState, $this->getAttribute('state'), 0, $this->getAttribute('quantity')); } /** @@ -97,7 +91,7 @@ public function postCreate() */ public function postUpdate() { - $this->generateTransactionHistory($this->beforeState, $this->state, $this->beforeQuantity, $this->quantity); + $this->generateTransactionHistory($this->beforeState, $this->getAttribute('state'), $this->beforeQuantity, $this->getAttribute('quantity')); } /** @@ -122,7 +116,7 @@ abstract public function histories(); */ public function isCheckout() { - return ($this->state === $this::STATE_COMMERCE_CHECKOUT ? true : false); + return ($this->getAttribute('state') === $this::STATE_COMMERCE_CHECKOUT ? true : false); } /** @@ -133,7 +127,7 @@ public function isCheckout() */ public function isReservation() { - return ($this->state === $this::STATE_COMMERCE_RESERVED ? true : false); + return ($this->getAttribute('state') === $this::STATE_COMMERCE_RESERVED ? true : false); } /** @@ -144,7 +138,7 @@ public function isReservation() */ public function isBackOrder() { - return ($this->state === $this::STATE_COMMERCE_BACK_ORDERED ? true : false); + return ($this->getAttribute('state') === $this::STATE_COMMERCE_BACK_ORDERED ? true : false); } /** @@ -155,7 +149,7 @@ public function isBackOrder() */ public function isReturn() { - return ($this->state === $this::STATE_COMMERCE_RETURNED ? true : false); + return ($this->getAttribute('state') === $this::STATE_COMMERCE_RETURNED ? true : false); } /** @@ -166,7 +160,7 @@ public function isReturn() */ public function isSold() { - return ($this->state === $this::STATE_COMMERCE_SOLD ? true : false); + return ($this->getAttribute('state') === $this::STATE_COMMERCE_SOLD ? true : false); } /** @@ -177,7 +171,7 @@ public function isSold() */ public function isCancelled() { - return ($this->state === $this::STATE_CANCELLED ? true : false); + return ($this->getAttribute('state') === $this::STATE_CANCELLED ? true : false); } /** @@ -188,7 +182,7 @@ public function isCancelled() */ public function isOrder() { - return ($this->state === $this::STATE_ORDERED_PENDING ? true : false); + return ($this->getAttribute('state') === $this::STATE_ORDERED_PENDING ? true : false); } /** @@ -199,7 +193,7 @@ public function isOrder() */ public function isOrderReceived() { - return ($this->state === $this::STATE_ORDERED_RECEIVED ? true : false); + return ($this->getAttribute('state') === $this::STATE_ORDERED_RECEIVED ? true : false); } /** @@ -210,7 +204,7 @@ public function isOrderReceived() */ public function isOnHold() { - return ($this->state === $this::STATE_INVENTORY_ON_HOLD ? true : false); + return ($this->getAttribute('state') === $this::STATE_INVENTORY_ON_HOLD ? true : false); } /** @@ -221,7 +215,7 @@ public function isOnHold() */ public function isReleased() { - return ($this->state === $this::STATE_INVENTORY_RELEASED ? true : false); + return ($this->getAttribute('state') === $this::STATE_INVENTORY_RELEASED ? true : false); } /** @@ -232,7 +226,7 @@ public function isReleased() */ public function isRemoved() { - return ($this->state === $this::STATE_INVENTORY_REMOVED ? true : false); + return ($this->getAttribute('state') === $this::STATE_INVENTORY_REMOVED ? true : false); } /** @@ -265,9 +259,8 @@ public function checkout($quantity = 0, $reason = '', $cost = 0) return $this->checkoutFromReserved(); } - $this->quantity = $quantity; - - $this->state = $this::STATE_COMMERCE_CHECKOUT; + $this->setAttribute('quantity', $quantity); + $this->setAttribute('state', $this::STATE_COMMERCE_CHECKOUT); if (!$reason) { $reason = $this->getTransactionReason('checkout'); @@ -317,7 +310,7 @@ public function sold($quantity = 0, $reason = '', $cost = 0) /* * Mark the current state sold */ - $this->state = $this::STATE_COMMERCE_SOLD; + $this->setAttribute('state', $this::STATE_COMMERCE_SOLD); return $this->processSave('inventory.transaction.sold'); } @@ -336,20 +329,15 @@ public function sold($quantity = 0, $reason = '', $cost = 0) */ public function soldAmount($quantity, $reason = '', $cost = 0) { - /* - * Only allow a previous state of null or opened - */ + // Only allow a previous state of null or opened $this->validatePreviousState([ null, $this::STATE_OPENED, ], $this::STATE_COMMERCE_SOLD); - /* - * Mark the current state sold - */ - $this->state = $this::STATE_COMMERCE_SOLD; - - $this->quantity = $quantity; + // Mark the current state sold + $this->setAttribute('state', $this::STATE_COMMERCE_SOLD); + $this->setAttribute('quantity', $quantity); if (!$reason) { $reason = $this->getTransactionReason('sold-amount'); @@ -518,9 +506,8 @@ public function reserved($quantity = 0, $backOrder = false, $reason = '', $cost return $this->reservedFromCheckout(); } - $this->state = $this::STATE_COMMERCE_RESERVED; - - $this->quantity = $quantity; + $this->setAttribute('quantity', $quantity); + $this->setAttribute('state', $this::STATE_COMMERCE_RESERVED); if (!$reason) { $reason = $this->getTransactionReason('reserved'); @@ -561,9 +548,8 @@ public function backOrder($quantity) $this::STATE_OPENED, ], $this::STATE_COMMERCE_BACK_ORDERED); - $this->state = $this::STATE_COMMERCE_BACK_ORDERED; - - $this->quantity = $quantity; + $this->setAttribute('state', $this::STATE_COMMERCE_BACK_ORDERED); + $this->setAttribute('quantity', $quantity); return $this->processSave('inventory.transaction.back-order'); } @@ -590,14 +576,14 @@ public function fillBackOrder($reason = '', $cost = 0) $this::STATE_COMMERCE_BACK_ORDERED, ], $this::STATE_COMMERCE_BACK_ORDER_FILLED); - $this->state = $this::STATE_COMMERCE_BACK_ORDER_FILLED; + $this->setAttribute('state', $this::STATE_COMMERCE_BACK_ORDER_FILLED); if (!$reason) { $reason = $this->getTransactionReason('back-order-filled'); } try { - return $this->processStockTakeAndSave($this->quantity, 'inventory.transaction.back-order.filled', $reason, $cost); + return $this->processStockTakeAndSave($this->getAttribute('quantity'), 'inventory.transaction.back-order.filled', $reason, $cost); } catch (NotEnoughStockException $e) { } @@ -626,9 +612,8 @@ public function ordered($quantity) $this::STATE_ORDERED_RECEIVED_PARTIAL, ], $this::STATE_ORDERED_PENDING); - $this->quantity = $quantity; - - $this->state = $this::STATE_ORDERED_PENDING; + $this->setAttribute('quantity', $quantity); + $this->setAttribute('state', $this::STATE_ORDERED_PENDING); return $this->processSave('inventory.transaction.ordered'); } @@ -675,11 +660,11 @@ public function receivedAll($reason = '', $cost = 0) $this::STATE_ORDERED_PENDING, ], $this::STATE_ORDERED_RECEIVED); - $received = $this->quantity; + $received = $this->getAttribute('quantity'); - $this->quantity = 0; + $this->setAttribute('quantity', 0); - $this->state = $this::STATE_ORDERED_RECEIVED; + $this->setAttribute('state', $this::STATE_ORDERED_RECEIVED); if (!$reason) { $reason = $this->getTransactionReason('received'); @@ -815,11 +800,11 @@ public function releaseAll($reason = '', $cost = 0) $this::STATE_INVENTORY_ON_HOLD, ], $this::STATE_INVENTORY_RELEASED); - $released = $this->quantity; + $released = $this->getAttribute('quantity'); - $this->quantity = 0; + $this->setAttribute('quantity', 0); - $this->state = $this::STATE_INVENTORY_RELEASED; + $this->setAttribute('state', $this::STATE_INVENTORY_RELEASED); if (!$reason) { $reason = $this->getTransactionReason('released'); @@ -919,9 +904,8 @@ public function removeAll() $this::STATE_INVENTORY_ON_HOLD, ], $this::STATE_INVENTORY_REMOVED); - $this->state = $this::STATE_INVENTORY_REMOVED; - - $this->quantity = 0; + $this->setAttribute('quantity', 0); + $this->setAttribute('state', $this::STATE_INVENTORY_REMOVED); return $this->processSave('inventory.transaction.removed'); } @@ -1152,7 +1136,7 @@ public function setStateAttribute($state) */ private function returnToPreviousState($previousState) { - $this->state = $previousState; + $this->setAttribute('state', $previousState); return $this->processSave(); } From 5fe0904ef65c3e7e7db3f1b207ac83595d414553 Mon Sep 17 00:00:00 2001 From: Steve Bauman Date: Fri, 19 Jun 2015 12:26:47 -0400 Subject: [PATCH 15/51] Remove supplier helpers in favor of traditional laravel relationship methods --- src/Traits/InventoryTrait.php | 177 ---------------------------------- 1 file changed, 177 deletions(-) diff --git a/src/Traits/InventoryTrait.php b/src/Traits/InventoryTrait.php index 9b92f5aa..7ca14d94 100644 --- a/src/Traits/InventoryTrait.php +++ b/src/Traits/InventoryTrait.php @@ -3,7 +3,6 @@ namespace Stevebauman\Inventory\Traits; use Illuminate\Database\Eloquent\Model; -use Stevebauman\Inventory\Exceptions\InvalidSupplierException; use Stevebauman\Inventory\Exceptions\SkuAlreadyExistsException; use Stevebauman\Inventory\Exceptions\StockNotFoundException; use Stevebauman\Inventory\Exceptions\StockAlreadyExistsException; @@ -675,112 +674,6 @@ public function updateSku($code, $sku = null) return $this->processSkuUpdate($sku, $code); } - /** - * Adds all of the specified suppliers inside - * the array to the current inventory item. - * - * @param array $suppliers - * - * @return bool - */ - public function addSuppliers($suppliers = []) - { - foreach ($suppliers as $supplier) { - $this->addSupplier($supplier); - } - - return true; - } - - /** - * Removes all suppliers from the current item. - * - * @return bool - */ - public function removeAllSuppliers() - { - $suppliers = $this->suppliers()->get(); - - foreach ($suppliers as $supplier) { - $this->removeSupplier($supplier); - } - - return true; - } - - /** - * Removes all of the specified suppliers inside - * the array from the current inventory item. - * - * @param array $suppliers - * - * @return bool - */ - public function removeSuppliers($suppliers = []) - { - foreach ($suppliers as $supplier) { - $this->removeSupplier($supplier); - } - - return true; - } - - /** - * Adds the specified supplier to the current inventory item. - * - * @param $supplier - * - * @throws InvalidSupplierException - * - * @return bool - */ - public function addSupplier($supplier) - { - $supplier = $this->getSupplier($supplier); - - return $this->processSupplierAttach($supplier); - } - - /** - * Removes the specified supplier from the current inventory item. - * - * @param $supplier - * - * @throws InvalidSupplierException - * - * @return bool - */ - public function removeSupplier($supplier) - { - $supplier = $this->getSupplier($supplier); - - return $this->processSupplierDetach($supplier); - } - - /** - * Retrieves a supplier from the specified variable. - * - * @param $supplier - * - * @throws InvalidSupplierException - * - * @return mixed - */ - public function getSupplier($supplier) - { - if ($this->isNumeric($supplier)) { - return $this->getSupplierById($supplier); - } elseif ($this->isModel($supplier)) { - return $supplier; - } - - $message = Lang::get('inventory::exceptions.InvalidSupplierException', [ - 'supplier' => $supplier, - ]); - - throw new InvalidSupplierException($message); - } - /** * Processes an SKU generation covered by database transactions. * @@ -842,76 +735,6 @@ private function processSkuUpdate(Model $sku, $code) return false; } - /** - * Processes attaching a supplier to an inventory item. - * - * @param Model $supplier - * - * @return bool - */ - private function processSupplierAttach(Model $supplier) - { - $this->dbStartTransaction(); - - try { - $this->suppliers()->attach($supplier); - - $this->dbCommitTransaction(); - - $this->fireEvent('inventory.supplier.attached', [ - 'item' => $this, - 'supplier' => $supplier, - ]); - - return true; - } catch (\Exception $e) { - $this->dbRollbackTransaction(); - } - - return false; - } - - /** - * Processes detaching a supplier. - * - * @param Model $supplier - * - * @return bool - */ - private function processSupplierDetach(Model $supplier) - { - $this->dbStartTransaction(); - - try { - $this->suppliers()->detach($supplier); - - $this->dbCommitTransaction(); - - $this->fireEvent('inventory.supplier.detached', [ - 'item' => $this, - 'supplier' => $supplier, - ]); - - return true; - } catch (\Exception $e) { - $this->dbRollbackTransaction(); - } - - return false; - } - - /** - * Returns a supplier by the specified ID. - * - * @param int|string $id - * - * @return mixed - */ - private function getSupplierById($id) - { - return $this->suppliers()->find($id); - } - /** * Returns the configuration option for the * enablement of automatic SKU generation. From 27d1a3be4cc2d350da4b7147eb29482cc627132e Mon Sep 17 00:00:00 2001 From: Steve Bauman Date: Fri, 19 Jun 2015 12:31:09 -0400 Subject: [PATCH 16/51] Remove supplier tests - Removed supplier tests as laravel already has tests for hasMany relationships --- tests/InventorySupplierTest.php | 96 --------------------------------- 1 file changed, 96 deletions(-) delete mode 100644 tests/InventorySupplierTest.php diff --git a/tests/InventorySupplierTest.php b/tests/InventorySupplierTest.php deleted file mode 100644 index be52538f..00000000 --- a/tests/InventorySupplierTest.php +++ /dev/null @@ -1,96 +0,0 @@ - 'Supplier', - 'address' => '123 Fake St', - 'postal_code' => '12345', - 'zip_code' => '12345', - 'region' => 'ON', - 'city' => 'Toronto', - 'country' => 'Canada', - 'contact_title' => 'Manager', - 'contact_name' => 'John Doe', - 'contact_phone' => '555 555 5555', - 'contact_fax' => '555 555 5555', - 'contact_email' => 'john.doe@email.com', - ]); - } - - public function testInventorySupplierAttach() - { - $item = $this->newInventory(); - - $newSupplier = $this->newSupplier(); - - $item->addSupplier($newSupplier); - - $supplier = $item->suppliers()->first(); - - $this->assertEquals('Supplier', $supplier->name); - } - - public function testInventorySupplierDetach() - { - $this->testInventorySupplierAttach(); - - $item = Inventory::find(1); - - $this->assertTrue($item->removeSupplier(1)); - } - - public function testInventorySupplierDetachAll() - { - $this->testInventorySupplierAttach(); - - $this->testInventorySupplierAttach(); - - $item = Inventory::find(1); - - $item->removeAllSuppliers(); - - $this->assertEquals(0, $item->suppliers()->count()); - } - - public function testSupplierAttachItem() - { - $item = $this->newInventory(); - - $supplier = $this->newSupplier(); - - $item->addSupplier($supplier); - - $this->assertEquals($supplier->name, $item->suppliers()->first()->name); - } - - public function testSupplierDetachItem() - { - $this->testSupplierAttachItem(); - - $item = Inventory::find(1); - - $item->removeSupplier(1); - - $this->assertEquals(0, $item->suppliers()->count()); - } - - public function testSupplierInvalidSupplierException() - { - $this->testSupplierAttachItem(); - - $item = Inventory::find(1); - - $this->setExpectedException('Stevebauman\Inventory\Exceptions\InvalidSupplierException'); - - $item->addSupplier('testing'); - $item->removeSupplier('testing'); - } -} From c2db72df1beae3d06ca6b20594bf7a340f88ddcc Mon Sep 17 00:00:00 2001 From: Steve Bauman Date: Fri, 19 Jun 2015 12:33:11 -0400 Subject: [PATCH 17/51] Removed unnecessary where call --- src/Traits/InventoryTrait.php | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/Traits/InventoryTrait.php b/src/Traits/InventoryTrait.php index 7ca14d94..c611898a 100644 --- a/src/Traits/InventoryTrait.php +++ b/src/Traits/InventoryTrait.php @@ -461,10 +461,7 @@ public function moveStock(Model $fromLocation, Model $toLocation) */ public function getStockFromLocation(Model $location) { - $stock = $this->stocks() - ->where('inventory_id', $this->getKey()) - ->where('location_id', $location->getKey()) - ->first(); + $stock = $this->stocks()->where('location_id', $location->getKey())->first(); if ($stock) { return $stock; From 91e3a67f3722d368285e3f8f32bbf10577896752 Mon Sep 17 00:00:00 2001 From: Steve Bauman Date: Fri, 19 Jun 2015 12:33:41 -0400 Subject: [PATCH 18/51] Removed supplier helper methods - Removed unnecessary supplier helper methods - Removed unused exceptions --- src/Exceptions/InvalidItemException.php | 7 - src/Exceptions/InvalidSupplierException.php | 7 - src/Traits/SupplierTrait.php | 180 -------------------- 3 files changed, 194 deletions(-) delete mode 100644 src/Exceptions/InvalidItemException.php delete mode 100644 src/Exceptions/InvalidSupplierException.php diff --git a/src/Exceptions/InvalidItemException.php b/src/Exceptions/InvalidItemException.php deleted file mode 100644 index 1a30f871..00000000 --- a/src/Exceptions/InvalidItemException.php +++ /dev/null @@ -1,7 +0,0 @@ -addItem($item); - } - - return true; - } - - /** - * Adds the specified item to the current supplier. - * - * @param mixed $item - * - * @throws InvalidItemException - * - * @return bool - */ - public function addItem($item) - { - $this->getItem($item); - - return $this->processItemAttach($item); - } - - /** - * Removes all items from the current supplier. - * - * @return bool - */ - public function removeAllItems() - { - $items = $this->items()->get(); - - foreach ($items as $item) { - $this->removeItem($item); - } - - return true; - } - - /** - * Removes all the specified items from the current supplier. - * - * @param array $items - * - * @return bool - */ - public function removeItems($items = []) - { - foreach ($items as $item) { - $this->removeItem($item); - } - - return true; - } - - /** - * Removes the specified item from the current supplier. - * - * @param mixed $item - * - * @throws InvalidItemException - * - * @return bool - */ - public function removeItem($item) - { - $item = $this->getItem($item); - - return $this->processItemDetach($item); - } - - /** - * Processes attaching the specified item to the current supplier. - * - * @param mixed $item - * - * @return bool - */ - private function processItemAttach($item) - { - $this->dbStartTransaction(); - - try { - $this->items()->attach($item); - - $this->dbCommitTransaction(); - - $this->fireEvent('inventory.supplier.attached', [ - 'item' => $item, - 'supplier' => $this, - ]); - - return true; - } catch (\Exception $e) { - $this->dbRollbackTransaction(); - } - - return false; - } - - /** - * Processes detaching the specified item from the current supplier. - * - * @param mixed $item - * - * @return bool - */ - private function processItemDetach($item) - { - $this->dbStartTransaction(); - - try { - $this->items()->detach($item); - - $this->dbCommitTransaction(); - - $this->fireEvent('inventory.supplier.detached', [ - 'item' => $item, - 'supplier' => $this, - ]); - - return true; - } catch (\Exception $e) { - $this->dbRollbackTransaction(); - } - - return false; - } - - /** - * Retrieves the specified item. - * - * @param mixed $item - * - * @throws InvalidItemException - * - * @return mixed - */ - public function getItem($item) - { - if ($this->isNumeric($item)) { - return $this->getItemById($item); - } elseif ($this->isModel($item)) { - return $item; - } else { - $message = Lang::get('inventory.exceptions.InvalidItemException', [ - 'item' => $item, - ]); - - throw new InvalidItemException($message); - } - } - - /** - * Retrieves an item by the specified ID. - * - * @param int|string $id - * - * @return mixed - */ - private function getItemById($id) - { - return $this->items()->find($id); - } } From 2f49f33aa081e2fa2769bcb65b97914e01009600 Mon Sep 17 00:00:00 2001 From: Steve Bauman Date: Fri, 19 Jun 2015 12:38:49 -0400 Subject: [PATCH 19/51] Remove global exception catching in helper --- src/Helper.php | 25 ++++++++----------------- 1 file changed, 8 insertions(+), 17 deletions(-) diff --git a/src/Helper.php b/src/Helper.php index a888145f..f178e723 100644 --- a/src/Helper.php +++ b/src/Helper.php @@ -54,30 +54,21 @@ public static function getCurrentUserId() { $separator = InventoryServiceProvider::$packageConfigSeparator; - /* - * Check if we're allowed to return no user ID to the model, if so we'll return null. - */ + // Check if we're allowed to return no user ID to the model, if so we'll return null. if (Config::get('inventory'.$separator.'allow_no_user')) { return; } - /* - * Accountability is enabled, let's try and retrieve the current users ID - */ - try { - if (class_exists($class = '\Cartalyst\Sentry\Facades\Laravel\Sentry') || class_exists($class = '\Cartalyst\Sentinel\Laravel\Facades\Sentinel')) { - if ($class::check()) { - return $class::getUser()->id; - } - } elseif (Auth::check()) { - return Auth::user()->getAuthIdentifier(); + // Accountability is enabled, let's try and retrieve the current users ID. + if (class_exists($class = '\Cartalyst\Sentry\Facades\Laravel\Sentry') || class_exists($class = '\Cartalyst\Sentinel\Laravel\Facades\Sentinel')) { + if ($class::check()) { + return $class::getUser()->id; } - } catch (\Exception $e) { + } else if (Auth::check()) { + return Auth::user()->getAuthIdentifier(); } - /* - * Couldn't get the current logged in users ID, throw exception - */ + // Couldn't get the current logged in users ID, throw exception $message = Lang::get('inventory::exceptions.NoUserLoggedInException'); throw new NoUserLoggedInException($message); From 7af4f7a3e8b00fc5468195d80e976f3f1f8a825b Mon Sep 17 00:00:00 2001 From: Steve Bauman Date: Fri, 19 Jun 2015 12:39:43 -0400 Subject: [PATCH 20/51] Set is_assembly in setter --- src/Traits/AssemblyTrait.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Traits/AssemblyTrait.php b/src/Traits/AssemblyTrait.php index 59f39d5d..734f6568 100644 --- a/src/Traits/AssemblyTrait.php +++ b/src/Traits/AssemblyTrait.php @@ -40,7 +40,7 @@ public function assembliesRecursive() */ public function makeAssembly() { - $this->is_assembly = true; + $this->setAttribute('is_assembly', true); return $this->save(); } From c9406f9a2477572f3ede600b99dfa2d69ffeb0f8 Mon Sep 17 00:00:00 2001 From: Steve Bauman Date: Fri, 19 Jun 2015 16:20:42 -0400 Subject: [PATCH 21/51] Remove unused use statement --- src/Traits/SupplierTrait.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/Traits/SupplierTrait.php b/src/Traits/SupplierTrait.php index 63f8380b..1c7ee0f6 100644 --- a/src/Traits/SupplierTrait.php +++ b/src/Traits/SupplierTrait.php @@ -2,8 +2,6 @@ namespace Stevebauman\Inventory\Traits; -use Illuminate\Support\Facades\Lang; - trait SupplierTrait { /** From 76ae0d63301c87b1ab61af7a07a1f2b51400c3e1 Mon Sep 17 00:00:00 2001 From: Steve Bauman Date: Mon, 29 Jun 2015 09:41:04 -0400 Subject: [PATCH 22/51] Update for MSSQL --- docs/INSTALLATION.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/INSTALLATION.md b/docs/INSTALLATION.md index 37f4d322..e73d71a6 100644 --- a/docs/INSTALLATION.md +++ b/docs/INSTALLATION.md @@ -1,5 +1,8 @@ ## Installation +> **Note**: If you're looking to use Inventory with MSSQL, you will need to modify the published migrations to suit. By default, +multiple cascade delete paths are present, and you'll need to modify and / or remove these for compatibility. + ### Installation (Laravel 4) Add inventory to your `composer.json` file: From d95fd79e6b466756b6288e2f5768c1ba02f5848c Mon Sep 17 00:00:00 2001 From: Steve Bauman Date: Mon, 29 Jun 2015 09:41:25 -0400 Subject: [PATCH 23/51] Small clarification --- docs/INSTALLATION.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/INSTALLATION.md b/docs/INSTALLATION.md index e73d71a6..ffd2c042 100644 --- a/docs/INSTALLATION.md +++ b/docs/INSTALLATION.md @@ -1,7 +1,7 @@ ## Installation > **Note**: If you're looking to use Inventory with MSSQL, you will need to modify the published migrations to suit. By default, -multiple cascade delete paths are present, and you'll need to modify and / or remove these for compatibility. +multiple cascade delete paths are present on foreign keys, and you'll need to modify and / or remove these for compatibility. ### Installation (Laravel 4) From 54eb7fc8983f3619d317f10e4a7bccc119e9c0c3 Mon Sep 17 00:00:00 2001 From: Steve Bauman Date: Mon, 29 Jun 2015 09:52:50 -0400 Subject: [PATCH 24/51] Use empty --- src/Traits/InventoryTransactionTrait.php | 32 +++++++++++++----------- 1 file changed, 17 insertions(+), 15 deletions(-) diff --git a/src/Traits/InventoryTransactionTrait.php b/src/Traits/InventoryTransactionTrait.php index 845e24e4..a0cd6cfb 100644 --- a/src/Traits/InventoryTransactionTrait.php +++ b/src/Traits/InventoryTransactionTrait.php @@ -262,7 +262,7 @@ public function checkout($quantity = 0, $reason = '', $cost = 0) $this->setAttribute('quantity', $quantity); $this->setAttribute('state', $this::STATE_COMMERCE_CHECKOUT); - if (!$reason) { + if (empty($reason)) { $reason = $this->getTransactionReason('checkout'); } @@ -339,7 +339,7 @@ public function soldAmount($quantity, $reason = '', $cost = 0) $this->setAttribute('state', $this::STATE_COMMERCE_SOLD); $this->setAttribute('quantity', $quantity); - if (!$reason) { + if (empty($reason)) { $reason = $this->getTransactionReason('sold-amount'); } @@ -420,7 +420,7 @@ public function returnedPartial($quantity, $reason = '', $cost = 0) $this->setAttribute('quantity', $left); - if (!$reason) { + if (empty($reason)) { $reason = $this->getTransactionReason('returned-partial'); } @@ -466,7 +466,7 @@ public function returnedAll($reason = '', $cost = 0) */ $this->setAttribute('quantity', 0); - if (!$reason) { + if (empty($reason)) { $reason = $this->getTransactionReason('returned'); } @@ -509,7 +509,7 @@ public function reserved($quantity = 0, $backOrder = false, $reason = '', $cost $this->setAttribute('quantity', $quantity); $this->setAttribute('state', $this::STATE_COMMERCE_RESERVED); - if (!$reason) { + if (empty($reason)) { $reason = $this->getTransactionReason('reserved'); } @@ -578,7 +578,7 @@ public function fillBackOrder($reason = '', $cost = 0) $this->setAttribute('state', $this::STATE_COMMERCE_BACK_ORDER_FILLED); - if (!$reason) { + if (empty($reason)) { $reason = $this->getTransactionReason('back-order-filled'); } @@ -666,7 +666,7 @@ public function receivedAll($reason = '', $cost = 0) $this->setAttribute('state', $this::STATE_ORDERED_RECEIVED); - if (!$reason) { + if (empty($reason)) { $reason = $this->getTransactionReason('received'); } @@ -714,7 +714,7 @@ public function receivedPartial($quantity, $reason = '', $cost = 0) $this->setAttribute('state', $this::STATE_ORDERED_RECEIVED_PARTIAL); - if (!$reason) { + if (empty($reason)) { $reason = $this->getTransactionReason('received-partial'); } @@ -749,7 +749,7 @@ public function hold($quantity, $reason = '', $cost = 0) $this->setAttribute('state', $this::STATE_INVENTORY_ON_HOLD); - if (!$reason) { + if (empty($reason)) { $reason = $this->getTransactionReason('hold'); } @@ -806,7 +806,7 @@ public function releaseAll($reason = '', $cost = 0) $this->setAttribute('state', $this::STATE_INVENTORY_RELEASED); - if (!$reason) { + if (empty($reason)) { $reason = $this->getTransactionReason('released'); } @@ -847,7 +847,7 @@ public function releasePartial($quantity, $reason = '', $cost = 0) $this->setAttribute('state', $this::STATE_INVENTORY_RELEASED_PARTIAL); - if (!$reason) { + if (empty($reason)) { $reason = $this->getTransactionReason('released-partial'); } @@ -970,7 +970,7 @@ public function removePartial($quantity, $reason = '', $cost = 0) $this->setAttribute('quantity', (float) $quantity); - if (!$reason) { + if (empty($reason)) { $reason = $this->getTransactionReason('removed'); } @@ -1016,7 +1016,7 @@ public function cancel($reason = '', $cost = 0) $event = 'inventory.transaction.cancelled'; - if (!$reason) { + if (empty($reason)) { $reason = $this->getTransactionReason('cancelled'); } @@ -1103,7 +1103,9 @@ public function getLastHistoryRecord() public function setQuantityAttribute($quantity) { if (!$this->isPositive($quantity)) { - $message = Lang::get('inventory'.InventoryServiceProvider::$packageConfigSeparator.'exceptions.InvalidQuantityException'); + $path = 'inventory'.InventoryServiceProvider::$packageConfigSeparator.'exceptions.InvalidQuantityException'; + + $message = Lang::get($path); throw new InvalidQuantityException($message); } @@ -1364,7 +1366,7 @@ private function getTransactionReason($key) * Make sure we set the reason to null if no translation is found * so the default stock change reason is used */ - if (!$reason) { + if (empty($reason)) { $reason = null; } From f13b247811a33c2cd39b15442c270f80e7267164 Mon Sep 17 00:00:00 2001 From: Steve Bauman Date: Mon, 29 Jun 2015 09:55:00 -0400 Subject: [PATCH 25/51] Small comment tweak --- src/Traits/InventoryTransactionTrait.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Traits/InventoryTransactionTrait.php b/src/Traits/InventoryTransactionTrait.php index a0cd6cfb..5acb6711 100644 --- a/src/Traits/InventoryTransactionTrait.php +++ b/src/Traits/InventoryTransactionTrait.php @@ -246,8 +246,8 @@ public function isRemoved() public function checkout($quantity = 0, $reason = '', $cost = 0) { /* - * Only allow a transaction that has a previous state of null, opened and reserved - * to use the checkout function + * Only allow a transaction that has a previous state of + * null, opened and reserved to use the checkout function */ $this->validatePreviousState([ null, From 4933142f1c8aa8bc629a5b0266ba1effa164820f Mon Sep 17 00:00:00 2001 From: Steve Bauman Date: Tue, 30 Jun 2015 16:00:34 -0400 Subject: [PATCH 26/51] Comment changes --- src/Traits/InventoryTrait.php | 36 +++++++++++------------------------ 1 file changed, 11 insertions(+), 25 deletions(-) diff --git a/src/Traits/InventoryTrait.php b/src/Traits/InventoryTrait.php index c611898a..23b00adc 100644 --- a/src/Traits/InventoryTrait.php +++ b/src/Traits/InventoryTrait.php @@ -509,40 +509,30 @@ public function getSkuCodeAttribute() */ public function generateSku() { - /* - * Make sure sku generation is enabled and the item has a category, if not we'll return false. - */ + // Make sure sku generation is enabled and the item has a category, if not we'll return false. if (!$this->skusEnabled() || !$this->hasCategory()) { return false; } - /* - * If the item already has an SKU, we'll return it - */ + // If the item already has an SKU, we'll return it if ($this->hasSku()) { return $this->sku; } $separator = InventoryServiceProvider::$packageConfigSeparator; - /* - * Get the set SKU code length from the configuration file - */ + // Get the set SKU code length from the configuration file $codeLength = Config::get('inventory'.$separator.'sku_code_length'); - /* - * Get the set SKU prefix length from the configuration file - */ + // Get the set SKU prefix length from the configuration file $prefixLength = Config::get('inventory'.$separator.'sku_prefix_length'); - /* - * Get the set SKU separator - */ + // Get the set SKU separator $skuSeparator = Config::get('inventory'.$separator.'sku_separator'); /* - * Make sure we trim empty spaces in the separator if it's a string, otherwise we'll - * set it to NULL + * Make sure we trim empty spaces in the separator + * if it's a string, otherwise we'll set it to NULL */ $skuSeparator = (is_string($skuSeparator) ? trim($skuSeparator) : null); @@ -553,8 +543,8 @@ public function generateSku() $prefix = strtoupper(substr(trim($this->category->getAttribute('name')), 0, intval($prefixLength))); /* - * We'll make sure the prefix length is greater than zero before we try and - * generate an SKU + * We'll make sure the prefix length is greater + * than zero before we try and generate an SKU */ if (strlen($prefix) > 0) { /* @@ -563,15 +553,11 @@ public function generateSku() */ $code = str_pad($this->getKey(), $codeLength, '0', STR_PAD_LEFT); - /* - * Process the generation - */ + // Return and process the generation return $this->processSkuGeneration($this->getKey(), $prefix.$skuSeparator.$code); } - /* - * Always return false on generation failure - */ + // Always return false on generation failure return false; } From 6a070778a86750e68782948cc3479254019292f5 Mon Sep 17 00:00:00 2001 From: Steve Bauman Date: Fri, 3 Jul 2015 20:28:28 -0400 Subject: [PATCH 27/51] Remove inventory banner --- README.md | 3 +-- inventory-banner.jpg | Bin 38126 -> 0 bytes 2 files changed, 1 insertion(+), 2 deletions(-) delete mode 100644 inventory-banner.jpg diff --git a/README.md b/README.md index 1778bf74..65629ba2 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,4 @@ -![Inventory Banner] -(https://github.com/stevebauman/inventory/blob/master/inventory-banner.jpg) +# Inventory [![Travis CI](https://img.shields.io/travis/stevebauman/inventory.svg?style=flat-square)](https://travis-ci.org/stevebauman/inventory) [![Scrutinizer Code Quality](https://img.shields.io/scrutinizer/g/stevebauman/inventory.svg?style=flat-square)](https://scrutinizer-ci.com/g/stevebauman/inventory/?branch=master) diff --git a/inventory-banner.jpg b/inventory-banner.jpg deleted file mode 100644 index 027e09ff5e0a518f9ebe1105643d96a39035d5b9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 38126 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 RR|Niw!2e$&aPD*e{{q%_s&D`R From 3af51397fff887de51f6eb82cf0a7abba892767d Mon Sep 17 00:00:00 2001 From: Steve Bauman Date: Fri, 3 Jul 2015 20:28:33 -0400 Subject: [PATCH 28/51] Rearrange use --- src/Traits/InventoryTrait.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Traits/InventoryTrait.php b/src/Traits/InventoryTrait.php index 23b00adc..3f520848 100644 --- a/src/Traits/InventoryTrait.php +++ b/src/Traits/InventoryTrait.php @@ -2,12 +2,12 @@ namespace Stevebauman\Inventory\Traits; -use Illuminate\Database\Eloquent\Model; use Stevebauman\Inventory\Exceptions\SkuAlreadyExistsException; use Stevebauman\Inventory\Exceptions\StockNotFoundException; use Stevebauman\Inventory\Exceptions\StockAlreadyExistsException; use Stevebauman\Inventory\InventoryServiceProvider; use Stevebauman\Inventory\Helper; +use Illuminate\Database\Eloquent\Model; use Illuminate\Support\Facades\Config; use Illuminate\Support\Facades\Lang; From 92448eefb7a6bea425b7e358b2a0a1589993020e Mon Sep 17 00:00:00 2001 From: Steve Bauman Date: Fri, 3 Jul 2015 20:29:37 -0400 Subject: [PATCH 29/51] Clarify requirements --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 65629ba2..526754c0 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# Inventory +# Inventory | For Laravel 4 - 5 [![Travis CI](https://img.shields.io/travis/stevebauman/inventory.svg?style=flat-square)](https://travis-ci.org/stevebauman/inventory) [![Scrutinizer Code Quality](https://img.shields.io/scrutinizer/g/stevebauman/inventory.svg?style=flat-square)](https://scrutinizer-ci.com/g/stevebauman/inventory/?branch=master) From 44116377d9e7db7a61788410479089df2e005d3c Mon Sep 17 00:00:00 2001 From: Steve Bauman Date: Fri, 3 Jul 2015 20:30:22 -0400 Subject: [PATCH 30/51] Remove clarification --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 526754c0..65629ba2 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# Inventory | For Laravel 4 - 5 +# Inventory [![Travis CI](https://img.shields.io/travis/stevebauman/inventory.svg?style=flat-square)](https://travis-ci.org/stevebauman/inventory) [![Scrutinizer Code Quality](https://img.shields.io/scrutinizer/g/stevebauman/inventory.svg?style=flat-square)](https://scrutinizer-ci.com/g/stevebauman/inventory/?branch=master) From 55be64f85b2791ba3d1b6acd9c09878e3d5aa39f Mon Sep 17 00:00:00 2001 From: asaf050 Date: Mon, 13 Jul 2015 22:34:34 +0300 Subject: [PATCH 31/51] Update INSTALLATION.md Add Assembly relationship to the Inventory model. --- docs/INSTALLATION.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/docs/INSTALLATION.md b/docs/INSTALLATION.md index ffd2c042..11bc5771 100644 --- a/docs/INSTALLATION.md +++ b/docs/INSTALLATION.md @@ -152,6 +152,7 @@ Inventory: use Stevebauman\Inventory\Traits\InventoryTrait; use Stevebauman\Inventory\Traits\InventoryVariantTrait; + use AssemblyTrait; class Inventory extends Model { @@ -184,6 +185,10 @@ Inventory: { return $this->belongsToMany('Supplier', 'inventory_suppliers', 'inventory_id')->withTimestamps(); } + + public function assemblies() { + return $this->belongsToMany( $this , 'inventory_assemblies' , 'inventory_id' , 'part_id') ->withPivot(['quantity'])->withTimestamps(); + } } InventorySku: From 16a632d095cb633c762fa649b098fca1b61c26a5 Mon Sep 17 00:00:00 2001 From: Steve Bauman Date: Mon, 13 Jul 2015 15:40:04 -0400 Subject: [PATCH 32/51] Small pull tweaks --- docs/INSTALLATION.md | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/docs/INSTALLATION.md b/docs/INSTALLATION.md index 11bc5771..3f608059 100644 --- a/docs/INSTALLATION.md +++ b/docs/INSTALLATION.md @@ -152,7 +152,7 @@ Inventory: use Stevebauman\Inventory\Traits\InventoryTrait; use Stevebauman\Inventory\Traits\InventoryVariantTrait; - use AssemblyTrait; + use Stevebauman\Inventory\Traits\AssemblyTrait; class Inventory extends Model { @@ -186,8 +186,10 @@ Inventory: return $this->belongsToMany('Supplier', 'inventory_suppliers', 'inventory_id')->withTimestamps(); } - public function assemblies() { - return $this->belongsToMany( $this , 'inventory_assemblies' , 'inventory_id' , 'part_id') ->withPivot(['quantity'])->withTimestamps(); + public function assemblies() + { + return $this->belongsToMany($this, 'inventory_assemblies', 'inventory_id', 'part_id') + ->withPivot(['quantity'])->withTimestamps(); } } From e13aee61c0a0d2a04dd45eb67834c4a79731435a Mon Sep 17 00:00:00 2001 From: Steve Bauman Date: Mon, 13 Jul 2015 15:40:45 -0400 Subject: [PATCH 33/51] Small doc fix --- docs/INSTALLATION.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/INSTALLATION.md b/docs/INSTALLATION.md index 3f608059..a41eabd6 100644 --- a/docs/INSTALLATION.md +++ b/docs/INSTALLATION.md @@ -150,14 +150,15 @@ Supplier: Inventory: + use Stevebauman\Inventory\Traits\AssemblyTrait; use Stevebauman\Inventory\Traits\InventoryTrait; use Stevebauman\Inventory\Traits\InventoryVariantTrait; - use Stevebauman\Inventory\Traits\AssemblyTrait; class Inventory extends Model { use InventoryTrait; use InventoryVariantTrait; + use AssemblyTrait; protected $table = 'inventory'; From 2621aed8bfd2fdb73b50c83ce6d6b3e40351e839 Mon Sep 17 00:00:00 2001 From: Steve Bauman Date: Tue, 4 Aug 2015 10:55:32 -0400 Subject: [PATCH 34/51] Recase folder --- src/{migrations => migrations2}/.gitkeep | 0 .../2014_07_31_123201_create_metrics_table.php | 0 .../2014_07_31_123204_create_categories_table.php | 0 .../2014_07_31_123204_create_locations_table.php | 0 .../2014_07_31_123213_create_inventory_tables.php | 0 .../2015_03_02_143457_create_inventory_sku_table.php | 0 .../2015_03_06_135351_create_inventory_supplier_tables.php | 0 .../2015_03_09_122729_create_inventory_transaction_tables.php | 0 .../2015_05_05_100032_create_inventory_variants_table.php | 0 .../2015_05_08_115310_modify_inventory_table_for_assemblies.php | 0 .../2015_05_08_115523_create_inventory_assemblies_table.php | 0 11 files changed, 0 insertions(+), 0 deletions(-) rename src/{migrations => migrations2}/.gitkeep (100%) rename src/{migrations => migrations2}/2014_07_31_123201_create_metrics_table.php (100%) rename src/{migrations => migrations2}/2014_07_31_123204_create_categories_table.php (100%) rename src/{migrations => migrations2}/2014_07_31_123204_create_locations_table.php (100%) rename src/{migrations => migrations2}/2014_07_31_123213_create_inventory_tables.php (100%) rename src/{migrations => migrations2}/2015_03_02_143457_create_inventory_sku_table.php (100%) rename src/{migrations => migrations2}/2015_03_06_135351_create_inventory_supplier_tables.php (100%) rename src/{migrations => migrations2}/2015_03_09_122729_create_inventory_transaction_tables.php (100%) rename src/{migrations => migrations2}/2015_05_05_100032_create_inventory_variants_table.php (100%) rename src/{migrations => migrations2}/2015_05_08_115310_modify_inventory_table_for_assemblies.php (100%) rename src/{migrations => migrations2}/2015_05_08_115523_create_inventory_assemblies_table.php (100%) diff --git a/src/migrations/.gitkeep b/src/migrations2/.gitkeep similarity index 100% rename from src/migrations/.gitkeep rename to src/migrations2/.gitkeep diff --git a/src/migrations/2014_07_31_123201_create_metrics_table.php b/src/migrations2/2014_07_31_123201_create_metrics_table.php similarity index 100% rename from src/migrations/2014_07_31_123201_create_metrics_table.php rename to src/migrations2/2014_07_31_123201_create_metrics_table.php diff --git a/src/migrations/2014_07_31_123204_create_categories_table.php b/src/migrations2/2014_07_31_123204_create_categories_table.php similarity index 100% rename from src/migrations/2014_07_31_123204_create_categories_table.php rename to src/migrations2/2014_07_31_123204_create_categories_table.php diff --git a/src/migrations/2014_07_31_123204_create_locations_table.php b/src/migrations2/2014_07_31_123204_create_locations_table.php similarity index 100% rename from src/migrations/2014_07_31_123204_create_locations_table.php rename to src/migrations2/2014_07_31_123204_create_locations_table.php diff --git a/src/migrations/2014_07_31_123213_create_inventory_tables.php b/src/migrations2/2014_07_31_123213_create_inventory_tables.php similarity index 100% rename from src/migrations/2014_07_31_123213_create_inventory_tables.php rename to src/migrations2/2014_07_31_123213_create_inventory_tables.php diff --git a/src/migrations/2015_03_02_143457_create_inventory_sku_table.php b/src/migrations2/2015_03_02_143457_create_inventory_sku_table.php similarity index 100% rename from src/migrations/2015_03_02_143457_create_inventory_sku_table.php rename to src/migrations2/2015_03_02_143457_create_inventory_sku_table.php diff --git a/src/migrations/2015_03_06_135351_create_inventory_supplier_tables.php b/src/migrations2/2015_03_06_135351_create_inventory_supplier_tables.php similarity index 100% rename from src/migrations/2015_03_06_135351_create_inventory_supplier_tables.php rename to src/migrations2/2015_03_06_135351_create_inventory_supplier_tables.php diff --git a/src/migrations/2015_03_09_122729_create_inventory_transaction_tables.php b/src/migrations2/2015_03_09_122729_create_inventory_transaction_tables.php similarity index 100% rename from src/migrations/2015_03_09_122729_create_inventory_transaction_tables.php rename to src/migrations2/2015_03_09_122729_create_inventory_transaction_tables.php diff --git a/src/migrations/2015_05_05_100032_create_inventory_variants_table.php b/src/migrations2/2015_05_05_100032_create_inventory_variants_table.php similarity index 100% rename from src/migrations/2015_05_05_100032_create_inventory_variants_table.php rename to src/migrations2/2015_05_05_100032_create_inventory_variants_table.php diff --git a/src/migrations/2015_05_08_115310_modify_inventory_table_for_assemblies.php b/src/migrations2/2015_05_08_115310_modify_inventory_table_for_assemblies.php similarity index 100% rename from src/migrations/2015_05_08_115310_modify_inventory_table_for_assemblies.php rename to src/migrations2/2015_05_08_115310_modify_inventory_table_for_assemblies.php diff --git a/src/migrations/2015_05_08_115523_create_inventory_assemblies_table.php b/src/migrations2/2015_05_08_115523_create_inventory_assemblies_table.php similarity index 100% rename from src/migrations/2015_05_08_115523_create_inventory_assemblies_table.php rename to src/migrations2/2015_05_08_115523_create_inventory_assemblies_table.php From b39bf555ae999230613311fa92c55810ab56ce84 Mon Sep 17 00:00:00 2001 From: Steve Bauman Date: Tue, 4 Aug 2015 10:56:09 -0400 Subject: [PATCH 35/51] Recased folder name --- src/{migrations2 => Migrations}/.gitkeep | 0 .../2014_07_31_123201_create_metrics_table.php | 0 .../2014_07_31_123204_create_categories_table.php | 0 .../2014_07_31_123204_create_locations_table.php | 0 .../2014_07_31_123213_create_inventory_tables.php | 0 .../2015_03_02_143457_create_inventory_sku_table.php | 0 .../2015_03_06_135351_create_inventory_supplier_tables.php | 0 .../2015_03_09_122729_create_inventory_transaction_tables.php | 0 .../2015_05_05_100032_create_inventory_variants_table.php | 0 .../2015_05_08_115310_modify_inventory_table_for_assemblies.php | 0 .../2015_05_08_115523_create_inventory_assemblies_table.php | 0 11 files changed, 0 insertions(+), 0 deletions(-) rename src/{migrations2 => Migrations}/.gitkeep (100%) rename src/{migrations2 => Migrations}/2014_07_31_123201_create_metrics_table.php (100%) rename src/{migrations2 => Migrations}/2014_07_31_123204_create_categories_table.php (100%) rename src/{migrations2 => Migrations}/2014_07_31_123204_create_locations_table.php (100%) rename src/{migrations2 => Migrations}/2014_07_31_123213_create_inventory_tables.php (100%) rename src/{migrations2 => Migrations}/2015_03_02_143457_create_inventory_sku_table.php (100%) rename src/{migrations2 => Migrations}/2015_03_06_135351_create_inventory_supplier_tables.php (100%) rename src/{migrations2 => Migrations}/2015_03_09_122729_create_inventory_transaction_tables.php (100%) rename src/{migrations2 => Migrations}/2015_05_05_100032_create_inventory_variants_table.php (100%) rename src/{migrations2 => Migrations}/2015_05_08_115310_modify_inventory_table_for_assemblies.php (100%) rename src/{migrations2 => Migrations}/2015_05_08_115523_create_inventory_assemblies_table.php (100%) diff --git a/src/migrations2/.gitkeep b/src/Migrations/.gitkeep similarity index 100% rename from src/migrations2/.gitkeep rename to src/Migrations/.gitkeep diff --git a/src/migrations2/2014_07_31_123201_create_metrics_table.php b/src/Migrations/2014_07_31_123201_create_metrics_table.php similarity index 100% rename from src/migrations2/2014_07_31_123201_create_metrics_table.php rename to src/Migrations/2014_07_31_123201_create_metrics_table.php diff --git a/src/migrations2/2014_07_31_123204_create_categories_table.php b/src/Migrations/2014_07_31_123204_create_categories_table.php similarity index 100% rename from src/migrations2/2014_07_31_123204_create_categories_table.php rename to src/Migrations/2014_07_31_123204_create_categories_table.php diff --git a/src/migrations2/2014_07_31_123204_create_locations_table.php b/src/Migrations/2014_07_31_123204_create_locations_table.php similarity index 100% rename from src/migrations2/2014_07_31_123204_create_locations_table.php rename to src/Migrations/2014_07_31_123204_create_locations_table.php diff --git a/src/migrations2/2014_07_31_123213_create_inventory_tables.php b/src/Migrations/2014_07_31_123213_create_inventory_tables.php similarity index 100% rename from src/migrations2/2014_07_31_123213_create_inventory_tables.php rename to src/Migrations/2014_07_31_123213_create_inventory_tables.php diff --git a/src/migrations2/2015_03_02_143457_create_inventory_sku_table.php b/src/Migrations/2015_03_02_143457_create_inventory_sku_table.php similarity index 100% rename from src/migrations2/2015_03_02_143457_create_inventory_sku_table.php rename to src/Migrations/2015_03_02_143457_create_inventory_sku_table.php diff --git a/src/migrations2/2015_03_06_135351_create_inventory_supplier_tables.php b/src/Migrations/2015_03_06_135351_create_inventory_supplier_tables.php similarity index 100% rename from src/migrations2/2015_03_06_135351_create_inventory_supplier_tables.php rename to src/Migrations/2015_03_06_135351_create_inventory_supplier_tables.php diff --git a/src/migrations2/2015_03_09_122729_create_inventory_transaction_tables.php b/src/Migrations/2015_03_09_122729_create_inventory_transaction_tables.php similarity index 100% rename from src/migrations2/2015_03_09_122729_create_inventory_transaction_tables.php rename to src/Migrations/2015_03_09_122729_create_inventory_transaction_tables.php diff --git a/src/migrations2/2015_05_05_100032_create_inventory_variants_table.php b/src/Migrations/2015_05_05_100032_create_inventory_variants_table.php similarity index 100% rename from src/migrations2/2015_05_05_100032_create_inventory_variants_table.php rename to src/Migrations/2015_05_05_100032_create_inventory_variants_table.php diff --git a/src/migrations2/2015_05_08_115310_modify_inventory_table_for_assemblies.php b/src/Migrations/2015_05_08_115310_modify_inventory_table_for_assemblies.php similarity index 100% rename from src/migrations2/2015_05_08_115310_modify_inventory_table_for_assemblies.php rename to src/Migrations/2015_05_08_115310_modify_inventory_table_for_assemblies.php diff --git a/src/migrations2/2015_05_08_115523_create_inventory_assemblies_table.php b/src/Migrations/2015_05_08_115523_create_inventory_assemblies_table.php similarity index 100% rename from src/migrations2/2015_05_08_115523_create_inventory_assemblies_table.php rename to src/Migrations/2015_05_08_115523_create_inventory_assemblies_table.php From bbe2a1b7850aa4d73e944d8923902a0897183a43 Mon Sep 17 00:00:00 2001 From: Steve Bauman Date: Tue, 4 Aug 2015 10:56:31 -0400 Subject: [PATCH 36/51] Recase folder name --- src/{lang => Lang2}/en/exceptions.php | 0 src/{lang => Lang2}/en/reasons.php | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename src/{lang => Lang2}/en/exceptions.php (100%) rename src/{lang => Lang2}/en/reasons.php (100%) diff --git a/src/lang/en/exceptions.php b/src/Lang2/en/exceptions.php similarity index 100% rename from src/lang/en/exceptions.php rename to src/Lang2/en/exceptions.php diff --git a/src/lang/en/reasons.php b/src/Lang2/en/reasons.php similarity index 100% rename from src/lang/en/reasons.php rename to src/Lang2/en/reasons.php From ee752a3a414f48cd8d14cdf4d21a1f2e0ea9e45c Mon Sep 17 00:00:00 2001 From: Steve Bauman Date: Tue, 4 Aug 2015 10:56:46 -0400 Subject: [PATCH 37/51] Recase folder name --- src/{Lang2 => Lang}/en/exceptions.php | 0 src/{Lang2 => Lang}/en/reasons.php | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename src/{Lang2 => Lang}/en/exceptions.php (100%) rename src/{Lang2 => Lang}/en/reasons.php (100%) diff --git a/src/Lang2/en/exceptions.php b/src/Lang/en/exceptions.php similarity index 100% rename from src/Lang2/en/exceptions.php rename to src/Lang/en/exceptions.php diff --git a/src/Lang2/en/reasons.php b/src/Lang/en/reasons.php similarity index 100% rename from src/Lang2/en/reasons.php rename to src/Lang/en/reasons.php From 22c778fb0570766875a1533d965d31962ff09ce6 Mon Sep 17 00:00:00 2001 From: Steve Bauman Date: Tue, 4 Aug 2015 10:56:55 -0400 Subject: [PATCH 38/51] Recase folder name --- src/{config => Config2}/.gitkeep | 0 src/{config => Config2}/config.php | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename src/{config => Config2}/.gitkeep (100%) rename src/{config => Config2}/config.php (100%) diff --git a/src/config/.gitkeep b/src/Config2/.gitkeep similarity index 100% rename from src/config/.gitkeep rename to src/Config2/.gitkeep diff --git a/src/config/config.php b/src/Config2/config.php similarity index 100% rename from src/config/config.php rename to src/Config2/config.php From 7d49f2beeeca71899677c791441dcfa68cb89263 Mon Sep 17 00:00:00 2001 From: Steve Bauman Date: Tue, 4 Aug 2015 10:57:03 -0400 Subject: [PATCH 39/51] Recase folder name --- src/{Config2 => Config}/.gitkeep | 0 src/{Config2 => Config}/config.php | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename src/{Config2 => Config}/.gitkeep (100%) rename src/{Config2 => Config}/config.php (100%) diff --git a/src/Config2/.gitkeep b/src/Config/.gitkeep similarity index 100% rename from src/Config2/.gitkeep rename to src/Config/.gitkeep diff --git a/src/Config2/config.php b/src/Config/config.php similarity index 100% rename from src/Config2/config.php rename to src/Config/config.php From a4ed568678488aeb2f8c10dc98daaeeb02050eaa Mon Sep 17 00:00:00 2001 From: Mohd Sulaiman Date: Tue, 11 Aug 2015 12:27:31 +0800 Subject: [PATCH 40/51] Update INSTALLATION.md --- docs/INSTALLATION.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/INSTALLATION.md b/docs/INSTALLATION.md index a41eabd6..724a5f29 100644 --- a/docs/INSTALLATION.md +++ b/docs/INSTALLATION.md @@ -160,7 +160,7 @@ Inventory: use InventoryVariantTrait; use AssemblyTrait; - protected $table = 'inventory'; + protected $table = 'inventories'; public function category() { From 833b906bade767b245ab635327cf5cbfaaeb36cf Mon Sep 17 00:00:00 2001 From: Steve Bauman Date: Thu, 13 Aug 2015 11:26:57 -0400 Subject: [PATCH 41/51] Working on 2.0 --- composer.json | 6 +- src/Commands/InstallCommand.php | 40 --- src/Commands/RunMigrationsCommand.php | 32 -- src/Commands/SchemaCheckCommand.php | 126 -------- .../DatabaseTableReservedException.php | 7 - .../Commands/DependencyNotFoundException.php | 7 - src/Helper.php | 39 +-- src/InventoryServiceProvider.php | 103 +------ ...4_07_31_123213_create_inventory_tables.php | 61 +--- ...3_02_143457_create_inventory_sku_table.php | 7 +- ...35351_create_inventory_supplier_tables.php | 12 +- ...5523_create_inventory_assemblies_table.php | 9 +- src/Models/Inventory.php | 4 +- src/Traits/InventoryStockTrait.php | 20 +- src/Traits/InventoryTrait.php | 76 ++--- src/Traits/InventoryTransactionTrait.php | 3 +- tests/FunctionalTestCase.php | 275 +----------------- tests/InventoryTest.php | 1 + 18 files changed, 99 insertions(+), 729 deletions(-) delete mode 100644 src/Commands/InstallCommand.php delete mode 100644 src/Commands/RunMigrationsCommand.php delete mode 100644 src/Commands/SchemaCheckCommand.php delete mode 100644 src/Exceptions/Commands/DatabaseTableReservedException.php delete mode 100644 src/Exceptions/Commands/DependencyNotFoundException.php diff --git a/composer.json b/composer.json index 217e0451..bfcd342f 100644 --- a/composer.json +++ b/composer.json @@ -11,9 +11,9 @@ "license": "MIT", "require": { "php": ">=5.4.0", - "illuminate/database": "4.* | 5.*", - "illuminate/support": "4.* | 5.*", - "baum/baum": "1.0.* | 1.1.*" + "illuminate/database": "5.*", + "illuminate/support": "5.*", + "baum/baum": "1.1.*" }, "require-dev": { "phpunit/phpunit": "4.*", diff --git a/src/Commands/InstallCommand.php b/src/Commands/InstallCommand.php deleted file mode 100644 index 8f9552cb..00000000 --- a/src/Commands/InstallCommand.php +++ /dev/null @@ -1,40 +0,0 @@ -info('Checking Database Schema'); - - $this->call('inventory:check-schema'); - - $this->info('Running migrations'); - - $this->call('inventory:run-migrations'); - - $this->info('Inventory has been successfully installed'); - } -} diff --git a/src/Commands/RunMigrationsCommand.php b/src/Commands/RunMigrationsCommand.php deleted file mode 100644 index 5a011649..00000000 --- a/src/Commands/RunMigrationsCommand.php +++ /dev/null @@ -1,32 +0,0 @@ -call('migrate', [ - '--path' => 'vendor/stevebauman/inventory/src/migrations', - ]); - } -} diff --git a/src/Commands/SchemaCheckCommand.php b/src/Commands/SchemaCheckCommand.php deleted file mode 100644 index b550c02f..00000000 --- a/src/Commands/SchemaCheckCommand.php +++ /dev/null @@ -1,126 +0,0 @@ - 'Sentry, Sentinel or Laravel', - ]; - - /** - * Holds the reserved database tables that - * cannot exist before installation. - * - * @var array - */ - protected $reserved = [ - 'metrics', - 'locations', - 'categories', - 'suppliers', - 'inventory', - 'inventory_skus', - 'inventory_stocks', - 'inventory_stock_movements', - 'inventory_suppliers', - 'inventory_transactions', - 'inventory_transaction_histories', - 'inventory_assemblies', - ]; - - /** - * Executes the console command. - * - * @throws DatabaseTableReservedException - * @throws DependencyNotFoundException - */ - public function fire() - { - if ($this->checkDependencies()) { - $this->info('Schema dependencies are all good!'); - } - - if ($this->checkReserved()) { - $this->info('Schema reserved tables are all good!'); - } - } - - /** - * Checks the current database for dependencies. - * - * @throws DependencyNotFoundException - * - * @return bool - */ - private function checkDependencies() - { - foreach ($this->dependencies as $table => $suppliedBy) { - if (!$this->tableExists($table)) { - $message = sprintf('Table: %s does not exist, it is supplied by %s', $table, $suppliedBy); - - throw new DependencyNotFoundException($message); - } - } - - return true; - } - - /** - * Checks the current database for reserved tables. - * - * @throws DatabaseTableReservedException - * - * @return bool - */ - private function checkReserved() - { - foreach ($this->reserved as $table) { - if ($this->tableExists($table)) { - $message = sprintf('Table: %s already exists. This table is reserved. Please remove the database table to continue', $table); - - throw new DatabaseTableReservedException($message); - } - } - - return true; - } - - /** - * Returns true / false if the current - * database table exists. - * - * @param string $table - * - * @return bool - */ - private function tableExists($table) - { - return Schema::hasTable($table); - } -} diff --git a/src/Exceptions/Commands/DatabaseTableReservedException.php b/src/Exceptions/Commands/DatabaseTableReservedException.php deleted file mode 100644 index 6f9a6f81..00000000 --- a/src/Exceptions/Commands/DatabaseTableReservedException.php +++ /dev/null @@ -1,7 +0,0 @@ -getAncestorsAndSelf(); - - foreach ($ancestors as $ancestor) { - if ($node->equals($ancestor) && $node->isRoot()) { - $html .= sprintf('%s', $ancestor->name); - } elseif ($node->equals($ancestor)) { - $html .= sprintf(' > %s', $ancestor->name); - } elseif ($ancestor->isRoot()) { - $html .= sprintf('%s', $ancestor->name); - } else { - $html .= sprintf(' > %s', $ancestor->name); - } - } - - return $html; - } - - return $node; - } - /** * Attempt to find the user id of the currently logged in user * Supports Cartalyst Sentry/Sentinel based authentication, as well as stock Auth. @@ -52,11 +19,9 @@ public function renderNode(Model $node) */ public static function getCurrentUserId() { - $separator = InventoryServiceProvider::$packageConfigSeparator; - // Check if we're allowed to return no user ID to the model, if so we'll return null. - if (Config::get('inventory'.$separator.'allow_no_user')) { - return; + if (Config::get('inventory.allow_no_user', false)) { + return null; } // Accountability is enabled, let's try and retrieve the current users ID. diff --git a/src/InventoryServiceProvider.php b/src/InventoryServiceProvider.php index 89a8ed56..9cd9a93f 100644 --- a/src/InventoryServiceProvider.php +++ b/src/InventoryServiceProvider.php @@ -4,9 +4,6 @@ use Illuminate\Support\ServiceProvider; -/** - * Class InventoryServiceProvider. - */ class InventoryServiceProvider extends ServiceProvider { /** @@ -14,23 +11,7 @@ class InventoryServiceProvider extends ServiceProvider * * @var string */ - const VERSION = '1.7.5'; - - /** - * Stores the package configuration separator - * for Laravel 5 compatibility. - * - * @var string - */ - public static $packageConfigSeparator = '::'; - - /** - * The laravel version number. This is - * used for the install commands. - * - * @var int - */ - public static $laravelVersion = 4; + const VERSION = '2.0'; /** * Indicates if loading of the provider is deferred. @@ -44,79 +25,23 @@ class InventoryServiceProvider extends ServiceProvider */ public function boot() { - /* - * If the package method exists, we're using Laravel 4, if not, we're on 5 - */ - if (method_exists($this, 'package')) { - $this->package('stevebauman/inventory', 'stevebauman/inventory', __DIR__.'/..'); - } else { - /* - * Set the proper configuration separator since - * retrieving configuration values in packages - * changed from '::' to '.' - */ - $this::$packageConfigSeparator = '.'; - - /* - * Set the local inventory laravel version for easy checking - */ - $this::$laravelVersion = 5; - - /* - * Load the inventory translations from the inventory lang folder - */ - $this->loadTranslationsFrom(__DIR__.'/lang', 'inventory'); - - /* - * Assign the configuration as publishable, and tag it as 'config' - */ - $this->publishes([ - __DIR__.'/config/config.php' => config_path('inventory.php'), - ], 'config'); - - /* - * Assign the migrations as publishable, and tag it as 'migrations' - */ - $this->publishes([ - __DIR__.'/migrations/' => base_path('database/migrations'), - ], 'migrations'); - } + // Load the inventory translations from the inventory lang folder + $this->loadTranslationsFrom(__DIR__.'/Lang', 'inventory'); + + // Assign the configuration as publishable, and tag it as 'config' + $this->publishes([ + __DIR__.'/Config/config.php' => config_path('inventory.php'), + ], 'config'); + + // Assign the migrations as publishable, and tag it as 'migrations' + $this->publishes([ + __DIR__.'/Migrations/' => base_path('database/migrations'), + ], 'migrations'); } - /** - * Register the service provider. - */ public function register() { - /* - * Bind the install command - */ - $this->app->bind('inventory:install', function () { - return new Commands\InstallCommand(); - }); - - /* - * Bind the check-schema command - */ - $this->app->bind('inventory:check-schema', function () { - return new Commands\SchemaCheckCommand(); - }); - - /* - * Bind the run migrations command - */ - $this->app->bind('inventory:run-migrations', function () { - return new Commands\RunMigrationsCommand(); - }); - - /* - * Register the commands - */ - $this->commands([ - 'inventory:install', - 'inventory:check-schema', - 'inventory:run-migrations', - ]); + // } /** diff --git a/src/Migrations/2014_07_31_123213_create_inventory_tables.php b/src/Migrations/2014_07_31_123213_create_inventory_tables.php index 769dfc45..4f97814c 100644 --- a/src/Migrations/2014_07_31_123213_create_inventory_tables.php +++ b/src/Migrations/2014_07_31_123213_create_inventory_tables.php @@ -10,63 +10,32 @@ class CreateInventoryTables extends Migration */ public function up() { - Schema::create('inventories', function (Blueprint $table) { + Schema::create('inventory_stocks', function (Blueprint $table) + { $table->increments('id'); $table->timestamps(); $table->softDeletes(); - $table->integer('category_id')->unsigned()->nullable(); - $table->integer('user_id')->unsigned()->nullable(); - $table->integer('metric_id')->unsigned(); - $table->string('name'); - $table->text('description')->nullable(); - - $table->foreign('category_id')->references('id')->on('categories') - ->onUpdate('restrict') - ->onDelete('set null'); - - $table->foreign('user_id')->references('id')->on('users') - ->onUpdate('restrict') - ->onDelete('set null'); - - $table->foreign('metric_id')->references('id')->on('metrics') - ->onUpdate('restrict') - ->onDelete('cascade'); - }); - - Schema::create('inventory_stocks', function (Blueprint $table) { - $table->increments('id'); - $table->timestamps(); - $table->softDeletes(); + $table->integer('stockable_id'); + $table->string('stockable_type'); $table->integer('user_id')->unsigned()->nullable(); - $table->integer('inventory_id')->unsigned(); $table->integer('location_id')->unsigned(); - $table->decimal('quantity', 8, 2)->default(0); $table->string('aisle')->nullable(); $table->string('row')->nullable(); $table->string('bin')->nullable(); - /* - * This allows only one inventory stock - * to be created on a single location - */ - $table->unique(['inventory_id', 'location_id']); - - $table->foreign('user_id')->references('id')->on('users') - ->onUpdate('restrict') - ->onDelete('set null'); + // This allows only one inventory stock + // to be created on a single location + $table->unique(['stockable_id', 'stockable_type', 'location_id']); - $table->foreign('inventory_id')->references('id')->on('inventories') - ->onUpdate('restrict') - ->onDelete('cascade'); + $table->foreign('user_id')->references('id')->on('users'); - $table->foreign('location_id')->references('id')->on('locations') - ->onUpdate('restrict') - ->onDelete('cascade'); + $table->foreign('location_id')->references('id')->on('locations'); }); - Schema::create('inventory_stock_movements', function (Blueprint $table) { + Schema::create('inventory_stock_movements', function (Blueprint $table) + { $table->increments('id'); $table->timestamps(); $table->softDeletes(); @@ -78,13 +47,9 @@ public function up() $table->decimal('cost', 8, 2)->default(0)->nullable(); $table->string('reason')->nullable(); - $table->foreign('stock_id')->references('id')->on('inventory_stocks') - ->onUpdate('restrict') - ->onDelete('cascade'); + $table->foreign('stock_id')->references('id')->on('inventory_stocks'); - $table->foreign('user_id')->references('id')->on('users') - ->onUpdate('restrict') - ->onDelete('set null'); + $table->foreign('user_id')->references('id')->on('users'); }); } diff --git a/src/Migrations/2015_03_02_143457_create_inventory_sku_table.php b/src/Migrations/2015_03_02_143457_create_inventory_sku_table.php index f09517cd..c8e71796 100644 --- a/src/Migrations/2015_03_02_143457_create_inventory_sku_table.php +++ b/src/Migrations/2015_03_02_143457_create_inventory_sku_table.php @@ -13,13 +13,10 @@ public function up() Schema::create('inventory_skus', function (Blueprint $table) { $table->increments('id'); $table->timestamps(); - $table->integer('inventory_id')->unsigned(); + $table->integer('inventoryable_id'); + $table->string('inventoryable_type'); $table->string('code'); - $table->foreign('inventory_id')->references('id')->on('inventories') - ->onUpdate('restrict') - ->onDelete('cascade'); - /* * Make sure each SKU is unique */ diff --git a/src/Migrations/2015_03_06_135351_create_inventory_supplier_tables.php b/src/Migrations/2015_03_06_135351_create_inventory_supplier_tables.php index 9220816e..80f3ca81 100644 --- a/src/Migrations/2015_03_06_135351_create_inventory_supplier_tables.php +++ b/src/Migrations/2015_03_06_135351_create_inventory_supplier_tables.php @@ -32,16 +32,12 @@ public function up() $table->increments('id'); $table->timestamps(); - $table->integer('inventory_id')->unsigned(); - $table->integer('supplier_id')->unsigned(); + $table->integer('inventoryable_id'); + $table->string('inventoryable_type'); - $table->foreign('inventory_id')->references('id')->on('inventories') - ->onUpdate('restrict') - ->onDelete('cascade'); + $table->integer('supplier_id')->unsigned(); - $table->foreign('supplier_id')->references('id')->on('suppliers') - ->onUpdate('restrict') - ->onDelete('cascade'); + $table->foreign('supplier_id')->references('id')->on('suppliers'); }); } diff --git a/src/Migrations/2015_05_08_115523_create_inventory_assemblies_table.php b/src/Migrations/2015_05_08_115523_create_inventory_assemblies_table.php index 093bd90b..8b1a17e6 100644 --- a/src/Migrations/2015_05_08_115523_create_inventory_assemblies_table.php +++ b/src/Migrations/2015_05_08_115523_create_inventory_assemblies_table.php @@ -14,13 +14,12 @@ public function up() $table->increments('id'); $table->timestamps(); - $table->integer('inventory_id')->unsigned(); - $table->integer('part_id')->unsigned(); + $table->integer('inventoryable_id'); + $table->string('inventoryable_type'); + $table->integer('inventoryable_part_id'); + $table->string('inventoryable_part_type'); $table->integer('quantity')->nullable(); - $table->foreign('inventory_id')->references('id')->on('inventories')->onDelete('cascade'); - $table->foreign('part_id')->references('id')->on('inventories')->onDelete('cascade'); - }); } diff --git a/src/Models/Inventory.php b/src/Models/Inventory.php index ff215832..9afd5f9c 100644 --- a/src/Models/Inventory.php +++ b/src/Models/Inventory.php @@ -52,11 +52,11 @@ public function sku() /** * The hasMany stocks relationship. * - * @return \Illuminate\Database\Eloquent\Relations\HasMany + * @return \Illuminate\Database\Eloquent\Relations\MorphMany */ public function stocks() { - return $this->hasMany('Stevebauman\Inventory\Models\InventoryStock', 'inventory_id', 'id'); + return $this->morphMany('Stevebauman\Inventory\Models\InventoryStock', 'stockable'); } /** diff --git a/src/Traits/InventoryStockTrait.php b/src/Traits/InventoryStockTrait.php index d28708dd..a5e3bf6b 100644 --- a/src/Traits/InventoryStockTrait.php +++ b/src/Traits/InventoryStockTrait.php @@ -2,7 +2,6 @@ namespace Stevebauman\Inventory\Traits; -use Stevebauman\Inventory\InventoryServiceProvider; use Stevebauman\Inventory\Exceptions\NotEnoughStockException; use Stevebauman\Inventory\Exceptions\InvalidMovementException; use Stevebauman\Inventory\Exceptions\InvalidQuantityException; @@ -40,18 +39,21 @@ trait InventoryStockTrait private $beforeQuantity = 0; /** - * The hasOne location relationship. + * The morphTo stockable owner relationship. * - * @return \Illuminate\Database\Eloquent\Relations\HasOne + * @return \Illuminate\Database\Eloquent\Relations\MorphTo */ - abstract public function location(); + public function stockable() + { + return $this->morphTo(); + } /** - * The belongsTo item relationship. + * The hasOne location relationship. * - * @return \Illuminate\Database\Eloquent\Relations\BelongsTo + * @return \Illuminate\Database\Eloquent\Relations\HasOne */ - abstract public function item(); + abstract public function location(); /** * The hasMany movements relationship. @@ -661,7 +663,7 @@ private function setReason($reason = '') */ private function allowDuplicateMovementsEnabled() { - return Config::get('inventory'.InventoryServiceProvider::$packageConfigSeparator.'allow_duplicate_movements'); + return Config::get('inventory.allow_duplicate_movements'); } /** @@ -673,6 +675,6 @@ private function allowDuplicateMovementsEnabled() */ private function rollbackCostEnabled() { - return Config::get('inventory'.InventoryServiceProvider::$packageConfigSeparator.'rollback_cost'); + return Config::get('inventory.rollback_cost'); } } diff --git a/src/Traits/InventoryTrait.php b/src/Traits/InventoryTrait.php index 3f520848..5f346aaa 100644 --- a/src/Traits/InventoryTrait.php +++ b/src/Traits/InventoryTrait.php @@ -5,7 +5,6 @@ use Stevebauman\Inventory\Exceptions\SkuAlreadyExistsException; use Stevebauman\Inventory\Exceptions\StockNotFoundException; use Stevebauman\Inventory\Exceptions\StockAlreadyExistsException; -use Stevebauman\Inventory\InventoryServiceProvider; use Stevebauman\Inventory\Helper; use Illuminate\Database\Eloquent\Model; use Illuminate\Support\Facades\Config; @@ -40,9 +39,9 @@ abstract public function metric(); abstract public function sku(); /** - * The hasMany stocks relationship. + * The morphMany stocks relationship. * - * @return \Illuminate\Database\Eloquent\Relations\HasMany + * @return \Illuminate\Database\Eloquent\Relations\MorphMany */ abstract public function stocks(); @@ -94,14 +93,10 @@ public static function bootInventoryTrait() */ public static function findBySku($sku) { - /* - * Create a new static instance - */ + // Create a new static instance $instance = new static(); - /* - * Try and find the SKU record - */ + // Try and find the SKU record $sku = $instance ->sku() ->getRelated() @@ -109,17 +104,12 @@ public static function findBySku($sku) ->where('code', $sku) ->first(); - /* - * Check if the SKU was found, and if an item is - * attached to the SKU we'll return it - */ + // Check if the SKU was found, and if an item + // is attached to the SKU we'll return it if ($sku && $sku->item) { return $sku->item; } - /* - * Return false on failure - */ return false; } @@ -186,7 +176,7 @@ public function getMetricSymbol() return $this->metric->symbol; } - return; + return null; } /** @@ -231,7 +221,8 @@ public function createStockOnLocation($quantity, Model $location, $reason = '', // A stock record wasn't found on this location, we'll create one. $stock = $this->stocks()->getRelated()->newInstance(); - $stock->setAttribute('inventory_id', $this->getKey()); + $stock->setAttribute('stockable_id', $this->getKey()); + $stock->setAttribute('stockable_type', get_class($this)); $stock->setAttribute('location_id', $location->getKey()); $stock->setAttribute('quantity', 0); $stock->setAttribute('aisle', $aisle); @@ -259,9 +250,8 @@ public function createStockOnLocation($quantity, Model $location, $reason = '', public function newStockOnLocation(Model $location) { try { - /* - * We want to make sure stock doesn't exist on the specified location already - */ + // We want to make sure stock doesn't exist + // on the specified location already if ($this->getStockFromLocation($location)) { $message = Lang::get('inventory::exceptions.StockAlreadyExistsException', [ 'location' => $location->name, @@ -274,7 +264,8 @@ public function newStockOnLocation(Model $location) $stock = $this->stocks()->getRelated()->newInstance(); // Assign the known attributes so devs don't have to - $stock->setAttribute('inventory_id', $this->getKey()); + $stock->setAttribute('stockable_id', $this->getKey()); + $stock->setAttribute('stockable_type', get_class($this)); $stock->setAttribute('location_id', $location->getKey()); return $stock; @@ -485,7 +476,7 @@ public function getSku() return $this->sku->getAttribute('code'); } - return; + return null; } /** @@ -519,38 +510,28 @@ public function generateSku() return $this->sku; } - $separator = InventoryServiceProvider::$packageConfigSeparator; - // Get the set SKU code length from the configuration file - $codeLength = Config::get('inventory'.$separator.'sku_code_length'); + $codeLength = Config::get('inventory.sku_code_length', 6); // Get the set SKU prefix length from the configuration file - $prefixLength = Config::get('inventory'.$separator.'sku_prefix_length'); + $prefixLength = Config::get('inventory.sku_prefix_length', 3); // Get the set SKU separator - $skuSeparator = Config::get('inventory'.$separator.'sku_separator'); + $skuSeparator = Config::get('inventory.sku_separator', ''); - /* - * Make sure we trim empty spaces in the separator - * if it's a string, otherwise we'll set it to NULL - */ + // Make sure we trim empty spaces in the separator if + // it's a string, otherwise we'll set it to NULL $skuSeparator = (is_string($skuSeparator) ? trim($skuSeparator) : null); - /* - * Trim the category name to remove blank spaces, then - * grab the first 3 letters of the string, and uppercase them - */ + // Trim the category name to remove blank spaces, then grab + // the first 3 letters of the string, and uppercase them $prefix = strtoupper(substr(trim($this->category->getAttribute('name')), 0, intval($prefixLength))); - /* - * We'll make sure the prefix length is greater - * than zero before we try and generate an SKU - */ + // We'll make sure the prefix length is greater + // than zero before we try and generate an SKU if (strlen($prefix) > 0) { - /* - * Create the numerical code by the items ID - * to accompany the prefix and pad left zeros - */ + // Create the numerical code by the items ID to + // accompany the prefix and pad left zeros $code = str_pad($this->getKey(), $codeLength, '0', STR_PAD_LEFT); // Return and process the generation @@ -646,10 +627,7 @@ public function updateSku($code, $sku = null) $sku = $this->sku()->first(); } - /* - * If an SKU still doesn't exist after - * trying to find one, we'll create one - */ + // If an SKU still doesn't exist after trying to find one, we'll create one if (!$sku) { return $this->processSkuGeneration($this->getKey(), $code); } @@ -726,6 +704,6 @@ private function processSkuUpdate(Model $sku, $code) */ private function skusEnabled() { - return Config::get('inventory'.InventoryServiceProvider::$packageConfigSeparator.'skus_enabled', false); + return Config::get('inventory.skus_enabled', false); } } diff --git a/src/Traits/InventoryTransactionTrait.php b/src/Traits/InventoryTransactionTrait.php index 5acb6711..7f4019dd 100644 --- a/src/Traits/InventoryTransactionTrait.php +++ b/src/Traits/InventoryTransactionTrait.php @@ -6,7 +6,6 @@ use Stevebauman\Inventory\Exceptions\NotEnoughStockException; use Stevebauman\Inventory\Exceptions\StockNotFoundException; use Stevebauman\Inventory\Exceptions\InvalidTransactionStateException; -use Stevebauman\Inventory\InventoryServiceProvider; use Stevebauman\Inventory\Helper; use Illuminate\Database\Eloquent\Model; use Illuminate\Support\Facades\Lang; @@ -1103,7 +1102,7 @@ public function getLastHistoryRecord() public function setQuantityAttribute($quantity) { if (!$this->isPositive($quantity)) { - $path = 'inventory'.InventoryServiceProvider::$packageConfigSeparator.'exceptions.InvalidQuantityException'; + $path = 'inventory.exceptions.InvalidQuantityException'; $message = Lang::get($path); diff --git a/tests/FunctionalTestCase.php b/tests/FunctionalTestCase.php index a1d13fc7..f6130dfc 100644 --- a/tests/FunctionalTestCase.php +++ b/tests/FunctionalTestCase.php @@ -2,279 +2,34 @@ namespace Stevebauman\Inventory\Tests; -use Illuminate\Database\Capsule\Manager as DB; +use Orchestra\Testbench\TestCase; -abstract class FunctionalTestCase extends \PHPUnit_Framework_TestCase +abstract class FunctionalTestCase extends TestCase { public function setUp() { parent::setUp(); - $this->configureDatabase(); - $this->migrateTables(); + $this->artisan('migrate', [ + '--database' => 'testbench', + '--realpath' => realpath(__DIR__.'/../src/Migrations'), + ]); } - private function configureDatabase() + protected function getEnvironmentSetup($app) { - $db = new DB(); - - $db->addConnection([ - 'driver' => 'sqlite', + $app['config']->set('database.default', 'testbench'); + $app['config']->set('database.connections.testbench', [ + 'driver' => 'sqlite', 'database' => ':memory:', - 'charset' => 'utf8', - 'collation' => 'utf8_unicode_ci', - 'prefix' => '', + 'prefix' => '', ]); - - $db->bootEloquent(); - - $db->setAsGlobal(); } - private function migrateTables() + protected function getPackageProviders() { - DB::schema()->create('users', function ($table) { - $table->increments('id'); - $table->string('name'); - }); - - DB::schema()->create('metrics', function ($table) { - $table->increments('id'); - $table->timestamps(); - $table->integer('user_id')->unsigned()->nullable(); - $table->string('name'); - $table->string('symbol'); - - $table->foreign('user_id')->references('id')->on('users') - ->onUpdate('restrict') - ->onDelete('set null'); - }); - - DB::schema()->create('categories', function ($table) { - $table->increments('id'); - $table->timestamps(); - $table->integer('parent_id')->nullable()->index(); - $table->integer('lft')->nullable()->index(); - $table->integer('rgt')->nullable()->index(); - $table->integer('depth')->nullable(); - $table->string('name'); - - /* - * This field is for scoping categories, use it if you - * want to store multiple nested sets on the same table - */ - $table->string('belongs_to')->nullable(); - }); - - DB::schema()->create('locations', function ($table) { - $table->increments('id'); - $table->timestamps(); - $table->integer('parent_id')->nullable()->index(); - $table->integer('lft')->nullable()->index(); - $table->integer('rgt')->nullable()->index(); - $table->integer('depth')->nullable(); - $table->string('name'); - - /* - * This field is for scoping categories, use it if you - * want to store multiple nested sets on the same table - */ - $table->string('belongs_to')->nullable(); - }); - - DB::schema()->create('inventories', function ($table) { - $table->increments('id'); - $table->timestamps(); - $table->softDeletes(); - $table->integer('category_id')->unsigned()->nullable(); - $table->integer('user_id')->unsigned()->nullable(); - $table->integer('metric_id')->unsigned(); - $table->string('name'); - $table->text('description')->nullable(); - - $table->foreign('category_id')->references('id')->on('categories') - ->onUpdate('restrict') - ->onDelete('set null'); - - $table->foreign('user_id')->references('id')->on('users') - ->onUpdate('restrict') - ->onDelete('set null'); - - $table->foreign('metric_id')->references('id')->on('metrics') - ->onUpdate('restrict') - ->onDelete('cascade'); - }); - - DB::schema()->create('inventory_stocks', function ($table) { - $table->increments('id'); - $table->timestamps(); - $table->integer('user_id')->unsigned()->nullable(); - $table->integer('inventory_id')->unsigned(); - $table->integer('location_id')->unsigned(); - $table->decimal('quantity', 8, 2)->default(0); - $table->string('aisle')->nullable(); - $table->string('row')->nullable(); - $table->string('bin')->nullable(); - - /* - * This allows only one stock to be created - * on a single location - */ - $table->unique(['inventory_id', 'location_id']); - - $table->foreign('user_id')->references('id')->on('users') - ->onUpdate('restrict') - ->onDelete('set null'); - - $table->foreign('inventory_id')->references('id')->on('inventories') - ->onUpdate('restrict') - ->onDelete('cascade'); - - $table->foreign('location_id')->references('id')->on('locations') - ->onUpdate('restrict') - ->onDelete('cascade'); - }); - - DB::schema()->create('inventory_stock_movements', function ($table) { - $table->increments('id'); - $table->timestamps(); - $table->integer('stock_id')->unsigned(); - $table->integer('user_id')->unsigned()->nullable(); - $table->decimal('before', 8, 2)->default(0); - $table->decimal('after', 8, 2)->default(0); - $table->decimal('cost', 8, 2)->default(0)->nullable(); - $table->string('reason')->nullable(); - - $table->foreign('stock_id')->references('id')->on('inventory_stocks') - ->onUpdate('restrict') - ->onDelete('cascade'); - - $table->foreign('user_id')->references('id')->on('users') - ->onUpdate('restrict') - ->onDelete('set null'); - }); - - DB::schema()->create('inventory_skus', function ($table) { - $table->increments('id'); - $table->timestamps(); - $table->integer('inventory_id')->unsigned(); - $table->string('code', 20); - - $table->foreign('inventory_id')->references('id')->on('inventories') - ->onUpdate('restrict') - ->onDelete('cascade'); - - /* - * Make sure each SKU is unique - */ - $table->unique(['code']); - }); - - DB::schema()->create('suppliers', function ($table) { - $table->increments('id'); - $table->timestamps(); - - $table->string('name'); - $table->string('address')->nullable(); - $table->string('postal_code')->nullable(); - $table->string('zip_code')->nullable(); - $table->string('region')->nullable(); - $table->string('city')->nullable(); - $table->string('country')->nullable(); - $table->string('contact_title')->nullable(); - $table->string('contact_name')->nullable(); - $table->string('contact_phone')->nullable(); - $table->string('contact_fax')->nullable(); - $table->string('contact_email')->nullable(); - }); - - DB::schema()->create('inventory_suppliers', function ($table) { - $table->increments('id'); - $table->timestamps(); - - $table->integer('inventory_id')->unsigned(); - $table->integer('supplier_id')->unsigned(); - - $table->foreign('inventory_id')->references('id')->on('inventories') - ->onUpdate('restrict') - ->onDelete('cascade'); - - $table->foreign('supplier_id')->references('id')->on('suppliers') - ->onUpdate('restrict') - ->onDelete('cascade'); - }); - - DB::schema()->create('inventory_transactions', function ($table) { - $table->increments('id'); - $table->timestamps(); - $table->integer('user_id')->unsigned()->nullable(); - $table->integer('stock_id')->unsigned(); - $table->string('name')->nullable(); - $table->string('state'); - $table->decimal('quantity', 8, 2)->default(0); - - $table->foreign('user_id')->references('id')->on('users') - ->onUpdate('restrict') - ->onDelete('set null'); - - $table->foreign('stock_id')->references('id')->on('inventory_stocks') - ->onUpdate('restrict') - ->onDelete('cascade'); - }); - - DB::schema()->create('inventory_transaction_histories', function ($table) { - $table->increments('id'); - $table->timestamps(); - $table->integer('user_id')->unsigned()->nullable(); - $table->integer('transaction_id')->unsigned(); - - /* - * Allows tracking states for each transaction - */ - $table->string('state_before'); - $table->string('state_after'); - - /* - * Allows tracking the quantities of each transaction - */ - $table->string('quantity_before'); - $table->string('quantity_after'); - - $table->foreign('user_id')->references('id')->on('users') - ->onUpdate('restrict') - ->onDelete('set null'); - - $table->foreign('transaction_id')->references('id')->on('inventory_transactions') - ->onUpdate('restrict') - ->onDelete('cascade'); - }); - - DB::schema()->table('inventories', function ($table) { - $table->integer('parent_id')->unsigned()->nullable()->after('id'); - - $table->foreign('parent_id')->references('id')->on('inventories') - ->onUpdate('restrict') - ->onDelete('cascade'); - }); - - DB::schema()->table('inventories', function ($table) { - $table->boolean('is_assembly')->default(false); - }); - - DB::schema()->create('inventory_assemblies', function ($table) { - - $table->increments('id'); - $table->timestamps(); - $table->integer('inventory_id')->unsigned(); - $table->integer('part_id')->unsigned(); - $table->integer('quantity')->nullable(); - - // Extra column for testing - $table->string('extra')->nullable(); - - $table->foreign('inventory_id')->references('id')->on('inventories')->onDelete('cascade'); - $table->foreign('part_id')->references('id')->on('inventories')->onDelete('cascade'); - - }); + return [ + 'Inventory' => 'Stevebauman\Inventory\InventoryServiceProvider', + ]; } } diff --git a/tests/InventoryTest.php b/tests/InventoryTest.php index b09da35f..fb365e34 100644 --- a/tests/InventoryTest.php +++ b/tests/InventoryTest.php @@ -27,6 +27,7 @@ public function setUp() */ protected function newInventory(array $attributes = []) { + $metric = $this->newMetric(); $category = $this->newCategory(); From 0f412bcabace2098612ef7294863cb70128a6a9e Mon Sep 17 00:00:00 2001 From: Steve Bauman Date: Thu, 13 Aug 2015 11:38:12 -0400 Subject: [PATCH 42/51] Revert "Working on 2.0" This reverts commit 833b906bade767b245ab635327cf5cbfaaeb36cf. --- composer.json | 6 +- src/Commands/InstallCommand.php | 40 +++ src/Commands/RunMigrationsCommand.php | 32 ++ src/Commands/SchemaCheckCommand.php | 126 ++++++++ .../DatabaseTableReservedException.php | 7 + .../Commands/DependencyNotFoundException.php | 7 + src/Helper.php | 39 ++- src/InventoryServiceProvider.php | 103 ++++++- ...4_07_31_123213_create_inventory_tables.php | 61 +++- ...3_02_143457_create_inventory_sku_table.php | 7 +- ...35351_create_inventory_supplier_tables.php | 12 +- ...5523_create_inventory_assemblies_table.php | 9 +- src/Models/Inventory.php | 4 +- src/Traits/InventoryStockTrait.php | 20 +- src/Traits/InventoryTrait.php | 76 +++-- src/Traits/InventoryTransactionTrait.php | 3 +- tests/FunctionalTestCase.php | 275 +++++++++++++++++- tests/InventoryTest.php | 1 - 18 files changed, 729 insertions(+), 99 deletions(-) create mode 100644 src/Commands/InstallCommand.php create mode 100644 src/Commands/RunMigrationsCommand.php create mode 100644 src/Commands/SchemaCheckCommand.php create mode 100644 src/Exceptions/Commands/DatabaseTableReservedException.php create mode 100644 src/Exceptions/Commands/DependencyNotFoundException.php diff --git a/composer.json b/composer.json index bfcd342f..217e0451 100644 --- a/composer.json +++ b/composer.json @@ -11,9 +11,9 @@ "license": "MIT", "require": { "php": ">=5.4.0", - "illuminate/database": "5.*", - "illuminate/support": "5.*", - "baum/baum": "1.1.*" + "illuminate/database": "4.* | 5.*", + "illuminate/support": "4.* | 5.*", + "baum/baum": "1.0.* | 1.1.*" }, "require-dev": { "phpunit/phpunit": "4.*", diff --git a/src/Commands/InstallCommand.php b/src/Commands/InstallCommand.php new file mode 100644 index 00000000..8f9552cb --- /dev/null +++ b/src/Commands/InstallCommand.php @@ -0,0 +1,40 @@ +info('Checking Database Schema'); + + $this->call('inventory:check-schema'); + + $this->info('Running migrations'); + + $this->call('inventory:run-migrations'); + + $this->info('Inventory has been successfully installed'); + } +} diff --git a/src/Commands/RunMigrationsCommand.php b/src/Commands/RunMigrationsCommand.php new file mode 100644 index 00000000..5a011649 --- /dev/null +++ b/src/Commands/RunMigrationsCommand.php @@ -0,0 +1,32 @@ +call('migrate', [ + '--path' => 'vendor/stevebauman/inventory/src/migrations', + ]); + } +} diff --git a/src/Commands/SchemaCheckCommand.php b/src/Commands/SchemaCheckCommand.php new file mode 100644 index 00000000..b550c02f --- /dev/null +++ b/src/Commands/SchemaCheckCommand.php @@ -0,0 +1,126 @@ + 'Sentry, Sentinel or Laravel', + ]; + + /** + * Holds the reserved database tables that + * cannot exist before installation. + * + * @var array + */ + protected $reserved = [ + 'metrics', + 'locations', + 'categories', + 'suppliers', + 'inventory', + 'inventory_skus', + 'inventory_stocks', + 'inventory_stock_movements', + 'inventory_suppliers', + 'inventory_transactions', + 'inventory_transaction_histories', + 'inventory_assemblies', + ]; + + /** + * Executes the console command. + * + * @throws DatabaseTableReservedException + * @throws DependencyNotFoundException + */ + public function fire() + { + if ($this->checkDependencies()) { + $this->info('Schema dependencies are all good!'); + } + + if ($this->checkReserved()) { + $this->info('Schema reserved tables are all good!'); + } + } + + /** + * Checks the current database for dependencies. + * + * @throws DependencyNotFoundException + * + * @return bool + */ + private function checkDependencies() + { + foreach ($this->dependencies as $table => $suppliedBy) { + if (!$this->tableExists($table)) { + $message = sprintf('Table: %s does not exist, it is supplied by %s', $table, $suppliedBy); + + throw new DependencyNotFoundException($message); + } + } + + return true; + } + + /** + * Checks the current database for reserved tables. + * + * @throws DatabaseTableReservedException + * + * @return bool + */ + private function checkReserved() + { + foreach ($this->reserved as $table) { + if ($this->tableExists($table)) { + $message = sprintf('Table: %s already exists. This table is reserved. Please remove the database table to continue', $table); + + throw new DatabaseTableReservedException($message); + } + } + + return true; + } + + /** + * Returns true / false if the current + * database table exists. + * + * @param string $table + * + * @return bool + */ + private function tableExists($table) + { + return Schema::hasTable($table); + } +} diff --git a/src/Exceptions/Commands/DatabaseTableReservedException.php b/src/Exceptions/Commands/DatabaseTableReservedException.php new file mode 100644 index 00000000..6f9a6f81 --- /dev/null +++ b/src/Exceptions/Commands/DatabaseTableReservedException.php @@ -0,0 +1,7 @@ +getAncestorsAndSelf(); + + foreach ($ancestors as $ancestor) { + if ($node->equals($ancestor) && $node->isRoot()) { + $html .= sprintf('%s', $ancestor->name); + } elseif ($node->equals($ancestor)) { + $html .= sprintf(' > %s', $ancestor->name); + } elseif ($ancestor->isRoot()) { + $html .= sprintf('%s', $ancestor->name); + } else { + $html .= sprintf(' > %s', $ancestor->name); + } + } + + return $html; + } + + return $node; + } + /** * Attempt to find the user id of the currently logged in user * Supports Cartalyst Sentry/Sentinel based authentication, as well as stock Auth. @@ -19,9 +52,11 @@ class Helper */ public static function getCurrentUserId() { + $separator = InventoryServiceProvider::$packageConfigSeparator; + // Check if we're allowed to return no user ID to the model, if so we'll return null. - if (Config::get('inventory.allow_no_user', false)) { - return null; + if (Config::get('inventory'.$separator.'allow_no_user')) { + return; } // Accountability is enabled, let's try and retrieve the current users ID. diff --git a/src/InventoryServiceProvider.php b/src/InventoryServiceProvider.php index 9cd9a93f..89a8ed56 100644 --- a/src/InventoryServiceProvider.php +++ b/src/InventoryServiceProvider.php @@ -4,6 +4,9 @@ use Illuminate\Support\ServiceProvider; +/** + * Class InventoryServiceProvider. + */ class InventoryServiceProvider extends ServiceProvider { /** @@ -11,7 +14,23 @@ class InventoryServiceProvider extends ServiceProvider * * @var string */ - const VERSION = '2.0'; + const VERSION = '1.7.5'; + + /** + * Stores the package configuration separator + * for Laravel 5 compatibility. + * + * @var string + */ + public static $packageConfigSeparator = '::'; + + /** + * The laravel version number. This is + * used for the install commands. + * + * @var int + */ + public static $laravelVersion = 4; /** * Indicates if loading of the provider is deferred. @@ -25,23 +44,79 @@ class InventoryServiceProvider extends ServiceProvider */ public function boot() { - // Load the inventory translations from the inventory lang folder - $this->loadTranslationsFrom(__DIR__.'/Lang', 'inventory'); - - // Assign the configuration as publishable, and tag it as 'config' - $this->publishes([ - __DIR__.'/Config/config.php' => config_path('inventory.php'), - ], 'config'); - - // Assign the migrations as publishable, and tag it as 'migrations' - $this->publishes([ - __DIR__.'/Migrations/' => base_path('database/migrations'), - ], 'migrations'); + /* + * If the package method exists, we're using Laravel 4, if not, we're on 5 + */ + if (method_exists($this, 'package')) { + $this->package('stevebauman/inventory', 'stevebauman/inventory', __DIR__.'/..'); + } else { + /* + * Set the proper configuration separator since + * retrieving configuration values in packages + * changed from '::' to '.' + */ + $this::$packageConfigSeparator = '.'; + + /* + * Set the local inventory laravel version for easy checking + */ + $this::$laravelVersion = 5; + + /* + * Load the inventory translations from the inventory lang folder + */ + $this->loadTranslationsFrom(__DIR__.'/lang', 'inventory'); + + /* + * Assign the configuration as publishable, and tag it as 'config' + */ + $this->publishes([ + __DIR__.'/config/config.php' => config_path('inventory.php'), + ], 'config'); + + /* + * Assign the migrations as publishable, and tag it as 'migrations' + */ + $this->publishes([ + __DIR__.'/migrations/' => base_path('database/migrations'), + ], 'migrations'); + } } + /** + * Register the service provider. + */ public function register() { - // + /* + * Bind the install command + */ + $this->app->bind('inventory:install', function () { + return new Commands\InstallCommand(); + }); + + /* + * Bind the check-schema command + */ + $this->app->bind('inventory:check-schema', function () { + return new Commands\SchemaCheckCommand(); + }); + + /* + * Bind the run migrations command + */ + $this->app->bind('inventory:run-migrations', function () { + return new Commands\RunMigrationsCommand(); + }); + + /* + * Register the commands + */ + $this->commands([ + 'inventory:install', + 'inventory:check-schema', + 'inventory:run-migrations', + ]); } /** diff --git a/src/Migrations/2014_07_31_123213_create_inventory_tables.php b/src/Migrations/2014_07_31_123213_create_inventory_tables.php index 4f97814c..769dfc45 100644 --- a/src/Migrations/2014_07_31_123213_create_inventory_tables.php +++ b/src/Migrations/2014_07_31_123213_create_inventory_tables.php @@ -10,32 +10,63 @@ class CreateInventoryTables extends Migration */ public function up() { - Schema::create('inventory_stocks', function (Blueprint $table) - { + Schema::create('inventories', function (Blueprint $table) { $table->increments('id'); $table->timestamps(); $table->softDeletes(); - $table->integer('stockable_id'); - $table->string('stockable_type'); + $table->integer('category_id')->unsigned()->nullable(); + $table->integer('user_id')->unsigned()->nullable(); + $table->integer('metric_id')->unsigned(); + $table->string('name'); + $table->text('description')->nullable(); + + $table->foreign('category_id')->references('id')->on('categories') + ->onUpdate('restrict') + ->onDelete('set null'); + + $table->foreign('user_id')->references('id')->on('users') + ->onUpdate('restrict') + ->onDelete('set null'); + + $table->foreign('metric_id')->references('id')->on('metrics') + ->onUpdate('restrict') + ->onDelete('cascade'); + }); + + Schema::create('inventory_stocks', function (Blueprint $table) { + $table->increments('id'); + $table->timestamps(); + $table->softDeletes(); $table->integer('user_id')->unsigned()->nullable(); + $table->integer('inventory_id')->unsigned(); $table->integer('location_id')->unsigned(); + $table->decimal('quantity', 8, 2)->default(0); $table->string('aisle')->nullable(); $table->string('row')->nullable(); $table->string('bin')->nullable(); - // This allows only one inventory stock - // to be created on a single location - $table->unique(['stockable_id', 'stockable_type', 'location_id']); + /* + * This allows only one inventory stock + * to be created on a single location + */ + $table->unique(['inventory_id', 'location_id']); + + $table->foreign('user_id')->references('id')->on('users') + ->onUpdate('restrict') + ->onDelete('set null'); - $table->foreign('user_id')->references('id')->on('users'); + $table->foreign('inventory_id')->references('id')->on('inventories') + ->onUpdate('restrict') + ->onDelete('cascade'); - $table->foreign('location_id')->references('id')->on('locations'); + $table->foreign('location_id')->references('id')->on('locations') + ->onUpdate('restrict') + ->onDelete('cascade'); }); - Schema::create('inventory_stock_movements', function (Blueprint $table) - { + Schema::create('inventory_stock_movements', function (Blueprint $table) { $table->increments('id'); $table->timestamps(); $table->softDeletes(); @@ -47,9 +78,13 @@ public function up() $table->decimal('cost', 8, 2)->default(0)->nullable(); $table->string('reason')->nullable(); - $table->foreign('stock_id')->references('id')->on('inventory_stocks'); + $table->foreign('stock_id')->references('id')->on('inventory_stocks') + ->onUpdate('restrict') + ->onDelete('cascade'); - $table->foreign('user_id')->references('id')->on('users'); + $table->foreign('user_id')->references('id')->on('users') + ->onUpdate('restrict') + ->onDelete('set null'); }); } diff --git a/src/Migrations/2015_03_02_143457_create_inventory_sku_table.php b/src/Migrations/2015_03_02_143457_create_inventory_sku_table.php index c8e71796..f09517cd 100644 --- a/src/Migrations/2015_03_02_143457_create_inventory_sku_table.php +++ b/src/Migrations/2015_03_02_143457_create_inventory_sku_table.php @@ -13,10 +13,13 @@ public function up() Schema::create('inventory_skus', function (Blueprint $table) { $table->increments('id'); $table->timestamps(); - $table->integer('inventoryable_id'); - $table->string('inventoryable_type'); + $table->integer('inventory_id')->unsigned(); $table->string('code'); + $table->foreign('inventory_id')->references('id')->on('inventories') + ->onUpdate('restrict') + ->onDelete('cascade'); + /* * Make sure each SKU is unique */ diff --git a/src/Migrations/2015_03_06_135351_create_inventory_supplier_tables.php b/src/Migrations/2015_03_06_135351_create_inventory_supplier_tables.php index 80f3ca81..9220816e 100644 --- a/src/Migrations/2015_03_06_135351_create_inventory_supplier_tables.php +++ b/src/Migrations/2015_03_06_135351_create_inventory_supplier_tables.php @@ -32,12 +32,16 @@ public function up() $table->increments('id'); $table->timestamps(); - $table->integer('inventoryable_id'); - $table->string('inventoryable_type'); - + $table->integer('inventory_id')->unsigned(); $table->integer('supplier_id')->unsigned(); - $table->foreign('supplier_id')->references('id')->on('suppliers'); + $table->foreign('inventory_id')->references('id')->on('inventories') + ->onUpdate('restrict') + ->onDelete('cascade'); + + $table->foreign('supplier_id')->references('id')->on('suppliers') + ->onUpdate('restrict') + ->onDelete('cascade'); }); } diff --git a/src/Migrations/2015_05_08_115523_create_inventory_assemblies_table.php b/src/Migrations/2015_05_08_115523_create_inventory_assemblies_table.php index 8b1a17e6..093bd90b 100644 --- a/src/Migrations/2015_05_08_115523_create_inventory_assemblies_table.php +++ b/src/Migrations/2015_05_08_115523_create_inventory_assemblies_table.php @@ -14,12 +14,13 @@ public function up() $table->increments('id'); $table->timestamps(); - $table->integer('inventoryable_id'); - $table->string('inventoryable_type'); - $table->integer('inventoryable_part_id'); - $table->string('inventoryable_part_type'); + $table->integer('inventory_id')->unsigned(); + $table->integer('part_id')->unsigned(); $table->integer('quantity')->nullable(); + $table->foreign('inventory_id')->references('id')->on('inventories')->onDelete('cascade'); + $table->foreign('part_id')->references('id')->on('inventories')->onDelete('cascade'); + }); } diff --git a/src/Models/Inventory.php b/src/Models/Inventory.php index 9afd5f9c..ff215832 100644 --- a/src/Models/Inventory.php +++ b/src/Models/Inventory.php @@ -52,11 +52,11 @@ public function sku() /** * The hasMany stocks relationship. * - * @return \Illuminate\Database\Eloquent\Relations\MorphMany + * @return \Illuminate\Database\Eloquent\Relations\HasMany */ public function stocks() { - return $this->morphMany('Stevebauman\Inventory\Models\InventoryStock', 'stockable'); + return $this->hasMany('Stevebauman\Inventory\Models\InventoryStock', 'inventory_id', 'id'); } /** diff --git a/src/Traits/InventoryStockTrait.php b/src/Traits/InventoryStockTrait.php index a5e3bf6b..d28708dd 100644 --- a/src/Traits/InventoryStockTrait.php +++ b/src/Traits/InventoryStockTrait.php @@ -2,6 +2,7 @@ namespace Stevebauman\Inventory\Traits; +use Stevebauman\Inventory\InventoryServiceProvider; use Stevebauman\Inventory\Exceptions\NotEnoughStockException; use Stevebauman\Inventory\Exceptions\InvalidMovementException; use Stevebauman\Inventory\Exceptions\InvalidQuantityException; @@ -39,21 +40,18 @@ trait InventoryStockTrait private $beforeQuantity = 0; /** - * The morphTo stockable owner relationship. + * The hasOne location relationship. * - * @return \Illuminate\Database\Eloquent\Relations\MorphTo + * @return \Illuminate\Database\Eloquent\Relations\HasOne */ - public function stockable() - { - return $this->morphTo(); - } + abstract public function location(); /** - * The hasOne location relationship. + * The belongsTo item relationship. * - * @return \Illuminate\Database\Eloquent\Relations\HasOne + * @return \Illuminate\Database\Eloquent\Relations\BelongsTo */ - abstract public function location(); + abstract public function item(); /** * The hasMany movements relationship. @@ -663,7 +661,7 @@ private function setReason($reason = '') */ private function allowDuplicateMovementsEnabled() { - return Config::get('inventory.allow_duplicate_movements'); + return Config::get('inventory'.InventoryServiceProvider::$packageConfigSeparator.'allow_duplicate_movements'); } /** @@ -675,6 +673,6 @@ private function allowDuplicateMovementsEnabled() */ private function rollbackCostEnabled() { - return Config::get('inventory.rollback_cost'); + return Config::get('inventory'.InventoryServiceProvider::$packageConfigSeparator.'rollback_cost'); } } diff --git a/src/Traits/InventoryTrait.php b/src/Traits/InventoryTrait.php index 5f346aaa..3f520848 100644 --- a/src/Traits/InventoryTrait.php +++ b/src/Traits/InventoryTrait.php @@ -5,6 +5,7 @@ use Stevebauman\Inventory\Exceptions\SkuAlreadyExistsException; use Stevebauman\Inventory\Exceptions\StockNotFoundException; use Stevebauman\Inventory\Exceptions\StockAlreadyExistsException; +use Stevebauman\Inventory\InventoryServiceProvider; use Stevebauman\Inventory\Helper; use Illuminate\Database\Eloquent\Model; use Illuminate\Support\Facades\Config; @@ -39,9 +40,9 @@ abstract public function metric(); abstract public function sku(); /** - * The morphMany stocks relationship. + * The hasMany stocks relationship. * - * @return \Illuminate\Database\Eloquent\Relations\MorphMany + * @return \Illuminate\Database\Eloquent\Relations\HasMany */ abstract public function stocks(); @@ -93,10 +94,14 @@ public static function bootInventoryTrait() */ public static function findBySku($sku) { - // Create a new static instance + /* + * Create a new static instance + */ $instance = new static(); - // Try and find the SKU record + /* + * Try and find the SKU record + */ $sku = $instance ->sku() ->getRelated() @@ -104,12 +109,17 @@ public static function findBySku($sku) ->where('code', $sku) ->first(); - // Check if the SKU was found, and if an item - // is attached to the SKU we'll return it + /* + * Check if the SKU was found, and if an item is + * attached to the SKU we'll return it + */ if ($sku && $sku->item) { return $sku->item; } + /* + * Return false on failure + */ return false; } @@ -176,7 +186,7 @@ public function getMetricSymbol() return $this->metric->symbol; } - return null; + return; } /** @@ -221,8 +231,7 @@ public function createStockOnLocation($quantity, Model $location, $reason = '', // A stock record wasn't found on this location, we'll create one. $stock = $this->stocks()->getRelated()->newInstance(); - $stock->setAttribute('stockable_id', $this->getKey()); - $stock->setAttribute('stockable_type', get_class($this)); + $stock->setAttribute('inventory_id', $this->getKey()); $stock->setAttribute('location_id', $location->getKey()); $stock->setAttribute('quantity', 0); $stock->setAttribute('aisle', $aisle); @@ -250,8 +259,9 @@ public function createStockOnLocation($quantity, Model $location, $reason = '', public function newStockOnLocation(Model $location) { try { - // We want to make sure stock doesn't exist - // on the specified location already + /* + * We want to make sure stock doesn't exist on the specified location already + */ if ($this->getStockFromLocation($location)) { $message = Lang::get('inventory::exceptions.StockAlreadyExistsException', [ 'location' => $location->name, @@ -264,8 +274,7 @@ public function newStockOnLocation(Model $location) $stock = $this->stocks()->getRelated()->newInstance(); // Assign the known attributes so devs don't have to - $stock->setAttribute('stockable_id', $this->getKey()); - $stock->setAttribute('stockable_type', get_class($this)); + $stock->setAttribute('inventory_id', $this->getKey()); $stock->setAttribute('location_id', $location->getKey()); return $stock; @@ -476,7 +485,7 @@ public function getSku() return $this->sku->getAttribute('code'); } - return null; + return; } /** @@ -510,28 +519,38 @@ public function generateSku() return $this->sku; } + $separator = InventoryServiceProvider::$packageConfigSeparator; + // Get the set SKU code length from the configuration file - $codeLength = Config::get('inventory.sku_code_length', 6); + $codeLength = Config::get('inventory'.$separator.'sku_code_length'); // Get the set SKU prefix length from the configuration file - $prefixLength = Config::get('inventory.sku_prefix_length', 3); + $prefixLength = Config::get('inventory'.$separator.'sku_prefix_length'); // Get the set SKU separator - $skuSeparator = Config::get('inventory.sku_separator', ''); + $skuSeparator = Config::get('inventory'.$separator.'sku_separator'); - // Make sure we trim empty spaces in the separator if - // it's a string, otherwise we'll set it to NULL + /* + * Make sure we trim empty spaces in the separator + * if it's a string, otherwise we'll set it to NULL + */ $skuSeparator = (is_string($skuSeparator) ? trim($skuSeparator) : null); - // Trim the category name to remove blank spaces, then grab - // the first 3 letters of the string, and uppercase them + /* + * Trim the category name to remove blank spaces, then + * grab the first 3 letters of the string, and uppercase them + */ $prefix = strtoupper(substr(trim($this->category->getAttribute('name')), 0, intval($prefixLength))); - // We'll make sure the prefix length is greater - // than zero before we try and generate an SKU + /* + * We'll make sure the prefix length is greater + * than zero before we try and generate an SKU + */ if (strlen($prefix) > 0) { - // Create the numerical code by the items ID to - // accompany the prefix and pad left zeros + /* + * Create the numerical code by the items ID + * to accompany the prefix and pad left zeros + */ $code = str_pad($this->getKey(), $codeLength, '0', STR_PAD_LEFT); // Return and process the generation @@ -627,7 +646,10 @@ public function updateSku($code, $sku = null) $sku = $this->sku()->first(); } - // If an SKU still doesn't exist after trying to find one, we'll create one + /* + * If an SKU still doesn't exist after + * trying to find one, we'll create one + */ if (!$sku) { return $this->processSkuGeneration($this->getKey(), $code); } @@ -704,6 +726,6 @@ private function processSkuUpdate(Model $sku, $code) */ private function skusEnabled() { - return Config::get('inventory.skus_enabled', false); + return Config::get('inventory'.InventoryServiceProvider::$packageConfigSeparator.'skus_enabled', false); } } diff --git a/src/Traits/InventoryTransactionTrait.php b/src/Traits/InventoryTransactionTrait.php index 7f4019dd..5acb6711 100644 --- a/src/Traits/InventoryTransactionTrait.php +++ b/src/Traits/InventoryTransactionTrait.php @@ -6,6 +6,7 @@ use Stevebauman\Inventory\Exceptions\NotEnoughStockException; use Stevebauman\Inventory\Exceptions\StockNotFoundException; use Stevebauman\Inventory\Exceptions\InvalidTransactionStateException; +use Stevebauman\Inventory\InventoryServiceProvider; use Stevebauman\Inventory\Helper; use Illuminate\Database\Eloquent\Model; use Illuminate\Support\Facades\Lang; @@ -1102,7 +1103,7 @@ public function getLastHistoryRecord() public function setQuantityAttribute($quantity) { if (!$this->isPositive($quantity)) { - $path = 'inventory.exceptions.InvalidQuantityException'; + $path = 'inventory'.InventoryServiceProvider::$packageConfigSeparator.'exceptions.InvalidQuantityException'; $message = Lang::get($path); diff --git a/tests/FunctionalTestCase.php b/tests/FunctionalTestCase.php index f6130dfc..a1d13fc7 100644 --- a/tests/FunctionalTestCase.php +++ b/tests/FunctionalTestCase.php @@ -2,34 +2,279 @@ namespace Stevebauman\Inventory\Tests; -use Orchestra\Testbench\TestCase; +use Illuminate\Database\Capsule\Manager as DB; -abstract class FunctionalTestCase extends TestCase +abstract class FunctionalTestCase extends \PHPUnit_Framework_TestCase { public function setUp() { parent::setUp(); - $this->artisan('migrate', [ - '--database' => 'testbench', - '--realpath' => realpath(__DIR__.'/../src/Migrations'), - ]); + $this->configureDatabase(); + $this->migrateTables(); } - protected function getEnvironmentSetup($app) + private function configureDatabase() { - $app['config']->set('database.default', 'testbench'); - $app['config']->set('database.connections.testbench', [ - 'driver' => 'sqlite', + $db = new DB(); + + $db->addConnection([ + 'driver' => 'sqlite', 'database' => ':memory:', - 'prefix' => '', + 'charset' => 'utf8', + 'collation' => 'utf8_unicode_ci', + 'prefix' => '', ]); + + $db->bootEloquent(); + + $db->setAsGlobal(); } - protected function getPackageProviders() + private function migrateTables() { - return [ - 'Inventory' => 'Stevebauman\Inventory\InventoryServiceProvider', - ]; + DB::schema()->create('users', function ($table) { + $table->increments('id'); + $table->string('name'); + }); + + DB::schema()->create('metrics', function ($table) { + $table->increments('id'); + $table->timestamps(); + $table->integer('user_id')->unsigned()->nullable(); + $table->string('name'); + $table->string('symbol'); + + $table->foreign('user_id')->references('id')->on('users') + ->onUpdate('restrict') + ->onDelete('set null'); + }); + + DB::schema()->create('categories', function ($table) { + $table->increments('id'); + $table->timestamps(); + $table->integer('parent_id')->nullable()->index(); + $table->integer('lft')->nullable()->index(); + $table->integer('rgt')->nullable()->index(); + $table->integer('depth')->nullable(); + $table->string('name'); + + /* + * This field is for scoping categories, use it if you + * want to store multiple nested sets on the same table + */ + $table->string('belongs_to')->nullable(); + }); + + DB::schema()->create('locations', function ($table) { + $table->increments('id'); + $table->timestamps(); + $table->integer('parent_id')->nullable()->index(); + $table->integer('lft')->nullable()->index(); + $table->integer('rgt')->nullable()->index(); + $table->integer('depth')->nullable(); + $table->string('name'); + + /* + * This field is for scoping categories, use it if you + * want to store multiple nested sets on the same table + */ + $table->string('belongs_to')->nullable(); + }); + + DB::schema()->create('inventories', function ($table) { + $table->increments('id'); + $table->timestamps(); + $table->softDeletes(); + $table->integer('category_id')->unsigned()->nullable(); + $table->integer('user_id')->unsigned()->nullable(); + $table->integer('metric_id')->unsigned(); + $table->string('name'); + $table->text('description')->nullable(); + + $table->foreign('category_id')->references('id')->on('categories') + ->onUpdate('restrict') + ->onDelete('set null'); + + $table->foreign('user_id')->references('id')->on('users') + ->onUpdate('restrict') + ->onDelete('set null'); + + $table->foreign('metric_id')->references('id')->on('metrics') + ->onUpdate('restrict') + ->onDelete('cascade'); + }); + + DB::schema()->create('inventory_stocks', function ($table) { + $table->increments('id'); + $table->timestamps(); + $table->integer('user_id')->unsigned()->nullable(); + $table->integer('inventory_id')->unsigned(); + $table->integer('location_id')->unsigned(); + $table->decimal('quantity', 8, 2)->default(0); + $table->string('aisle')->nullable(); + $table->string('row')->nullable(); + $table->string('bin')->nullable(); + + /* + * This allows only one stock to be created + * on a single location + */ + $table->unique(['inventory_id', 'location_id']); + + $table->foreign('user_id')->references('id')->on('users') + ->onUpdate('restrict') + ->onDelete('set null'); + + $table->foreign('inventory_id')->references('id')->on('inventories') + ->onUpdate('restrict') + ->onDelete('cascade'); + + $table->foreign('location_id')->references('id')->on('locations') + ->onUpdate('restrict') + ->onDelete('cascade'); + }); + + DB::schema()->create('inventory_stock_movements', function ($table) { + $table->increments('id'); + $table->timestamps(); + $table->integer('stock_id')->unsigned(); + $table->integer('user_id')->unsigned()->nullable(); + $table->decimal('before', 8, 2)->default(0); + $table->decimal('after', 8, 2)->default(0); + $table->decimal('cost', 8, 2)->default(0)->nullable(); + $table->string('reason')->nullable(); + + $table->foreign('stock_id')->references('id')->on('inventory_stocks') + ->onUpdate('restrict') + ->onDelete('cascade'); + + $table->foreign('user_id')->references('id')->on('users') + ->onUpdate('restrict') + ->onDelete('set null'); + }); + + DB::schema()->create('inventory_skus', function ($table) { + $table->increments('id'); + $table->timestamps(); + $table->integer('inventory_id')->unsigned(); + $table->string('code', 20); + + $table->foreign('inventory_id')->references('id')->on('inventories') + ->onUpdate('restrict') + ->onDelete('cascade'); + + /* + * Make sure each SKU is unique + */ + $table->unique(['code']); + }); + + DB::schema()->create('suppliers', function ($table) { + $table->increments('id'); + $table->timestamps(); + + $table->string('name'); + $table->string('address')->nullable(); + $table->string('postal_code')->nullable(); + $table->string('zip_code')->nullable(); + $table->string('region')->nullable(); + $table->string('city')->nullable(); + $table->string('country')->nullable(); + $table->string('contact_title')->nullable(); + $table->string('contact_name')->nullable(); + $table->string('contact_phone')->nullable(); + $table->string('contact_fax')->nullable(); + $table->string('contact_email')->nullable(); + }); + + DB::schema()->create('inventory_suppliers', function ($table) { + $table->increments('id'); + $table->timestamps(); + + $table->integer('inventory_id')->unsigned(); + $table->integer('supplier_id')->unsigned(); + + $table->foreign('inventory_id')->references('id')->on('inventories') + ->onUpdate('restrict') + ->onDelete('cascade'); + + $table->foreign('supplier_id')->references('id')->on('suppliers') + ->onUpdate('restrict') + ->onDelete('cascade'); + }); + + DB::schema()->create('inventory_transactions', function ($table) { + $table->increments('id'); + $table->timestamps(); + $table->integer('user_id')->unsigned()->nullable(); + $table->integer('stock_id')->unsigned(); + $table->string('name')->nullable(); + $table->string('state'); + $table->decimal('quantity', 8, 2)->default(0); + + $table->foreign('user_id')->references('id')->on('users') + ->onUpdate('restrict') + ->onDelete('set null'); + + $table->foreign('stock_id')->references('id')->on('inventory_stocks') + ->onUpdate('restrict') + ->onDelete('cascade'); + }); + + DB::schema()->create('inventory_transaction_histories', function ($table) { + $table->increments('id'); + $table->timestamps(); + $table->integer('user_id')->unsigned()->nullable(); + $table->integer('transaction_id')->unsigned(); + + /* + * Allows tracking states for each transaction + */ + $table->string('state_before'); + $table->string('state_after'); + + /* + * Allows tracking the quantities of each transaction + */ + $table->string('quantity_before'); + $table->string('quantity_after'); + + $table->foreign('user_id')->references('id')->on('users') + ->onUpdate('restrict') + ->onDelete('set null'); + + $table->foreign('transaction_id')->references('id')->on('inventory_transactions') + ->onUpdate('restrict') + ->onDelete('cascade'); + }); + + DB::schema()->table('inventories', function ($table) { + $table->integer('parent_id')->unsigned()->nullable()->after('id'); + + $table->foreign('parent_id')->references('id')->on('inventories') + ->onUpdate('restrict') + ->onDelete('cascade'); + }); + + DB::schema()->table('inventories', function ($table) { + $table->boolean('is_assembly')->default(false); + }); + + DB::schema()->create('inventory_assemblies', function ($table) { + + $table->increments('id'); + $table->timestamps(); + $table->integer('inventory_id')->unsigned(); + $table->integer('part_id')->unsigned(); + $table->integer('quantity')->nullable(); + + // Extra column for testing + $table->string('extra')->nullable(); + + $table->foreign('inventory_id')->references('id')->on('inventories')->onDelete('cascade'); + $table->foreign('part_id')->references('id')->on('inventories')->onDelete('cascade'); + + }); } } diff --git a/tests/InventoryTest.php b/tests/InventoryTest.php index fb365e34..b09da35f 100644 --- a/tests/InventoryTest.php +++ b/tests/InventoryTest.php @@ -27,7 +27,6 @@ public function setUp() */ protected function newInventory(array $attributes = []) { - $metric = $this->newMetric(); $category = $this->newCategory(); From eca80e68f102b5206706249b268c0073b517213b Mon Sep 17 00:00:00 2001 From: Steve Bauman Date: Thu, 13 Aug 2015 11:45:41 -0400 Subject: [PATCH 43/51] Working on 1.8, redoing tests --- composer.json | 10 +- src/Commands/InstallCommand.php | 40 -- src/Commands/RunMigrationsCommand.php | 32 - src/Commands/SchemaCheckCommand.php | 126 ---- src/Helper.php | 39 +- src/InventoryServiceProvider.php | 103 +--- src/Traits/InventoryStockTrait.php | 5 +- src/Traits/InventoryTrait.php | 35 +- src/Traits/InventoryTransactionTrait.php | 4 +- tests/FunctionalTestCase.php | 275 +-------- tests/InventoryAssemblyTest.php | 581 ------------------ tests/InventoryCategoryTest.php | 54 -- tests/InventorySkuTest.php | 307 --------- tests/InventoryStockTest.php | 259 -------- tests/InventoryTest.php | 166 ----- tests/InventoryVariantTest.php | 242 -------- .../InventoryTransactionBackOrderTest.php | 68 -- .../InventoryTransactionCancelledTest.php | 101 --- .../InventoryTransactionCheckoutTest.php | 225 ------- .../InventoryTransactionHoldTest.php | 64 -- .../InventoryTransactionOrderedTest.php | 85 --- .../InventoryTransactionReleaseTest.php | 85 --- .../InventoryTransactionRemoveTest.php | 94 --- .../InventoryTransactionReservedTest.php | 75 --- .../InventoryTransactionReturnedTest.php | 116 ---- .../InventoryTransactionSoldTest.php | 124 ---- .../Transactions/InventoryTransactionTest.php | 71 --- 27 files changed, 51 insertions(+), 3335 deletions(-) delete mode 100644 src/Commands/InstallCommand.php delete mode 100644 src/Commands/RunMigrationsCommand.php delete mode 100644 src/Commands/SchemaCheckCommand.php delete mode 100644 tests/InventoryAssemblyTest.php delete mode 100644 tests/InventoryCategoryTest.php delete mode 100644 tests/InventorySkuTest.php delete mode 100644 tests/InventoryStockTest.php delete mode 100644 tests/InventoryTest.php delete mode 100644 tests/InventoryVariantTest.php delete mode 100644 tests/Transactions/InventoryTransactionBackOrderTest.php delete mode 100644 tests/Transactions/InventoryTransactionCancelledTest.php delete mode 100644 tests/Transactions/InventoryTransactionCheckoutTest.php delete mode 100644 tests/Transactions/InventoryTransactionHoldTest.php delete mode 100644 tests/Transactions/InventoryTransactionOrderedTest.php delete mode 100644 tests/Transactions/InventoryTransactionReleaseTest.php delete mode 100644 tests/Transactions/InventoryTransactionRemoveTest.php delete mode 100644 tests/Transactions/InventoryTransactionReservedTest.php delete mode 100644 tests/Transactions/InventoryTransactionReturnedTest.php delete mode 100644 tests/Transactions/InventoryTransactionSoldTest.php delete mode 100644 tests/Transactions/InventoryTransactionTest.php diff --git a/composer.json b/composer.json index 217e0451..9e10e841 100644 --- a/composer.json +++ b/composer.json @@ -11,16 +11,16 @@ "license": "MIT", "require": { "php": ">=5.4.0", - "illuminate/database": "4.* | 5.*", - "illuminate/support": "4.* | 5.*", - "baum/baum": "1.0.* | 1.1.*" + "illuminate/database": "5.*", + "illuminate/support": "5.*", + "baum/baum": "1.1.*" }, "require-dev": { "phpunit/phpunit": "4.*", "mockery/mockery": "0.9.*" }, "archive": { - "exclude": ["/tests"] + "exclude": ["/tests"] }, "autoload": { "psr-4": { @@ -30,7 +30,7 @@ "autoload-dev": { "psr-4": { - "Stevebauman\\Inventory\\Tests\\": "tests/" + "Stevebauman\\Inventory\\Tests\\": "tests/" } }, "minimum-stability": "stable" diff --git a/src/Commands/InstallCommand.php b/src/Commands/InstallCommand.php deleted file mode 100644 index 8f9552cb..00000000 --- a/src/Commands/InstallCommand.php +++ /dev/null @@ -1,40 +0,0 @@ -info('Checking Database Schema'); - - $this->call('inventory:check-schema'); - - $this->info('Running migrations'); - - $this->call('inventory:run-migrations'); - - $this->info('Inventory has been successfully installed'); - } -} diff --git a/src/Commands/RunMigrationsCommand.php b/src/Commands/RunMigrationsCommand.php deleted file mode 100644 index 5a011649..00000000 --- a/src/Commands/RunMigrationsCommand.php +++ /dev/null @@ -1,32 +0,0 @@ -call('migrate', [ - '--path' => 'vendor/stevebauman/inventory/src/migrations', - ]); - } -} diff --git a/src/Commands/SchemaCheckCommand.php b/src/Commands/SchemaCheckCommand.php deleted file mode 100644 index b550c02f..00000000 --- a/src/Commands/SchemaCheckCommand.php +++ /dev/null @@ -1,126 +0,0 @@ - 'Sentry, Sentinel or Laravel', - ]; - - /** - * Holds the reserved database tables that - * cannot exist before installation. - * - * @var array - */ - protected $reserved = [ - 'metrics', - 'locations', - 'categories', - 'suppliers', - 'inventory', - 'inventory_skus', - 'inventory_stocks', - 'inventory_stock_movements', - 'inventory_suppliers', - 'inventory_transactions', - 'inventory_transaction_histories', - 'inventory_assemblies', - ]; - - /** - * Executes the console command. - * - * @throws DatabaseTableReservedException - * @throws DependencyNotFoundException - */ - public function fire() - { - if ($this->checkDependencies()) { - $this->info('Schema dependencies are all good!'); - } - - if ($this->checkReserved()) { - $this->info('Schema reserved tables are all good!'); - } - } - - /** - * Checks the current database for dependencies. - * - * @throws DependencyNotFoundException - * - * @return bool - */ - private function checkDependencies() - { - foreach ($this->dependencies as $table => $suppliedBy) { - if (!$this->tableExists($table)) { - $message = sprintf('Table: %s does not exist, it is supplied by %s', $table, $suppliedBy); - - throw new DependencyNotFoundException($message); - } - } - - return true; - } - - /** - * Checks the current database for reserved tables. - * - * @throws DatabaseTableReservedException - * - * @return bool - */ - private function checkReserved() - { - foreach ($this->reserved as $table) { - if ($this->tableExists($table)) { - $message = sprintf('Table: %s already exists. This table is reserved. Please remove the database table to continue', $table); - - throw new DatabaseTableReservedException($message); - } - } - - return true; - } - - /** - * Returns true / false if the current - * database table exists. - * - * @param string $table - * - * @return bool - */ - private function tableExists($table) - { - return Schema::hasTable($table); - } -} diff --git a/src/Helper.php b/src/Helper.php index f178e723..e89bc793 100644 --- a/src/Helper.php +++ b/src/Helper.php @@ -3,45 +3,12 @@ namespace Stevebauman\Inventory; use Stevebauman\Inventory\Exceptions\NoUserLoggedInException; -use Illuminate\Database\Eloquent\Model; use Illuminate\Support\Facades\Auth; use Illuminate\Support\Facades\Config; use Illuminate\Support\Facades\Lang; class Helper { - /** - * Returns a single lined path for a baum node. - * - * @param Model $node - * - * @return string - */ - public function renderNode(Model $node) - { - $html = ''; - - if (is_object($node)) { - $ancestors = $node->getAncestorsAndSelf(); - - foreach ($ancestors as $ancestor) { - if ($node->equals($ancestor) && $node->isRoot()) { - $html .= sprintf('%s', $ancestor->name); - } elseif ($node->equals($ancestor)) { - $html .= sprintf(' > %s', $ancestor->name); - } elseif ($ancestor->isRoot()) { - $html .= sprintf('%s', $ancestor->name); - } else { - $html .= sprintf(' > %s', $ancestor->name); - } - } - - return $html; - } - - return $node; - } - /** * Attempt to find the user id of the currently logged in user * Supports Cartalyst Sentry/Sentinel based authentication, as well as stock Auth. @@ -52,11 +19,9 @@ public function renderNode(Model $node) */ public static function getCurrentUserId() { - $separator = InventoryServiceProvider::$packageConfigSeparator; - // Check if we're allowed to return no user ID to the model, if so we'll return null. - if (Config::get('inventory'.$separator.'allow_no_user')) { - return; + if (Config::get('inventory.allow_no_user', false)) { + return null; } // Accountability is enabled, let's try and retrieve the current users ID. diff --git a/src/InventoryServiceProvider.php b/src/InventoryServiceProvider.php index 89a8ed56..5d0adb75 100644 --- a/src/InventoryServiceProvider.php +++ b/src/InventoryServiceProvider.php @@ -4,9 +4,6 @@ use Illuminate\Support\ServiceProvider; -/** - * Class InventoryServiceProvider. - */ class InventoryServiceProvider extends ServiceProvider { /** @@ -14,23 +11,7 @@ class InventoryServiceProvider extends ServiceProvider * * @var string */ - const VERSION = '1.7.5'; - - /** - * Stores the package configuration separator - * for Laravel 5 compatibility. - * - * @var string - */ - public static $packageConfigSeparator = '::'; - - /** - * The laravel version number. This is - * used for the install commands. - * - * @var int - */ - public static $laravelVersion = 4; + const VERSION = '1.8.0'; /** * Indicates if loading of the provider is deferred. @@ -44,79 +25,23 @@ class InventoryServiceProvider extends ServiceProvider */ public function boot() { - /* - * If the package method exists, we're using Laravel 4, if not, we're on 5 - */ - if (method_exists($this, 'package')) { - $this->package('stevebauman/inventory', 'stevebauman/inventory', __DIR__.'/..'); - } else { - /* - * Set the proper configuration separator since - * retrieving configuration values in packages - * changed from '::' to '.' - */ - $this::$packageConfigSeparator = '.'; - - /* - * Set the local inventory laravel version for easy checking - */ - $this::$laravelVersion = 5; - - /* - * Load the inventory translations from the inventory lang folder - */ - $this->loadTranslationsFrom(__DIR__.'/lang', 'inventory'); - - /* - * Assign the configuration as publishable, and tag it as 'config' - */ - $this->publishes([ - __DIR__.'/config/config.php' => config_path('inventory.php'), - ], 'config'); - - /* - * Assign the migrations as publishable, and tag it as 'migrations' - */ - $this->publishes([ - __DIR__.'/migrations/' => base_path('database/migrations'), - ], 'migrations'); - } + // Load the inventory translations from the inventory lang folder + $this->loadTranslationsFrom(__DIR__.'/Lang', 'inventory'); + + // Assign the configuration as publishable, and tag it as 'config' + $this->publishes([ + __DIR__.'/Config/config.php' => config_path('inventory.php'), + ], 'config'); + + // Assign the migrations as publishable, and tag it as 'migrations' + $this->publishes([ + __DIR__.'/Migrations/' => base_path('database/migrations'), + ], 'migrations'); } - /** - * Register the service provider. - */ public function register() { - /* - * Bind the install command - */ - $this->app->bind('inventory:install', function () { - return new Commands\InstallCommand(); - }); - - /* - * Bind the check-schema command - */ - $this->app->bind('inventory:check-schema', function () { - return new Commands\SchemaCheckCommand(); - }); - - /* - * Bind the run migrations command - */ - $this->app->bind('inventory:run-migrations', function () { - return new Commands\RunMigrationsCommand(); - }); - - /* - * Register the commands - */ - $this->commands([ - 'inventory:install', - 'inventory:check-schema', - 'inventory:run-migrations', - ]); + // } /** diff --git a/src/Traits/InventoryStockTrait.php b/src/Traits/InventoryStockTrait.php index d28708dd..b6257430 100644 --- a/src/Traits/InventoryStockTrait.php +++ b/src/Traits/InventoryStockTrait.php @@ -2,7 +2,6 @@ namespace Stevebauman\Inventory\Traits; -use Stevebauman\Inventory\InventoryServiceProvider; use Stevebauman\Inventory\Exceptions\NotEnoughStockException; use Stevebauman\Inventory\Exceptions\InvalidMovementException; use Stevebauman\Inventory\Exceptions\InvalidQuantityException; @@ -661,7 +660,7 @@ private function setReason($reason = '') */ private function allowDuplicateMovementsEnabled() { - return Config::get('inventory'.InventoryServiceProvider::$packageConfigSeparator.'allow_duplicate_movements'); + return Config::get('inventory.allow_duplicate_movements'); } /** @@ -673,6 +672,6 @@ private function allowDuplicateMovementsEnabled() */ private function rollbackCostEnabled() { - return Config::get('inventory'.InventoryServiceProvider::$packageConfigSeparator.'rollback_cost'); + return Config::get('inventory.rollback_cost'); } } diff --git a/src/Traits/InventoryTrait.php b/src/Traits/InventoryTrait.php index 3f520848..6c3e1a90 100644 --- a/src/Traits/InventoryTrait.php +++ b/src/Traits/InventoryTrait.php @@ -5,7 +5,6 @@ use Stevebauman\Inventory\Exceptions\SkuAlreadyExistsException; use Stevebauman\Inventory\Exceptions\StockNotFoundException; use Stevebauman\Inventory\Exceptions\StockAlreadyExistsException; -use Stevebauman\Inventory\InventoryServiceProvider; use Stevebauman\Inventory\Helper; use Illuminate\Database\Eloquent\Model; use Illuminate\Support\Facades\Config; @@ -519,38 +518,28 @@ public function generateSku() return $this->sku; } - $separator = InventoryServiceProvider::$packageConfigSeparator; - // Get the set SKU code length from the configuration file - $codeLength = Config::get('inventory'.$separator.'sku_code_length'); + $codeLength = Config::get('inventory.sku_code_length'); // Get the set SKU prefix length from the configuration file - $prefixLength = Config::get('inventory'.$separator.'sku_prefix_length'); + $prefixLength = Config::get('inventory.sku_prefix_length'); // Get the set SKU separator - $skuSeparator = Config::get('inventory'.$separator.'sku_separator'); + $skuSeparator = Config::get('inventory.sku_separator'); - /* - * Make sure we trim empty spaces in the separator - * if it's a string, otherwise we'll set it to NULL - */ + // Make sure we trim empty spaces in the separator if + // it's a string, otherwise we'll set it to NULL $skuSeparator = (is_string($skuSeparator) ? trim($skuSeparator) : null); - /* - * Trim the category name to remove blank spaces, then - * grab the first 3 letters of the string, and uppercase them - */ + // Trim the category name to remove blank spaces, then grab + // the first 3 letters of the string, and uppercase them $prefix = strtoupper(substr(trim($this->category->getAttribute('name')), 0, intval($prefixLength))); - /* - * We'll make sure the prefix length is greater - * than zero before we try and generate an SKU - */ + // We'll make sure the prefix length is greater + // than zero before we try and generate an SKU if (strlen($prefix) > 0) { - /* - * Create the numerical code by the items ID - * to accompany the prefix and pad left zeros - */ + // Create the numerical code by the items ID to + // accompany the prefix and pad left zeros $code = str_pad($this->getKey(), $codeLength, '0', STR_PAD_LEFT); // Return and process the generation @@ -726,6 +715,6 @@ private function processSkuUpdate(Model $sku, $code) */ private function skusEnabled() { - return Config::get('inventory'.InventoryServiceProvider::$packageConfigSeparator.'skus_enabled', false); + return Config::get('inventory.skus_enabled', false); } } diff --git a/src/Traits/InventoryTransactionTrait.php b/src/Traits/InventoryTransactionTrait.php index 5acb6711..0ae9cef7 100644 --- a/src/Traits/InventoryTransactionTrait.php +++ b/src/Traits/InventoryTransactionTrait.php @@ -1103,9 +1103,7 @@ public function getLastHistoryRecord() public function setQuantityAttribute($quantity) { if (!$this->isPositive($quantity)) { - $path = 'inventory'.InventoryServiceProvider::$packageConfigSeparator.'exceptions.InvalidQuantityException'; - - $message = Lang::get($path); + $message = Lang::get('inventory::exceptions.InvalidQuantityException'); throw new InvalidQuantityException($message); } diff --git a/tests/FunctionalTestCase.php b/tests/FunctionalTestCase.php index a1d13fc7..f6130dfc 100644 --- a/tests/FunctionalTestCase.php +++ b/tests/FunctionalTestCase.php @@ -2,279 +2,34 @@ namespace Stevebauman\Inventory\Tests; -use Illuminate\Database\Capsule\Manager as DB; +use Orchestra\Testbench\TestCase; -abstract class FunctionalTestCase extends \PHPUnit_Framework_TestCase +abstract class FunctionalTestCase extends TestCase { public function setUp() { parent::setUp(); - $this->configureDatabase(); - $this->migrateTables(); + $this->artisan('migrate', [ + '--database' => 'testbench', + '--realpath' => realpath(__DIR__.'/../src/Migrations'), + ]); } - private function configureDatabase() + protected function getEnvironmentSetup($app) { - $db = new DB(); - - $db->addConnection([ - 'driver' => 'sqlite', + $app['config']->set('database.default', 'testbench'); + $app['config']->set('database.connections.testbench', [ + 'driver' => 'sqlite', 'database' => ':memory:', - 'charset' => 'utf8', - 'collation' => 'utf8_unicode_ci', - 'prefix' => '', + 'prefix' => '', ]); - - $db->bootEloquent(); - - $db->setAsGlobal(); } - private function migrateTables() + protected function getPackageProviders() { - DB::schema()->create('users', function ($table) { - $table->increments('id'); - $table->string('name'); - }); - - DB::schema()->create('metrics', function ($table) { - $table->increments('id'); - $table->timestamps(); - $table->integer('user_id')->unsigned()->nullable(); - $table->string('name'); - $table->string('symbol'); - - $table->foreign('user_id')->references('id')->on('users') - ->onUpdate('restrict') - ->onDelete('set null'); - }); - - DB::schema()->create('categories', function ($table) { - $table->increments('id'); - $table->timestamps(); - $table->integer('parent_id')->nullable()->index(); - $table->integer('lft')->nullable()->index(); - $table->integer('rgt')->nullable()->index(); - $table->integer('depth')->nullable(); - $table->string('name'); - - /* - * This field is for scoping categories, use it if you - * want to store multiple nested sets on the same table - */ - $table->string('belongs_to')->nullable(); - }); - - DB::schema()->create('locations', function ($table) { - $table->increments('id'); - $table->timestamps(); - $table->integer('parent_id')->nullable()->index(); - $table->integer('lft')->nullable()->index(); - $table->integer('rgt')->nullable()->index(); - $table->integer('depth')->nullable(); - $table->string('name'); - - /* - * This field is for scoping categories, use it if you - * want to store multiple nested sets on the same table - */ - $table->string('belongs_to')->nullable(); - }); - - DB::schema()->create('inventories', function ($table) { - $table->increments('id'); - $table->timestamps(); - $table->softDeletes(); - $table->integer('category_id')->unsigned()->nullable(); - $table->integer('user_id')->unsigned()->nullable(); - $table->integer('metric_id')->unsigned(); - $table->string('name'); - $table->text('description')->nullable(); - - $table->foreign('category_id')->references('id')->on('categories') - ->onUpdate('restrict') - ->onDelete('set null'); - - $table->foreign('user_id')->references('id')->on('users') - ->onUpdate('restrict') - ->onDelete('set null'); - - $table->foreign('metric_id')->references('id')->on('metrics') - ->onUpdate('restrict') - ->onDelete('cascade'); - }); - - DB::schema()->create('inventory_stocks', function ($table) { - $table->increments('id'); - $table->timestamps(); - $table->integer('user_id')->unsigned()->nullable(); - $table->integer('inventory_id')->unsigned(); - $table->integer('location_id')->unsigned(); - $table->decimal('quantity', 8, 2)->default(0); - $table->string('aisle')->nullable(); - $table->string('row')->nullable(); - $table->string('bin')->nullable(); - - /* - * This allows only one stock to be created - * on a single location - */ - $table->unique(['inventory_id', 'location_id']); - - $table->foreign('user_id')->references('id')->on('users') - ->onUpdate('restrict') - ->onDelete('set null'); - - $table->foreign('inventory_id')->references('id')->on('inventories') - ->onUpdate('restrict') - ->onDelete('cascade'); - - $table->foreign('location_id')->references('id')->on('locations') - ->onUpdate('restrict') - ->onDelete('cascade'); - }); - - DB::schema()->create('inventory_stock_movements', function ($table) { - $table->increments('id'); - $table->timestamps(); - $table->integer('stock_id')->unsigned(); - $table->integer('user_id')->unsigned()->nullable(); - $table->decimal('before', 8, 2)->default(0); - $table->decimal('after', 8, 2)->default(0); - $table->decimal('cost', 8, 2)->default(0)->nullable(); - $table->string('reason')->nullable(); - - $table->foreign('stock_id')->references('id')->on('inventory_stocks') - ->onUpdate('restrict') - ->onDelete('cascade'); - - $table->foreign('user_id')->references('id')->on('users') - ->onUpdate('restrict') - ->onDelete('set null'); - }); - - DB::schema()->create('inventory_skus', function ($table) { - $table->increments('id'); - $table->timestamps(); - $table->integer('inventory_id')->unsigned(); - $table->string('code', 20); - - $table->foreign('inventory_id')->references('id')->on('inventories') - ->onUpdate('restrict') - ->onDelete('cascade'); - - /* - * Make sure each SKU is unique - */ - $table->unique(['code']); - }); - - DB::schema()->create('suppliers', function ($table) { - $table->increments('id'); - $table->timestamps(); - - $table->string('name'); - $table->string('address')->nullable(); - $table->string('postal_code')->nullable(); - $table->string('zip_code')->nullable(); - $table->string('region')->nullable(); - $table->string('city')->nullable(); - $table->string('country')->nullable(); - $table->string('contact_title')->nullable(); - $table->string('contact_name')->nullable(); - $table->string('contact_phone')->nullable(); - $table->string('contact_fax')->nullable(); - $table->string('contact_email')->nullable(); - }); - - DB::schema()->create('inventory_suppliers', function ($table) { - $table->increments('id'); - $table->timestamps(); - - $table->integer('inventory_id')->unsigned(); - $table->integer('supplier_id')->unsigned(); - - $table->foreign('inventory_id')->references('id')->on('inventories') - ->onUpdate('restrict') - ->onDelete('cascade'); - - $table->foreign('supplier_id')->references('id')->on('suppliers') - ->onUpdate('restrict') - ->onDelete('cascade'); - }); - - DB::schema()->create('inventory_transactions', function ($table) { - $table->increments('id'); - $table->timestamps(); - $table->integer('user_id')->unsigned()->nullable(); - $table->integer('stock_id')->unsigned(); - $table->string('name')->nullable(); - $table->string('state'); - $table->decimal('quantity', 8, 2)->default(0); - - $table->foreign('user_id')->references('id')->on('users') - ->onUpdate('restrict') - ->onDelete('set null'); - - $table->foreign('stock_id')->references('id')->on('inventory_stocks') - ->onUpdate('restrict') - ->onDelete('cascade'); - }); - - DB::schema()->create('inventory_transaction_histories', function ($table) { - $table->increments('id'); - $table->timestamps(); - $table->integer('user_id')->unsigned()->nullable(); - $table->integer('transaction_id')->unsigned(); - - /* - * Allows tracking states for each transaction - */ - $table->string('state_before'); - $table->string('state_after'); - - /* - * Allows tracking the quantities of each transaction - */ - $table->string('quantity_before'); - $table->string('quantity_after'); - - $table->foreign('user_id')->references('id')->on('users') - ->onUpdate('restrict') - ->onDelete('set null'); - - $table->foreign('transaction_id')->references('id')->on('inventory_transactions') - ->onUpdate('restrict') - ->onDelete('cascade'); - }); - - DB::schema()->table('inventories', function ($table) { - $table->integer('parent_id')->unsigned()->nullable()->after('id'); - - $table->foreign('parent_id')->references('id')->on('inventories') - ->onUpdate('restrict') - ->onDelete('cascade'); - }); - - DB::schema()->table('inventories', function ($table) { - $table->boolean('is_assembly')->default(false); - }); - - DB::schema()->create('inventory_assemblies', function ($table) { - - $table->increments('id'); - $table->timestamps(); - $table->integer('inventory_id')->unsigned(); - $table->integer('part_id')->unsigned(); - $table->integer('quantity')->nullable(); - - // Extra column for testing - $table->string('extra')->nullable(); - - $table->foreign('inventory_id')->references('id')->on('inventories')->onDelete('cascade'); - $table->foreign('part_id')->references('id')->on('inventories')->onDelete('cascade'); - - }); + return [ + 'Inventory' => 'Stevebauman\Inventory\InventoryServiceProvider', + ]; } } diff --git a/tests/InventoryAssemblyTest.php b/tests/InventoryAssemblyTest.php deleted file mode 100644 index 95672180..00000000 --- a/tests/InventoryAssemblyTest.php +++ /dev/null @@ -1,581 +0,0 @@ -newInventory(); - - DB::shouldReceive('beginTransaction')->once()->andReturn(true); - DB::shouldReceive('commit')->once()->andReturn(true); - - Event::shouldReceive('fire')->once()->andReturn(true); - - $item->makeAssembly(); - - $this->assertTrue($item->is_assembly); - } - - public function testAddAssemblyItem() - { - $item = $this->newInventory(); - - $childItem = $this->newInventory([ - 'name' => 'Child Item', - 'metric_id' => $item->metric_id, - 'category_id' => $item->category_id, - ]); - - Cache::shouldReceive('forget')->once()->andReturn(true); - - $item->addAssemblyItem($childItem, 10); - - $items = $item->assemblies; - - $this->assertEquals('Child Item', $items->first()->name); - $this->assertEquals(10, $items->first()->pivot->quantity); - } - - public function testAddAssemblyItems() - { - $item = $this->newInventory(); - - $childItem = $this->newInventory([ - 'name' => 'Child Item', - 'metric_id' => $item->metric_id, - 'category_id' => $item->category_id, - ]); - - $childItem2 = $this->newInventory([ - 'name' => 'Child Item 2', - 'metric_id' => $item->metric_id, - 'category_id' => $item->category_id, - ]); - - Cache::shouldReceive('forget')->twice()->andReturn(true); - - $item->addAssemblyItems([$childItem, $childItem2], 10); - - $items = $item->assemblies; - - $this->assertEquals('Child Item', $items->get(0)->name); - $this->assertEquals(10, $items->get(0)->pivot->quantity); - - $this->assertEquals('Child Item 2', $items->get(1)->name); - $this->assertEquals(10, $items->get(1)->pivot->quantity); - } - - public function testAddSameAssemblyItems() - { - $item = $this->newInventory(); - - $childItem = $this->newInventory([ - 'name' => 'Child Item', - 'metric_id' => $item->metric_id, - 'category_id' => $item->category_id, - ]); - - Cache::shouldReceive('forget')->twice()->andReturn(true); - - $item->addAssemblyItems([$childItem, $childItem]); - - Cache::shouldReceive('has')->once()->andReturn(false); - Cache::shouldReceive('forever')->once()->andReturn(true); - - $this->assertEquals(2, $item->getAssemblyItems()->count()); - } - - public function testAddAssemblyItemExtraAttributes() - { - $item = $this->newInventory(); - - $childItem = $this->newInventory([ - 'name' => 'Child Item', - 'metric_id' => $item->metric_id, - 'category_id' => $item->category_id, - ]); - - Cache::shouldReceive('forget')->once()->andReturn(true); - - $item->addAssemblyItem($childItem, 10, ['extra' => 'testing']); - - /* - * Tests that the extra array is merged - * and updated successfully with the quantity - */ - $this->assertEquals(10, $item->assemblies()->first()->pivot->quantity); - } - - public function testAddInvalidAssemblyItem() - { - $item = $this->newInventory(); - - try { - $item->addAssemblyItem('invalid item'); - - $passes = false; - } catch (\Exception $e) { - $passes = true; - } - - $this->assertTrue($passes); - } - - public function testAddInvalidQuantityWithAssemblyItem() - { - $item = $this->newInventory(); - - $childItem = $this->newInventory([ - 'name' => 'Child Item', - 'metric_id' => $item->metric_id, - 'category_id' => $item->category_id, - ]); - - Lang::shouldReceive('get')->once()->andReturn('Invalid Quantity'); - - $this->setExpectedException('Stevebauman\Inventory\Exceptions\InvalidQuantityException'); - - $item->addAssemblyItem($childItem, 'invalid quantity'); - } - - public function testUpdateAssemblyItem() - { - $item = $this->newInventory(); - - $childItem = $this->newInventory([ - 'name' => 'Child Item', - 'metric_id' => $item->metric_id, - 'category_id' => $item->category_id, - ]); - - Cache::shouldReceive('forget')->times(3)->andReturn(true); - - $item->addAssemblyItem($childItem); - - $item->updateAssemblyItem($childItem, 5); - - $this->assertEquals(5, $item->assemblies()->first()->pivot->quantity); - - $item->updateAssemblyItem($childItem->id, 10); - - $this->assertEquals(10, $item->assemblies()->first()->pivot->quantity); - } - - public function testUpdateAssemblyItems() - { - $item = $this->newInventory(); - - $childItem = $this->newInventory([ - 'name' => 'Child Item', - 'metric_id' => $item->metric_id, - 'category_id' => $item->category_id, - ]); - - $childItem2 = $this->newInventory([ - 'name' => 'Child Item 2', - 'metric_id' => $item->metric_id, - 'category_id' => $item->category_id, - ]); - - Cache::shouldReceive('forget')->times(4)->andReturn(true); - - $item->addAssemblyItem($childItem); - $item->addAssemblyItem($childItem2); - - $item->updateAssemblyItems([$childItem, $childItem2], 10); - - $items = $item->assemblies()->get(); - - $this->assertEquals(10, $items->get(0)->pivot->quantity); - $this->assertEquals(10, $items->get(1)->pivot->quantity); - } - - public function testUpdateInvalidQuantityWithAssemblyItem() - { - $item = $this->newInventory(); - - $childItem = $this->newInventory([ - 'name' => 'Child Item', - 'metric_id' => $item->metric_id, - 'category_id' => $item->category_id, - ]); - - $this->setExpectedException('Stevebauman\Inventory\Exceptions\InvalidQuantityException'); - - $item->addAssemblyItem($childItem, 'invalid quantity'); - } - - public function testUpdateAssemblyItemWhenItemIsNotAnAssembly() - { - $item = $this->newInventory(); - - $this->assertFalse($item->updateAssemblyItem(1, 5)); - } - - public function testUpdateAssemblyItemsWhenItemIsNotAnAssembly() - { - $item = $this->newInventory(); - - $this->assertEquals(0, $item->updateAssemblyItems([1, 2], 5)); - } - - public function testGetAssemblies() - { - $metric = $this->newMetric(); - - $category = $this->newCategory(); - - $table = $this->newInventory([ - 'name' => 'Table', - 'metric_id' => $metric->id, - 'category_id' => $category->id, - ]); - - $tableTop = $this->newInventory([ - 'name' => 'Table Top', - 'metric_id' => $table->metric_id, - 'category_id' => $table->category_id, - ]); - - $tableLegs = $this->newInventory([ - 'name' => 'Table Legs', - 'metric_id' => $table->metric_id, - 'category_id' => $table->category_id, - ]); - - Cache::shouldReceive('forget')->twice()->andReturn(true); - - $table->addAssemblyItem($tableTop, 1); - $table->addAssemblyItem($tableLegs, 4); - - $items = $table->assemblies; - - $this->assertEquals(2, $items->count()); - - $this->assertEquals('Table Top', $items->get(0)->name); - $this->assertEquals(1, $items->get(0)->pivot->quantity); - - $this->assertEquals('Table Legs', $items->get(1)->name); - $this->assertEquals(4, $items->get(1)->pivot->quantity); - - $this->assertNull($items->get(2)); - } - - public function testGetAssembliesRecursive() - { - $metric = $this->newMetric(); - - $category = $this->newCategory(); - - $table = $this->newInventory([ - 'name' => 'Table', - 'metric_id' => $metric->id, - 'category_id' => $category->id, - ]); - - $tableTop = $this->newInventory([ - 'name' => 'Table Top', - 'metric_id' => $table->metric_id, - 'category_id' => $table->category_id, - ]); - - $tableLegs = $this->newInventory([ - 'name' => 'Table Legs', - 'metric_id' => $table->metric_id, - 'category_id' => $table->category_id, - ]); - - $screws = $this->newInventory([ - 'name' => 'Screws', - 'metric_id' => $table->metric_id, - 'category_id' => $table->category_id, - ]); - - Cache::shouldReceive('forget')->times(4)->andReturn(true); - - $table->addAssemblyItem($tableTop, 1); - $table->addAssemblyItem($tableLegs, 4); - - $tableTop->addAssemblyItem($screws, 1); - $tableLegs->addAssemblyItem($screws, 2); - - Cache::shouldReceive('has')->once()->andReturn(false); - Cache::shouldReceive('forever')->once()->andReturn(true); - - $items = $table->getAssemblyItems(); - - $this->assertEquals(2, $items->count()); - - $this->assertEquals('Table Top', $items->get(0)->name); - $this->assertEquals(1, $items->get(0)->pivot->quantity); - - $this->assertEquals('Table Legs', $items->get(1)->name); - $this->assertEquals(4, $items->get(1)->pivot->quantity); - - // One screw item exists on each model - $this->assertEquals(1, $items->get(0)->assemblies->count()); - $this->assertEquals(1, $items->get(1)->assemblies->count()); - - // One screw for table top - $this->assertEquals('Screws', $items->get(0)->assemblies->get(0)->name); - $this->assertEquals(1, $items->get(0)->assemblies->get(0)->pivot->quantity); - - // Two screws for table legs - $this->assertEquals('Screws', $items->get(1)->assemblies->get(0)->name); - $this->assertEquals(2, $items->get(1)->assemblies->get(0)->pivot->quantity); - } - - public function testGetAssemblyItemsCached() - { - $item = $this->newInventory(); - - Cache::shouldReceive('has')->once()->andReturn(true); - Cache::shouldReceive('get')->once()->andReturn('cached items'); - - $this->assertEquals('cached items', $item->getAssemblyItems()); - } - - public function testRemoveAssemblyItem() - { - $metric = $this->newMetric(); - - $category = $this->newCategory(); - - $table = $this->newInventory([ - 'name' => 'Table', - 'metric_id' => $metric->id, - 'category_id' => $category->id, - ]); - - $tableTop = $this->newInventory([ - 'name' => 'Table Top', - 'metric_id' => $table->metric_id, - 'category_id' => $table->category_id, - ]); - - Cache::shouldReceive('forget')->twice()->andReturn(true); - - $table->addAssemblyItem($tableTop, 1); - - $this->assertTrue($table->removeAssemblyItem($tableTop)); - - $this->assertNull($table->assemblies->first()); - } - - public function testRemoveAssemblyItemWhenItemIsNotAnAssembly() - { - $item = $this->newInventory(); - - $this->assertFalse($item->removeAssemblyItem(1)); - } - - public function testRemoveAssemblyItemsWhenItemIsNotAnAssembly() - { - $item = $this->newInventory(); - - $this->assertEquals(0, $item->removeAssemblyItems([1, 2])); - } - - public function testGetAssemblyItemsList() - { - $metric = $this->newMetric(); - - $category = $this->newCategory(); - - $table = $this->newInventory([ - 'name' => 'Table', - 'metric_id' => $metric->id, - 'category_id' => $category->id, - ]); - - $tableTop = $this->newInventory([ - 'name' => 'Table Top', - 'metric_id' => $table->metric_id, - 'category_id' => $table->category_id, - ]); - - $tableLegs = $this->newInventory([ - 'name' => 'Table Legs', - 'metric_id' => $table->metric_id, - 'category_id' => $table->category_id, - ]); - - $screws = $this->newInventory([ - 'name' => 'Screws', - 'metric_id' => $table->metric_id, - 'category_id' => $table->category_id, - ]); - - $metal = $this->newInventory([ - 'name' => 'Metal', - 'metric_id' => $table->metric_id, - 'category_id' => $table->category_id, - ]); - - $ore = $this->newInventory([ - 'name' => 'Ore', - 'metric_id' => $table->metric_id, - 'category_id' => $table->category_id, - ]); - - $flux = $this->newInventory([ - 'name' => 'Flux', - 'metric_id' => $table->metric_id, - 'category_id' => $table->category_id, - ]); - - Cache::shouldReceive('forget')->times(7)->andReturn(true); - - $table->addAssemblyItem($tableTop, 1); - $table->addAssemblyItem($tableLegs, 4); - - $tableTop->addAssemblyItem($screws, 1); - $tableLegs->addAssemblyItem($screws, 2); - - $screws->addAssemblyItem($metal, 5); - - $metal->addAssemblyItem($ore, 10); - $metal->addAssemblyItem($flux, 5); - - Cache::shouldReceive('has')->once()->andReturn(false); - Cache::shouldReceive('forever')->once()->andReturn(true); - - $list = $table->getAssemblyItemsList(); - - $this->assertEquals('Table Top', $list[0]['name']); - $this->assertEquals('Table Legs', $list[1]['name']); - - // Validate Table Top / Table Leg Depth - $this->assertEquals(1, $list[0]['depth']); - $this->assertEquals(1, $list[1]['depth']); - - $this->assertEquals('Screws', $list[0]['parts'][0]['name']); - $this->assertEquals('Screws', $list[1]['parts'][0]['name']); - - // Validate Screw Depth - $this->assertEquals(2, $list[0]['parts'][0]['depth']); - $this->assertEquals(2, $list[1]['parts'][0]['depth']); - - $this->assertEquals('Metal', $list[0]['parts'][0]['parts'][0]['name']); - $this->assertEquals('Metal', $list[1]['parts'][0]['parts'][0]['name']); - - // Validate Metal Depth - $this->assertEquals(3, $list[0]['parts'][0]['parts'][0]['depth']); - $this->assertEquals(3, $list[1]['parts'][0]['parts'][0]['depth']); - - $this->assertEquals('Ore', $list[0]['parts'][0]['parts'][0]['parts'][0]['name']); - $this->assertEquals('Ore', $list[1]['parts'][0]['parts'][0]['parts'][0]['name']); - - // Validate Ore Depth - $this->assertEquals(4, $list[0]['parts'][0]['parts'][0]['parts'][0]['depth']); - $this->assertEquals(4, $list[1]['parts'][0]['parts'][0]['parts'][0]['depth']); - } - - public function testInvalidPartException() - { - $metric = $this->newMetric(); - - $category = $this->newCategory(); - - $table = $this->newInventory([ - 'name' => 'Table', - 'metric_id' => $metric->id, - 'category_id' => $category->id, - ]); - - $this->setExpectedException('Stevebauman\Inventory\Exceptions\InvalidPartException'); - - $table->addAssemblyItem($table); - } - - public function testNestedInvalidPartException() - { - $metric = $this->newMetric(); - - $category = $this->newCategory(); - - $table = $this->newInventory([ - 'name' => 'Table', - 'metric_id' => $metric->id, - 'category_id' => $category->id, - ]); - - $tableTop = $this->newInventory([ - 'name' => 'Table Top', - 'metric_id' => $table->metric_id, - 'category_id' => $table->category_id, - ]); - - $tableLegs = $this->newInventory([ - 'name' => 'Table Legs', - 'metric_id' => $table->metric_id, - 'category_id' => $table->category_id, - ]); - - $screws = $this->newInventory([ - 'name' => 'Screws', - 'metric_id' => $table->metric_id, - 'category_id' => $table->category_id, - ]); - - $metal = $this->newInventory([ - 'name' => 'Metal', - 'metric_id' => $table->metric_id, - 'category_id' => $table->category_id, - ]); - - Cache::shouldReceive('forget')->times(5)->andReturn(true); - - $table->addAssemblyItem($tableTop, 1); - $table->addAssemblyItem($tableLegs, 4); - - $tableTop->addAssemblyItem($screws, 1); - $tableLegs->addAssemblyItem($screws, 2); - - $screws->addAssemblyItem($metal, 5); - - $this->setExpectedException('Stevebauman\Inventory\Exceptions\InvalidPartException'); - - /* - * Since metal is already apart of screws, - * adding table as an assembly item of metal - * would cause an infinite recursive query - */ - $metal->addAssemblyItem($table); - } - - public function testHasCachedAssemblyItems() - { - $item = $this->newInventory(); - - Cache::shouldReceive('has')->once()->andReturn(false); - - $this->assertFalse($item->hasCachedAssemblyItems()); - } - - public function testGetCachedAssemblyItems() - { - $item = $this->newInventory(); - - Cache::shouldReceive('has')->once()->andReturn(true); - Cache::shouldReceive('get')->once()->andReturn('cached items'); - - $this->assertEquals('cached items', $item->getCachedAssemblyItems()); - } - - public function testForgetCachedAssemblyItems() - { - $item = $this->newInventory(); - - Cache::shouldReceive('forget')->once()->andReturn(true); - - $this->assertTrue($item->forgetCachedAssemblyItems()); - } -} \ No newline at end of file diff --git a/tests/InventoryCategoryTest.php b/tests/InventoryCategoryTest.php deleted file mode 100644 index 545c2d16..00000000 --- a/tests/InventoryCategoryTest.php +++ /dev/null @@ -1,54 +0,0 @@ -name = 'Test Metric'; - $metric->symbol = 'Test Symbol'; - $metric->save(); - - $productsCategory = Category::create([ - 'name' => 'Products', - 'belongs_to' => 'Products' - ]); - - $miscCategory = Category::create([ - 'name' => 'Misc', - 'belongs_to' => 'Misc', - ]); - - $noItemCategory = Category::create([ - 'name' => 'No Items', - ]); - - $productItem = Inventory::create([ - 'name' => '', - 'category_id' => $productsCategory->id, - 'metric_id' => $metric->id, - ]); - - $miscItem = Inventory::create([ - 'name' => 'Item 1', - 'category_id' => $miscCategory->id, - 'metric_id' => $metric->id, - ]); - - $miscItem2 = Inventory::create([ - 'name' => 'Item 2', - 'category_id' => $miscCategory->id, - 'metric_id' => $metric->id, - ]); - - $this->assertEquals(0, $noItemCategory->inventories()->count()); - $this->assertEquals(1, $productsCategory->inventories()->count()); - $this->assertEquals(2, $miscCategory->inventories()->count()); - } -} \ No newline at end of file diff --git a/tests/InventorySkuTest.php b/tests/InventorySkuTest.php deleted file mode 100644 index e01e3b34..00000000 --- a/tests/InventorySkuTest.php +++ /dev/null @@ -1,307 +0,0 @@ -newInventory(); - - return $item->generateSku(); - } - - public function testInventorySkuGeneration() - { - /* - * SKU generation is enabled - */ - Config::shouldReceive('get')->once()->andReturn(true); - - /* - * SKU code limit - */ - Config::shouldReceive('get')->once()->andReturn(6); - - /* - * SKU prefix limit - */ - Config::shouldReceive('get')->once()->andReturn(3); - - /* - * SKU separator - */ - Config::shouldReceive('get')->once()->andReturn(''); - - DB::shouldReceive('beginTransaction')->once()->shouldReceive('commit')->once(); - - Event::shouldReceive('fire')->once(); - - $sku = $this->newInventorySku(); - - $this->assertEquals(1, $sku->inventory_id); - $this->assertEquals('DRI000001', $sku->code); - } - - public function testInventorySkuGenerationForSmallCategoryName() - { - $item = $this->newInventory(); - - $category = Category::find(1); - - $update = [ - 'name' => 'D', - ]; - - $category->update($update); - - /* - * SKU generation is enabled - */ - Config::shouldReceive('get')->once()->andReturn(true); - - /* - * SKU code limit - */ - Config::shouldReceive('get')->once()->andReturn(6); - - /* - * SKU prefix limit - */ - Config::shouldReceive('get')->once()->andReturn(3); - - /* - * SKU separator - */ - Config::shouldReceive('get')->once()->andReturn(''); - - /* - * Generate the SKU - */ - $item->generateSku(); - - /* - * Get the sku code - */ - $sku = $item->sku()->first()->code; - - $this->assertEquals('D000001', $sku); - } - - public function testInventorySkuRegeneration() - { - $this->newInventorySku(); - - $item = Inventory::find(1); - - /* - * SKU code limit - */ - Config::shouldReceive('get')->once()->andReturn(6); - - /* - * SKU prefix limit - */ - Config::shouldReceive('get')->once()->andReturn(3); - - DB::shouldReceive('beginTransaction')->once()->shouldReceive('commit')->once(); - - $item->regenerateSku(); - - $sku = InventorySku::first(); - - $this->assertEquals($sku->id, 2); - } - - public function testInventoryHasSku() - { - $this->newInventorySku(); - - $item = Inventory::find(1); - - $this->assertTrue($item->hasSku()); - } - - public function testInventoryDoesNotHaveSku() - { - $this->newInventorySku(); - - $sku = InventorySku::first(); - $sku->delete(); - - $item = Inventory::find(1); - - $this->assertFalse($item->hasSku()); - } - - public function testInventorySkuGenerationFalse() - { - $item = $this->newInventory(); - - $item->category_id = null; - $item->save(); - - $this->assertFalse($item->generateSku()); - } - - public function testInventoryGetSku() - { - $this->testInventorySkuGeneration(); - - $item = Inventory::find(1); - - $expected = 'DRI000001'; - - $this->assertEquals($expected, $item->sku->code); - $this->assertEquals($expected, $item->getSku()); - } - - public function testInventoryFindBySku() - { - $this->testInventorySkuGeneration(); - - $item = Inventory::findBySku('DRI000001'); - - $this->assertEquals('Milk', $item->name); - } - - public function testInventorySkuBlankCategoryName() - { - $this->testInventorySkuGeneration(); - - $category = Category::find(1); - - $category->update(['name' => ' ']); - - $item = Inventory::find(1); - - /* - * SKU generation is enabled - */ - Config::shouldReceive('get')->once()->andReturn(true); - - /* - * SKU code limit - */ - Config::shouldReceive('get')->once()->andReturn(6); - - /* - * SKU prefix limit - */ - Config::shouldReceive('get')->once()->andReturn(3); - - /* - * SKU separator - */ - Config::shouldReceive('get')->once()->andReturn(''); - - $sku = $item->regenerateSku(); - - /* - * SKU generation will fail and the previous will be restored - * with new ID - */ - $this->assertEquals(2, $sku->id); - $this->assertEquals('DRI000001', $sku->code); - } - - public function testInventorySkuSeparator() - { - $this->testInventorySkuGeneration(); - - /* - * SKU generation is enabled - */ - Config::shouldReceive('get')->once()->andReturn(true); - - /* - * SKU code limit - */ - Config::shouldReceive('get')->once()->andReturn(6); - - /* - * SKU prefix limit - */ - Config::shouldReceive('get')->once()->andReturn(3); - - /* - * SKU separator - */ - Config::shouldReceive('get')->once()->andReturn('-'); - - $item = Inventory::find(1); - - $sku = $item->regenerateSku(); - - $this->assertEquals(2, $sku->id); - $this->assertEquals('DRI-000001', $sku->code); - } - - public function testInventorySkuCreateSku() - { - $item = $this->newInventory(); - - $sku = $item->createSku('TESTING'); - - $this->assertEquals(1, $sku->inventory_id); - $this->assertEquals('TESTING', $sku->code); - } - - public function testInventorySkuCreateSkuOverwrite() - { - $item = $this->newInventory(); - - $item->createSku('TESTING'); - - $newSku = $item->createSku('TESTING-RESTORE', true); - - $this->assertEquals(1, $newSku->id); - $this->assertEquals(1, $newSku->inventory_id); - $this->assertEquals('TESTING-RESTORE', $newSku->code); - } - - public function testsInventorySkuUpdate() - { - $item = $this->newInventory(); - - $item->createSku('TESTING'); - - $sku = $item->updateSku('TESTING-UPDATE'); - - $this->assertEquals(1, $sku->id); - $this->assertEquals(1, $sku->inventory_id); - $this->assertEquals('TESTING-UPDATE', $sku->code); - } - - public function testInventorySkuUpdateCreate() - { - $item = $this->newInventory(); - - $sku = $item->updateSku('TESTING-UPDATE-CREATE'); - - $this->assertEquals(1, $sku->id); - $this->assertEquals(1, $sku->inventory_id); - $this->assertEquals('TESTING-UPDATE-CREATE', $sku->code); - } - - public function testInventorySkuCreateSkuAlreadyExistsException() - { - $this->newInventorySku(); - - $item = Inventory::find(1); - - Lang::shouldReceive('get')->once()->andReturn('Failed'); - - $this->setExpectedException('Stevebauman\Inventory\Exceptions\SkuAlreadyExistsException'); - - $item->createSku('test'); - } -} diff --git a/tests/InventoryStockTest.php b/tests/InventoryStockTest.php deleted file mode 100644 index 1e8d0d3c..00000000 --- a/tests/InventoryStockTest.php +++ /dev/null @@ -1,259 +0,0 @@ -newInventory(); - - $location = $this->newLocation(); - - $stock = new InventoryStock(); - $stock->inventory_id = $item->id; - $stock->location_id = $location->id; - $stock->quantity = 20; - $stock->cost = '5.20'; - $stock->reason = 'I bought some'; - $stock->save(); - - return $stock; - } - - public function testInventoryStockCreation() - { - $stock = $this->newInventoryStock(); - - $this->assertEquals(20, $stock->quantity); - } - - public function testStockPut() - { - $stock = $this->newInventoryStock(); - - DB::shouldReceive('beginTransaction')->once()->shouldReceive('commit')->once(); - Event::shouldReceive('fire')->once(); - - $stock->put(10, 'Added some', 15); - - $this->assertEquals(30, $stock->quantity); - } - - public function testStockTake() - { - $stock = $this->newInventoryStock(); - - DB::shouldReceive('beginTransaction')->once()->shouldReceive('commit')->once(); - Event::shouldReceive('fire')->once(); - - $stock->take(10, 'Removed some', 15); - - $this->assertEquals(10, $stock->quantity); - $this->assertEquals('Removed some', $stock->reason); - $this->assertEquals(15, $stock->cost); - } - - public function testStockMove() - { - $stock = $this->newInventoryStock(); - - $newLocation = Location::create([ - 'name' => 'New Location', - ]); - - DB::shouldReceive('beginTransaction')->once()->shouldReceive('commit')->once(); - Event::shouldReceive('fire')->once(); - - $stock->moveTo($newLocation); - - $this->assertEquals(2, $stock->location_id); - } - - public function testStockIsValidQuantitySuccess() - { - $stock = $this->newInventoryStock(); - - $this->assertTrue($stock->isValidQuantity(500)); - $this->assertTrue($stock->isValidQuantity(5, 000)); - $this->assertTrue($stock->isValidQuantity('500')); - $this->assertTrue($stock->isValidQuantity('500.00')); - $this->assertTrue($stock->isValidQuantity('500.0')); - $this->assertTrue($stock->isValidQuantity('1.500')); - $this->assertTrue($stock->isValidQuantity('15000000')); - } - - public function testStockIsValidQuantityFailure() - { - $stock = $this->newInventoryStock(); - - $this->setExpectedException('Stevebauman\Inventory\Exceptions\InvalidQuantityException'); - - $stock->isValidQuantity('40a'); - $stock->isValidQuantity('5,000'); - $stock->isValidQuantity('5.000.00'); - } - - public function testInvalidMovementException() - { - $stock = $this->newInventoryStock(); - - Lang::shouldReceive('get')->once(); - - $this->setExpectedException('Stevebauman\Inventory\Exceptions\InvalidMovementException'); - - $stock->getMovement('testing'); - } - - public function testUpdateStockQuantity() - { - $stock = $this->newInventoryStock(); - - $stock->updateQuantity(10); - - $this->assertEquals(10, $stock->quantity); - } - - public function testUpdateStockQuantityFailure() - { - $stock = $this->newInventoryStock(); - - $this->setExpectedException('Stevebauman\Inventory\Exceptions\InvalidQuantityException'); - - $stock->updateQuantity(-100); - } - - public function testNotEnoughStockException() - { - $stock = $this->newInventoryStock(); - - Lang::shouldReceive('get')->once(); - - $this->setExpectedException('Stevebauman\Inventory\Exceptions\NotEnoughStockException'); - - $stock->take(1000); - } - - public function testStockAlreadyExistsException() - { - $this->newInventoryStock(); - - $location = Location::find(1); - - $item = Inventory::find(1); - - Lang::shouldReceive('get')->once(); - - $this->setExpectedException('Stevebauman\Inventory\Exceptions\StockAlreadyExistsException'); - - $item->createStockOnLocation(1, $location); - } - - public function testStockNotFoundException() - { - $item = $this->newInventory(); - - $location = $this->newLocation(); - - Lang::shouldReceive('get')->once(); - - $this->setExpectedException('Stevebauman\Inventory\Exceptions\StockNotFoundException'); - - $item->getStockFromLocation($location); - } - - public function testInventoryTakeFromManyLocations() - { - $this->newInventoryStock(); - - $item = Inventory::find(1); - - $location = Location::find(1); - - $item->takeFromManyLocations(10, [$location]); - - $stock = InventoryStock::find(1); - - $this->assertEquals(10, $stock->quantity); - } - - public function testInventoryAddToManyLocations() - { - $this->newInventoryStock(); - - $item = Inventory::find(1); - - $location = Location::find(1); - - $item->addToManyLocations(10, [$location]); - - $stock = InventoryStock::find(1); - - $this->assertEquals(30, $stock->quantity); - } - - public function testInventoryMoveItemStock() - { - $this->newInventoryStock(); - - $locationFrom = Location::find(1); - - $locationTo = new Location(); - $locationTo->name = 'New Location'; - $locationTo->save(); - - $item = Inventory::find(1); - - $item->moveStock($locationFrom, $locationTo); - - $stock = InventoryStock::find(1); - - $this->assertEquals(2, $stock->location_id); - } - - public function testInventoryGetTotalStock() - { - $this->newInventoryStock(); - - $item = Inventory::find(1); - - $this->assertEquals(20, $item->getTotalStock()); - } - - public function testInventoryGetStockFromLocationInvalidLocation() - { - $this->newInventoryStock(); - - $item = Inventory::find(1); - - Lang::shouldReceive('get')->once(); - - try { - $item->getStockFromLocation('testing'); - - $passes = false; - } catch (\Exception $e) { - $passes = true; - } - - $this->assertTrue($passes); - } - - public function testInventoryStockNewTransaction() - { - $this->newInventoryStock(); - - $stock = InventoryStock::find(1); - - $transaction = $stock->newTransaction(); - - $this->assertInstanceOf('Stevebauman\Inventory\Interfaces\StateableInterface', $transaction); - } -} diff --git a/tests/InventoryTest.php b/tests/InventoryTest.php deleted file mode 100644 index b09da35f..00000000 --- a/tests/InventoryTest.php +++ /dev/null @@ -1,166 +0,0 @@ -newMetric(); - - $category = $this->newCategory(); - - if(count($attributes) > 0) { - return Inventory::create($attributes); - } - - return Inventory::create([ - 'metric_id' => $metric->id, - 'category_id' => $category->id, - 'name' => 'Milk', - 'description' => 'Delicious Milk', - ]); - } - - /** - * @return Metric - */ - protected function newMetric() - { - return Metric::create([ - 'name' => 'Litres', - 'symbol' => 'L', - ]); - } - - /** - * @return Location - */ - protected function newLocation() - { - return Location::create([ - 'name' => 'Warehouse', - 'belongs_to' => '', - ]); - } - - /** - * @return Category - */ - protected function newCategory() - { - return Category::create([ - 'name' => 'Drinks', - ]); - } - - public function testInventoryHasMetric() - { - $item = $this->newInventory(); - - $this->assertTrue($item->hasMetric()); - } - - public function testInventoryDoesNotHaveMetric() - { - $item = $this->newInventory(); - - $metric = Metric::find(1); - $metric->delete(); - - $this->assertFalse($item->hasMetric()); - } - - public function testInventoryCreateStockOnLocation() - { - $item = $this->newInventory(); - - $location = $this->newLocation(); - - Lang::shouldReceive('get')->once(); - - $item->createStockOnLocation(10, $location); - - $stock = InventoryStock::find(1); - - $this->assertEquals(10, $stock->quantity); - } - - public function testInventoryNewStockOnLocation() - { - $item = $this->newInventory(); - - $location = $this->newLocation(); - - $stock = $item->newStockOnLocation($location); - - $this->assertEquals(1, $stock->inventory_id); - $this->assertEquals(1, $stock->location_id); - } - - public function testInventoryNewStockOnLocationFailure() - { - $item = $this->newInventory(); - - $location = $this->newLocation(); - - $stock = $item->newStockOnLocation($location); - $stock->save(); - - $this->setExpectedException('Stevebauman\Inventory\Exceptions\StockAlreadyExistsException'); - - $item->newStockOnLocation($location); - } - - public function testInventoryInvalidQuantityException() - { - $item = $this->newInventory(); - - $location = $this->newLocation(); - - Lang::shouldReceive('get')->once(); - - $this->setExpectedException('Stevebauman\Inventory\Exceptions\InvalidQuantityException'); - - $item->createStockOnLocation('invalid quantity', $location); - } - - public function testInventoryHasCategory() - { - $item = $this->newInventory(); - - $this->assertTrue($item->hasCategory()); - } - - public function testInventoryDoesNotHaveCategory() - { - $this->newInventory(); - - $item = Inventory::find(1); - $item->category_id = null; - $item->save(); - - $this->assertFalse($item->hasCategory()); - } -} diff --git a/tests/InventoryVariantTest.php b/tests/InventoryVariantTest.php deleted file mode 100644 index 9a93ac17..00000000 --- a/tests/InventoryVariantTest.php +++ /dev/null @@ -1,242 +0,0 @@ -newInventory(); - - $milk = Inventory::find(1); - - $chocolateMilk = $milk->newVariant(); - - $chocolateMilk->name = 'Chocolate Milk'; - - DB::shouldReceive('beginTransaction')->once()->andReturn(true); - DB::shouldReceive('commit')->once()->andReturn(true); - - Event::shouldReceive('fire')->once()->andReturn(true); - - $chocolateMilk->save(); - - $this->assertEquals($chocolateMilk->parent_id, $milk->id); - $this->assertEquals($chocolateMilk->category_id, $milk->category_id); - $this->assertEquals($chocolateMilk->metric_id, $milk->metric_id); - } - - public function testCreateVariant() - { - $this->newCategory(); - $this->newMetric(); - - $coke = Inventory::create([ - 'name' => 'Coke', - 'description' => 'Delicious Pop', - 'metric_id' => 1, - 'category_id' => 1, - ]); - - DB::shouldReceive('beginTransaction')->once()->andReturn(true); - DB::shouldReceive('commit')->once()->andReturn(true); - - Event::shouldReceive('fire')->once()->andReturn(true); - - $name = 'Cherry Coke'; - $description = 'Delicious Cherry Coke'; - - $cherryCoke = $coke->createVariant($name, $description); - - $this->assertTrue($cherryCoke->isVariant()); - $this->assertEquals(1, $cherryCoke->parent_id); - $this->assertEquals($name, $cherryCoke->name); - $this->assertEquals($description, $cherryCoke->description); - $this->assertEquals(1, $cherryCoke->category_id); - $this->assertEquals(1, $cherryCoke->metric_id); - } - - public function testMakeVariant() - { - $this->newCategory(); - $this->newMetric(); - - $coke = Inventory::create([ - 'name' => 'Coke', - 'description' => 'Delicious Pop', - 'metric_id' => 1, - 'category_id' => 1, - ]); - - $cherryCoke = Inventory::create([ - 'name' => 'Cherry Coke', - 'description' => 'Delicious Cherry Coke', - 'metric_id' => 1, - 'category_id' => 1, - ]); - - DB::shouldReceive('beginTransaction')->once()->andReturn(true); - DB::shouldReceive('commit')->once()->andReturn(true); - - Event::shouldReceive('fire')->once()->andReturn(true); - - $cherryCoke->makeVariantOf($coke); - - $this->assertEquals($cherryCoke->parent_id, $coke->id); - } - - public function testIsVariant() - { - $this->newCategory(); - $this->newMetric(); - - $coke = Inventory::create([ - 'name' => 'Coke', - 'description' => 'Delicious Pop', - 'metric_id' => 1, - 'category_id' => 1, - ]); - - $cherryCoke = $coke->createVariant('Cherry Coke'); - - DB::shouldReceive('beginTransaction')->once()->andReturn(true); - DB::shouldReceive('commit')->once()->andReturn(true); - - Event::shouldReceive('fire')->once()->andReturn(true); - - $cherryCoke->makeVariantOf($coke); - - $this->assertFalse($coke->isVariant()); - $this->assertTrue($cherryCoke->isVariant()); - } - - public function testGetVariants() - { - $this->newCategory(); - $this->newMetric(); - - $coke = Inventory::create([ - 'name' => 'Coke', - 'description' => 'Delicious Pop', - 'metric_id' => 1, - 'category_id' => 1, - ]); - - $cherryCoke = $coke->createVariant('Cherry Coke'); - - DB::shouldReceive('beginTransaction')->once()->andReturn(true); - DB::shouldReceive('commit')->once()->andReturn(true); - - Event::shouldReceive('fire')->once()->andReturn(true); - - $cherryCoke->makeVariantOf($coke); - - $variants = $coke->getVariants(); - - $this->assertInstanceOf('Illuminate\Support\Collection', $variants); - $this->assertEquals(1, $variants->count()); - } - - public function testGetVariantsRecursive() - { - $this->newCategory(); - $this->newMetric(); - - $coke = Inventory::create([ - 'name' => 'Coke', - 'description' => 'Delicious Pop', - 'metric_id' => 1, - 'category_id' => 1, - ]); - - $cherryCoke = $coke->createVariant('Cherry Coke'); - - $vanillaCherryCoke = $cherryCoke->createVariant('Vanilla Cherry Coke'); - - $vanillaLimeCherryCoke = $vanillaCherryCoke->createVariant('Vanilla Lime Cherry Coke'); - - $variants = $coke->getVariants(true); - - $this->assertEquals($cherryCoke->name, $variants->get(0)->name); - $this->assertEquals($vanillaCherryCoke->name, $variants->get(0)->variants->get(0)->name); - $this->assertEquals($vanillaLimeCherryCoke->name, $variants->get(0)->variants->get(0)->variants->get(0)->name); - } - - public function testGetParent() - { - $this->newCategory(); - $this->newMetric(); - - $coke = Inventory::create([ - 'name' => 'Coke', - 'description' => 'Delicious Pop', - 'metric_id' => 1, - 'category_id' => 1, - ]); - - $cherryCoke = Inventory::create([ - 'name' => 'Cherry Coke', - 'description' => 'Delicious Cherry Coke', - 'metric_id' => 1, - 'category_id' => 1, - ]); - - DB::shouldReceive('beginTransaction')->once()->andReturn(true); - DB::shouldReceive('commit')->once()->andReturn(true); - - Event::shouldReceive('fire')->once()->andReturn(true); - - $cherryCoke->makeVariantOf($coke); - - $parent = $cherryCoke->getParent(); - - $this->assertEquals('Coke', $parent->name); - $this->assertEquals(null, $parent->parent_id); - } - - public function testGetTotalVariantStock() - { - $this->newCategory(); - $this->newMetric(); - - $coke = Inventory::create([ - 'name' => 'Coke', - 'description' => 'Delicious Pop', - 'metric_id' => 1, - 'category_id' => 1, - ]); - - $cherryCoke = $coke->createVariant('Cherry Coke'); - - $cherryCoke->makeVariantOf($coke); - - $vanillaCherryCoke = $cherryCoke->createVariant('Vanilla Cherry Coke'); - - $vanillaCherryCoke->makeVariantOf($cherryCoke); - - DB::shouldReceive('beginTransaction')->once()->andReturn(true); - DB::shouldReceive('commit')->once()->andReturn(true); - - Event::shouldReceive('fire')->once()->andReturn(true); - - $location = $this->newLocation(); - - // Allow duplicate movements configuration option - Config::shouldReceive('get')->twice()->andReturn(true); - - // Stock change reasons (one for create, one for put, for both items) - Lang::shouldReceive('get')->times(4)->andReturn('Default Reason'); - - $cherryCoke->createStockOnLocation(20, $location); - - $vanillaCherryCoke->createStockOnLocation(20, $location); - - $this->assertEquals(40, $coke->getTotalVariantStock()); - } -} diff --git a/tests/Transactions/InventoryTransactionBackOrderTest.php b/tests/Transactions/InventoryTransactionBackOrderTest.php deleted file mode 100644 index 8dd7bf25..00000000 --- a/tests/Transactions/InventoryTransactionBackOrderTest.php +++ /dev/null @@ -1,68 +0,0 @@ -newTransaction(); - - $transaction->backOrder(500); - - $this->assertEquals(500, $transaction->quantity); - $this->assertEquals(InventoryTransaction::STATE_COMMERCE_BACK_ORDERED, $transaction->state); - } - - public function testInventoryTransactionBackOrderFilled() - { - $transaction = $this->newTransaction(); - - $transaction->backOrder(25); - - $stock = $transaction->getStockRecord(); - - $stock->put(5); - - $transaction->fillBackOrder(); - - $this->assertEquals(25, $transaction->quantity); - $this->assertEquals(InventoryTransaction::STATE_COMMERCE_BACK_ORDER_FILLED, $transaction->state); - } - - public function testInventoryTransactionBackOrderInvalidQuantityException() - { - $transaction = $this->newTransaction(); - - $this->setExpectedException('Stevebauman\Inventory\Exceptions\InvalidQuantityException'); - - $transaction->backOrder('40s'); - } - - public function testInventoryTransactionBackOrderInvalidTransactionStateException() - { - $transaction = $this->newTransaction(); - - $this->setExpectedException('Stevebauman\Inventory\Exceptions\InvalidTransactionStateException'); - - $transaction->checkout(5)->backOrder(3); - } - - public function testInventoryTransactionBackOrderFilledDefaultReason() - { - $transaction = $this->newTransaction(); - - $transaction->backOrder(5); - - $stock = $transaction->getStockRecord(); - - Lang::shouldReceive('get')->once()->andReturn('test'); - - $transaction->fillBackOrder(); - - $this->assertEquals('test', $stock->reason); - } -} diff --git a/tests/Transactions/InventoryTransactionCancelledTest.php b/tests/Transactions/InventoryTransactionCancelledTest.php deleted file mode 100644 index 654d77bf..00000000 --- a/tests/Transactions/InventoryTransactionCancelledTest.php +++ /dev/null @@ -1,101 +0,0 @@ -newTransaction(); - - $transaction->reserved(5)->cancel(); - - $this->assertEquals(0, $transaction->quantity); - $this->assertEquals(InventoryTransaction::STATE_CANCELLED, $transaction->state); - } - - public function testInventoryTransactionCancelAfterOnHold() - { - $transaction = $this->newTransaction(); - - $transaction->hold(5)->cancel(); - - $this->assertEquals(0, $transaction->quantity); - $this->assertEquals(InventoryTransaction::STATE_CANCELLED, $transaction->state); - - $stock = $transaction->getStockRecord(); - - $this->assertEquals(20, $stock->quantity); - } - - public function testInventoryTransactionCancelAfterCheckout() - { - $transaction = $this->newTransaction(); - - $transaction->checkout(5)->cancel(); - - $this->assertEquals(0, $transaction->quantity); - $this->assertEquals(InventoryTransaction::STATE_CANCELLED, $transaction->state); - - $stock = $transaction->getStockRecord(); - - $this->assertEquals(20, $stock->quantity); - } - - public function testInventoryTransactionCancelAfterBackOrder() - { - $transaction = $this->newTransaction(); - - $transaction->backOrder(500)->cancel(); - - $this->assertEquals(0, $transaction->quantity); - $this->assertEquals(InventoryTransaction::STATE_CANCELLED, $transaction->state); - } - - public function testInventoryTransactionCancelAfterOrdered() - { - $transaction = $this->newTransaction(); - - $transaction->ordered(500)->cancel(); - - $this->assertEquals(0, $transaction->quantity); - $this->assertEquals(InventoryTransaction::STATE_CANCELLED, $transaction->state); - } - - public function testInventoryTransactionCancelAfterOpened() - { - $transaction = $this->newTransaction(); - - $transaction->cancel(); - - $this->assertEquals(0, $transaction->quantity); - $this->assertEquals(InventoryTransaction::STATE_CANCELLED, $transaction->state); - } - - public function testInventoryTransactionCancelAfterCancelFailure() - { - $transaction = $this->newTransaction(); - - $this->setExpectedException('Stevebauman\Inventory\Exceptions\InvalidTransactionStateException'); - - $transaction->cancel()->cancel(); - } - - public function testInventoryTransactionCancelledDefaultReason() - { - $transaction = $this->newTransaction(); - - $transaction->checkout(5); - - $stock = $transaction->getStockRecord(); - - Lang::shouldReceive('get')->once()->andReturn('test'); - - $transaction->cancel(); - - $this->assertEquals('test', $stock->reason); - } -} diff --git a/tests/Transactions/InventoryTransactionCheckoutTest.php b/tests/Transactions/InventoryTransactionCheckoutTest.php deleted file mode 100644 index ab546aba..00000000 --- a/tests/Transactions/InventoryTransactionCheckoutTest.php +++ /dev/null @@ -1,225 +0,0 @@ -newTransaction(); - - DB::shouldReceive('startTransaction')->once(); - - DB::shouldReceive('commit')->once(); - - $transaction->checkout(5, 'Checking out', 25); - - $this->assertEquals(5, $transaction->quantity); - $this->assertEquals(InventoryTransaction::STATE_COMMERCE_CHECKOUT, $transaction->state); - - $stock = $transaction->getStockRecord(); - - $this->assertEquals('Checking out', $stock->reason); - $this->assertEquals(25, $stock->cost); - } - - public function testInventoryTransactionIsCheckout() - { - $transaction = $this->newTransaction(); - - $transaction->checkout(5); - - $this->assertTrue($transaction->isCheckout()); - } - - public function testInventoryTransactionIsNotCheckout() - { - $transaction = $this->newTransaction(); - - $transaction->reserved(5); - - $this->assertFalse($transaction->isCheckout()); - } - - public function testInventoryTransactionCheckoutFailure() - { - $transaction = $this->newTransaction(); - - $this->setExpectedException('Stevebauman\Inventory\Exceptions\NotEnoughStockException'); - - $transaction->checkout(5000); - } - - public function testInventoryTransactionCheckoutQuantityFailure() - { - $transaction = $this->newTransaction(); - - $this->setExpectedException('Stevebauman\Inventory\Exceptions\InvalidQuantityException'); - - $transaction->checkout('30as'); - } - - public function testInventoryTransactionReservationAfterCheckout() - { - $transaction = $this->newTransaction(); - - $transaction->checkout(5)->reserved(); - - $this->assertEquals(5, $transaction->quantity); - $this->assertEquals(InventoryTransaction::STATE_COMMERCE_RESERVED, $transaction->state); - } - - /** - * The transaction quantity stays at 5 because a partial reserve cannot be made on a checkout. - */ - public function testInventoryTransactionReservationAfterCheckoutQuantity() - { - $transaction = $this->newTransaction(); - - $transaction->checkout(5)->reserved(500); - - $this->assertEquals(5, $transaction->quantity); - $this->assertEquals(InventoryTransaction::STATE_COMMERCE_RESERVED, $transaction->state); - } - - /** - * This fails because the transaction is already set to checkout, a quantity update could simply be made - * instead of calling checkout again. - */ - public function testInventoryTransactionCheckoutAfterCheckoutFailure() - { - $transaction = $this->newTransaction(); - - $this->setExpectedException('Stevebauman\Inventory\Exceptions\InvalidTransactionStateException'); - - $transaction->checkout(5)->checkout(500); - } - - /* - * This works because you can always update the quantity on any transaction - * if needed - */ - public function testInventoryTransactionQuantityUpdateAfterCheckout() - { - $transaction = $this->newTransaction(); - - $transaction->checkout(5); - - $transaction->quantity = 10; - $transaction->save(); - - $this->assertEquals(10, $transaction->quantity); - $this->assertEquals(InventoryTransaction::STATE_COMMERCE_CHECKOUT, $transaction->state); - } - - public function testInventoryTransactionReturnedAfterCheckout() - { - $transaction = $this->newTransaction(); - - $transaction->checkout(5)->returned(); - - $this->assertEquals(0, $transaction->quantity); - $this->assertEquals(InventoryTransaction::STATE_COMMERCE_RETURNED, $transaction->state); - } - - public function testInventoryTransactionReturnedPartialAfterCheckout() - { - $transaction = $this->newTransaction(); - - $transaction->checkout(5)->returned(2); - - $this->assertEquals(3, $transaction->quantity); - $this->assertEquals(InventoryTransaction::STATE_COMMERCE_CHECKOUT, $transaction->state); - } - - public function testInventoryTransactionSoldAfterCheckout() - { - $transaction = $this->newTransaction(); - - $transaction->checkout(5)->sold(); - - $this->assertEquals(5, $transaction->quantity); - $this->assertEquals(InventoryTransaction::STATE_COMMERCE_SOLD, $transaction->state); - } - - public function testInventoryTransactionSoldAmountAfterCheckoutFailure() - { - $transaction = $this->newTransaction(); - - $this->setExpectedException('Stevebauman\Inventory\Exceptions\InvalidTransactionStateException'); - - $transaction->checkout(5)->sold(500); - } - - public function testInventoryTransactionSoldAfterReservationAndCheckout() - { - $transaction = $this->newTransaction(); - - $transaction->checkout(5)->reserved()->sold(); - - $this->assertEquals(5, $transaction->quantity); - $this->assertEquals(InventoryTransaction::STATE_COMMERCE_SOLD, $transaction->state); - } - - public function testInventoryTransactionCheckoutSoldAndReturned() - { - $transaction = $this->newTransaction(); - - $transaction->checkout(5)->reserved()->sold()->returned(); - - $this->assertEquals(0, $transaction->quantity); - $this->assertEquals(InventoryTransaction::STATE_COMMERCE_RETURNED, $transaction->state); - } - - public function testInventoryTransactionCheckoutSoldAndReturnedPartial() - { - $transaction = $this->newTransaction(); - - $transaction->checkout(5)->reserved()->sold()->returned(3); - - $this->assertEquals(2, $transaction->quantity); - $this->assertEquals(InventoryTransaction::STATE_COMMERCE_SOLD, $transaction->state); - } - - /** - * This fails because when a stock is returned a new transaction must be created - * for any functions. It's an 'end of the line' state. - */ - public function testInventoryTransactionCheckoutSoldReturnedAndReservedFailure() - { - $transaction = $this->newTransaction(); - - $this->setExpectedException('Stevebauman\Inventory\Exceptions\InvalidTransactionStateException'); - - $transaction->checkout(5)->reserved()->sold()->returned()->reserved(5); - - $transaction->checkout(5)->reserved()->sold()->returned()->reserved(); - } - - public function testInventoryTransactionCheckoutReserved() - { - $transaction = $this->newTransaction(); - - $transaction->reserved(5)->checkout(); - - $this->assertEquals(5, $transaction->quantity); - $this->assertEquals(InventoryTransaction::STATE_COMMERCE_CHECKOUT, $transaction->state); - } - - public function testInventoryTransactionCheckoutDefaultReason() - { - $transaction = $this->newTransaction(); - - Lang::shouldReceive('get')->once()->andReturn('test'); - - $transaction->checkout(5); - - $stock = $transaction->getStockRecord(); - - $this->assertEquals('test', $stock->reason); - } -} diff --git a/tests/Transactions/InventoryTransactionHoldTest.php b/tests/Transactions/InventoryTransactionHoldTest.php deleted file mode 100644 index 4a52c8eb..00000000 --- a/tests/Transactions/InventoryTransactionHoldTest.php +++ /dev/null @@ -1,64 +0,0 @@ -newTransaction(); - - $transaction->hold(10, 'Holding', 25); - - $this->assertEquals(10, $transaction->quantity); - $this->assertEquals(InventoryTransaction::STATE_INVENTORY_ON_HOLD, $transaction->state); - - $stock = $transaction->getStockRecord(); - - $this->assertEquals('Holding', $stock->reason); - $this->assertEquals(25, $stock->cost); - } - - public function testInventoryTransactionHoldInvalidQuantityException() - { - $transaction = $this->newTransaction(); - - $this->setExpectedException('Stevebauman\Inventory\Exceptions\InvalidQuantityException'); - - $transaction->hold('40a'); - } - - public function testInventoryTransactionHoldInvalidTransactionStateException() - { - $transaction = $this->newTransaction(); - - $this->setExpectedException('Stevebauman\Inventory\Exceptions\InvalidTransactionStateException'); - - $transaction->ordered(5)->hold(5); - } - - public function testInventoryTransactionHoldNotEnoughStockException() - { - $transaction = $this->newTransaction(); - - $this->setExpectedException('Stevebauman\Inventory\Exceptions\NotEnoughStockException'); - - $transaction->hold(500); - } - - public function testInventoryTransactionHoldDefaultReason() - { - $transaction = $this->newTransaction(); - - Lang::shouldReceive('get')->once()->andReturn('test'); - - $transaction->hold(5); - - $stock = $transaction->getStockRecord(); - - $this->assertEquals('test', $stock->reason); - } -} diff --git a/tests/Transactions/InventoryTransactionOrderedTest.php b/tests/Transactions/InventoryTransactionOrderedTest.php deleted file mode 100644 index de88b08e..00000000 --- a/tests/Transactions/InventoryTransactionOrderedTest.php +++ /dev/null @@ -1,85 +0,0 @@ -newTransaction(); - - $transaction->ordered(5); - - $this->assertEquals(5, $transaction->quantity); - $this->assertEquals(InventoryTransaction::STATE_ORDERED_PENDING, $transaction->state); - } - - public function testInventoryTransactionOrderedReceived() - { - $transaction = $this->newTransaction(); - - $transaction->ordered(5)->received(5, 'Received Order', 25); - - $this->assertEquals(0, $transaction->quantity); - $this->assertEquals(InventoryTransaction::STATE_ORDERED_RECEIVED, $transaction->state); - - $stock = $transaction->getStockRecord(); - - $this->assertEquals('Received Order', $stock->reason); - $this->assertEquals(25, $stock->cost); - } - - public function testInventoryTransactionOrderedReceivedPartial() - { - $transaction = $this->newTransaction(); - - $transaction->ordered(5)->received(2); - - $this->assertEquals(3, $transaction->quantity); - $this->assertEquals(InventoryTransaction::STATE_ORDERED_PENDING, $transaction->state); - } - - public function testInventoryTransactionOrderedReceivedPartialAll() - { - $transaction = $this->newTransaction(); - - $transaction->ordered(5)->received(10); - - $this->assertEquals(0, $transaction->quantity); - $this->assertEquals(InventoryTransaction::STATE_ORDERED_RECEIVED, $transaction->state); - } - - public function testInventoryTransactionOrderedInvalidQuantityException() - { - $transaction = $this->newTransaction(); - - $this->setExpectedException('Stevebauman\Inventory\Exceptions\InvalidQuantityException'); - - $transaction->ordered('40a'); - } - - public function testInventoryTransactionOrderedInvalidTransactionStateException() - { - $transaction = $this->newTransaction(); - - $this->setExpectedException('Stevebauman\Inventory\Exceptions\InvalidTransactionStateException'); - - $transaction->reserved(5)->ordered(10); - } - - public function testInventoryTransactionReceivedDefaultReason() - { - $transaction = $this->newTransaction(); - - Lang::shouldReceive('get')->once()->andReturn('test'); - - $transaction->ordered(5)->received(5); - - $stock = $transaction->getStockRecord(); - - $this->assertEquals('test', $stock->reason); - } -} diff --git a/tests/Transactions/InventoryTransactionReleaseTest.php b/tests/Transactions/InventoryTransactionReleaseTest.php deleted file mode 100644 index 823943b0..00000000 --- a/tests/Transactions/InventoryTransactionReleaseTest.php +++ /dev/null @@ -1,85 +0,0 @@ -newTransaction(); - - $transaction->hold(5)->release(null, 'Released', 25); - - $this->assertEquals(0, $transaction->quantity); - $this->assertEquals(InventoryTransaction::STATE_INVENTORY_RELEASED, $transaction->state); - - $stock = $transaction->getStockRecord(); - - $this->assertEquals('Released', $stock->reason); - $this->assertEquals(25, $stock->cost); - } - - public function testInventoryTransactionReleasePartial() - { - $transaction = $this->newTransaction(); - - $transaction->hold(5)->release(2); - - $this->assertEquals(3, $transaction->quantity); - $this->assertEquals(InventoryTransaction::STATE_INVENTORY_ON_HOLD, $transaction->state); - } - - public function testInventoryTransactionReleaseAll() - { - $transaction = $this->newTransaction(); - - $transaction->hold(5)->releaseAll(); - - $this->assertEquals(0, $transaction->quantity); - $this->assertEquals(InventoryTransaction::STATE_INVENTORY_RELEASED, $transaction->state); - } - - public function testInventoryTransactionReleasePartialAll() - { - $transaction = $this->newTransaction(); - - $transaction->hold(5)->release(10); - - $this->assertEquals(0, $transaction->quantity); - $this->assertEquals(InventoryTransaction::STATE_INVENTORY_RELEASED, $transaction->state); - } - - public function testInventoryTransactionReleaseInvalidQuantity() - { - $transaction = $this->newTransaction(); - - $transaction->hold(5)->release('asddsa'); - - $this->assertEquals(5, $transaction->quantity); - } - - public function testInventoryTransactionReleaseInvalidTransactionStateException() - { - $transaction = $this->newTransaction(); - - $this->setExpectedException('Stevebauman\Inventory\Exceptions\InvalidTransactionStateException'); - - $transaction->ordered(5)->release(); - } - - public function testInventoryTransactionReleaseDefaultReason() - { - $transaction = $this->newTransaction(); - - Lang::shouldReceive('get')->twice()->andReturn('test'); - - $transaction->hold(5)->release(3); - - $stock = $transaction->getStockRecord(); - - $this->assertEquals('test', $stock->reason); - } -} diff --git a/tests/Transactions/InventoryTransactionRemoveTest.php b/tests/Transactions/InventoryTransactionRemoveTest.php deleted file mode 100644 index d30a84a5..00000000 --- a/tests/Transactions/InventoryTransactionRemoveTest.php +++ /dev/null @@ -1,94 +0,0 @@ -newTransaction(); - - $transaction->remove(5, 'Removed from inventory', 25); - - $this->assertEquals(5, $transaction->quantity); - $this->assertEquals(InventoryTransaction::STATE_INVENTORY_REMOVED, $transaction->state); - - $stock = $transaction->getStockRecord(); - - $this->assertEquals('Removed from inventory', $stock->reason); - $this->assertEquals(25, $stock->cost); - } - - public function testInventoryTransactionRemovePartial() - { - $transaction = $this->newTransaction(); - - $transaction->hold(5)->remove(2); - - $this->assertEquals(3, $transaction->quantity); - $this->assertEquals(InventoryTransaction::STATE_INVENTORY_ON_HOLD, $transaction->state); - } - - public function testInventoryTransactionRemovePartialFailureRollback() - { - $transaction = $this->newTransaction(); - - $transaction->hold(5)->remove('testing'); - - $this->assertEquals(5, $transaction->quantity); - $this->assertEquals(InventoryTransaction::STATE_INVENTORY_ON_HOLD, $transaction->state); - } - - public function testInventoryTransactionRemovePartialAll() - { - $transaction = $this->newTransaction(); - - $transaction->hold(5)->remove(10); - - $this->assertEquals(0, $transaction->quantity); - $this->assertEquals(InventoryTransaction::STATE_INVENTORY_REMOVED, $transaction->state); - } - - public function testInventoryTransactionRemoveInvalidQuantityException() - { - $transaction = $this->newTransaction(); - - $this->setExpectedException('Stevebauman\Inventory\Exceptions\InvalidQuantityException'); - - $transaction->remove('10a'); - } - - public function testInventoryTransactionRemoveBlankInvalidTransactionStateException() - { - $transaction = $this->newTransaction(); - - $this->setExpectedException('Stevebauman\Inventory\Exceptions\InvalidTransactionStateException'); - - $transaction->remove(); - } - - public function testInventoryTransactionRemoveInvalidTransactionStateException() - { - $transaction = $this->newTransaction(); - - $this->setExpectedException('Stevebauman\Inventory\Exceptions\InvalidTransactionStateException'); - - $transaction->ordered(5)->remove(); - } - - public function testInventoryTransactionRemoveDefaultReason() - { - $transaction = $this->newTransaction(); - - Lang::shouldReceive('get')->once()->andReturn('test'); - - $transaction->remove(5); - - $stock = $transaction->getStockRecord(); - - $this->assertEquals('test', $stock->reason); - } -} diff --git a/tests/Transactions/InventoryTransactionReservedTest.php b/tests/Transactions/InventoryTransactionReservedTest.php deleted file mode 100644 index d424c27c..00000000 --- a/tests/Transactions/InventoryTransactionReservedTest.php +++ /dev/null @@ -1,75 +0,0 @@ -newTransaction(); - - $transaction->reserved(10, $backOrder = false, 'Reservation', 25); - - $this->assertEquals(10, $transaction->quantity); - $this->assertEquals(InventoryTransaction::STATE_COMMERCE_RESERVED, $transaction->state); - - $stock = $transaction->getStockRecord(); - - $this->assertEquals(10, $stock->quantity); - $this->assertEquals('Reservation', $stock->reason); - $this->assertEquals(25, $stock->cost); - } - - public function testInventoryTransactionReservedNotEnoughStockException() - { - $transaction = $this->newTransaction(); - - $this->setExpectedException('Stevebauman\Inventory\Exceptions\NotEnoughStockException'); - - $transaction->reserved(100); - } - - public function testInventoryTransactionReservedInvalidQuantityException() - { - $transaction = $this->newTransaction(); - - $this->setExpectedException('Stevebauman\Inventory\Exceptions\InvalidQuantityException'); - - $transaction->reserved('40a'); - } - - public function testInventoryTransactionReservedInvalidTransactionStateException() - { - $transaction = $this->newTransaction(); - - $this->setExpectedException('Stevebauman\Inventory\Exceptions\InvalidTransactionStateException'); - - $transaction->hold(5)->reserved(20); - } - - public function testInventoryTransactionReservedCheckout() - { - $transaction = $this->newTransaction(); - - $transaction->checkout(5)->reserved(); - - $this->assertEquals(5, $transaction->quantity); - $this->assertEquals(InventoryTransaction::STATE_COMMERCE_RESERVED, $transaction->state); - } - - public function testInventoryTransactionReservedDefaultReason() - { - $transaction = $this->newTransaction(); - - Lang::shouldReceive('get')->once()->andReturn('test'); - - $transaction->reserved(5); - - $stock = $transaction->getStockRecord(); - - $this->assertEquals('test', $stock->reason); - } -} diff --git a/tests/Transactions/InventoryTransactionReturnedTest.php b/tests/Transactions/InventoryTransactionReturnedTest.php deleted file mode 100644 index 9ba955e8..00000000 --- a/tests/Transactions/InventoryTransactionReturnedTest.php +++ /dev/null @@ -1,116 +0,0 @@ -newTransaction(); - - $transaction->sold(5)->returned(5, 'Returned', 25); - - $this->assertEquals(0, $transaction->quantity); - $this->assertEquals(InventoryTransaction::STATE_COMMERCE_RETURNED, $transaction->state); - - $stock = $transaction->getStockRecord(); - - $this->assertEquals('Returned', $stock->reason); - $this->assertEquals(25, $stock->cost); - } - - public function testInventoryTransactionReturnedAllAfterSold() - { - $transaction = $this->newTransaction(); - - $transaction->sold(5)->returnedAll(); - - $this->assertEquals(0, $transaction->quantity); - $this->assertEquals(InventoryTransaction::STATE_COMMERCE_RETURNED, $transaction->state); - } - - public function testInventoryTransactionReturnedPartialAfterSold() - { - $transaction = $this->newTransaction(); - - $transaction->sold(5)->returned(3); - - $this->assertEquals(2, $transaction->quantity); - $this->assertEquals(InventoryTransaction::STATE_COMMERCE_SOLD, $transaction->state); - } - - public function testInventoryTransactionReturnedAfterCheckout() - { - $transaction = $this->newTransaction(); - - $transaction->checkout(5)->returned(); - - $this->assertEquals(0, $transaction->quantity); - $this->assertEquals(InventoryTransaction::STATE_COMMERCE_RETURNED, $transaction->state); - } - - public function testInventoryTransactionReturnedAllAfterCheckout() - { - $transaction = $this->newTransaction(); - - $transaction->checkout(5)->returnedAll(); - - $this->assertEquals(0, $transaction->quantity); - $this->assertEquals(InventoryTransaction::STATE_COMMERCE_RETURNED, $transaction->state); - } - - public function testInventoryTransactionReturnedPartialAfterCheckoutRollback() - { - $transaction = $this->newTransaction(); - - $transaction->checkout(5)->returned('testing'); - - $this->assertEquals(5, $transaction->quantity); - $this->assertEquals(InventoryTransaction::STATE_COMMERCE_CHECKOUT, $transaction->state); - } - - public function testInventoryTransactionReturnedPartialAfterCheckout() - { - $transaction = $this->newTransaction(); - - $transaction->checkout(5)->returned(2); - - $this->assertEquals(3, $transaction->quantity); - $this->assertEquals(InventoryTransaction::STATE_COMMERCE_CHECKOUT, $transaction->state); - } - - public function testInventoryTransactionReturnedPartialAfterSoldRollBack() - { - $transaction = $this->newTransaction(); - - $transaction->sold(5)->returned('testing'); - - $this->assertEquals(5, $transaction->quantity); - $this->assertEquals(InventoryTransaction::STATE_COMMERCE_SOLD, $transaction->state); - } - - public function testInventoryTransactionReturnedInvalidTransactionStateException() - { - $transaction = $this->newTransaction(); - - $this->setExpectedException('Stevebauman\Inventory\Exceptions\InvalidTransactionStateException'); - - $transaction->returned(5); - } - - public function testInventoryTransactionReturnedDefaultReason() - { - $transaction = $this->newTransaction(); - - Lang::shouldReceive('get')->twice()->andReturn('test'); - - $transaction->sold(5)->returned(5); - - $stock = $transaction->getStockRecord(); - - $this->assertEquals('test', $stock->reason); - } -} diff --git a/tests/Transactions/InventoryTransactionSoldTest.php b/tests/Transactions/InventoryTransactionSoldTest.php deleted file mode 100644 index 456e02e1..00000000 --- a/tests/Transactions/InventoryTransactionSoldTest.php +++ /dev/null @@ -1,124 +0,0 @@ -newTransaction(); - - $transaction->sold(5, 'Sold some', 25); - - $this->assertEquals(5, $transaction->quantity); - $this->assertEquals(InventoryTransaction::STATE_COMMERCE_SOLD, $transaction->state); - - $stock = $transaction->getStockRecord(); - - $this->assertEquals(15, $stock->quantity); - $this->assertEquals('Sold some', $stock->reason); - $this->assertEquals(25, $stock->cost); - } - - public function testInventoryTransactionSoldNotEnoughStockFailure() - { - $transaction = $this->newTransaction(); - - $this->setExpectedException('Stevebauman\Inventory\Exceptions\NotEnoughStockException'); - - $transaction->sold(5000); - } - - public function testInventoryTransactionSoldInvalidQuantityFailure() - { - $transaction = $this->newTransaction(); - - $this->setExpectedException('Stevebauman\Inventory\Exceptions\InvalidQuantityException'); - - $transaction->sold('50a'); - } - - public function testInventoryTransactionSoldAndThenReturned() - { - $transaction = $this->newTransaction(); - - $transaction->sold(5)->returned(); - - $this->assertEquals(0, $transaction->quantity); - $this->assertEquals(InventoryTransaction::STATE_COMMERCE_RETURNED, $transaction->state); - } - - public function testInventoryTransactionSoldAndThenReturnedAll() - { - $transaction = $this->newTransaction(); - - $transaction->sold(5)->returnedAll(); - - $this->assertEquals(0, $transaction->quantity); - $this->assertEquals(InventoryTransaction::STATE_COMMERCE_RETURNED, $transaction->state); - } - - public function testInventoryTransactionSoldAndThenReturnedPartial() - { - $transaction = $this->newTransaction(); - - $transaction->sold(5)->returned(2); - - $this->assertEquals(3, $transaction->quantity); - $this->assertEquals(InventoryTransaction::STATE_COMMERCE_SOLD, $transaction->state); - } - - public function testInventoryTransactionSoldAndThenReturnedPartialAll() - { - $transaction = $this->newTransaction(); - - $transaction->sold(5)->returned(5); - - $this->assertEquals(0, $transaction->quantity); - $this->assertEquals(InventoryTransaction::STATE_COMMERCE_RETURNED, $transaction->state); - } - - public function testInventoryTransactionSoldAmount() - { - $transaction = $this->newTransaction(); - - $transaction->soldAmount(5); - - $this->assertEquals(5, $transaction->quantity); - $this->assertEquals(InventoryTransaction::STATE_COMMERCE_SOLD, $transaction->state); - } - - public function testInventoryTransactionSoldAmountInvalidQuantityFailure() - { - $transaction = $this->newTransaction(); - - $this->setExpectedException('Stevebauman\Inventory\Exceptions\InvalidQuantityException'); - - $transaction->soldAmount('40a'); - } - - public function testInventoryTransactionSoldAmountNotEnoughStockFailure() - { - $transaction = $this->newTransaction(); - - $this->setExpectedException('Stevebauman\Inventory\Exceptions\NotEnoughStockException'); - - $transaction->soldAmount(5000); - } - - public function testInventoryTransactionSoldDefaultReason() - { - $transaction = $this->newTransaction(); - - Lang::shouldReceive('get')->once()->andReturn('test'); - - $transaction->sold(5); - - $stock = $transaction->getStockRecord(); - - $this->assertEquals('test', $stock->reason); - } -} diff --git a/tests/Transactions/InventoryTransactionTest.php b/tests/Transactions/InventoryTransactionTest.php deleted file mode 100644 index 8029ac75..00000000 --- a/tests/Transactions/InventoryTransactionTest.php +++ /dev/null @@ -1,71 +0,0 @@ -newInventoryStock(); - - return $stock->newTransaction(); - } - - public function testInventoryTransactionStockNotFoundException() - { - $transaction = $this->newTransaction(); - - $transaction->stock_id = 15; - - $this->setExpectedException('Stevebauman\Inventory\Exceptions\StockNotFoundException'); - - $transaction->getStockRecord(); - } - - public function testInventoryTransactionSetStateFailure() - { - $transaction = $this->newTransaction(); - - $this->setExpectedException('Stevebauman\Inventory\Exceptions\InvalidTransactionStateException'); - - $transaction->state = 'test'; - } - - public function testInventoryTransactionSetStateSuccess() - { - $transaction = $this->newTransaction(); - - $transaction->state = InventoryTransaction::STATE_COMMERCE_RESERVED; - } - - public function testInventoryTransactionGetByState() - { - $transaction = $this->newTransaction(); - - $transaction->reserved(2); - - $results = InventoryTransaction::getByState(InventoryTransaction::STATE_COMMERCE_RESERVED); - - $this->assertEquals(1, $results->count()); - } -} From 232a304286767d38d01e3202418a96993ec75dea Mon Sep 17 00:00:00 2001 From: Steve Bauman Date: Thu, 13 Aug 2015 11:47:43 -0400 Subject: [PATCH 44/51] Update tests badge --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 65629ba2..9fa21e6f 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Inventory -[![Travis CI](https://img.shields.io/travis/stevebauman/inventory.svg?style=flat-square)](https://travis-ci.org/stevebauman/inventory) +[![Travis CI](https://img.shields.io/travis/stevebauman/inventory/v1.7.svg?style=flat-square)](https://travis-ci.org/stevebauman/inventory) [![Scrutinizer Code Quality](https://img.shields.io/scrutinizer/g/stevebauman/inventory.svg?style=flat-square)](https://scrutinizer-ci.com/g/stevebauman/inventory/?branch=master) [![SensioLabsInsight](https://img.shields.io/sensiolabs/i/69e0abf0-cd74-4d4d-b40c-e943c4a7eea9.svg?style=flat-square)](https://insight.sensiolabs.com/projects/69e0abf0-cd74-4d4d-b40c-e943c4a7eea9) [![Latest Stable Version](https://img.shields.io/packagist/v/stevebauman/inventory.svg?style=flat-square)](https://packagist.org/packages/stevebauman/inventory) From 00e48cd682e85f3f0f8d7d9d56ed8883a9247208 Mon Sep 17 00:00:00 2001 From: Steve Bauman Date: Thu, 13 Aug 2015 12:56:44 -0400 Subject: [PATCH 45/51] Require testbench, fix travis badge --- README.md | 2 +- composer.json | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 9fa21e6f..728f1dc4 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Inventory -[![Travis CI](https://img.shields.io/travis/stevebauman/inventory/v1.7.svg?style=flat-square)](https://travis-ci.org/stevebauman/inventory) +[![Travis CI](https://img.shields.io/travis/stevebauman/inventory/v1.7.5.svg?style=flat-square)](https://travis-ci.org/stevebauman/inventory) [![Scrutinizer Code Quality](https://img.shields.io/scrutinizer/g/stevebauman/inventory.svg?style=flat-square)](https://scrutinizer-ci.com/g/stevebauman/inventory/?branch=master) [![SensioLabsInsight](https://img.shields.io/sensiolabs/i/69e0abf0-cd74-4d4d-b40c-e943c4a7eea9.svg?style=flat-square)](https://insight.sensiolabs.com/projects/69e0abf0-cd74-4d4d-b40c-e943c4a7eea9) [![Latest Stable Version](https://img.shields.io/packagist/v/stevebauman/inventory.svg?style=flat-square)](https://packagist.org/packages/stevebauman/inventory) diff --git a/composer.json b/composer.json index 9e10e841..85203658 100644 --- a/composer.json +++ b/composer.json @@ -16,8 +16,7 @@ "baum/baum": "1.1.*" }, "require-dev": { - "phpunit/phpunit": "4.*", - "mockery/mockery": "0.9.*" + "orchestra/testbench": "3.1.*", }, "archive": { "exclude": ["/tests"] From 641aa501d898a105cc28c72a5f07f7bdabd41fb3 Mon Sep 17 00:00:00 2001 From: Steve Bauman Date: Sun, 16 Aug 2015 19:29:42 -0400 Subject: [PATCH 46/51] Fix composer.json extra comma --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 85203658..0320274e 100644 --- a/composer.json +++ b/composer.json @@ -16,7 +16,7 @@ "baum/baum": "1.1.*" }, "require-dev": { - "orchestra/testbench": "3.1.*", + "orchestra/testbench": "3.1.*" }, "archive": { "exclude": ["/tests"] From 1fa07ea1975290a1ca4608d929453b90cf556616 Mon Sep 17 00:00:00 2001 From: Mohd Sulaiman Date: Mon, 7 Sep 2015 16:32:37 +0800 Subject: [PATCH 47/51] metric_id is not nullable Inventory model has hasMetric() function, but metric_id is not nullable. Metric Id is not necessary in inventory which has assemblies and is not being assembly, right? --- src/Migrations/2014_07_31_123213_create_inventory_tables.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Migrations/2014_07_31_123213_create_inventory_tables.php b/src/Migrations/2014_07_31_123213_create_inventory_tables.php index 769dfc45..8126e279 100644 --- a/src/Migrations/2014_07_31_123213_create_inventory_tables.php +++ b/src/Migrations/2014_07_31_123213_create_inventory_tables.php @@ -17,7 +17,7 @@ public function up() $table->integer('category_id')->unsigned()->nullable(); $table->integer('user_id')->unsigned()->nullable(); - $table->integer('metric_id')->unsigned(); + $table->integer('metric_id')->unsigned()->nullable(); $table->string('name'); $table->text('description')->nullable(); From b7889328ff6834df5be5835c4a13d845da057a43 Mon Sep 17 00:00:00 2001 From: Steve Bauman Date: Wed, 7 Oct 2015 10:02:21 -0400 Subject: [PATCH 48/51] Added missing start transaction method --- src/Traits/InventoryVariantTrait.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Traits/InventoryVariantTrait.php b/src/Traits/InventoryVariantTrait.php index 1c8bbbbd..87a02b25 100644 --- a/src/Traits/InventoryVariantTrait.php +++ b/src/Traits/InventoryVariantTrait.php @@ -166,6 +166,8 @@ public function newVariant($name = '') public function createVariant($name = '', $description = '', $categoryId = null, $metricId = null) { $variant = $this->newVariant($name); + + $this->dbStartTransaction(); try { if (!empty($description)) { From 9693715f60a217d8ccfb3cfb7e55228a2f96227c Mon Sep 17 00:00:00 2001 From: Steve Bauman Date: Tue, 10 May 2016 09:11:56 -0400 Subject: [PATCH 49/51] Make configuration prettier --- src/Config/config.php | 100 ++++++++++++++++++++++++++++-------------- 1 file changed, 66 insertions(+), 34 deletions(-) diff --git a/src/Config/config.php b/src/Config/config.php index 219d15c1..56e6d3f5 100644 --- a/src/Config/config.php +++ b/src/Config/config.php @@ -1,57 +1,76 @@ false, /* - * Allows inventory stock movements to have the same before and after quantity - * - * @var bool - */ + |-------------------------------------------------------------------------- + | Allow Duplicate Movements + |-------------------------------------------------------------------------- + | + | Allows inventory stock movements to have the same before and after quantity. + | + */ + 'allow_duplicate_movements' => true, /* - * When set to true, this will reverse the cost in the rolled back movement. - * - * For example, if the movement's cost that is being rolled back is 500, the rolled back - * movement will be -500. - * - * @var bool - */ + |-------------------------------------------------------------------------- + | Rollback Cost + |-------------------------------------------------------------------------- + | + | For example, if the movement's cost that is being rolled + | back is 500, the rolled back movement will be -500. + | + */ + 'rollback_cost' => true, /* - * Enables SKUs to be automatically generated on item creation - * - * @var bool - */ + |-------------------------------------------------------------------------- + | Skus Enabled + |-------------------------------------------------------------------------- + | + | Enables SKUs to be automatically generated on item creation. + | + */ + 'skus_enabled' => true, /* - * The sku prefix length, not including the code for example: - * - * An item with a category named 'Sauce', the sku prefix generated will be: SAU - * - * @var int - */ + |-------------------------------------------------------------------------- + | Sku Prefix Length + |-------------------------------------------------------------------------- + | + | The sku prefix length, not including the code for example: + | + | An item with a category named 'Sauce', the sku prefix generated will be: SAU + | + */ + 'sku_prefix_length' => 3, /* - * The sku code length, not including prefix for example: - * - * An item with an ID of 1 (one) the sku code will be: 000001 - * - * @var int - */ + |-------------------------------------------------------------------------- + | Sku Code Length + |-------------------------------------------------------------------------- + | + | The sku code length, not including prefix for example: + | + | An item with an ID of 1 (one) the sku code will be: 000001 + | + */ + 'sku_code_length' => 6, /* @@ -62,6 +81,19 @@ * * @var string */ + + /* + |-------------------------------------------------------------------------- + | Sku Separator + |-------------------------------------------------------------------------- + | + | The sku separator for use in separating the prefix from the code. + | + | For example, if a hyphen (-) is inserted in the string + | below, a possible SKU might be 'DRI-00001' + | + */ + 'sku_separator' => '', ]; From f8f3ba7312efe22c1caa93cf8519b608db19a913 Mon Sep 17 00:00:00 2001 From: Steve Bauman Date: Tue, 10 May 2016 09:17:15 -0400 Subject: [PATCH 50/51] Cleaning. --- src/InventoryServiceProvider.php | 20 +++----------------- src/Models/BaseModel.php | 1 + src/Models/Category.php | 7 ------- src/Models/Inventory.php | 10 +++++----- src/Models/InventorySku.php | 9 +-------- src/Models/InventoryStock.php | 15 ++++----------- src/Models/InventoryStockMovement.php | 9 +-------- src/Models/InventoryTransaction.php | 11 ++--------- src/Models/InventoryTransactionHistory.php | 9 +-------- src/Models/Location.php | 9 +-------- src/Models/Metric.php | 9 +-------- src/Models/Supplier.php | 9 +-------- 12 files changed, 21 insertions(+), 97 deletions(-) diff --git a/src/InventoryServiceProvider.php b/src/InventoryServiceProvider.php index 5d0adb75..69a5d28b 100644 --- a/src/InventoryServiceProvider.php +++ b/src/InventoryServiceProvider.php @@ -14,16 +14,9 @@ class InventoryServiceProvider extends ServiceProvider const VERSION = '1.8.0'; /** - * Indicates if loading of the provider is deferred. - * - * @var bool + * {@inheritdoc} */ - protected $defer = false; - - /** - * Boot the service provider. - */ - public function boot() + public function register() { // Load the inventory translations from the inventory lang folder $this->loadTranslationsFrom(__DIR__.'/Lang', 'inventory'); @@ -39,15 +32,8 @@ public function boot() ], 'migrations'); } - public function register() - { - // - } - /** - * Get the services provided by the provider. - * - * @return array + * {@inheritdoc} */ public function provides() { diff --git a/src/Models/BaseModel.php b/src/Models/BaseModel.php index c4726674..4a90ef1d 100644 --- a/src/Models/BaseModel.php +++ b/src/Models/BaseModel.php @@ -6,4 +6,5 @@ class BaseModel extends Eloquent { + // } diff --git a/src/Models/Category.php b/src/Models/Category.php index 69a2db7c..5848fd64 100644 --- a/src/Models/Category.php +++ b/src/Models/Category.php @@ -9,13 +9,6 @@ class Category extends Node { use CategoryTrait; - /** - * The category table. - * - * @var string - */ - protected $table = 'categories'; - /** * The scoped category attrbiutes. * diff --git a/src/Models/Inventory.php b/src/Models/Inventory.php index ff215832..80340217 100644 --- a/src/Models/Inventory.php +++ b/src/Models/Inventory.php @@ -26,7 +26,7 @@ class Inventory extends BaseModel */ public function category() { - return $this->hasOne('Stevebauman\Inventory\Models\Category', 'id', 'category_id'); + return $this->hasOne(Category::class); } /** @@ -36,7 +36,7 @@ public function category() */ public function metric() { - return $this->hasOne('Stevebauman\Inventory\Models\Metric', 'id', 'metric_id'); + return $this->hasOne(Metric::class); } /** @@ -46,7 +46,7 @@ public function metric() */ public function sku() { - return $this->hasOne('Stevebauman\Inventory\Models\InventorySku', 'inventory_id', 'id'); + return $this->hasOne(InventorySku::class, 'inventory_id', 'id'); } /** @@ -56,7 +56,7 @@ public function sku() */ public function stocks() { - return $this->hasMany('Stevebauman\Inventory\Models\InventoryStock', 'inventory_id', 'id'); + return $this->hasMany(InventoryStock::class, 'inventory_id', 'id'); } /** @@ -66,7 +66,7 @@ public function stocks() */ public function suppliers() { - return $this->belongsToMany('Stevebauman\Inventory\Models\Supplier', 'inventory_suppliers', 'inventory_id')->withTimestamps(); + return $this->belongsToMany(Supplier::class, 'inventory_suppliers', 'inventory_id')->withTimestamps(); } /** diff --git a/src/Models/InventorySku.php b/src/Models/InventorySku.php index 718731bb..473484f3 100644 --- a/src/Models/InventorySku.php +++ b/src/Models/InventorySku.php @@ -8,13 +8,6 @@ class InventorySku extends BaseModel { use InventorySkuTrait; - /** - * The inventory SKU table. - * - * @var string - */ - protected $table = 'inventory_skus'; - /** * The belongsTo item trait. * @@ -22,6 +15,6 @@ class InventorySku extends BaseModel */ public function item() { - return $this->belongsTo('Stevebauman\Inventory\Models\Inventory', 'inventory_id', 'id'); + return $this->belongsTo(Inventory::class, 'inventory_id', 'id'); } } diff --git a/src/Models/InventoryStock.php b/src/Models/InventoryStock.php index 18cefa38..9cacf694 100644 --- a/src/Models/InventoryStock.php +++ b/src/Models/InventoryStock.php @@ -8,13 +8,6 @@ class InventoryStock extends BaseModel { use InventoryStockTrait; - /** - * The inventory stocks table. - * - * @var string - */ - protected $table = 'inventory_stocks'; - /** * The belongsTo inventory item relationship. * @@ -22,7 +15,7 @@ class InventoryStock extends BaseModel */ public function item() { - return $this->belongsTo('Stevebauman\Inventory\Models\Inventory', 'inventory_id', 'id'); + return $this->belongsTo(Inventory::class, 'inventory_id', 'id'); } /** @@ -32,7 +25,7 @@ public function item() */ public function movements() { - return $this->hasMany('Stevebauman\Inventory\Models\InventoryStockMovement', 'stock_id', 'id'); + return $this->hasMany(InventoryStockMovement::class, 'stock_id', 'id'); } /** @@ -42,7 +35,7 @@ public function movements() */ public function transactions() { - return $this->hasMany('Stevebauman\Inventory\Models\InventoryTransaction', 'stock_id', 'id'); + return $this->hasMany(InventoryTransaction::class, 'stock_id', 'id'); } /** @@ -52,6 +45,6 @@ public function transactions() */ public function location() { - return $this->hasOne('Stevebauman\Inventory\Models\Location', 'id', 'location_id'); + return $this->hasOne(Location::class); } } diff --git a/src/Models/InventoryStockMovement.php b/src/Models/InventoryStockMovement.php index cd59833d..4313c981 100644 --- a/src/Models/InventoryStockMovement.php +++ b/src/Models/InventoryStockMovement.php @@ -8,13 +8,6 @@ class InventoryStockMovement extends BaseModel { use InventoryStockMovementTrait; - /** - * The inventory stock movements table. - * - * @var string - */ - protected $table = 'inventory_stock_movements'; - /** * The belongsTo stock relationship. * @@ -22,6 +15,6 @@ class InventoryStockMovement extends BaseModel */ public function stock() { - return $this->belongsTo('Stevebauman\Inventory\Models\InventoryStock', 'stock_id', 'id'); + return $this->belongsTo(InventoryStock::class); } } diff --git a/src/Models/InventoryTransaction.php b/src/Models/InventoryTransaction.php index 89bb11a1..48c1d8de 100644 --- a/src/Models/InventoryTransaction.php +++ b/src/Models/InventoryTransaction.php @@ -9,13 +9,6 @@ class InventoryTransaction extends BaseModel implements StateableInterface { use InventoryTransactionTrait; - /** - * The inventory transactions table. - * - * @var string - */ - protected $table = 'inventory_transactions'; - /** * The belongsTo stock relationship. * @@ -23,7 +16,7 @@ class InventoryTransaction extends BaseModel implements StateableInterface */ public function stock() { - return $this->belongsTo('Stevebauman\Inventory\Models\InventoryStock', 'stock_id', 'id'); + return $this->belongsTo(InventoryStock::class, 'stock_id', 'id'); } /** @@ -33,6 +26,6 @@ public function stock() */ public function histories() { - return $this->hasMany('Stevebauman\Inventory\Models\InventoryTransactionHistory', 'transaction_id', 'id'); + return $this->hasMany(InventoryTransactionHistory::class, 'transaction_id', 'id'); } } diff --git a/src/Models/InventoryTransactionHistory.php b/src/Models/InventoryTransactionHistory.php index 1b390da8..5d1739df 100644 --- a/src/Models/InventoryTransactionHistory.php +++ b/src/Models/InventoryTransactionHistory.php @@ -8,13 +8,6 @@ class InventoryTransactionHistory extends BaseModel { use InventoryTransactionHistoryTrait; - /** - * The inventory transaction histories table. - * - * @var string - */ - protected $table = 'inventory_transaction_histories'; - /** * The belongsTo transaction relationship. * @@ -22,6 +15,6 @@ class InventoryTransactionHistory extends BaseModel */ public function transaction() { - return $this->belongsTo('Stevebauman\Inventory\Models\InventoryTransaction', 'transaction_id', 'id'); + return $this->belongsTo(InventoryTransaction::class); } } diff --git a/src/Models/Location.php b/src/Models/Location.php index 7f6659ad..cd550894 100644 --- a/src/Models/Location.php +++ b/src/Models/Location.php @@ -6,13 +6,6 @@ class Location extends Node { - /** - * The locations table. - * - * @var string - */ - protected $table = 'locations'; - /** * The scoped location attributes. * @@ -27,6 +20,6 @@ class Location extends Node */ public function stocks() { - return $this->hasMany('Stevebauman\Inventory\Models\InventoryStock', 'location_id', 'id'); + return $this->hasMany(InventoryStock::class, 'location_id', 'id'); } } diff --git a/src/Models/Metric.php b/src/Models/Metric.php index bd3a71dc..3b7b851f 100644 --- a/src/Models/Metric.php +++ b/src/Models/Metric.php @@ -4,13 +4,6 @@ class Metric extends BaseModel { - /** - * The metrics table. - * - * @var string - */ - protected $table = 'metrics'; - /** * The hasMany inventory items relationship. * @@ -18,6 +11,6 @@ class Metric extends BaseModel */ public function items() { - return $this->hasMany('Stevebauman\Inventory\Models\Inventory', 'metric_id', 'id'); + return $this->hasMany(Inventory::class, 'metric_id', 'id'); } } diff --git a/src/Models/Supplier.php b/src/Models/Supplier.php index b8495b23..42c5a507 100644 --- a/src/Models/Supplier.php +++ b/src/Models/Supplier.php @@ -8,13 +8,6 @@ class Supplier extends BaseModel { use SupplierTrait; - /** - * The suppliers table. - * - * @var string - */ - protected $table = 'suppliers'; - /** * The belongsToMany items relationship. * @@ -22,6 +15,6 @@ class Supplier extends BaseModel */ public function items() { - return $this->belongsToMany('Stevebauman\Inventory\Models\Inventory', 'inventory_suppliers', 'supplier_id')->withTimestamps(); + return $this->belongsToMany(Inventory::class, 'inventory_suppliers', 'supplier_id')->withTimestamps(); } } From 57566ab55c5330367dcbed92a671f36d2528d604 Mon Sep 17 00:00:00 2001 From: Steve Bauman Date: Tue, 10 May 2016 09:29:43 -0400 Subject: [PATCH 51/51] Replace all private methods with protected. --- src/Lang/en/exceptions.php | 5 -- src/Lang/en/reasons.php | 6 +- src/Models/BaseModel.php | 2 +- src/Models/Inventory.php | 2 +- src/Models/InventorySku.php | 2 +- src/Models/InventoryStock.php | 2 +- src/Models/InventoryStockMovement.php | 2 +- src/Models/InventoryTransaction.php | 2 +- src/Models/InventoryTransactionHistory.php | 2 +- src/Models/Metric.php | 2 +- src/Models/Supplier.php | 2 +- src/Traits/AssemblyTrait.php | 24 ++++---- src/Traits/CommonMethodsTrait.php | 30 +++------- src/Traits/InventoryStockMovementTrait.php | 2 + src/Traits/InventoryStockTrait.php | 58 +++++++++---------- src/Traits/InventoryTrait.php | 9 +-- .../InventoryTransactionHistoryTrait.php | 2 + src/Traits/InventoryTransactionTrait.php | 27 +++++---- src/Traits/InventoryVariantTrait.php | 2 +- 19 files changed, 77 insertions(+), 106 deletions(-) diff --git a/src/Lang/en/exceptions.php b/src/Lang/en/exceptions.php index df714ac5..18b20179 100644 --- a/src/Lang/en/exceptions.php +++ b/src/Lang/en/exceptions.php @@ -1,10 +1,5 @@ 'Movement :movement is invalid', diff --git a/src/Lang/en/reasons.php b/src/Lang/en/reasons.php index 4f790716..6b2fb464 100644 --- a/src/Lang/en/reasons.php +++ b/src/Lang/en/reasons.php @@ -1,10 +1,5 @@ 'First Item Record; Stock Increase', @@ -41,4 +36,5 @@ 'cancelled' => 'Cancellation occurred on Transaction ID :id on :date', ], + ]; diff --git a/src/Models/BaseModel.php b/src/Models/BaseModel.php index 4a90ef1d..43fe346c 100644 --- a/src/Models/BaseModel.php +++ b/src/Models/BaseModel.php @@ -4,7 +4,7 @@ use Illuminate\Database\Eloquent\Model as Eloquent; -class BaseModel extends Eloquent +class Model extends Eloquent { // } diff --git a/src/Models/Inventory.php b/src/Models/Inventory.php index 80340217..c2dd6750 100644 --- a/src/Models/Inventory.php +++ b/src/Models/Inventory.php @@ -6,7 +6,7 @@ use Stevebauman\Inventory\Traits\InventoryVariantTrait; use Stevebauman\Inventory\Traits\InventoryTrait; -class Inventory extends BaseModel +class Inventory extends Model { use InventoryTrait; use InventoryVariantTrait; diff --git a/src/Models/InventorySku.php b/src/Models/InventorySku.php index 473484f3..f8b30a0d 100644 --- a/src/Models/InventorySku.php +++ b/src/Models/InventorySku.php @@ -4,7 +4,7 @@ use Stevebauman\Inventory\Traits\InventorySkuTrait; -class InventorySku extends BaseModel +class InventorySku extends Model { use InventorySkuTrait; diff --git a/src/Models/InventoryStock.php b/src/Models/InventoryStock.php index 9cacf694..a0e3b7b1 100644 --- a/src/Models/InventoryStock.php +++ b/src/Models/InventoryStock.php @@ -4,7 +4,7 @@ use Stevebauman\Inventory\Traits\InventoryStockTrait; -class InventoryStock extends BaseModel +class InventoryStock extends Model { use InventoryStockTrait; diff --git a/src/Models/InventoryStockMovement.php b/src/Models/InventoryStockMovement.php index 4313c981..7520f1f7 100644 --- a/src/Models/InventoryStockMovement.php +++ b/src/Models/InventoryStockMovement.php @@ -4,7 +4,7 @@ use Stevebauman\Inventory\Traits\InventoryStockMovementTrait; -class InventoryStockMovement extends BaseModel +class InventoryStockMovement extends Model { use InventoryStockMovementTrait; diff --git a/src/Models/InventoryTransaction.php b/src/Models/InventoryTransaction.php index 48c1d8de..db1f44fd 100644 --- a/src/Models/InventoryTransaction.php +++ b/src/Models/InventoryTransaction.php @@ -5,7 +5,7 @@ use Stevebauman\Inventory\Traits\InventoryTransactionTrait; use Stevebauman\Inventory\Interfaces\StateableInterface; -class InventoryTransaction extends BaseModel implements StateableInterface +class InventoryTransaction extends Model implements StateableInterface { use InventoryTransactionTrait; diff --git a/src/Models/InventoryTransactionHistory.php b/src/Models/InventoryTransactionHistory.php index 5d1739df..0bc2c45a 100644 --- a/src/Models/InventoryTransactionHistory.php +++ b/src/Models/InventoryTransactionHistory.php @@ -4,7 +4,7 @@ use Stevebauman\Inventory\Traits\InventoryTransactionHistoryTrait; -class InventoryTransactionHistory extends BaseModel +class InventoryTransactionHistory extends Model { use InventoryTransactionHistoryTrait; diff --git a/src/Models/Metric.php b/src/Models/Metric.php index 3b7b851f..21e96d45 100644 --- a/src/Models/Metric.php +++ b/src/Models/Metric.php @@ -2,7 +2,7 @@ namespace Stevebauman\Inventory\Models; -class Metric extends BaseModel +class Metric extends Model { /** * The hasMany inventory items relationship. diff --git a/src/Models/Supplier.php b/src/Models/Supplier.php index 42c5a507..3331f589 100644 --- a/src/Models/Supplier.php +++ b/src/Models/Supplier.php @@ -4,7 +4,7 @@ use Stevebauman\Inventory\Traits\SupplierTrait; -class Supplier extends BaseModel +class Supplier extends Model { use SupplierTrait; diff --git a/src/Traits/AssemblyTrait.php b/src/Traits/AssemblyTrait.php index 734f6568..cb34d6f6 100644 --- a/src/Traits/AssemblyTrait.php +++ b/src/Traits/AssemblyTrait.php @@ -100,10 +100,8 @@ public function getAssemblyItems($recursive = true) if (!$results) { $results = $this->assembliesRecursive; - /* - * Cache forever since adding / removing assembly - * items will automatically clear this cache - */ + // Cache forever since adding / removing assembly + // items will automatically clear this cache. Cache::forever($this->getAssemblyCacheKey(), $results); } @@ -134,12 +132,12 @@ public function getAssemblyItemsList($recursive = true, $depth = 0) foreach ($items as $item) { $list[$level] = [ - 'id' => $item->getKey(), - 'name' => $item->name, - 'metric_id' => $item->metric_id, - 'category_id' => $item->category_id, - 'quantity' => $item->pivot->quantity, - 'depth' => $depth, + 'id' => $item->getKey(), + 'name' => $item->name, + 'metric_id' => $item->metric_id, + 'category_id' => $item->category_id, + 'quantity' => $item->pivot->quantity, + 'depth' => $depth, ]; if ($item->is_assembly && $recursive) { @@ -351,7 +349,7 @@ public function scopeAssembly(Builder $query) * * @throws InvalidPartException */ - private function validatePart(Model $part) + protected function validatePart(Model $part) { if ((int) $part->getKey() === (int) $this->getKey()) { $message = 'An item cannot be an assembly of itself.'; @@ -376,7 +374,7 @@ private function validatePart(Model $part) * * @throws InvalidPartException */ - private function validatePartAgainstList($value, $key) + protected function validatePartAgainstList($value, $key) { if ((string) $key === (string) $this->getKeyName()) { if ((int) $value === (int) $this->getKey()) { @@ -392,7 +390,7 @@ private function validatePartAgainstList($value, $key) * * @return string */ - private function getAssemblyCacheKey() + protected function getAssemblyCacheKey() { return $this->assemblyCacheKey.$this->getKey(); } diff --git a/src/Traits/CommonMethodsTrait.php b/src/Traits/CommonMethodsTrait.php index bc5854d0..3b6dd5db 100644 --- a/src/Traits/CommonMethodsTrait.php +++ b/src/Traits/CommonMethodsTrait.php @@ -2,6 +2,7 @@ namespace Stevebauman\Inventory\Traits; +use Illuminate\Database\Eloquent\Model; use Illuminate\Support\Facades\Lang; use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\Event; @@ -10,35 +11,22 @@ trait CommonMethodsTrait { /** - * Returns the models identifier key. - * - * @return int|string + * {@inheritdoc} */ abstract public function getKey(); /** - * Returns the models identifier key name. - * - * @return string + * {@inheritdoc} */ abstract public function getKeyName(); /** - * Returns a attribute from the model. - * - * @param string $key - * - * @return mixed + * {@inheritdoc} */ abstract public function getAttribute($key); /** - * Set a given attribute on the model. - * - * @param string $key - * @param mixed $value - * - * @return void + * {@inheritdoc} */ abstract public function setAttribute($key, $value); @@ -115,7 +103,7 @@ protected function dbRollbackTransaction() * * @return bool */ - private function isNumeric($number) + protected function isNumeric($number) { return (is_numeric($number) ? true : false); } @@ -127,7 +115,7 @@ private function isNumeric($number) * * @return bool */ - private function isPositive($number) + protected function isPositive($number) { if ($this->isNumeric($number)) { return ($number >= 0 ? true : false); @@ -144,8 +132,8 @@ private function isPositive($number) * * @return bool */ - private function isModel($model) + protected function isModel($model) { - return is_subclass_of($model, 'Illuminate\Database\Eloquent\Model'); + return $model instanceof Model; } } diff --git a/src/Traits/InventoryStockMovementTrait.php b/src/Traits/InventoryStockMovementTrait.php index fdd1eae1..c48c8f2d 100644 --- a/src/Traits/InventoryStockMovementTrait.php +++ b/src/Traits/InventoryStockMovementTrait.php @@ -19,6 +19,8 @@ abstract public function stock(); /** * Overrides the models boot function to set * the user ID automatically to every new record. + * + * @return void */ public static function bootInventoryStockMovementTrait() { diff --git a/src/Traits/InventoryStockTrait.php b/src/Traits/InventoryStockTrait.php index b6257430..423e78bc 100644 --- a/src/Traits/InventoryStockTrait.php +++ b/src/Traits/InventoryStockTrait.php @@ -12,9 +12,6 @@ trait InventoryStockTrait { - /* - * Verification helper functions - */ use CommonMethodsTrait; /** @@ -36,7 +33,7 @@ trait InventoryStockTrait * * @var int|float|string */ - private $beforeQuantity = 0; + protected $beforeQuantity = 0; /** * The hasOne location relationship. @@ -75,10 +72,8 @@ public static function bootInventoryStockTrait() static::creating(function (Model $model) { $model->setAttribute('user_id', Helper::getCurrentUserId()); - /* - * Check if a reason has been set, if not - * let's retrieve the default first entry reason - */ + // Check if a reason has been set, if not let's + // retrieve the default first entry reason. if (!$model->reason) { $model->reason = Lang::get('inventory::reasons.first_record'); } @@ -89,15 +84,12 @@ public static function bootInventoryStockTrait() }); static::updating(function (Model $model) { - /* - * Retrieve the original quantity before it was updated, - * so we can create generate an update with it - */ + // Retrieve the original quantity before it was updated, + // so we can create generate an update with it. $model->beforeQuantity = $model->getOriginal('quantity'); - /* - * Check if a reason has been set, if not let's retrieve the default change reason - */ + // Check if a reason has been set, if not let's + // retrieve the default change reason. if (!$model->reason) { $model->reason = Lang::get('inventory::reasons.change'); } @@ -110,6 +102,8 @@ public static function bootInventoryStockTrait() /** * Generates a stock movement after a stock is created. + * + * @return void */ public function postCreate() { @@ -118,6 +112,8 @@ public function postCreate() /** * Generates a stock movement after a stock is updated. + * + * @return void */ public function postUpdate() { @@ -351,7 +347,7 @@ public function newTransaction($name = '') * * @return null|Model */ - private function getMovementById($id) + protected function getMovementById($id) { return $this->movements()->find($id); } @@ -365,7 +361,7 @@ private function getMovementById($id) * * @return $this */ - private function processUpdateQuantityOperation($quantity, $reason = '', $cost = 0) + protected function processUpdateQuantityOperation($quantity, $reason = '', $cost = 0) { $current = $this->getAttribute('quantity'); @@ -389,7 +385,7 @@ private function processUpdateQuantityOperation($quantity, $reason = '', $cost = * * @return $this|bool */ - private function processTakeOperation($taking, $reason = '', $cost = 0) + protected function processTakeOperation($taking, $reason = '', $cost = 0) { if($this->isValidQuantity($taking) && $this->hasEnoughStock($taking)) { $available = $this->getAttribute('quantity'); @@ -440,17 +436,15 @@ private function processTakeOperation($taking, $reason = '', $cost = 0) * * @return $this|bool */ - private function processPutOperation($putting, $reason = '', $cost = 0) + protected function processPutOperation($putting, $reason = '', $cost = 0) { if($this->isValidQuantity($putting)) { $current = $this->getAttribute('quantity'); $total = (float) $putting + (float) $current; - /* - * If the updated total and the beginning total are the same, - * we'll check if duplicate movements are allowed - */ + // If the updated total and the beginning total are the same, + // we'll check if duplicate movements are allowed. if ((float) $total === (float) $current && !$this->allowDuplicateMovementsEnabled()) { return $this; } @@ -489,7 +483,7 @@ private function processPutOperation($putting, $reason = '', $cost = 0) * * @return bool */ - private function processMoveOperation(Model $location) + protected function processMoveOperation(Model $location) { $this->setAttribute('location_id', $location->getKey()); @@ -520,7 +514,7 @@ private function processMoveOperation(Model $location) * * @return $this|bool */ - private function processRollbackOperation(Model $movement, $recursive = false) + protected function processRollbackOperation(Model $movement, $recursive = false) { if ($recursive) { return $this->processRecursiveRollbackOperation($movement); @@ -567,7 +561,7 @@ private function processRollbackOperation(Model $movement, $recursive = false) * * @return array */ - private function processRecursiveRollbackOperation(Model $movement) + protected function processRecursiveRollbackOperation(Model $movement) { /* * Retrieve movements that were created after @@ -600,7 +594,7 @@ private function processRecursiveRollbackOperation(Model $movement) * * @return bool|Model */ - private function generateStockMovement($before, $after, $reason = '', $cost = 0) + protected function generateStockMovement($before, $after, $reason = '', $cost = 0) { $movement = $this->movements()->getRelated()->newInstance(); @@ -622,7 +616,7 @@ private function generateStockMovement($before, $after, $reason = '', $cost = 0) * * @param int|float|string $cost */ - private function setCost($cost = 0) + protected function setCost($cost = 0) { $this->cost = (float) $cost; } @@ -630,7 +624,7 @@ private function setCost($cost = 0) /** * Reverses the cost of a movement. */ - private function reverseCost() + protected function reverseCost() { $cost = $this->getAttribute('cost'); @@ -646,7 +640,7 @@ private function reverseCost() * * @param string $reason */ - private function setReason($reason = '') + protected function setReason($reason = '') { $this->reason = $reason; } @@ -658,7 +652,7 @@ private function setReason($reason = '') * * @return bool */ - private function allowDuplicateMovementsEnabled() + protected function allowDuplicateMovementsEnabled() { return Config::get('inventory.allow_duplicate_movements'); } @@ -670,7 +664,7 @@ private function allowDuplicateMovementsEnabled() * * @return bool */ - private function rollbackCostEnabled() + protected function rollbackCostEnabled() { return Config::get('inventory.rollback_cost'); } diff --git a/src/Traits/InventoryTrait.php b/src/Traits/InventoryTrait.php index 6c3e1a90..ba6190b3 100644 --- a/src/Traits/InventoryTrait.php +++ b/src/Traits/InventoryTrait.php @@ -12,9 +12,6 @@ trait InventoryTrait { - /* - * Common Helper Methods - */ use CommonMethodsTrait; /** @@ -654,7 +651,7 @@ public function updateSku($code, $sku = null) * * @return bool|mixed */ - private function processSkuGeneration($inventoryId, $code) + protected function processSkuGeneration($inventoryId, $code) { $this->dbStartTransaction(); @@ -690,7 +687,7 @@ private function processSkuGeneration($inventoryId, $code) * * @return mixed|bool */ - private function processSkuUpdate(Model $sku, $code) + protected function processSkuUpdate(Model $sku, $code) { $this->dbStartTransaction(); @@ -713,7 +710,7 @@ private function processSkuUpdate(Model $sku, $code) * * @return mixed */ - private function skusEnabled() + protected function skusEnabled() { return Config::get('inventory.skus_enabled', false); } diff --git a/src/Traits/InventoryTransactionHistoryTrait.php b/src/Traits/InventoryTransactionHistoryTrait.php index d00b5509..45dc5c91 100644 --- a/src/Traits/InventoryTransactionHistoryTrait.php +++ b/src/Traits/InventoryTransactionHistoryTrait.php @@ -9,6 +9,8 @@ trait InventoryTransactionHistoryTrait { /** * Make sure we try and assign the current user if enabled. + * + * @return void */ public static function bootInventoryTransactionHistoryTrait() { diff --git a/src/Traits/InventoryTransactionTrait.php b/src/Traits/InventoryTransactionTrait.php index 0ae9cef7..03014fa3 100644 --- a/src/Traits/InventoryTransactionTrait.php +++ b/src/Traits/InventoryTransactionTrait.php @@ -13,9 +13,6 @@ trait InventoryTransactionTrait { - /* - * Common Inventory Helper Methods - */ use CommonMethodsTrait; /** @@ -35,6 +32,8 @@ trait InventoryTransactionTrait /** * Overrides the models boot function to generate a new transaction history * record when it is created and updated. + * + * @return void */ public static function bootInventoryTransactionTrait() { @@ -1134,7 +1133,7 @@ public function setStateAttribute($state) * * @return $this|bool */ - private function returnToPreviousState($previousState) + protected function returnToPreviousState($previousState) { $this->setAttribute('state', $previousState); @@ -1148,7 +1147,7 @@ private function returnToPreviousState($previousState) * * @return $this|bool */ - private function reservedFromCheckout() + protected function reservedFromCheckout() { $this->setAttribute('state', $this::STATE_COMMERCE_RESERVED); @@ -1161,7 +1160,7 @@ private function reservedFromCheckout() * * @return $this|bool */ - private function checkoutFromReserved() + protected function checkoutFromReserved() { $this->setAttribute('state', $this::STATE_COMMERCE_CHECKOUT); @@ -1179,7 +1178,7 @@ private function checkoutFromReserved() * * @return bool */ - private function validatePreviousState($allowedStates = [], $toState) + protected function validatePreviousState($allowedStates = [], $toState) { $state = $this->getAttribute('state'); @@ -1204,7 +1203,7 @@ private function validatePreviousState($allowedStates = [], $toState) * * @return bool */ - private function validateStateIsAvailable($state) + protected function validateStateIsAvailable($state) { if (!in_array($state, $this->getAvailableStates())) { $message = "State: $state is an invalid state, and cannot be used."; @@ -1229,7 +1228,7 @@ private function validateStateIsAvailable($state) * * @return $this|bool */ - private function processStockPutAndSave($quantity, $event = '', $reason = '', $cost = 0) + protected function processStockPutAndSave($quantity, $event = '', $reason = '', $cost = 0) { $stock = $this->getStockRecord(); @@ -1265,7 +1264,7 @@ private function processStockPutAndSave($quantity, $event = '', $reason = '', $c * * @return $this|bool */ - private function processStockTakeAndSave($quantity, $event = '', $reason = '', $cost = 0) + protected function processStockTakeAndSave($quantity, $event = '', $reason = '', $cost = 0) { $stock = $this->getStockRecord(); @@ -1300,7 +1299,7 @@ private function processStockTakeAndSave($quantity, $event = '', $reason = '', $ * * @return $this|bool */ - private function processSave($event = '') + protected function processSave($event = '') { $this->dbStartTransaction(); @@ -1331,7 +1330,7 @@ private function processSave($event = '') * * @return bool|Model */ - private function generateTransactionHistory($stateBefore, $stateAfter, $quantityBefore = 0, $quantityAfter = 0) + protected function generateTransactionHistory($stateBefore, $stateAfter, $quantityBefore = 0, $quantityAfter = 0) { $history = $this->histories()->getRelated()->newInstance(); @@ -1356,7 +1355,7 @@ private function generateTransactionHistory($stateBefore, $stateAfter, $quantity * * @return string */ - private function getTransactionReason($key) + protected function getTransactionReason($key) { $reason = Lang::get('inventory::reasons.transactions.'.$key, ['id' => $this->getKey(), 'date' => date('Y-m-d H:i:s')]); @@ -1376,7 +1375,7 @@ private function getTransactionReason($key) * * @return array */ - private function getAvailableStates() + protected function getAvailableStates() { return [ self::STATE_COMMERCE_CHECKOUT, diff --git a/src/Traits/InventoryVariantTrait.php b/src/Traits/InventoryVariantTrait.php index 87a02b25..6af4ca9c 100644 --- a/src/Traits/InventoryVariantTrait.php +++ b/src/Traits/InventoryVariantTrait.php @@ -219,7 +219,7 @@ public function makeVariantOf(Model $item) * * @return $this|bool */ - private function processMakeVariant($itemId) + protected function processMakeVariant($itemId) { $this->dbStartTransaction();