unit uGenerarAlbaranesCliUtils;

interface

uses
 Windows, SysUtils, Classes, pngimage, JSDialog,
 uBizContratosCliente, uBizAlbaranesCliente;

type
  TdmGenerarAlbaranesCli = class(TDataModule)
    JsListaAlbaranesGenerados: TJSDialog;
  end;

  function GenerarAlbaranCli(const IDContrato : Integer) : Boolean; overload;
  function GenerarAlbaranCli(AContrato : IBizContratoCliente; var AAlbaran: IBizAlbaranCliente) : Boolean; overload;
//  function ElegirPedidoYGenerarAlbaranCli(var IDAlbaran: Integer) : Boolean;
  function ElegirContratoYGenerarAlbaranCli(var IDAlbaran: Integer) : Boolean;

implementation

{$R *.dfm}

uses
  uDialogUtils, uBizDetallesContratoCliente, uBizDetallesAlbaranCliente,
  uContratosClienteController, uAlbaranesClienteController, uClientesController,
  uDetallesAlbaranClienteController, uControllerDetallesBase,
  uBizContactos, schAlbaranesClienteClient_Intf,
  schContratosClienteClient_Intf, uBizDetallesPresupuestoCliente;

var
  dmGenerarAlbaranesCli: TdmGenerarAlbaranesCli;
  AContratosClienteController : IContratosClienteController;
  AAlbaranesClienteController : IAlbaranesClienteController;
  AClientesController : IClientesController;

{ Métodos auxiliares }
procedure CopiarContratoAAlbaran(AContrato: IBizContratoCliente; AAlbaran : IBizAlbaranCliente);
begin
  if not Assigned(AAlbaran) then
    raise Exception.Create ('Albarán no asignado (CopiarContratoAAlbaran)');

  if not Assigned(AContrato) then
    raise Exception.Create ('Contrato no asignado (CopiarContratoAAlbaran)');

  if not AContrato.DataTable.Active then
    AContrato.DataTable.Active := True;

  // El albarán tiene que venir ya abierto y posicionado donde hay que copiar
  AAlbaran.ID_CLIENTE := AContrato.ID_CLIENTE;
  // Lo dejamos listo para que se localize la subcuenta contable asociada al cliente
  AAlbaranesClienteController.RecuperarCliente(AAlbaran);
  AAlbaran.Cliente.Open;

//  AAlbaran.NIF_CIF := AContrato.NIF_CIF;
  AAlbaran.NOMBRE := AContrato.NOMBRE;
  AAlbaran.CALLE := AContrato.CALLE;
  AAlbaran.POBLACION := AContrato.POBLACION;
  AAlbaran.PROVINCIA := AContrato.PROVINCIA;
  AAlbaran.CODIGO_POSTAL := AContrato.CODIGO_POSTAL;


//  AAlbaran.PERSONA_CONTACTO := AContrato.PERSONA_CONTACTO;
//  AAlbaran.DataTable.FieldByName(fld_FacturasClientePLAZO_ENTREGA).AsVariant := AContrato.DataTable.FieldByName(fld_ContratosClientePLAZO_ENTREGA).AsVariant;

  AAlbaran.DataTable.FieldByName(fld_AlbaranesClienteOBSERVACIONES).AsVariant := AContrato.DataTable.FieldByName(fld_ContratosClienteOBSERVACIONES).AsVariant;
  AAlbaran.IMPORTE_NETO := AContrato.IMPORTE_NETO;

// Los albaranes no tienen Descuento
//  AAlbaran.IMPORTE_PORTE := AContrato.IMPORTE_PORTE;
//  AAlbaran.DESCUENTO := AContrato.DESCUENTO;
//  AAlbaran.IMPORTE_DESCUENTO := AContrato.IMPORTE_DESCUENTO;
  AAlbaran.BASE_IMPONIBLE := AContrato.BASE_IMPONIBLE;

// Los albaranes no tienen IVA
//  AAlbaran.ID_TIPO_IVA := AContrato.ID_TIPO_IVA;
//  AAlbaran.IVA := AContrato.IVA;
//  AAlbaran.IMPORTE_IVA := AContrato.IMPORTE_IVA;
  AAlbaran.IMPORTE_TOTAL := AContrato.BASE_IMPONIBLE;

  AAlbaran.ID_TIENDA := AContrato.ID_TIENDA;
  AAlbaran.ID_CONTRATO := AContrato.ID;
  
