unit uBizPedidosProveedor; interface uses uDAInterfaces, uDADataTable, Classes, Controls, uBizContacto, schPedidosProveedorClient_Intf, uBizImportesDetalleBase, uBizImportesCabeceraBase, uExceptions, uBizInformesBase, DB, uDBSelectionList, uBizPresupuestosCliente, uBizMontajes; const BIZ_PEDIDOSPROVEEDOR = 'Client.PedidoProveedor'; BIZ_DETALLESPEDIDOSPROVEEDOR = 'Client.DetallesPedidoProveedor'; SITUACION_PENDIENTE = 'Pendiente'; SITUACION_PARCIAL = 'Parcialmente recibido'; SITUACION_RECIBIDO = 'Recibido'; type IBizDetallesPedidoProveedor = interface(IDetallesPedidosProveedor) ['{4B5CF17E-23E1-489F-B591-AC19C7A5BDDC}'] procedure CopyFrom(ADetallesPresupuesto : IBizDetallesPresupuesto); overload; procedure CopyFrom(ADetallesPedido : IBizDetallesPedidoProveedor); overload; end; IBizPedidosProveedor = interface(IPedidosProveedor) ['{0A258465-6526-483B-AEE9-3DB3750D3C12}'] function GetDetalles: IBizDetallesPedidoProveedor; procedure SetDetalles(const Value: IBizDetallesPedidoProveedor); property Detalles: IBizDetallesPedidoProveedor read GetDetalles write SetDetalles; function GetProveedor: IBizProveedor; procedure SetProveedor(const Value: IBizProveedor); property Proveedor: IBizProveedor read GetProveedor write SetProveedor; function GetMontaje: IBizMontaje; procedure SetMontaje(const Value: IBizMontaje); property Montaje: IBizMontaje read GetMontaje write SetMontaje; procedure Show; function ShowForSelect : TModalResult; procedure CopyFrom(APedido : IBizPedidosProveedor); procedure CambiarSituacion(ASituacion: String); // procedure Preview; // procedure CalcularTotal; end; TBizDetallesPedidoProveedor = class(TDetallesPedidosProveedorDataTableRules, IBizDetallesPedidoProveedor, IBizImportesDetalle, IParche) // PARCHE *********************** private FIsAppend : Boolean; FPosicionNueva : Integer; FPuedoLanzarEvento : Boolean; // PARCHE *********************** protected procedure OnNewRecord(Sender: TDADataTable); override; procedure BeforeInsert(Sender: TDADataTable); override; procedure AfterPost(Sender: TDADataTable); override; procedure AfterInsert(Sender: TDADataTable); override; procedure AfterDelete(Sender: TDADataTable); override; procedure BeforeDelete(Sender: TDADataTable); override; // PARCHE *********************** procedure ActivarEventos; procedure DesactivarEventos; procedure Refrescar; function PuedoLanzarEvento : Boolean; public procedure RecalcularImporte; function DarSumaTotalImportes : Currency; constructor Create(aDataTable: TDADataTable); override; destructor destroy; override; procedure CopyFrom(ADetallesPresupuesto : IBizDetallesPresupuesto); overload; procedure CopyFrom(ADetallesPedido : IBizDetallesPedidoProveedor); overload; end; TBizPedidosProveedor = class(TPedidosProveedorDataTableRules, IBizPedidosProveedor, IBizImportesCabecera, ISelectedRowList, IApplyUpdateFailedException, IBizInformesAware) private FProveedor : IBizProveedor; FMontaje : IBizMontaje; FDetalles: IBizDetallesPedidoProveedor; FDetallesLink: TDADataSource; FSelectedRows : TSelectedRowList; protected procedure SetCODIGOALMACENValue(const aValue: Integer); override; procedure ShowApplyUpdateFailed(const Error: EDAApplyUpdateFailed); function GetDetalles: IBizDetallesPedidoProveedor; procedure SetDetalles(const Value: IBizDetallesPedidoProveedor); function GetProveedor: IBizProveedor; procedure SetProveedor(const Value: IBizProveedor); function GetMontaje: IBizMontaje; procedure SetMontaje(const Value: IBizMontaje); procedure BeforeApplyUpdates(Sender : TDADataTable; const Delta : IDADelta); procedure OnNewRecord(Sender: TDADataTable); override; function GetSelectedRows : TSelectedRowList; procedure BeforeDelete(Sender: TDADataTable); override; procedure AfterDelete(Sender: TDADataTable); override; procedure OnPostError(DataTable: TDADataTable; Error: EDatabaseError; var Action: TDataAction); override; public property Proveedor: IBizProveedor read GetProveedor write SetProveedor; property Montaje: IBizMontaje read GetMontaje write SetMontaje; property Detalles: IBizDetallesPedidoProveedor read GetDetalles write SetDetalles; property SelectedRows : TSelectedRowList read GetSelectedRows; procedure RecalcularImporte; procedure Show; virtual; function ShowForSelect : TModalResult; procedure Preview; procedure Print; procedure CopyFrom(APedido : IBizPedidosProveedor); procedure CambiarSituacion(ASituacion: String); constructor Create(aDataTable: TDADataTable); override; destructor Destroy; override; end; procedure ValidarPedido (const APedido : IBizPedidosProveedor); implementation uses Dialogs, uDACDSDataTable, SysUtils, uEditorUtils, uDataModuleContactos, Variants, Math, Windows, uROClasses, uDataModulePedidosProveedor, uDataModuleBase, uDataModuleUsuarios, FactuGES_Intf, uDataTableUtils, Forms, uDataModuleMontajes; var FMasterDeleting : Boolean; FCancelInsert : Boolean; procedure ValidarPedido (const APedido : IBizPedidosProveedor); begin if (APedido.CODIGOALMACEN = 0) and (Length(APedido.DIRECCIONCOMPLETA.Text) = 0) then raise Exception.Create('Debe indicar un almacén o una dirección alternativa donde recibir el pedido'); end; { TBizPedidosProveedor } procedure TBizPedidosProveedor.AfterDelete(Sender: TDADataTable); begin inherited; FMasterDeleting := False; end; procedure TBizPedidosProveedor.BeforeApplyUpdates(Sender: TDADataTable; const Delta: IDADelta); var i : integer; begin for i := 0 to Delta.Count - 1 do case Delta.Changes[i].ChangeType of ctInsert, ctUpdate : ValidarPedido(Self); //ctDelete : end; end; procedure TBizPedidosProveedor.BeforeDelete(Sender: TDADataTable); begin inherited; if not dmPedidos.PuedoEliminarPedido(CODIGO) then raise Exception.Create('No se puede borrar este pedido porque tiene ya se han recibido artículos suyos en algún almacén'); FMasterDeleting := True; // Para que los detalles se borren de golpe y no recalcule posiciones ni totales end; procedure TBizPedidosProveedor.CambiarSituacion(ASituacion: String); begin if not (Self.DataTable.State in dsEditModes) then Self.DataTable.Edit; Self.SITUACION := ASituacion; Self.FECHAENTREGA := Date; Self.Post; Self.DataTable.ApplyUpdates; end; procedure TBizPedidosProveedor.CopyFrom(APedido: IBizPedidosProveedor); begin DataTable.DisableEventHandlers; try if not APedido.DataTable.Active then APedido.DataTable.Active := True; CODIGOEMPRESA := APedido.CODIGOEMPRESA; CODIGOCONTACTO := APedido.CODIGOCONTACTO; REFERENCIA := APedido.REFERENCIA; IMPORTETOTAL := APedido.IMPORTETOTAL; OBSERVACIONES := APedido.OBSERVACIONES; DIRECCIONCOMPLETA := APedido.DIRECCIONCOMPLETA; INCIDENCIAS := APedido.INCIDENCIAS; if not APedido.DataTable.FieldByName(fld_PedidosProveedorCODIGOALMACEN).IsNull then CODIGOALMACEN := APedido.CODIGOALMACEN; if not APedido.DataTable.FieldByName(fld_PedidosProveedorCODIGOMONTAJE).IsNull then CODIGOMONTAJE := APedido.CODIGOMONTAJE; finally DataTable.EnableEventHandlers; end; Post; Detalles.CopyFrom(APedido.Detalles); end; constructor TBizPedidosProveedor.Create(aDataTable: TDADataTable); begin inherited; FProveedor := NIL; // FMontaje := NIL; FDetallesLink := TDADataSource.Create(NIL); FSelectedRows := TSelectedRowList.Create(aDataTable); aDataTable.OnBeforeApplyUpdates := BeforeApplyUpdates; end; destructor TBizPedidosProveedor.Destroy; begin FProveedor := NIL; // FMontaje := NIL; FDetalles := NIL; FDetallesLink.Free; FSelectedRows.Free; inherited; end; function TBizPedidosProveedor.GetDetalles: IBizDetallesPedidoProveedor; begin Result := FDetalles; { if not Assigned(FDetalles) then FDetalles := (dmPedidos.GetItem(CODIGO)).detalles; { else if (CODIGOMONTAJE <> FMontaje.Codigo) and not (FMontaje.DataTable.State in dsEditModes) then FMontaje := dmMontajes.GetItem(CODIGOMONTAJE); if not FMontaje.DataTable.Active then FMontaje.DataTable.Active := True; Result := FDetalles; } end; function TBizPedidosProveedor.GetMontaje: IBizMontaje; begin if not Assigned(FMontaje) then FMontaje := dmMontajes.GetItem(CODIGOMONTAJE) else if (CODIGOMONTAJE <> FMontaje.Codigo) and not (FMontaje.DataTable.State in dsEditModes) then FMontaje := dmMontajes.GetItem(CODIGOMONTAJE); if not FMontaje.DataTable.Active then FMontaje.DataTable.Active := True; Result := FMontaje; end; function TBizPedidosProveedor.GetProveedor: IBizProveedor; begin if not Assigned(FProveedor) then FProveedor := dmContactos.GetProveedor(CODIGOCONTACTO) else if (CODIGOCONTACTO <> FProveedor.Codigo) and not (FProveedor.DataTable.State in dsEditModes) then dmContactos.GetContacto(FProveedor, CODIGOCONTACTO); if not FProveedor.DataTable.Active then FProveedor.DataTable.Active := True; Result := FProveedor; end; function TBizPedidosProveedor.GetSelectedRows: TSelectedRowList; begin Result := FSelectedRows; end; procedure TBizPedidosProveedor.OnNewRecord(Sender: TDADataTable); var Cadenas: TStringList; begin inherited; CODIGOEMPRESA := dmBase.CodigoEmpresa; USUARIO := dmUsuarios.LoginInfo.UserID; FECHAALTA := Date; FECHAPEDIDO := Date; FECHACONFIRMACION := FECHAPEDIDO + 3; SITUACION := SITUACION_PENDIENTE; CODIGO := dmPedidos.GetNextAutoinc; //Rellenamos las caracteristicas por defecto del pedido Cadenas := TStringList.Create; Cadenas.Append('Modelo: '); Cadenas.Append(''); Cadenas.Append('Tirador: '); Cadenas.Append(''); Cadenas.Append('Color de casco: '); Cadenas.Append(''); Cadenas.Append('Cristal: '); Self.DataTable.FieldByName(fld_PedidosProveedorOBSERVACIONES).AsString := Cadenas.Text; FreeAndNil(Cadenas); end; procedure TBizPedidosProveedor.OnPostError(DataTable: TDADataTable; Error: EDatabaseError; var Action: TDataAction); begin inherited; Action := daAbort; if (Pos(AUF_HAVEVALUE, Error.Message) > 0) then begin if (Pos('contacto', Error.Message) > 0) then MessageBox(0, 'Debe indicar el proveedor de este pedido', 'Atención', MB_ICONWARNING or MB_OK); if (Pos('Fecha pedido', Error.Message) > 0) then MessageBox(0, 'Debe indicar la fecha de este pedido', 'Atención', MB_ICONWARNING or MB_OK); end else raise Error; end; procedure TBizPedidosProveedor.Preview; begin dmPedidos.Preview(CODIGO); end; procedure TBizPedidosProveedor.Print; begin dmPedidos.Print(CODIGO); end; procedure TBizPedidosProveedor.RecalcularImporte; begin // No hay que recalcular importes // RecalcularImportesCabecera(Self.DataTable, Detalles.DataTable); end; procedure TBizPedidosProveedor.SetCODIGOALMACENValue(const aValue: Integer); begin if aValue = 0 then DataTable.Fields[idx_PedidosProveedorCODIGOALMACEN].AsVariant := NULL else inherited; end; procedure TBizPedidosProveedor.SetDetalles(const Value: IBizDetallesPedidoProveedor); begin FDetalles := Value; FDetallesLink.DataTable := Self.DataTable; FDetalles.DataTable.MasterSource := FDetallesLink; end; procedure TBizPedidosProveedor.SetMontaje(const Value: IBizMontaje); var bEnEdicion : Boolean; begin bEnEdicion := (DataTable.State in dsEditModes); if not bEnEdicion then Edit; FMontaje := Value; if Assigned(FMontaje) then begin CODIGOMONTAJE := FMontaje.CODIGO; REFERENCIA := FMontaje.REFERENCIA; Post; if (MessageBox(0, 'Si lo desea, puede utilizar los conceptos del presupuesto ' + #10#13 + 'de este montaje para rellenar el pedido nuevo que va a hacer.' + #10#13 + #10#13 + '¿Desea copiar los conceptos del presupuesto al pedido nuevo?', 'Confirmación', MB_ICONQUESTION or MB_YESNO) = idYes) then Self.Detalles.CopyFrom(FMontaje.Presupuesto.Detalles); if bEnEdicion then Edit; end end; procedure TBizPedidosProveedor.SetProveedor(const Value: IBizProveedor); var bEnEdicion : Boolean; begin bEnEdicion := (DataTable.State in dsEditModes); if not bEnEdicion then Edit; FProveedor := Value; if Assigned(FProveedor) then begin CODIGOCONTACTO := FProveedor.CODIGO; Post; if bEnEdicion then Edit; end end; procedure TBizPedidosProveedor.Show; begin ShowEditor(IBizPedidosProveedor, Self, etItem); end; procedure TBizPedidosProveedor.ShowApplyUpdateFailed( const Error: EDAApplyUpdateFailed); begin if (Pos(AUF_FKVIOLATION, Error.Message) > 0) then MessageBox(0, 'No se puede borrar este pedido porque tiene un algo asociado', 'Atención', MB_ICONWARNING or MB_OK); end; function TBizPedidosProveedor.ShowForSelect: TModalResult; begin Result := ShowEditor(IBizPedidosProveedor, Self, etSelectItems); end; { TBizDetallesPedidoProveedor } procedure TBizDetallesPedidoProveedor.ActivarEventos; begin FPuedoLanzarEvento := True; end; procedure TBizDetallesPedidoProveedor.AfterDelete(Sender: TDADataTable); var ACabecera : IBizImportesCabecera; begin inherited; // PARCHE ******************* if not PuedoLanzarEvento then Exit; if (not FMasterDeleting) and (not FCancelInsert) then begin ReasignarPosiciones(Self.DataTable); if Assigned(DataTable.MasterSource) and Supports(DataTable.MasterSource.DataTable, IBizImportesCabecera, ACabecera) then ACabecera.RecalcularImporte; end; FCancelInsert := False; end; procedure TBizDetallesPedidoProveedor.AfterInsert(Sender: TDADataTable); begin inherited; // PARCHE ******************* if not PuedoLanzarEvento then Exit; FIsAppend := DataTable.EOF; Post; // Para lanzar AfterPost y asigne posición Edit; // Para volver a dejarlo en modo de edición end; procedure TBizDetallesPedidoProveedor.AfterPost(Sender: TDADataTable); begin inherited; // PARCHE ******************* if not PuedoLanzarEvento then Exit; if POSICION < 0 then AsignarPosicion(Self.DataTable, FIsAppend); if NUMCONCEPTO < 0 then AsignarNumConcepto(Self.DataTable); FIsAppend := False; end; procedure TBizDetallesPedidoProveedor.BeforeDelete(Sender: TDADataTable); begin inherited; // PARCHE ******************* if not PuedoLanzarEvento then Exit; if (DataTable.State in dsEditModes) then DataTable.Cancel; if not FMasterDeleting then FCancelInsert := not (DataTable.MasterSource.DataTable.FieldByName('CODIGO').AsInteger = CODIGOPEDIDO); end; procedure TBizDetallesPedidoProveedor.BeforeInsert(Sender: TDADataTable); begin inherited; // PARCHE ******************* if not PuedoLanzarEvento then Exit; if Assigned(DataTable.MasterSource) and (DataTable.MasterSource.DataTable.State in dsEditModes) then DataTable.MasterSource.DataTable.Post; if GetRecordCount = 0 then FPosicionNueva := -1 else FPosicionNueva := POSICION * (-1); end; procedure TBizDetallesPedidoProveedor.CopyFrom(ADetallesPresupuesto: IBizDetallesPresupuesto); begin DeleteAllTable(Self.DataTable); ADetallesPresupuesto.First; while not ADetallesPresupuesto.EOF do begin if (ADetallesPresupuesto.TIPO <> TIPODETALLE_SUBTOTAL) then begin try Append; DataTable.DisableEventHandlers; TIPO := ADetallesPresupuesto.TIPO; DESCRIPCION := ADetallesPresupuesto.DESCRIPCION; CANTIDAD := ADetallesPresupuesto.CANTIDAD; //Por si lo piden para saber el precio de venta // IMPORTEUNIDAD := ADetallesPresupuesto.IMPORTEUNIDAD; // IMPORTETOTAL := ADetallesPresupuesto.IMPORTETOTAL; finally DataTable.EnableEventHandlers; end; Post; end; ADetallesPresupuesto.Next; end; end; procedure TBizDetallesPedidoProveedor.CopyFrom(ADetallesPedido: IBizDetallesPedidoProveedor); begin ADetallesPedido.First; while not ADetallesPedido.EOF do begin Append; DataTable.DisableEventHandlers; NUMCONCEPTO := ADetallesPedido.NUMCONCEPTO; POSICION := ADetallesPedido.POSICION; TIPO := ADetallesPedido.TIPO; DESCRIPCION := ADetallesPedido.DESCRIPCION; CANTIDAD := ADetallesPedido.CANTIDAD; if not ADetallesPedido.DataTable.FieldByName(fld_DetallesPedidosProveedorIMPORTEUNIDAD).IsNull then IMPORTEUNIDAD := ADetallesPedido.IMPORTEUNIDAD; if not ADetallesPedido.DataTable.FieldByName(fld_DetallesPedidosProveedorIMPORTETOTAL).IsNull then IMPORTETOTAL := ADetallesPedido.IMPORTETOTAL; DataTable.EnableEventHandlers; Post; ADetallesPedido.Next; end; end; constructor TBizDetallesPedidoProveedor.Create(aDataTable: TDADataTable); begin inherited; FPosicionNueva := 1; // Los conceptos empiezan a contar en 1 FPuedoLanzarEvento := True; end; function TBizDetallesPedidoProveedor.DarSumaTotalImportes: Currency; begin Result := DarTotalDetalles(Self.DataTable, True, True); end; procedure TBizDetallesPedidoProveedor.DesactivarEventos; begin FPuedoLanzarEvento := False; end; destructor TBizDetallesPedidoProveedor.destroy; begin showmessage('libero detalles'); inherited; end; procedure TBizDetallesPedidoProveedor.OnNewRecord(Sender: TDADataTable); begin inherited; // PARCHE ******************* if not PuedoLanzarEvento then Exit; POSICION := FPosicionNueva; NUMCONCEPTO := -1; TIPO := TIPODETALLE_CONCEPTO; end; function TBizDetallesPedidoProveedor.PuedoLanzarEvento: Boolean; begin Result := FPuedoLanzarEvento; end; procedure TBizDetallesPedidoProveedor.RecalcularImporte; begin RecalcularImporteDetalle(Self.DataTable, False, False); end; procedure TBizDetallesPedidoProveedor.Refrescar; begin DataTable.Refresh; end; initialization FMasterDeleting := False; RegisterDataTableRules(BIZ_DETALLESPEDIDOSPROVEEDOR, TBizDetallesPedidoProveedor); RegisterDataTableRules(BIZ_PEDIDOSPROVEEDOR, TBizPedidosProveedor); finalization end.