unit StageLeafXmjGlDm; interface uses SysUtils, Classes, sdDB, sdProvider, ADODB, mDataRecord, CalcDecimal; type TStageLeafXmjGlData = class(TDataModule) sdpStageLeafXmjGl: TsdADOProvider; sddStageLeafXmjGl: TsdDataSet; procedure sddStageLeafXmjGlGetRecordClass( var ARecordClass: TsdRecordClass); procedure sddStageLeafXmjGlAfterValueChanged(AValue: TsdValue); private FPhaseData: TObject; procedure SaveCurStageData; procedure BeforeBatchOperation; procedure AfterBatchOperation; procedure UpdateEndTotalPrice(ARec: TStageLeafXmjGlRecord); procedure UpdateEndQuantity(ARec: TStageLeafXmjGlRecord); procedure CalculateQuantity(ARec: TStageLeafXmjGlRecord); procedure UpdateEndPALRela(ARec:TStageLeafXmjGlRecord); procedure CalculatePALRela(ARec:TStageLeafXmjGlRecord; AProjGLRec: TProjectGLRecord); function GetDecimal: TCalcDecimal; public constructor Create(APhaseData: TObject); destructor Destroy; override; procedure Open(AConnection: TADOConnection); procedure Save; procedure CopyPrePhaseData; procedure LoadCurStageData; function StageLeafXmjGlRecord(AID: Integer): TStageLeafXmjGlRecord; procedure DeleteLeafXmjGLRecord(AID: Integer); procedure Calculate(AID: Integer); // 调整工料价格后,需计算项 procedure CalculatePriceRela(AGLID: Integer); property Decimal: TCalcDecimal read GetDecimal; end; implementation uses PhaseData, ProjectData, UtilMethods, LeafXmjGlDm, ProjectGLDm, StrUtils, DetailGLDm, BillsTree, BillsMeasureDm; {$R *.dfm} { TStageLeafXmjGlData } procedure TStageLeafXmjGlData.AfterBatchOperation; begin sddStageLeafXmjGl.EndUpdate; sddStageLeafXmjGl.EnableControls; sddStageLeafXmjGl.AfterValueChanged := sddStageLeafXmjGlAfterValueChanged; end; procedure TStageLeafXmjGlData.BeforeBatchOperation; begin sddStageLeafXmjGl.DisableControls; sddStageLeafXmjGl.BeginUpdate; sddStageLeafXmjGl.AfterValueChanged := nil; end; procedure TStageLeafXmjGlData.Calculate(AID: Integer); var Rec: TStageLeafXmjGlRecord; ProjGLRec: TProjectGLRecord; fValue: Double; begin Rec := StageLeafXmjGlRecord(AID); CalculateQuantity(Rec); with TProjectData(TPhaseData(FPhaseData).ProjectData) do ProjGLRec := ProjectGLData.ProjectGLRec(Rec.GLID); // 计算调差金额 fValue := Decimal.TotalPrice.RoundTo(Rec.Quantity.AsFloat * ProjGLRec.ValidDeltaPrice.AsFloat); Rec.SetFloatValue(Rec.TotalPrice, fValue); UpdateEndTotalPrice(Rec); // 计算本期实耗分析相关 CalculatePALRela(Rec, ProjGLRec); end; procedure TStageLeafXmjGlData.CalculatePriceRela(AGLID: Integer); var i: Integer; Rec: TStageLeafXmjGlRecord; ProjGLRec: TProjectGLRecord; fValue: Double; begin with TProjectData(TPhaseData(FPhaseData).ProjectData) do ProjGLRec := ProjectGLData.ProjectGLRec(AGLID); for i := 0 to sddStageLeafXmjGl.RecordCount - 1 do begin Rec := TStageLeafXmjGlRecord(sddStageLeafXmjGl.Records[i]); if Rec.GLID = AGLID then begin // 计算调差金额 fValue := Decimal.TotalPrice.RoundTo(Rec.Quantity.AsFloat * ProjGLRec.ValidDeltaPrice.AsFloat); Rec.SetFloatValue(Rec.TotalPrice, fValue); UpdateEndTotalPrice(Rec); // 计算本期实耗分析相关 CalculatePALRela(Rec, ProjGLRec); end; end; end; procedure TStageLeafXmjGlData.CalculateQuantity(ARec: TStageLeafXmjGlRecord); var vDetails: TList; fQuantity: Double; i: Integer; GLRec: TDetailGLRecord; vNode: TMeasureBillsIDTreeNode; begin vDetails := TList.Create; try with TProjectData(TPhaseData(FPhaseData).ProjectData).DetailGLData do LoadXmjDetailGLs(ARec.XmjID, ARec.GLID, vDetails); fQuantity := 0; for i := 0 to vDetails.Count - 1 do begin GLRec := TDetailGLRecord(vDetails.Items[i]); with TProjectData(TPhaseData(FPhaseData).ProjectData).BillsMeasureData do vNode := TMeasureBillsIDTreeNode(BillsMeasureTree.FindNode(GLRec.BillsID.AsInteger)); if Assigned(vNode.StageRec) then fQuantity := fQuantity + Decimal.Quantity.RoundTo(vNode.StageRec.GatherQuantity.AsFloat * GLRec.Quantity.AsFloat); end; ARec.SetFloatValue(ARec.Quantity, fQuantity); UpdateEndQuantity(ARec); finally vDetails.Free; end; end; constructor TStageLeafXmjGlData.Create(APhaseData: TObject); begin inherited Create(nil); FPhaseData := APhaseData; end; destructor TStageLeafXmjGlData.Destroy; begin inherited; end; function TStageLeafXmjGlData.GetDecimal: TCalcDecimal; begin Result := TProjectData(TPhaseData(FPhaseData).ProjectData).ProjProperties.DecimalManager.Common; end; procedure TStageLeafXmjGlData.LoadCurStageData; const sSelectSql = 'Select * From PhaseLeafXmjGL Where StageID = %d'; var vQuery: TADOQuery; procedure LoadData; var iRec: Integer; Rec: TStageLeafXmjGlRecord; begin for iRec := 0 to sddStageLeafXmjGl.RecordCount - 1 do begin Rec := TStageLeafXmjGlRecord(sddStageLeafXmjGl.Records[iRec]); if vQuery.Active and vQuery.Locate('ID', Rec.ID.AsInteger, []) then begin Rec.SetFloatValue(Rec.Quantity, vQuery.FieldByName('Quantity').AsFloat); Rec.SetFloatValue(Rec.TotalPrice, vQuery.FieldByName('TotalPrice').AsFloat); Rec.SetFloatValue(Rec.UsedQuantity, vQuery.FieldByName('UsedQuantity').AsFloat); Rec.SetFloatValue(Rec.UsedTotalPrice, vQuery.FieldByName('UsedTotalPrice').AsFloat); Rec.SetFloatValue(Rec.PAL_UsedQuantity, vQuery.FieldByName('PAL_UsedQuantity').AsFloat); Rec.SetFloatValue(Rec.PAL_UsedTotalPrice, vQuery.FieldByName('PAL_UsedTotalPrice').AsFloat); Rec.SetFloatValue(Rec.PAL_DeltaPrice, vQuery.FieldByName('PAL_DeltaPrice').AsFloat); Rec.SetFloatValue(Rec.PAL_Total, vQuery.FieldByName('PAL_Total').AsFloat); Rec.SetFloatValue(Rec.EndQuantity, Decimal.Quantity.RoundTo(Rec.PreQuantity.AsFloat + Rec.Quantity.AsFloat)); Rec.SetFloatValue(Rec.EndTotalPrice, Decimal.TotalPrice.RoundTo(Rec.PreTotalPrice.AsFloat + Rec.TotalPrice.AsFloat)); Rec.SetFloatValue(Rec.EndUsedQuantity, Decimal.Quantity.RoundTo(Rec.PreUsedQuantity.AsFloat + Rec.UsedQuantity.AsFloat)); Rec.SetFloatValue(Rec.EndUsedTotalPrice, Decimal.TotalPrice.RoundTo(Rec.PreUsedTotalPrice.AsFloat + Rec.UsedTotalPrice.AsFloat)); Rec.SetFloatValue(Rec.EndPAL_UsedQuantity, Decimal.Quantity.RoundTo(Rec.PrePAL_UsedQuantity.AsFloat + Rec.PAL_UsedQuantity.AsFloat)); Rec.SetFloatValue(Rec.EndPAL_UsedTotalPrice, Decimal.TotalPrice.RoundTo(Rec.PrePAL_UsedTotalPrice.AsFloat + Rec.PAL_UsedTotalPrice.AsFloat)); Rec.SetFloatValue(Rec.EndPAL_DeltaPrice, Decimal.TotalPrice.RoundTo(Rec.PrePAL_DeltaPrice.AsFloat + Rec.PAL_DeltaPrice.AsFloat)); Rec.SetFloatValue(Rec.EndPAL_Total, Decimal.TotalPrice.RoundTo(Rec.PrePAL_Total.AsFloat + Rec.PAL_Total.AsFloat)); end else begin Rec.SetFloatValue(Rec.Quantity, 0); Rec.SetFloatValue(Rec.TotalPrice, 0); Rec.SetFloatValue(Rec.UsedQuantity, 0); Rec.SetFloatValue(Rec.UsedTotalPrice, 0); Rec.SetFloatValue(Rec.PAL_UsedQuantity, 0); Rec.SetFloatValue(Rec.PAL_UsedTotalPrice, 0); Rec.SetFloatValue(Rec.PAL_DeltaPrice, 0); Rec.SetFloatValue(Rec.PAL_Total, 0); Rec.SetFloatValue(Rec.EndQuantity, Rec.PreQuantity.AsFloat); Rec.SetFloatValue(Rec.EndTotalPrice, Rec.PreTotalPrice.AsFloat); Rec.SetFloatValue(Rec.EndUsedQuantity, Rec.PreUsedQuantity.AsFloat); Rec.SetFloatValue(Rec.EndUsedTotalPrice, Rec.PreUsedTotalPrice.AsFloat); Rec.SetFloatValue(Rec.EndPAL_UsedQuantity, Rec.PrePAL_UsedQuantity.AsFloat); Rec.SetFloatValue(Rec.EndPAL_UsedTotalPrice, Rec.PrePAL_UsedTotalPrice.AsFloat); Rec.SetFloatValue(Rec.EndPAL_DeltaPrice, Rec.PrePAL_DeltaPrice.AsFloat); Rec.SetFloatValue(Rec.EndPAL_Total, Rec.PrePAL_Total.AsFloat); end; end; end; begin BeforeBatchOperation; vQuery := TADOQuery.Create(nil); try vQuery.Connection := sdpStageLeafXmjGl.Connection; vQuery.SQL.Clear; vQuery.SQL.Add(Format(sSelectSql, [TPhaseData(FPhaseData).StageIndex])); vQuery.Open; LoadData; finally vQuery.Free; AfterBatchOperation; end; end; procedure TStageLeafXmjGlData.Open(AConnection: TADOConnection); begin sdpStageLeafXmjGl.Connection := AConnection; sddStageLeafXmjGl.Open; if not Assigned(sddStageLeafXmjGl.FindIndex('idxID')) then sddStageLeafXmjGl.AddIndex('idxID', 'ID'); LoadCurStageData; end; procedure TStageLeafXmjGlData.Save; begin sddStageLeafXmjGl.Save; if not TPhaseData(FPhaseData).StageDataReadOnly then SaveCurStageData; end; procedure TStageLeafXmjGlData.SaveCurStageData; const sDeleteSql = 'Delete From PhaseLeafXmjGL where (StageID = %d)'; sCopySql = 'Insert Into PhaseLeafXmjGL'+ ' Select ID, %d As StageID, Quantity, TotalPrice, UsedQuantity, UsedTotalPrice,'+ ' PAL_UsedQuantity, PAL_UsedTotalPrice, PAL_DeltaPrice, PAL_Total'+ ' From StageLeafXmjGL' + ' Where (Quantity <> 0) or (UsedQuantity <> 0)'; begin if TPhaseData(FPhaseData).StageDataReadOnly then Exit; ExecuteSql(sdpStageLeafXmjGl.Connection, Format(sDeleteSql, [TPhaseData(FPhaseData).StageIndex])); ExecuteSql(sdpStageLeafXmjGl.Connection, Format(sCopySql, [TPhaseData(FPhaseData).StageIndex])); // 不要问我为什么,不写下面这个,上面那句不执行 ExecuteSql(sdpStageLeafXmjGl.Connection, Format(sDeleteSql, [-1])); ExecuteSql(sdpStageLeafXmjGl.Connection, Format(sCopySql, [-1])); end; procedure TStageLeafXmjGlData.sddStageLeafXmjGlGetRecordClass( var ARecordClass: TsdRecordClass); begin ARecordClass := TStageLeafXmjGlRecord; end; function TStageLeafXmjGlData.StageLeafXmjGlRecord( AID: Integer): TStageLeafXmjGlRecord; begin Result := TStageLeafXmjGlRecord(sddStageLeafXmjGl.FindKey('idxID', AID)); if not Assigned(Result) then begin Result := TStageLeafXmjGlRecord(sddStageLeafXmjGl.Add); Result.ID.AsInteger := AID; end; end; procedure TStageLeafXmjGlData.sddStageLeafXmjGlAfterValueChanged( AValue: TsdValue); var Rec: TStageLeafXmjGlRecord; ProjGLRec: TProjectGLRecord; begin if SameText(AValue.FieldName, 'UsedQuantity') then begin Rec := TStageLeafXmjGlRecord(AValue.Owner); with TProjectData(TPhaseData(FPhaseData).ProjectData) do begin ProjGLRec := ProjectGLData.ProjectGLRec(Rec.GLID); CalculatePALRela(Rec, ProjGLRec); ProjectGLData.CalculatePALRela(ProjGLRec); PhaseData.StageData.CalculateMaterialNode; end; end; end; procedure TStageLeafXmjGlData.CalculatePALRela( ARec: TStageLeafXmjGlRecord; AProjGLRec: TProjectGLRecord); var fValue: Double; begin // 计算 材料实耗金额 fValue := Decimal.TotalPrice.RoundTo(ARec.UsedQuantity.AsFloat * AProjGLRec.InfoPrice.AsFloat); ARec.SetFloatValue(ARec.UsedTotalPrice, fValue); // 计算 数量差 fValue := Decimal.Quantity.RoundTo(ARec.Quantity.AsFloat - ARec.UsedQuantity.AsFloat); ARec.SetFloatValue(ARec.PAL_UsedQuantity, fValue); // 计算 数量差金额 fValue := Decimal.Quantity.RoundTo(ARec.PAL_UsedQuantity.AsFloat * AProjGLRec.BasePrice.AsFloat); ARec.SetFloatValue(ARec.PAL_UsedTotalPrice, fValue); // 计算 实耗价差金额 fValue := Decimal.TotalPrice.RoundTo( - ARec.UsedQuantity.AsFloat * AProjGLRec.DeltaPrice.AsFloat); ARec.SetFloatValue(ARec.PAL_DeltaPrice, fValue); // 计算 节余金额 fValue := Decimal.TotalPrice.RoundTo(AProjGLRec.BasePrice.AsFloat*ARec.Quantity.AsFloat - AProjGLRec.InfoPrice.AsFloat*ARec.UsedQuantity.AsFloat); ARec.SetFloatValue(ARec.PAL_Total, fValue); UpdateEndPALRela(ARec); end; procedure TStageLeafXmjGlData.DeleteLeafXmjGLRecord(AID: Integer); var Rec: TsdDataRecord; begin Rec := sddStageLeafXmjGl.FindKey('idxID', AID); sddStageLeafXmjGl.Remove(Rec); end; procedure TStageLeafXmjGlData.UpdateEndQuantity( ARec: TStageLeafXmjGlRecord); var fQuantity: Double; AddRec: TLeafXmjGlRecord; begin fQuantity := Decimal.Quantity.RoundTo(ARec.PreQuantity.AsFloat + ARec.Quantity.AsFloat); ARec.SetFloatValue(ARec.EndQuantity, fQuantity); if Assigned(ARec.MainRec) then begin AddRec := TLeafXmjGlRecord(ARec.MainRec); AddRec.SetFloatValue(AddRec.AddQuantity, fQuantity); end; end; procedure TStageLeafXmjGlData.UpdateEndPALRela( ARec: TStageLeafXmjGlRecord); var fValue: Double; AddRec: TLeafXmjGlRecord; begin // 实耗数量 fValue := Decimal.Quantity.RoundTo(ARec.PreUsedQuantity.AsFloat + ARec.UsedQuantity.AsFloat); ARec.SetFloatValue(ARec.EndUsedQuantity, fValue); // 实耗金额 fValue := Decimal.TotalPrice.RoundTo(ARec.PreUsedTotalPrice.AsFloat + ARec.UsedTotalPrice.AsFloat); ARec.SetFloatValue(ARec.EndUsedTotalPrice, fValue); // 数量差 fValue := Decimal.Quantity.RoundTo(ARec.PrePAL_UsedQuantity.AsFloat + ARec.PAL_UsedQuantity.AsFloat); ARec.SetFloatValue(ARec.EndPAL_UsedQuantity, fValue); // 数量差金额 fValue := Decimal.TotalPrice.RoundTo(ARec.PrePAL_UsedTotalPrice.AsFloat + ARec.PAL_UsedTotalPrice.AsFloat); ARec.SetFloatValue(ARec.EndPAL_UsedTotalPrice, fValue); // 实耗价差金额 fValue := Decimal.TotalPrice.RoundTo(ARec.PrePAL_DeltaPrice.AsFloat + ARec.PAL_DeltaPrice.AsFloat); ARec.SetFloatValue(ARec.EndPAL_DeltaPrice, fValue); // 节余金额 fValue := Decimal.TotalPrice.RoundTo(ARec.PrePAL_Total.AsFloat + ARec.PAL_Total.AsFloat); ARec.SetFloatValue(ARec.EndPAL_Total, fValue); if Assigned(ARec.MainRec) then begin AddRec := TLeafXmjGlRecord(ARec.MainRec); AddRec.SetFloatValue(AddRec.AddUsedQuantity, ARec.EndUsedQuantity.AsFloat); AddRec.SetFloatValue(AddRec.AddUsedTotalPrice, ARec.EndUsedTotalPrice.AsFloat); AddRec.SetFloatValue(AddRec.AddPAL_UsedQuantity, ARec.EndPAL_UsedQuantity.AsFloat); AddRec.SetFloatValue(AddRec.AddPAL_UsedTotalPrice, ARec.EndPAL_UsedTotalPrice.AsFloat); AddRec.SetFloatValue(AddRec.AddPAL_DeltaPrice, ARec.EndPAL_DeltaPrice.AsFloat); AddRec.SetFloatValue(AddRec.AddPAL_Total, ARec.EndPAL_Total.AsFloat); end; end; procedure TStageLeafXmjGlData.UpdateEndTotalPrice( ARec: TStageLeafXmjGlRecord); var fValue: Double; AddRec: TLeafXmjGlRecord; begin fValue := Decimal.TotalPrice.RoundTo(ARec.PreTotalPrice.AsFloat + ARec.TotalPrice.AsFloat); ARec.SetFloatValue(ARec.EndTotalPrice, fValue); if Assigned(ARec.MainRec) then begin AddRec := TLeafXmjGlRecord(ARec.MainRec); AddRec.SetFloatValue(AddRec.AddTotalPrice, fValue); end; end; procedure TStageLeafXmjGlData.CopyPrePhaseData; var iRecord: Integer; Rec: TLeafXmjGlRecord; NewRec: TStageLeafXmjGlRecord; begin BeforeBatchOperation; try with TProjectData(TPhaseData(FPhaseData).ProjectData).LeafXmjGlData do for iRecord := 0 to sddLeafXmjGL.RecordCount - 1 do begin Rec := TLeafXmjGlRecord(sddLeafXmjGL.Records[iRecord]); NewRec := TStageLeafXmjGlRecord(Rec.StageRec); NewRec.ID.AsInteger := Rec.ID.AsInteger; NewRec.PreQuantity.AsFloat := Rec.AddQuantity.AsFloat; NewRec.PreTotalPrice.AsFloat := Rec.AddQuantity.AsFloat; NewRec.PreUsedQuantity.AsFloat := Rec.AddUsedQuantity.AsFloat; NewRec.PreUsedTotalPrice.AsFloat := Rec.AddUsedTotalPrice.AsFloat; NewRec.PrePAL_UsedQuantity.AsFloat := Rec.AddPAL_UsedQuantity.AsFloat; NewRec.PrePAL_UsedTotalPrice.AsFloat := Rec.AddPAL_UsedTotalPrice.AsFloat; NewRec.PrePAL_DeltaPrice.AsFloat := Rec.AddPAL_DeltaPrice.AsFloat; NewRec.PrePAL_Total.AsFloat := Rec.AddPAL_Total.AsFloat; NewRec.EndQuantity.AsFloat := Rec.AddQuantity.AsFloat; NewRec.EndTotalPrice.AsFloat := Rec.AddQuantity.AsFloat; NewRec.EndUsedQuantity.AsFloat := Rec.AddUsedQuantity.AsFloat; NewRec.EndUsedTotalPrice.AsFloat := Rec.AddUsedTotalPrice.AsFloat; NewRec.EndPAL_UsedQuantity.AsFloat := Rec.AddPAL_UsedQuantity.AsFloat; NewRec.EndPAL_UsedTotalPrice.AsFloat := Rec.AddPAL_UsedTotalPrice.AsFloat; NewRec.EndPAL_DeltaPrice.AsFloat := Rec.AddPAL_DeltaPrice.AsFloat; NewRec.EndPAL_Total.AsFloat := Rec.AddPAL_Total.AsFloat; end; finally AfterBatchOperation; end; end; end.