261 lines
11 KiB
ObjectPascal
261 lines
11 KiB
ObjectPascal
{**************************************************************************************************}
|
|
{ }
|
|
{ Project JEDI Code Library (JCL) }
|
|
{ }
|
|
{ The contents of this file are subject to the Mozilla Public License Version 1.1 (the "License"); }
|
|
{ you may not use this file except in compliance with the License. You may obtain a copy of the }
|
|
{ License at http://www.mozilla.org/MPL/ }
|
|
{ }
|
|
{ Software distributed under the License is distributed on an "AS IS" basis, WITHOUT WARRANTY OF }
|
|
{ ANY KIND, either express or implied. See the License for the specific language governing rights }
|
|
{ and limitations under the License. }
|
|
{ }
|
|
{ The Original Code is JclEDI_ANSIX12_Ext.pas. }
|
|
{ }
|
|
{ The Initial Developer of the Original Code is Raymond Alexander. }
|
|
{ Portions created by Raymond Alexander are Copyright Raymond Alexander. All rights reserved. }
|
|
{ }
|
|
{ Contributor(s): }
|
|
{ Raymond Alexander (rayspostbox3), Robert Rossmair }
|
|
{ }
|
|
{**************************************************************************************************}
|
|
{ }
|
|
{ EDI ANSI X12 - Standard Exchange Format (*.sef) File Extensions }
|
|
{ }
|
|
{ This unit is still in development }
|
|
{ }
|
|
{ Unit owner: Raymond Alexander }
|
|
{ Date created: March 1, 2004 }
|
|
{ Additional Info: }
|
|
{ E-Mail at RaysDelphiBox3 att hotmail dott com }
|
|
{ For latest EDI specific demos see http://sourceforge.net/projects/edisdk }
|
|
{ See home page for latest news & events and online help. }
|
|
{ }
|
|
{**************************************************************************************************}
|
|
|
|
// $Id: JclEDI_ANSIX12_Ext.pas,v 1.9 2005/03/08 08:33:16 marquardt Exp $
|
|
|
|
unit JclEDI_ANSIX12_Ext;
|
|
|
|
{$I jcl.inc}
|
|
|
|
{$IFDEF SUPPORTS_WEAKPACKAGEUNIT}
|
|
{$WEAKPACKAGEUNIT ON}
|
|
{$ENDIF SUPPORTS_WEAKPACKAGEUNIT}
|
|
|
|
interface
|
|
|
|
uses
|
|
SysUtils, Classes, Contnrs, JclResources,
|
|
JclEDI, JclEDI_ANSIX12, JclEDISEF;
|
|
|
|
type
|
|
// EDI Transaction Set Document and related types and classes
|
|
TEDI_ANSIX12_Document = class(TEDITransactionSetLoop)
|
|
private
|
|
FEDISEFSet: TEDISEFSet;
|
|
protected
|
|
FErrorOccured: Boolean;
|
|
FEDITSDOptions: TEDITransactionSetDocumentOptions;
|
|
FEDILoopStack: TEDILoopStack;
|
|
// References
|
|
FEDITransactionSet: TEDITransactionSet;
|
|
FEDITransactionSetSpec: TObjectList;
|
|
function ValidateSegSpecIndex(DataSegmentId: string; SpecStartIndex: Integer): Integer;
|
|
function AdvanceSegSpecIndex(DataIndex, SpecStartIndex, SpecEndIndex: Integer): Integer;
|
|
procedure AddLoopToDoc(StackRecord: TEDILoopStackRecord;
|
|
SegmentId, OwnerLoopId, ParentLoopId: string; var EDIObject: TEDIObject);
|
|
procedure SetSpecificationPointers(DataSegment: TEDISegment; SpecSegment: TEDISEFSegment);
|
|
protected
|
|
procedure ValidateData(TSDocument: TEDI_ANSIX12_Document;
|
|
LoopStack: TEDILoopStack;
|
|
DataSegment: TEDISegment;
|
|
SpecSegment: TEDISEFSegment;
|
|
var DataIndex, SpecIndex: Integer;
|
|
var ErrorOccured: Boolean); virtual;
|
|
public
|
|
constructor Create(Parent: TEDIDataObject; TransactionSet: TEDITransactionSet;
|
|
SEFSet: TEDISEFSet); reintroduce;
|
|
destructor Destroy; override;
|
|
//
|
|
// ToDo: More procedures and functions to manage internal structures
|
|
//
|
|
procedure FormatDocument; virtual;
|
|
published
|
|
property EDITSDOptions: TEDITransactionSetDocumentOptions read FEDITSDOptions
|
|
write FEDITSDOptions;
|
|
property ErrorOccured: Boolean read FErrorOccured;
|
|
end;
|
|
|
|
implementation
|
|
|
|
constructor TEDI_ANSIX12_Document.Create(Parent: TEDIDataObject;
|
|
TransactionSet: TEDITransactionSet; SEFSet: TEDISEFSet);
|
|
begin
|
|
inherited Create(Parent);
|
|
FEDILoopStack := TEDILoopStack.Create;
|
|
FEDILoopStack.OnAddLoop := AddLoopToDoc;
|
|
FEDITransactionSet := TransactionSet;
|
|
FEDISEFSet := SEFSet;
|
|
FEDITransactionSetSpec := SEFSet.GetSegmentObjectList;
|
|
FEDITSDOptions := [];
|
|
end;
|
|
|
|
destructor TEDI_ANSIX12_Document.Destroy;
|
|
begin
|
|
FreeAndNil(FEDILoopStack);
|
|
FEDITransactionSet := nil;
|
|
FEDITransactionSetSpec.Free;
|
|
inherited Destroy;
|
|
end;
|
|
|
|
procedure TEDI_ANSIX12_Document.FormatDocument;
|
|
var
|
|
I, J: Integer;
|
|
LSR: TEDILoopStackRecord;
|
|
DataSegment: TEDISegment;
|
|
SpecSegment: TEDISEFSegment;
|
|
begin
|
|
I := 0;
|
|
J := 0;
|
|
if doLinkSpecToDataObject in FEDITSDOptions then
|
|
begin
|
|
FEDISEFSet.BindTextSets(FEDISEFSet.SEFFile.TEXTSETS);
|
|
FEDISEFSet.BindSegmentTextSets;
|
|
end;
|
|
// Initialize the stack
|
|
FEDILoopStack.Flags := FEDILoopStack.Flags - [ediLoopRepeated];
|
|
LSR := FEDILoopStack.ValidateLoopStack(FEDITransactionSet.Segment[I].SegmentID,
|
|
NA_LoopId, NA_LoopId, 0, Self);
|
|
//
|
|
while (I <= FEDITransactionSet.SegmentCount - 1) and
|
|
(J <= FEDITransactionSetSpec.Count - 1) do
|
|
begin
|
|
FEDILoopStack.Flags := FEDILoopStack.Flags - [ediLoopRepeated];
|
|
DataSegment := FEDITransactionSet.Segment[I];
|
|
// If loop has repeated then move the spec index back
|
|
J := ValidateSegSpecIndex(DataSegment.SegmentID, J);
|
|
// Check current segment against segment spec
|
|
SpecSegment := TEDISEFSegment(FEDITransactionSetSpec[J]);
|
|
if DataSegment.SegmentID = SpecSegment.SegmentID then
|
|
begin
|
|
// Retrieve the correct record to use from the stack
|
|
LSR := FEDILoopStack.ValidateLoopStack(SpecSegment.SegmentID, SpecSegment.OwnerLoopId,
|
|
SpecSegment.ParentLoopId, J, LSR.EDIObject);
|
|
//
|
|
// Debug - Keep the following here in case someone wants to debug what happens to the stack.
|
|
// ShowMessage('Current Data Segment: [' + IntToStr(I) + '] ' + DataSegment.SegmentID + #13#10 +
|
|
// 'Current Spec Segment: [' + IntToStr(J) + '] ' + SpecSegment.SegmentID + #13#10 +
|
|
// FEDILoopStack.Debug);
|
|
//
|
|
// Do error checking and data validation in decendent class
|
|
ValidateData(Self, FEDILoopStack, DataSegment, SpecSegment, I, J, FErrorOccured);
|
|
if FErrorOccured then
|
|
Exit;
|
|
// Process Segment Id
|
|
TEDITransactionSetLoop(LSR.EDIObject).AppendSegment(DataSegment);
|
|
//
|
|
if doLinkSpecToDataObject in FEDITSDOptions then
|
|
begin
|
|
SpecSegment.BindTextSets(SpecSegment.SEFFile.TEXTSETS);
|
|
SpecSegment.BindElementTextSets;
|
|
SetSpecificationPointers(DataSegment, SpecSegment);
|
|
end;
|
|
// Move to the next data segment
|
|
Inc(I);
|
|
end
|
|
else
|
|
begin
|
|
// Do error checking and data validation in decendent class
|
|
ValidateData(Self, FEDILoopStack, DataSegment, SpecSegment, I, J, FErrorOccured);
|
|
if FErrorOccured then
|
|
Exit;
|
|
//
|
|
// Debug - Keep the following here in case someone wants to debug what happens to the stack.
|
|
// ShowMessage('Current Data Segment: [' + IntToStr(I) + '] ' + DataSegment.SegmentID + #13#10 +
|
|
// 'Current Spec Segment: [' + IntToStr(J) + '] ' + SpecSegment.SegmentID + #13#10 +
|
|
// FEDILoopStack.Debug);
|
|
//
|
|
// Move to the next specification segment
|
|
J := AdvanceSegSpecIndex(I, J, FEDITransactionSetSpec.Count - 1); //Inc(J);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure TEDI_ANSIX12_Document.ValidateData(TSDocument: TEDI_ANSIX12_Document;
|
|
LoopStack: TEDILoopStack; DataSegment: TEDISegment; SpecSegment: TEDISEFSegment;
|
|
var DataIndex, SpecIndex: Integer; var ErrorOccured: Boolean);
|
|
begin
|
|
ErrorOccured := False;
|
|
end;
|
|
|
|
procedure TEDI_ANSIX12_Document.SetSpecificationPointers(DataSegment: TEDISegment;
|
|
SpecSegment: TEDISEFSegment);
|
|
var
|
|
I, J: Integer;
|
|
begin
|
|
DataSegment.SpecPointer := SpecSegment;
|
|
J := SpecSegment.Elements.Count - 1;
|
|
for I := 0 to DataSegment.ElementCount - 1 do
|
|
begin
|
|
if I > J then
|
|
raise EJclEDIError.CreateResFmt(@RsEDIError058,
|
|
[IntToStr(I), DataSegment.SegmentId,
|
|
IntToStr(DataSegment.GetIndexPositionFromParent)]);
|
|
DataSegment.Element[I].SpecPointer := SpecSegment.Elements[I];
|
|
end;
|
|
end;
|
|
|
|
procedure TEDI_ANSIX12_Document.AddLoopToDoc(StackRecord: TEDILoopStackRecord;
|
|
SegmentId, OwnerLoopId, ParentLoopId: string; var EDIObject: TEDIObject);
|
|
var
|
|
I: Integer;
|
|
Loop: TEDITransactionSetLoop;
|
|
begin
|
|
Loop := TEDITransactionSetLoop(StackRecord.EDIObject);
|
|
I := Loop.AddLoop(OwnerLoopId, ParentLoopId);
|
|
EDIObject := TEDITransactionSetLoop(Loop[I]);
|
|
end;
|
|
|
|
function TEDI_ANSIX12_Document.ValidateSegSpecIndex(DataSegmentId: string;
|
|
SpecStartIndex: Integer): Integer;
|
|
var
|
|
I: Integer;
|
|
begin
|
|
Result := SpecStartIndex;
|
|
// Find the segment in the stack to determine if a loop has repeated
|
|
for I := High(FEDILoopStack.Stack) downto Low(FEDILoopStack.Stack) do
|
|
begin
|
|
if (DataSegmentId = FEDILoopStack.Stack[I].SegmentId) and
|
|
(FEDILoopStack.Stack[I].OwnerLoopId <> NA_LoopId) then
|
|
begin
|
|
FEDILoopStack.Flags := FEDILoopStack.Flags + [ediLoopRepeated];
|
|
Result := FEDILoopStack.Stack[I].SpecStartIndex;
|
|
Break;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
function TEDI_ANSIX12_Document.AdvanceSegSpecIndex(DataIndex, SpecStartIndex,
|
|
SpecEndIndex: Integer): Integer;
|
|
var
|
|
DataSegment: TEDISegment;
|
|
TestSegment: TEDISEFSegment;
|
|
I: Integer;
|
|
begin
|
|
Result := SpecEndIndex + 1;
|
|
DataSegment := FEDITransactionSet.Segment[DataIndex];
|
|
for I := SpecStartIndex + 1 to SpecEndIndex do
|
|
begin
|
|
TestSegment := TEDISEFSegment(FEDITransactionSetSpec[I]);
|
|
// Find matching segment
|
|
if ((DataSegment.SegmentID) = (TestSegment.SegmentID)) then
|
|
begin
|
|
Result := I;
|
|
Break;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
end.
|