Skip to content

Commit

Permalink
Merge pull request #135 from johanib/feature/fix1
Browse files Browse the repository at this point in the history
Add support for parsing duplicated segments, closes #134
  • Loading branch information
sabas authored May 21, 2024
2 parents fe5d6b6 + 749c2e9 commit e54c693
Show file tree
Hide file tree
Showing 4 changed files with 117 additions and 14 deletions.
65 changes: 52 additions & 13 deletions src/EDI/Reader.php
Original file line number Diff line number Diff line change
Expand Up @@ -174,10 +174,9 @@ public function readEdiDataValueReq($filter, int $l1, $l2 = false)
* @param bool $required if required, but no exist, register error
* @return string|null
*/
public function readEdiDataValue($filter, int $l1, $l2 = false, bool $required = false)
public function readEdiDataValue($filter, int $l1, $l2 = false, bool $required = false, int $offset = null)
{
$segment = false;
$segment_count = 0;
$found_segments = [];
$segment_name = $filter;
$filter_elements = false;
if (\is_array($filter)) {
Expand Down Expand Up @@ -221,24 +220,23 @@ public function readEdiDataValue($filter, int $l1, $l2 = false, bool $required =
continue;
}
}
$segment = $edi_row;
$segment_count++;
$found_segments[] = $edi_row;
}
}

// no segment found
if (! $segment) {
if ($required) {
$this->errors[] = 'Segment "'.$segment_name.'" no exist';
try {
if ($offset !== null) {
$segment = $this->getOffsetSegmentFromResult($found_segments, $offset, $required, $segment_name);
} else {
$segment = $this->getSegmentFromResult($found_segments, $required, $segment_name);
}
} catch (ReaderException $e) {
$this->errors[] = $e->getMessage();

return null;
}

// found more than one segment - error
if ($segment_count > 1) {
$this->errors[] = 'Segment "'.$segment_name.'" is ambiguous';

if ($segment === false) {
return null;
}

Expand Down Expand Up @@ -561,4 +559,45 @@ private static function unwrap($string)
}
}
}

/**
* @param array $matchingSegments
* @param int $offset
* @param bool $required
* @param mixed $segment_name
*
* @return false|mixed
*/
private function getOffsetSegmentFromResult(array $matchingSegments, int $offset, bool $required, mixed $segment_name): mixed
{
if (isset($matchingSegments[$offset])) {
return $matchingSegments[$offset];
}

if ($required) {
throw new ReaderException('Segment "' . $segment_name . '" does not exist at offset "' . $offset . '"');
}

return false;
}

/**
* @param array $matchingSegments
* @param mixed $segment_name
*
* @return false|mixed
*/
private function getSegmentFromResult(array $matchingSegments, bool $required, mixed $segment_name): mixed
{
// found more than one segment - error
if (count($matchingSegments) > 1) {
throw new ReaderException('Segment "' . $segment_name . '" is ambiguous');
}

if ($required && !isset($matchingSegments[0])) {
throw new ReaderException('Segment "' . $segment_name . '" no exist');
}

return $matchingSegments[0] ?? false;
}
}
11 changes: 11 additions & 0 deletions src/EDI/ReaderException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?php

declare(strict_types=1);

namespace EDI;

use RuntimeException;

class ReaderException extends RuntimeException
{
}
45 changes: 44 additions & 1 deletion tests/EDITest/ReaderTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@

namespace EDITest;

use EDI\Reader;
use EDI\Parser;
use EDI\Reader;

/**
* @internal
Expand Down Expand Up @@ -102,4 +102,47 @@ public function testSplitMultiMessage()
$messageType = $r->readUNHmessageType();
static::assertSame('PAORES', $messageType);
}

public function testReadsMultiSegmentsByOffset()
{
$p = new Parser();
$p->setStrict(true);
$p->load(__DIR__ . '/../files/example_multiline.edi');
$r = new Reader($p);

$lines = [];
for ($i = 0; $i < 10; $i++) {
$line = $r->readEdiDataValue(['FTX', [1 => 'AAI']], 4, false, false, $i);
if ($line !== null) {
$lines[] = $line;
}
}

self::assertSame(
[
0 => [
0 => 'PLS ENSURE TO TAKE OUR APPROVAL PRIOR STUFFING ANY NON HAZ CHEMICA',
1 => 'LS',
],
1 => [
0 => 'THE SHIPPER SHALL NOT BE RESPONSIBLE FOR ANY COSTS/DELAYS OCCUR',
1 => 'DUE TO INTERVENTION OF CUSTOMS.',
],

],
$lines
);
}

public function testAddsErrorOnMissingRequiredOffest()
{
$p = new Parser();
$p->setStrict(true);
$p->load(__DIR__ . '/../files/example_multiline.edi');
$r = new Reader($p);
$line = $r->readEdiDataValue(['FTX', [1 => 'AAI']], 4, false, true, 99);
self::assertSame(['Segment "FTX" does not exist at offset "99"'], $r->errors());
self::assertNull($line);
}

}
10 changes: 10 additions & 0 deletions tests/files/example_multiline.edi
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
UNB+UNOB:2+CARRIER+RECEIVER-ID+999818:999+251'
UNH+0001+IFTMBC:D:00B:UN'
BGM+770+AAA99970929+9'
TSR+30+2:::2'
FTX+AAI+++PLS ENSURE TO TAKE OUR APPROVAL PRIOR STUFFING ANY NON HAZ CHEMICA:LS'
FTX+ABV+++THIS BOOKING CONFIRMATION IS SUBJECT TO SEALING'
FTX+AAI+++THE SHIPPER SHALL NOT BE RESPONSIBLE FOR ANY COSTS/DELAYS OCCUR
:DUE TO INTERVENTION OF CUSTOMS.'
UNT+10+0001'
UNZ+1+251'

0 comments on commit e54c693

Please sign in to comment.