BillsDm.pas 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643
  1. unit BillsDm;
  2. interface
  3. uses
  4. StandardBillsFme,
  5. ZhAPI, StandardLib, StageDm, BillsTree, mDataRecord,
  6. SysUtils, Classes, sdDB, sdProvider, ADODB, sdIDTree, Math;
  7. const
  8. DealIndex = 0;
  9. AddDealIndex = 1;
  10. AddQcIndex = 2;
  11. AddPcIndex = 3;
  12. AddGatherIndex = 4;
  13. type
  14. TRecChangeEvent = procedure (ARec: TsdDataRecord) of object;
  15. TBillsData = class(TDataModule)
  16. sdpBills: TsdADOProvider;
  17. sddBills: TsdDataSet;
  18. procedure sddBillsAfterAddRecord(ARecord: TsdDataRecord);
  19. procedure sddBillsBeforeDeleteRecord(ARecord: TsdDataRecord;
  20. var Allow: Boolean);
  21. procedure sddBillsBeforeValueChange(AValue: TsdValue;
  22. const NewValue: Variant; var Allow: Boolean);
  23. procedure sddBillsGetRecordClass(var ARecordClass: TsdRecordClass);
  24. private
  25. FProjectData: TObject;
  26. FCurPhaseIndex: Integer;
  27. FBeforeChangeTotalPrice: Double;
  28. FBeforeChangeParentID: Integer;
  29. //procedure RecursiveCalculate(ABillsID: Integer);
  30. function GetStageData: TStageData;
  31. function GetBuildLoadInterest(AIndex: Integer): Double;
  32. function GetFirstPart(AIndex: Integer): Double;
  33. function GetOtherFee(AIndex: Integer): Double;
  34. function GetOtherProjectFee(AIndex: Integer): Double;
  35. function GetRecyclingFee(AIndex: Integer): Double;
  36. function GetReservedFee(AIndex: Integer): Double;
  37. function GetSecondPart(AIndex: Integer): Double;
  38. function GetStageSettlement(AIndex: Integer): Double;
  39. function GetThirdPart(AIndex: Integer): Double;
  40. public
  41. constructor Create(AProjectData: TObject);
  42. destructor Destroy; override;
  43. procedure Open(AConnection: TADOConnection);
  44. procedure Close;
  45. procedure Save;
  46. procedure InitBills;
  47. // 计算 -- 均采用增量汇总方式计算父项
  48. {procedure Calculate(ABillsID: Integer);
  49. procedure CalculateDeal(ABillsID: Integer); // 合同计量
  50. procedure CalculateQuantityChange(ABillsID: Integer); // 数量变更计量
  51. procedure CalculatePriceChange(ABillsID: Integer); // 单价变更计量}
  52. // 上报审核批复过程 -- 锁定数据
  53. procedure LockedBaseData;
  54. // 解锁数据
  55. procedure UnLockedBaseData;
  56. procedure DisableEvents;
  57. procedure EnableEvents;
  58. function GetMaxBillsID: Integer;
  59. function GetGatherTotalPrice(ABillsID, AIndex: Integer): Double;
  60. procedure SyncSetOthersGatherZJJL(ANode: TBillsIDTreeNode; ATree: TBillsIDTree);
  61. property ProjectData: TObject read FProjectData;
  62. property StageData: TStageData read GetStageData;
  63. {累计完成 可查数据}
  64. // AIndex表示不同类型,取值如下:
  65. // 0: 0号台账合同 1: 累计合同计量 2: 累计数量变更计量 3: 累计单价变更计量 4: 累计完成计量
  66. // 第一部分
  67. property FirstPart[AIndex: Integer]: Double read GetFirstPart;
  68. // 第二部分
  69. property SecondPart[AIndex: Integer]: Double read GetSecondPart;
  70. // 第三部分
  71. property ThirdPart[AIndex: Integer]: Double read GetThirdPart;
  72. // 预留费用
  73. property ReservedFee[AIndex: Integer]: Double read GetReservedFee;
  74. // 其他费用项目
  75. property OtherFee[AIndex: Integer]: Double read GetOtherFee;
  76. // 建设期贷款利息
  77. property BuildLoadInterest[AIndex: Integer]: Double read GetBuildLoadInterest;
  78. // 回收金额
  79. property RecyclingFee[AIndex: Integer]: Double read GetRecyclingFee;
  80. // 公路工程以外的工程费用
  81. property OtherProjectFee[AIndex: Integer]: Double read GetOtherProjectFee;
  82. // 结算价
  83. property Settlement[AIndex: Integer]: Double read GetStageSettlement;
  84. end;
  85. implementation
  86. uses
  87. Variants, UtilMethods, Globals, ProjectData, ExcelImport, BillsCommand,
  88. PhaseData, BillsCompileDm, ConditionalDefines, FormulaCalc;
  89. {$R *.dfm}
  90. { TBillsData }
  91. procedure TBillsData.Close;
  92. begin
  93. sddBills.Close;
  94. end;
  95. constructor TBillsData.Create(AProjectData: TObject);
  96. begin
  97. inherited Create(nil);
  98. FProjectData := AProjectData;
  99. end;
  100. destructor TBillsData.Destroy;
  101. begin
  102. inherited;
  103. end;
  104. procedure TBillsData.Open(AConnection: TADOConnection);
  105. begin
  106. sdpBills.Connection := AConnection;
  107. sddBills.Open;
  108. if not Assigned(sddBills.IndexList.FindByName('idxID')) then
  109. sddBills.AddIndex('idxID', 'ID');
  110. if not Assigned(sddBills.IndexList.FindByName('idxSerialNo')) then
  111. sddBills.AddIndex('idxSerialNo', 'SerialNo');
  112. sddBills.FieldByName('OrgQuantity').ValidChars := sddBills.FieldByName('Quantity').ValidChars + ArithmeticCharSet;
  113. sddBills.FieldByName('OrgTotalPrice').ValidChars := sddBills.FieldByName('OrgQuantity').ValidChars;
  114. sddBills.FieldByName('MisQuantity').ValidChars := sddBills.FieldByName('OrgQuantity').ValidChars;
  115. sddBills.FieldByName('MisTotalPrice').ValidChars := sddBills.FieldByName('OrgQuantity').ValidChars;
  116. sddBills.FieldByName('OthQuantity').ValidChars := sddBills.FieldByName('OrgQuantity').ValidChars;
  117. sddBills.FieldByName('OthTotalPrice').ValidChars := sddBills.FieldByName('OrgQuantity').ValidChars;
  118. end;
  119. procedure TBillsData.Save;
  120. procedure ResolveCode(ARec: TBillsRecord);
  121. var
  122. sgs: TStrings;
  123. i: Integer;
  124. sXiangCode, sMuCode, sJieCode, sXiMuCode: string;
  125. begin
  126. sgs := TStringList.Create;
  127. try
  128. sgs.Delimiter := '-';
  129. sgs.DelimitedText := ARec.Code.AsString;
  130. case sgs.Count of
  131. 1: sXiangCode := '';
  132. 2: sXiangCode := ChinessNum(StrToIntDef(sgs[1], 0));
  133. 3: sMuCode := sgs[2];
  134. 4: sJieCode := sgs[3];
  135. else
  136. begin
  137. for i := 4 to sgs.Count - 1 do
  138. if sXiMuCode = '' then
  139. sXiMuCode := sgs[i]
  140. else
  141. sXiMuCode := sXiMuCode + '-' + sgs[i];
  142. end;
  143. end;
  144. finally
  145. ARec.SetStrValue(ARec.XiangCode, sXiangCode);
  146. ARec.SetStrValue(ARec.MuCode, sMuCode);
  147. ARec.SetStrValue(ARec.JieCode, sJieCode);
  148. ARec.SetStrValue(ARec.XimuCode, sXiMuCode);
  149. sgs.Free;
  150. end;
  151. end;
  152. function GetB_CodeChapter(const AB_Code: string): Integer;
  153. var
  154. iValue, iError: Integer;
  155. begin
  156. Result := -1;
  157. Val(AB_Code, iValue, iError);
  158. if iValue > 0 then
  159. Result := iValue div 100;
  160. end;
  161. procedure SaveReportsRela;
  162. var
  163. iIndex: Integer;
  164. stnNode: TBillsIDTreeNode;
  165. iLeafXmjParentID, iChapterParentID: Integer;
  166. sIndexCode: string;
  167. begin
  168. sddBills.BeginUpdate;
  169. try
  170. with TProjectData(FProjectData).BillsCompileData do
  171. for iIndex := 0 to BillsCompileTree.Count - 1 do
  172. begin
  173. stnNode := TBillsIDTreeNode(BillsCompileTree.Items[iIndex]);
  174. // 分项清单排序
  175. if (stnNode.Rec.SerialNo.AsString = '') or
  176. (stnNode.MajorIndex <> stnNode.Rec.SerialNo.AsInteger) then
  177. stnNode.Rec.SerialNo.AsInteger := stnNode.MajorIndex;
  178. // 叶子节点
  179. stnNode.Rec.SetBoolValue(stnNode.Rec.IsLeaf, not stnNode.HasChildren);
  180. // 最底项目节父节点ID
  181. if (stnNode.Rec.B_Code.AsString <> '') then
  182. iLeafXmjParentID := GetLeafXmjParentID(stnNode.ID)
  183. else
  184. iLeafXmjParentID := -1;
  185. stnNode.Rec.SetIntValue(stnNode.Rec.LeafXmjParentID, iLeafXmjParentID);
  186. stnNode.Rec.SetIntValue(stnNode.Rec.ChapterParentID, stnNode.ChapterParentID);
  187. // 分解项目节编号为项、目、节、细目
  188. if stnNode.Rec.Code.AsString <> '' then
  189. ResolveCode(stnNode.Rec);
  190. // 工程量清单排序Code
  191. if (stnNode.Rec.B_Code.AsString <> '') then
  192. begin
  193. sIndexCode := B_CodeToIndexCode(stnNode.Rec.B_Code.AsString);
  194. stnNode.Rec.SetStrValue(stnNode.Rec.IndexCode, sIndexCode);
  195. end;
  196. stnNode.Rec.SetIntValue(stnNode.Rec.NodeLevel, stnNode.Level);
  197. // 工程量清单所属章级
  198. stnNode.Rec.SetIntValue(stnNode.Rec.B_CodeChapter, GetB_CodeChapter(stnNode.Rec.B_Code.AsString));
  199. end;
  200. finally
  201. sddBills.EndUpdate;
  202. end;
  203. end;
  204. begin
  205. if TProjectData(FProjectData).BillsCompileData.Active then
  206. SaveReportsRela; // 保存 SerialNo, IsLeaf, LeafXmjParentID, 分解Code
  207. sddBills.Save;
  208. end;
  209. {procedure TBillsData.Calculate(ABillsID: Integer);
  210. var
  211. stnNode: TsdIDTreeNode;
  212. iChild: Integer;
  213. begin
  214. stnNode := FBillsTree.FindNode(ABillsID);
  215. if stnNode.HasChildren then
  216. begin
  217. for iChild := 0 to stnNode.ChildCount - 1 do
  218. Calculate(stnNode.ChildNodes[iChild].ID);
  219. end
  220. else
  221. begin
  222. CalculateOrg(ABillsID);
  223. CalculateDeal(ABillsID);
  224. CalculateQuantityChange(ABillsID);
  225. CalculatePriceChange(ABillsID);
  226. end;
  227. end;
  228. procedure TBillsData.CalculateDeal(ABillsID: Integer);
  229. var
  230. iIndex: Integer;
  231. fQuantity, fTotalPrice: Double;
  232. Rec: TsdDataRecord;
  233. begin
  234. fQuantity := 0;
  235. fTotalPrice := 0;
  236. with TProjectData(FProjectData) do
  237. for iIndex := 0 to PhaseCount - 1 do
  238. begin
  239. Rec := PhaseData[iIndex].PhaseRecord(ABillsID);
  240. if not Assigned(Rec) then Continue;
  241. fQuantity := fQuantity + Rec.ValueByName('DealQuantity').AsFloat;
  242. fTotalPrice := fTotalPrice + Rec.ValueByName('DealTotalPrice').AsFloat;
  243. end;
  244. with FBillsTree.FindNode(ABillsID).Rec do
  245. UpdateRecordDeal(ABillsID, fQuantity - ValueByName('AddDealQuantity').AsFloat,
  246. fTotalPrice - ValueByName('AddDealTotalPrice').AsFloat);
  247. end;
  248. procedure TBillsData.CalculatePriceChange(ABillsID: Integer);
  249. var
  250. iIndex: Integer;
  251. fQuantity, fTotalPrice: Double;
  252. Rec: TsdDataRecord;
  253. begin
  254. fQuantity := 0;
  255. fTotalPrice := 0;
  256. with TProjectData(FProjectData) do
  257. for iIndex := 0 to PhaseCount - 1 do
  258. begin
  259. Rec := PhaseData[iIndex].PhaseRecord(ABillsID);
  260. if not Assigned(Rec) then Continue;
  261. fQuantity := fQuantity + Rec.ValueByName('PcQuantity').AsFloat;
  262. fTotalPrice := fTotalPrice + Rec.ValueByName('PcTotalPrice').AsFloat;
  263. end;
  264. with FBillsTree.FindNode(ABillsID).Rec do
  265. UpdateRecordPc(ABillsID, fQuantity - ValueByName('AddPcQuantity').AsFloat,
  266. fTotalPrice - ValueByName('AddPcTotalPrice').AsFloat);
  267. end;
  268. procedure TBillsData.CalculateQuantityChange(ABillsID: Integer);
  269. var
  270. iIndex: Integer;
  271. fQuantity, fTotalPrice: Double;
  272. Rec: TsdDataRecord;
  273. begin
  274. fQuantity := 0;
  275. fTotalPrice := 0;
  276. with TProjectData(FProjectData) do
  277. for iIndex := 0 to PhaseCount - 1 do
  278. begin
  279. Rec := PhaseData[iIndex].PhaseRecord(ABillsID);
  280. if not Assigned(Rec) then Continue;
  281. fQuantity := fQuantity + Rec.ValueByName('QcQuantity').AsFloat;
  282. fTotalPrice := fTotalPrice + Rec.ValueByName('QcTotalPrice').AsFloat;
  283. end;
  284. with FBillsTree.FindNode(ABillsID).Rec do
  285. UpdateRecordQc(ABillsID, fQuantity - ValueByName('AddQcQuantity').AsFloat,
  286. fTotalPrice - ValueByName('AddQcTotalPrice').AsFloat);
  287. end; }
  288. {
  289. procedure TBillsData.RecursiveCalculate(ABillsID: Integer);
  290. procedure GatherChildValue(ANode: TsdIDTreeNode);
  291. var
  292. CacheRecord: TCacheRecord;
  293. iChild: Integer;
  294. begin
  295. CacheRecord := TCacheRecord.Create;
  296. try
  297. for iChild := 0 to ANode.ChildCount - 1 do
  298. with ANode.ChildNodes[iChild].Rec do
  299. begin
  300. CacheRecord.FTotalPrice := CacheRecord.FTotalPrice + ValueByName('TotalPrice').AsFloat;
  301. CacheRecord.FDealQuantity := CacheRecord.FDealQuantity + ValueByName('AddDealQuantity').AsFloat;
  302. CacheRecord.FDealTotalPrice := CacheRecord.FDealTotalPrice + ValueByName('AddDealTotalPrice').AsFloat;
  303. CacheRecord.FQcQuantity := CacheRecord.FQcQuantity + ValueByName('AddQcQuantity').AsFloat;
  304. CacheRecord.FQcTotalPrice := CacheRecord.FQcTotalPrice + ValueByName('AddQcTotalPrice').AsFloat;
  305. CacheRecord.FPcQuantity := CacheRecord.FPcQuantity + ValueByName('AddPcQuantity').AsFloat;
  306. CacheRecord.FPcTotalPrice := CacheRecord.FPcTotalPrice + ValueByName('AddPcTotalPrice').AsFloat;
  307. end;
  308. finally
  309. CacheRecord.SetBillsRecord(ANode);
  310. CacheRecord.Free;
  311. end;
  312. end;
  313. procedure CalculateLeafNode(ANode: TsdIDTreeNode; ACacheRecord: TCacheRecord);
  314. begin
  315. with ANode.Rec do
  316. begin
  317. if ValueByName('QtyFlag').AsInteger = 1 then
  318. ValueByName('Quantity').AsFloat := EvaluateExprs(ValueByName('QtyFormula').AsString);
  319. if ValueByName('QtyFlag').AsInteger < 2 then
  320. ACacheRecord.FTotalPrice := ValueByName('Quantity').AsFloat * ValueByName('Price').AsFloat
  321. else
  322. begin
  323. FFormulaCalc.SetRecordText(ValueByName('QtyFormula').AsString);
  324. ACacheRecord.FTotalPrice := FFormulaCalc.Value;
  325. end;
  326. end;
  327. end;
  328. procedure GatherPhaseValue(ANode: TsdIDTreeNode);
  329. var
  330. CacheRecord: TCacheRecord;
  331. iIndex: Integer;
  332. Rec: TsdDataRecord;
  333. begin
  334. CacheRecord := TCacheRecord.Create;
  335. try
  336. CalculateLeafNode(ANode, CacheRecord);
  337. {with TProjectData(FProjectData) do
  338. for iIndex := 0 to PhaseCount - 1 do
  339. begin
  340. PhaseData[iIndex].ReCalculate(ANode.ID);
  341. Rec := PhaseData[iIndex].PhaseRecord(ANode.ID);
  342. if not Assigned(Rec) then Continue;
  343. CacheRecord.FDealQuantity := CacheRecord.FDealQuantity + Rec.ValueByName('DealQuantity').AsFloat;
  344. CacheRecord.FDealTotalPrice := CacheRecord.FDealTotalPrice + Rec.ValueByName('DealTotalPrice').AsFloat;
  345. CacheRecord.FQcQuantity := CacheRecord.FQcQuantity + Rec.ValueByName('QcQuantity').AsFloat;
  346. CacheRecord.FQcTotalPrice := CacheRecord.FQcTotalPrice + Rec.ValueByName('QcTotalPrice').AsFloat;
  347. CacheRecord.FPcQuantity := CacheRecord.FPcQuantity + Rec.ValueByName('PcQuantity').AsFloat;
  348. CacheRecord.FPcTotalPrice := CacheRecord.FPcTotalPrice + Rec.ValueByName('PcTotalPrice').AsFloat;
  349. end;}
  350. { finally
  351. CacheRecord.SetBillsRecord(ANode);
  352. CacheRecord.Free;
  353. end;
  354. end;
  355. procedure CalculateCurNode(ANode: TsdIDTreeNode);
  356. begin
  357. if ANode.HasChildren then
  358. GatherChildValue(ANode)
  359. else
  360. GatherPhaseValue(ANode);
  361. end;
  362. procedure CalculateAllChildren(ANode: TsdIDTreeNode);
  363. var
  364. iChild: Integer;
  365. begin
  366. if ANode.HasChildren then
  367. for iChild := 0 to ANode.ChildCount - 1 do
  368. RecursiveCalculate(ANode.ChildNodes[iChild].ID);
  369. end;
  370. var
  371. stnNode: TsdIDTreeNode;
  372. begin
  373. stnNode := FBillsTree.FindNode(ABillsID);
  374. CalculateAllChildren(stnNode);
  375. CalculateCurNode(stnNode);
  376. end; }
  377. procedure TBillsData.InitBills;
  378. var
  379. Import: TBillsExcelImport;
  380. begin
  381. Import := TBillsExcelImport.Create(TProjectData(ProjectData));
  382. try
  383. Import.ImportFile(GetTemplateBillsFileName);
  384. finally
  385. Import.Free;
  386. end;
  387. end;
  388. function TBillsData.GetStageData: TStageData;
  389. begin
  390. Result := TProjectData(FProjectData).PhaseData.StageData;
  391. end;
  392. procedure TBillsData.LockedBaseData;
  393. var
  394. iIndex: Integer;
  395. Rec: TBillsRecord;
  396. begin
  397. sddBills.BeginUpdate;
  398. for iIndex := 0 to sddBills.RecordCount - 1 do
  399. begin
  400. Rec := TBillsRecord(sddBills.Records[iIndex]);
  401. Rec.SetBoolValue(Rec.LockedLevel, True);
  402. Rec.SetBoolValue(Rec.LockedInfo, True);
  403. Rec.SetBoolValue(Rec.LockedNewPrice, Rec.NewPrice.AsFloat <> 0);
  404. end;
  405. sddBills.EndUpdate;
  406. end;
  407. procedure TBillsData.sddBillsAfterAddRecord(ARecord: TsdDataRecord);
  408. begin
  409. ARecord.ValueByName('CreatePhaseID').AsInteger := TProjectData(FProjectData).PhaseIndex;
  410. end;
  411. function TBillsData.GetBuildLoadInterest(AIndex: Integer): Double;
  412. begin
  413. Result := GetGatherTotalPrice(34, AIndex);
  414. end;
  415. function TBillsData.GetFirstPart(AIndex: Integer): Double;
  416. begin
  417. Result := GetGatherTotalPrice(1, AIndex);
  418. end;
  419. function TBillsData.GetOtherFee(AIndex: Integer): Double;
  420. begin
  421. Result := GetGatherTotalPrice(15, AIndex);
  422. end;
  423. function TBillsData.GetOtherProjectFee(AIndex: Integer): Double;
  424. begin
  425. Result := GetGatherTotalPrice(9, AIndex);
  426. end;
  427. function TBillsData.GetRecyclingFee(AIndex: Integer): Double;
  428. begin
  429. Result := GetGatherTotalPrice(16, AIndex);
  430. end;
  431. function TBillsData.GetReservedFee(AIndex: Integer): Double;
  432. begin
  433. Result := GetGatherTotalPrice(7, AIndex);
  434. end;
  435. function TBillsData.GetSecondPart(AIndex: Integer): Double;
  436. begin
  437. Result := GetGatherTotalPrice(2, AIndex);
  438. end;
  439. function TBillsData.GetStageSettlement(AIndex: Integer): Double;
  440. begin
  441. // 全国
  442. // 第一部分+第二部分+第三部分+预备费+新增加费用项目(其他费用_广东)-回收金额
  443. Result := FirstPart[AIndex] + SecondPart[AIndex] + ThirdPart[AIndex]
  444. + ReservedFee[AIndex] + OtherFee[AIndex] - RecyclingFee[AIndex];
  445. // 广东
  446. // 全国的基础上+建设期贷款利息+公路功能以外的项目
  447. if _IsGuangDong then
  448. Result := Result + BuildLoadInterest[AIndex] + OtherProjectFee[AIndex];
  449. end;
  450. function TBillsData.GetThirdPart(AIndex: Integer): Double;
  451. begin
  452. Result := GetGatherTotalPrice(3, AIndex);
  453. end;
  454. function TBillsData.GetGatherTotalPrice(ABillsID, AIndex: Integer): Double;
  455. var
  456. Rec: TsdDataRecord;
  457. begin
  458. Result := 0;
  459. Rec := sddBills.FindKey('idxID', ABillsID);
  460. if Assigned(Rec) then
  461. begin
  462. case AIndex of
  463. 0: Result := Rec.ValueByName('TotalPrice').AsFloat;
  464. 1: Result := Rec.ValueByName('AddDealTotalPrice').AsFloat;
  465. 2: Result := Rec.ValueByName('AddQcTotalPrice').AsFloat;
  466. 3: Result := Rec.ValueByName('AddPcTotalPrice').AsFloat;
  467. 4: Result := Rec.ValueByName('AddGatherTotalPrice').AsFloat;
  468. end;
  469. end;
  470. end;
  471. procedure TBillsData.DisableEvents;
  472. begin
  473. sddBills.BeforeValueChange := nil;
  474. end;
  475. procedure TBillsData.EnableEvents;
  476. begin
  477. sddBills.BeforeValueChange := sddBillsBeforeValueChange;
  478. end;
  479. procedure TBillsData.UnLockedBaseData;
  480. var
  481. iIndex: Integer;
  482. begin
  483. for iIndex := 0 to sddBills.RecordCount - 1 do
  484. sddBills.Records[iIndex].ValueByName('LockedInfo').AsBoolean := False;
  485. end;
  486. procedure TBillsData.sddBillsBeforeDeleteRecord(ARecord: TsdDataRecord;
  487. var Allow: Boolean);
  488. begin
  489. with TProjectData(FProjectData) do
  490. begin
  491. if ProjProperties.PhaseCount > 0 then
  492. PhaseData.StageData.DeletePhaseRecord(ARecord.ValueByName('ID').AsInteger);
  493. end;
  494. end;
  495. procedure TBillsData.sddBillsBeforeValueChange(AValue: TsdValue;
  496. const NewValue: Variant; var Allow: Boolean);
  497. begin
  498. if (Pos('DgnQuantity', AValue.FieldName) > 0) and
  499. not (VarIsNull(NewValue) or (NewValue = 0)) then
  500. begin
  501. if AValue.Owner.ValueByName('B_Code').AsString <> '' then
  502. begin
  503. ErrorMessage('仅项目节可以输入设计数量!');
  504. Allow := False;
  505. end;
  506. end;
  507. end;
  508. function TBillsData.GetMaxBillsID: Integer;
  509. var
  510. Rec: TsdDataRecord;
  511. i: Integer;
  512. begin
  513. Result := 100;
  514. for i := 0 to sddBills.RecordCount - 1 do
  515. begin
  516. Rec := sddBills.Records[i];
  517. if Rec.ValueByName('ID').AsInteger > Result then
  518. Result := Rec.ValueByName('ID').AsInteger;
  519. end;
  520. end;
  521. procedure TBillsData.sddBillsGetRecordClass(
  522. var ARecordClass: TsdRecordClass);
  523. begin
  524. ARecordClass := TBillsRecord;
  525. end;
  526. procedure TBillsData.SyncSetOthersGatherZJJL(ANode: TBillsIDTreeNode;
  527. ATree: TBillsIDTree);
  528. procedure SetSibling;
  529. var
  530. vSibling: TBillsIDTreeNode;
  531. begin
  532. if Assigned(ANode.Parent) then
  533. vSibling := TBillsIDTreeNode(ANode.Parent.FirstChild)
  534. else
  535. vSibling := TBillsIDTreeNode(ATree.FirstNode);
  536. while Assigned(vSibling) do
  537. begin
  538. vSibling.Rec.IsGatherZJJL.AsBoolean := ANode.Rec.IsGatherZJJL.AsBoolean;
  539. vSibling := TBillsIDTreeNode(vSibling.NextSibling);
  540. end;
  541. end;
  542. procedure SetSameLevelXmj;
  543. var
  544. vParent, vChild: TBillsIDTreeNode;
  545. iCount, iPosterity: Integer;
  546. begin
  547. if ANode.Level < 1 then Exit;
  548. vParent := TBillsIDTreeNode(ANode.Parent);
  549. while (vParent.Level > 1) do
  550. vParent := TBillsIDTreeNode(vParent.Parent);
  551. iCount := 0;
  552. iPosterity := vParent.PosterityCount;
  553. vChild := TBillsIDTreeNode(vParent.NextNode);
  554. while (iCount < iPosterity) do
  555. begin
  556. if (vChild.Level = ANode.Level) and (vChild.Rec.B_Code.AsString = '') then
  557. vChild.Rec.IsGatherZJJL.AsBoolean := ANode.Rec.IsGatherZJJL.AsBoolean;
  558. vChild := TBillsIDTreeNode(vChild.NextNode);
  559. Inc(iCount);
  560. end;
  561. end;
  562. begin
  563. case SupportManager.ConfigInfo.GatherZJJLSelect of
  564. 1: SetSameLevelXmj;
  565. 2: SetSibling;
  566. end;
  567. end;
  568. end.