ProjGatherTree.pas 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456
  1. unit ProjGatherTree;
  2. interface
  3. uses
  4. CacheTree, Classes, CalcData;
  5. type
  6. TProjGatherTreeNode = class(TCacheNode)
  7. private
  8. FCode: string;
  9. FB_Code: string;
  10. FName: string;
  11. FUnits: string;
  12. FPrice: Double;
  13. FSerialNo: Integer;
  14. FXiangCode: string;
  15. FMuCode: string;
  16. FJieCode: string;
  17. FXiMuCode: string;
  18. FIndexCode: string;
  19. FChapterParentID: Integer;
  20. FGatherCalc: TProjCalc;
  21. FProjs: TList;
  22. function GetProjCount: Integer;
  23. function GetProj(AIndex: Integer): TProjCalc;
  24. function GetChapterParentID: Integer;
  25. function GetLevel: Integer;
  26. public
  27. constructor Create(ACacheTree: TCacheTree; AID: Integer; AProjCount: Integer);
  28. destructor Destroy; override;
  29. procedure InitTotalPrice_Rc;
  30. procedure UpdateTotalPrice_Rc(ANode: TProjGatherTreeNode);
  31. procedure CalcTotalPrice_Rc;
  32. procedure InitCalcData;
  33. procedure AddCalcData(ANode: TProjGatherTreeNode);
  34. procedure MinusCalcData(ANode: TProjGatherTreeNode);
  35. property Code: string read FCode write FCode;
  36. property B_Code: string read FB_Code write FB_Code;
  37. property Name: string read FName write FName;
  38. property Units: string read FUnits write FUnits;
  39. property Price: Double read FPrice write FPrice;
  40. property SerialNo: Integer read FSerialNo write FSerialNo;
  41. property XiangCode: string read FXiangCode write FXiangCode;
  42. property MuCode: string read FMuCode write FMuCode;
  43. property JieCode: string read FJieCode write FJieCode;
  44. property XiMuCode: string read FXiMuCode write FXiMuCode;
  45. property IndexCode: string read FIndexCode write FIndexCode;
  46. property Level: Integer read GetLevel;
  47. property ChapterParentID: Integer read GetChapterParentID;
  48. property GatherCalc: TProjCalc read FGatherCalc;
  49. property ProjCount: Integer read GetProjCount;
  50. property Proj[AIndex: Integer]: TProjCalc read GetProj;
  51. end;
  52. TProjGatherTree = class(TCacheTree)
  53. private
  54. FProjCount: Integer;
  55. FFixedIDNodes: TList;
  56. FGatherNode: TProjGatherTreeNode;
  57. FSerialNo: Integer;
  58. function GetNewNode(AFixedID: Integer = -1): TProjGatherTreeNode;
  59. procedure Calculate(ANode: TProjGatherTreeNode);
  60. procedure CalcGatherNode;
  61. public
  62. constructor Create(AProjCount: Integer);
  63. destructor Destroy; override;
  64. function AddNode(AParent, ANextSibling: TProjGatherTreeNode; AFixedID: Integer = -1): TProjGatherTreeNode;
  65. function FindNode(AParent: TProjGatherTreeNode; const ACode, AB_Code, AName: string; APrice: Double): TProjGatherTreeNode; overload;
  66. function FindNode(AParent: TProjGatherTreeNode; const ACode, AB_Code: string; APrice: Double): TProjGatherTreeNode; overload;
  67. function FindNode(AParent: TProjGatherTreeNode; const AName: string; APrice: Double): TProjGatherTreeNode; overload;
  68. function FindNode(AFixedID: Integer): TProjGatherTreeNode; overload;
  69. function FindNextSibling(AParent: TProjGatherTreeNode; const ACode, AB_Code: string): TProjGatherTreeNode;
  70. procedure CalculateAll;
  71. procedure SaveDebugFile(const AFileName: string);
  72. property GatherNode: TProjGatherTreeNode read FGatherNode;
  73. end;
  74. implementation
  75. uses
  76. ZhAPI, SysUtils, ConditionalDefines;
  77. { TProjGatherTreeNode }
  78. procedure TProjGatherTreeNode.AddCalcData(ANode: TProjGatherTreeNode);
  79. var
  80. iProj: Integer;
  81. begin
  82. GatherCalc.AddCalcData(ANode.GatherCalc);
  83. for iProj := 0 to ProjCount - 1 do
  84. Proj[iProj].AddCalcData(ANode.Proj[iProj]);
  85. end;
  86. procedure TProjGatherTreeNode.CalcTotalPrice_Rc;
  87. var
  88. iProj: Integer;
  89. begin
  90. GatherCalc.CalcTotalPrice_Rc(Price);
  91. for iProj := 0 to ProjCount - 1 do
  92. Proj[iProj].CalcTotalPrice_Rc(Price);
  93. end;
  94. constructor TProjGatherTreeNode.Create(ACacheTree: TCacheTree; AID: Integer; AProjCount: Integer);
  95. var
  96. i: Integer;
  97. ProjCalc: TProjCalc;
  98. begin
  99. inherited Create(ACacheTree, AID);
  100. FGatherCalc := TProjCalc.Create;
  101. FProjs := TList.Create;
  102. for i := 0 to AProjCount - 1 do
  103. begin
  104. ProjCalc := TProjCalc.Create;
  105. FProjs.Add(ProjCalc);
  106. end;
  107. end;
  108. destructor TProjGatherTreeNode.Destroy;
  109. begin
  110. FGatherCalc.free;
  111. ClearObjects(FProjs);
  112. FProjs.Free;
  113. inherited;
  114. end;
  115. function TProjGatherTreeNode.GetChapterParentID: Integer;
  116. var
  117. vNode: TProjGatherTreeNode;
  118. begin
  119. Result := -1;
  120. if Self.Level > 2 then
  121. begin
  122. vNode := TProjGatherTreeNode(Self.Parent);
  123. while vNode.Level > 2 do
  124. vNode := TProjGatherTreeNode(vNode.Parent);
  125. Result := vNode.ID
  126. end;
  127. end;
  128. function TProjGatherTreeNode.GetLevel: Integer;
  129. begin
  130. if Assigned(Parent) and (Parent.ID <> -1) then
  131. Result := TProjGatherTreeNode(Parent).Level + 1
  132. else
  133. Result := 1;
  134. end;
  135. function TProjGatherTreeNode.GetProj(AIndex: Integer): TProjCalc;
  136. begin
  137. Result := TProjCalc(FProjs.Items[AIndex]);
  138. end;
  139. function TProjGatherTreeNode.GetProjCount: Integer;
  140. begin
  141. Result := FProjs.Count;
  142. end;
  143. procedure TProjGatherTreeNode.InitCalcData;
  144. var
  145. iProj: Integer;
  146. begin
  147. GatherCalc.InitCalcData;
  148. for iProj := 0 to ProjCount - 1 do
  149. Proj[iProj].InitCalcData;
  150. end;
  151. procedure TProjGatherTreeNode.InitTotalPrice_Rc;
  152. var
  153. iProj: Integer;
  154. begin
  155. GatherCalc.InitTotalPrice_Rc;
  156. for iProj := 0 to ProjCount - 1 do
  157. Proj[iProj].InitTotalPrice_Rc;
  158. end;
  159. procedure TProjGatherTreeNode.MinusCalcData(ANode: TProjGatherTreeNode);
  160. var
  161. iProj: Integer;
  162. begin
  163. GatherCalc.MinusCalcData(ANode.GatherCalc);
  164. for iProj := 0 to ProjCount - 1 do
  165. Proj[iProj].MinusCalcData(ANode.Proj[iProj]);
  166. end;
  167. procedure TProjGatherTreeNode.UpdateTotalPrice_Rc(ANode: TProjGatherTreeNode);
  168. var
  169. iProj: Integer;
  170. begin
  171. GatherCalc.UpdateTotalPrice_Rc(ANode.GatherCalc);
  172. for iProj := 0 to ANode.ProjCount - 1 do
  173. Proj[iProj].UpdateTotalPrice_Rc(ANode.Proj[iProj]);
  174. end;
  175. { TProjGatherTree }
  176. procedure TProjGatherTree.Calculate(ANode: TProjGatherTreeNode);
  177. var
  178. iChild: Integer;
  179. vChild: TProjGatherTreeNode;
  180. begin
  181. ANode.SerialNo := FSerialNo;
  182. Inc(FSerialNo);
  183. ANode.InitTotalPrice_Rc;
  184. if ANode.Children.Count > 0 then
  185. begin
  186. for iChild := 0 to ANode.Children.Count - 1 do
  187. begin
  188. vChild := TProjGatherTreeNode(ANode.Children.Items[iChild]);
  189. Calculate(vChild);
  190. ANode.UpdateTotalPrice_Rc(vChild);
  191. end;
  192. end
  193. else
  194. ANode.CalcTotalPrice_Rc;
  195. end;
  196. procedure TProjGatherTree.CalculateAll;
  197. var
  198. vNode: TProjGatherTreeNode;
  199. begin
  200. FSerialNo := 1;
  201. vNode := TProjGatherTreeNode(FirstNode);
  202. while Assigned(vNode) do
  203. begin
  204. Calculate(vNode);
  205. vNode := TProjGatherTreeNode(vNode.NextSibling);
  206. end;
  207. CalcGatherNode;
  208. end;
  209. constructor TProjGatherTree.Create(AProjCount: Integer);
  210. begin
  211. inherited Create;
  212. FProjCount := AProjCount;
  213. FFixedIDNodes := TList.Create;
  214. FGatherNode := TProjGatherTreeNode.Create(nil, -2, AProjCount);
  215. end;
  216. destructor TProjGatherTree.Destroy;
  217. begin
  218. FGatherNode.Free;
  219. FFixedIDNodes.Free;
  220. inherited;
  221. end;
  222. function TProjGatherTree.FindNode(AParent: TProjGatherTreeNode;
  223. const ACode, AB_Code, AName: string;
  224. APrice: Double): TProjGatherTreeNode;
  225. var
  226. iChild: Integer;
  227. vChild: TProjGatherTreeNode;
  228. begin
  229. Result := nil;
  230. for iChild := 0 to AParent.Children.Count - 1 do
  231. begin
  232. vChild := TProjGatherTreeNode(AParent.Children.Items[iChild]);
  233. if (vChild.Code = ACode) and (vChild.B_Code = AB_Code) and
  234. (vChild.Name = AName) and (abs(vChild.Price - APrice) < 0.00001) then
  235. begin
  236. Result := vChild;
  237. Break;
  238. end;
  239. end;
  240. end;
  241. function TProjGatherTree.FindNode(AParent: TProjGatherTreeNode;
  242. const ACode, AB_Code: string; APrice: Double): TProjGatherTreeNode;
  243. var
  244. iChild: Integer;
  245. vChild: TProjGatherTreeNode;
  246. begin
  247. Result := nil;
  248. for iChild := 0 to AParent.Children.Count - 1 do
  249. begin
  250. vChild := TProjGatherTreeNode(AParent.Children.Items[iChild]);
  251. if (vChild.Code = ACode) and (vChild.B_Code = AB_Code) and
  252. (abs(vChild.Price - APrice) < 0.00001) then
  253. begin
  254. Result := vChild;
  255. Break;
  256. end;
  257. end;
  258. end;
  259. function TProjGatherTree.FindNode(AParent: TProjGatherTreeNode;
  260. const AName: string; APrice: Double): TProjGatherTreeNode;
  261. var
  262. iChild: Integer;
  263. vChild: TProjGatherTreeNode;
  264. begin
  265. Result := nil;
  266. for iChild := 0 to AParent.Children.Count - 1 do
  267. begin
  268. vChild := TProjGatherTreeNode(AParent.Children.Items[iChild]);
  269. if (vChild.Name = AName) and (abs(vChild.Price - APrice) < 0.00001) then
  270. begin
  271. Result := vChild;
  272. Break;
  273. end;
  274. end;
  275. end;
  276. function TProjGatherTree.FindNextSibling(AParent: TProjGatherTreeNode;
  277. const ACode, AB_Code: string): TProjGatherTreeNode;
  278. var
  279. vNext: TProjGatherTreeNode;
  280. sCodeID, sCodeID2, sB_CodeID, sB_CodeID2: string;
  281. begin
  282. Result := nil;
  283. if Assigned(AParent) then
  284. vNext := TProjGatherTreeNode(AParent.FirstChild)
  285. else
  286. vNext := TProjGatherTreeNode(Root.FirstChild);
  287. if (ACode = '') and (AB_Code = '') then Exit;
  288. sCodeID := ConvertDigitCode(ACode, 3, '-');
  289. sB_CodeID := ConvertDigitCode(AB_Code, 4, '-');
  290. while Assigned(vNext) do
  291. begin
  292. sCodeID2 := ConvertDigitCode(vNext.Code, 3, '-');
  293. sB_CodeID2 := ConvertDigitCode(vNext.B_Code, 4, '-');
  294. if sCodeID < sCodeID2 then
  295. begin
  296. Result := vNext;
  297. Break;
  298. end
  299. else if sB_CodeID < sB_CodeID2 then
  300. begin
  301. Result := vNext;
  302. Break;
  303. end;
  304. vNext := TProjGatherTreeNode(vNext.NextSibling);
  305. end;
  306. end;
  307. function TProjGatherTree.FindNode(AFixedID: Integer): TProjGatherTreeNode;
  308. var
  309. i: Integer;
  310. vNode: TProjGatherTreeNode;
  311. begin
  312. Result := nil;
  313. for i := 0 to FFixedIDNodes.Count - 1 do
  314. begin
  315. vNode := TProjGatherTreeNode(FFixedIDNodes.Items[i]);
  316. if vNode.ID = AFixedID then
  317. begin
  318. Result := vNode;
  319. Break;
  320. end;
  321. end;
  322. end;
  323. function TProjGatherTree.GetNewNode(AFixedID: Integer): TProjGatherTreeNode;
  324. begin
  325. if AFixedID <> -1 then
  326. begin
  327. Result := TProjGatherTreeNode.Create(Self, AFixedID, FProjCount);
  328. FFixedIDNodes.Add(Result);
  329. end
  330. else
  331. Result := TProjGatherTreeNode.Create(Self, GetNewNodeID, FProjCount);
  332. CacheNodes.Add(Result);
  333. end;
  334. function TProjGatherTree.AddNode(AParent, ANextSibling: TProjGatherTreeNode;
  335. AFixedID: Integer): TProjGatherTreeNode;
  336. begin
  337. Result := GetNewNode(AFixedID);
  338. if Assigned(ANextSibling) then
  339. ANextSibling.InsertPreSibling(Result)
  340. else if Assigned(AParent) then
  341. AParent.InsertChild(Result)
  342. else
  343. Root.InsertChild(Result);
  344. end;
  345. procedure TProjGatherTree.SaveDebugFile(const AFileName: string);
  346. var
  347. sgs: TStringList;
  348. i: Integer;
  349. vNode: TProjGatherTreeNode;
  350. begin
  351. sgs := TStringList.Create;
  352. try
  353. for i := 0 to CacheNodes.Count - 1 do
  354. begin
  355. vNode := TProjGatherTreeNode(CacheNodes.Items[i]);
  356. sgs.Add(Format('ID: %d; Code: %s; B_Code: %s; Name: %s', [vNode.ID, vNode.Code, vNode.B_Code, vNode.Name]));
  357. end;
  358. sgs.SaveToFile(AFileName);
  359. finally
  360. sgs.Free;
  361. end;
  362. end;
  363. procedure TProjGatherTree.CalcGatherNode;
  364. procedure AddGatherCalc(AID: Integer);
  365. var
  366. vNode: TProjGatherTreeNode;
  367. begin
  368. vNode := FindNode(AID);
  369. if Assigned(vNode) then
  370. GatherNode.AddCalcData(vNode);
  371. end;
  372. procedure MinusGatherCalc(AID: Integer);
  373. var
  374. vNode: TProjGatherTreeNode;
  375. begin
  376. vNode := FindNode(AID);
  377. if Assigned(vNode) then
  378. GatherNode.MinusCalcData(vNode);
  379. end;
  380. begin
  381. GatherNode.InitCalcData;
  382. // 全国
  383. // 第一部分(1)+第二部分(2)+第三部分(3)+预备费(7)+新增加费用项目(其他费用_广东)(15)-回收金额(16)
  384. AddGatherCalc(1);
  385. AddGatherCalc(2);
  386. AddGatherCalc(3);
  387. AddGatherCalc(7);
  388. AddGatherCalc(15);
  389. MinusGatherCalc(16);
  390. // 广东
  391. // 全国的基础上+建设期贷款利息(34)+公路功能以外的项目(9)
  392. if _IsGuangDong then
  393. begin
  394. AddGatherCalc(34);
  395. AddGatherCalc(9);
  396. end;
  397. end;
  398. end.