//  AAlbaran.ID_VENDEDOR := AContrato.ID_VENDEDOR;
//  AAlbaran.RECARGO_EQUIVALENCIA := AContrato.RECARGO_EQUIVALENCIA;
//  AAlbaran.RE := AContrato.RE;
//  AAlbaran.IMPORTE_RE := AContrato.IMPORTE_RE;
//  AAlbaran.TIPO_FACTURA := AContrato.TIPO_CONTRATO;
end;

procedure CopiarDetallesAAlbaran(
  AContrato: IBizContratoCliente;
  AAlbaran: IBizAlbaranCliente;
  AArticulos: IBizDetallesContratoCliente);
var
  i : integer;
  ADetalles : IBizDetallesAlbaranCliente;
  ADetallesController : IDetallesAlbaranClienteController;
begin
  if not Assigned(AAlbaran) then
    raise Exception.Create ('Albarán no asignada (CopiarDetallesAAlbaran)');

  if not Assigned(AContrato) then
    raise Exception.Create ('Contrato no asignado (CopiarDetallesAAlbaran)');

  if not Assigned(AArticulos) then
    raise Exception.Create ('Artículos no asignado (CopiarDetallesAAlbaran)');

  if not AArticulos.DataTable.Active then
    AArticulos.DataTable.Active := True;

  // El contrato tiene que venir ya abierto y posicionado donde hay que copiar

  ADetalles := AAlbaran.Detalles;
  ADetallesController := TDetallesAlbaranClienteController.Create;
  try
    //OJO IMPORTANTE
    //Siempre que vayamos a trabajar con los detalles debemos hacer un beginupdate de los mismos y un endupdate para
    //obligarle siempre a recalcular los detalles una sola vez
    ADetallesController.BeginUpdate(ADetalles);

    AArticulos.DataTable.First;
    for i := 0 to AArticulos.DataTable.RecordCount - 1 do
    begin
      ADetallesController.Add(ADetalles, AArticulos.TIPO_DETALLE);
      ADetalles.Edit;
      ADetalles.REFERENCIA := AArticulos.REFERENCIA;
      ADetalles.ID_ARTICULO := AArticulos.ID_ARTICULO;
      if (AArticulos.PROPIEDAD <> '') then
        ADetalles.CONCEPTO := AArticulos.PROPIEDAD + ': '+ AArticulos.CONCEPTO
      else
        ADetalles.CONCEPTO := AArticulos.CONCEPTO;

      if not AArticulos.CANTIDADIsNull then
         ADetalles.CANTIDAD := AArticulos.CANTIDAD;
      if not AArticulos.IMPORTE_UNIDADIsNull then
         ADetalles.IMPORTE_UNIDAD := AArticulos.IMPORTE_UNIDAD;
      if not AArticulos.IMPORTE_TOTALIsNull then
         ADetalles.IMPORTE_TOTAL := AArticulos.IMPORTE_TOTAL;
      if not AArticulos.DESCUENTOIsNull then
         ADetalles.DESCUENTO := AArticulos.DESCUENTO;
      if not AArticulos.IMPORTE_PORTEIsNull then
         ADetalles.IMPORTE_PORTE := AArticulos.IMPORTE_PORTE;
      ADetalles.VISIBLE := AArticulos.VISIBLE;
      ADetalles.REFERENCIA_PROVEEDOR := AArticulos.REFERENCIA_PROVEEDOR;
      ADetalles.Post;
      AArticulos.Next;
    end;
  finally
    ADetallesController.EndUpdate(ADetalles);
    ADetallesController := NIL;
  end;
end;

procedure RecalcularImporteAlbaran(AAlbaran : IBizAlbaranCliente);
begin
  if not Assigned(AAlbaran) then
    raise Exception.Create ('Albarán no asignado (RecalcularImporteAlbaran)');

  AAlbaran.Edit;
  try
    AAlbaran.IMPORTE_NETO := AAlbaranesClienteController.DetallesController.DarTotalImporteTotal(AAlbaran.Detalles);
    AAlbaran.BASE_IMPONIBLE := AAlbaran.IMPORTE_NETO;
    AAlbaran.IMPORTE_TOTAL := AAlbaran.BASE_IMPONIBLE;
  finally
    AAlbaran.Post;
  end;
end;

