unit uComisionesController; interface uses Classes, SysUtils, uDADataTable, uControllerBase, uEditorDBItem, uIDataModuleComisiones, uBizComisiones, uFacturasClienteController, uBizFacturasCliente; type IComisionesController = interface(IObservador) ['{0C281A5D-9DF9-46BD-99CB-1150A536EFA1}'] function BuscarTodos: IBizComisiones; procedure VerTodos(AComision: IBizComisiones); procedure Ver(AComision: IBizComisiones); function Anadir(AComision : IBizComisiones): Boolean; function Eliminar(AComision : IBizComisiones): Boolean; function Guardar(AComision : IBizComisiones): Boolean; procedure DescartarCambios(AComision : IBizComisiones); procedure Preview(AComision : IBizComisiones; const DesglosadoProv: Boolean); procedure Print(AComision : IBizComisiones; const DesglosadoProv: Boolean); function ElegirFacturasComision(AComision : IBizComisiones): Boolean; procedure EliminarFactura(AComision : IBizComisiones); procedure AsignarImporteTotal(AComision : IBizComisiones; Const ImporteTotal: Variant); end; TComisionesController = class(TObservador, IComisionesController) private function BuscarFacturasDesglosadas(AFacturas: IBizFacturaCliente): IBizFacturasComision; // procedure QuitarExistentes(AFacturas: IBizFacturaCliente; AFacturasComision: IBizFacturasComision); protected FDataModule : IDataModuleComisiones; FFacturasClienteController: IFacturasClienteController; procedure RecibirAviso(ASujeto: ISujeto; ADataTable: IDAStronglyTypedDataTable); override; function CreateEditor(const AName : String; const IID: TGUID; out Intf): Boolean; function ValidarComision(AComision: IBizComisiones): Boolean; procedure AsignarID(AComision: IBizComisiones; const IDNuevo: Integer); procedure AsignarIDDetalles(AFacturasComision: IBizFacturasComision; IDComision: Integer; AEsNuevo: Boolean); //Estos son los tres métodos a sobre escribir si se desea heredar toda la logica de //este controller procedure AsignarDataModule; virtual; public constructor Create; virtual; destructor Destroy; override; function Eliminar(AComision : IBizComisiones): Boolean; function Guardar(AComision : IBizComisiones): Boolean; procedure DescartarCambios(AComision : IBizComisiones); function Anadir(AComision : IBizComisiones): Boolean; function BuscarTodos: IBizComisiones; procedure VerTodos(AComision: IBizComisiones); procedure Ver(AComision: IBizComisiones); procedure Preview(AComision : IBizComisiones; const DesglosadoProv: Boolean); procedure Print(AComision : IBizComisiones; const DesglosadoProv: Boolean); function ElegirFacturasComision(AComision : IBizComisiones): Boolean; procedure EliminarFactura(AComision : IBizComisiones); procedure AsignarImporteTotal(AComision : IBizComisiones; Const ImporteTotal: Variant); end; implementation uses Variants, Dialogs, cxControls, DB, uEditorRegistryUtils, schComisionesClient_Intf, uIEditorComisiones, uDataModuleComisiones, uDataModuleUsuarios, uDAInterfaces, uDataTableUtils, uIEditorComision, uComisionesReportController, uDateUtils, uROTypes, DateUtils, Controls, Windows, uDialogUtils; { TComisionesController } function TComisionesController.Anadir(AComision: IBizComisiones): Boolean; begin if not Assigned(AComision) then raise Exception.Create ('Comision no asignado (Anadir)'); if not AComision.DataTable.Active then AComision.DataTable.Active := True; AComision.Insert; Result := True; end; procedure TComisionesController.AsignarDataModule; begin FDataModule := TDataModuleComisiones.Create(Nil); end; procedure TComisionesController.AsignarID(AComision: IBizComisiones; const IDNuevo: Integer); begin if not Assigned(AComision) then raise Exception.Create ('Comision no asignado'); AsignarIDDetalles(AComision.Facturas, IDNuevo, AComision.EsNuevo); if AComision.EsNuevo then begin AComision.Edit; AComision.ID := IDNuevo; AComision.Post; end; end; procedure TComisionesController.AsignarIDDetalles(AFacturasComision: IBizFacturasComision; IDComision: Integer; AEsNuevo: Boolean); begin with AFacturasComision do begin DataTable.DisableControls; try begin if not DataTable.Active then DataTable.Active := True; { ¡¡¡¡ OJO !!!! Para asignar el ID en los detalles 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_PRESUPUESTO. Por esa razón no sirve hacer un recorrido desde el principio hasta el final porque las detalles 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 detalles. Cuando el RecordCount llegue a 0 quiere decir que hemos tratado todos los detalles. El bucle cambia en el caso de ser llamada esta funcion desde modificar un presupuesto ya que en ese caso si 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_COMISION_LIQUIDADA := IdComision; Post end end else begin DataTable.First; while not DataTable.EOF do begin if ID_COMISION_LIQUIDADA < 0 then begin Edit; ID_COMISION_LIQUIDADA := IdComision; Post end; DataTable.Next end; end; end; finally DataTable.EnableControls; end; end; end; procedure TComisionesController.AsignarImporteTotal(AComision: IBizComisiones; const ImporteTotal: Variant); begin if Assigned(AComision) then begin if (not VarIsNull(ImporteTotal)) and (AComision.DataTable.FieldByName(fld_ComisionesIMPORTE_TOTAL).IsNull or (AComision.IMPORTE_TOTAL <> ImporteTotal)) then begin AComision.Edit; AComision.IMPORTE_TOTAL := ImporteTotal; AComision.Post; end; end; end; function TComisionesController.BuscarFacturasDesglosadas(AFacturas: IBizFacturaCliente): IBizFacturasComision; var Cadena: String; begin if Assigned(AFacturas) then begin with AFacturas.DataTable do begin if not Active then Active := True; First; Cadena := ''; While not Eof do begin if (Length(Cadena) > 0) then Cadena := Cadena + ', '; Cadena := Cadena + IntToStr(AFacturas.ID); Next; end; end; end; // Showmessage(Cadena); Result := FDataModule.GetFacturasDesglosadas; with Result.DataTable.Where do begin if NotEmpty then AddOperator(opAND); OpenBraket; AddText('ID_FACTURA in (' + Cadena + ')'); CloseBraket; end; end; function TComisionesController.BuscarTodos: IBizComisiones; begin Result := FDataModule.GetItems; end; constructor TComisionesController.Create; begin AsignarDataModule; FFacturasClienteController := TFacturasClienteController.Create; end; function TComisionesController.CreateEditor(const AName: String; const IID: TGUID; out Intf): Boolean; begin Result := Supports(EditorRegistry.CreateEditor(AName), IID, Intf); end; procedure TComisionesController.DescartarCambios(AComision: IBizComisiones); begin if not Assigned(AComision) then raise Exception.Create ('Almacen no asignado'); ShowHourglassCursor; try if (AComision.State in dsEditModes) then AComision.Cancel; AComision.DataTable.CancelUpdates; finally HideHourglassCursor; end; end; destructor TComisionesController.Destroy; begin FFacturasClienteController := Nil; FDataModule := Nil; inherited; end; function TComisionesController.ValidarComision(AComision: IBizComisiones): Boolean; var AFechaPagado : TDateTime; begin Result := False; if not Assigned(AComision) then raise Exception.Create ('Comision no asignada'); if (AComision.DataTable.State in dsEditModes) then AComision.DataTable.Post; if AComision.DataTable.FieldByName(fld_ComisionesID_AGENTE).IsNull then raise Exception.Create('Debe indicar el agente de esta liquidación de comisiones.'); if AComision.DataTable.FieldByName(fld_ComisionesFECHA).IsNull then raise Exception.Create('Debe indicar la fecha de esta liquidación de comisiones.'); if AComision.DataTable.FieldByName(fld_ComisionesDESCRIPCION).IsNull then raise Exception.Create('Debe indicar una descripción para la liquidación de comisión.'); // Asegurarse de valores en campos "automáticos" AComision.Edit; try AComision.USUARIO := dmUsuarios.LoginInfo.Usuario; Result := True; finally AComision.Post; end; end; procedure TComisionesController.Ver(AComision: IBizComisiones); var AEditor : IEditorComision; begin AEditor := NIL; ShowHourglassCursor; try // RecuperarObjetos(ARemesaCliente); CreateEditor('EditorComision', IEditorComision, AEditor); with (AEditor as IEditorComision) do begin Controller := Self; //OJO ORDEN MUY IMPORTANTE Comision := AComision; end; finally HideHourglassCursor; end; if Assigned(AEditor) then try AEditor.ShowModal; AEditor.Release; finally AEditor := NIL; end; end; procedure TComisionesController.VerTodos(AComision: IBizComisiones); var AEditor : IEditorComisiones; begin AEditor := NIL; ShowHourglassCursor; try CreateEditor('EditorComisiones', IEditorComisiones, AEditor); with AEditor do begin Controller := Self; //OJO ORDEN MUY IMPORTANTE Comisiones := AComision; end; finally HideHourglassCursor; end; if Assigned(AEditor) then try AEditor.ShowEmbedded; finally AEditor := NIL; end; end; function TComisionesController.ElegirFacturasComision(AComision: IBizComisiones): Boolean; var AFacturasAgente : IBizFacturaCliente; AFacturasSeleccionadas : IBizFacturaCliente; AFacturasDesglosadas: IBizFacturasComision; Cadena: String; begin Result := False; if (AComision.ID_AGENTE <> 0) then begin if Assigned(AComision.Facturas) then begin with AComision.Facturas.DataTable do begin if not Active then Active := True; First; Cadena := ''; While not Eof do begin if (Length(Cadena) > 0) then Cadena := Cadena + ', '; Cadena := Cadena + IntToStr(AComision.Facturas.ID_FACTURA); Next; end; end; end; AFacturasAgente := FFacturasClienteController.BuscarTodasPendientesComision(AComision.ID_AGENTE, AComision.ID, Cadena); AFacturasSeleccionadas := (FFacturasClienteController.ElegirFacturas(AFacturasAgente, 'Elija uno o más facturas para incluirlos en esta liquidación de comisiones', True) as IBizFacturaCliente); if Assigned(AFacturasSeleccionadas) then begin ShowHourglassCursor; try AFacturasDesglosadas := BuscarFacturasDesglosadas(AFacturasSeleccionadas); //Copia las facturas desglosadas de las facturas seleccionadas DuplicarRegistros(AFacturasDesglosadas.DataTable, AComision.Facturas.DataTable, mdrTodos, True, True, False); Result := True; finally HideHourglassCursor; end; end; AFacturasAgente := Nil; AFacturasSeleccionadas := Nil; AFacturasDesglosadas := Nil; end else ShowWarningMessage('Debe elegir primero el agente asociado a la liquidación'); end; function TComisionesController.Eliminar(AComision: IBizComisiones): Boolean; begin Result := False; if not Assigned(AComision) then raise Exception.Create ('Comision no asignada'); ShowHourglassCursor; try if (AComision.State in dsEditModes) then AComision.Cancel; AComision.Delete; AComision.DataTable.ApplyUpdates; HideHourglassCursor; Result := True; finally HideHourglassCursor; end; end; procedure TComisionesController.EliminarFactura(AComision: IBizComisiones); var IdFactura: Variant; begin IdFactura := AComision.Facturas.ID_FACTURA; AComision.Facturas.First; while AComision.Facturas.DataTable.Locate('ID_FACTURA', IdFactura,[]) do begin AComision.Facturas.Delete; AComision.Facturas.First; end; end; procedure TComisionesController.RecibirAviso(ASujeto: ISujeto; ADataTable: IDAStronglyTypedDataTable); begin inherited; // end; function TComisionesController.Guardar(AComision: IBizComisiones): Boolean; var NuevoID: Integer; begin Result := False; if not Assigned(AComision) then raise Exception.Create ('Almacen no asignada'); if ValidarComision(AComision) then begin ShowHourglassCursor; try if (AComision.EsNuevo) then NuevoID := FDataModule.GetNextID(AComision.DataTable.LogicalName) else NuevoID := AComision.ID; AsignarID(AComision, NuevoID); AComision.DataTable.ApplyUpdates; //Si todo ha ido bien, asignamos la comision a las facturas asociadas //Como no están declarados como maestro-detalles debemos hacer el applyupdates nosotros // RecibosClienteController.AsignarRemesa(ARemesaCliente.Recibos, NuevoID); // ARemesaCliente.Recibos.DataTable.ApplyUpdates; //En este applyupdates tambien se realizarán todos los cambios acumulados sobre los recibos asociados (EliminarReciboCliente/ ElegirRecibosCliente) Result := True; finally HideHourglassCursor; end; end; end; procedure TComisionesController.Preview(AComision: IBizComisiones; const DesglosadoProv: Boolean); var AReportController : IComisionesReportController; begin AReportController := TComisionesReportController.Create; try if Assigned(AComision) then AReportController.Preview(AComision.ID, DesglosadoProv) else AReportController.Preview(Null, DesglosadoProv) finally AReportController := NIL; end; end; procedure TComisionesController.Print(AComision: IBizComisiones; const DesglosadoProv: Boolean); var AReportController : IComisionesReportController; begin AReportController := TComisionesReportController.Create; try if Assigned(AComision) then AReportController.Print(AComision.ID, DesglosadoProv) else AReportController.Print(Null, DesglosadoProv); finally AReportController := NIL; end; end; end.