Nevar pievienot vairāk kā 25 tēmas Tēmai ir jāsākas ar burtu vai ciparu, tā var saturēt domu zīmes ('-') un var būt līdz 35 simboliem gara.

144 rindas
3.5KB

  1. <?php
  2. namespace App\Http\API\SMBC\Payment;
  3. use App\Util\EncodingUtil;
  4. use Exception;
  5. use Illuminate\Support\Collection;
  6. use Illuminate\Support\Str;
  7. class PollResult
  8. {
  9. // 共通
  10. private const IDX_RECORD_CODE = 0;
  11. // ヘッダー
  12. private const IDX_HEADER_RESULT = 1;
  13. private const IDX_HEADER_MESSAGE = 2;
  14. // ボディー
  15. private const IDX_FOOTER_COUNT = 1;
  16. // フッター
  17. private const RECORD_CODE_HEADER = "10";
  18. private const RECORD_CODE_BODY = "20";
  19. private const RECORD_CODE_FOOTER = "80";
  20. private const RESULT_CODE_SUCCESS = ["000000", "943037"];
  21. /**
  22. * @var Collection<int, Collection<int, string>>
  23. */
  24. private Collection $lines;
  25. /**
  26. * @var Collection<int, PollResultRecord>
  27. */
  28. private Collection $body;
  29. private bool $success = false;
  30. private string $message = "";
  31. private int $count = 0;
  32. public function __construct(string $data)
  33. {
  34. $this->lines = collect();
  35. $lines = Str::of($data)->replace('"', '')->explode("\r\n");
  36. foreach ($lines as $lineStr) {
  37. if ($lineStr) {
  38. $lineStr = EncodingUtil::toUtf8FromSjis($lineStr);
  39. $this->lines->push(Str::of($lineStr)->explode(','));
  40. }
  41. }
  42. if (!$this->parseHeader()) {
  43. return;
  44. }
  45. if (!$this->parseBody()) {
  46. return;
  47. }
  48. if (!$this->parseFooter()) {
  49. return;
  50. }
  51. $this->success = true;
  52. }
  53. public function ok(): bool
  54. {
  55. return $this->success;
  56. }
  57. public function getMessage(): string
  58. {
  59. return $this->message;
  60. }
  61. public function getRecord()
  62. {
  63. return $this->body;
  64. }
  65. public function getCount(): int
  66. {
  67. return $this->count;
  68. }
  69. private function parseHeader(): bool
  70. {
  71. $header = $this->lines->first();
  72. if (!$header) {
  73. $this->success = false;
  74. $this->message = "ヘッダーなし";
  75. return false;
  76. }
  77. $resultCode = $header->get(self::IDX_HEADER_RESULT);
  78. if (!in_array($resultCode, self::RESULT_CODE_SUCCESS)) {
  79. $this->success = false;
  80. $this->message = sprintf("結果コードNG %s", $resultCode);
  81. $readMessage = EncodingUtil::toUtf8FromSjis($header->get(self::IDX_HEADER_MESSAGE));
  82. return false;
  83. }
  84. return true;
  85. }
  86. private function parseBody(): bool
  87. {
  88. $this->body = collect();
  89. try {
  90. foreach ($this->lines as $line) {
  91. if ($line[self::IDX_RECORD_CODE] === self::RECORD_CODE_BODY) {
  92. $this->body->push(new PollResultRecord($line));
  93. }
  94. }
  95. } catch (Exception $e) {
  96. $this->success = false;
  97. $this->message = sprintf("Bodyパース失敗 %s", $e->getMessage());
  98. return false;
  99. }
  100. return true;
  101. }
  102. private function parseFooter(): bool
  103. {
  104. $footer = $this->lines->last();
  105. if (!$footer) {
  106. $this->success = false;
  107. $this->message = "フッターなし";
  108. return false;
  109. }
  110. $count = intval($footer->get(self::IDX_FOOTER_COUNT));
  111. if ($count !== $this->body->count()) {
  112. $this->success = false;
  113. $this->message = sprintf("読込件数に差異あり %d : %d", $count, $this->body->count());
  114. return false;
  115. }
  116. $this->count = $count;
  117. return true;
  118. }
  119. }