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
28 changes: 28 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ We have provided the API Documentation on the web. For more information, please
- [x] Set good code parser
- [x] Complex good code parser
- [x] Option Good code parser(No code, it matched by name)
- [x] Receipt code parser

## Install

Expand Down Expand Up @@ -172,6 +173,33 @@ print SetGood::ofArray(['43' => 3, '253' => 3])->code();
//=> SET43x3zz253x3
```

### Receipt Code

```php
<?php

use Cable8mm\GoodCode\ReceiptCode;

print ReceiptCode::of('PO-20250312-0001')->code;
//=> PO-20250312-0001

print ReceiptCode::of('PO-20250312-0001')->prefix;
//=> PO

print ReceiptCode::of('PO-20250312-0001')->ymd;
//=> 20250312

print ReceiptCode::of('PO-20250312-0001')->number;
//=> 0001

print ReceiptCode::of('PO-20250312-0001')->nextCode();
//=> PO-20250312-0002

print ReceiptCode::make()->nextCode();
//=> PO-[Today's ymd]-0001

```

## Formatting

```sh
Expand Down
112 changes: 112 additions & 0 deletions src/ReceiptCode.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
<?php

namespace Cable8mm\GoodCode;

use InvalidArgumentException;
use Stringable;

class ReceiptCode implements Stringable
{
/**
* Prefix of the receipt code
*/
public string $prefix = 'PO';

/**
* Year month day of the receipt code
*/
public string $ymd;

/**
* Number of the receipt code
*/
public int $number;

/**
* Receipt code
*/
public string $code;

/**
* ReceiptCode constructor.
*
* @param string|null $code ReceiptCode
*/
private function __construct(
?string $code = null,
) {
if (! is_null($code)) {
$this->code($code);
}
}

/**
* Parse code and set `code`, `prefix`, `ymd` and `number`.
*
* @param string $code ReceiptCode
* @return static Provides a fluent interface
*/
public function code(string $code): static
{
if (preg_match('/^([^\-]+)\-([^\-]+)\-(.+)$/', $code, $matches) === false) {
throw new InvalidArgumentException('Invalid code format.');
}

[$this->code, $this->prefix, $this->ymd, $this->number] = $matches;

return $this;
}

/**
* Get next code.
*
* @return string Next code
*
* @example ReceiptCode::make()->nextCode() => PO-20250312-0001
* @example ReceiptCode::make()->code('PO-20250312-0001')->nextCode() => PO-20250312-0002
* @example ReceiptCode::make()->code('PO-20250312-9999')->nextCode() => PO-20250312-10000
*/
public function nextCode(): string
{
if (! isset($this->code)) {
return $this->prefix.'-'.date('Ymd').'-0001';
}

if ($this->ymd === $this->ymd) {
return $this->prefix.'-'.$this->ymd.'-'.str_pad($this->number + 1, 4, '0', STR_PAD_LEFT);
}

return $this->prefix.'-'.date('Ymd').'-0001';
}

/**
* Create a new instance of ReceiptCode.
*
* @param string $code ReceiptCode
* @return static Provides a new instance of ReceiptCode
*/
public static function of(string $code): self
{
return new self($code);
}

/**
* Create a new instance of ReceiptCode.
*
* @return static Provides a new instance of ReceiptCode
*/
public static function make(): self
{
return new self;
}

/**
* Get the string representation of the object.
*
* @return string The method returns the `code` representation
*/
public function __toString(): string
{
return $this->code ?? '';
}
}
33 changes: 33 additions & 0 deletions tests/ReceiptCodeTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<?php

namespace Cable8mm\GoodCode\Tests;

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

class ReceiptCodeTest extends TestCase
{
public function test_of_method()
{
$this->assertEquals('PO-20250312-0001', ReceiptCode::of('PO-20250312-0001')->code);
}

public function test_code_method()
{
$this->assertEquals('PO-20250312-0001', ReceiptCode::make()->code('PO-20250312-0001')->code);
$this->assertEquals('PO', ReceiptCode::make()->code('PO-20250312-0001')->prefix);
$this->assertEquals('20250312', ReceiptCode::make()->code('PO-20250312-0001')->ymd);
$this->assertEquals('0001', ReceiptCode::make()->code('PO-20250312-0001')->number);
}

public function test_next_code_method()
{
$this->assertEquals('PO-20250312-0002', ReceiptCode::make()->code('PO-20250312-0001')->nextCode());
$this->assertEquals('PO-20250312-10000', ReceiptCode::make()->code('PO-20250312-9999')->nextCode());
}

public function test_no_code()
{
$this->assertEquals('PO-'.date('Ymd').'-0001', ReceiptCode::make()->nextCode());
}
}