{ =============================================================================== Copyright (©) 2007. Rodax Software. =============================================================================== Los contenidos de este fichero son propiedad de Rodax Software titular del copyright. Este fichero sólo podrá ser copiado, distribuido y utilizado, en su totalidad o en parte, con el permiso escrito de Rodax Software, o de acuerdo con los términos y condiciones establecidas en el acuerdo/contrato bajo el que se suministra. ----------------------------------------------------------------------------- Web: www.rodax-software.com =============================================================================== Fecha primera versión: Versión actual: 1.0.0 Fecha versión actual: =============================================================================== Modificaciones: Fecha Comentarios --------------------------------------------------------------------------- =============================================================================== } unit uRecibosClienteController; interface uses Classes, SysUtils, uDADataTable, uControllerBase, uPagosClienteController, uBizRecibosCliente, uIDataModuleRecibosCliente; type IRecibosClienteController = interface(IObservador) ['{CBC8BDB8-FBE0-4D54-B2F1-A9330E8339EB}'] function GetPagosController: IPagosClienteController; procedure SetPagosController(const Value: IPagosClienteController); property PagosController: IPagosClienteController read GetPagosController write SetPagosController; procedure Anadir(ARecibosCliente : IBizRecibosCliente); function AnadirPago(ARecibosCliente : IBizRecibosCliente; Const Fecha: String = ''): Boolean; procedure ModificarPago(ARecibosCliente : IBizRecibosCliente; Const Fecha: String); function Eliminar(ARecibosCliente : IBizRecibosCliente): Boolean; function EliminarPago(ARecibosCliente : IBizRecibosCliente): Boolean; function EliminarTodo(ARecibosCliente : IBizRecibosCliente): Boolean; procedure Guardar(ARecibosCliente : IBizRecibosCliente); procedure DescartarCambios(ARecibosCliente : IBizRecibosCliente); function Duplicar(ARecibosCliente: IBizRecibosCliente): IBizRecibosCliente; function Nuevo : IBizRecibosCliente; function Buscar(const ID: Integer): IBizRecibosCliente; function BuscarTodosRemesa(const ID_REMESA: Integer): IBizRecibosCliente; function BuscarTodosFactura(const ID_FACTURA: Integer): IBizRecibosCliente; function BuscarTodos: IBizRecibosCliente; function BuscarTodosPendientesSinRemesa: IBizRecibosCliente; procedure VerTodos(ARecibosCliente: IBizRecibosCliente); procedure Ver(ARecibosCliente: IBizRecibosCliente); function Localizar(ARecibosCliente: IBizRecibosCliente; ADescripcion:String): Boolean; function DarListaRecibosCliente: TStringList; function ExtraerSeleccionados(ARecibosCliente: IBizRecibosCliente) : IBizRecibosCliente; function ElegirRecibos(ARecibos : IBizRecibosCliente; AMensaje: String; AMultiSelect: Boolean): IBizRecibosCliente; procedure AsignarRemesa(ARecibos : IBizRecibosCliente; ID_REMESA: Integer); procedure QuitarRemesa(ARecibos : IBizRecibosCliente); // Descomentar esto si hay informe // procedure Preview(ARecibosCliente : IBizRecibosCliente); // procedure Print(ARecibosCliente : IBizRecibosCliente); end; TRecibosClienteController = class(TObservador, IRecibosClienteController) protected FDataModule : IDataModuleRecibosCliente; FPagosController : IPagosClienteController; function GetPagosController: IPagosClienteController; procedure SetPagosController(const Value: IPagosClienteController); procedure RecibirAviso(ASujeto: ISujeto; ADataTable: IDAStronglyTypedDataTable); override; function _Vacio : IBizRecibosCliente; function ValidarReciboCliente(ARecibosCliente: IBizRecibosCliente): Boolean; procedure AsignarDataModule; procedure AsignarID(ARecibosCliente: IBizRecibosCliente; const IDNuevo: Integer); function DarNuevaReferencia(ID_FACTURA : Integer; REFERENCIA: String): String; public property PagosController: IPagosClienteController read GetPagosController write SetPagosController; constructor Create; virtual; destructor Destroy; override; procedure Anadir(ARecibosCliente : IBizRecibosCliente); function AnadirPago(ARecibosCliente : IBizRecibosCliente; Const Fecha: String = ''): Boolean; procedure ModificarPago(ARecibosCliente : IBizRecibosCliente; Const Fecha: String); function Eliminar(ARecibosCliente : IBizRecibosCliente): Boolean; function EliminarPago(ARecibosCliente : IBizRecibosCliente): Boolean; function EliminarTodo(ARecibosCliente : IBizRecibosCliente): Boolean; procedure Guardar(ARecibosCliente : IBizRecibosCliente); procedure DescartarCambios(ARecibosCliente : IBizRecibosCliente); function Duplicar(ARecibosCliente: IBizRecibosCliente): IBizRecibosCliente; function Nuevo : IBizRecibosCliente; function Buscar(const ID: Integer): IBizRecibosCliente; function BuscarTodosRemesa(const ID_REMESA: Integer): IBizRecibosCliente; function BuscarTodosFactura(const ID_FACTURA: Integer): IBizRecibosCliente; function BuscarTodos: IBizRecibosCliente; function BuscarTodosPendientesSinRemesa: IBizRecibosCliente; procedure VerTodos(ARecibosCliente: IBizRecibosCliente); procedure Ver(ARecibosCliente: IBizRecibosCliente); function Localizar(ARecibosCliente: IBizRecibosCliente; ADescripcion:String): Boolean; function DarListaRecibosCliente: TStringList; function ExtraerSeleccionados(ARecibosCliente: IBizRecibosCliente) : IBizRecibosCliente; function ElegirRecibos(ARecibos : IBizRecibosCliente; AMensaje: String; AMultiSelect: Boolean): IBizRecibosCliente; procedure AsignarRemesa(ARecibos : IBizRecibosCliente; ID_REMESA: Integer); procedure QuitarRemesa(ARecibos : IBizRecibosCliente); // Descomentar esto si hay informe // procedure Preview(ARecibosCliente : IBizRecibosCliente); // procedure Print(ARecibosCliente : IBizRecibosCliente); end; implementation uses cxControls, DB, uEditorRegistryUtils,Dialogs, uDAInterfaces, uDataTableUtils, uDataModuleUsuarios, uDateUtils, uROTypes, DateUtils, Controls, Windows, Variants, // Descomentar esto si hay informe // uRecibosClienteReportController, schRecibosClienteClient_Intf, uIEditorRecibosCliente, uIEditorReciboCliente, uIEditorElegirRecibosCliente, uDataModuleRecibosCliente; { TRecibosClienteController } procedure TRecibosClienteController.Anadir(ARecibosCliente: IBizRecibosCliente); begin ARecibosCliente.Insert; end; function TRecibosClienteController.AnadirPago(ARecibosCliente: IBizRecibosCliente; Const Fecha: String = ''): Boolean; begin Result := PagosController.Anadir(ARecibosCliente.Pagos, Fecha); end; procedure TRecibosClienteController.AsignarDataModule; begin FDataModule := TDataModuleRecibosCliente.Create(Nil); end; procedure TRecibosClienteController.AsignarID(ARecibosCliente: IBizRecibosCliente; const IDNuevo: Integer); var AContador : Integer; begin if not Assigned(ARecibosCliente) then raise Exception.Create ('IBizRecibosCliente no asignado'); if not Assigned(ARecibosCliente.Pagos) then raise Exception.Create ('Pagos del recibo no asignados'); if not Assigned(FPagosController) then raise Exception.Create ('Controller pagos no asignado'); { Los detalles hay que comprobarlos siempre tanto en inserción como en modificación. } if Assigned(ARecibosCliente.Pagos) then FPagosController.AsignarID(ARecibosCliente.Pagos, IDNuevo, ARecibosCliente.EsNuevo); if ARecibosCliente.EsNuevo then begin ARecibosCliente.Edit; ARecibosCliente.ID := IDNuevo; ARecibosCliente.Post; end; end; procedure TRecibosClienteController.AsignarRemesa(ARecibos: IBizRecibosCliente; ID_REMESA: Integer); begin if Assigned(ARecibos) then begin With ARecibos.DataTable do begin First; While not eof do begin ARecibos.Edit; ARecibos.ID_REMESA := ID_REMESA; //Añadimos el cobro automatico por la remesa y volvemos a asignar ID //para que asigne un ID nuevo para el pago, porque aqui si hay maestro-detalle AnadirPago(ARecibos); AsignarID(ARecibos, ARecibos.ID); ARecibos.Post; Next; end; end; end; end; function TRecibosClienteController.BuscarTodos: IBizRecibosCliente; begin Result := FDataModule.GetItems; end; constructor TRecibosClienteController.Create; begin inherited; AsignarDataModule; FPagosController := TPagosClienteController.Create; // FPagosController.addObservador(Self); //PETA NO SE PORQUE end; function TRecibosClienteController.Buscar(const ID: Integer): IBizRecibosCliente; begin Result := (FDataModule as IDataModuleRecibosCliente).GetItem(ID); end; function TRecibosClienteController.BuscarTodosFactura(const ID_FACTURA: Integer): IBizRecibosCliente; begin ShowHourglassCursor; try Result := BuscarTodos; with Result.DataTable.Where do begin if NotEmpty then AddOperator(opAND); OpenBraket; AddText(fld_RecibosClienteID_FACTURA + ' = ' + IntToStr(ID_FACTURA)); CloseBraket; end; finally HideHourglassCursor; end; end; function TRecibosClienteController.BuscarTodosPendientesSinRemesa: IBizRecibosCliente; begin ShowHourglassCursor; try Result := BuscarTodos; with Result.DataTable.Where do begin if NotEmpty then AddOperator(opAND); OpenBraket; AddText(fld_RecibosClienteID_REMESA + ' IS NULL AND ' + fld_RecibosClienteSITUACION + ' = ''' + CTE_PENDIENTE + ''''); CloseBraket; end; finally HideHourglassCursor; end; end; function TRecibosClienteController.BuscarTodosRemesa(const ID_REMESA: Integer): IBizRecibosCliente; begin ShowHourglassCursor; try Result := BuscarTodos; with Result.DataTable.Where do begin if NotEmpty then AddOperator(opAND); OpenBraket; AddText(fld_RecibosClienteID_REMESA + ' = ' + IntToStr(ID_REMESA)); CloseBraket; end; finally HideHourglassCursor; end; end; function TRecibosClienteController._Vacio: IBizRecibosCliente; begin Result := Buscar(ID_NULO); end; function TRecibosClienteController.DarListaRecibosCliente: TStringList; var ARecibosCliente: IBizRecibosCliente; begin ARecibosCliente := BuscarTodos; ARecibosCliente.DataTable.Active := True; Result := TStringList.Create; try with Result do begin ARecibosCliente.DataTable.First; while not ARecibosCliente.DataTable.EOF do begin Add(ARecibosCliente.DESCRIPCION); ARecibosCliente.DataTable.Next; end; end; finally ARecibosCliente := NIL; end; end; function TRecibosClienteController.DarNuevaReferencia(ID_FACTURA: Integer; REFERENCIA: String): String; var ARecibosCliente: IBizRecibosCliente; NumReferencia : Integer; Cadena : String; begin try ARecibosCliente := BuscarTodosFactura(ID_FACTURA); ARecibosCliente.DataTable.Active := True; NumReferencia := ARecibosCliente.DataTable.RecordCount; Cadena := Copy(REFERENCIA, 0, Pos('-', REFERENCIA)); Result := Cadena + ' ' + IntToStr((NumReferencia + 1)); finally ARecibosCliente := Nil; end; end; procedure TRecibosClienteController.DescartarCambios(ARecibosCliente: IBizRecibosCliente); begin if not Assigned(ARecibosCliente) then raise Exception.Create ('IBizRecibosCliente no asignado'); ShowHourglassCursor; try if (ARecibosCliente.State in dsEditModes) then ARecibosCliente.Cancel; ARecibosCliente.DataTable.CancelUpdates; finally HideHourglassCursor; end; end; destructor TRecibosClienteController.Destroy; begin FDataModule := NIL; FPagosController := NIL; inherited; end; function TRecibosClienteController.Duplicar(ARecibosCliente: IBizRecibosCliente): IBizRecibosCliente; begin Result := Self._Vacio; ShowHourglassCursor; try DuplicarRegistros(ARecibosCliente.DataTable, Result.DataTable, mdrActual); // Descomentar esto si hay detalles // (EN ESTE CASO NO NOS INTERESA COPIAR LOS PAGOS DEL RECIBO DUPLIACDO) // DuplicarRegistros(ARecibosCliente.Detalles.DataTable, Result.Detalles.DataTable, mdrTodos); // ¡CUIDADO! Hay que dejar algunos campos como si fuera todo nuevo Result.Edit; with Result do begin // Ejemplos // ID_EMPRESA := dmUsuarios.IDEmpresaActual; // USUARIO := dmUsuarios.LoginInfo.Usuario; // REFERENCIA := ''; //Para que se asigne una nueva // FECHA_FACTURA := DateOf(Now); // SITUACION := SITUACION_PENDIENTE; end; Result.Post; finally HideHourglassCursor; end; end; function TRecibosClienteController.ValidarReciboCliente(ARecibosCliente: IBizRecibosCliente): Boolean; var ImporteRestante: Double; begin Result := False; if not Assigned(ARecibosCliente) then raise Exception.Create ('IBizRecibosCliente no asignado'); if (ARecibosCliente.DataTable.State in dsEditModes) then ARecibosCliente.DataTable.Post; // Tambien hacemos post de sus tablas hija if (ARecibosCliente.Pagos.DataTable.State in dsEditModes) then ARecibosCliente.Pagos.DataTable.Post; //Validaciones { Asegurarse de valores en campos "automáticos" tanto en MODIFICACIÓN como en INSERCIÓN. } ARecibosCliente.Edit; try ARecibosCliente.USUARIO := dmUsuarios.LoginInfo.Usuario; Result := True; finally ARecibosCliente.Post; end; Result := True; end; procedure TRecibosClienteController.Ver(ARecibosCliente: IBizRecibosCliente); var AEditor : IEditorReciboCliente; begin AEditor := NIL; ShowHourglassCursor; try CreateEditor('EditorReciboCliente', IEditorReciboCliente, AEditor); with AEditor do begin Controller := Self; //OJO ORDEN MUY IMPORTANTE Recibo := ARecibosCliente; end; finally HideHourglassCursor; end; if Assigned(AEditor) then try AEditor.ShowModal; AEditor.Release; finally AEditor := NIL; end; end; procedure TRecibosClienteController.VerTodos(ARecibosCliente: IBizRecibosCliente); var AEditor : IEditorRecibosCliente; begin AEditor := NIL; ShowHourglassCursor; try CreateEditor('EditorRecibosCliente', IEditorRecibosCliente, AEditor); with AEditor do RecibosCliente := ARecibosCliente; finally HideHourglassCursor; end; if Assigned(AEditor) then try AEditor.ShowEmbedded; finally AEditor := NIL; end; end; function TRecibosClienteController.ElegirRecibos(ARecibos: IBizRecibosCliente; AMensaje: String; AMultiSelect: Boolean): IBizRecibosCliente; var AEditor : IEditorElegirRecibosCliente; begin Result := NIL; CreateEditor('EditorElegirRecibosCliente', IEditorElegirRecibosCliente, AEditor); try with AEditor do begin Controller := Self; RecibosCliente := ARecibos; MultiSelect := AMultiSelect; Mensaje := AMensaje; if IsPositiveResult(ShowModal) then Result := RecibosClienteSeleccionados; Release; end; finally AEditor := NIL; end; end; function TRecibosClienteController.Eliminar(ARecibosCliente: IBizRecibosCliente): Boolean; begin Result := False; if not Assigned(ARecibosCliente) then raise Exception.Create ('IBizRecibosCliente no asignado'); ShowHourglassCursor; try if (ARecibosCliente.State in dsEditModes) then ARecibosCliente.Cancel; ARecibosCliente.Delete; ARecibosCliente.DataTable.ApplyUpdates; HideHourglassCursor; Result := True; finally HideHourglassCursor; end; end; function TRecibosClienteController.EliminarPago(ARecibosCliente: IBizRecibosCliente): Boolean; begin Result := PagosController.Eliminar(ARecibosCliente.Pagos); end; function TRecibosClienteController.EliminarTodo(ARecibosCliente: IBizRecibosCliente): Boolean; begin if Assigned(ARecibosCliente) then begin if not ARecibosCliente.DataTable.Active then ARecibosCliente.DataTable.Active := True; ARecibosCliente.DataTable.ClearRows; ARecibosCliente.DataTable.ApplyUpdates; end; end; procedure TRecibosClienteController.RecibirAviso(ASujeto: ISujeto; ADataTable: IDAStronglyTypedDataTable); // Descomentar si hubiera detalles {var ARecibosCliente : IBizRecibosCliente; ADetalles : IBizDetallesIBizRecibosCliente;} begin inherited; // Descomentar si hubiera detalles {if Supports(ADataTable, IBizDetallesIBizRecibosCliente, ADetalles) and Supports(ADetalles.DataTable.MasterSource.DataTable, IBizRecibosCliente, ARecibosCliente) then begin ARecibosCliente.Edit; try ARecibosCliente.IMPORTE_TOTAL := FDetallesController.DarTotalImporteTotal(ADetalles); finally ARecibosCliente.Post; end; end;} end; function TRecibosClienteController.GetPagosController: IPagosClienteController; begin Result := FPagosController; end; procedure TRecibosClienteController.SetPagosController(const Value: IPagosClienteController); begin FPagosController := Value; end; procedure TRecibosClienteController.Guardar(ARecibosCliente: IBizRecibosCliente); var NuevoID : Integer; ANuevoReciboCliente : IBizRecibosCliente; CambioImporte: TDADeltaChange; ImporteRestante : Double; begin if ValidarReciboCliente(ARecibosCliente) then begin ShowHourglassCursor; try if ARecibosCliente.EsNuevo then NuevoID := FDataModule.GetNextID(ARecibosCliente.DataTable.LogicalName) else NuevoID := ARecibosCliente.ID; //Si el importe ha cambiado se debe hacer un recibo nuevo con el importe restante ImporteRestante := 0; CambioImporte := ARecibosCliente.DataTable.Delta.FindChange(ARecibosCliente.RecNo); if (Assigned(CambioImporte)) and (CambioImporte.OldValueByName[fld_RecibosClienteIMPORTE] <> 0) then ImporteRestante := CambioImporte.OldValueByName[fld_RecibosClienteIMPORTE] - ARecibosCliente.IMPORTE; if ImporteRestante > 0 then begin ANuevoReciboCliente := Duplicar(ARecibosCliente); ANuevoReciboCliente.Edit; ANuevoReciboCliente.REFERENCIA := DarNuevaReferencia(ARecibosCliente.ID_FACTURA, ARecibosCliente.REFERENCIA); ANuevoReciboCliente.DESCRIPCION := 'RECIBO ' + ANuevoReciboCliente.REFERENCIA; ANuevoReciboCliente.ID := FDataModule.GetNextID(ARecibosCliente.DataTable.LogicalName); ANuevoReciboCliente.IMPORTE := ImporteRestante; ANuevoReciboCliente.Post; end; AsignarID(ARecibosCliente, NuevoID); ARecibosCliente.DataTable.ApplyUpdates; //Primero debemos hacer el ApplyUpdates del recibo inicial por si fallase //Así no se haría el nuevo if Assigned(ANuevoReciboCliente) then ANuevoReciboCliente.DataTable.ApplyUpdates; finally ANuevoReciboCliente := Nil; HideHourglassCursor; end; end; end; function TRecibosClienteController.Localizar(ARecibosCliente: IBizRecibosCliente; ADescripcion: String): Boolean; begin Result := True; ShowHourglassCursor; try with ARecibosCliente.DataTable do begin DisableControls; First; if not Locate(fld_RecibosClienteDESCRIPCION, ADescripcion, []) then Result := False; EnableControls; end; finally HideHourglassCursor; end; end; procedure TRecibosClienteController.ModificarPago(ARecibosCliente: IBizRecibosCliente; const Fecha: String); begin PagosController.Modificar(ARecibosCliente.Pagos, Fecha); end; function TRecibosClienteController.Nuevo: IBizRecibosCliente; var ARecibo : IBizRecibosCliente; begin ARecibo := Buscar(ID_NULO); ARecibo.DataTable.Active := True; Anadir(ARecibo); Result := ARecibo; end; procedure TRecibosClienteController.QuitarRemesa(ARecibos: IBizRecibosCliente); begin if Assigned(ARecibos) then begin //Eliminamos el cobro generado por la remesa y quitamos el ID_REMESA del recibo if ARecibos.Pagos.DataTable.RecordCount = 1 then begin ARecibos.Pagos.Delete; ARecibos.DataTable.Edit; ARecibos.DataTable.FieldByName(fld_RecibosClienteID_REMESA).AsVariant := Null; ARecibos.DataTable.Post; end else raise Exception.Create('El recibo a eliminar tiene devoluciones o cobros posteriores al cobro inicial generado por la remesa, antes debe eliminar dichos movimientos, para poder quitar el recibo de la remesa') end; end; function TRecibosClienteController.ExtraerSeleccionados(ARecibosCliente: IBizRecibosCliente): IBizRecibosCliente; var ASeleccionados : IBizRecibosCliente; begin ASeleccionados := (Self.Buscar(ID_NULO) as IBizRecibosCliente); CopyDataTable(ARecibosCliente.DataTable, ASeleccionados.DataTable, True); Result := ASeleccionados; end; // Descomentar esto si hay informe // procedure TRecibosClienteController.Preview(ARecibosCliente: IBizRecibosCliente); // var // AReportController : IRecibosClienteReportController; // begin // AReportController := TRecibosClienteReportController.Create; // try // AReportController.Preview(ARecibosCliente.ID); // finally // AReportController := NIL; // end; // end; // Descomentar esto si hay informe // procedure TRecibosClienteController.Print(ARecibosCliente: IBizRecibosCliente); // var // AReportController : IRecibosClienteReportController; // begin // AReportController := TRecibosClienteReportController.Create; // try // AReportController.Print(ARecibosCliente.ID); // finally // AReportController := NIL; // end; // end; end.