AbetoDesign_FactuGES2/Source/Modulos/Facturas de cliente/Views/uEditorFacturaCliente.pas
roberto 1f5e6ebcb9 Version 4.5.4
Cambio en los informes de Contratos de cliente de todas las entidades: Cambio fecha de entrega por fecha expedicion - Solicitado por Próspero
Cambio logo uecko y sellos cabecera en todos los informes de todas las entidades- Solicitado por Noelia
Arreglo para que permita introducir DNI y CIFs raros - Solicitado por Mónica
Las facturas proforma no se tendrán en cuenta en las facturas asociadas a los contratos, listado de contratos - Solicitado por Eva
Se añade comprobación de capitulos para que avise si existe un subtotal sin capitulo correspondiente, ayudará a controlar errores en presupuestos y contratos largos. - Solicitado por Miriam
En los detalles de presupuestos y contratos si eligen un articulo de la tarífa el programa no deja modificar las descripciones (Se ha detectado que lo hen hecho en ocasiones en las tiendas) - Solicitado por Miriam

git-svn-id: https://192.168.0.254/svn/Proyectos.AbetoDesign_FactuGES/trunk@186 93f398dd-4eb6-7a46-baf6-13f46f578da2
2024-02-05 10:15:29 +00:00

545 lines
19 KiB
ObjectPascal
Raw Blame History

