unit uRemesasClienteController; interface uses Classes, SysUtils, uDADataTable, uControllerBase, uEditorDBItem, uIDataModuleRemesasCliente, uBizRemesasCliente, uProveedoresController, uBizContactos, uRecibosClienteController; type IRemesasClienteController = interface(IControllerBase) ['{F5D925C6-255C-4374-9A71-DFC0FBB7FA96}'] function Buscar(const ID: Integer): IBizRemesaCliente; function BuscarTodos: IBizRemesaCliente; overload; procedure Ver(ARemesaCliente : IBizRemesaCliente); procedure VerTodos(ARemesasCliente: IBizRemesaCliente); function Nuevo : IBizRemesaCliente; procedure Anadir(ARemesaCliente : IBizRemesaCliente); function Eliminar(const ID : Integer): Boolean; overload; function Eliminar(ARemesaCliente : IBizRemesaCliente; AllItems: Boolean = false): Boolean; overload; function Guardar(ARemesaCliente : IBizRemesaCliente): Boolean; procedure DescartarCambios(ARemesaCliente : IBizRemesaCliente); function Existe(const ID: Integer) : Boolean; procedure Preview(ARemesaCliente : IBizRemesaCliente; AllItems: Boolean = false); procedure Print(ARemesaCliente : IBizRemesaCliente; AllItems: Boolean = false); function EsModificable(ARemesaProveedor : IBizRemesaCliente): Boolean; function EsEliminable(ARemesaProveedor : IBizRemesaCliente): Boolean; function ElegirRecibosCliente(ARemesaCliente : IBizRemesaCliente; AListaRecibosIniciales: TStringList): Boolean; procedure EliminarReciboCliente(ARemesaCliente : IBizRemesaCliente); function GetRecibosClienteController: IRecibosClienteController; property RecibosClienteController: IRecibosClienteController read GetRecibosClienteController; procedure RecuperarRecibos(ARemesaCliente: IBizRemesaCliente); function ExtraerSeleccionados(ARemesasCliente: IBizRemesaCliente) : IBizRemesaCliente; function DarListaAnosRemesas: TStringList; procedure FiltrarAno(ARemesa: IBizRemesaCliente; ADynWhereDataTable: WideString; const Ano: String); end; TRemesasClienteController = class(TControllerBase, IRemesasClienteController) protected FDataModule : IDataModuleRemesasCliente; FRecibosClienteController: IRecibosClienteController; function GetRecibosClienteController: IRecibosClienteController; procedure RecibirAviso(ASujeto: ISujeto; ADataTable: IDAStronglyTypedDataTable); override; procedure AsignarID(ARemesaCliente: IBizRemesaCliente; const IDNuevo: Integer); virtual; function CreateEditor(const AName : String; const IID: TGUID; out Intf): Boolean; function _Vacio : IBizRemesaCliente; procedure FiltrarEmpresa(ARemesaCliente: IBizRemesaCliente); function ValidarRemesaCliente(ARemesaCliente: IBizRemesaCliente): Boolean; virtual; procedure RecuperarRecibos(ARemesaCliente: IBizRemesaCliente); procedure RecuperarObjetos(ARemesaCliente: IBizRemesaCliente); virtual; procedure AsignarDataModule; virtual; public property RecibosClienteController: IRecibosClienteController read GetRecibosClienteController; constructor Create; override; destructor Destroy; override; function Eliminar(const ID : Integer): Boolean; overload; function Eliminar(ARemesaCliente : IBizRemesaCliente; AllItems: Boolean = false): Boolean; overload; function Guardar(ARemesaCliente : IBizRemesaCliente): Boolean; procedure DescartarCambios(ARemesaCliente : IBizRemesaCliente); virtual; function Existe(const ID: Integer) : Boolean; virtual; procedure Anadir(ARemesaCliente : IBizRemesaCliente); virtual; function Buscar(const ID: Integer): IBizRemesaCliente; virtual; function BuscarTodos: IBizRemesaCliente; overload; function Nuevo : IBizRemesaCliente; virtual; procedure Ver(ARemesaCliente : IBizRemesaCliente); virtual; procedure VerTodos(ARemesasCliente: IBizRemesaCliente); virtual; procedure Preview(ARemesaCliente : IBizRemesaCliente; AllItems: Boolean = false); virtual; procedure Print(ARemesaCliente : IBizRemesaCliente; AllItems: Boolean = false); virtual; function EsModificable(ARemesaProveedor : IBizRemesaCliente): Boolean; function EsEliminable(ARemesaProveedor : IBizRemesaCliente): Boolean; function ExtraerSeleccionados(ARemesasCliente: IBizRemesaCliente) : IBizRemesaCliente; virtual; function ElegirRecibosCliente(ARemesaCliente : IBizRemesaCliente; AListaRecibosIniciales: TStringList): Boolean; procedure EliminarReciboCliente(ARemesaCliente : IBizRemesaCliente); function DarListaAnosRemesas: TStringList; procedure FiltrarAno(ARemesa: IBizRemesaCliente; ADynWhereDataTable: WideString; const Ano: String); end; implementation uses cxControls, DB, uEditorRegistryUtils, schRemesasClienteClient_Intf, uFactuGES_App, schRecibosClienteClient_Intf, uIEditorRemesasCliente, uIEditorRemesaCliente, Dialogs, uDataModuleRemesasCliente, uDataModuleUsuarios, uDAInterfaces, uDataTableUtils, uDateUtils, uROTypes, DateUtils, Controls, Windows, uBizRecibosCliente, Variants, uRemesasClienteReportController; { TRemesasClienteController } procedure TRemesasClienteController.Anadir(ARemesaCliente: IBizRemesaCliente); begin ARemesaCliente.Insert; end; procedure TRemesasClienteController.EliminarReciboCliente(ARemesaCliente: IBizRemesaCliente); var ARecibosRemesa : IBizRecibosCliente; begin inherited; ARecibosRemesa := ARemesaCliente.Recibos; RecibosClienteController.QuitarRemesa(ARecibosRemesa); //Quitamos el recibo de la remesa sin que el servidor se entere para que no elimine el recibo DesconectarTabla(ARecibosRemesa.DataTable); ARecibosRemesa.DataTable.Delete; ConectarTabla(ARecibosRemesa.DataTable); ARecibosRemesa := Nil; end; function TRemesasClienteController.EsEliminable(ARemesaProveedor: IBizRemesaCliente): Boolean; begin Result := True; end; function TRemesasClienteController.EsModificable(ARemesaProveedor: IBizRemesaCliente): Boolean; begin Result := True; end; procedure TRemesasClienteController.AsignarDataModule; begin FDataModule := TDataModuleRemesasCliente.Create(Nil); FRecibosClienteController := TRecibosClienteController.Create; end; procedure TRemesasClienteController.AsignarID(ARemesaCliente: IBizRemesaCliente; const IDNuevo: Integer); begin if not Assigned(ARemesaCliente) then raise Exception.Create ('RemesaCliente no asignado'); ARemesaCliente.Edit; ARemesaCliente.ID := IDNuevo; ARemesaCliente.Post; end; function TRemesasClienteController.Buscar(const ID: Integer): IBizRemesaCliente; begin Result := (FDataModule as IDataModuleRemesasCliente).GetItem(ID); FiltrarEmpresa(Result); end; function TRemesasClienteController.BuscarTodos: IBizRemesaCliente; begin Result := FDataModule.GetItems; FiltrarEmpresa(Result); end; constructor TRemesasClienteController.Create; begin inherited; AsignarDataModule; end; function TRemesasClienteController.CreateEditor(const AName: String; const IID: TGUID; out Intf): Boolean; begin Result := Supports(EditorRegistry.CreateEditor(AName), IID, Intf); end; function TRemesasClienteController.DarListaAnosRemesas: TStringList; begin Result := FDataModule.GetAnosItems; end; procedure TRemesasClienteController.DescartarCambios(ARemesaCliente: IBizRemesaCliente); begin if not Assigned(ARemesaCliente) then raise Exception.Create ('RemesaCliente no asignado'); ShowHourglassCursor; try if (ARemesaCliente.State in dsEditModes) then ARemesaCliente.Cancel; ARemesaCliente.DataTable.CancelUpdates; finally HideHourglassCursor; end; end; destructor TRemesasClienteController.Destroy; begin FDataModule := Nil; FRecibosClienteController := Nil; inherited; end; function TRemesasClienteController.ValidarRemesaCliente(ARemesaCliente: IBizRemesaCliente): Boolean; begin Result := False; if not Assigned(ARemesaCliente) then raise Exception.Create ('Remesa no asignada'); if (ARemesaCliente.DataTable.State in dsEditModes) then ARemesaCliente.DataTable.Post; if ARemesaCliente.DataTable.FieldByName(fld_RemesasClienteFECHA_REMESA).IsNull then raise Exception.Create('Debe indicar la fecha de esta remesa.'); if ARemesaCliente.ID_DATOS_BANCO < 1 then raise Exception.Create('Debe la cuenta bancaria sobre la que realizará la remesa.'); // Asegurarse de valores en campos "automáticos" ARemesaCliente.Edit; try ARemesaCliente.USUARIO := AppFactuGES.UsuarioActivo.UserName; Result := True; finally ARemesaCliente.Post; end; end; procedure TRemesasClienteController.Ver(ARemesaCliente: IBizRemesaCliente); var AEditor : IEditorRemesaCliente; begin AEditor := NIL; RecuperarObjetos(ARemesaCliente); CreateEditor('EditorRemesaCliente', IEditorRemesaCliente, AEditor); if Assigned(AEditor) then try AEditor.Controller := Self; //OJO ORDEN MUY IMPORTANTE AEditor.RemesaCliente := ARemesaCliente; //MODO CONSULTAR if not EsModificable(ARemesaCliente) then begin SetDataTableReadOnly(ARemesaCliente.DataTable, True); AEditor.ReadOnly := True; end; AEditor.ShowModal; //MODO CONSULTAR (Se deja la tabla como estaba) if AEditor.ReadOnly then SetDataTableReadOnly(ARemesaCliente.DataTable, False); finally AEditor.Release; AEditor := NIL; end; end; procedure TRemesasClienteController.VerTodos(ARemesasCliente: IBizRemesaCliente); var AEditor : IEditorRemesasCliente; begin AEditor := NIL; CreateEditor('EditorRemesasCliente', IEditorRemesasCliente, AEditor); if Assigned(AEditor) then with (AEditor as IEditorRemesasCliente) do begin Controller := Self; //OJO ORDEN MUY IMPORTANTE RemesasCliente := ARemesasCliente; MultiSelect := True; ShowEmbedded; end; end; function TRemesasClienteController._Vacio: IBizRemesaCliente; begin Result := Buscar(ID_NULO); end; function TRemesasClienteController.Eliminar(const ID: Integer): Boolean; var ARemesaCliente : IBizRemesaCliente; begin ARemesaCliente := Buscar(ID); if not Assigned(ARemesaCliente) then raise Exception.Create(Format('No se ha encontrado la remesa con ID = %d', [ID])); Result := Eliminar(ARemesaCliente); ARemesaCliente := NIL; end; function TRemesasClienteController.ElegirRecibosCliente(ARemesaCliente: IBizRemesaCliente; AListaRecibosIniciales: TStringList): Boolean; var ARecibosRemesa : IBizRecibosCliente; ARecibosSeleccionados : IBizRecibosCliente; ListaRecibosVisibles: TStringList; ListaRecibosNoVisibles: TStringList; i: Integer; begin Result := False; ListaRecibosVisibles := TStringList.Create; ListaRecibosNoVisibles := TStringList.Create; //Todos los recibos que tenga la remesa no deben de visualizarse en la lista de seleccion ARemesaCliente.Recibos.DataTable.First; while not ARemesaCliente.Recibos.DataTable.eof do begin ListaRecibosNoVisibles.Add(IntToStr(ARemesaCliente.Recibos.ID)); ARemesaCliente.Recibos.DataTable.Next; end; ARemesaCliente.Recibos.DataTable.First; //Si de la lista inicial hay alguno que no se encuentre en la lista de recibos de la //remesa que tenemos en memoria dicho recibo debería verse por lo que lo añadimos a la lista de visibles for i := 0 to AListaRecibosIniciales.Count - 1 do begin ARemesaCliente.Recibos.DataTable.First; if not ARemesaCliente.Recibos.DataTable.Locate(fld_RecibosClienteID, AListaRecibosIniciales.strings[i], []) then ListaRecibosVisibles.Add(AListaRecibosIniciales.strings[i]); end; ARemesaCliente.Recibos.DataTable.First; ARecibosSeleccionados := (FRecibosClienteController.ElegirRecibos(FRecibosClienteController.BuscarRecibosARemesar(ListaRecibosVisibles, ListaRecibosNoVisibles), 'Elija uno o más recibos para incluirlos en esta remesa', True) as IBizRecibosCliente); if Assigned(ARecibosSeleccionados) then begin ShowHourglassCursor; try ARecibosRemesa := ARemesaCliente.Recibos; //Copia los recibos seleccionados a los recibos de la remesa sin que el servidor se entere de //las inserciones DuplicarRegistros(ARecibosSeleccionados.DataTable,ARecibosRemesa.DataTable, mdrTodos, True, False, True); FRecibosClienteController.SetSituacionCobrados(ARecibosRemesa); Result := True; finally HideHourglassCursor; end; end; ListaRecibosVisibles.Free; ListaRecibosNoVisibles.Free; ARecibosRemesa := Nil; ARecibosSeleccionados := Nil; end; function TRemesasClienteController.Eliminar(ARemesaCliente: IBizRemesaCliente; AllItems: Boolean = false): Boolean; //En el caso de eliminar almenos un elemento del conjunto se devuelve true var bEliminado: Boolean; begin Result := False; bEliminado := False; if not Assigned(ARemesaCliente) then raise Exception.Create ('ARemesaCliente no asignada'); ShowHourglassCursor; try if not ARemesaCliente.DataTable.Active then ARemesaCliente.DataTable.Active := True; if (ARemesaCliente.State in dsEditModes) then ARemesaCliente.Cancel; //Siempre eliminaremos el seleccionado if EsEliminable(ARemesaCliente) then begin //Si la llamada a eliminar es por el editor RemesasCliente, debo recuperar los recibos //de la remesa a eliminar, en caso de venir por el editor RemesaCliente ya los tengo if not Assigned(ARemesaCliente.Recibos) then RecuperarRecibos(ARemesaCliente); //Eliminaremos la remesa de los recibos asociados With ARemesaCliente.Recibos.DataTable do begin First; While not Eof do begin RecibosClienteController.QuitarRemesa(ARemesaCliente.Recibos); Next; end; end; //Como no están declarados como maestro-detalles debemos hacer el applyupdates nosotros ARemesaCliente.Recibos.DataTable.ApplyUpdates; ARemesaCliente.Delete; bEliminado := True; end; //En el caso de querer eliminar todos los items del objeto AAlbaran if AllItems then begin with ARemesaCliente.DataTable do begin First; while not EOF do begin if EsEliminable(ARemesaCliente) then begin //Si la llamada a eliminar es por el editor RemesasProveedor, debo recuperar los recibos //de la remesa a eliminar, en caso de venir por el editor RemesaCliente ya los tengo if not Assigned(ARemesaCliente.Recibos) then RecuperarRecibos(ARemesaCliente); //Eliminaremos la remesa de los recibos asociados With ARemesaCliente.Recibos.DataTable do begin First; While not Eof do begin RecibosClienteController.QuitarRemesa(ARemesaCliente.Recibos); Next; end; end; //Como no están declarados como maestro-detalles debemos hacer el applyupdates nosotros ARemesaCliente.Recibos.DataTable.ApplyUpdates; ARemesaCliente.Delete; bEliminado := True end else Next; end; end; end; if bEliminado then begin ARemesaCliente.DataTable.ApplyUpdates; Result := True; end else Result := False; HideHourglassCursor; except //Hay algun recibo de la remesa que tiene movimientos (Cobros/Devoluciones) posteriores al cobro inicial de la remesa on E: Exception do begin ARemesaCliente.Recibos.DataTable.CancelUpdates; ARemesaCliente.DataTable.CancelUpdates; HideHourglassCursor; MessageBox(0, 'Exiten movimientos (Cobros/Devoluciones) en los recibos posteriores al cobro inicial de la remesa', 'Atención', MB_ICONWARNING or MB_OK); end; end; end; procedure TRemesasClienteController.RecibirAviso(ASujeto: ISujeto; ADataTable: IDAStronglyTypedDataTable); begin inherited; // end; procedure TRemesasClienteController.RecuperarObjetos(ARemesaCliente: IBizRemesaCliente); begin RecuperarRecibos(ARemesaCliente); end; procedure TRemesasClienteController.RecuperarRecibos(ARemesaCliente: IBizRemesaCliente); begin ARemesaCliente.Recibos := RecibosClienteController.BuscarRecibosRemesa(ARemesaCliente.ID); end; function TRemesasClienteController.Existe(const ID: Integer): Boolean; var ARemesaCliente : IBizRemesaCliente; begin try ARemesaCliente := Buscar(ID); Result := Assigned(ARemesaCliente) and (ARemesaCliente.ID = ID); finally ARemesaCliente := NIL; end; end; function TRemesasClienteController.ExtraerSeleccionados(ARemesasCliente: IBizRemesaCliente): IBizRemesaCliente; var ASeleccionados : IBizRemesaCliente; begin ASeleccionados := (Self.Buscar(ID_NULO) as IBizRemesaCliente); CopyDataTableDA5(ARemesasCliente.DataTable, ASeleccionados.DataTable, True); Result := ASeleccionados; end; procedure TRemesasClienteController.FiltrarAno(ARemesa: IBizRemesaCliente; ADynWhereDataTable: WideString; const Ano: String); var Condicion: TDAWhereExpression; FechaIni: String; FechaFin: String; begin ARemesa.DataTable.DynamicWhere.Clear; ARemesa.DataTable.DynamicWhere.Xml := ADynWhereDataTable; if (Ano <> 'Todos') then begin // Filtrar las facturas actuales por empresa FechaIni := '01/01/' + Ano; FechaFin := '31/12/' + Ano; with ARemesa.DataTable.DynamicWhere do begin // (FECHA_INICIO between FECHA_FIN) Condicion := NewBinaryExpression(NewField('', fld_RemesasClienteFECHA_REMESA), NewConstant(FechaIni, datString), dboGreaterOrEqual); Condicion := NewBinaryExpression(NewBinaryExpression(NewField('', fld_RemesasClienteFECHA_REMESA), NewConstant(FechaFin, datString), dboLessOrEqual), Condicion, dboAnd); if IsEmpty then Expression := Condicion else Expression := NewBinaryExpression(Condicion, Expression, dboAnd); end; end; end; procedure TRemesasClienteController.FiltrarEmpresa(ARemesaCliente: IBizRemesaCliente); var Condicion: TDAWhereExpression; begin if ARemesaCliente.DataTable.Active then ARemesaCliente.DataTable.Active := False; // Filtrar las remesas actuales por empresa with ARemesaCliente.DataTable.DynamicWhere do begin // (ID_EMPRESA >= ID) Condicion := NewBinaryExpression(NewField('', fld_RemesasClienteID_EMPRESA), NewConstant(AppFactuGES.EmpresaActiva.ID, datInteger), dboEqual); if IsEmpty then Expression := Condicion else Expression := NewBinaryExpression(Expression, Condicion, dboAnd); end; end; function TRemesasClienteController.GetRecibosClienteController: IRecibosClienteController; begin Result := FRecibosClienteController; end; function TRemesasClienteController.Guardar(ARemesaCliente: IBizRemesaCliente): Boolean; var bEsNuevo: Boolean; begin Result := False; if ValidarRemesaCliente(ARemesaCliente) then begin ShowHourglassCursor; try bEsNuevo := ARemesaCliente.EsNuevo; //Si es nuevo debemos hacer el applyupdates por la integridad referencial de BD if bEsNuevo then ARemesaCliente.DataTable.ApplyUpdates; //Si todo ha ido bien, asignamos la remesa a los recibos asociados //Como no están declarados como maestro-detalles debemos hacer el applyupdates nosotros RecibosClienteController.AsignarRemesa(ARemesaCliente.Recibos, ARemesaCliente.ID); ARemesaCliente.Recibos.DataTable.ApplyUpdates; //En este applyupdates tambien se realizarán todos los cambios acumulados sobre los recibos asociados (EliminarReciboCliente/ ElegirRecibosCliente) //Es necesario ya que no se refrescan bien los deltas y despues del applyupdates siguen //existiendo deltas, de esta forma los limpiamos if ARemesaCliente.Recibos.DataTable.HasDelta then ARemesaCliente.Recibos.DataTable.Refresh; ARemesaCliente.DataTable.ApplyUpdates; Result := True; finally HideHourglassCursor; end; end; end; function TRemesasClienteController.Nuevo: IBizRemesaCliente; var ARemesaCliente : IBizRemesaCliente; begin ARemesaCliente := FDataModule.NewItem; FiltrarEmpresa(ARemesaCliente); ARemesaCliente.DataTable.Active := True; ARemesaCliente.Insert; Result := ARemesaCliente; end; procedure TRemesasClienteController.Preview(ARemesaCliente: IBizRemesaCliente; AllItems: Boolean = false); var AReportController : IRemesasClienteReportController; ID_Remesas: TStringList; begin AReportController := TRemesasClienteReportController.Create; ID_Remesas := TStringList.Create; try //Si deseamos previsualizar todos los items del objeto albaran if AllItems then begin with ARemesaCliente.DataTable do begin First; while not EOF do begin ID_Remesas.Add(IntToStr(ARemesaCliente.ID)); Next; end; end; end //Solo previsualizamos el item seleccionado else ID_Remesas.Add(IntToStr(ARemesaCliente.ID)); AReportController.Preview(ID_Remesas.CommaText); finally AReportController := NIL; ID_Remesas.Free; end; end; procedure TRemesasClienteController.Print(ARemesaCliente: IBizRemesaCliente; AllItems: Boolean = false); var AReportController : IRemesasClienteReportController; ID_Remesas: TStringList; begin AReportController := TRemesasClienteReportController.Create; ID_Remesas := TStringList.Create; try //Si deseamos previsualizar todos los items del objeto albaran if AllItems then begin with ARemesaCliente.DataTable do begin First; while not EOF do begin ID_Remesas.Add(IntToStr(ARemesaCliente.ID)); Next; end; end; end //Solo previsualizamos el item seleccionado else ID_Remesas.Add(IntToStr(ARemesaCliente.ID)); AReportController.Print(ID_Remesas.CommaText); finally AReportController := NIL; ID_Remesas.Free; end; end; end.