unit uInventarioController; interface uses Classes, SysUtils, uDADataTable, uControllerBase, uEditorDBItem, uIDataModuleInventario, uBizInventario, uArticulosInventarioController, uAlmacenesController, uObrasController, uPresupuestosClienteController, uBizPresupuestosCliente, uPedidosProveedorController, uBizPedidosProveedor, uBizArticulos, uBizAlmacenes, uBizObras; type IInventarioController = interface(IControllerBase) ['{FB1DE6BA-ADCC-4A83-B4D4-37DC5892766B}'] function Eliminar(AInventario : IBizInventario; Todos: Boolean; ApplyUpdates: Boolean): Boolean; function Trasladar(AInventario : IBizInventario; Todos: Boolean): Boolean; // procedure RecibirArticulos(Const APedido: IBizPedidoProveedor; Const CodigoAlmacenDes: Integer); overload; // procedure RecibirPedidos(Const CodigoAlmacenDes: Integer); function Liberar(AInventario : IBizInventario): Boolean; function Ver(AArticulos: IBizInventario; AInventario : IBizInventario; APedido: IBizPedidoProveedor = Nil): Boolean; procedure VerTodos(AInventario: IBizInventario; const pTipoInventario: String); procedure VerReservas(AArticulo: IBizInventario; const ATipoReservas: String; Const IdAlmacenObra: Integer); function BuscarTodos: IBizInventario; function BuscarTodosAlmacenes: IBizInventario; function BuscarTodosObras: IBizInventario; function Buscar(const ID_ALMACEN: Integer): IBizInventario; function BuscarDetalleReservas: IBizDetalleReservas; function ExtraerSeleccionados(AArticulos: IBizInventario) : IBizInventario; overload; function ExtraerSeleccionados(AArticulos: IBizDetalleReservas) : IBizDetalleReservas; overload; procedure Anadir(AArticulos, AInventario : IBizInventario); function Guardar(AArticulos : IBizInventario; const FechaMovimiento: TDateTime; const CausaMovimiento: String; AValidar:Boolean = True): Boolean; procedure EntradaArticulosLibre(AInventario: IBizInventario; Const CodigoAlmacenDestino: Integer); procedure SalidaArticulosLibre(AInventario: IBizInventario; Const CodigoAlmacenOrigen: Integer); procedure TrasladarArticulosLibre(AInventario: IBizInventario; Const CodigoAlmacenOrigen: Integer; Const CodigoAlmacenDestino: Integer); procedure ReservarArticulosLibre(AInventario: IBizInventario; Const CodigoAlmacenOrigen: Integer; Const CodigoAlmacenDestino: Integer); procedure CancelarReservas(AReservas: IBizDetalleReservas); procedure TrasladarReservas(AReservas: IBizDetalleReservas); function EntradaPedido(AInventario: IBizInventario; APedido: IBizPedidoProveedor; ADetalles: IDAStronglyTypedDataTable; var ADetallesFinal: IBizInventario): Boolean; function SalidaAlbaran(AInventario: IBizInventario; Const CodigoAlmacenOrigen: Integer; ADetalles: IDAStronglyTypedDataTable): Boolean; function GetAlmacenesController: IAlmacenesController; procedure SetAlmacenesController(const Value: IAlmacenesController); property AlmacenesController: IAlmacenesController read GetAlmacenesController write SetAlmacenesController; function GetObrasController: IObrasController; procedure SetObrasController(const Value: IObrasController); property ObrasController: IObrasController read GetObrasController write SetObrasController; procedure Copiar(AArticulos: IBizInventario; ADetalles: IDAStronglyTypedDataTable; AInventario: IBizInventario); overload; end; TInventarioController = class(TControllerBase, IInventarioController) private FAlmacenesController: IAlmacenesController; FObrasController: IObrasController; FArticulosController : IArticulosInventarioController; FPresupuestosClienteController : IPresupuestosClienteController; FPedidosProveedorController : IPedidosProveedorController; function GetAlmacenesController: IAlmacenesController; function GetObrasController: IObrasController; function GetArticulosController: IArticulosInventarioController; function GetPresupuestosClienteController: IPresupuestosClienteController; function GetPedidosProveedorController: IPedidosProveedorController; procedure SetAlmacenesController(const Value: IAlmacenesController); procedure SetObrasController(const Value: IObrasController); procedure SetArticulosController(const Value: IArticulosInventarioController); procedure SetPresupuestosClienteController(const Value: IPresupuestosClienteController); procedure SetPedidosProveedorController(const Value: IPedidosProveedorController); function Liberar(AInventario : IBizInventario; Todos: Boolean): Boolean; overload; function EntradaSalidaArticulos(AArticulos, AInventario : IBizInventario; APedido: IBizPedidoProveedor = Nil): Boolean; overload; function ReservarArticulos(AArticulos, AInventario : IBizInventario): Boolean; procedure Copiar(AArticulos: IBizInventario; ADetalles: IDAStronglyTypedDataTable; AInventario: IBizInventario); overload; function GuardarMovimientos(AArticulos : IBizInventario; const FechaMovimiento: TDateTime; const CausaMovimiento: String): Boolean; protected FDataModule : IDataModuleInventario; procedure RecibirAviso(ASujeto: ISujeto; ADataTable: IDAStronglyTypedDataTable); override; function CreateEditor(const AName : String; const IID: TGUID; out Intf): Boolean; function _Vacio : IBizInventario; procedure FiltrarEmpresa(AInventario: IBizInventario); overload; procedure FiltrarEmpresa(ADetalleReservas: IBizDetalleReservas); overload; procedure DeshabilitarOnCalcFields(Sender: TDADataTable); function ValidarCantidades(AArticulos: IBizInventario): Boolean; function Validar(AArticulos: IBizInventario): Boolean; //Estos son los tres métodos a sobre escribir si se desea heredar toda la logica de //este controller procedure AsignarDataModule; virtual; public property AlmacenesController: IAlmacenesController read GetAlmacenesController write SetAlmacenesController; property ObrasController: IObrasController read GetObrasController write SetObrasController; property ArticulosController: IArticulosInventarioController read GetArticulosController write SetArticulosController; property PresupuestosClienteController: IPresupuestosClienteController read GetPresupuestosClienteController write SetPresupuestosClienteController; property PedidosProveedorController: IPedidosProveedorController read GetPedidosProveedorController write SetPedidosProveedorController; constructor Create; override; destructor Destroy; override; function Trasladar(AInventario : IBizInventario; Todos: Boolean): Boolean; // procedure RecibirArticulos(Const APedido: IBizPedidoProveedor; Const CodigoAlmacenDes: Integer); overload; // procedure RecibirPedidos(Const CodigoAlmacenDes: Integer); function Buscar(const ID_ALMACEN: Integer): IBizInventario; function BuscarTodos: IBizInventario; function BuscarTodosAlmacenes: IBizInventario; function BuscarTodosObras: IBizInventario; function BuscarDetalleReservas: IBizDetalleReservas; function ElegirArticulos(AArticulos : IBizInventario; AMensaje: String; AMultiSelect: Boolean): IBizInventario; function ExtraerSeleccionados(AArticulos: IBizInventario) : IBizInventario; overload; function ExtraerSeleccionados(AArticulos: IBizDetalleReservas) : IBizDetalleReservas; overload; procedure Anadir(AArticulos, AInventario : IBizInventario); function Eliminar(AInventario : IBizInventario; Todos: Boolean; ApplyUpdates: Boolean): Boolean; procedure EntradaArticulosLibre(AInventario: IBizInventario; Const CodigoAlmacenDestino: Integer); procedure SalidaArticulosLibre(AInventario: IBizInventario; Const CodigoAlmacenOrigen: Integer); procedure TrasladarArticulosLibre(AInventario: IBizInventario; Const CodigoAlmacenOrigen: Integer; Const CodigoAlmacenDestino: Integer); procedure ReservarArticulosLibre(AInventario: IBizInventario; Const CodigoAlmacenOrigen: Integer; Const CodigoAlmacenDestino: Integer); procedure CancelarReservas(AReservas: IBizDetalleReservas); procedure TrasladarReservas(AReservas: IBizDetalleReservas); function EntradaPedido(AInventario: IBizInventario; APedido: IBizPedidoProveedor; ADetalles: IDAStronglyTypedDataTable; var ADetallesFinal: IBizInventario): Boolean; function SalidaAlbaran(AInventario: IBizInventario; Const CodigoAlmacenOrigen: Integer; ADetalles: IDAStronglyTypedDataTable): Boolean; procedure VerTodos(AInventario: IBizInventario; const pTipoInventario: String); function Ver(AArticulos: IBizInventario; AInventario : IBizInventario; APedido: IBizPedidoProveedor = Nil): Boolean; procedure VerReservas(AArticulo: IBizInventario; const ATipoReservas: String; Const IdAlmacenObra: Integer); function Guardar(AArticulos : IBizInventario; const FechaMovimiento: TDateTime; const CausaMovimiento: String; AValidar:Boolean = True): Boolean; function Liberar(AInventario : IBizInventario): Boolean; overload; end; implementation uses Forms, cxControls, DB, schInventarioClient_Intf, uEditorRegistryUtils, uIEditorInventario, uDataModuleInventario, uDataModuleUsuarios, uDAInterfaces, uDataTableUtils, uDateUtils, uROTypes, DateUtils, Controls, Windows, dialogs, Variants, schPedidosProveedorClient_Intf, uControllerDetallesBase, uDialogUtils, uFactuGES_App, uIEditorEntradaSalidaArticulos, schArticulosClient_Intf, uIEditorElegirArticulosAlmacen, uInventarioUtils, uIEditorDetalleReservas, schAlmacenesClient_Intf; const CTE_NULA = -1000; //No se utiliza ID_NULO porque en los albaranes de cliente se está asignando ID_NULO y esto ocasiona que se devuelvan tuplas { TInventarioController } { procedure TInventarioController.Anadir(AArticulo: IBizArticulo); begin AArticulo.Insert; end; } procedure TInventarioController.Anadir(AArticulos, AInventario: IBizInventario); var AArticulosSeleccionados: IDAStronglyTypedDataTable; begin AArticulosSeleccionados := Nil; case AArticulos.TipoMovimiento of tEntradaLibre: begin //IBizArticulo AArticulosSeleccionados := FArticulosController.ElegirArticulos(FArticulosController.BuscarInventariables, '', True); end; tSalidaLibre, tTraslado, tReserva: begin //IBizInventario AArticulosSeleccionados := ElegirArticulos(Buscar(AArticulos.IDAlmacenOrigen), '', True); end; end; if Assigned(AArticulosSeleccionados) then Copiar(AArticulos, AArticulosSeleccionados, AInventario) end; procedure TInventarioController.AsignarDataModule; begin FDataModule := TDataModuleInventario.Create(Nil); end; function TInventarioController.Buscar(const ID_ALMACEN: Integer): IBizInventario; begin Result := (FDataModule as IDataModuleInventario).GetItems(ID_ALMACEN); //Los inventarios serán comunes // FiltrarEmpresa(Result); end; function TInventarioController.BuscarDetalleReservas: IBizDetalleReservas; begin Result := FDataModule.GetDetalleReservas; //Los inventarios serán comunes // FiltrarEmpresa(Result); end; function TInventarioController.BuscarTodos: IBizInventario; begin Result := FDataModule.GetItems; //Los inventarios serán comunes // FiltrarEmpresa(Result); end; function TInventarioController.BuscarTodosAlmacenes: IBizInventario; var Condicion: TDAWhereExpression; begin ShowHourglassCursor; try Result := BuscarTodos; // Filtrar los pedidos pendientes de recepcion with Result.DataTable.DynamicWhere do begin // (TIPO_ALMACEN <> ALMACEN) Condicion := NewBinaryExpression(NewField('', fld_InventarioTIPO_ALMACEN), NewConstant(CTE_INV_ALMACEN, datString), dboEqual); if IsEmpty then Expression := Condicion else Expression := NewBinaryExpression(Expression, Condicion, dboAnd); end; finally HideHourglassCursor; end; end; function TInventarioController.BuscarTodosObras: IBizInventario; var Condicion: TDAWhereExpression; begin ShowHourglassCursor; try Result := BuscarTodos; // Filtrar los pedidos pendientes de recepcion with Result.DataTable.DynamicWhere do begin // (TIPO_ALMACEN <> ALMACEN) Condicion := NewBinaryExpression(NewField('', fld_InventarioTIPO_ALMACEN), NewConstant(CTE_INV_OBRA, datString), dboEqual); if IsEmpty then Expression := Condicion else Expression := NewBinaryExpression(Expression, Condicion, dboAnd); end; finally HideHourglassCursor; end; end; procedure TInventarioController.CancelarReservas(AReservas: IBizDetalleReservas); begin ShowHourglassCursor; try AReservas.DataTable.ClearRows; AReservas.DataTable.ApplyUpdates; finally HideHourglassCursor; end; end; procedure TInventarioController.Copiar(AArticulos: IBizInventario; ADetalles: IDAStronglyTypedDataTable; AInventario: IBizInventario); { Procedimiento que copia en AArticulos, todos los detalles pasados por parametro ADetalles añadiendo además el stock de cada uno de los detalles datos, siempre y cuando dichos detalles existan en AInventario pasado por parámetro. ADetalles será una interfaz genérica porque pueden venir dos tipos de elementos a añadir: - 1 Articulos de catálogo: IBizArticulo - 2 Artículos de un almacén: IBizInventario - 3 Detalles de un pedido de proveedor u albaran de cliente: IDAStronglyTypedDataTable (cumple con los tipos de controller detalles base } var StockArticulo: Double; begin if (not Assigned(AArticulos)) or (not Assigned(ADetalles)) then exit; if not AArticulos.DataTable.Active then AArticulos.DataTable.Active := True; if not ADetalles.DataTable.Active then ADetalles.DataTable.Active := True; if not Assigned(AInventario) then begin AInventario := BuscarTodos; AInventario.DataTable.Active := True; end; //Hacemos el recorrido de los detalles para insertarlos en AArticulos with ADetalles.DataTable do begin First; while not EOF do begin AArticulos.DataTable.Insert; //Estos campos serán comunes para todos los tipos de ADetalles a recibir AArticulos.REFERENCIA := FieldByName(fld_INVENTARIOREFERENCIA).AsString; //Caso 1 ADetalles = IBizArticulo if Supports(ADetalles, IBizArticulo) then begin AArticulos.ID_ARTICULO := FieldByName(fld_ArticulosID).AsInteger; // AArticulos.REFERENCIA_PROVEEDOR := FieldByName(fld_ArticulosREFERENCIA_PROV).AsString; AArticulos.DESCRIPCION := FieldByName(fld_INVENTARIODESCRIPCION).AsString; AArticulos.CANTIDAD := 1; end //Casos 2, 3 ADetalles = IBizInventario, IDAStronglyTypedDataTable else begin AArticulos.ID_ARTICULO := FieldByName(fld_INVENTARIOID_ARTICULO).AsInteger; // AArticulos.REFERENCIA_PROVEEDOR := FieldByName(fld_INVENTARIOREFERENCIA_PROVEEDOR).AsString; if Supports(ADetalles, IBizInventario) then begin AArticulos.DESCRIPCION := FieldByName(fld_INVENTARIODESCRIPCION).AsString; AArticulos.CANTIDAD := 1; end else begin AArticulos.DESCRIPCION := FieldByName(fld_PedidosProveedor_DetallesCONCEPTO).AsString; AArticulos.CANTIDAD := FieldByName(fld_INVENTARIOCANTIDAD).Asfloat; end; end; //Localizamos el stock en AInventario por cada uno de los ADetalles a copiar AInventario.DataTable.First; if AInventario.DataTable.Locate(fld_INVENTARIOID_ALMACEN + ';' + fld_INVENTARIOID_ARTICULO, VarArrayOf([AArticulos.ID_ALMACEN, AArticulos.ID_ARTICULO]), []) then StockArticulo := AInventario.STOCK else StockArticulo := 0; //Asignamos el Stock al articulo añadido if not AArticulos.DataTable.Editing then AArticulos.DataTable.Edit; AArticulos.STOCK := StockArticulo; AArticulos.DataTable.Post; Next; end; end; end; constructor TInventarioController.Create; begin inherited; AsignarDataModule; FArticulosController := TArticulosInventarioController.Create; FAlmacenesController := TAlmacenesController.Create; FObrasController := TObrasController.Create; FPresupuestosClienteController := TPresupuestosClienteController.Create; FPedidosProveedorController := TPedidosProveedorController.Create; end; function TInventarioController.CreateEditor(const AName: String; const IID: TGUID; out Intf): Boolean; begin Result := Supports(EditorRegistry.CreateEditor(AName), IID, Intf); end; { procedure TInventarioController.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 TInventarioController.Destroy; begin FDataModule := Nil; FArticulosController := Nil; FAlmacenesController := Nil; FObrasController := Nil; FPresupuestosClienteController := Nil; FPedidosProveedorController := Nil; inherited; end; function TInventarioController.ElegirArticulos(AArticulos: IBizInventario; AMensaje: String; AMultiSelect: Boolean): IBizInventario; var AEditor : IEditorElegirArticulosAlmacen; begin Result := NIL; CreateEditor('EditorElegirArticulosAlmacen', IEditorElegirArticulosAlmacen, AEditor); if Assigned(AEditor) then try AEditor.Controller := Self; AEditor.Inventario := AArticulos; AEditor.MultiSelect := AMultiSelect; AEditor.Mensaje := AMensaje; if IsPositiveResult(AEditor.ShowModal) then Result := AEditor.ArticulosSeleccionados; finally AEditor.Release; AEditor := NIL; end; end; function TInventarioController.Eliminar(AInventario: IBizInventario; Todos: Boolean; ApplyUpdates: Boolean): Boolean; begin Result := False; if Assigned(AInventario) then begin ShowHourglassCursor; try if Todos then AInventario.DataTable.ClearRows else AInventario.DataTable.Delete; if ApplyUpdates then AInventario.DataTable.ApplyUpdates; Result := True; finally HideHourglassCursor; end; end; end; function TInventarioController.ExtraerSeleccionados(AArticulos: IBizInventario): IBizInventario; var ASeleccionados : IBizInventario; begin ASeleccionados := (Self.Buscar(CTE_NULA) as IBizInventario); CopyDataTableDA5(AArticulos.DataTable, ASeleccionados.DataTable, True); Result := ASeleccionados; end; procedure TInventarioController.FiltrarEmpresa(ADetalleReservas: IBizDetalleReservas); var Condicion: TDAWhereExpression; begin if ADetalleReservas.DataTable.Active then ADetalleReservas.DataTable.Active := False; // Filtrar los inventario actuales por empresa with ADetalleReservas.DataTable.DynamicWhere do begin // (ID_EMPRESA >= ID) Condicion := NewBinaryExpression(NewField('', fld_DetalleReservasID_EMPRESA), NewConstant(AppFactuGES.EmpresaActiva.ID, datInteger), dboEqual); if IsEmpty then Expression := Condicion else Expression := NewBinaryExpression(Expression, Condicion, dboAnd); end; end; function TInventarioController.Validar(AArticulos: IBizInventario): Boolean; begin Result := True; if not Assigned(AArticulos) then raise Exception.Create ('Articulos no asignados'); if (AArticulos.DataTable.State in dsEditModes) then AArticulos.DataTable.Post; case AArticulos.TipoMovimiento of tSalidaLibre, tSalidaAlbaranCliente, tTraslado, tReserva: begin Result := ValidarCantidades(AArticulos); if not Result then raise Exception.Create ('Revise las cantidades'); end; end; end; function TInventarioController.ValidarCantidades(AArticulos: IBizInventario): Boolean; var ListaArticulos: TStringList; begin Result := False; if Assigned(AArticulos) then begin ShowHourglassCursor; try ListaArticulos := TStringList.Create; With AArticulos.DataTable do begin First; while not eof do begin if (AArticulos.CANTIDAD > AArticulos.STOCK) then ListaArticulos.Add(AArticulos.REFERENCIA + ' - ' + AArticulos.DESCRIPCION); next; end; if ListaArticulos.Count > 0 then Result := (ShowConfirmMessage_ArticulosSinStock(ListaArticulos) = IDYES) else Result := True; end; finally FreeAndNil(ListaArticulos); HideHourglassCursor; end; end; end; function TInventarioController.Ver(AArticulos: IBizInventario; AInventario: IBizInventario; APedido: IBizPedidoProveedor = Nil): Boolean; var AEditor : IEditorEntradaSalidaArticulos; begin Result := False; AEditor := NIL; CreateEditor('EditorEntradaSalidaArticulos', IEditorEntradaSalidaArticulos, AEditor); if Assigned(AEditor) then try AEditor.Controller := Self; //OJO ORDEN MUY IMPORTANTE AEditor.Articulos := AArticulos; AEditor.Inventario := AInventario; if Assigned(APedido) then AEditor.PedidoProveedor := APedido; AEditor.ShowModal; Result := AEditor.ResultadoModalOK; finally AEditor.Release; AEditor := NIL; end; end; procedure TInventarioController.VerReservas(AArticulo: IBizInventario; const ATipoReservas: String; Const IdAlmacenObra: Integer); var AEditor : IEditorDetalleReservas; begin AEditor := NIL; CreateEditor('EditorDetalleReservas', IEditorDetalleReservas, AEditor); if Assigned(AEditor) then try AEditor.Controller := Self; //OJO ORDEN MUY IMPORTANTE AEditor.TipoReservas := ATipoReservas; AEditor.IdAlmacenObra := IdAlmacenObra; AEditor.DetalleReservas := FDataModule.GetDetalleReservas; AEditor.Articulo := AArticulo; AEditor.MultiSelect := True; AEditor.ShowModal; finally AEditor.Release; AEditor := NIL; end; end; procedure TInventarioController.VerTodos(AInventario: IBizInventario; const pTipoInventario: String); var AEditor : IEditorInventario; begin AEditor := NIL; CreateEditor('EditorInventario', IEditorInventario, AEditor); if Assigned(AEditor) then with AEditor do begin Controller := Self; //OJO ORDEN MUY IMPORTANTE TipoInventario := pTipoInventario; Inventario := AInventario; MultiSelect := False; ShowEmbedded; end; end; function TInventarioController._Vacio: IBizInventario; begin Result := Buscar(CTE_NULA); end; { procedure TInventarioController.Eliminar(const ID: Integer); 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])); Eliminar(AArticulo); AArticulo := NIL; end; function TInventarioController.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; } function TInventarioController.EntradaSalidaArticulos(AArticulos, AInventario : IBizInventario; APedido: IBizPedidoProveedor = Nil): Boolean; begin Result := False; if not Assigned(AArticulos) then Exit; if not AArticulos.DataTable.Active then AArticulos.DataTable.Active := True; Result := Ver(AArticulos, AInventario, APedido); end; function TInventarioController.ExtraerSeleccionados(AArticulos: IBizDetalleReservas): IBizDetalleReservas; var ASeleccionados : IBizDetalleReservas; begin ASeleccionados := (FDataModule as IDataModuleInventario).GetDetalleReservasVacio; CopyDataTableDA5(AArticulos.DataTable, ASeleccionados.DataTable, True); Result := ASeleccionados; end; {procedure TInventarioController.RecibirArticulos(const APedido: IBizPedidoProveedor; const CodigoAlmacenDes: Integer); {var AArticulos: IBizInventario; // ADetalles: IBizDetallesPedidoProveedor; begin try if APedido.DataTable.FieldByName(fld_PedidosProveedorID_ALMACEN).IsNull then begin MessageBox(0, 'En el pedido que ha elegido no figura ningún almacén como destino.' + #10#13 + 'Si desea recibir este pedido en algún almacén' + #10#13 + 'modifique antes el pedido para indicarlo.', 'Atención', MB_ICONWARNING or MB_OK); Exit; end; AArticulos := Buscar(CTE_NULA); if not AArticulos.DataTable.Active then AArticulos.DataTable.Active := True; if Assigned(APedido.Detalles) then begin APedido.Detalles.First; while not APedido.Detalles.EOF do begin //Solo aquellos artículos que esten dados de alta en nuestro catálogo if (APedido.Detalles.ID_ARTICULO > 0) then begin AArticulos.Insert; if not APedido.DataTable.FieldByName(fld_PedidosProveedorID_ALMACEN).IsNull then AArticulos.ID_ALMACEN := APedido.ID_ALMACEN; if not APedido.DataTable.FieldByName(fld_PedidosProveedorID).IsNull then AArticulos.ID_PEDIDO_PROVEEDOR := APedido.ID; AArticulos.ID_ARTICULO := APedido.Detalles.ID_ARTICULO; AArticulos.REFERENCIA_CLIENTE := APedido.Detalles.REFERENCIA; AArticulos.REFERENCIA_PROVEEDOR := APedido.Detalles.REFERENCIA_PROVEEDOR; AArticulos.DESCRIPCION := APedido.Detalles.CONCEPTO; AArticulos.CANTIDAD := APedido.Detalles.CANTIDAD; AArticulos.Post; end; APedido.Detalles.Next; end; end; if RecibirArticulos(AArticulos, CodigoAlmacenDes) then PedidosProveedorController.CambiarSituacion(APedido); finally AArticulos := Nil; end; end;} procedure TInventarioController.EntradaArticulosLibre(AInventario: IBizInventario; const CodigoAlmacenDestino: Integer); var AArticulos: IBizInventario; begin try AArticulos := Buscar(CTE_NULA); //Se queda en la clase de negocio para así todos y cada uno de los artículos que //se agreguen se asigne automáticamente el codigo de almacen destino en OnNewRecord AArticulos.TipoMovimiento := tEntradaLibre; AArticulos.IDAlmacenDestino := CodigoAlmacenDestino; EntradaSalidaArticulos(AArticulos, AInventario); finally AArticulos := Nil; end; end; function TInventarioController.EntradaPedido(AInventario: IBizInventario; APedido: IBizPedidoProveedor; ADetalles: IDAStronglyTypedDataTable; var ADetallesFinal: IBizInventario): Boolean; var AArticulos: IBizInventario; begin AArticulos := Buscar(CTE_NULA); //Se queda en la clase de negocio para así todos y cada uno de los artículos que //se agreguen se asigne automáticamente el codigo de almacen destino en OnNewRecord AArticulos.TipoMovimiento := tEntradaPedidoProveedor; AArticulos.IDAlmacenDestino := APedido.ID_ALMACEN; //Inicializamos los articulos a hacer salida con los dados por parametro Copiar(AArticulos, ADetalles, AInventario); ADetallesFinal:= AArticulos; Result := EntradaSalidaArticulos(AArticulos, AInventario, APedido); end; procedure TInventarioController.RecibirAviso(ASujeto: ISujeto; ADataTable: IDAStronglyTypedDataTable); begin inherited; // end; function TInventarioController.ReservarArticulos(AArticulos, AInventario: IBizInventario): Boolean; begin Result := False; if not Assigned(AArticulos) then Exit; if not AArticulos.DataTable.Active then AArticulos.DataTable.Active := True; Result := Ver(AArticulos, AInventario); end; procedure TInventarioController.ReservarArticulosLibre(AInventario: IBizInventario; const CodigoAlmacenOrigen, CodigoAlmacenDestino: Integer); var AArticulos: IBizInventario; begin if (CodigoAlmacenOrigen <> CodigoAlmacenDestino) then begin try AArticulos := Buscar(CTE_NULA); //Se queda en la clase de negocio para así todos y cada uno de los artículos que //se agreguen se asigne automáticamente el codigo de almacen destino en OnNewRecord AArticulos.TipoMovimiento := tReserva; AArticulos.IDAlmacenOrigen := CodigoAlmacenOrigen; AArticulos.IDAlmacenDestino := CodigoAlmacenDestino; ReservarArticulos(AArticulos, AInventario); finally AArticulos := Nil; end; end; end; {procedure TInventarioController.RecibirPedidos(const CodigoAlmacenDes: Integer); var APedido: IBizPedidoProveedor; begin try APedido := FPedidosProveedorController.BuscarPendientesRecepcion; APedido := FPedidosProveedorController.ElegirPedidos(APedido, '', False); if Assigned(APedido) then RecibirArticulos(APedido, CodigoAlmacenDes); finally APedido := Nil; end; end;} function TInventarioController.SalidaAlbaran(AInventario: IBizInventario; const CodigoAlmacenOrigen: Integer; ADetalles: IDAStronglyTypedDataTable): Boolean; var AArticulos: IBizInventario; begin try Result := False; AArticulos := Buscar(CTE_NULA); //Se queda en la clase de negocio para así todos y cada uno de los artículos que //se agreguen se asigne automáticamente el codigo de almacen destino en OnNewRecord AArticulos.TipoMovimiento := tSalidaAlbaranCliente; AArticulos.IDAlmacenOrigen := CodigoAlmacenOrigen; //Inicializamos los articulos a hacer salida con los dados por parametro Copiar(AArticulos, ADetalles, AInventario); Result := EntradaSalidaArticulos(AArticulos, AInventario); finally AArticulos := Nil; end; end; procedure TInventarioController.SalidaArticulosLibre(AInventario: IBizInventario; Const CodigoAlmacenOrigen: Integer); var AArticulos: IBizInventario; begin try AArticulos := Buscar(CTE_NULA); //Se queda en la clase de negocio para así todos y cada uno de los artículos que //se agreguen se asigne automáticamente el codigo de almacen destino en OnNewRecord AArticulos.TipoMovimiento := tSalidaLibre; AArticulos.IDAlmacenOrigen := CodigoAlmacenOrigen; EntradaSalidaArticulos(AArticulos, AInventario); finally AArticulos := Nil; end; end; procedure TInventarioController.SetAlmacenesController(const Value: IAlmacenesController); begin FAlmacenesController := Value; end; procedure TInventarioController.SetObrasController(const Value: IObrasController); begin FObrasController := Value; end; procedure TInventarioController.SetArticulosController(const Value: IArticulosInventarioController); begin FArticulosController := Value end; procedure TInventarioController.SetPresupuestosClienteController(const Value: IPresupuestosClienteController); begin FPresupuestosClienteController := Value end; procedure TInventarioController.SetPedidosProveedorController(const Value: IPedidosProveedorController); begin FPedidosProveedorController := Value end; function TInventarioController.Trasladar(AInventario: IBizInventario; Todos: Boolean): Boolean; var AAlmacenes : IBizAlmacen; begin Result := False; if Assigned(AInventario) then begin ShowHourglassCursor; try //Seleccionamos almacén AAlmacenes := FAlmacenesController.BuscarTodos; if not AAlmacenes.DataTable.Active then AAlmacenes.DataTable.Active := True; AAlmacenes := FAlmacenesController.VerLista(AAlmacenes); //Aginamos el nuevo almacén if Assigned(AAlmacenes) then begin if not AInventario.DataTable.Editing then AInventario.Edit; AInventario.ID_ALMACEN := AAlmacenes.ID; AInventario.Post; AInventario.DataTable.ApplyUpdates; Result := True; // if Todos // then AInventario.DataTable.ClearRows // else AInventario.DataTable.Delete; end; finally HideHourglassCursor; end; end; end; procedure TInventarioController.TrasladarArticulosLibre(AInventario: IBizInventario; const CodigoAlmacenOrigen: Integer; Const CodigoAlmacenDestino: Integer); var AArticulos: IBizInventario; begin if (CodigoAlmacenOrigen <> CodigoAlmacenDestino) then begin try AArticulos := Buscar(CTE_NULA); //Se queda en la clase de negocio para así todos y cada uno de los artículos que //se agreguen se asigne automáticamente el codigo de almacen destino en OnNewRecord AArticulos.TipoMovimiento := tTraslado; AArticulos.IDAlmacenOrigen := CodigoAlmacenOrigen; AArticulos.IDAlmacenDestino := CodigoAlmacenDestino; EntradaSalidaArticulos(AArticulos, AInventario); finally AArticulos := Nil; end; end; end; procedure TInventarioController.TrasladarReservas(AReservas: IBizDetalleReservas); var AArticulo: IBizInventario; begin ShowHourglassCursor; try with AReservas.DataTable do begin first; while not eof do begin //Preparamos el articulo a trasladar con la cantidad correspondiente AArticulo := Buscar(CTE_NULA); AArticulo.DataTable.Active := True; // DesconectarTabla(AArticulo.DataTable); AArticulo.Edit; AArticulo.ID_ALMACEN := AReservas.ID_ALMACEN; AArticulo.ID_ARTICULO := AReservas.ID_ARTICULO; AArticulo.CANTIDAD := AReservas.CANTIDAD; AArticulo.Post; // ConectarTabla(AArticulo.DataTable); //Se queda en la clase de negocio para así todos y cada uno de los artículos que //se agreguen se asigne automáticamente el codigo de almacen destino en OnNewRecord AArticulo.TipoMovimiento := tTraslado; AArticulo.IDAlmacenOrigen := AReservas.ID_ALMACEN; AArticulo.IDAlmacenDestino := AReservas.ID_ALMACEN_RESERVA; GuardarMovimientos(AArticulo, AReservas.FECHA_RESERVA, 'Traslado de material por la reserva: ' + AReservas.CAUSA_RESERVA); // showmessage('trasladar: ' + IntToStr(AReservas.ID_ARTICULO) + ',' + IntToStr(AReservas.ID_ALMACEN) + ',' + IntToStr(AReservas.ID_ALMACEN_RESERVA)); next; end; end; //Eliminamos los registro de reserva relacionados en la tabla de movimientos CancelarReservas(AReservas); finally HideHourglassCursor; end; end; { function TInventarioController.Trasladar: Boolean; begin end; function TInventarioController.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; } procedure TInventarioController.FiltrarEmpresa(AInventario: IBizInventario); var Condicion: TDAWhereExpression; begin if AInventario.DataTable.Active then AInventario.DataTable.Active := False; // Filtrar los inventario actuales por empresa with AInventario.DataTable.DynamicWhere do begin // (ID_EMPRESA >= ID) Condicion := NewBinaryExpression(NewField('', fld_InventarioID_EMPRESA), NewConstant(AppFactuGES.EmpresaActiva.ID, datInteger), dboEqual); if IsEmpty then Expression := Condicion else Expression := NewBinaryExpression(Expression, Condicion, dboAnd); end; end; function TInventarioController.GetAlmacenesController: IAlmacenesController; begin Result := FAlmacenesController; end; function TInventarioController.GetObrasController: IObrasController; begin Result := FObrasController; end; function TInventarioController.GetArticulosController: IArticulosInventarioController; begin Result := FArticulosController; end; function TInventarioController.GetPresupuestosClienteController: IPresupuestosClienteController; begin Result := FPresupuestosClienteController; end; function TInventarioController.GetPedidosProveedorController: IPedidosProveedorController; begin Result := FPedidosProveedorController; end; {procedure TInventarioController.GuardarArticulos(AInventario : IBizInventario); var AArticulos: IBizInventario; i: Integer; begin AArticulosUnitarios := Buscar(CTE_NULA); if not AArticulosUnitarios.DataTable.Active then AArticulosUnitarios.DataTable.Active := True; with AInventario do begin DataTable.First; while not DataTable.EOF do begin for i:=0 to (CANTIDAD - 1) do begin AArticulosUnitarios.Insert; AArticulosUnitarios.ID_ALMACEN := ID_ALMACEN; AArticulosUnitarios.ID_ARTICULO := ID_ARTICULO; if not DataTable.FieldByName(fld_INVENTARIOID_PEDIDO_PROVEEDOR).IsNull then AArticulosUnitarios.ID_PEDIDO_PROVEEDOR := ID_PEDIDO_PROVEEDOR; if not DataTable.FieldByName(fld_INVENTARIOID_PEDIDO_CLIENTE).IsNull then AArticulosUnitarios.ID_PEDIDO_CLIENTE := ID_PEDIDO_CLIENTE; AArticulosUnitarios.DESCRIPCION := DESCRIPCION; AArticulosUnitarios.Post; AssignarID(AArticulosUnitarios, (FDataModule as IDataModuleInventario)); end; DataTable.Next; end; DataTable.CancelUpdates; AArticulosUnitarios.DataTable.ApplyUpdates; end; end;} function TInventarioController.Liberar(AInventario: IBizInventario; Todos: Boolean): Boolean; begin Result := False; { if not Assigned(AInventario) then exit; try with AInventario.DataTable do begin if not Active then Active := True; if Todos then begin First; while not EOF do begin Edit; FieldByName(fld_INVENTARIOID_PEDIDO_CLIENTE).AsVariant := Null; Post; Next; end; end else begin Edit; FieldByName(fld_INVENTARIOID_PEDIDO_CLIENTE).AsVariant := Null; Post; Next; end; ApplyUpdates; Result := True; end; except on E: EDAApplyUpdateFailed do begin AInventario.DataTable.CancelUpdates; showmessage('Error al liberar los artículos seleccionados'); end; end; } end; function TInventarioController.Liberar(AInventario : IBizInventario): Boolean; begin Result := False; if Assigned(AInventario) then Result := Liberar(AInventario, False); end; procedure TInventarioController.DeshabilitarOnCalcFields(Sender: TDADataTable); begin // Deshabilita el devolver RECID para la localización unica de tuplas de inventario // Para así poder utiliza ID para la inserción de movimientos end; function TInventarioController.Guardar(AArticulos: IBizInventario; const FechaMovimiento: TDateTime; const CausaMovimiento: String; AValidar:Boolean = True): Boolean; begin Result := False; if not Assigned(AArticulos) then raise Exception.Create ('Artículos no asignados'); if not AValidar or (AValidar and Validar(AArticulos)) then //Evaluacion perezosa begin ShowHourglassCursor; try case AArticulos.TipoMovimiento of tEntradaLibre, tSalidaLibre, tTraslado, tReserva: Result := GuardarMovimientos(AArticulos, FechaMovimiento, CausaMovimiento); tSalidaAlbaranCliente : begin AArticulos.DataTable.CancelUpdates; Result := True; end; tEntradaPedidoProveedor : Result := True; //Dar de alta el albarán end; finally HideHourglassCursor; end; end else AArticulos.DataTable.CancelUpdates; end; function TInventarioController.GuardarMovimientos(AArticulos: IBizInventario; const FechaMovimiento: TDateTime; const CausaMovimiento: String): Boolean; var AArticulosTraslado : IBizInventario; begin Result := False; if Assigned(AArticulos) then begin //Eliminamos todos los articulos que no esten en el catalogo ya que estos no se podrán reservar repeat if (AArticulos.ID_ARTICULO < 1) then AArticulos.Delete; AArticulos.First; until (AArticulos.DataTable.Locate('ID_ARTICULO', '0', []) = false); //Deshabilitamos el calculo de ID (RECID) para poderlo usar para la inserción de movimientos AArticulos.DataTable.OnCalcFields := DeshabilitarOnCalcFields; with AArticulos.DataTable do begin First; while not EOF do begin if not Editing then Edit; //Realmente son los campos de la tabla movimientos los que estamos asignando //que luego por comandos se realizarán las inserciones AArticulos.FECHA_MOVIMIENTO := FechaMovimiento; AArticulos.CAUSA := CausaMovimiento; case AArticulos.TipoMovimiento of tEntradaLibre: AArticulos.TIPO := CTE_TIPO_ENTRADA; tSalidaLibre, tTraslado: AArticulos.TIPO := CTE_TIPO_SALIDA; tReserva: begin AArticulos.TIPO := CTE_TIPO_RESERVA; AArticulos.ID_ALMACEN_RESERVA := AArticulos.IDAlmacenDestino; end; end; Post; Next; end; //Solo para traslados, realizaremos los mismos movimientos, pero en este caso //de entrada en el almacén destino if (AArticulos.TipoMovimiento = tTraslado) then begin AArticulosTraslado := Buscar(CTE_NULA); //Deshabilitamos el calculo de ID (RECID) para poderlo usar para la inserción de movimientos AArticulosTraslado.DataTable.OnCalcFields := DeshabilitarOnCalcFields; AArticulosTraslado.DataTable.Active := True; First; while not EOF do begin AArticulosTraslado.Insert; AArticulosTraslado.ID_ALMACEN := AArticulos.IDAlmacenDestino; AArticulosTraslado.ID_ARTICULO := AArticulos.ID_ARTICULO; AArticulosTraslado.FECHA_MOVIMIENTO := AArticulos.FECHA_MOVIMIENTO; AArticulosTraslado.CAUSA := AArticulos.CAUSA; AArticulosTraslado.TIPO := CTE_TIPO_ENTRADA; AArticulosTraslado.CANTIDAD := AArticulos.CANTIDAD; AArticulosTraslado.Post; Next; end; AArticulosTraslado.DataTable.ApplyUpdates; end; ApplyUpdates; Result := True; end; end; end; {function TInventarioController.Nuevo: IBizArticulo; var AArticulo : IBizArticulo; begin AArticulo := FDataModule.NewItem; FiltrarEmpresa(AArticulo); AArticulo.DataTable.Active := True; AArticulo.Insert; Result := AArticulo; end; } { procedure TInventarioController.Preview(AArticulo: IBizArticulo); var AReportController : IArticulosReportController; begin AReportController := TArticulosReportController.Create; try AReportController.Preview(AArticulo.ID); finally AReportController := NIL; end; end; procedure TInventarioController.Print(AArticulo: IBizArticulo); var AReportController : IArticulosReportController; begin AReportController := TArticulosReportController.Create; try AReportController.Print(AArticulo.ID); finally AReportController := NIL; end; end; } end.