unit uArticulosController; interface uses Classes, SysUtils, uDADataTable, uControllerBase, uEditorDBItem, uIDataModuleArticulos, uBizArticulos, uProveedoresController, uBizContactos; type IArticulosController = interface(IControllerBase) ['{C7EA6486-7BE4-468E-A27A-621E1BA13430}'] function Buscar(const ID: Integer; AClienteID: Integer = -1): IBizArticulo; function BuscarInventariables: IBizArticulo; function BuscarTodos: IBizArticulo; overload; function BuscarTodos(ACliente: IBizCliente): IBizArticulo; overload; function BuscarTodos(AProveedor: IBizProveedor): IBizArticulo; overload; function BuscarReferencia(const Ref: String; AClienteID: Integer): IBizArticulo; function BuscarReferenciaProveedor(const Ref: String; AClienteID: Integer): IBizArticulo; procedure Ver(AArticulo : IBizArticulo); procedure VerTodos(AArticulos: IBizArticulo); function Nuevo : IBizArticulo; procedure Anadir(AArticulo : IBizArticulo); function Eliminar(const ID : Integer): Boolean; overload; function Eliminar(AArticulo : IBizArticulo): Boolean; overload; function Guardar(AArticulo : IBizArticulo): Boolean; procedure DescartarCambios(AArticulo : IBizArticulo); function Existe(const ID: Integer) : Boolean; function Duplicar(AArticulo: IBizArticulo): IBizArticulo; procedure Preview(AArticulo : IBizArticulo); procedure Print(AArticulo : IBizArticulo); procedure ElegirProveedor(AArticulo : IBizArticulo); procedure AnadirProveedor(AArticulo : IBizArticulo); procedure VerProveedor(AArticulo : IBizArticulo); function ExtraerSeleccionados(AArticulos: IBizArticulo) : IBizArticulo; function ElegirArticulos(AArticulos : IBizArticulo; AMensaje: String; AMultiSelect: Boolean): IBizArticulo; procedure CalcularPrecioNeto(AArticulos: IBizArticulo); function GetProveedoresController: IProveedoresController; property ProveedoresController: IProveedoresController read GetProveedoresController; procedure SetPrecioPunto (const AValue: Currency); function GetPrecioPunto: Currency; property PrecioPunto : Currency read GetPrecioPunto write SetPrecioPunto; end; TArticulosController = class(TControllerBase, IArticulosController) protected FPrecioPunto: Currency; FDataModule : IDataModuleArticulos; FProveedoresController: IProveedoresController; function GetProveedoresController: IProveedoresController; procedure RecibirAviso(ASujeto: ISujeto; ADataTable: IDAStronglyTypedDataTable); override; function CreateEditor(const AName : String; const IID: TGUID; out Intf): Boolean; function _Vacio : IBizArticulo; procedure FiltrarEmpresa(AArticulo: IBizArticulo); function ValidarArticulo(AArticulo: IBizArticulo): Boolean; virtual; procedure RecuperarObjetos(AArticulo: IBizArticulo); virtual; procedure AsignarDataModule; virtual; procedure SetPrecioPunto (const AValue: Currency); function GetPrecioPunto: Currency; public property ProveedoresController: IProveedoresController read GetProveedoresController; constructor Create; override; destructor Destroy; override; function Eliminar(const ID : Integer): Boolean; overload; function Eliminar(AArticulo : IBizArticulo): Boolean; overload; function Guardar(AArticulo : IBizArticulo): Boolean; procedure DescartarCambios(AArticulo : IBizArticulo); virtual; function Existe(const ID: Integer) : Boolean; virtual; procedure Anadir(AArticulo : IBizArticulo); virtual; function Buscar(const ID: Integer; AClienteID: Integer = -1): IBizArticulo; virtual; function BuscarTodos: IBizArticulo; overload; function BuscarInventariables: IBizArticulo; function BuscarTodos(ACliente: IBizCliente): IBizArticulo; overload; function BuscarTodos(ACliente: Integer): IBizArticulo; overload; function BuscarTodos(AProveedor: IBizProveedor): IBizArticulo; overload; function BuscarReferencia(const Ref: String; AClienteID: Integer = -1): IBizArticulo; virtual; function BuscarReferenciaProveedor(const Ref: String; AClienteID: Integer): IBizArticulo; virtual; function Nuevo : IBizArticulo; virtual; procedure Ver(AArticulo : IBizArticulo); virtual; procedure VerTodos(AArticulos: IBizArticulo); virtual; function Duplicar(AArticulo: IBizArticulo): IBizArticulo; virtual; procedure Preview(AArticulo : IBizArticulo); virtual; procedure Print(AArticulo : IBizArticulo); virtual; function ExtraerSeleccionados(AArticulos: IBizArticulo) : IBizArticulo; virtual; function ElegirArticulos(AArticulos : IBizArticulo; AMensaje: String; AMultiSelect: Boolean): IBizArticulo; virtual; procedure CalcularPrecioNeto(AArticulos: IBizArticulo); procedure ElegirProveedor(AArticulo : IBizArticulo); procedure AnadirProveedor(AArticulo : IBizArticulo); procedure VerProveedor(AArticulo : IBizArticulo); property PrecioPunto : Currency read GetPrecioPunto write SetPrecioPunto; end; implementation uses cxControls, DB, uEditorRegistryUtils, schArticulosClient_Intf, uFactuGES_App, uIEditorArticulos, uIEditorArticulo, uIEditorElegirArticulos, uDataModuleArticulos, uDataModuleUsuarios, uDAInterfaces, uDataTableUtils, uDateUtils, uROTypes, DateUtils, Controls, Windows; { TArticulosController } procedure TArticulosController.Anadir(AArticulo: IBizArticulo); begin AArticulo.Insert; end; procedure TArticulosController.AnadirProveedor(AArticulo: IBizArticulo); var AProveedor : IBizContacto; begin inherited; AProveedor := (FProveedoresController.Nuevo as IBizProveedor); FProveedoresController.Ver(AProveedor); if Assigned(AProveedor) then begin if not AArticulo.DataTable.Editing then AArticulo.Edit; AArticulo.ID_PROVEEDOR := AProveedor.ID; AArticulo.NOMBRE_PROVEEDOR := AProveedor.NOMBRE; end; AProveedor := Nil; end; procedure TArticulosController.AsignarDataModule; begin FDataModule := TDataModuleArticulos.Create(Nil); FProveedoresController := TProveedoresController.Create; end; function TArticulosController.Buscar(const ID: Integer; AClienteID: Integer = -1): IBizArticulo; begin if (AClienteID = -1) then Result := (FDataModule as IDataModuleArticulos).GetItem(ID) else Result := (FDataModule as IDataModuleArticulos).GetItem(ID, AClienteID); //LOS ARTICULOS PASAN A SER COMUNES PARA LAS EMPRESAS // FiltrarEmpresa(Result); end; function TArticulosController.BuscarInventariables: IBizArticulo; var Condicion: TDAWhereExpression; begin ShowHourglassCursor; try Result := BuscarTodos; // Filtrar los articulos inventariables with Result.DataTable.DynamicWhere do begin // (ID_EMPRESA >= ID) Condicion := NewBinaryExpression(NewField('', fld_ArticulosINVENTARIABLE), NewConstant(1, datInteger), dboEqual); if IsEmpty then Expression := Condicion else Expression := NewBinaryExpression(Expression, Condicion, dboAnd); end; finally HideHourglassCursor; end; end; function TArticulosController.BuscarReferencia(const Ref: String; AClienteID: Integer = -1): IBizArticulo; var Condicion: TDAWhereExpression; begin ShowHourglassCursor; try if (AClienteID = -1) then Result := BuscarTodos else Result := BuscarTodos(AClienteID); // Filtrar por referencia, se cambia por el where anterior porque luego no nos reconoce bien la cadena, al contener UPPER with Result.DataTable.Where do begin AddText(Format('UPPER(%s) = ''%s''', [fld_ArticulosREFERENCIA, UpperCase(Ref)])); end; {with Result.DataTable.DynamicWhere do begin // (REFERENCIA >= Ref) Condicion := NewBinaryExpression(NewField('', fld_ArticulosREFERENCIA), NewConstant(UpperCase(Ref), datString), dboEqual); if IsEmpty then Expression := Condicion else Expression := NewBinaryExpression(Expression, Condicion, dboAnd); end;} finally HideHourglassCursor; end; end; function TArticulosController.BuscarReferenciaProveedor(const Ref: String; AClienteID: Integer): IBizArticulo; var Condicion: TDAWhereExpression; begin ShowHourglassCursor; try if (AClienteID = -1) then Result := BuscarTodos else Result := BuscarTodos(AClienteID); // Filtrar por referencia, se cambia por el where anterior porque luego no nos reconoce bien la cadena, al contener UPPER with Result.DataTable.Where do begin AddText(Format('UPPER(%s) = ''%s''', [fld_ArticulosREFERENCIA_PROV, UpperCase(Ref)])); end; {with Result.DataTable.DynamicWhere do begin // (REFERENCIA >= Ref) Condicion := NewBinaryExpression(NewField('', fld_ArticulosREFERENCIA_PROV), NewConstant(UpperCase(Ref), datString), dboEqual); if IsEmpty then Expression := Condicion else Expression := NewBinaryExpression(Expression, Condicion, dboAnd); end;} finally HideHourglassCursor; end; end; function TArticulosController.BuscarTodos(ACliente: Integer): IBizArticulo; begin Result := FDataModule.GetItems(ACliente); //LOS ARTICULOS PASAN A SER COMUNES PARA LAS EMPRESAS // FiltrarEmpresa(Result); end; function TArticulosController.BuscarTodos(ACliente: IBizCliente): IBizArticulo; begin if not Assigned(ACliente) then raise Exception.Create('Falta ACliente: BuscarTodos'); Result := BuscarTodos(ACliente.ID); end; function TArticulosController.BuscarTodos(AProveedor: IBizProveedor): IBizArticulo; var Condicion: TDAWhereExpression; begin if Assigned(AProveedor) then begin ShowHourglassCursor; try Result := BuscarTodos; // Filtrar los articulos del proveedor with Result.DataTable.DynamicWhere do begin // (ID_PROVEEDOR = ID) Condicion := NewBinaryExpression(NewField('', fld_ArticulosID_PROVEEDOR), NewConstant(AProveedor.ID, datInteger), dboEqual); if IsEmpty then Expression := Condicion else Expression := NewBinaryExpression(Expression, Condicion, dboAnd); end; finally HideHourglassCursor; end; end; end; function TArticulosController.BuscarTodos: IBizArticulo; begin Result := FDataModule.GetItems; //LOS ARTICULOS PASAN A SER COMUNES PARA LAS EMPRESAS // FiltrarEmpresa(Result); end; procedure TArticulosController.CalcularPrecioNeto(AArticulos: IBizArticulo); var lPrecioNeto: Double; begin if Assigned(AArticulos) then begin with AArticulos do begin try ShowHourglassCursor; DataTable.DisableControls; if not DataTable.Active then DataTable.Active := True; //Calcular precio neto lPrecioNeto := PRECIO_COSTE - ((PRECIO_COSTE * DESCUENTO)/100); if (PRECIO_NETO <> lPrecioNeto) then begin if not DataTable.Editing then DataTable.Edit; PRECIO_NETO := lPrecioNeto; end; finally DataTable.EnableControls; HideHourglassCursor; end; end; end; end; constructor TArticulosController.Create; begin inherited; FPrecioPunto:= AppFactuGES.EmpresaActiva.PRECIO_PUNTO; AsignarDataModule; end; function TArticulosController.CreateEditor(const AName: String; const IID: TGUID; out Intf): Boolean; begin Result := Supports(EditorRegistry.CreateEditor(AName), IID, Intf); end; procedure TArticulosController.DescartarCambios(AArticulo: IBizArticulo); begin if not Assigned(AArticulo) then raise Exception.Create ('Articulo no asignado'); ShowHourglassCursor; try if (AArticulo.State in dsEditModes) then AArticulo.Cancel; AArticulo.DataTable.CancelUpdates; finally HideHourglassCursor; end; end; destructor TArticulosController.Destroy; begin FDataModule := Nil; FProveedoresController := Nil; inherited; end; function TArticulosController.Duplicar(AArticulo: IBizArticulo): IBizArticulo; begin Result := Self._Vacio; ShowHourglassCursor; try DuplicarRegistros(AArticulo.DataTable, Result.DataTable, mdrActual); // Hay que dejar algunos campos como si fuera un artículo nuevo Result.Edit; with Result do begin ID_EMPRESA := AppFactuGES.EmpresaActiva.ID; USUARIO := AppFactuGES.UsuarioActivo.UserName; end; Result.Post; finally HideHourglassCursor; end; end; function TArticulosController.ValidarArticulo(AArticulo: IBizArticulo): Boolean; begin Result := False; if not Assigned(AArticulo) then raise Exception.Create ('Artículo no asignado'); if (AArticulo.DataTable.State in dsEditModes) then AArticulo.DataTable.Post; if Length(AArticulo.DESCRIPCION) = 0 then raise Exception.Create('Debe indicar al menos la descripción de este artículo.'); // Asegurarse de valores en campos "automáticos" AArticulo.Edit; try AArticulo.USUARIO := AppFactuGES.UsuarioActivo.UserName; Result := True; finally AArticulo.Post; end; end; procedure TArticulosController.Ver(AArticulo: IBizArticulo); var AEditor : IEditorArticulo; begin AEditor := NIL; RecuperarObjetos(AArticulo); CreateEditor('EditorArticulo', IEditorArticulo, AEditor); if Assigned(AEditor) then try AEditor.Controller := Self; //OJO ORDEN MUY IMPORTANTE AEditor.Articulo := AArticulo; AEditor.ShowModal; finally AEditor.Release; AEditor := NIL; end; end; procedure TArticulosController.VerProveedor(AArticulo: IBizArticulo); var AProveedor : IBizContacto; begin AProveedor := FProveedoresController.Buscar(AArticulo.ID_PROVEEDOR); FProveedoresController.Ver(AProveedor); if Assigned(AProveedor) then begin if not AArticulo.DataTable.Editing then AArticulo.Edit; AArticulo.ID_PROVEEDOR := AProveedor.ID; AArticulo.NOMBRE_PROVEEDOR := AProveedor.NOMBRE; end; AProveedor := Nil; end; procedure TArticulosController.VerTodos(AArticulos: IBizArticulo); var AEditor : IEditorArticulos; begin AEditor := NIL; RecuperarObjetos(AArticulos); CreateEditor('EditorArticulos', IEditorArticulos, AEditor); if Assigned(AEditor) then with (AEditor as IEditorArticulos) do begin Controller := Self; //OJO ORDEN MUY IMPORTANTE Articulos := AArticulos; ShowEmbedded; end; end; function TArticulosController._Vacio: IBizArticulo; begin Result := Buscar(ID_NULO); end; function TArticulosController.Eliminar(const ID: Integer): Boolean; var AArticulo : IBizArticulo; begin AArticulo := Buscar(ID); if not Assigned(AArticulo) then raise Exception.Create(Format('No se ha encontrado el artículo con ID = %d', [ID])); Result := Eliminar(AArticulo); AArticulo := NIL; end; function TArticulosController.ElegirArticulos(AArticulos: IBizArticulo; AMensaje: String; AMultiSelect: Boolean): IBizArticulo; var AEditor : IEditorElegirArticulos; begin Result := NIL; CreateEditor('EditorElegirArticulos', IEditorElegirArticulos, AEditor); if Assigned(AEditor) then try AEditor.Controller := Self; AEditor.Articulos := AArticulos; AEditor.MultiSelect := AMultiSelect; AEditor.Mensaje := AMensaje; if IsPositiveResult(AEditor.ShowModal) then Result := AEditor.ArticulosSeleccionados; finally AEditor.Release; AEditor := NIL; end; end; procedure TArticulosController.ElegirProveedor(AArticulo: IBizArticulo); var AProveedor : IBizContacto; begin inherited; AProveedor := (FProveedoresController.ElegirContacto(FProveedoresController.BuscarTodos, '', False) as IBizProveedor); if Assigned(AProveedor) then begin if not AArticulo.DataTable.Editing then AArticulo.Edit; AArticulo.ID_PROVEEDOR := AProveedor.ID; AArticulo.NOMBRE_PROVEEDOR := AProveedor.NOMBRE; end; AProveedor := Nil; end; function TArticulosController.Eliminar(AArticulo: IBizArticulo): Boolean; begin Result := False; if not Assigned(AArticulo) then raise Exception.Create ('Articulo no asignada'); ShowHourglassCursor; try if (AArticulo.State in dsEditModes) then AArticulo.Cancel; AArticulo.Delete; AArticulo.DataTable.ApplyUpdates; HideHourglassCursor; Result := True; except on E: Exception do begin AArticulo.DataTable.CancelUpdates; HideHourglassCursor; if (Pos('FOREIGN KEY', E.Message) > 0) then MessageBox(0, 'No se puede borrar este artículo porque tiene artículos', 'Atención', MB_ICONWARNING or MB_OK); end; end; end; procedure TArticulosController.RecibirAviso(ASujeto: ISujeto; ADataTable: IDAStronglyTypedDataTable); begin inherited; // end; procedure TArticulosController.RecuperarObjetos(AArticulo: IBizArticulo); begin // end; procedure TArticulosController.SetPrecioPunto(const AValue: Currency); begin FPrecioPunto := AValue; end; function TArticulosController.Existe(const ID: Integer): Boolean; var AArticulo : IBizArticulo; begin try AArticulo := Buscar(ID); Result := Assigned(AArticulo) and (AArticulo.ID = ID); finally AArticulo := NIL; end; end; function TArticulosController.ExtraerSeleccionados(AArticulos: IBizArticulo): IBizArticulo; var ASeleccionados : IBizArticulo; begin ASeleccionados := (Self.Buscar(ID_NULO) as IBizArticulo); CopyDataTableDA5(AArticulos.DataTable, ASeleccionados.DataTable, True); Result := ASeleccionados; end; procedure TArticulosController.FiltrarEmpresa(AArticulo: IBizArticulo); var Condicion: TDAWhereExpression; begin if AArticulo.DataTable.Active then AArticulo.DataTable.Active := False; // Filtrar los Articulos actuales por empresa with AArticulo.DataTable.DynamicWhere do begin // (ID_EMPRESA >= ID) Condicion := NewBinaryExpression(NewField('', fld_ArticulosID_EMPRESA), NewConstant(AppFactuGES.EmpresaActiva.ID, datInteger), dboEqual); if IsEmpty then Expression := Condicion else Expression := NewBinaryExpression(Expression, Condicion, dboAnd); end; end; function TArticulosController.GetPrecioPunto: Currency; begin Result := FPrecioPunto; end; function TArticulosController.GetProveedoresController: IProveedoresController; begin Result := FProveedoresController; end; function TArticulosController.Guardar(AArticulo: IBizArticulo): Boolean; var NuevoID: Integer; begin Result := False; if ValidarArticulo(AArticulo) then begin ShowHourglassCursor; try AArticulo.DataTable.ApplyUpdates; Result := True; finally HideHourglassCursor; end; end; end; function TArticulosController.Nuevo: IBizArticulo; var AArticulo : IBizArticulo; begin AArticulo := FDataModule.NewItem; //LOS ARTICULOS PASAN A SER COMUNES PARA LAS EMPRESAS // FiltrarEmpresa(AArticulo); AArticulo.DataTable.Active := True; AArticulo.Insert; Result := AArticulo; end; procedure TArticulosController.Preview(AArticulo: IBizArticulo); //var // AReportController : IArticulosReportController; begin { AReportController := TArticulosReportController.Create; try AReportController.Preview(AArticulo.ID); finally AReportController := NIL; end; } end; procedure TArticulosController.Print(AArticulo: IBizArticulo); //var // AReportController : IArticulosReportController; begin { AReportController := TArticulosReportController.Create; try AReportController.Print(AArticulo.ID); finally AReportController := NIL; end; } end; end.