BillsMeasureDm.pas 34 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006
  1. unit BillsMeasureDm;
  2. interface
  3. uses
  4. BillsDm, BillsTree, FormulaCalc, sdIDTree, StageDm,
  5. SysUtils, Classes, sdDB;
  6. type
  7. TBillsMeasureData = class(TDataModule)
  8. sdvBillsMeasure: TsdDataView;
  9. procedure sdvBillsMeasureAfterOpen(Sender: TObject);
  10. procedure sdvBillsMeasureAfterAddRecord(ARecord: TsdDataRecord);
  11. procedure sdvBillsMeasureGetText(var Text: String;
  12. ARecord: TsdDataRecord; AValue: TsdValue; AColumn: TsdViewColumn;
  13. DisplayText: Boolean);
  14. procedure sdvBillsMeasureSetText(var Text: String;
  15. ARecord: TsdDataRecord; AValue: TsdValue; AColumn: TsdViewColumn;
  16. var Allow: Boolean);
  17. procedure sdvBillsMeasureNeedLookupRecord(ARecord: TsdDataRecord;
  18. AColumn: TsdViewColumn; ANewText: String);
  19. procedure sdvBillsMeasureAfterClose(Sender: TObject);
  20. procedure sdvBillsMeasureAfterValueChanged(AValue: TsdValue);
  21. procedure sdvBillsMeasureCurrentChanged(ARecord: TsdDataRecord);
  22. private
  23. FProjectData: TObject;
  24. FBillsData: TBillsData;
  25. FBillsMeasureTree: TBillsIDTree;
  26. FFormulaCalc: TFormulaCalc;
  27. FShowParentData: Boolean;
  28. FOnRecChange: TRecChangeEvent;
  29. function OnGetCardinalNum(const ACardinalNum: string): Double;
  30. procedure CalcAddCompleteRate(ANode: TsdIDTreeNode);
  31. procedure CalcAddDgnPrice(ANode: TsdIDTreeNode);
  32. function SelectAndUpdateBGL(ABillsID: Integer; ARec: TsdDataRecord;
  33. ANewValue: Double; const AType: string): Boolean;
  34. procedure CalculateNode(ANode: TBillsIDTreeNode);
  35. procedure UpdateRecordGather(ANode: TsdIDTreeNode; AQuantity, ATotalPrice: Double);
  36. function GetStageData: TStageData;
  37. procedure SetOnRecChange(const Value: TRecChangeEvent);
  38. public
  39. constructor Create(AProjectData: TObject);
  40. destructor Destroy; override;
  41. procedure Open;
  42. procedure Close;
  43. procedure ReConnectTree;
  44. procedure CalculateAll;
  45. procedure ResetPhaseStageLink;
  46. procedure ResetTreeNodeStageRec;
  47. procedure ExpandNodeTo(ALevel: Integer);
  48. procedure ExpandXmjNode;
  49. procedure ExpandCurPhase;
  50. function GatherRelaBGL(ANode: TsdIDTreeNode): string;
  51. // 计算 修改各期原报审核数据时,需对累计数据做增量
  52. procedure UpdateRecordDeal(ABillsID: Integer; AQuantity, ATotalPrice: Double);
  53. procedure UpdateRecordQc(ABillsID: Integer; AQuantity, ATotalPrice: Double);
  54. procedure UpdateRecordPc(ABillsID: Integer; AQuantity, ATotalPrice: Double);
  55. procedure UpdateRecordPM(ABillsID: Integer; ADiffer: Double);
  56. procedure UpdateGather(ABillsID: Integer; ADiffer: Double);
  57. procedure UpdateBGLInfo(ABillsID: Integer; ARec: TsdDataRecord; const AType: string);
  58. property ProjectData: TObject read FProjectData;
  59. property BillsData: TBillsData read FBillsData;
  60. property BillsMeasureTree: TBillsIDTree read FBillsMeasureTree;
  61. property StageData: TStageData read GetStageData;
  62. property ShowParentData: Boolean read FShowParentData write FShowParentData;
  63. property OnRecChange: TRecChangeEvent read FOnRecChange write SetOnRecChange;
  64. end;
  65. implementation
  66. uses
  67. ProjectData, PhaseData, Math, ZhAPI, BillsCommand, BGLSelectFrm,
  68. BGLDm, UtilMethods, mDataRecord, ConstUnit;
  69. {$R *.dfm}
  70. { TBillsMeasureData }
  71. constructor TBillsMeasureData.Create(AProjectData: TObject);
  72. begin
  73. inherited Create(nil);
  74. FProjectData := AProjectData;
  75. FBillsData := TProjectData(FProjectData).BillsData;
  76. FBillsMeasureTree := TBillsIDTree.Create;
  77. FBillsMeasureTree.KeyFieldName := 'ID';
  78. FBillsMeasureTree.ParentFieldName := 'ParentID';
  79. FBillsMeasureTree.NextSiblingFieldName := 'NextSiblingID';
  80. FBillsMeasureTree.AutoCreateKeyID := True;
  81. FBillsMeasureTree.AutoExpand := True;
  82. FBillsMeasureTree.DataView := sdvBillsMeasure;
  83. FBillsMeasureTree.SeedID := Max(FBillsMeasureTree.SeedID, 100);
  84. FBillsMeasureTree.Link(TProjectData(FProjectData).BillsCompileData.BillsCompileTree, True);
  85. FFormulaCalc := TFormulaCalc.Create(FBillsMeasureTree);
  86. FFormulaCalc.OnGetValue := OnGetCardinalNum;
  87. end;
  88. destructor TBillsMeasureData.Destroy;
  89. begin
  90. FFormulaCalc.Free;
  91. FBillsMeasureTree.Free;
  92. inherited;
  93. end;
  94. procedure TBillsMeasureData.Open;
  95. begin
  96. sdvBillsMeasure.DataSet := TProjectData(FProjectData).BillsData.sddBills;
  97. sdvBillsMeasure.Open;
  98. end;
  99. procedure TBillsMeasureData.ReConnectTree;
  100. begin
  101. FBillsMeasureTree.DataView := nil;
  102. FBillsMeasureTree.DataView := sdvBillsMeasure;
  103. FBillsMeasureTree.Link(TProjectData(FProjectData).BillsCompileData.BillsCompileTree, True);
  104. end;
  105. procedure TBillsMeasureData.ResetPhaseStageLink;
  106. begin
  107. with TProjectData(FProjectData).PhaseData do
  108. begin
  109. sdvBillsMeasure.Columns.FindColumn('CurDealQuantity').LookupDataSet := StageData.sddStage;
  110. sdvBillsMeasure.Columns.FindColumn('CurDealTotalPrice').LookupDataSet := StageData.sddStage;
  111. sdvBillsMeasure.Columns.FindColumn('CurQcQuantity').LookupDataSet := StageData.sddStage;
  112. sdvBillsMeasure.Columns.FindColumn('CurQcTotalPrice').LookupDataSet := StageData.sddStage;
  113. sdvBillsMeasure.Columns.FindColumn('CurQcBGLCode').LookupDataSet := StageData.sddStage;
  114. sdvBillsMeasure.Columns.FindColumn('CurPcQuantity').LookupDataSet := StageData.sddStage;
  115. sdvBillsMeasure.Columns.FindColumn('CurPcTotalPrice').LookupDataSet := StageData.sddStage;
  116. sdvBillsMeasure.Columns.FindColumn('CurPcBGLCode').LookupDataSet := StageData.sddStage;
  117. sdvBillsMeasure.Columns.FindColumn('CurGatherQuantity').LookupDataSet := StageData.sddStage;
  118. sdvBillsMeasure.Columns.FindColumn('CurGatherTotalPrice').LookupDataSet := StageData.sddStage;
  119. sdvBillsMeasure.Columns.FindColumn('EndDealQuantity').LookupDataSet := StageData.sddStage;
  120. sdvBillsMeasure.Columns.FindColumn('EndDealTotalPrice').LookupDataSet := StageData.sddStage;
  121. sdvBillsMeasure.Columns.FindColumn('EndQcQuantity').LookupDataSet := StageData.sddStage;
  122. sdvBillsMeasure.Columns.FindColumn('EndQcTotalPrice').LookupDataSet := StageData.sddStage;
  123. sdvBillsMeasure.Columns.FindColumn('EndPcQuantity').LookupDataSet := StageData.sddStage;
  124. sdvBillsMeasure.Columns.FindColumn('EndPcTotalPrice').LookupDataSet := StageData.sddStage;
  125. sdvBillsMeasure.Columns.FindColumn('EndGatherQuantity').LookupDataSet := StageData.sddStage;
  126. sdvBillsMeasure.Columns.FindColumn('EndGatherTotalPrice').LookupDataSet := StageData.sddStage;
  127. sdvBillsMeasure.Columns.FindColumn('PM_PreTotalPrice').LookupDataSet := StageData.sddStage;
  128. sdvBillsMeasure.Columns.FindColumn('PM_TotalPrice').LookupDataSet := StageData.sddStage;
  129. end;
  130. end;
  131. procedure TBillsMeasureData.sdvBillsMeasureAfterOpen(Sender: TObject);
  132. begin
  133. FBillsMeasureTree.Active := True;
  134. end;
  135. procedure TBillsMeasureData.sdvBillsMeasureAfterAddRecord(
  136. ARecord: TsdDataRecord);
  137. begin
  138. ARecord.ValueByName('IsMeasureAdd').AsBoolean := True;
  139. end;
  140. procedure TBillsMeasureData.sdvBillsMeasureGetText(var Text: String;
  141. ARecord: TsdDataRecord; AValue: TsdValue; AColumn: TsdViewColumn;
  142. DisplayText: Boolean);
  143. function GetQuantityValueOrFormula(const AQtyType: string): string;
  144. begin
  145. with AValue.Owner do
  146. begin
  147. if ValueByName(AQtyType + 'Flag').AsInteger = 1 then
  148. Result := ValueByName(AQtyType + 'Formula').AsString
  149. else
  150. Result := Text;
  151. end;
  152. end;
  153. function GetTotalPriceValueOrFormula(const AQtyType: string): string;
  154. begin
  155. with AValue.Owner do
  156. begin
  157. if ValueByName(AQtyType + 'Formula').AsString <> '' then
  158. Result := ValueByName(AQtyType + 'Formula').AsString
  159. else
  160. Result := Text;
  161. end;
  162. end;
  163. procedure GetDisplayText(var AText: string; AValue: TsdValue;
  164. AColumn: TsdViewColumn);
  165. var
  166. stnNode: TsdIDTreeNode;
  167. begin
  168. if (Pos('TotalPrice', AColumn.FieldName) > 0) or
  169. (Pos('Quantity', AColumn.FieldName) > 0) or
  170. (Pos('Price', AColumn.FieldName) > 0) then
  171. begin
  172. if AValue.AsFloat = 0 then
  173. Text := '';
  174. end;
  175. if SameText('Quantity', AColumn.FieldName) or
  176. SameText('Price', AColumn.FieldName) or
  177. SameText('NewPrice', AColumn.FieldName) or
  178. SameText('AddGatherQuantity', AColumn.FieldName) then
  179. begin
  180. stnNode := BillsMeasureTree.FindNode(AValue.Owner.ValueByName('ID').AsInteger);
  181. if stnNode.HasChildren then
  182. Text := '';
  183. end;
  184. // 所有本期数据,当节点为父节点时,不显示值(实际上需要计算其中的金额值,但又不能显示)
  185. // 有病。每天都在变。
  186. if not ShowParentData and (Pos('Cur', AColumn.FieldName) > 0) and (Pos('Gather', AColumn.FieldName) = 0) then
  187. begin
  188. stnNode := BillsMeasureTree.FindNode(AValue.Owner.ValueByName('BillsID').AsInteger);
  189. if stnNode.HasChildren then
  190. Text := '';
  191. end;
  192. end;
  193. procedure GetEditText(var AText: string; AValue: TsdValue;
  194. AColumn: TsdViewColumn);
  195. begin
  196. if SameText(AColumn.FieldName, 'Quantity') then
  197. Text := GetQuantityValueOrFormula('Qty')
  198. else if SameText(AColumn.FieldName, 'CurDealQuantity') then
  199. Text := GetQuantityValueOrFormula('Deal')
  200. else if SameText(AColumn.FieldName, 'CurQcQuantity') then
  201. Text := GetQuantityValueOrFormula('Qc')
  202. else if SameText(AColumn.FieldName, 'CurPcQuantity') then
  203. Text := GetQuantityValueOrFormula('Pc')
  204. else if SameText(AColumn.FieldName, 'CurDealTotalPrice') then
  205. Text := GetTotalPriceValueOrFormula('Deal')
  206. else if SameText(AColumn.FieldName, 'CurQcTotalPrice') then
  207. Text := GetTotalPriceValueOrFormula('Qc')
  208. else if SameText(AColumn.FieldName, 'CurPcTotalPrice') then
  209. Text := GetTotalPriceValueOrFormula('Pc');
  210. end;
  211. var
  212. fPercent: Double;
  213. begin
  214. if not Assigned(AValue) then Exit;
  215. if DisplayText then
  216. GetDisplayText(Text, AValue, AColumn)
  217. else
  218. GetEditText(Text, AValue, AColumn);
  219. end;
  220. procedure TBillsMeasureData.sdvBillsMeasureSetText(var Text: String;
  221. ARecord: TsdDataRecord; AValue: TsdValue; AColumn: TsdViewColumn;
  222. var Allow: Boolean);
  223. function GetBillsID: Integer;
  224. begin
  225. if Pos('Cur', AColumn.FieldName) = 1 then
  226. Result := AValue.Owner.ValueByName('BillsID').AsInteger
  227. else
  228. Result := ARecord.ValueByName('ID').AsInteger;
  229. end;
  230. procedure CheckLockedData;
  231. begin
  232. if SameText(AColumn.FieldName, 'Code') or
  233. SameText(AColumn.FieldName, 'B_Code') or
  234. SameText(AColumn.FieldName, 'Name') or
  235. SameText(AColumn.FieldName, 'Units') or
  236. SameText(AColumn.FieldName, 'Price') then
  237. if ARecord.ValueByName('LockedInfo').AsBoolean then
  238. DataSetErrorMessage(Allow, '清单信息已被锁定,不允许修改编号、名称、单位、清单单价!');
  239. if not Allow then Exit;
  240. if SameText(AColumn.FieldName, 'NewPrice') then
  241. if ARecord.ValueByName('LockedNewPrice').AsBoolean then
  242. DataSetErrorMessage(Allow, '变更单价已被锁定,不允许修改!');
  243. end;
  244. procedure CheckNodeWritable;
  245. var
  246. vNode: TBillsIDTreeNode;
  247. iCreatePhase: Integer;
  248. begin
  249. vNode := TBillsIDTreeNode(BillsMeasureTree.FindNode(GetBillsID));
  250. iCreatePhase := vNode.Rec.ValueByName('CreatePhaseID').AsInteger;
  251. if vNode.ID = iPriceMarginID then
  252. DataSetErrorMessage(Allow, sBills_PMHint);
  253. if SameText('B_Code', AColumn.FieldName) or
  254. SameText('Name', AColumn.FieldName) or
  255. SameText('Units', AColumn.FieldName) then
  256. if vNode.Rec.ValueByName('AddQcQuantity').AsFloat <> 0 then
  257. DataSetErrorMessage(Allow, '该清单已进行过变更,不可修改清单编号、名称、单位!');
  258. if not Allow then Exit;
  259. if SameText('Price', AColumn.FieldName) then
  260. if vNode.Rec.ValueByName('AddGatherTotalPrice').AsFloat <> 0 then
  261. DataSetErrorMessage(Allow, '该清单已经计量,不可修改清单单价!');
  262. if not Allow then Exit;
  263. if SameText('NewPrice', AColumn.FieldName) then
  264. if vNode.Rec.ValueByName('AddPcTotalPrice').AsFloat <> 0 then
  265. DataSetErrorMessage(Allow, '该清单已经计量,不可修改清单变更单价!');
  266. if not Allow then Exit;
  267. if vNode.HasChildren then
  268. begin
  269. if Text = '' then
  270. Exit
  271. else if ((Pos('Quantity', AColumn.FieldName) > 0) and (Pos('Dgn', AColumn.FieldName) <=0)) or
  272. (Pos('TotalPrice', AColumn.FieldName) > 0) then
  273. DataSetErrorMessage(Allow, '该清单有子计算项,不能直接修改!')
  274. else if (Pos('Price', AColumn.FieldName) > 0) then
  275. DataSetErrorMessage(Allow, '仅最底层清单可输入单价!');
  276. end
  277. else
  278. begin
  279. // 目前仅允许本期合同计量,可直接输入金额
  280. if SameText('CurDealTotalPrice', AColumn.FieldName) then
  281. begin
  282. if not vNode.TotalPriceEnable then
  283. DataSetErrorMessage(Allow, '该清单不可直接输入金额,如需直接输入金额,请先清空所有数量、单价!');
  284. end
  285. else if SameText('CurDealQuantity', AColumn.FieldName) or
  286. SameText('CurQcQuantity', AColumn.FieldName) or
  287. SameText('CurPcQuantity', AColumn.FieldName) or
  288. SameText('Price', AColumn.FieldName) then
  289. begin
  290. if not vNode.CountPriceEnable then
  291. DataSetErrorMessage(Allow, '该清单不可输入数量单价,如需使用数量×单价计算,请先清空所有直接输入的金额!');
  292. end;
  293. end;
  294. if not Allow then Exit;
  295. // 变更清单允许填写本期合同计量,按超计论
  296. {if vNode.Rec.ValueByName('IsMeasureAdd').AsBoolean and (iCreatePhase > 0) and
  297. (SameText('CurDealQuantity', AColumn.FieldName) or
  298. SameText('CurDealTotalPrice', AColumn.FieldName)) then
  299. DataSetErrorMessage(Allow, Format('该清单为第%d期新增清单,不可填写本期合同计量数据!', [iCreatePhase]));}
  300. end;
  301. procedure SetQuantity(const AField: string);
  302. var
  303. vNode: TBillsIDTreeNode;
  304. begin
  305. // 变更应选择变更令
  306. if SameText(AField , 'Qc') or SameText(AField , 'Pc') then
  307. Allow := SelectAndUpdateBGL(GetBillsID, AValue.Owner, StrToFloatDef(Text, 0), AField);
  308. if not Allow then Exit;
  309. if CheckStringNull(Text) or CheckNumeric(Text) then
  310. begin
  311. AValue.Owner.ValueByName(AField + 'Flag').AsInteger := 0;
  312. AValue.Owner.ValueByName(AField + 'Formula').AsString := '';
  313. Text := FloatToStr(QuantityRoundTo(StrToFloatDef(Text, 0)));
  314. end
  315. else
  316. begin
  317. AValue.Owner.ValueByName(AField + 'Flag').AsInteger := 1;
  318. AValue.Owner.ValueByName(AField + 'Formula').AsString := Text;
  319. Text := FloatToStr(QuantityRoundTo(EvaluateExprs(Text)));
  320. end;
  321. vNode := TBillsIDTreeNode(BillsMeasureTree.FindNode(GetBillsID));
  322. if vNode.Rec.CalcType.AsInteger <> 0 then
  323. vNode.Rec.CalcType.AsInteger := 0;
  324. end;
  325. procedure SetTotalPrice(const AField: string);
  326. var
  327. vNode: TBillsIDTreeNode;
  328. begin
  329. // 变更应选择变更令
  330. if SameText(AField , 'Qc') or SameText(AField , 'Pc') then
  331. Allow := SelectAndUpdateBGL(GetBillsID, AValue.Owner, StrToFloatDef(Text, 0), AField);
  332. if not Allow then Exit;
  333. AValue.Owner.ValueByName(AField + 'Flag').AsInteger := 2;
  334. AValue.Owner.ValueByName(AField + 'Quantity').AsString := '';
  335. if CheckStringNull(Text) or CheckNumeric(Text) then
  336. begin
  337. AValue.Owner.ValueByName(AField + 'Formula').AsString := '';
  338. Text := FloatToStr(TotalPriceRoundTo(StrToFloatDef(Text, 0)));
  339. end
  340. else
  341. begin
  342. AValue.Owner.ValueByName(AField + 'Formula').AsString := Text;
  343. Text := FloatToStr(TotalPriceRoundTo(EvaluateExprs(Text)));
  344. end;
  345. vNode := TBillsIDTreeNode(BillsMeasureTree.FindNode(GetBillsID));
  346. if vNode.Rec.CalcType.AsInteger <> 1 then
  347. vNode.Rec.CalcType.AsInteger := 1;
  348. end;
  349. procedure DoCurChanged;
  350. begin
  351. if SameText(AColumn.FieldName, 'CurDealQuantity') then
  352. SetQuantity('Deal')
  353. else if SameText(AColumn.FieldName, 'CurQcQuantity') then
  354. SetQuantity('Qc')
  355. else if SameText(AColumn.FieldName, 'CurPcQuantity') then
  356. SetQuantity('Pc')
  357. else if SameText(AColumn.FieldName, 'CurDealTotalPrice') then
  358. SetTotalPrice('Deal')
  359. else if SameText(AColumn.FieldName, 'CurQcTotalPrice') then
  360. SetTotalPrice('Qc')
  361. else if SameText(AColumn.FieldName, 'CurPcTotalPrice') then
  362. SetTotalPrice('Pc')
  363. else if (Pos('DgnQuantity', AColumn.FieldName) > 0) or
  364. SameText(AColumn.FieldName, 'Quantity') then
  365. Text := FloatToStr(QuantityRoundTo(StrToFloatDef(Text, 0)))
  366. else if SameText(AColumn.FieldName, 'NewPrice') or
  367. SameText(AColumn.FieldName, 'Price') then
  368. Text := FloatToStr(PriceRoundTo(StrToFloatDef(Text, 0)));
  369. end;
  370. function CheckValidData: Boolean;
  371. begin
  372. Result := (AValue.AsString <> Text);
  373. if (Pos('Quantity', AColumn.FieldName) > 0) or
  374. (Pos('Price', AColumn.FieldName) > 0) then
  375. begin
  376. if (AValue.AsFloat = 0) and (Text = '') then
  377. Result := False;
  378. end;
  379. end;
  380. begin
  381. if not Assigned(AValue) then Exit;
  382. // 修改后数据与原数据相同则不提交
  383. if not CheckValidData then
  384. Allow := False;
  385. if not Allow then Exit;
  386. CheckLockedData;
  387. if not Allow then Exit;
  388. CheckNodeWritable;
  389. if not Allow then Exit;
  390. Text := Trim(Text);
  391. if Pos('=', Text) = 1 then
  392. Text := Copy(Text, 2, Length(Text) - 1);
  393. DoCurChanged;
  394. end;
  395. procedure TBillsMeasureData.sdvBillsMeasureNeedLookupRecord(
  396. ARecord: TsdDataRecord; AColumn: TsdViewColumn; ANewText: String);
  397. function CheckNeedAddPhaseRecord(ANode: TBillsIDTreeNode): Boolean;
  398. begin
  399. Result := SameText(AColumn.FieldName, 'CurDealQuantity') or
  400. SameText(AColumn.FieldName, 'CurQcQuantity') or
  401. SameText(AColumn.FieldName, 'CurPcQuantity') or
  402. SameText(AColumn.FieldName, 'CurDealTotalPrice') or
  403. SameText(AColumn.FieldName, 'CurQcTotalPrice') or
  404. SameText(AColumn.FieldName, 'CurPcTotalPrice');
  405. Result := Result and not ANode.HasChildren;
  406. Result := Result and not Assigned(ANode.StageRec);
  407. end;
  408. function HasCardinalNum(AFormula: string): Boolean;
  409. var
  410. iCharIndex: Integer;
  411. begin
  412. Result := False;
  413. iCharIndex := 1;
  414. while ((iCharIndex <= Length(AFormula)) and not Result) do
  415. begin
  416. if AFormula[iCharIndex] in ['A'..'D', 'a'..'d'] then
  417. Result := True;
  418. Inc(iCharIndex);
  419. end;
  420. end;
  421. procedure SetQuantityRec(APhaseRec: TsdDataRecord; const AType: string);
  422. var
  423. bAllow: Boolean;
  424. begin
  425. bAllow := True;
  426. // 变更应选择变更令
  427. if SameText(AType , 'Qc') or SameText(AType , 'Pc') then
  428. bAllow := SelectAndUpdateBGL(ARecord.ValueByName('ID').AsInteger,
  429. APhaseRec, StrToFloatDef(ANewText, 0), AType);
  430. if bAllow then
  431. begin
  432. if CheckNumeric(ANewText) then
  433. APhaseRec.ValueByName(AType + 'Quantity').AsFloat := QuantityRoundTo(StrToFloatDef(ANewText, 0))
  434. else
  435. begin
  436. APhaseRec.ValueByName(AType + 'Flag').AsInteger := 1;
  437. APhaseRec.ValueByName(AType + 'Quantity').AsFloat := QuantityRoundTo(EvaluateExprs(ANewText));
  438. APhaseRec.ValueByName(AType + 'Formula').AsString := ANewText;
  439. end;
  440. end;
  441. end;
  442. procedure SetTotalPriceRec(APhaseRec: TsdDataRecord; const AType: string);
  443. begin
  444. APhaseRec.ValueByName(AType + 'Flag').AsInteger := 2;
  445. if CheckNumeric(ANewText) then
  446. APhaseRec.ValueByName(AType + 'TotalPrice').AsFloat := TotalPriceRoundTo(StrToFloatDef(ANewText, 0))
  447. else
  448. begin
  449. APhaseRec.ValueByName(AType + 'TotalPrice').AsFloat := TotalPriceRoundTo(EvaluateExprs(ANewText));
  450. APhaseRec.ValueByName(AType + 'Formula').AsString := ANewText;
  451. end;
  452. end;
  453. procedure SetNewRecValue(APhaseRec: TsdDataRecord);
  454. begin
  455. if SameText(AColumn.FieldName, 'CurDealQuantity') then
  456. SetQuantityRec(APhaseRec, 'Deal')
  457. else if SameText(AColumn.FieldName, 'CurQcQuantity') then
  458. SetQuantityRec(APhaseRec, 'Qc')
  459. else if SameText(AColumn.FieldName, 'CurPcQuantity') then
  460. SetQuantityRec(APhaseRec, 'Pc')
  461. else if SameText(AColumn.FieldName, 'CurDealTotalPrice') then
  462. SetTotalPriceRec(APhaseRec, 'Deal')
  463. else if SameText(AColumn.FieldName, 'CurQcTotalPrice') then
  464. SetTotalPriceRec(APhaseRec, 'Qc')
  465. else if SameText(AColumn.FieldName, 'CurPcTotalPrice') then
  466. SetTotalPriceRec(APhaseRec, 'Pc');
  467. end;
  468. function CheckNodeWritable(ANode: TBillsIDTreeNode): Boolean;
  469. var
  470. iCreatePhase: Integer;
  471. begin
  472. Result := True;
  473. if ANode.ID = iPriceMarginID then
  474. DataSetErrorMessage(Result, sBills_PMHint);
  475. if ANode.HasChildren then
  476. begin
  477. if ANewText = '' then
  478. Result := False
  479. else
  480. DataSetErrorMessage(Result, '该清单有子计算项,不能直接修改!');
  481. end
  482. else
  483. begin
  484. // 目前仅允许本期合同计量,可直接输入金额
  485. if SameText('CurDealTotalPrice', AColumn.FieldName) then
  486. begin
  487. if not ANode.TotalPriceEnable then
  488. DataSetErrorMessage(Result, '该清单不可直接输入金额,如需直接输入金额,请先清空所有数量、单价!');
  489. end
  490. else if SameText('CurDealQuantity', AColumn.FieldName) or
  491. SameText('CurQcQuantity', AColumn.FieldName) or
  492. SameText('CurPcQuantity', AColumn.FieldName) then
  493. begin
  494. if not ANode.CountPriceEnable then
  495. DataSetErrorMessage(Result, '该清单不可输入数量单价,如需使用数量×单价计算,请先清空所有直接输入的金额!');
  496. end;
  497. end;
  498. // 变更清单允许填写本期合同计量,按超计论
  499. {iCreatePhase := ANode.Rec.ValueByName('CreatePhaseID').AsInteger;
  500. if ANode.Rec.ValueByName('IsMeasureAdd').AsBoolean and (iCreatePhase > 0) and
  501. (SameText('CurDealQuantity', AColumn.FieldName) or
  502. SameText('CurDealTotalPrice', AColumn.FieldName)) then
  503. begin
  504. ErrorMessage(Format('该清单为第%d期新增清单,不可填写本期合同计量数据!', [iCreatePhase]));
  505. Exit;
  506. end; }
  507. end;
  508. var
  509. NewRec: TStageRecord;
  510. vNode: TBillsIDTreeNode;
  511. begin
  512. vNode := TBillsIDTreeNode(BillsMeasureTree.FindNode(ARecord.ValueByName('ID').AsInteger));
  513. if not CheckNodeWritable(vNode) then
  514. Exit;
  515. if CheckNeedAddPhaseRecord(vNode) then
  516. begin
  517. if Pos('Quantity', AColumn.FieldName) > 0 then
  518. if HasCardinalNum(ANewText) then
  519. raise Exception.Create('数量列公式不可输入参数');
  520. NewRec := StageData.AddStageRecord(ARecord.ValueByName('ID').AsInteger);
  521. vNode.StageRec := NewRec;
  522. SetNewRecValue(NewRec);
  523. end;
  524. end;
  525. procedure TBillsMeasureData.sdvBillsMeasureAfterClose(Sender: TObject);
  526. begin
  527. FBillsMeasureTree.Active := False;
  528. end;
  529. function TBillsMeasureData.OnGetCardinalNum(
  530. const ACardinalNum: string): Double;
  531. {
  532. function GetTotalPrice(ABillsID: Integer): Double;
  533. var
  534. stnNode: TsdIDTreeNode;
  535. begin
  536. stnNode := FBillsTree.FindNode(ABillsID);
  537. if Assigned(stnNode) then
  538. Result := stnNode.Rec.ValueByName('TotalPrice').AsFloat;
  539. end;
  540. function GetPhaseTotalPrice(ABillsID: Integer; const AType: string): Double;
  541. var
  542. Rec: TsdDataRecord;
  543. begin
  544. Rec := CurPhaseData.PhaseRecord(ABillsID);
  545. if Assigned(Rec) then
  546. Result := Rec.ValueByName(AType + 'TotalPrice').AsFloat;
  547. end;
  548. }
  549. function GetTotalPrice(ANode: TsdIDTreeNode): Double;
  550. var
  551. iChild: Integer;
  552. begin
  553. Result := 0;
  554. if not Assigned(ANode) then Exit;
  555. if ANode.HasChildren then
  556. for iChild := 0 to ANode.ChildCount - 1 do
  557. Result := Result + GetTotalPrice(ANode.ChildNodes[iChild])
  558. else
  559. Result := ANode.Rec.ValueByName('TotalPrice').AsFloat;
  560. end;
  561. function GetPhaseTotalPrice(ANode: TsdIDTreeNode; const AType: string): Double;
  562. var
  563. iChild: Integer;
  564. Rec: TsdDataRecord;
  565. begin
  566. Result := 0;
  567. if not Assigned(ANode) then Exit;
  568. if ANode.HasChildren then
  569. for iChild := 0 to ANode.ChildCount - 1 do
  570. Result := Result + GetPhaseTotalPrice(ANode.ChildNodes[iChild], AType)
  571. else
  572. begin
  573. Rec := StageData.StageRecord(ANode.ID);
  574. if Assigned(Rec) then
  575. Result := Rec.ValueByName(AType + 'TotalPrice').AsFloat;
  576. end;
  577. end;
  578. var
  579. iNodeID: Integer;
  580. begin
  581. Result := 0;
  582. iNodeID := StrToIntDef(Copy(ACardinalNum, 2, Length(ACardinalNum) - 1), -1);
  583. case ACardinalNum[1] of
  584. 'A','a': Result := GetTotalPrice(BillsMeasureTree.FindNode(iNodeID));
  585. 'B','b': Result := GetPhaseTotalPrice(BillsMeasureTree.FindNode(iNodeID), 'Deal');
  586. 'C','c': Result := GetPhaseTotalPrice(BillsMeasureTree.FindNode(iNodeID), 'Qc');
  587. 'D','d': Result := GetPhaseTotalPrice(BillsMeasureTree.FindNode(iNodeID), 'Pc');
  588. {'A','a': Result := GetTotalPrice(iNodeID);
  589. 'B','b': Result := GetPhaseTotalPrice(iNodeID, 'Deal');
  590. 'C','c': Result := GetPhaseTotalPrice(iNodeID, 'Qc');
  591. 'D','d': Result := GetPhaseTotalPrice(iNodeID, 'Pc');}
  592. end;
  593. end;
  594. function TBillsMeasureData.GetStageData: TStageData;
  595. begin
  596. Result := TProjectData(FProjectData).PhaseData.StageData;
  597. end;
  598. procedure TBillsMeasureData.ExpandNodeTo(ALevel: Integer);
  599. begin
  600. BillsMeasureTree.ExpandLevel := ALevel;
  601. end;
  602. procedure TBillsMeasureData.ExpandXmjNode;
  603. var
  604. iIndex: Integer;
  605. stnNode: TsdIDTreeNode;
  606. begin
  607. for iIndex := 0 to BillsMeasureTree.Count - 1 do
  608. begin
  609. stnNode := BillsMeasureTree.Items[iIndex];
  610. if (stnNode.ParentID <> -1) then
  611. stnNode.Parent.Expanded := stnNode.Rec.ValueByName('B_Code').AsString = '';
  612. end;
  613. end;
  614. procedure TBillsMeasureData.CalculateAll;
  615. var
  616. //Cacl: TBillsCalculate;
  617. i: Integer;
  618. begin
  619. if not TProjectData(FProjectData).StageDataReadOnly then
  620. for i := 0 to BillsMeasureTree.Count - 1 do
  621. CalculateNode(TBillsIDTreeNode(BillsMeasureTree.Items[i]));
  622. {Cacl := TBillsCalculate.Create(Self);
  623. try
  624. Cacl.Execute;
  625. finally
  626. Cacl.Free;
  627. end;}
  628. end;
  629. procedure TBillsMeasureData.UpdateRecordDeal(ABillsID: Integer; AQuantity,
  630. ATotalPrice: Double);
  631. var
  632. stnNode: TsdIDTreeNode;
  633. begin
  634. stnNode := BillsMeasureTree.FindNode(ABillsID);
  635. if not Assigned(stnNode) then Exit;
  636. with stnNode.Rec do
  637. begin
  638. if not stnNode.HasChildren then
  639. ValueByName('AddDealQuantity').AsFloat := QuantityRoundTo(
  640. ValueByName('AddDealQuantity').AsFloat + AQuantity);
  641. ValueByName('AddDealTotalPrice').AsFloat := TotalPriceRoundTo(
  642. ValueByName('AddDealTotalPrice').AsFloat + ATotalPrice);
  643. end;
  644. UpdateRecordGather(stnNode, AQuantity, ATotalPrice);
  645. UpdateRecordDeal(stnNode.ParentID, AQuantity, ATotalPrice);
  646. end;
  647. procedure TBillsMeasureData.UpdateRecordPc(ABillsID: Integer; AQuantity,
  648. ATotalPrice: Double);
  649. var
  650. stnNode: TsdIDTreeNode;
  651. begin
  652. stnNode := BillsMeasureTree.FindNode(ABillsID);
  653. if not Assigned(stnNode) then Exit;
  654. with stnNode.Rec do
  655. begin
  656. if not stnNode.HasChildren then
  657. ValueByName('AddPcQuantity').AsFloat := QuantityRoundTo(
  658. ValueByName('AddPcQuantity').AsFloat + AQuantity);
  659. ValueByName('AddPcTotalPrice').AsFloat := TotalPriceRoundTo(
  660. ValueByName('AddPcTotalPrice').AsFloat + ATotalPrice);
  661. end;
  662. UpdateRecordGather(stnNode, 0, ATotalPrice);
  663. UpdateRecordPc(stnNode.ParentID, AQuantity, ATotalPrice);
  664. end;
  665. procedure TBillsMeasureData.UpdateRecordQc(ABillsID: Integer; AQuantity,
  666. ATotalPrice: Double);
  667. var
  668. stnNode: TsdIDTreeNode;
  669. begin
  670. stnNode := BillsMeasureTree.FindNode(ABillsID);
  671. if not Assigned(stnNode) then Exit;
  672. with stnNode.Rec do
  673. begin
  674. if not stnNode.HasChildren then
  675. ValueByName('AddQcQuantity').AsFloat := QuantityRoundTo(
  676. ValueByName('AddQcQuantity').AsFloat + AQuantity);
  677. ValueByName('AddQcTotalPrice').AsFloat := TotalPriceRoundTo(
  678. ValueByName('AddQcTotalPrice').AsFloat + ATotalPrice);
  679. end;
  680. UpdateRecordGather(stnNode, AQuantity, ATotalPrice);
  681. UpdateRecordQc(stnNode.ParentID, AQuantity, ATotalPrice);
  682. end;
  683. procedure TBillsMeasureData.UpdateRecordGather(ANode: TsdIDTreeNode;
  684. AQuantity, ATotalPrice: Double);
  685. begin
  686. with ANode.Rec do
  687. begin
  688. if not ANode.HasChildren then
  689. ValueByName('AddGatherQuantity').AsFloat := QuantityRoundTo(
  690. ValueByName('AddGatherQuantity').AsFloat + AQuantity);
  691. ValueByName('AddGatherTotalPrice').AsFloat := TotalPriceRoundTo(
  692. ValueByName('AddGatherTotalPrice').AsFloat + ATotalPrice);
  693. end;
  694. CalcAddDgnPrice(ANode);
  695. CalcAddCompleteRate(ANode);
  696. end;
  697. function TBillsMeasureData.GatherRelaBGL(ANode: TsdIDTreeNode): string;
  698. var
  699. iChild: Integer;
  700. Rec: TsdDataRecord;
  701. begin
  702. Result := '';
  703. if not Assigned(ANode) then Exit;
  704. if ANode.HasChildren then
  705. begin
  706. for iChild := 0 to ANode.ChildCount - 1 do
  707. Result := MergeRelaBGL(Result, GatherRelaBGL(ANode.ChildNodes[iChild]));
  708. end
  709. else
  710. begin
  711. with TProjectData(FProjectData).PhaseData.StageData do
  712. Rec := StageRecord(ANode.ID);
  713. if Assigned(Rec) then
  714. Result := MergeRelaBGL(Rec.ValueByName('QcBGLCode').AsString, Rec.ValueByName('PcBGLCode').AsString);
  715. end;
  716. end;
  717. procedure TBillsMeasureData.sdvBillsMeasureAfterValueChanged(
  718. AValue: TsdValue);
  719. var
  720. stnNode: TsdIDTreeNode;
  721. begin
  722. if TProjectData(FProjectData).PhaseData.Active then
  723. begin
  724. if AValue.FieldName = 'Price' then
  725. StageData.ReCalculate(AValue.Owner.ValueByName('ID').AsInteger);
  726. if AValue.FieldName = 'NewPrice' then
  727. StageData.ReCalculate(AValue.Owner.ValueByName('ID').AsInteger);
  728. end;
  729. if Pos('DgnQuantity1', AValue.FieldName) > 0 then
  730. begin
  731. stnNode := BillsMeasureTree.FindNode(AValue.Owner.ValueByName('ID').AsInteger);
  732. CalcAddDgnPrice(stnNode);
  733. end;
  734. end;
  735. procedure TBillsMeasureData.ExpandCurPhase;
  736. var
  737. iIndex: Integer;
  738. stnNode: TsdIDTreeNode;
  739. StageRec: TsdDataRecord;
  740. begin
  741. for iIndex := 0 to BillsMeasureTree.Count - 1 do
  742. begin
  743. stnNode := BillsMeasureTree.Items[iIndex];
  744. StageRec := TBillsIDTreeNode(stnNode).StageRec;
  745. if (stnNode.ParentID <> -1) then
  746. if Assigned(StageRec) then
  747. stnNode.Expanded := StageRec.ValueByName('GatherTotalPrice').AsFloat <> 0
  748. else
  749. stnNode.Expanded := False;
  750. end;
  751. end;
  752. procedure TBillsMeasureData.UpdateBGLInfo(ABillsID: Integer;
  753. ARec: TsdDataRecord; const AType: string);
  754. var
  755. stnNode: TsdIDTreeNode;
  756. begin
  757. stnNode := BillsMeasureTree.FindNode(ABillsID);
  758. if not Assigned(stnNode) then Exit;
  759. stnNode.Rec.ValueByName('Add' + AType + 'BGLCode').AsString :=
  760. ARec.ValueByName('End' + AType + 'BGLCode').AsString;
  761. stnNode.Rec.ValueByName('Add' + AType + 'BGLNum').AsString :=
  762. ARec.ValueByName('End' + AType + 'BGLNum').AsString;
  763. end;
  764. function TBillsMeasureData.SelectAndUpdateBGL(ABillsID: Integer;
  765. ARec: TsdDataRecord; ANewValue: Double; const AType: string): Boolean;
  766. var
  767. AOrgBGL, ANewBGL: TBGLSelectInfo;
  768. ACurNode: TsdIDTreeNode;
  769. procedure UpdateBGL;
  770. begin
  771. ARec.ValueByName(AType + 'BGLCode').AsString := ANewBGL.MergedCode;
  772. ARec.ValueByName(AType + 'BGLNum').AsString := ANewBGL.MergedNum;
  773. TProjectData(ProjectData).BGLData.ApplyBGL(AOrgBGL, ANewBGL);
  774. end;
  775. begin
  776. Result := True;
  777. ACurNode := BillsMeasureTree.FindNode(ABillsID);
  778. AOrgBGL := TBGLSelectInfo.Create(ACurNode.Rec,
  779. ARec.ValueByName(AType + 'Quantity').AsFloat, True);
  780. AOrgBGL.MergedCode := ARec.ValueByName(AType + 'BGLCode').AsString;
  781. AOrgBGL.MergedNum := ARec.ValueByName(AType + 'BGLNum').AsString;
  782. ANewBGL := TBGLSelectInfo.Create(ACurNode.Rec, ANewValue, False);
  783. try
  784. if ANewBGL.TotalNum <> 0 then
  785. begin
  786. Result := SelectBGL(AOrgBGL, ANewBGL, ProjectData);
  787. if Result then
  788. UpdateBGL;
  789. end
  790. else
  791. UpdateBGL;
  792. StageData.UpdateBGLInfo(ARec, AType);
  793. UpdateBGLInfo(ABillsID, ARec, AType);
  794. finally
  795. AOrgBGL.Free;
  796. ANewBGL.Free;
  797. end;
  798. end;
  799. procedure TBillsMeasureData.Close;
  800. begin
  801. sdvBillsMeasure.Close;
  802. end;
  803. procedure TBillsMeasureData.CalcAddCompleteRate(ANode: TsdIDTreeNode);
  804. var
  805. fDividend, fDivisor: Double;
  806. begin
  807. with ANode.Rec do
  808. begin
  809. fDividend := ValueByName('AddGatherTotalPrice').AsFloat;
  810. fDivisor := ValueByName('TotalPrice').AsFloat + ValueByName('AddQcTotalPrice').AsFloat
  811. + ValueByName('AddPcTotalPrice').AsFloat;
  812. if fDivisor <> 0 then
  813. ValueByName('AddCompleteRate').AsFloat := AdvRoundTo(fDividend/fDivisor*100);
  814. end;
  815. end;
  816. procedure TBillsMeasureData.CalcAddDgnPrice(ANode: TsdIDTreeNode);
  817. var
  818. fDividend, fDivisor: Double;
  819. begin
  820. with ANode.Rec do
  821. begin
  822. fDividend := ValueByName('AddGatherTotalPrice').AsFloat;
  823. fDivisor := ValueByName('DealDgnQuantity1').AsFloat + ValueByName('CDgnQuantity1').AsFloat;
  824. if fDivisor <> 0 then
  825. ValueByName('AddDgnPrice').AsFloat := AdvRoundTo(fDividend/fDivisor);
  826. end;
  827. end;
  828. procedure TBillsMeasureData.SetOnRecChange(const Value: TRecChangeEvent);
  829. begin
  830. FOnRecChange := Value;
  831. end;
  832. procedure TBillsMeasureData.sdvBillsMeasureCurrentChanged(
  833. ARecord: TsdDataRecord);
  834. begin
  835. if Assigned(FOnRecChange) then
  836. FOnRecChange(ARecord);
  837. end;
  838. procedure TBillsMeasureData.ResetTreeNodeStageRec;
  839. var
  840. i: Integer;
  841. vNode: TBillsIDTreeNode;
  842. begin
  843. for i := 0 to BillsMeasureTree.Count - 1 do
  844. begin
  845. vNode := TBillsIDTreeNode(BillsMeasureTree.Items[i]);
  846. vNode.StageRec := StageData.StageRecord(vNode.ID);
  847. end;
  848. end;
  849. procedure TBillsMeasureData.UpdateRecordPM(ABillsID: Integer;
  850. ADiffer: Double);
  851. var
  852. stnNode: TBillsIDTreeNode;
  853. begin
  854. stnNode := TBillsIDTreeNode(BillsMeasureTree.FindNode(ABillsID));
  855. if not Assigned(stnNode) then Exit;
  856. stnNode.Rec.PM_AddTotalPrice.AsFloat := stnNode.Rec.PM_AddTotalPrice.AsFloat + ADiffer;
  857. UpdateRecordPM(stnNode.ParentID, ADiffer);
  858. end;
  859. procedure TBillsMeasureData.CalculateNode(ANode: TBillsIDTreeNode);
  860. begin
  861. if Assigned(ANode.StageRec) then
  862. begin
  863. if not ANode.HasChildren then
  864. begin
  865. ANode.Rec.AddDealQuantity.AsFloat := ANode.StageRec.EndDealQuantity.AsFloat;
  866. ANode.Rec.AddQcQuantity.AsFloat := ANode.StageRec.EndQcQuantity.AsFloat;
  867. ANode.Rec.AddQcBGLCode.AsString := ANode.StageRec.EndQcBGLCode.AsString;
  868. ANode.Rec.AddQcBGLNum.AsString := ANode.StageRec.EndQcBGLNum.AsString;
  869. ANode.Rec.AddPcQuantity.AsFloat := ANode.StageRec.EndPcQuantity.AsFloat;
  870. ANode.Rec.AddPcBGLCode.AsString := ANode.StageRec.EndPcBGLCode.AsString;
  871. ANode.Rec.AddPcBGLNum.AsString := ANode.StageRec.EndPcBGLNum.AsString;
  872. ANode.Rec.AddGatherQuantity.AsFloat := ANode.StageRec.EndGatherQuantity.AsFloat;
  873. end;
  874. ANode.Rec.AddDealTotalPrice.AsFloat := ANode.StageRec.EndDealTotalPrice.AsFloat;
  875. ANode.Rec.AddQcTotalPrice.AsFloat := ANode.StageRec.EndQcTotalPrice.AsFloat;
  876. ANode.Rec.AddPcTotalPrice.AsFloat := ANode.StageRec.EndPcTotalPrice.AsFloat;
  877. ANode.Rec.AddGatherTotalPrice.AsFloat := ANode.StageRec.EndGatherTotalPrice.AsFloat;
  878. ANode.Rec.PM_AddTotalPrice.AsFloat := ANode.StageRec.PM_PreTotalPrice.AsFloat + ANode.StageRec.PM_TotalPrice.AsFloat;
  879. end;
  880. end;
  881. procedure TBillsMeasureData.UpdateGather(ABillsID: Integer;
  882. ADiffer: Double);
  883. var
  884. stnNode: TBillsIDTreeNode;
  885. begin
  886. stnNode := TBillsIDTreeNode(BillsMeasureTree.FindNode(ABillsID));
  887. if not Assigned(stnNode) then Exit;
  888. with stnNode.Rec do
  889. AddDifferValue(AddGatherTotalPrice, ADiffer);
  890. UpdateGather(stnNode.ParentID, ADiffer);
  891. end;
  892. end.