unit uMontajesDetallesController;

interface


uses
  Classes, SysUtils, uDADataTable, uControllerBase, uEditorDBItem,
  uIDataModuleMontajes, uBizMontajes, uBizMontajesDetalles,
  uMontajesController, uBizPresupuestos, uPresupuestosController, uDetallesMontajeController;

type
  IMontajesDetallesController = interface(IMontajesController)
  ['{84A6AB42-D89D-4BA8-8B0C-594B96CA0C13}']
    function GetDetallesController: IDetallesMontajeController;
    procedure SetDetallesController(const Value: IDetallesMontajeController);
    property DetallesController: IDetallesMontajeController read GetDetallesController write SetDetallesController;

    function GetPresupuestoController: IPresupuestosController;
    procedure SetPresupuestoController(const Value: IPresupuestosController);
    property PresupuestoController: IPresupuestosController read GetPresupuestoController write SetPresupuestoController;

    function Nuevo(Presupuesto: IBizPresupuesto) : IBizMontajeDetalles; overload;
  end;

  TMontajesDetallesController = class(TMontajesController, IMontajesDetallesController)
  protected
    FPresupuestoController: IPresupuestosController;
    FDetallesController : IDetallesMontajeController;
    function GetDetallesController: IDetallesMontajeController;
    procedure SetDetallesController(const Value: IDetallesMontajeController);
    function GetPresupuestoController: IPresupuestosController;
    procedure SetPresupuestoController(const Value: IPresupuestosController);
    procedure RecuperarPresupuesto(AMontaje : IBizMontajeDetalles);

    //Estos son los tres métodos a sobre escribir si se desea heredar toda la logica de
    //este controller
    procedure AsignarDataModule; override;
    procedure RecuperarObjetos(AMontaje: IBizMontaje); override;
    procedure AsignarEditor(out AEditor: IEditorDBItem); override;

    function ValidarMontaje(AMontaje: IBizMontaje): Boolean; override;
    procedure AsignarID(AMontaje: IBizMontaje; NuevoID:Integer); override;

    procedure RecibirAviso(ASujeto: ISujeto; ADataTable: IDAStronglyTypedDataTable); override;
  public
    property PresupuestoController: IPresupuestosController read GetPresupuestoController write SetPresupuestoController;
    property DetallesController: IDetallesMontajeController read GetDetallesController write SetDetallesController;

    constructor Create;
    destructor Destroy; override;
    function Nuevo(Presupuesto: IBizPresupuesto) : IBizMontajeDetalles; overload;
  end;

implementation

uses
  cxControls, DB, uEditorRegistryUtils, schMontajesClient_Intf,
  uBizContactos, uIEditorMontajes, uIEditorMontaje, uDataModuleMontajesDetalle,
  uIEditorElegirMontajes, uDataModuleUsuarios, uDAInterfaces, uDataTableUtils,
  uDateUtils, uROTypes, DateUtils, Controls,
  uIEditorMontajeDetalle, uIDataModuleMontajesDetalle,
  schPresupuestosClient_Intf;

{ TMontajesDetallesController }

procedure TMontajesDetallesController.AsignarDataModule;
begin
  FDataModule := TDataModuleMontajesDetalles.Create(Nil);
end;

procedure TMontajesDetallesController.AsignarEditor(out AEditor: IEditorDBItem);
begin
  CreateEditor('EditorMontajeDetalle', IEditorMontajeDetalle, AEditor);
end;

procedure TMontajesDetallesController.AsignarID(AMontaje: IBizMontaje; NuevoID:Integer);
begin
  if not Assigned(FDetallesController) then
    raise Exception.Create ('Controller detalles no asignado');

  { ¡¡¡ OJO !!!
    Primero cambiamos el ID de las tablas detalles
    porque si cambiamos antes el ID de la cabecera
    deja de funcionar la relacion M/D y no
    encontraríamos las filas detalle.

      -->  MASTER.ID = DETAIL.ID_MONTAJE <--
  }
  FDetallesController.AsignarID((AMontaje as IBizMontajeDetalles).Detalles, NuevoID, AMontaje.EsNuevo);
  inherited;
end;

constructor TMontajesDetallesController.Create;
begin
  inherited;
  FPresupuestoController := TPresupuestosController.Create;
  FDetallesController := TDetallesMontajeController.Create;
  FDetallesController.addObservador(Self);
