BillsMeasureDm.pas 34 KB

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