From 277e7daaef8a30758731207d52cb3a61afdc79d5 Mon Sep 17 00:00:00 2001 From: Sam Lee Date: Fri, 21 Feb 2025 03:08:46 +0900 Subject: [PATCH] Add receipt code classes --- README.md | 28 ++++++++++ src/ReceiptCode.php | 112 ++++++++++++++++++++++++++++++++++++++ tests/ReceiptCodeTest.php | 33 +++++++++++ 3 files changed, 173 insertions(+) create mode 100644 src/ReceiptCode.php create mode 100644 tests/ReceiptCodeTest.php diff --git a/README.md b/README.md index 5d8721e..a75ac1e 100644 --- a/README.md +++ b/README.md @@ -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 @@ -172,6 +173,33 @@ print SetGood::ofArray(['43' => 3, '253' => 3])->code(); //=> SET43x3zz253x3 ``` +### Receipt Code + +```php +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 diff --git a/src/ReceiptCode.php b/src/ReceiptCode.php new file mode 100644 index 0000000..ce29640 --- /dev/null +++ b/src/ReceiptCode.php @@ -0,0 +1,112 @@ +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 ?? ''; + } +} diff --git a/tests/ReceiptCodeTest.php b/tests/ReceiptCodeTest.php new file mode 100644 index 0000000..6206182 --- /dev/null +++ b/tests/ReceiptCodeTest.php @@ -0,0 +1,33 @@ +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()); + } +}