unit uComisionesController; interface uses Classes, SysUtils, uDADataTable, uControllerBase, uEditorDBItem, uIDataModuleComisiones, uBizComisiones; //, uFacturasClienteController, uBizFacturasCliente; type IComisionesController = interface(IControllerBase) ['{0C281A5D-9DF9-46BD-99CB-1150A536EFA1}'] function BuscarTodos: IBizComisiones; function Buscar(const ID: Integer): 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 Preview(AComision : IBizComisiones; AllItems: Boolean = false); procedure Print(AComision : IBizComisiones; AllItems: Boolean = false); function ExtraerSeleccionados(AComisiones: IBizComisiones) : IBizComisiones; function ElegirFacturasComision(AComision : IBizComisiones): Boolean; function ElegirVendedoresComision(AComision : IBizComisiones): Boolean; procedure RecalcularComisiones(AComision : IBizComisiones; Const ImporteTotal: Variant); procedure AsignarImporteTotal(AComision : IBizComisiones; Const ImporteTotal: Variant); end; TComisionesController = class(TControllerBase, IComisionesController) private // function BuscarFacturasDesglosadas(AFacturas: IBizFacturaCliente): IBizFacturasComision; // procedure QuitarExistentes(AFacturas: IBizFacturaCliente; AFacturasComision: IBizFacturasComision); procedure FiltrarEmpresa(AComisiones: IBizComisiones); 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 AsignarDataModule; virtual; public constructor Create; override; destructor Destroy; override; function Eliminar(AComision : IBizComisiones): Boolean; function Guardar(AComision : IBizComisiones): Boolean; function Anadir(AComision : IBizComisiones): Boolean; function BuscarTodos: IBizComisiones; function Buscar(const ID: Integer): IBizComisiones; procedure VerTodos(AComision: IBizComisiones); procedure Ver(AComision: IBizComisiones); procedure Preview(AComision : IBizComisiones; AllItems: Boolean = false); procedure Print(AComision : IBizComisiones; AllItems: Boolean = false); function ExtraerSeleccionados(AComisiones: IBizComisiones) : IBizComisiones; function ElegirFacturasComision(AComision : IBizComisiones): Boolean; function ElegirVendedoresComision(AComision : IBizComisiones): Boolean; procedure RecalcularComisiones(AComision : IBizComisiones; Const ImporteTotal: Variant); procedure AsignarImporteTotal(AComision : IBizComisiones; Const ImporteTotal: Variant); end; implementation uses Variants, Dialogs, cxControls, DB, uEditorRegistryUtils, schComisionesClient_Intf, uIEditorComisiones, uDataModuleComisiones, uDataModuleUsuarios, uFactuGES_App, uDAInterfaces, uDataTableUtils, uIEditorComision, uComisionesReportController, uDateUtils, uROTypes, DateUtils, Controls, Windows, uDialogUtils, uBizContactos, uVendedoresController, uBizFacturasCliente, uFacturasClienteController; { 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); var EnEdicion: Boolean; 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 EnEdicion:= AComision.DataTable.Editing; if not EnEdicion then AComision.DataTable.Edit; AComision.IMPORTE_TOTAL := ImporteTotal; AComision.DataTable.Post; if EnEdicion then AComision.DataTable.Edit; // Recalcular 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.Buscar(const ID: Integer): IBizComisiones; begin Result := (FDataModule as IDataModuleComisiones).GetItem(ID); FiltrarEmpresa(Result); end; function TComisionesController.BuscarTodos: IBizComisiones; begin Result := FDataModule.GetItems; FiltrarEmpresa(Result); end; constructor TComisionesController.Create; begin inherited; 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; 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; //Tambien hacemos post de sus tablas hija if (AComision.Facturas.DataTable.State in dsEditModes) then AComision.Facturas.DataTable.Post; if (AComision.Vendedores.DataTable.State in dsEditModes) then AComision.Vendedores.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 := AppFactuGES.UsuarioActivo.UserName; Result := True; finally AComision.Post; end; end; procedure TComisionesController.Ver(AComision: IBizComisiones); var AEditor : IEditorComision; begin AEditor := NIL; // RecuperarObjetos(ARemesaCliente); CreateEditor('EditorComision', IEditorComision, AEditor); if Assigned(AEditor) then try AEditor.Controller := Self; //OJO ORDEN MUY IMPORTANTE AEditor.Comision := AComision; AEditor.ShowModal; finally AEditor.Release; AEditor := NIL; end; end; procedure TComisionesController.VerTodos(AComision: IBizComisiones); var AEditor : IEditorComisiones; begin AEditor := NIL; CreateEditor('EditorComisiones', IEditorComisiones, AEditor); if Assigned(AEditor) then with AEditor do begin Controller := Self; //OJO ORDEN MUY IMPORTANTE Comisiones := AComision; ShowEmbedded; end; end; function TComisionesController.ElegirFacturasComision(AComision: IBizComisiones): Boolean; var AFacturasSeleccionadas : IBizFacturaCliente; AFacturasController: IFacturasClienteController; Cadena: TStringList; begin Result := False; if Assigned(AComision.Facturas) then begin //Recogemos los id de las facturas que ya tiene asociada la liquidación with AComision.Facturas.DataTable do begin if not Active then Active := True; First; Cadena := TStringList.Create; While not Eof do begin Cadena.Add(IntToStr(AComision.Facturas.ID)); Next; end; end; AFacturasController := TFacturasClienteController.Create; try AFacturasSeleccionadas := AFacturasController.BuscarTodasPendientesComision(AComision.ID_AGENTE, AComision.ID, Cadena.CommaText); AFacturasSeleccionadas := (AFacturasController.ElegirFacturas(AFacturasSeleccionadas, 'Elija uno o más facturas para incluirlos en esta liquidación de comisiones', True) as IBizFacturaCliente); if Assigned(AFacturasSeleccionadas) then begin ShowHourglassCursor; try //Copia las facturas desglosadas de las facturas seleccionadas DuplicarRegistros(AFacturasSeleccionadas.DataTable, AComision.Facturas.DataTable, mdrTodos, True, True, True); Result := True; finally HideHourglassCursor; end; end; finally Cadena.Free; AFacturasController := Nil; AFacturasSeleccionadas := Nil; end; end; end; function TComisionesController.ElegirVendedoresComision(AComision: IBizComisiones): Boolean; var AVendedoresSeleccionados : IBizContacto; AVendedoresController : IVendedoresController; Cadena: TStringList; begin Result := False; if Assigned(AComision.Vendedores) then begin //Recogemos los id de los vendedores que ya tiene asociada la liquidación with AComision.Vendedores.DataTable do begin if not Active then Active := True; First; Cadena := TStringList.Create; While not Eof do begin Cadena.Add(IntToStr(AComision.Vendedores.ID_VENDEDOR)); Next; end; end; AVendedoresController := TVendedoresController.Create; try AVendedoresSeleccionados := AVendedoresController.BuscarTodos(Cadena.CommaText); AVendedoresSeleccionados := AVendedoresController.ElegirContacto(AvendedoresSeleccionados, 'Elija los vendedores de la comision', True); if Assigned(AVendedoresSeleccionados) then begin ShowHourglassCursor; try //Copia los vendedores seleccionados DuplicarRegistros(AVendedoresSeleccionados.DataTable, AComision.Vendedores.DataTable, mdrTodos, True, True, False); //Copiamos el ID de los vendedores seleccionados en ID_VENDEDOR de la tabla detalle AVendedoresSeleccionados.DataTable.First; AComision.Vendedores.DataTable.First; while not AVendedoresSeleccionados.DataTable.EOF do begin if not AComision.Vendedores.DataTable.Editing then AComision.Vendedores.DataTable.Edit; AComision.Vendedores.ID_VENDEDOR := AVendedoresSeleccionados.ID; AComision.Vendedores.DataTable.Post; AVendedoresSeleccionados.DataTable.Next; AComision.Vendedores.DataTable.Next; end; AComision.Vendedores.DataTable.First; Result := True; finally HideHourglassCursor; end; end; finally Cadena.Free; AVendedoresController := Nil; AVendedoresSeleccionados := Nil; end; end; 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; function TComisionesController.ExtraerSeleccionados(AComisiones: IBizComisiones): IBizComisiones; var ASeleccionados : IBizComisiones; begin ASeleccionados := (Self.Buscar(ID_NULO) as IBizComisiones); CopyDataTableDA5(AComisiones.DataTable, ASeleccionados.DataTable, True); Result := ASeleccionados; end; procedure TComisionesController.FiltrarEmpresa(AComisiones: IBizComisiones); var Condicion: TDAWhereExpression; begin if AComisiones.DataTable.Active then AComisiones.DataTable.Active := False; // Filtrar las facturas actuales por empresa with AComisiones.DataTable.DynamicWhere do begin // (ID_EMPRESA >= ID) Condicion := NewBinaryExpression(NewField('', fld_ComisionesID_EMPRESA), NewConstant(AppFactuGES.EmpresaActiva.ID, datInteger), dboEqual); if IsEmpty then Expression := Condicion else Expression := NewBinaryExpression(Expression, Condicion, dboAnd); end; end; procedure TComisionesController.RecalcularComisiones(AComision: IBizComisiones; const ImporteTotal: Variant); begin if Assigned(AComision) and Assigned(AComision.Vendedores) and (not AComision.Vendedores.IsEmpty) then begin AComision.Vendedores.DataTable.DisableControls; try AComision.Vendedores.DataTable.First; while not AComision.Vendedores.DataTable.EOF do begin AComision.Vendedores.Edit; AComision.Vendedores.IMPORTE_TOTAL := ((AComision.Vendedores.COMISION / 100) * ImporteTotal); AComision.Vendedores.Post; AComision.Vendedores.DataTable.Next; end; finally AComision.Vendedores.DataTable.EnableControls; end; 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 ('Comision no asignada'); if ValidarComision(AComision) then begin ShowHourglassCursor; try AComision.DataTable.ApplyUpdates; Result := True; finally HideHourglassCursor; end; end; end; procedure TComisionesController.Preview(AComision: IBizComisiones; AllItems: Boolean = false); var AReportController : IComisionesReportController; ID_Comisiones: TStringList; begin AReportController := TComisionesReportController.Create; try ID_Comisiones := TStringList.Create; //Si deseamos previsualizar todos los items del objeto comision if AllItems then begin with AComision.DataTable do begin First; while not EOF do begin ID_Comisiones.Add(IntToStr(AComision.ID)); Next; end; end; end //Solo previsualizamos el item seleccionado else ID_Comisiones.Add(IntToStr(AComision.ID)); AReportController.Preview(ID_Comisiones.CommaText); finally AReportController := NIL; ID_Comisiones.Free; end; end; procedure TComisionesController.Print(AComision: IBizComisiones; AllItems: Boolean = false); var AReportController : IComisionesReportController; ID_Comisiones: TStringList; begin AReportController := TComisionesReportController.Create; try ID_Comisiones := TStringList.Create; //Si deseamos previsualizar todos los items del objeto comision if AllItems then begin with AComision.DataTable do begin First; while not EOF do begin ID_Comisiones.Add(IntToStr(AComision.ID)); Next; end; end; end //Solo previsualizamos el item seleccionado else ID_Comisiones.Add(IntToStr(AComision.ID)); AReportController.Print(ID_Comisiones.CommaText); finally AReportController := NIL; ID_Comisiones.Free; end; end; end.