end;

destructor TMontajesDetallesController.Destroy;
begin
  FPresupuestoController := Nil;
  FDetallesController := Nil;
  inherited;
end;

procedure TMontajesDetallesController.RecibirAviso(ASujeto: ISujeto; ADataTable: IDAStronglyTypedDataTable);
var
  AMontaje : IBizMontajeDetalles;
  ADetallesMontaje : IBizDetallesMontaje;
begin
  inherited;

  if Supports(ADataTable, IBizDetallesMontaje, ADetallesMontaje) and
     Supports(ADetallesMontaje.DataTable.MasterSource.DataTable, IBizMontajeDetalles, AMontaje) then
  begin
    AMontaje.Edit;
    try
      AMontaje.IMPORTE_TOTAL := FDetallesController.DarTotalImporteTotal(ADetallesMontaje);
    finally
      AMontaje.Post;
    end;
  end;
end;

procedure TMontajesDetallesController.RecuperarObjetos(AMontaje: IBizMontaje);
begin
  inherited;
  if not Assigned((AMontaje as IBizMontajeDetalles).Presupuesto)
  or ((AMontaje as IBizMontajeDetalles).ID_PRESUPUESTO <> (AMontaje as IBizMontajeDetalles).Presupuesto.ID) then
     RecuperarPresupuesto((AMontaje as IBizMontajeDetalles));
end;

procedure TMontajesDetallesController.RecuperarPresupuesto(AMontaje: IBizMontajeDetalles);
begin
  AMontaje.Presupuesto := FPresupuestoController.Buscar(AMontaje.ID_PRESUPUESTO);
end;

procedure TMontajesDetallesController.SetDetallesController(const Value: IDetallesMontajeController);
begin
  FDetallesController := Value;
end;

procedure TMontajesDetallesController.SetPresupuestoController(const Value: IPresupuestosController);
begin
  FPresupuestoController := Value;
end;

function TMontajesDetallesController.ValidarMontaje(AMontaje: IBizMontaje): Boolean;
begin
  Result := inherited ValidarMontaje(AMontaje);
  if not Result then exit;

  Result := False;

  if not Assigned(FDetallesController) then
    raise Exception.Create ('Controller detalles no asignado');

  //Tambien hacemos post de sus tablas hija
  if ((AMontaje as IBizMontajeDetalles).Detalles.DataTable.State in dsEditModes) then
      (AMontaje as IBizMontajeDetalles).Detalles.DataTable.Post;

  Result := True;
end;

function TMontajesDetallesController.Nuevo(Presupuesto: IBizPresupuesto): IBizMontajeDetalles;
var
  AMontaje: IBizMontajeDetalles;
begin
  AMontaje := (Nuevo as IBizMontajeDetalles);
  AMontaje.REFERENCIA := Presupuesto.REFERENCIA;
  AMontaje.ID_PRESUPUESTO := Presupuesto.ID;
  AMontaje.IMPORTE_TOTAL := Presupuesto.IMPORTE_TOTAL;
  AMontaje.Cliente := Presupuesto.Cliente;

  //Copiamos los detalles del presupuesto
  with Presupuesto.Detalles do
  begin
    DataTable.First;
    while not DataTable.EOF do
    begin
      AMontaje.Detalles.Insert;
      AMontaje.Detalles.POSICION := POSICION;
      AMontaje.Detalles.TIPO_DETALLE := TIPO_DETALLE;
      AMontaje.Detalles.CONCEPTO := CONCEPTO;
      AMontaje.Detalles.CANTIDAD := CANTIDAD;
      AMontaje.Detalles.DESCUENTO := DESCUENTO;
      AMontaje.Detalles.IMPORTE_UNIDAD := IMPORTE_UNIDAD;
      AMontaje.Detalles.IMPORTE_TOTAL := IMPORTE_TOTAL;
      AMontaje.Detalles.Post;
      DataTable.Next;
    end;
  end;

  Result := AMontaje;
end;

function TMontajesDetallesController.GetDetallesController: IDetallesMontajeController;
begin
  Result := FDetallesController;
end;

function TMontajesDetallesController.GetPresupuestoController: IPresupuestosController;
begin
  Result := FPresupuestoController;
end;

end.