unit uEditorFacturaCliente;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, uEditorDBItem, DB, uDADataTable, JvAppStorage,
JvAppRegistryStorage, JvComponent, JvFormPlacement, ImgList,
PngImageList, StdActns, ActnList, ComCtrls, TBX, TB2Item, TB2Dock,
TB2Toolbar, ExtCtrls, JvExControls, JvNavigationPane,
uViewFacturaCliente, uCustomView, uViewBase, uViewTotales,
StdCtrls, pngimage, AppEvnts, JvComponentBase,
uBizFacturasCliente, uBizTiposIVA,
uIEditorFacturaCliente, uFacturasClienteController, uViewDetallesBase,
uViewDetallesFacturaCliente, dxLayoutLookAndFeels, JvExComCtrls, JvStatusBar,
uViewDetallesDTO, uViewDetallesArticulos, uTiposIVAController, uDAInterfaces,
cxControls, cxContainer, cxEdit, cxTextEdit, cxDBEdit, Grids, DBGrids,
cxCheckBox, uViewListaSubCuentas;
type
TfEditorFacturaCliente = class(TfEditorDBItem, IEditorFacturaCliente)
frViewFacturaCliente1: TfrViewFacturaCliente;
frViewTotales1: TfrViewTotales;
frViewDetallesFacturaCliente1: TfrViewDetallesFacturaCliente;
pagContabilidad: TTabSheet;
frViewListaSubcuentas1: TfrViewListaSubcuentas;
procedure FormShow(Sender: TObject);
procedure frViewClienteFactura1edtlNombrePropertiesEditValueChanged(Sender: TObject);
procedure dsDataTableDataChange(Sender: TObject; Field: TField);
procedure CustomEditorClose(Sender: TObject; var Action: TCloseAction);
procedure frViewClienteFacturaedtlNombrePropertiesChange(Sender: TObject);
procedure pgPaginasChanging(Sender: TObject; var AllowChange: Boolean);
procedure frViewTotales1edtDescuentoPropertiesValidate(Sender: TObject;
var DisplayValue: Variant; var ErrorText: TCaption; var Error: Boolean);
procedure frViewTotales1bTiposIVAClick(Sender: TObject);
procedure frViewTotales1eIVAPropertiesValidate(Sender: TObject;
var DisplayValue: Variant; var ErrorText: TCaption; var Error: Boolean);
procedure frViewTotales1ePortePropertiesValidate(Sender: TObject;
var DisplayValue: Variant; var ErrorText: TCaption; var Error: Boolean);
procedure frViewTotales1ePorteEditing(Sender: TObject; var CanEdit: Boolean);
procedure OnRecargoEquivalenciaPropertiesValidate(Sender: TObject; var DisplayValue: Variant; var ErrorText: TCaption;
var Error: Boolean);
procedure frViewDetallesFacturaCliente1actQuitarPreciosExecute(
Sender: TObject);
procedure frViewDetallesFacturaCliente1actQuitarPreciosUpdate(
Sender: TObject); //Importante en este punto se deben de quitar los eventos que puedan afectar a la tabla una vez se cierre el editor.
private
procedure RecalcularPortePorUnidad;
protected
FController : IFacturasClienteController;
FFactura: IBizFacturaCliente;
FTiposIVAController : ITiposIVAController;
FTiposIVA: IBizTipoIVA;
FViewFactura: IViewFacturaCliente;
function GetController : IFacturasClienteController;
procedure SetController (const Value : IFacturasClienteController);
function GetFactura: IBizFacturaCliente;
procedure SetFactura(const Value: IBizFacturaCliente);
function GetViewFactura: IViewFacturaCliente;
procedure SetViewFactura(const Value: IViewFacturaCliente);
property ViewFacturaCliente: IViewFacturaCliente read GetViewFactura write SetViewFactura;
procedure OnClienteChanged(Sender: TObject);
procedure GuardarInterno; override;
procedure EliminarInterno; override;
procedure ImprimirInterno; override;
procedure PrevisualizarInterno; override;
procedure PonerTitulos(const ATitulo: string = ''); override;
function PuedoImprimir: Boolean; override;
public
destructor Destroy; override;
property Controller : IFacturasClienteController read GetController write SetController;
property Factura: IBizFacturaCliente read GetFactura write SetFactura;
constructor Create(AOwner: TComponent); override;
end;
implementation
{$R *.dfm}
{$INCLUDE ..\..\..\FactuGES.inc}
uses
uBizContactos, uDataModuleUsuarios, uFactuGES_App, uSubCuentasController,
uDetallesFacturaClienteController, uDialogUtils, uDataTableUtils,
uViewClienteFactura, uBizDireccionesContacto, uClientesController;
// uGenerarAlbaranesCliFacCliUtils;
{ TfEditorFacturaCliente }
{
**************************** TfEditorFacturaCliente ****************************
}
constructor TfEditorFacturaCliente.Create(AOwner: TComponent);
begin
inherited;
pgPaginas.ActivePageIndex := 0;
ViewFacturaCliente := frViewFacturaCliente1;
FTiposIVAController := TTiposIVAController.Create;
{$IFDEF CONTABILIDAD}
frViewListaSubcuentas1.TipoSubCuenta := tVentas;
{$ENDIF}
end;
procedure TfEditorFacturaCliente.CustomEditorClose(Sender: TObject;
var Action: TCloseAction);
begin
inherited;
dsDataTable.DataTable := NIL;
frViewTotales1.DADataSource.DataTable := NIL;
frViewTotales1.cbRecargoEquivalencia.Properties.OnValidate := nil;
Factura := NIL;
FTiposIVA := NIL;
FTiposIVAController := Nil;
FController := NIL;
FViewFactura := NIL;
end;
destructor TfEditorFacturaCliente.Destroy;
begin
inherited;
end;
procedure TfEditorFacturaCliente.dsDataTableDataChange(Sender: TObject;
Field: TField);
begin
inherited;
if Assigned(FFactura) and (not (FFactura.DataTable.Fetching) or
not (FFactura.DataTable.Opening) or not (FFactura.DataTable.Closing)) then
PonerTitulos;
end;
procedure TfEditorFacturaCliente.EliminarInterno;
var
ACadena : String;
begin
if (Application.MessageBox('Atenci<63>n, si elimina facturas/abonos de cliente podr<64>a producir huecos el la lista de facturas, <20>Desea continuar?', 'Atenci<63>n', MB_YESNO) = IDYES) then
begin
if Factura.TIPO = CTE_TIPO_FACTURA then
ACadena := '<27>Desea borrar esta factura de cliente?'
else if Factura.TIPO = CTE_TIPO_PROFORMA then
ACadena := '<27>Desea borrar esta factura proforma de cliente?'
else
ACadena := '<27>Desea borrar este abono a cliente?';
if (Application.MessageBox(PChar(ACadena), 'Atenci<63>n', MB_YESNO) = IDYES) then
begin
//Es el caso de querer borrar una factura pendiente cuyos recibos tienen devoluciones
if not FController.Eliminar(Factura) then
Application.MessageBox('La factura no ha podido ser eliminada porque tiene recibos con pagos o devoluciones emitidas.', 'Atenci<63>n', MB_OK);
inherited;
end;
end;
end;
procedure TfEditorFacturaCliente.FormShow(Sender: TObject);
begin
inherited;
if not Assigned(FViewFactura) then
raise Exception.Create('No hay ninguna vista asignada');
if not Assigned(Factura) then
raise Exception.Create('No hay ninguna factura asignada');
frViewTotales1.cbRecargoEquivalencia.Properties.OnValidate := OnRecargoEquivalenciaPropertiesValidate;
Factura.DataTable.Active := True;
end;
procedure TfEditorFacturaCliente.frViewClienteFactura1edtlNombrePropertiesEditValueChanged(Sender: TObject);
begin
inherited;
with (Sender as TcxDBTextEdit) do
Enabled := (FFactura.ID <> 0)
end;
procedure TfEditorFacturaCliente.frViewClienteFacturaedtlNombrePropertiesChange(
Sender: TObject);
begin
inherited;
PonerTitulos;
end;
procedure TfEditorFacturaCliente.frViewDetallesFacturaCliente1actQuitarPreciosExecute(
Sender: TObject);
begin
inherited;
FController.DetallesController.QuitarPrecioDetalles(FFactura.Detalles);
end;
procedure TfEditorFacturaCliente.frViewDetallesFacturaCliente1actQuitarPreciosUpdate(
Sender: TObject);
begin
if not Assigned(frViewDetallesFacturaCliente1.DADataSource.DataTable) then
(Sender as TAction).Enabled := False
else
(Sender as TAction).Enabled := (not ReadOnly)
and (not frViewDetallesFacturaCliente1.DADataSource.DataTable.IsEmpty)
end;
procedure TfEditorFacturaCliente.frViewTotales1bTiposIVAClick(Sender: TObject);
begin
inherited;
FTiposIVAController.VerTodos(FTiposIVA);
end;
procedure TfEditorFacturaCliente.OnRecargoEquivalenciaPropertiesValidate(
Sender: TObject; var DisplayValue: Variant; var ErrorText: TCaption;
var Error: Boolean);
begin
inherited;
if frViewTotales1.cbRecargoEquivalencia.Checked then
Factura.RECARGO_EQUIVALENCIA := 1
else
Factura.RECARGO_EQUIVALENCIA := 0;
end;
procedure TfEditorFacturaCliente.frViewTotales1edtDescuentoPropertiesValidate(
Sender: TObject; var DisplayValue: Variant; var ErrorText: TCaption;
var Error: Boolean);
begin
inherited;
Factura.DESCUENTO := DisplayValue;
end;
procedure TfEditorFacturaCliente.frViewTotales1eIVAPropertiesValidate(
Sender: TObject; var DisplayValue: Variant; var ErrorText: TCaption;
var Error: Boolean);
begin
inherited;
Factura.Edit;
Factura.ID_TIPO_IVA := FTiposIVA.ID; // ((frViewTotales1.dsTiposIVA.DataTable) as IBizTipoIVA).ID;
end;
procedure TfEditorFacturaCliente.frViewTotales1ePorteEditing(Sender: TObject;
var CanEdit: Boolean);
begin
inherited;
if FFactura.TIPO = CTE_TIPO_ABONO then
CanEdit := False;
end;
procedure TfEditorFacturaCliente.frViewTotales1ePortePropertiesValidate(
Sender: TObject; var DisplayValue: Variant; var ErrorText: TCaption;
var Error: Boolean);
begin
inherited;
if not VarIsNull(DisplayValue) and (Length(DisplayValue) > 0) then
FFactura.IMPORTE_PORTE := DisplayValue
else
FFactura.IMPORTE_PORTE := 0;
// RecalcularPortePorUnidad; No se desglosa el importe del porte por articulo
end;
function TfEditorFacturaCliente.GetController: IFacturasClienteController;
begin
Result := FController;
end;
function TfEditorFacturaCliente.GetFactura: IBizFacturaCliente;
begin
Result := FFactura;
end;
function TfEditorFacturaCliente.GetViewFactura: IViewFacturaCliente;
begin
Result := FViewFactura;
end;
procedure TfEditorFacturaCliente.GuardarInterno;
var
bEsNuevo : Boolean;
begin
inherited;
ShowHourglassCursor;
//frViewDetallesFacturaCliente1.SaveGridStatus; // Para guardar estado del grid
frViewDetallesFacturaCliente1.BeginUpdate; // Para que no se mueva el foco
try
bEsNuevo := FFactura.EsNuevo;
{$IFDEF CONTABILIDAD}
FFactura.Edit;
FFactura.ID_SUBCUENTA := frViewListaSubCuentas1.IdSubCuenta;
FController.SetIgnorarContabilidad(FFactura, frViewListaSubCuentas1.eContabilizar.EditValue);
{$ENDIF}
FController.Guardar(FFactura);
finally
frViewDetallesFacturaCliente1.EndUpdate;
//frViewDetallesFacturaCliente1.RestoreGridStatus;
HideHourglassCursor;
end;
if bEsNuevo then
begin
if FFactura.TIPO = CTE_TIPO_FACTURA then
ShowInfoMessage('La factura se ha dado de alta con el c<>digo ' + FFactura.REFERENCIA)
else if FFactura.TIPO = CTE_TIPO_PROFORMA then
ShowInfoMessage('La factura proforma se ha dado de alta con el c<>digo ' + FFactura.REFERENCIA)
else
begin
ShowInfoMessage('El abono se ha dado de alta con el c<>digo ' + FFactura.REFERENCIA);
//Preguntamos is desea hacer una orden de devoluci<63>n asociada
// if (Application.MessageBox('<27>Desea crear una orden de devoluci<63>n para el abono?', 'Atenci<63>n', MB_YESNO) = IDYES) then
// GenerarAlbaranCli(FFactura);
end;
end;
Modified := False;
end;
procedure TfEditorFacturaCliente.ImprimirInterno;
var
AVerLogotipo: Boolean;
begin
inherited;
AVerLogotipo:= False;
if(AppFactuGES.EmpresaActiva.IVA > 0) then
AVerLogotipo := (Application.MessageBox('<27>Desea imprimir el documento con logotipo?', 'Atenci<63>n', MB_YESNO) = IDYES);
FController.Print(FFactura, False, aVerLogotipo);
end;
procedure TfEditorFacturaCliente.OnClienteChanged(Sender: TObject);
var
// FDetallesController : IDetallesFacturaClienteController;
AClientesController : IClientesController;
ADireccion : IBizDireccionesContacto;
APrimerCliente : Boolean;
begin
FFactura.Cliente := frViewFacturaCliente1.frViewClienteFactura1.Cliente;
Controller.DetallesController.PrecioPunto := FFactura.Cliente.PRECIO_PUNTO;
if not (FFactura.DataTable.State in dsEditModes) then
FFactura.DataTable.Edit;
//En el caso de Acana no se cambia para que el IVA y la FORMA DE PAGO por defecto sea el de la empresa.
// Actualizar IVA y RE a partir del tipo de IVA del cliente.
{ Factura.IVA := FTiposIVA.IVA; //((frViewTotales1.dsTiposIVA.DataTable) as IBizTipoIVA).IVA;
if FFactura.Cliente.RECARGO_EQUIVALENCIA = 1 then
Factura.RE := FTiposIVA.RE
else
Factura.RE := 0;
}
// En el caso de tener direcciones asociadas, se debe dar la posibilidad de elegir la direcci<63>n principal o las secundarias para la factura
AClientesController := TClientesController.Create;
try
case FFactura.Cliente.Direcciones.RecordCount of
0 : //No hay direcciones secundarias asociadas
else ADireccion := AClientesController.ElegirDireccion(FFactura.Cliente, 'Seleccione la direcci<63>n del cliente que quiere utilizar como direcci<63>n fiscal de esta factura.');
end;
// Si hay direcci<63>n de envio, copiarla a la factura y poner el coste del porte
if Assigned(ADireccion) then
begin
if not ADireccion.IDIsNull then
try
FFactura.Edit;
FFactura.IMPORTE_PORTE := ADireccion.PORTE;
FController.CopiarDireccion(ADireccion, FFactura);
finally
ADireccion := NIL;
end;
end
finally
AClientesController := Nil;
end;
if Assigned(FFactura) then
begin
APrimerCliente := (FFactura.Cliente.ID = 0);
//En el caso de ser una factura proforma no se cambia el IVA ni la FORMA DE PAGO, solicitado por EVA
if (FFactura.TIPO <> CTE_TIPO_PROFORMA) then
if (ShowConfirmMessage('Cambio forma de pago y tipo de IVA', '<27>Desea actualizar la forma de pago y el tipo de IVA a la asignada en la ficha del cliente seleccionado?') = IDYES) then
FController.ActualizarFormaDePago(FFactura, FFactura.Cliente.ID_FORMA_PAGO);
if (not APrimerCliente) and (FFactura.Detalles.RecordCount > 0) then begin
if (ShowConfirmMessage('Actualizar los descuentos de las l<>neas',
'<27>Desea actualizar las l<>neas de detalle con el descuento del cliente?' + #10#13 +
'S<>lo se cambiar<61>n las l<>neas que tengan cantidades.') = IDYES) then
begin
FController.DetallesController.ActualizarDetalles(FFactura.Detalles, FFactura.Cliente);
ShowInfoMessage('Se han actualizado las l<>neas con el descuento del cliente seleccionado');
end;
end;
end;
end;
procedure TfEditorFacturaCliente.pgPaginasChanging(Sender: TObject;
var AllowChange: Boolean);
var
ACadena : String;
begin
inherited;
if (not Assigned(FFactura)) or (FFactura.ID_CLIENTE = ID_NULO) then
begin
if FFactura.TIPO = CTE_TIPO_FACTURA then
ACadena := 'Antes debe elegir un cliente para esta factura'
else
ACadena := 'Antes debe elegir un cliente para este abono';
ShowWarningMessage(ACadena);
AllowChange := False;
end;
end;
procedure TfEditorFacturaCliente.PonerTitulos(const ATitulo: string);
var
FTitulo : String;
begin
FTitulo := ATitulo;
if (FTitulo = '') and Assigned(Factura) then
begin
if Factura.EsNuevo then
if Factura.TIPO = CTE_TIPO_FACTURA then
FTitulo := 'Nueva factura de cliente'
else if Factura.TIPO = CTE_TIPO_PROFORMA then
FTitulo := 'Nueva factura proforma de cliente'
else
FTitulo := 'Nuevo abono a cliente'
else
if Factura.TIPO = CTE_TIPO_FACTURA then
FTitulo := 'Factura de cliente' + ' - ' + FFactura.Cliente.Nombre
else if Factura.TIPO = CTE_TIPO_PROFORMA then
FTitulo := 'Factura proforma de cliente' + ' - ' + FFactura.Cliente.Nombre
else
FTitulo := 'Abono a cliente' + ' - ' + FFactura.Cliente.Nombre
end;
inherited PonerTitulos(FTitulo);
Self.Caption := FTitulo + ' (' + AppFactuGES.EmpresaActiva.NOMBRE + ')';
end;
function TfEditorFacturaCliente.PuedoImprimir: Boolean;
begin
Result := inherited PuedoImprimir and (not Factura.Cliente.IDIsNull);
end;
procedure TfEditorFacturaCliente.PrevisualizarInterno;
var
AVerLogotipo: Boolean;
begin
inherited;
AVerLogotipo:= False;
if(AppFactuGES.EmpresaActiva.IVA > 0) then
AVerLogotipo := (Application.MessageBox('<27>Desea previsualizar el documento con logotipo?', 'Atenci<63>n', MB_YESNO) = IDYES);
FController.Preview(FFactura, False, AVerLogotipo);
end;
procedure TfEditorFacturaCliente.RecalcularPortePorUnidad;
begin
//Esta l<>gica se llamar<61> en el editor porque es para facilitar el rellenado de informaci<63>n del documento
//no puede ir en la clase de negocio porque no es una l<>gica que tenga sentido fuera del editor.
if Assigned(Controller)
and Assigned(Controller.DetallesController) then
Controller.DetallesController.DesglosarPorteDetalles(FFactura.IMPORTE_PORTE, FFactura.Detalles)
end;
procedure TfEditorFacturaCliente.SetController(const Value: IFacturasClienteController);
begin
FController := Value;
if Assigned(FController) then
begin
ViewFacturaCliente.Controller := FController;
frViewDetallesFacturaCliente1.Controller := Controller.DetallesController;
end;
end;
procedure TfEditorFacturaCliente.SetFactura(const Value: IBizFacturaCliente);
begin
FFactura := Value;
if Assigned(FFactura) then
begin
dsDataTable.DataTable := FFactura.DataTable;
frViewTotales1.DADataSource.DataTable := FFactura.DataTable;
FTiposIVA := FTiposIVAController.BuscarTodos;
frViewTotales1.dsTiposIVA.DataTable := FTiposIVA.DataTable;
FTiposIVA.DataTable.Active := True;
if Assigned(FViewFactura) then
begin
frViewFacturaCliente1.frViewClienteFactura1.Cliente := FFactura.Cliente;
frViewFacturaCliente1.frViewClienteFactura1.OnClienteChanged := OnClienteChanged;
FViewFactura.Factura := FFactura;
frViewDetallesFacturaCliente1.Detalles := FFactura.Detalles;
frViewDetallesFacturaCliente1.Factura := FFactura; //Para poder sacar los descuento del articulos segun el cliente seleccionado
Controller.DetallesController.PrecioPunto := FFactura.Cliente.PRECIO_PUNTO;
end;
{$IFDEF CONTABILIDAD}
frViewListaSubCuentas1.eContabilizar.EditValue := FFactura.IGNORAR_CONTABILIDAD;
frViewListaSubCuentas1.ElegirSubCuenta(FFactura.ID_SUBCUENTA);
{$ENDIF}
end
else begin
frViewFacturaCliente1.frViewClienteFactura1.OnClienteChanged := NIL;
frViewFacturaCliente1.frViewClienteFactura1.Cliente := NIL;
dsDataTable.DataTable := NIL;
frViewTotales1.DADataSource.DataTable := NIL;
frViewTotales1.dsTiposIVA.DataTable := NIL;
end
end;
procedure TfEditorFacturaCliente.SetViewFactura(const Value: IViewFacturaCliente);
begin
FViewFactura := Value;
if Assigned(FViewFactura) and Assigned(Factura) then
FViewFactura.Factura := Factura;
end;
end.