unit uBizAlbaranesCliente; interface uses Controls, uDAInterfaces, uDADataTable, Classes, uBizContacto, DB, schAlbaranesClienteClient_Intf, uBizImportesDetalleBase, uBizImportesCabeceraBase, uBizPresupuestosCliente, uDBSelectionList, uExceptions, uBizInformesBase; const BIZ_ALBARANCLIENTE = 'Client.AlbaranCliente'; BIZ_DETALLESALBARANCLIENTE = 'Client.DetallesAlbaranCliente'; SITUACION_PENDIENTE = 'Pendiente'; SITUACION_PAGADO = 'Pagado'; type IBizDetallesAlbaranCliente = interface(IDetallesAlbaranCliente) ['{8AA767E6-8C11-4E72-81B7-609DA076AC77}'] procedure CopyFrom(ADetallesPresupuesto : IBizDetallesPresupuesto); end; IBizAlbaranesCliente = interface(IAlbaranCliente) ['{18C13046-1C42-477C-95F4-C80739D97A54}'] function GetDetalles: IBizDetallesAlbaranCliente; procedure SetDetalles(Value: IBizDetallesAlbaranCliente); property Detalles: IBizDetallesAlbaranCliente read GetDetalles write SetDetalles; function GetCliente: IBizCliente; procedure SetCliente(Value: IBizCliente); property Cliente: IBizCliente read GetCliente write SetCliente; procedure Show; function ShowForSelect : TModalResult; procedure CopyFrom(APresupuesto : IBizPresupuestos); end; TBizDetallesAlbaranCliente = class(TDetallesAlbaranClienteDataTableRules, IBizDetallesAlbaranCliente, IBizImportesDetalle, IBizPuntosDetalle, IBizVisibleDetalle, IBizValoradoDetalle, IParche) // PARCHE *********************** private FIsAppend : Boolean; FPosicionNueva : Integer; FPuedoLanzarEvento : Boolean; // PARCHE *********************** procedure SetCANTIDADValue(const aValue: Integer); override; procedure SetIMPORTEUNIDADValue(const aValue: Currency); override; procedure SetIMPORTETOTALValue(const aValue: Currency); override; procedure SetPUNTOSValue(const aValue: Integer); override; procedure SetIMPORTEPUNTOSValue(const aValue: Currency); override; 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; procedure CopyFrom(ADetallesPresupuesto : IBizDetallesPresupuesto); end; TBizAlbaranesCliente = class(TAlbaranClienteDataTableRules, IBizAlbaranesCliente, IBizImportesCabecera, ISelectedRowList, IApplyUpdateFailedException, IBizInformesAware) private FCliente : IBizCliente; FDetalles: IBizDetallesAlbaranCliente; FDetallesLink: TDADataSource; FSelectedRows : TSelectedRowList; protected procedure ShowApplyUpdateFailed (const Error: EDAApplyUpdateFailed); function GetDetalles: IBizDetallesAlbaranCliente; procedure SetDetalles(Value: IBizDetallesAlbaranCliente); function GetCliente: IBizCliente; procedure SetCliente(Value: IBizCliente); 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; procedure BeforeApplyUpdates(Sender : TDADataTable; const Delta : IDADelta); public procedure RecalcularImporte; property Cliente: IBizCliente read GetCliente write SetCliente; property Detalles: IBizDetallesAlbaranCliente read GetDetalles write SetDetalles; procedure Show; function ShowForSelect : TModalResult; procedure Preview; procedure Print; procedure CopyFrom(APresupuesto : IBizPresupuestos); constructor Create(aDataTable: TDADataTable); override; destructor Destroy; override; property SelectedRows : TSelectedRowList read GetSelectedRows; end; procedure ValidarAlbaranCliente (const AAlbaranCliente : IBizAlbaranesCliente); implementation uses Windows, Dialogs, uDACDSDataTable, SysUtils, uEditorUtils, Variants, Math, uDataModuleContactos, schPresupuestosClient_Intf, Forms, uDataModuleBase, uDataModuleUsuarios, uDataModuleAlbaranesCliente, uDataTableUtils; var FMasterDeleting : Boolean; FCancelInsert : Boolean; procedure ValidarAlbaranCliente (const AAlbaranCliente : IBizAlbaranesCliente); begin if (FloatToStr(AAlbaranCliente.FECHAALBARAN) = '0') then raise Exception.Create('Debe indicar la fecha de este albarán'); if not Assigned(AAlbaranCliente.Cliente) or (AAlbaranCliente.Cliente.DataTable.IsEmpty) then raise Exception.Create('Debe indicar el cliente de este albarán'); AAlbaranCliente.Edit; if (FloatToStr(AAlbaranCliente.FECHAPAGO) = '0') then AAlbaranCliente.SITUACION := SITUACION_PENDIENTE else AAlbaranCliente.SITUACION := SITUACION_PAGADO; AAlbaranCliente.Post; if (Length(AAlbaranCliente.REFERENCIA) = 0) then begin AAlbaranCliente.Edit; AAlbaranCliente.REFERENCIA := dmAlbaranesCliente.DarNuevaReferencia; AAlbaranCliente.Post; ShowMessage('A este albarán se le ha asignado la referencia ' + AAlbaranCliente.REFERENCIA); end; end; constructor TBizAlbaranesCliente.Create(aDataTable: TDADataTable); begin inherited; FCliente := NIL; FDetallesLink := TDADataSource.Create(NIL); FSelectedRows := TSelectedRowList.Create(aDataTable); aDataTable.OnBeforeApplyUpdates := BeforeApplyUpdates; end; destructor TBizAlbaranesCliente.Destroy; begin FCliente := NIL; FDetalles := NIL; FDetallesLink.Free; FSelectedRows.Free; inherited; end; function TBizAlbaranesCliente.GetCliente: IBizCliente; begin if not Assigned(FCliente) then FCliente := dmContactos.GetCliente(CODIGOCONTACTO) else if (CODIGOCONTACTO <> FCliente.Codigo) and not (FCliente.DataTable.State in dsEditModes) then dmContactos.GetContacto(FCliente, CODIGOCONTACTO); if not FCliente.DataTable.Active then FCliente.DataTable.Active := True; Result := FCliente; end; function TBizAlbaranesCliente.GetDetalles: IBizDetallesAlbaranCliente; begin Result := FDetalles; end; procedure TBizAlbaranesCliente.CopyFrom(APresupuesto: IBizPresupuestos); var ACursor: TCursor; begin if not (State in dsEditModes) then Edit; if not (APresupuesto.DataTable.Active) then APresupuesto.DataTable.Active := True; ACursor := Screen.Cursor; Screen.Cursor := crHourGlass; Application.ProcessMessages; try CODIGOEMPRESA := APresupuesto.CODIGOEMPRESA; CODIGOCONTACTO := APresupuesto.CODIGOCONTACTO; BASEIMPONIBLE := APresupuesto.BASEIMPONIBLE; DESCUENTO := APresupuesto.DESCUENTO; IVA := APresupuesto.IVA; OBSERVACIONES := APresupuesto.OBSERVACIONES; FORMAPAGO := APresupuesto.FORMAPAGO; CODIGOPRESUPUESTO := APresupuesto.CODIGO; Cliente := APresupuesto.Cliente; Detalles.CopyFrom(APresupuesto.Detalles); RecalcularImporte; finally Screen.Cursor := ACursor; end; end; procedure TBizAlbaranesCliente.OnNewRecord(Sender: TDADataTable); begin inherited; CODIGOEMPRESA := dmBase.CodigoEmpresa; USUARIO := dmUsuarios.LoginInfo.UserID; FECHAALTA := Date; FECHAALBARAN := Date; SITUACION := SITUACION_PENDIENTE; CODIGO := dmAlbaranesCliente.GetNextAutoinc; end; procedure TBizAlbaranesCliente.Preview; begin dmAlbaranesCliente.Preview(Self.CODIGO); end; procedure TBizAlbaranesCliente.SetCliente(Value: IBizCliente); var bEnEdicion : Boolean; begin bEnEdicion := (DataTable.State in dsEditModes); if not bEnEdicion then Edit; FCliente := Value; if Assigned(FCliente) then begin CODIGOCONTACTO := FCliente.CODIGO; Post; if bEnEdicion then Edit; end end; procedure TBizAlbaranesCliente.SetDetalles(Value: IBizDetallesAlbaranCliente); begin FDetalles := Value; FDetallesLink.DataTable := Self.DataTable; FDetalles.DataTable.MasterSource := FDetallesLink; end; procedure TBizAlbaranesCliente.Show; begin ShowEditor(IBizAlbaranesCliente, Self, etItem); end; procedure TBizDetallesAlbaranCliente.ActivarEventos; begin FPuedoLanzarEvento := True; end; procedure TBizDetallesAlbaranCliente.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 TBizDetallesAlbaranCliente.AfterInsert(Sender: TDADataTable); begin inherited; // PARCHE ******************* if not PuedoLanzarEvento then Exit; FIsAppend := DataTable.EOF; Post; Edit; // Para volver a dejarlo en modo de edición end; procedure TBizDetallesAlbaranCliente.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 TBizDetallesAlbaranCliente.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 = CODIGOALBARAN); end; procedure TBizDetallesAlbaranCliente.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 TBizDetallesAlbaranCliente.CopyFrom( ADetallesPresupuesto: IBizDetallesPresupuesto); begin DeleteAllTable(Self.DataTable); ADetallesPresupuesto.First; while not ADetallesPresupuesto.EOF do begin Append; DataTable.DisableControls; DataTable.DisableEventHandlers; try TIPO := ADetallesPresupuesto.TIPO; DESCRIPCION := ADetallesPresupuesto.DESCRIPCION; CANTIDAD := ADetallesPresupuesto.CANTIDAD; IMPORTEUNIDAD := ADetallesPresupuesto.IMPORTEUNIDAD; IMPORTETOTAL := ADetallesPresupuesto.IMPORTETOTAL; PUNTOS := ADetallesPresupuesto.PUNTOS; IMPORTEPUNTOS := ADetallesPresupuesto.IMPORTEPUNTOS; VISIBLE := ADetallesPresupuesto.VISIBLE; VALORADO := ADetallesPresupuesto.VALORADO; finally DataTable.EnableControls; DataTable.EnableEventHandlers; end; Post; ADetallesPresupuesto.Next; end; end; constructor TBizDetallesAlbaranCliente.Create(aDataTable: TDADataTable); begin inherited; FPosicionNueva := 1; // Los conceptos empiezan a contar en 1 // PARCHE ******************* FPuedoLanzarEvento := True; end; function TBizDetallesAlbaranCliente.DarSumaTotalImportes: Currency; begin Result := DarTotalDetalles(Self.DataTable, True, True); end; procedure TBizDetallesAlbaranCliente.DesactivarEventos; begin FPuedoLanzarEvento := False; end; procedure TBizDetallesAlbaranCliente.OnNewRecord(Sender: TDADataTable); begin inherited; // PARCHE ******************* if not PuedoLanzarEvento then Exit; POSICION := FPosicionNueva; NUMCONCEPTO := -1; TIPO := TIPODETALLE_CONCEPTO; VISIBLE := VISIBLE_TRUE; VALORADO := VALORADO_TRUE; Self.DataTable.DisableEventHandlers; try CANTIDAD := 1; finally Self.DataTable.EnableEventHandlers; end; end; function TBizAlbaranesCliente.GetSelectedRows: TSelectedRowList; begin Result := FSelectedRows; end; procedure TBizAlbaranesCliente.ShowApplyUpdateFailed( const Error: EDAApplyUpdateFailed); begin if (Pos(AUF_FKVIOLATION, Error.Message) > 0) then MessageBox(0, 'No se puede borrar este albarán porque tiene una factura asociada', 'Atención', MB_ICONWARNING or MB_OK); end; procedure TBizAlbaranesCliente.BeforeDelete(Sender: TDADataTable); begin inherited; if not dmAlbaranesCliente.PuedoEliminarAlbaran(CODIGO) then raise Exception.Create('No se puede borrar este albarán porque tiene una factura asociada'); FMasterDeleting := True; // Para que los detalles de borren de golpe y no recalcule posiciones ni totales end; procedure TBizAlbaranesCliente.AfterDelete(Sender: TDADataTable); begin inherited; FMasterDeleting := False; end; procedure TBizAlbaranesCliente.Print; begin dmAlbaranesCliente.Print(Self.CODIGO); end; procedure TBizAlbaranesCliente.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 cliente de este albarán', 'Atención', MB_ICONWARNING or MB_OK) else if (Pos('Fecha albarán', Error.Message) > 0) then MessageBox(0, 'Debe indicar la fecha de este albarán', 'Atención', MB_ICONWARNING or MB_OK) else raise Error; end else raise Error; end; procedure TBizAlbaranesCliente.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 : ValidarAlbaranCliente(Self); //ctDelete : end; end; function TBizDetallesAlbaranCliente.PuedoLanzarEvento: Boolean; begin Result := FPuedoLanzarEvento; end; procedure TBizDetallesAlbaranCliente.RecalcularImporte; begin RecalcularImporteDetalle(Self.DataTable, True, True); end; procedure TBizAlbaranesCliente.RecalcularImporte; begin RecalcularImportesCabecera(Self.DataTable, Detalles.DataTable); end; procedure TBizDetallesAlbaranCliente.Refrescar; begin DataTable.Refresh; end; function TBizAlbaranesCliente.ShowForSelect: TModalResult; begin Result := ShowEditor(IBizAlbaranesCliente, Self, etSelectItems); end; procedure TBizDetallesAlbaranCliente.SetCANTIDADValue(const aValue: Integer); begin if aValue = 0 then DataTable.Fields[idx_DetallesAlbaranClienteCANTIDAD].AsVariant := Null else inherited; end; procedure TBizDetallesAlbaranCliente.SetIMPORTEPUNTOSValue(const aValue: Currency); begin if aValue = 0 then DataTable.Fields[idx_DetallesAlbaranClienteIMPORTEPUNTOS].AsVariant := Null else inherited; end; procedure TBizDetallesAlbaranCliente.SetIMPORTETOTALValue(const aValue: Currency); begin if aValue = 0 then DataTable.Fields[idx_DetallesAlbaranClienteIMPORTETOTAL].AsVariant := Null else inherited; end; procedure TBizDetallesAlbaranCliente.SetIMPORTEUNIDADValue(const aValue: Currency); begin if aValue = 0 then DataTable.Fields[idx_DetallesAlbaranClienteIMPORTEUNIDAD].AsVariant := Null else inherited; end; procedure TBizDetallesAlbaranCliente.SetPUNTOSValue(const aValue: Integer); begin if aValue = 0 then DataTable.Fields[idx_DetallesAlbaranClientePUNTOS].AsVariant := Null else inherited; end; initialization FMasterDeleting := False; RegisterDataTableRules(BIZ_DETALLESALBARANCLIENTE, TBizDetallesAlbaranCliente); RegisterDataTableRules(BIZ_ALBARANCLIENTE, TBizAlbaranesCliente); finalization end.