ProjGatherTree.pas 13 KB

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