unit uControllerDetallesArticulos; interface uses Classes, Variants, uDACDSDataTable, uDADataTable, uControllerDetallesBase, uBizArticulos, uArticulosController; const CAMPO_REFERENCIA = 'REFERENCIA'; //Campo ficticio CAMPO_REFERENCIA_PROVEEDOR = 'REFERENCIA_PROVEEDOR'; //Campo ficticio type TEnumReferencia = (tCliente, tProveedor); IControllerDetallesArticulos = interface(IControllerDetallesBase) ['{6E156796-DB1F-4727-BBFB-FBAEF2E5C098}'] procedure AnadirArticulos(ADetalles: IDAStronglyTypedDataTable); function AnadirArticulo(ADetalles: IDAStronglyTypedDataTable; Referencia: String; TipoReferencia: TEnumReferencia; AClienteID: Integer = -1): Boolean; overload; function AnadirArticulo(ADetalles: IDAStronglyTypedDataTable; IDArticulo: Integer; AClienteID: Integer = -1): Boolean; overload; procedure ActualizarDetalles(ADetalles: IDAStronglyTypedDataTable; AArticulos: IBizArticulo); procedure CambiarSignoDetalles(ADetalles: IDAStronglyTypedDataTable); procedure AnadirConceptoInicial(ADetalles: IDAStronglyTypedDataTable; AConcepto: String); end; TControllerDetallesArticulos = class (TControllerDetallesBase, IControllerDetallesArticulos) protected FArticulosController: IArticulosController; procedure EliminarArticulosProveedor(ADetalles: IDAStronglyTypedDataTable); procedure AsignarDatos(ADetalles: IDAStronglyTypedDataTable; IDCabecera: Integer); virtual; procedure RellenarOtros(ADetalles: IDAStronglyTypedDataTable; AArticulos: IBizArticulo); virtual; procedure RellenarImportes(ADetalles: IDAStronglyTypedDataTable; AArticulos: IBizArticulo); virtual; procedure RellenarGenerales(ADetalles: IDAStronglyTypedDataTable; AArticulos: IBizArticulo); virtual; procedure RellenarDetalle(ADetalles: IDAStronglyTypedDataTable; AArticulos: IBizArticulo); virtual; procedure Add(ADetalles: IDAStronglyTypedDataTable; AArticulos: IBizArticulo); overload; procedure AsignarController; virtual; public function AnadirArticulo(ADetalles: IDAStronglyTypedDataTable; Referencia: String; TipoReferencia: TEnumReferencia; AClienteID: Integer = -1): Boolean; overload; function AnadirArticulo(ADetalles: IDAStronglyTypedDataTable; IDArticulo: Integer; AClienteID: Integer = -1): Boolean; overload; procedure AnadirArticulos(ADetalles: IDAStronglyTypedDataTable); virtual; procedure ActualizarDetalles(ADetalles: IDAStronglyTypedDataTable; AArticulos: IBizArticulo); procedure CambiarSignoDetalles(ADetalles: IDAStronglyTypedDataTable); procedure AnadirConceptoInicial(ADetalles: IDAStronglyTypedDataTable; AConcepto: String); constructor Create; override; destructor Destroy; override; end; implementation { TControllerDetallesArticulos } uses DB, Dialogs, cxControls, SysUtils, uDAInterfaces, uCalculosUtils, schArticulosClient_Intf; { TControllerDetallesArticulos } procedure TControllerDetallesArticulos.ActualizarDetalles(ADetalles: IDAStronglyTypedDataTable; AArticulos: IBizArticulo); begin if (Assigned(ADetalles) and Assigned(AArticulos)) then begin if not AArticulos.DataTable.Active then AArticulos.DataTable.Active := True; BeginUpdate(ADetalles); try ADetalles.DataTable.First; with ADetalles.DataTable do begin while not Eof do begin Edit; AArticulos.DataTable.First; try if AArticulos.DataTable.Locate(CAMPO_ID, FieldByName(CAMPO_ID_ARTICULOS).AsVariant, []) then RellenarDetalle(ADetalles, AArticulos) else RellenarDetalle(ADetalles, Nil); except on E: Exception do ShowMessage(E.Message); end; Next; end; //Volvemos a dejarlo al principio ADetalles.DataTable.First; end; finally EndUpdate(ADetalles); end; end; end; procedure TControllerDetallesArticulos.Add(ADetalles: IDAStronglyTypedDataTable; AArticulos: IBizArticulo); begin if Assigned(ADetalles) and Assigned(AArticulos) then begin try ShowHourglassCursor; BeginUpdate(ADetalles); if not ADetalles.DataTable.Active then ADetalles.DataTable.Active := True; if not AArticulos.DataTable.Active then AArticulos.DataTable.Active := True; with AArticulos.DataTable do begin First; while not EOF do begin Self.Add(ADetalles, TIPO_DETALLE_CONCEPTO); RellenarDetalle(ADetalles, AArticulos); Next; end; end; finally EndUpdate(ADetalles); HideHourglassCursor; end; end; end; function TControllerDetallesArticulos.AnadirArticulo(ADetalles: IDAStronglyTypedDataTable; IDArticulo: Integer; AClienteID: Integer = -1): Boolean; var AArticulo: IBizArticulo; begin { Añade el artículo con la referencia pasada por parametro a los detalles pasados por parametro En el caso de asignar un AClienteID el articulo debe contener el descuento para ese cliente } Result := False; BeginUpdate(ADetalles); ShowHourglassCursor; try AArticulo := FArticulosController.Buscar(IDArticulo, AClienteID); if Assigned(AArticulo) then begin AArticulo.DataTable.Active := True; if (AArticulo.RecordCount > 0) then begin RellenarDetalle(ADetalles, AArticulo); Result := True; end; end; finally EndUpdate(ADetalles); HideHourglassCursor; end; end; procedure TControllerDetallesArticulos.AnadirArticulos(ADetalles: IDAStronglyTypedDataTable); var AArticulos: IBizArticulo; begin if Assigned(ADetalles) then begin try AArticulos := (FArticulosController.BuscarTodos as IBizArticulo); AArticulos := FArticulosController.ElegirArticulos(AArticulos, 'Elija los artículos que desea añadir', True); Add(ADetalles, AArticulos); finally AArticulos := Nil; end; end; end; procedure TControllerDetallesArticulos.AnadirConceptoInicial(ADetalles: IDAStronglyTypedDataTable; AConcepto: String); begin if Assigned(ADetalles) then begin With ADetalles.DataTable do begin First; Add(ADetalles, TIPO_DETALLE_TITULO); Edit; FieldByName(CAMPO_CONCEPTO).AsString := AConcepto; Post; //Subimos la linea insertada al inicio de los detalles Self.Mover(ADetalles.DataTable, 1, -1); //Añadimos linea en blanco Add(ADetalles, TIPO_DETALLE_CONCEPTO); Edit; FieldByName(CAMPO_CONCEPTO).AsString := ''; Post; // First; end; end; end; procedure TControllerDetallesArticulos.AsignarController; begin FArticulosController := TArticulosController.Create; end; procedure TControllerDetallesArticulos.AsignarDatos(ADetalles: IDAStronglyTypedDataTable; IDCabecera: Integer); begin // end; procedure TControllerDetallesArticulos.CambiarSignoDetalles(ADetalles: IDAStronglyTypedDataTable); begin //Cambia de signo los detalles de la pasados por parámetro if Assigned(ADetalles) then begin try BeginUpdate(ADetalles); if not ADetalles.DataTable.Active then ADetalles.DataTable.Active := True; with ADetalles.DataTable do begin First; while not EOF do begin if (FieldByName(CAMPO_CANTIDAD).AsInteger <> 0) then begin Edit; FieldByName(CAMPO_CANTIDAD).AsInteger := -1; end; Next; end; end; finally EndUpdate(ADetalles); end; end; end; constructor TControllerDetallesArticulos.Create; begin inherited; AsignarController; end; destructor TControllerDetallesArticulos.Destroy; begin FArticulosController := Nil; inherited; end; procedure TControllerDetallesArticulos.EliminarArticulosProveedor(ADetalles: IDAStronglyTypedDataTable); begin if Assigned(ADetalles) then begin with ADetalles.DataTable do begin First; while not Eof do if not FieldByName(CAMPO_ID_ARTICULOS).IsNull then Delete else Next; end; end; end; function TControllerDetallesArticulos.AnadirArticulo(ADetalles: IDAStronglyTypedDataTable; Referencia: String; TipoReferencia: TEnumReferencia; AClienteID: Integer = -1): Boolean; var AArticulo: IBizArticulo; begin { Añade el artículo con la referencia pasada por parametro a los detalles pasados por parametro En el caso de asignar un AClienteID el articulo debe contener el descuento para ese cliente } Result := False; BeginUpdate(ADetalles); ShowHourglassCursor; try case TipoReferencia of tCliente: AArticulo := FArticulosController.BuscarReferencia(Referencia, AClienteID); tProveedor: AArticulo := FArticulosController.BuscarReferenciaProveedor(Referencia, AClienteID) end; if Assigned(AArticulo) then begin AArticulo.DataTable.Active := True; if (AArticulo.RecordCount > 0) then begin RellenarDetalle(ADetalles, AArticulo); Result := True; end; end; finally EndUpdate(ADetalles); HideHourglassCursor; end; end; procedure TControllerDetallesArticulos.RellenarOtros(ADetalles: IDAStronglyTypedDataTable; AArticulos: IBizArticulo); begin // Procedimiento que en los hijos se sobreescribirá para rellenar otros campos según necesidades end; procedure TControllerDetallesArticulos.RellenarDetalle(ADetalles: IDAStronglyTypedDataTable; AArticulos: IBizArticulo); begin if Assigned(ADetalles) then begin if not ADetalles.DataTable.Editing then ADetalles.DataTable.Edit; RellenarGenerales(ADetalles, AArticulos); RellenarImportes(ADetalles, AArticulos); RellenarOtros(ADetalles, AArticulos); ADetalles.DataTable.Post; end; end; procedure TControllerDetallesArticulos.RellenarGenerales(ADetalles: IDAStronglyTypedDataTable; AArticulos: IBizArticulo); begin if Assigned(AArticulos) then begin ADetalles.DataTable.FieldByName(CAMPO_ID_ARTICULOS).AsVariant := AArticulos.ID; ADetalles.DataTable.FieldByName(CAMPO_REFERENCIA).AsVariant := AArticulos.REFERENCIA; ADetalles.DataTable.FieldByName(CAMPO_REFERENCIA_PROVEEDOR).AsVariant := AArticulos.REFERENCIA_PROV; ADetalles.DataTable.FieldByName(CAMPO_CONCEPTO).AsVariant := AArticulos.DESCRIPCION; ADetalles.DataTable.FieldByName(CAMPO_CANTIDAD).AsInteger := 1; end; end; procedure TControllerDetallesArticulos.RellenarImportes(ADetalles: IDAStronglyTypedDataTable; AArticulos: IBizArticulo); begin // Procedimiento que en los hijos se sobreescribirá para rellenar el campo importe según necesidades end; end.