rmXmjBGLDetailDm.pas 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422
  1. unit rmXmjBGLDetailDm;
  2. interface
  3. uses
  4. SysUtils, Classes, DB, DBClient, ProjectData, sdIDTree, sdDB;
  5. type
  6. TBGLNode = class
  7. private
  8. FBGLCode: string;
  9. FBGLName: string;
  10. FBGLReason: string;
  11. FDirection: string;
  12. FBGLType: string;
  13. FDrawingCode: string;
  14. FApprovalCode: string;
  15. FBGLRelaFile: string;
  16. end;
  17. TXmjNode = class
  18. private
  19. FChildList: TList;
  20. FBGLList: TList;
  21. FCode: string;
  22. FName: string;
  23. FDgnQuantity1: Double;
  24. FDgnQuantity2: Double;
  25. FEndDealTotalPrice: Double;
  26. FEndGatherTotalPrice: Double;
  27. function GetChildCount: Integer;
  28. function GetChildNode(AIndex: Integer): TXmjNode;
  29. function GetBGLCount: Integer;
  30. function GetBGLNode(AIndex: Integer): TBGLNode;
  31. public
  32. constructor Create;
  33. destructor Destroy; override;
  34. function FindBGLNode(const ABGLCode: string): TBGLNode;
  35. property ChildCount: Integer read GetChildCount;
  36. property ChildNode[AIndex: Integer]: TXmjNode read GetChildNode;
  37. property BGLCount: Integer read GetBGLCount;
  38. property BGLNode[AIndex: Integer]: TBGLNode read GetBGLNode;
  39. end;
  40. TrmXmjBGLDetailData = class(TDataModule)
  41. cdsXmjBGLDetail: TClientDataSet;
  42. cdsXmjBGLDetailCode: TStringField;
  43. cdsXmjBGLDetailName: TWideStringField;
  44. cdsXmjBGLDetailDgnQuantity1: TFloatField;
  45. cdsXmjBGLDetailDgnQuantity2: TFloatField;
  46. cdsXmjBGLDetailDgnQuantity: TStringField;
  47. cdsXmjBGLDetailXmj_BGLName: TWideStringField;
  48. cdsXmjBGLDetailBGLCode: TWideStringField;
  49. cdsXmjBGLDetailBGLName: TWideStringField;
  50. cdsXmjBGLDetailBGLType: TWideStringField;
  51. cdsXmjBGLDetailReason: TWideStringField;
  52. cdsXmjBGLDetailDirection: TWideStringField;
  53. cdsXmjBGLDetailEndDealTotalPrice: TFloatField;
  54. cdsXmjBGLDetailEndGatherTotalPrice: TFloatField;
  55. cdsXmjBGLDetailBGTotalPrice: TFloatField;
  56. cdsXmjBGLDetailDrawingCode: TWideStringField;
  57. cdsXmjBGLDetailApprovalCode: TWideStringField;
  58. cdsXmjBGLDetailBGLRelaFile: TWideStringField;
  59. cdsXmjBGLDetailMemoStr: TWideStringField;
  60. private
  61. FProjectData: TProjectData;
  62. FClassXmjList: TList;
  63. function GetDgnQuantity(ANum1, ANum2: Double): string;
  64. procedure AddBGL(ABGLCode: string; AClassNode: TXmjNode);
  65. procedure AddBGLsData(ABGLCode: string; AClassNode: TXmjNode);
  66. procedure FilterNodeBGLData(ANode: TsdIDTreeNode; AClassNode: TXmjNode);
  67. procedure FilterBGLData(ANode: TsdIDTreeNode; AClassNode: TXmjNode);
  68. procedure AddDetailXmjNode(ANode: TsdIDTreeNode; AClassNode: TXmjNode);
  69. function CheckLeafXmj(ANode: TsdIDTreeNode): Boolean;
  70. function CheckHasBGL(ANode: TsdIDTreeNode): Boolean;
  71. procedure FilterDetailNode(ANode: TsdIDTreeNode; AClassNode: TXmjNode);
  72. procedure AddClassXmjNode(ANode: TsdIDTreeNode);
  73. function CheckChildNodeHasBGL(ANode: TsdIDTreeNode): Boolean;
  74. procedure FilterNode(ANode: TsdIDTreeNode);
  75. procedure WriteBGLNodeData(ABGLNode: TBGLNode);
  76. procedure WriteXmjNodeData(AXmjNode: TXmjNode; AIndex: Integer = -1);
  77. procedure WriteData;
  78. public
  79. function AssignData(AProjectData: TProjectData): TDataSet;
  80. end;
  81. implementation
  82. uses
  83. ZhAPI, DateUtils, BGLDm;
  84. {$R *.dfm}
  85. { TrmXmjBGLDetailData }
  86. procedure TrmXmjBGLDetailData.AddBGL(ABGLCode: string;
  87. AClassNode: TXmjNode);
  88. var
  89. BGLNode: TBGLNode;
  90. begin
  91. BGLNode := AClassNode.FindBGLNode(ABGLCode);
  92. if not Assigned(BGLNode) then
  93. begin
  94. BGLNode := TBGLNode.Create;
  95. BGLNode.FBGLCode := ABGLCode;
  96. with FProjectData.BGLData do
  97. begin
  98. if cdsBGL.Locate('Code', ABGLCode, []) then
  99. begin
  100. BGLNode.FBGLName := cdsBGLName.AsString;
  101. BGLNode.FBGLReason := cdsBGLPos_Reason.AsString;
  102. BGLNode.FDirection := cdsBGLDirection.AsString;
  103. BGLNode.FBGLType := '';
  104. BGLNode.FDrawingCode := cdsBGLDrawingCode.AsString;
  105. BGLNode.FApprovalCode := cdsBGLApprovalCode.AsString;
  106. BGLNode.FBGLRelaFile := '';
  107. end;
  108. end;
  109. AClassNode.FBGLList.Add(BGLNode);
  110. end;
  111. end;
  112. procedure TrmXmjBGLDetailData.AddBGLsData(ABGLCode: string;
  113. AClassNode: TXmjNode);
  114. var
  115. sgs: TStrings;
  116. i: Integer;
  117. begin
  118. if ABGLCode = '' then Exit;
  119. sgs := TStringList.Create;
  120. try
  121. sgs.Delimiter := ';';
  122. sgs.DelimitedText := ABGLCode;
  123. for i := 0 to sgs.Count - 1 do
  124. AddBGL(sgs.Strings[i], AClassNode);
  125. finally
  126. sgs.Free;
  127. end;
  128. end;
  129. procedure TrmXmjBGLDetailData.AddClassXmjNode(ANode: TsdIDTreeNode);
  130. var
  131. XmjNode: TXmjNode;
  132. begin
  133. if not Assigned(ANode) then Exit;
  134. XmjNode := TXmjNode.Create;
  135. FClassXmjList.Add(XmjNode);
  136. XmjNode.FCode := ANode.Rec.ValueByName('Code').AsString;
  137. XmjNode.FName := ANode.Rec.ValueByName('Name').AsString;
  138. XmjNode.FDgnQuantity1 := ANode.Rec.ValueByName('DgnQuantity1').AsFloat;
  139. FilterDetailNode(ANode, XmjNode);
  140. end;
  141. procedure TrmXmjBGLDetailData.AddDetailXmjNode(ANode: TsdIDTreeNode;
  142. AClassNode: TXmjNode);
  143. var
  144. DetailNode: TXmjNode;
  145. StageRec: TsdDataRecord;
  146. begin
  147. DetailNode := TXmjNode.Create;
  148. AClassNode.FChildList.Add(DetailNode);
  149. DetailNode.FName := ANode.Rec.ValueByName('Name').AsString;
  150. DetailNode.FDgnQuantity1 := ANode.Rec.ValueByName('DgnQuantity1').AsFloat;
  151. DetailNode.FDgnQuantity2 := ANode.Rec.ValueByName('DgnQuantity2').AsFloat;
  152. if FProjectData.PhaseData.Active then
  153. begin
  154. StageRec := FProjectData.PhaseData.StageData.StageRecord(ANode.ID);
  155. if Assigned(StageRec) then
  156. begin
  157. DetailNode.FEndDealTotalPrice := StageRec.ValueByName('EndDealTotalPrice').AsFloat;
  158. DetailNode.FEndGatherTotalPrice := StageRec.ValueByName('EndGatherTotalPrice').AsFloat;
  159. end;
  160. end;
  161. FilterBGLData(ANode, DetailNode);
  162. end;
  163. function TrmXmjBGLDetailData.AssignData(
  164. AProjectData: TProjectData): TDataSet;
  165. begin
  166. FProjectData := AProjectData;
  167. FClassXmjList := TList.Create;
  168. cdsXmjBGLDetail.Active := True;
  169. cdsXmjBGLDetail.EmptyDataSet;
  170. cdsXmjBGLDetail.DisableControls;
  171. try
  172. FilterNode(AProjectData.BillsCompileData.BillsCompileTree.FirstNode);
  173. WriteData;
  174. finally
  175. cdsXmjBGLDetail.EnableControls;
  176. Result := cdsXmjBGLDetail;
  177. ClearObjects(FClassXmjList);
  178. FClassXmjList.Free;
  179. end;
  180. end;
  181. function TrmXmjBGLDetailData.CheckChildNodeHasBGL(
  182. ANode: TsdIDTreeNode): Boolean;
  183. var
  184. iNext, iTotal: Integer;
  185. vChild: TsdIDTreeNode;
  186. begin
  187. Result := False;
  188. if not Assigned(ANode) then Exit;
  189. iNext := 1;
  190. iTotal := ANode.PosterityCount;
  191. vChild := ANode.NextNode;
  192. while (iNext <= iTotal) and not Result do
  193. begin
  194. if not vChild.HasChildren then
  195. Result := CheckHasBGL(vChild);
  196. vChild := vChild.NextNode;
  197. Inc(iNext);
  198. end;
  199. end;
  200. function TrmXmjBGLDetailData.CheckHasBGL(ANode: TsdIDTreeNode): Boolean;
  201. var
  202. StageRec: TsdDataRecord;
  203. begin
  204. Result := False;
  205. StageRec := FProjectData.PhaseData.StageData.StageRecord(ANode.ID);
  206. if Assigned(StageRec) then
  207. Result := (StageRec.ValueByName('EndQcTotalPrice').AsFloat <> 0)
  208. or (StageRec.ValueByName('EndPcTotalPrice').AsFloat <> 0);
  209. end;
  210. function TrmXmjBGLDetailData.CheckLeafXmj(ANode: TsdIDTreeNode): Boolean;
  211. var
  212. i: Integer;
  213. begin
  214. Result := True;
  215. for i := 0 to ANode.ChildCount - 1 do
  216. begin
  217. if ANode.ChildNodes[i].Rec.ValueByName('B_Code').AsString = '' then
  218. begin
  219. Result := False;
  220. Break;
  221. end;
  222. end;
  223. end;
  224. procedure TrmXmjBGLDetailData.FilterBGLData(ANode: TsdIDTreeNode;
  225. AClassNode: TXmjNode);
  226. var
  227. i: Integer;
  228. begin
  229. if not Assigned(ANode) then Exit;
  230. if ANode.HasChildren then
  231. for i := 0 to ANode.ChildCount - 1 do
  232. FilterBGLData(ANode.ChildNodes[i], AClassNode)
  233. else
  234. FilterNodeBGLData(ANode, AClassNode);
  235. end;
  236. procedure TrmXmjBGLDetailData.FilterDetailNode(ANode: TsdIDTreeNode;
  237. AClassNode: TXmjNode);
  238. var
  239. i: Integer;
  240. begin
  241. if not Assigned(ANode) and (ANode.Level < 2) then Exit;
  242. if ANode.Rec.ValueByName('B_Code').AsString <> '' then Exit;
  243. if CheckLeafXmj(ANode) and CheckHasBGL(ANode) then
  244. AddDetailXmjNode(ANode, AClassNode);
  245. if ANode.HasChildren then
  246. begin
  247. for i := 0 to ANode.ChildCount - 1 do
  248. FilterDetailNode(ANode.ChildNodes[i], AClassNode);
  249. end;
  250. end;
  251. procedure TrmXmjBGLDetailData.FilterNode(ANode: TsdIDTreeNode);
  252. begin
  253. if not Assigned(ANode) then Exit;
  254. if ANode.Level> 1 then Exit;
  255. if ANode.Level = 0 then
  256. FilterNode(ANode.FirstChild)
  257. else if CheckHasBGL(ANode) then
  258. AddClassXmjNode(ANode);
  259. FilterNode(ANode.NextSibling);
  260. end;
  261. procedure TrmXmjBGLDetailData.FilterNodeBGLData(ANode: TsdIDTreeNode;
  262. AClassNode: TXmjNode);
  263. var
  264. StageRec: TsdDataRecord;
  265. begin
  266. StageRec := FProjectData.PhaseData.StageData.StageRecord(ANode.ID);
  267. if not Assigned(StageRec) then Exit;
  268. AddBGLsData(StageRec.ValueByName('EndQcBGLCode').AsString, AClassNode);
  269. AddBGLsData(StageRec.ValueByName('EndPcBGLCode').AsString, AClassNode);
  270. end;
  271. function TrmXmjBGLDetailData.GetDgnQuantity(ANum1, ANum2: Double): string;
  272. begin
  273. Result := '';
  274. if ANum1 <> 0 then
  275. begin
  276. Result := FloatToStr(ANum1);
  277. if ANum2 <> 0 then
  278. Result := Result + '/' + FloatToStr(ANum2);
  279. end;
  280. end;
  281. procedure TrmXmjBGLDetailData.WriteBGLNodeData(ABGLNode: TBGLNode);
  282. begin
  283. cdsXmjBGLDetail.Append;
  284. cdsXmjBGLDetailXmj_BGLName.AsString := ABGLNode.FBGLName;
  285. cdsXmjBGLDetailBGLCode.AsString := ABGLNode.FBGLCode;
  286. cdsXmjBGLDetailBGLName.AsString := ABGLNode.FBGLName;
  287. cdsXmjBGLDetailReason.AsString := ABGLNode.FBGLReason;
  288. cdsXmjBGLDetailDirection.AsString := ABGLNode.FDirection;
  289. cdsXmjBGLDetailDrawingCode.AsString := ABGLNode.FDrawingCode;
  290. cdsXmjBGLDetailApprovalCode.AsString := ABGLNode.FApprovalCode;
  291. cdsXmjBGLDetailBGLRelaFile.AsString := ABGLNode.FBGLRelaFile;
  292. cdsXmjBGLDetail.Post;
  293. end;
  294. procedure TrmXmjBGLDetailData.WriteData;
  295. var
  296. i: Integer;
  297. begin
  298. for i := 0 to FClassXmjList.Count - 1 do
  299. WriteXmjNodeData(TXmjNode(FClassXmjList.Items[i]));
  300. end;
  301. procedure TrmXmjBGLDetailData.WriteXmjNodeData(AXmjNode: TXmjNode;
  302. AIndex: Integer);
  303. var
  304. i: Integer;
  305. begin
  306. cdsXmjBGLDetail.Append;
  307. if AIndex = -1 then
  308. cdsXmjBGLDetailCode.AsString := AXmjNode.FCode
  309. else
  310. cdsXmjBGLDetailCode.AsString := IntToStr(AIndex + 1);
  311. cdsXmjBGLDetailName.AsString := AXmjNode.FName;
  312. cdsXmjBGLDetailDgnQuantity1.AsFloat := AXmjNode.FDgnQuantity1;
  313. cdsXmjBGLDetailDgnQuantity2.AsFloat := AXmjNode.FDgnQuantity2;
  314. cdsXmjBGLDetailDgnQuantity.AsString := GetDgnQuantity(AXmjNode.FDgnQuantity1, AXmjNode.FDgnQuantity2);
  315. cdsXmjBGLDetailEndDealTotalPrice.AsFloat := AXmjNode.FEndDealTotalPrice;
  316. cdsXmjBGLDetailEndGatherTotalPrice.AsFloat := AXmjNode.FEndGatherTotalPrice;
  317. cdsXmjBGLDetailBGTotalPrice.AsFloat := AXmjNode.FEndGatherTotalPrice - AXmjNode.FEndDealTotalPrice;
  318. cdsXmjBGLDetailXmj_BGLName.AsString := AXmjNode.FName;
  319. cdsXmjBGLDetail.Post;
  320. for i := 0 to AXmjNode.BGLCount - 1 do
  321. WriteBGLNodeData(AXmjNode.BGLNode[i]);
  322. for i := 0 to AXmjNode.ChildCount - 1 do
  323. WriteXmjNodeData(AXmjNode.ChildNode[i], i);
  324. end;
  325. { TXmjNode }
  326. constructor TXmjNode.Create;
  327. begin
  328. FChildList := TList.Create;
  329. FBGLList := TList.Create;
  330. end;
  331. destructor TXmjNode.Destroy;
  332. begin
  333. ClearObjects(FBGLList);
  334. FBGLList.Free;
  335. ClearObjects(FChildList);
  336. FChildList.Free;
  337. inherited;
  338. end;
  339. function TXmjNode.FindBGLNode(const ABGLCode: string): TBGLNode;
  340. var
  341. i: Integer;
  342. begin
  343. Result := nil;
  344. for i := 0 to BGLCount - 1 do
  345. begin
  346. if BGLNode[i].FBGLCode = ABGLCode then
  347. begin
  348. Result := BGLNode[i];
  349. Break;
  350. end;
  351. end;
  352. end;
  353. function TXmjNode.GetBGLCount: Integer;
  354. begin
  355. Result := FBGLList.Count;
  356. end;
  357. function TXmjNode.GetBGLNode(AIndex: Integer): TBGLNode;
  358. begin
  359. Result := TBGLNode(FBGLList.Items[AIndex]);
  360. end;
  361. function TXmjNode.GetChildCount: Integer;
  362. begin
  363. Result := FChildList.Count;
  364. end;
  365. function TXmjNode.GetChildNode(AIndex: Integer): TXmjNode;
  366. begin
  367. Result := TXmjNode(FChildList.Items[AIndex]);
  368. end;
  369. end.