procedure Inicializar;
begin
  dmGenerarAlbaranesCli := TdmGenerarAlbaranesCli.Create(nil);
  AContratosClienteController := TContratosClienteController.Create;
  AAlbaranesClienteController := TAlbaranesClienteController.Create;
  AClientesController := TClientesController.Create;
end;

procedure Finalizar;
begin
  FreeAndNIL(dmGenerarAlbaranesCli);
  AContratosClienteController := nil;
  AAlbaranesClienteController := nil;
  AClientesController := nil;
end;


function GenerarAlbaranCli(const IDContrato : Integer) : Boolean; overload;
var
  AContrato : IBizContratoCliente;
  AAlbaran : IBizAlbaranCliente;
begin
  Result := False;

  try
    if not Assigned(AContratosClienteController) then
       Inicializar;

    AContrato := AContratosClienteController.Buscar(IDContrato);
    if Assigned(AContrato) then
       Result := GenerarAlbaranCli(AContrato, AAlbaran);
  finally
    if Assigned(AContratosClienteController) then
       Finalizar;
  end;
end;

function GenerarAlbaranCli(AContrato : IBizContratoCliente; var AAlbaran: IBizAlbaranCliente) : Boolean; overload;
var
  ARespuesta : Integer;
begin
  AAlbaran := NIL;

  if not Assigned(AContrato) then
    raise Exception.Create('Contrato de cliente no asignado (GenerarAlbaranCli)');

  if not AContrato.DataTable.Active then
     AContrato.DataTable.Active := True;

  if not Assigned(AContratosClienteController) then
     Inicializar;

  try
    AAlbaran := AAlbaranesClienteController.Nuevo;
    CopiarContratoAAlbaran(AContrato, AAlbaran);
    CopiarDetallesAAlbaran(AContrato, AAlbaran, AContrato.Detalles);
    RecalcularImporteAlbaran(AAlbaran);

    //Sustituir por if de guardar
    if AAlbaranesClienteController.Guardar(AAlbaran) then
    begin
// Asocio el contrato al presupuesto
      with dmGenerarAlbaranesCli.JsListaAlbaranesGenerados do
      begin
        Instruction.Text := 'Se ha generado el albarán';

        Content.Clear;
        Content.Add(Format('Se ha generado correctamente el albarán %s a partir del contrato de cliente' + #10#13, [AAlbaran.REFERENCIA]));
        Execute;

        ARespuesta := CustomButtonResult;
        case ARespuesta of
          100 : begin
                  // Ver el albarán
                  AAlbaranesClienteController.Ver(AAlbaran);
                end;
          200 : // Continuar;
        end;
      end;
    end;

    Result := True;
  finally
    if Assigned(AContratosClienteController) then
       Finalizar;
  end;
end;

function ElegirContratoYGenerarAlbaranCli(var IDAlbaran: Integer) : Boolean;
var
  AContrato : IBizContratoCliente;
  AAlbaran : IBizAlbaranCliente;
begin
  Result := False;
  IDAlbaran := -1;

  AAlbaran := NIL;
  try
    if not Assigned(AContratosClienteController) then
      Inicializar;

    AContrato := AContratosClienteController.ElegirContratos(AContratosClienteController.BuscarTodos,
                  'Elija el contrato de cliente que desea utilizar para dar de alta el albarán.', False);

    if Assigned(AContrato) then
    begin
      Result := GenerarAlbaranCli(AContrato, AAlbaran);
      if Result then
        IDAlbaran := AAlbaran.ID;
    end;
  finally
    if Assigned(AContratosClienteController) then
      Finalizar;
  end;
end;



{
function ElegirPedidoYGenerarAlbaranCli(var IDAlbaran: Integer) : Boolean; overload;
var
  APedido : IBizPedidoCliente;
  AAlbaran : IBizAlbaranCliente;
begin
  Result := False;
  IDAlbaran := -1;

  AAlbaran := NIL;
  try
    if not Assigned(APedidosClienteController) then
      Inicializar;

    APedido := APedidosClienteController.ElegirPedidos(APedidosClienteController.BuscarPendientes,
                  'Elija el pedido de cliente que desea utilizar para dar de alta el albarán de cliente.'
                  , False);

    if Assigned(APedido) then
    begin
      Result := GenerarAlbaranCli(APedido, AAlbaran);
      if Result then
        IDAlbaran := AAlbaran.ID;
    end;
  finally
    if Assigned(APedidosClienteController) then
      Finalizar;
  end;
end;
}
end.
