From 865024dd775a20e8e7ba7418e18e543fffeb10a1 Mon Sep 17 00:00:00 2001 From: Sam Lee Date: Sun, 23 Feb 2025 22:09:21 +0900 Subject: [PATCH] Add `Location` class for `locationCode()` method --- README.md | 10 ++++ src/Location.php | 105 +++++++++++++++++++++++++++++++++++++++++ tests/LocationTest.php | 101 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 216 insertions(+) create mode 100644 src/Location.php create mode 100644 tests/LocationTest.php diff --git a/README.md b/README.md index d0c2a49..d592287 100644 --- a/README.md +++ b/README.md @@ -22,6 +22,7 @@ We have provided the API Documentation on the web. For more information, please - [x] Complex good code parser - [x] Option Good code parser(No code, it matched by name) - [x] Receipt code parser +- [x] Location code parser ## Install @@ -202,6 +203,15 @@ print ReceiptCode::of(prefix: 'CT')->nextCode(); //=> CT-[Today's ymd]-0001 ``` +### Location Code + +```php +print Location::of(warehouse: 'AUK', rack: 'R3', shelf: 'S32')->locationCode(); +print Location::of(['warehouse' => 'AUK', 'rack' => 'R3', 'shelf' => 'S32')->locationCode(); +print Location::of(warehouse: 'AUK', rack: 'R3', shelf: 'S32'); //` Stringable` supported +//=> AUK-R3-S32 +``` + ## Formatting ```sh diff --git a/src/Location.php b/src/Location.php new file mode 100644 index 0000000..c59cbcb --- /dev/null +++ b/src/Location.php @@ -0,0 +1,105 @@ +warehouse = $warehouse ?? ''; + $this->rack = $rack ?? ''; + $this->shelf = $shelf ?? ''; + + $this->locationCode = implode('-', array_filter([ + $this->warehouse, + $this->rack, + $this->shelf, + ])); + + $this->locationCode = preg_replace('/-+/', '-', $this->locationCode); + } + + public function locationCode(): string + { + return $this->locationCode; + } + + /** + * Create a new Location instance. + * + * @param string|array|null $warehouse Warehouse ID or array of arguments + * @param string|null $rack Rack + * @param string|null $shelf Shelf + * @return self Provides fluent interface + * + * @throws \InvalidArgumentException + */ + public static function of( + string|array|null $warehouse = null, + ?string $rack = null, + ?string $shelf = null + ): self { + if (is_array($warehouse)) { + if (empty($warehouse)) { + throw new \InvalidArgumentException('At least one parameter must be provided.'); + } + + $disallowedKeys = array_diff_key($warehouse, array_flip(['warehouse', 'rack', 'shelf'])); + + if (! empty($disallowedKeys)) { + throw new \InvalidArgumentException('Invalid key(s): '.implode(', ', array_keys($disallowedKeys))); + } + + return new self( + warehouse: $warehouse['warehouse'] ?? null, + rack: $warehouse['rack'] ?? null, + shelf: $warehouse['shelf'] ?? null + ); + } + + return new self( + warehouse: $warehouse, + rack: $rack, + shelf: $shelf + ); + } + + public function __toString(): string + { + return $this->locationCode; + } +} diff --git a/tests/LocationTest.php b/tests/LocationTest.php new file mode 100644 index 0000000..7208286 --- /dev/null +++ b/tests/LocationTest.php @@ -0,0 +1,101 @@ +assertEquals('AUK-R3-S32', Location::of( + warehouse: 'AUK', + rack: 'R3', + shelf: 'S32' + )->locationCode()); + + $this->assertEquals('AUK-R3-S32', Location::of([ + 'warehouse' => 'AUK', + 'rack' => 'R3', + 'shelf' => 'S32', + ])->locationCode()); + } + + public function test_location_code_without_warehouse() + { + $this->assertEquals('R3-S32', Location::of( + rack: 'R3', + shelf: 'S32' + )->locationCode()); + + $this->assertEquals('R3-S32', Location::of([ + 'rack' => 'R3', + 'shelf' => 'S32', + ])->locationCode()); + } + + public function test_location_code_without_shelf() + { + $this->assertEquals('AUK-R3', Location::of( + warehouse: 'AUK', + rack: 'R3' + )->locationCode()); + + $this->assertEquals('AUK-R3', Location::of([ + 'warehouse' => 'AUK', + 'rack' => 'R3', + ])->locationCode()); + } + + public function test_location_code_with_only_warehouse() + { + $this->assertEquals('AUK', Location::of( + warehouse: 'AUK' + )->locationCode()); + + $this->assertEquals('AUK', Location::of([ + 'warehouse' => 'AUK', + ])->locationCode()); + } + + public function test_location_code_with_only_rack_excepted() + { + $this->expectException(\InvalidArgumentException::class); + + Location::of([ + 'rack2' => 'R3', + ]); + } + + public function test_location_code_with_only_shelf_excepted() + { + $this->expectException(\InvalidArgumentException::class); + + Location::of([ + 'shelf2' => 'S32', + ]); + } + + public function test_location_code_with_empty() + { + $this->expectException(\InvalidArgumentException::class); + + Location::of(); + } + + public function test_location_code_to_string() + { + $this->assertEquals('AUK-R3-S32', (string) Location::of( + warehouse: 'AUK', + rack: 'R3', + shelf: 'S32' + )); + + $this->assertEquals('AUK-R3-S32', (string) Location::of([ + 'warehouse' => 'AUK', + 'rack' => 'R3', + 'shelf' => 'S32', + ])); + } +}