Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -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
Expand Down
105 changes: 105 additions & 0 deletions src/Location.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
<?php

namespace Cable8mm\GoodCode;

use Stringable;

class Location implements Stringable
{
/**
* Code representing the product’s storage location
*
* @example A1-B3-S5
*/
private string $locationCode;

private function __construct(
/**
* Warehouse ID (for multi-warehouse management)
*
* @example AUK
* @example SEL
*/
private ?string $warehouse = null,
/**
* Rack number
*
* @example R3
* @example S5
*/
private ?string $rack = null,
/**
* Shelf number
*
* @example S5
* @example F7
*/
private ?string $shelf = null,
) {
if (is_null($warehouse) && is_null($rack) && is_null($shelf)) {
throw new \InvalidArgumentException('At least one parameter must be provided.');
}

$this->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;
}
}
101 changes: 101 additions & 0 deletions tests/LocationTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
<?php

namespace Cable8mm\GoodCode\Tests;

use Cable8mm\GoodCode\Location;
use PHPUnit\Framework\TestCase;

class LocationTest extends TestCase
{
public function test_full_location_code()
{
$this->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',
]));
}
}