unit uGastosMontajeController; interface uses Classes, uDADataTable, uBizMontajesCompleto, uIDataModuleMontajesCompleto; type IGastosMontajeController = interface ['{B5C769F2-76DE-4F3E-8F80-EDA2DC099985}'] procedure AsignarID(AGastos: IBizGastosMontaje; IDCabecera: Integer; EsNuevo:Boolean); // function Buscar(const ID: Integer): IBizMontaje; // function BuscarTodos: IBizMontaje; procedure Anadir(AMontaje : IBizGastosMontaje); // procedure Eliminar(const ID : Integer); overload; procedure Eliminar(AMontaje : IBizGastosMontaje); end; TGastosMontajeController = class(TInterfacedObject, IGastosMontajeController) protected FDataModule : IDataModuleMontajesCompleto; public procedure Anadir(AGastos : IBizGastosMontaje); procedure Eliminar(AGastos : IBizGastosMontaje); procedure AsignarID(AGastos: IBizGastosMontaje; IDCabecera: Integer; AEsNuevo : Boolean); constructor Create; destructor Destroy; override; end; implementation uses DB, SysUtils, uDAInterfaces, Variants, uDataModuleMontajesCompleto; { TGastosMontajeController } procedure TGastosMontajeController.Anadir(AGastos: IBizGastosMontaje); begin AGastos.Insert; end; procedure TGastosMontajeController.AsignarID(AGastos: IBizGastosMontaje; IDCabecera: Integer; AEsNuevo:Boolean); begin with AGastos do begin DataTable.DisableControls; try if not DataTable.Active then DataTable.Active := True; { ¡¡¡¡ OJO !!!! Para asignar el ID en los Gastos hay que tener en cuenta una cosa: Si se cambia el ID, ese detalle ya no pertenece a esa cabecera porque ya no se cumple la condición de la relacion: Master.ID = Detail.ID_MONTAJE. Por esa razón no sirve hacer un recorrido desde el principio hasta el final porque las Gastos van desapareciendo según asignamos el valor al campo ID y nos mueve aleatoriamente la posición del registro actual. Es mejor hacer un bucle sencillo hasta que "se gasten" todos los Gastos. Cuando el RecordCount llegue a 0 quiere decir que hemos tratado todos los Gastos. El bucle cambia en el caso de ser llamada esta funcion desde modificar un montaje ya que en ese caso sí que hay que hacer un recorrido total de las tuplas de detalle. } if AEsNuevo then begin while RecordCount > 0 do begin DataTable.First; Edit; ID := FDataModule.GetNextID(DataTable.LogicalName); ID_MONTAJE := IDCabecera; Post end end else begin DataTable.First; while not DataTable.EOF do begin if not AEsNuevo then begin Edit; ID := FDataModule.GetNextID(DataTable.LogicalName); ID_MONTAJE := IDCabecera; Post end; DataTable.Next end; end; finally DataTable.EnableControls; end; end; end; constructor TGastosMontajeController.Create; begin inherited; FDataModule := TDataModuleMontajesCompleto.Create(Nil); end; destructor TGastosMontajeController.Destroy; begin FDataModule := Nil; inherited; end; procedure TGastosMontajeController.Eliminar(AGastos: IBizGastosMontaje); begin if not Assigned(AGastos) then raise Exception.Create ('Gasto no asignado'); // ShowHourglassCursor; try if (AGastos.State in dsEditModes) then AGastos.Cancel; AGastos.Delete; // AGastos.DataTable.ApplyUpdates; finally // HideHourglassCursor; end; end; end.