stgGatherCacheData.pas 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718
  1. unit stgGatherCacheData;
  2. interface
  3. uses
  4. CacheTree, SysUtils, BillsTree, Classes, sdDB, mDataRecord;
  5. const
  6. // 新增项目节
  7. iErrorXmjAdd = 1;
  8. // 存在同号项目节,但名称、单价不同
  9. iErrorXmjDiff = 2;
  10. // 项目节层次少于总包
  11. iErrorXmjLess = 3;
  12. // 新增工程量清单
  13. iErrorGclAdd = 11;
  14. // 存在同名工程量清单,但名称、单价不同
  15. iErrorGclDiff = 12;
  16. // 工程量清单层次多于总包
  17. iErrorGclMore = 13;
  18. // 工程量清单层次少于总包
  19. iErrorGclLess = 14;
  20. type
  21. TstgStageData = class
  22. private
  23. FDealQuantity: Double;
  24. FDealTotalPrice: Double;
  25. FQcQuantity: Double;
  26. FQcTotalPrice: Double;
  27. FQcBGLCode: string;
  28. FQcBGLNum: string;
  29. procedure AddBGLCodeAndNum(ACode, ANum: string);
  30. public
  31. procedure ClearData;
  32. procedure AddStageData(AStageData: TstgStageData);
  33. procedure AssignedData(AStageRecord: TStageRecord);
  34. property DealQuantity: Double read FDealQuantity;
  35. property DealTotalPrice: Double read FDealTotalPrice;
  36. property QcQuantity: Double read FQcQuantity;
  37. property QcTotalPrice: Double read FQcTotalPrice;
  38. property QcBGLCode: string read FQcBGLCode;
  39. property QcBGLNum: string read FQcBGLNum;
  40. end;
  41. TstgSubTenderDetailData = class
  42. private
  43. FSerialNo: Integer;
  44. FLeafXmjCode: string;
  45. FDetailStage: TstgStageData;
  46. public
  47. constructor Create(ANode: TMeasureBillsIDTreeNode);
  48. destructor Destroy; override;
  49. property SerialNo: Integer read FSerialNo;
  50. property LeafXmjCode: string read FLeafXmjCode;
  51. property DetailStage: TstgStageData read FDetailStage;
  52. end;
  53. TstgSubTenderStageData = class
  54. private
  55. FSubTenderID: Integer;
  56. FGather: TstgStageData;
  57. FDetails: TList;
  58. function GetDetail(AIndex: Integer): TstgSubTenderDetailData;
  59. function GetDetailCount: Integer;
  60. public
  61. constructor Create(ASubTenderID: Integer);
  62. destructor Destroy; override;
  63. function AddDetail(ANode: TMeasureBillsIDTreeNode): TstgSubTenderDetailData;
  64. procedure CalculateGather;
  65. property SubTenderID: Integer read FSubTenderID;
  66. property Gather: TstgStageData read FGather;
  67. property DetailCount: Integer read GetDetailCount;
  68. property Detail[AIndex: Integer]: TstgSubTenderDetailData read GetDetail;
  69. end;
  70. TstgGatherTreeNode = class(TCacheNode)
  71. private
  72. FCode: string;
  73. FB_Code: string;
  74. FName: string;
  75. FUnits: string;
  76. FIsSumBase: Boolean;
  77. FIsLeafXmj: Boolean;
  78. FIsLeaf: Boolean;
  79. FIsSubTender: Boolean;
  80. FGather: TstgStageData;
  81. FSubTenders: TList;
  82. function GetIsGclBills: Boolean;
  83. function GetSubTender(AIndex: Integer): TstgSubTenderStageData;
  84. function GetSubTenderCount: Integer;
  85. public
  86. constructor Create(ATree: TCacheTree; AID: Integer); override;
  87. destructor Destroy; override;
  88. function FindSubTender(ASubTenderID: Integer): TstgSubTenderStageData;
  89. function SafeSubTender(ASubTenderID: Integer): TstgSubTenderStageData;
  90. procedure CalculateGather;
  91. property Code: string read FCode write FCode;
  92. property B_Code: string read FB_Code write FB_Code;
  93. property Name: string read FName write FName;
  94. property Units: string read FUnits write FUnits;
  95. property IsSumBase: Boolean read FIsSumBase write FIsSumBase;
  96. property IsLeafXmj: Boolean read FIsLeafXmj write FIsLeafXmj;
  97. property IsLeaf: Boolean read FIsLeaf write FIsLeaf;
  98. property IsSubTender: Boolean read FIsSubTender write FIsSubTender;
  99. property IsGclBills: Boolean read GetIsGclBills;
  100. property SubTenderCount: Integer read GetSubTenderCount;
  101. property SubTender[AIndex: Integer]: TstgSubTenderStageData read GetSubTender;
  102. property Gather: TstgStageData read FGather;
  103. end;
  104. TstgGatherTree = class(TCacheTree)
  105. private
  106. FFixedNodes: TCacheNodeList;
  107. // -1的情况下默认自动赋值一个新的ID
  108. function GetNewNode(AID: Integer = -1): TstgGatherTreeNode; overload;
  109. function CheckLeafXmj(ANode: TstgGatherTreeNode): Boolean;
  110. public
  111. constructor Create; override;
  112. destructor Destroy; override;
  113. function FindNextSibling(AParent: TCacheNode; ACode: string): TstgGatherTreeNode;
  114. function FindNode(AParent: TCacheNode; AInfo: TBillsIDTreeNode): TstgGatherTreeNode; overload;
  115. function FindNode(AID: Integer): TstgGatherTreeNode; overload;
  116. function AddFixedNode(AParent: TCacheNode; ANextSibling:
  117. TCacheNode = nil; AFixedID: Integer = -1): TstgGatherTreeNode;
  118. function AddNode(AParent: TCacheNode; ANextSibling:
  119. TCacheNode = nil; ASumBaseID: Integer = -1): TstgGatherTreeNode;
  120. function AddSumBaseNode(AParent: TCacheNode; ASumBaseID: Integer): TstgGatherTreeNode;
  121. function AddSubTenderNode(AParent: TCacheNode; ANextSibling: TCacheNode; AFixedID: Integer = -1): TstgGatherTreeNode;
  122. // Only for Debugging lot of Data
  123. procedure SaveTreeToFile(const AFileName: string);
  124. procedure MarkLeafXmj;
  125. procedure CalculateAll;
  126. end;
  127. TstgGatherSubTender = class
  128. private
  129. FID: Integer;
  130. FRec: TsdDataRecord;
  131. public
  132. constructor Create(ARec: TsdDataRecord);
  133. property ID: Integer read FID;
  134. property Rec: TsdDataRecord read FRec;
  135. end;
  136. TstgErrorInfo = class
  137. private
  138. FRelaNode: TstgGatherTreeNode;
  139. FErrorType: Integer;
  140. FDetails: TList;
  141. function GetDetail(AIndex: Integer): TstgGatherTreeNode;
  142. function GetDetailCount: Integer;
  143. public
  144. constructor Create(ARelaNode: TstgGatherTreeNode);
  145. destructor Destroy; override;
  146. procedure AddErrorDetail(ARelaDetailNode: TstgGatherTreeNode);
  147. property RelaNode: TstgGatherTreeNode read FRelaNode;
  148. property ErrorType: Integer read FErrorType write FErrorType;
  149. property DetailCount: Integer read GetDetailCount;
  150. property Detail[AIndex: Integer]: TstgGatherTreeNode read GetDetail;
  151. end;
  152. TstgGatherCacheData = class
  153. private
  154. FGatherTree: TstgGatherTree;
  155. FSubTenders: TList;
  156. FErrors: TList;
  157. function FindError(ANode: TstgGatherTreeNode): TstgErrorInfo;
  158. function NewError(ANode: TstgGatherTreeNode; AErrorType: Integer): TstgErrorInfo;
  159. function GetSubTenderCount: Integer;
  160. function GetSubTender(AIndex: Integer): TstgGatherSubTender;
  161. function GetErrorCount: Integer;
  162. function GetError(AIndex: Integer): TstgErrorInfo;
  163. public
  164. constructor Create;
  165. destructor Destroy; override;
  166. function FindSubTender(AID: Integer): TstgGatherSubTender;
  167. function AddSubTender(ARec: TsdDataRecord): TstgGatherSubTender;
  168. procedure AddError(ANode, ALeafErrorNode: TstgGatherTreeNode; AErrorType: Integer);
  169. property SubTenderCount: Integer read GetSubTenderCount;
  170. property SubTender[AIndex: Integer]: TstgGatherSubTender read GetSubTender;
  171. property ErrorCount: Integer read GetErrorCount;
  172. property Error[AIndex: Integer]: TstgErrorInfo read GetError;
  173. property GatherTree: TstgGatherTree read FGatherTree;
  174. end;
  175. implementation
  176. uses
  177. ZhAPI, UtilMethods, Math;
  178. { TstgGatherTreeNode }
  179. procedure TstgGatherTreeNode.CalculateGather;
  180. var
  181. i: Integer;
  182. vSubTender: TstgSubTenderDetailData;
  183. begin
  184. FGather.ClearData;
  185. for i := 0 to FSubTenders.Count - 1 do
  186. begin
  187. SubTender[i].CalculateGather;
  188. FGather.AddStageData(SubTender[i].Gather);
  189. end;
  190. end;
  191. constructor TstgGatherTreeNode.Create(ATree: TCacheTree; AID: Integer);
  192. begin
  193. inherited Create(ATree, AID);
  194. FSubTenders := TList.Create;
  195. FGather := TstgStageData.Create;
  196. end;
  197. destructor TstgGatherTreeNode.Destroy;
  198. begin
  199. FGather.Free;
  200. ClearObjects(FSubTenders);
  201. FSubTenders.Free;
  202. inherited;
  203. end;
  204. function TstgGatherTreeNode.FindSubTender(
  205. ASubTenderID: Integer): TstgSubTenderStageData;
  206. var
  207. i: Integer;
  208. begin
  209. Result := nil;
  210. for i := 0 to FSubTenders.Count - 1 do
  211. begin
  212. if ASubTenderID = SubTender[i].SubTenderID then
  213. begin
  214. Result := SubTender[i];
  215. Break;
  216. end;
  217. end;
  218. end;
  219. function TstgGatherTreeNode.GetIsGclBills: Boolean;
  220. begin
  221. Result := FB_Code <> '';
  222. end;
  223. function TstgGatherTreeNode.GetSubTender(
  224. AIndex: Integer): TstgSubTenderStageData;
  225. begin
  226. Result := TstgSubTenderStageData(FSubTenders.Items[AIndex]);
  227. end;
  228. function TstgGatherTreeNode.GetSubTenderCount: Integer;
  229. begin
  230. Result := FSubTenders.Count;
  231. end;
  232. function TstgGatherTreeNode.SafeSubTender(
  233. ASubTenderID: Integer): TstgSubTenderStageData;
  234. begin
  235. Result := FindSubTender(ASubTenderID);
  236. if not Assigned(Result) then
  237. begin
  238. Result := TstgSubTenderStageData.Create(ASubTenderID);
  239. FSubTenders.Add(Result);
  240. end;
  241. end;
  242. { TstgGatherTree }
  243. function TstgGatherTree.AddFixedNode(AParent, ANextSibling: TCacheNode;
  244. AFixedID: Integer): TstgGatherTreeNode;
  245. begin
  246. Result := GetNewNode(AFixedID);
  247. if Assigned(ANextSibling) then
  248. ANextSibling.InsertPreSibling(Result)
  249. else if Assigned(AParent) then
  250. AParent.InsertChild(Result)
  251. else
  252. Root.InsertChild(Result);
  253. FFixedNodes.Add(Result);
  254. end;
  255. function TstgGatherTree.AddNode(AParent, ANextSibling: TCacheNode;
  256. ASumBaseID: Integer): TstgGatherTreeNode;
  257. begin
  258. Result := GetNewNode(ASumBaseID);
  259. if Assigned(ANextSibling) then
  260. ANextSibling.InsertPreSibling(Result)
  261. else if Assigned(AParent) then
  262. AParent.InsertChild(Result)
  263. else
  264. Root.InsertChild(Result);
  265. end;
  266. function TstgGatherTree.AddSubTenderNode(AParent, ANextSibling: TCacheNode;
  267. AFixedID: Integer): TstgGatherTreeNode;
  268. begin
  269. Result := GetNewNode(AFixedID);
  270. Result.IsSubTender := True;
  271. if Assigned(ANextSibling) then
  272. ANextSibling.InsertPreSibling(Result)
  273. else if Assigned(AParent) then
  274. AParent.InsertChild(Result)
  275. else
  276. Root.InsertChild(Result);
  277. end;
  278. function TstgGatherTree.AddSumBaseNode(AParent: TCacheNode;
  279. ASumBaseID: Integer): TstgGatherTreeNode;
  280. begin
  281. Result := GetNewNode(ASumBaseID);
  282. Result.IsSumBase := True;
  283. if Assigned(AParent) then
  284. AParent.InsertChild(Result)
  285. else
  286. Root.InsertChild(Result);
  287. end;
  288. procedure TstgGatherTree.CalculateAll;
  289. var
  290. i: Integer;
  291. begin
  292. for i := 0 to CacheNodes.Count - 1 do
  293. TstgGatherTreeNode(CacheNodes[i]).CalculateGather;
  294. end;
  295. function TstgGatherTree.CheckLeafXmj(ANode: TstgGatherTreeNode): Boolean;
  296. var
  297. iChild: Integer;
  298. vChild: TstgGatherTreeNode;
  299. begin
  300. Result := True;
  301. for iChild := 0 to ANode.Children.Count - 1 do
  302. begin
  303. vChild := TstgGatherTreeNode(ANode.Children.Items[iChild]);
  304. if vChild.FB_Code = '' then
  305. begin
  306. Result := False;
  307. Break;
  308. end;
  309. end;
  310. end;
  311. constructor TstgGatherTree.Create;
  312. begin
  313. inherited;
  314. FFixedNodes := TCacheNodeList.Create;
  315. NewNodeID := 100;
  316. end;
  317. destructor TstgGatherTree.Destroy;
  318. begin
  319. FFixedNodes.Free;
  320. inherited;
  321. end;
  322. function TstgGatherTree.FindNextSibling(AParent: TCacheNode;
  323. ACode: string): TstgGatherTreeNode;
  324. begin
  325. end;
  326. function TstgGatherTree.FindNode(AID: Integer): TstgGatherTreeNode;
  327. var
  328. i: Integer;
  329. Node: TCacheNode;
  330. begin
  331. Result := nil;
  332. for i := 0 to FFixedNodes.Count - 1 do
  333. begin
  334. Node := FFixedNodes.Items[i];
  335. if Node.ID = AID then
  336. begin
  337. Result := TstgGatherTreeNode(Node);
  338. Break;
  339. end;
  340. end;
  341. end;
  342. function TstgGatherTree.FindNode(AParent: TCacheNode;
  343. AInfo: TBillsIDTreeNode): TstgGatherTreeNode;
  344. var
  345. vNode: TstgGatherTreeNode;
  346. begin
  347. Result := nil;
  348. if Assigned(AParent) then
  349. vNode := TstgGatherTreeNode(AParent.FirstChild)
  350. else
  351. vNode := TstgGatherTreeNode(Root.FirstChild);
  352. while Assigned(vNode) and not Assigned(Result) do
  353. begin
  354. if SameText(vNode.Code, AInfo.Rec.Code.AsString) and SameText(vNode.B_Code, AInfo.Rec.B_Code.AsString)
  355. and SameText(vNode.Name, AInfo.Rec.Name.AsString) and SameText(vNode.Units, AInfo.Rec.Units.AsString) then
  356. Result := vNode;
  357. vNode := TstgGatherTreeNode(vNode.NextSibling);
  358. end;
  359. end;
  360. function TstgGatherTree.GetNewNode(AID: Integer): TstgGatherTreeNode;
  361. begin
  362. if AID = -1 then
  363. Result := TstgGatherTreeNode.Create(Self, GetNewNodeID)
  364. else
  365. Result := TstgGatherTreeNode.Create(Self, AID);
  366. NewNodeID := Max(NewNodeID, AID + 1);
  367. CacheNodes.Add(Result);
  368. if AID < 100 then
  369. FFixedNodes.Add(Result);
  370. end;
  371. procedure TstgGatherTree.MarkLeafXmj;
  372. var
  373. i: Integer;
  374. vNode: TstgGatherTreeNode;
  375. begin
  376. for i := 0 to CacheNodes.Count - 1 do
  377. begin
  378. vNode := TstgGatherTreeNode(CacheNodes.Items[i]);
  379. vNode.IsLeafXmj := CheckLeafXmj(vNode);
  380. end;
  381. end;
  382. procedure TstgGatherTree.SaveTreeToFile(const AFileName: string);
  383. var
  384. sgs: TStringList;
  385. I: Integer;
  386. Node: TstgGatherTreeNode;
  387. begin
  388. sgs := TStringList.Create;
  389. try
  390. for I := 0 to CacheNodes.Count - 1 do
  391. begin
  392. Node := TstgGatherTreeNode(CacheNodes.Items[I]);
  393. sgs.Add(Format('ID: %3d; ParentID: %3d; NextID: %3d; Code: %s; B_Code: %s; Name: %s;',
  394. [Node.ID, Node.ParentID, Node.NextSiblingID, Node.Code, Node.B_Code, Node.Name]));
  395. end;
  396. sgs.SaveToFile(AFileName);
  397. finally
  398. sgs.Free;
  399. end;
  400. end;
  401. { TstgGatherCacheData }
  402. procedure TstgGatherCacheData.AddError(ANode,
  403. ALeafErrorNode: TstgGatherTreeNode; AErrorType: Integer);
  404. var
  405. vError: TstgErrorInfo;
  406. begin
  407. vError := FindError(ANode);
  408. if not Assigned(vError) then
  409. vError := NewError(ANode, AErrorType);
  410. vError.AddErrorDetail(ALeafErrorNode);
  411. end;
  412. function TstgGatherCacheData.AddSubTender(
  413. ARec: TsdDataRecord): TstgGatherSubTender;
  414. begin
  415. Result := FindSubTender(ARec.ValueByName('ID').AsInteger);
  416. if not Assigned(Result) then
  417. begin
  418. Result := TstgGatherSubTender.Create(ARec);
  419. FSubTenders.Add(Result);
  420. end;
  421. end;
  422. constructor TstgGatherCacheData.Create;
  423. begin
  424. FGatherTree := TstgGatherTree.Create;
  425. FSubTenders := TList.Create;
  426. FErrors := TList.Create;
  427. end;
  428. destructor TstgGatherCacheData.Destroy;
  429. begin
  430. ClearObjects(FErrors);
  431. FErrors.Free;
  432. ClearObjects(FSubTenders);
  433. FSubTenders.Free;
  434. FGatherTree.Free;
  435. inherited;
  436. end;
  437. function TstgGatherCacheData.FindError(
  438. ANode: TstgGatherTreeNode): TstgErrorInfo;
  439. var
  440. i: Integer;
  441. begin
  442. Result := nil;
  443. for i := 0 to ErrorCount - 1 do
  444. begin
  445. if Error[i].RelaNode = ANode then
  446. begin
  447. Result := Error[i];
  448. Break;
  449. end;
  450. end;
  451. end;
  452. function TstgGatherCacheData.FindSubTender(
  453. AID: Integer): TstgGatherSubTender;
  454. var
  455. i: Integer;
  456. begin
  457. Result := nil;
  458. for i := 0 to SubTenderCount - 1 do
  459. begin
  460. if SubTender[i].ID = AID then
  461. begin
  462. Result := SubTender[i];
  463. Break;
  464. end;
  465. end;
  466. end;
  467. function TstgGatherCacheData.GetError(AIndex: Integer): TstgErrorInfo;
  468. begin
  469. Result := TstgErrorInfo(FErrors.Items[AIndex]);
  470. end;
  471. function TstgGatherCacheData.GetErrorCount: Integer;
  472. begin
  473. Result := FErrors.Count;
  474. end;
  475. function TstgGatherCacheData.GetSubTender(AIndex: Integer): TstgGatherSubTender;
  476. begin
  477. Result := TstgGatherSubTender(FSubTenders.Items[AIndex]);
  478. end;
  479. function TstgGatherCacheData.GetSubTenderCount: Integer;
  480. begin
  481. Result := FSubTenders.Count;
  482. end;
  483. function TstgGatherCacheData.NewError(
  484. ANode: TstgGatherTreeNode; AErrorType: Integer): TstgErrorInfo;
  485. begin
  486. Result := TstgErrorInfo.Create(ANode);
  487. Result.ErrorType := AErrorType;
  488. FErrors.Add(Result);
  489. end;
  490. { TstgGatherSubTender }
  491. constructor TstgGatherSubTender.Create(ARec: TsdDataRecord);
  492. begin
  493. FID := ARec.ValueByName('ID').AsInteger;
  494. FRec := ARec;
  495. end;
  496. { TstgStageData }
  497. procedure TstgStageData.AddBGLCodeAndNum(ACode, ANum: string);
  498. var
  499. sCode, sNum: string;
  500. begin
  501. sCode := FQcBGLCode;
  502. sNum := FQcBGLNum;
  503. MergeRelaBGLAndNum(sCode, sNum, ACode, ANum);
  504. FQcBGLCode := sCode;
  505. FQcBGLNum := sNum;
  506. end;
  507. procedure TstgStageData.AddStageData(AStageData: TstgStageData);
  508. begin
  509. FDealQuantity := FDealQuantity + AStageData.DealQuantity;
  510. FDealTotalPrice := FDealTotalPrice + AStageData.DealTotalPrice;
  511. FQcQuantity := FQcQuantity + AStageData.QcQuantity;
  512. FQcTotalPrice := FQcTotalPrice + AStageData.QcTotalPrice;
  513. AddBGLCodeAndNum(AStageData.QcBGLCode, AStageData.QcBGLNum);
  514. end;
  515. procedure TstgStageData.AssignedData(AStageRecord: TStageRecord);
  516. begin
  517. FDealQuantity := AStageRecord.DealQuantity.AsFloat;
  518. FDealTotalPrice := AStageRecord.DealTotalPrice.AsFloat;
  519. FQcQuantity := AStageRecord.QcQuantity.AsFloat;
  520. FQcTotalPrice := AStageRecord.QcTotalPrice.AsFloat;
  521. FQcBGLCode := AStageRecord.QcBGLCode.AsString;
  522. FQcBGLNum := AStageRecord.QcBGLNum.AsString;
  523. end;
  524. procedure TstgStageData.ClearData;
  525. begin
  526. FDealQuantity := 0;
  527. FDealTotalPrice := 0;
  528. FQcQuantity := 0;
  529. FQcTotalPrice := 0;
  530. FQcBGLCode := '';
  531. FQcBGLNum := '';
  532. end;
  533. { TstgSubTenderStageData }
  534. function TstgSubTenderStageData.AddDetail(
  535. ANode: TMeasureBillsIDTreeNode): TstgSubTenderDetailData;
  536. begin
  537. Result := TstgSubTenderDetailData.Create(ANode);
  538. FDetails.Add(Result);
  539. end;
  540. procedure TstgSubTenderStageData.CalculateGather;
  541. var
  542. i: Integer;
  543. begin
  544. FGather.ClearData;
  545. for i := 0 to DetailCount - 1 do
  546. FGather.AddStageData(Detail[i].DetailStage);
  547. end;
  548. constructor TstgSubTenderStageData.Create(ASubTenderID: Integer);
  549. begin
  550. FSubTenderID := ASubTenderID;
  551. FGather := TstgStageData.Create;
  552. FDetails := TList.Create;
  553. end;
  554. destructor TstgSubTenderStageData.Destroy;
  555. begin
  556. ClearObjects(FDetails);
  557. FDetails.Free;
  558. FGather.Free;
  559. inherited;
  560. end;
  561. function TstgSubTenderStageData.GetDetail(
  562. AIndex: Integer): TstgSubTenderDetailData;
  563. begin
  564. Result := TstgSubTenderDetailData(FDetails.Items[AIndex]);
  565. end;
  566. function TstgSubTenderStageData.GetDetailCount: Integer;
  567. begin
  568. Result := FDetails.Count;
  569. end;
  570. { TstgSubTenderDetailData }
  571. constructor TstgSubTenderDetailData.Create(ANode: TMeasureBillsIDTreeNode);
  572. begin
  573. FSerialNo := ANode.MajorIndex;
  574. FDetailStage := TstgStageData.Create;
  575. if Assigned(ANode.StageRec) then
  576. FDetailStage.AssignedData(ANode.StageRec);
  577. end;
  578. destructor TstgSubTenderDetailData.Destroy;
  579. begin
  580. FDetailStage.Free;
  581. inherited;
  582. end;
  583. { TstgErrorInfo }
  584. procedure TstgErrorInfo.AddErrorDetail(
  585. ARelaDetailNode: TstgGatherTreeNode);
  586. begin
  587. FDetails.Add(ARelaDetailNode);
  588. end;
  589. constructor TstgErrorInfo.Create(ARelaNode: TstgGatherTreeNode);
  590. begin
  591. FRelaNode := ARelaNode;
  592. FDetails := TList.Create;
  593. end;
  594. destructor TstgErrorInfo.Destroy;
  595. begin
  596. FDetails.Free;
  597. inherited;
  598. end;
  599. function TstgErrorInfo.GetDetail(AIndex: Integer): TstgGatherTreeNode;
  600. begin
  601. Result := TstgGatherTreeNode(FDetails.Items[AIndex]);
  602. end;
  603. function TstgErrorInfo.GetDetailCount: Integer;
  604. begin
  605. Result := FDetails.Count;
  606. end;
  607. end.