BillsTree.pas 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386
  1. unit BillsTree;
  2. interface
  3. uses
  4. sdIDTree, sdDB, mDataRecord;
  5. type
  6. TBillsIDTreeNode = class(TsdIDTreeNode)
  7. private
  8. FDealQuantity: Double;
  9. FDealTotalPrice: Double;
  10. FQcQuantity: Double;
  11. FQcTotalPrice: Double;
  12. FPcQuantity: Double;
  13. FPcTotalPrice: Double;
  14. FGatherTotalPrice: Double;
  15. FGatherQuantity: Double;
  16. function HasCountPrice: Boolean;
  17. function HasTotalPrice: Boolean;
  18. function GetRec: TBillsRecord;
  19. public
  20. function CanUpLevel: Boolean; override;
  21. function CanDownLevel: Boolean; override;
  22. function CanUpMove: Boolean; override;
  23. function CanDownMove: Boolean; override;
  24. function UpLevel: Boolean; override;
  25. function DownLevel: Boolean; override;
  26. function HasMeasure: Boolean;
  27. function HasLedger: Boolean;
  28. function CountPriceEnable: Boolean;
  29. function TotalPriceEnable: Boolean;
  30. property Rec: TBillsRecord read GetRec;
  31. property DealQuantity: Double read FDealQuantity write FDealQuantity;
  32. property DealTotalPrice: Double read FDealTotalPrice write FDealTotalPrice;
  33. property QcQuantity: Double read FQcQuantity write FQcQuantity;
  34. property QcTotalPrice: Double read FQcTotalPrice write FQcTotalPrice;
  35. property PcQuantity: Double read FPcQuantity write FPcQuantity;
  36. property PcTotalPrice: Double read FPcTotalPrice write FPcTotalPrice;
  37. property GatherQuantity: Double read FGatherQuantity write FGatherQuantity;
  38. property GatherTotalPrice: Double read FGatherTotalPrice write FGatherTotalPrice;
  39. end;
  40. TReCalculateNode = procedure(AID: Integer) of object;
  41. TBillsIDTree = class(TsdIDTree)
  42. protected
  43. function CreateItem: TsdIDTreeNode; override;
  44. public
  45. function CanDelete(ANode: TsdIDTreeNode): Boolean; override;
  46. function DeleteNode(ANode: TsdIDTreeNode): Boolean; override;
  47. function Add(AParentID, ANextSiblingID: TsdTreeNodeID): TsdIDTreeNode; override;
  48. procedure DoOnReCalcNode(AID: Integer); overload; virtual; abstract;
  49. procedure DoOnReCalcNode(ANode: TsdIDTreeNode); overload; virtual; abstract;
  50. end;
  51. TCompileBillsIDTree = class(TBillsIDTree)
  52. private
  53. FOnReCalcNode: TReCalculateNode;
  54. public
  55. procedure DoOnReCalcNode(AID: Integer); overload; override;
  56. procedure DoOnReCalcNode(ANode: TsdIDTreeNode); overload; override;
  57. property OnReCalcNode: TReCalculateNode read FOnReCalcNode write FOnReCalcNode;
  58. end;
  59. TMeasureBillsIDTreeNode = class(TBillsIDTreeNode)
  60. private
  61. FStageRec: TStageRecord;
  62. public
  63. function UpLevel: Boolean; override;
  64. function DownLevel: Boolean; override;
  65. // Cache Data
  66. property StageRec: TStageRecord read FStageRec write FStageRec;
  67. end;
  68. TMeasureBillsIDTree = class(TBillsIDTree)
  69. private
  70. FCompileTree: TCompileBillsIDTree;
  71. protected
  72. function CreateItem: TsdIDTreeNode; override;
  73. public
  74. procedure DoOnReCalcNode(AID: Integer); overload; override;
  75. procedure DoOnReCalcNode(ANode: TsdIDTreeNode); overload; override;
  76. property CompileTree: TCompileBillsIDTree read FCompileTree write FCompileTree;
  77. end;
  78. TEstimateIDTreeNode = class(TsdIDTreeNode)
  79. public
  80. function CanExpand: Boolean; override;
  81. end;
  82. TEstimateIDTree = class(TsdIDTree)
  83. public
  84. function CreateItem: TsdIDTreeNode; override;
  85. end;
  86. implementation
  87. { TBillsIDTree }
  88. function TBillsIDTree.Add(AParentID,
  89. ANextSiblingID: TsdTreeNodeID): TsdIDTreeNode;
  90. begin
  91. // 不允许插入首层节点
  92. if (Selected <> nil) and (Selected.Level = 0) then
  93. Result := inherited Add(Selected.ID, -1)
  94. else
  95. Result := inherited Add(AParentID, ANextSiblingID);
  96. end;
  97. function TBillsIDTree.CanDelete(ANode: TsdIDTreeNode): Boolean;
  98. begin
  99. Result := Inherited CanDelete(ANode)
  100. and (ANode.ID >= 100)
  101. and (not ANode.Rec.ValueByName('LockedLevel').AsBoolean)
  102. and (ANode.Rec.ValueByName('AddDealQuantity').AsFloat = 0)
  103. and (ANode.Rec.ValueByName('AddDealTotalPrice').AsFloat = 0)
  104. and (ANode.Rec.ValueByName('AddQcQuantity').AsFloat = 0)
  105. and (ANode.Rec.ValueByName('AddQcTotalPrice').AsFloat = 0)
  106. and (ANode.Rec.ValueByName('AddPcQuantity').AsFloat = 0)
  107. and (ANode.Rec.ValueByName('AddPcTotalPrice').AsFloat = 0);
  108. end;
  109. function TBillsIDTree.CreateItem: TsdIDTreeNode;
  110. begin
  111. Result := TBillsIDTreeNode.Create(Self);
  112. end;
  113. function TBillsIDTree.DeleteNode(ANode: TsdIDTreeNode): Boolean;
  114. var
  115. vParent: TsdIDTreeNode;
  116. begin
  117. vParent := ANode.Parent;
  118. Result := inherited DeleteNode(ANode);
  119. DoOnReCalcNode(vParent);
  120. end;
  121. { TBillsIDTreeNode }
  122. function TBillsIDTreeNode.CanDownLevel: Boolean;
  123. begin
  124. Result := Inherited CanDownLevel
  125. and (Level > 0)
  126. and (not Rec.ValueByName('LockedLevel').AsBoolean)
  127. and not HasMeasure;
  128. if Assigned(PrevSibling) then
  129. begin
  130. Result := Result
  131. and (PrevSibling.HasChildren or not TBillsIDTreeNode(PrevSibling).HasMeasure);
  132. end;
  133. end;
  134. function TBillsIDTreeNode.CanDownMove: Boolean;
  135. begin
  136. Result := Inherited CanDownMove
  137. and (not Rec.ValueByName('LockedLevel').AsBoolean);
  138. end;
  139. function TBillsIDTreeNode.CanUpLevel: Boolean;
  140. var
  141. vNextSibling: TsdIDTreeNode;
  142. begin
  143. Result := Inherited CanUpLevel
  144. and (Level > 1)
  145. and (not Rec.ValueByName('LockedLevel').AsBoolean)
  146. and not HasMeasure;
  147. vNextSibling := NextSibling;
  148. while Assigned(vNextSibling) and Result do
  149. begin
  150. Result := Result
  151. and not TBillsIDTreeNode(NextSibling).HasMeasure;
  152. vNextSibling := vNextSibling.NextSibling;
  153. end;
  154. end;
  155. function TBillsIDTreeNode.CanUpMove: Boolean;
  156. begin
  157. Result := Inherited CanUpMove
  158. and (not Rec.ValueByName('LockedLevel').AsBoolean);
  159. end;
  160. function TBillsIDTreeNode.CountPriceEnable: Boolean;
  161. begin
  162. Result := HasCountPrice or (not HasTotalPrice);
  163. end;
  164. function TBillsIDTreeNode.DownLevel: Boolean;
  165. var
  166. iOrgParentID: Integer;
  167. begin
  168. iOrgParentID := ParentID;
  169. Result := inherited DownLevel;
  170. if not Result then Exit;
  171. // 如升级后变为父项,则清空数量、单价
  172. if Assigned(Parent) then
  173. begin
  174. Parent.Rec.ValueByName('OrgQuantity').AsFloat := 0;
  175. Parent.Rec.ValueByName('MisQuantity').AsFloat := 0;
  176. Parent.Rec.ValueByName('OthQuantity').AsFloat := 0;
  177. Parent.Rec.ValueByName('Quantity').AsFloat := 0;
  178. Parent.Rec.ValueByName('Price').AsFloat := 0;
  179. end;
  180. TBillsIDTree(Owner).DoOnReCalcNode(ParentID);
  181. TBillsIDTree(Owner).DoOnReCalcNode(iOrgParentID);
  182. end;
  183. function TBillsIDTreeNode.GetRec: TBillsRecord;
  184. begin
  185. Result := TBillsRecord(TsdIDTreeNode(Self).Rec);
  186. end;
  187. function TBillsIDTreeNode.HasCountPrice: Boolean;
  188. begin
  189. Result := False;
  190. if not Assigned(Rec) then Exit;
  191. Result := (Rec.Price.AsFloat <> 0)
  192. or (Rec.OrgQuantity.AsFloat <> 0)
  193. or (Rec.MisQuantity.AsFloat <> 0)
  194. or (Rec.OthQuantity.AsFloat <> 0)
  195. or (Rec.AddDealQuantity.AsFloat <> 0)
  196. or (Rec.AddQcQuantity.AsFloat <> 0)
  197. or (Rec.AddPcQuantity.AsFloat <> 0);
  198. end;
  199. function TBillsIDTreeNode.HasLedger: Boolean;
  200. begin
  201. Result := False;
  202. if not Assigned(Rec) then Exit;
  203. Result := (Rec.Price.AsFloat <> 0)
  204. or (Rec.Quantity.AsFloat <> 0);
  205. end;
  206. function TBillsIDTreeNode.HasMeasure: Boolean;
  207. begin
  208. Result := False;
  209. if not Assigned(Rec) then Exit;
  210. Result := (Rec.AddDealQuantity.AsFloat <> 0)
  211. or (Rec.AddDealTotalPrice.AsFloat <> 0)
  212. or (Rec.AddQcQuantity.AsFloat <> 0)
  213. or (Rec.AddQcTotalPrice.AsFloat <> 0)
  214. or (Rec.AddPcQuantity.AsFloat <> 0)
  215. or (Rec.AddPcTotalPrice.AsFloat <> 0);
  216. end;
  217. function TBillsIDTreeNode.HasTotalPrice: Boolean;
  218. begin
  219. Result := False;
  220. if not Assigned(Rec) then Exit;
  221. Result := (Rec.OrgTotalPrice.AsFloat <> 0)
  222. or (Rec.MisTotalPrice.AsFloat <> 0)
  223. or (Rec.OthTotalPrice.AsFloat <> 0)
  224. or (Rec.AddDealTotalPrice.AsFloat <> 0)
  225. or (Rec.AddQcTotalPrice.AsFloat <> 0)
  226. or (Rec.AddPcTotalPrice.AsFloat <> 0);
  227. end;
  228. function TBillsIDTreeNode.TotalPriceEnable: Boolean;
  229. begin
  230. Result := not HasCountPrice;
  231. end;
  232. function TBillsIDTreeNode.UpLevel: Boolean;
  233. var
  234. iOrgParentID: Integer;
  235. begin
  236. iOrgParentID := ParentID;
  237. Result := inherited UpLevel;
  238. if not Result then Exit;
  239. // 如升级后变为父项,则清空数量、单价
  240. if HasChildren then
  241. begin
  242. Rec.ValueByName('OrgQuantity').AsFloat := 0;
  243. Rec.ValueByName('MisQuantity').AsFloat := 0;
  244. Rec.ValueByName('OthQuantity').AsFloat := 0;
  245. Rec.ValueByName('Quantity').AsFloat := 0;
  246. Rec.ValueByName('Price').AsFloat := 0;
  247. end;
  248. TBillsIDTree(Owner).DoOnReCalcNode(iOrgParentID);
  249. TBillsIDTree(Owner).DoOnReCalcNode(ParentID);
  250. end;
  251. { TEstimateIDTreeNode }
  252. function TEstimateIDTreeNode.CanExpand: Boolean;
  253. var
  254. iChild: Integer;
  255. vChild: TsdIDTreeNode;
  256. begin
  257. Result := True;
  258. if HasChildren then
  259. for iChild := 0 to ChildCount - 1 do
  260. begin
  261. vChild := ChildNodes[iChild];
  262. if vChild.Rec.ValueByName('B_Code').AsString <> '' then
  263. begin
  264. Result := False;
  265. Break;
  266. end;
  267. end;
  268. end;
  269. { TEstimateIDTree }
  270. function TEstimateIDTree.CreateItem: TsdIDTreeNode;
  271. begin
  272. Result := TEstimateIDTreeNode.Create(Self);
  273. end;
  274. { TCompileBillsIDTree }
  275. procedure TCompileBillsIDTree.DoOnReCalcNode(AID: Integer);
  276. begin
  277. if (AID <> -1) and Assigned(FOnReCalcNode) then
  278. FOnReCalcNode(AID);
  279. end;
  280. procedure TCompileBillsIDTree.DoOnReCalcNode(ANode: TsdIDTreeNode);
  281. begin
  282. if Assigned(ANode) then
  283. DoOnReCalcNode(ANode.ID);
  284. end;
  285. { TMeasureBillsIDTree }
  286. procedure TMeasureBillsIDTree.DoOnReCalcNode(AID: Integer);
  287. begin
  288. if Assigned(FCompileTree) then
  289. FCompileTree.DoOnReCalcNode(AID);
  290. end;
  291. function TMeasureBillsIDTree.CreateItem: TsdIDTreeNode;
  292. begin
  293. Result := TMeasureBillsIDTreeNode.Create(Self);
  294. end;
  295. procedure TMeasureBillsIDTree.DoOnReCalcNode(ANode: TsdIDTreeNode);
  296. begin
  297. if Assigned(FCompileTree) then
  298. FCompileTree.DoOnReCalcNode(ANode);
  299. end;
  300. { TMeasureBillsIDTreeNode }
  301. function TMeasureBillsIDTreeNode.DownLevel: Boolean;
  302. var
  303. iOrgParentID: Integer;
  304. begin
  305. iOrgParentID := ParentID;
  306. Result := inherited DownLevel;
  307. if not Result then Exit;
  308. TMeasureBillsIDTree(Owner).DoOnReCalcNode(ParentID);
  309. TMeasureBillsIDTree(Owner).DoOnReCalcNode(iOrgParentID);
  310. end;
  311. function TMeasureBillsIDTreeNode.UpLevel: Boolean;
  312. var
  313. iOrgParentID: Integer;
  314. begin
  315. iOrgParentID := ParentID;
  316. Result := inherited UpLevel;
  317. if not Result then Exit;
  318. TMeasureBillsIDTree(Owner).DoOnReCalcNode(iOrgParentID);
  319. TMeasureBillsIDTree(Owner).DoOnReCalcNode(ParentID);
  320. end;
  321. end.