{$A8,B-,C+,D+,E-,F-,G+,H+,I+,J-,K-,L+,M-,N+,O+,P+,Q-,R-,S-,T-,U-,V+,W-,X+,Y+,Z1} {$MINSTACKSIZE $00004000} {$MAXSTACKSIZE $00100000} {$IMAGEBASE $00400000} {$APPTYPE GUI} {$WARN SYMBOL_DEPRECATED ON} {$WARN SYMBOL_LIBRARY ON} {$WARN SYMBOL_PLATFORM ON} {$WARN SYMBOL_EXPERIMENTAL ON} {$WARN UNIT_LIBRARY ON} {$WARN UNIT_PLATFORM ON} {$WARN UNIT_DEPRECATED ON} {$WARN UNIT_EXPERIMENTAL ON} {$WARN HRESULT_COMPAT ON} {$WARN HIDING_MEMBER ON} {$WARN HIDDEN_VIRTUAL ON} {$WARN GARBAGE ON} {$WARN BOUNDS_ERROR ON} {$WARN ZERO_NIL_COMPAT ON} {$WARN STRING_CONST_TRUNCED ON} {$WARN FOR_LOOP_VAR_VARPAR ON} {$WARN TYPED_CONST_VARPAR ON} {$WARN ASG_TO_TYPED_CONST ON} {$WARN CASE_LABEL_RANGE ON} {$WARN FOR_VARIABLE ON} {$WARN CONSTRUCTING_ABSTRACT ON} {$WARN COMPARISON_FALSE ON} {$WARN COMPARISON_TRUE ON} {$WARN COMPARING_SIGNED_UNSIGNED ON} {$WARN COMBINING_SIGNED_UNSIGNED ON} {$WARN UNSUPPORTED_CONSTRUCT ON} {$WARN FILE_OPEN ON} {$WARN FILE_OPEN_UNITSRC ON} {$WARN BAD_GLOBAL_SYMBOL ON} {$WARN DUPLICATE_CTOR_DTOR ON} {$WARN INVALID_DIRECTIVE ON} {$WARN PACKAGE_NO_LINK ON} {$WARN PACKAGED_THREADVAR ON} {$WARN IMPLICIT_IMPORT ON} {$WARN HPPEMIT_IGNORED ON} {$WARN NO_RETVAL ON} {$WARN USE_BEFORE_DEF ON} {$WARN FOR_LOOP_VAR_UNDEF ON} {$WARN UNIT_NAME_MISMATCH ON} {$WARN NO_CFG_FILE_FOUND ON} {$WARN IMPLICIT_VARIANTS ON} {$WARN UNICODE_TO_LOCALE ON} {$WARN LOCALE_TO_UNICODE ON} {$WARN IMAGEBASE_MULTIPLE ON} {$WARN SUSPICIOUS_TYPECAST ON} {$WARN PRIVATE_PROPACCESSOR ON} {$WARN UNSAFE_TYPE OFF} {$WARN UNSAFE_CODE OFF} {$WARN UNSAFE_CAST OFF} {$WARN OPTION_TRUNCATED ON} {$WARN WIDECHAR_REDUCED ON} {$WARN DUPLICATES_IGNORED ON} {$WARN UNIT_INIT_SEQ ON} {$WARN LOCAL_PINVOKE ON} {$WARN MESSAGE_DIRECTIVE ON} {$WARN TYPEINFO_IMPLICITLY_ADDED ON} {$WARN XML_WHITESPACE_NOT_ALLOWED ON} {$WARN XML_UNKNOWN_ENTITY ON} {$WARN XML_INVALID_NAME_START ON} {$WARN XML_INVALID_NAME ON} {$WARN XML_EXPECTED_CHARACTER ON} {$WARN XML_CREF_NO_RESOLVE ON} {$WARN XML_NO_PARM ON} {$WARN XML_NO_MATCHING_PARM ON} unit uGenerarAlbaranesProvUtils; interface uses Windows, SysUtils, Classes, uBizPedidosProveedor, pngimage, JSDialog; type TdmGenerarAlbaranesProv = class(TDataModule) JsListaAlbaranesGenerados: TJSDialog; end; function GenerarAlbaranProv(const IDPedido : Integer) : Boolean; overload; function GenerarAlbaranProv(APedido : IBizPedidoProveedor) : Boolean; overload; function GenerarAlbaranProv : Boolean; overload; function RecibirPedidoProv(APedido: IBizPedidoProveedor): Boolean; overload; function RecibirPedidoProv: Boolean; overload; implementation {$R *.dfm} uses Forms, Dialogs, uDialogUtils, uDataTableUtils, uBizDetallesPedidoProveedor, uBizDetallesAlbaranProveedor, uPedidosProveedorController, uDetallesPedidoProveedorController, uAlbaranesProveedorController, uProveedoresController, uDetallesAlbaranProveedorController, uControllerDetallesBase, uBizAlbaranesProveedor, uBizContactos, schPedidosProveedorClient_Intf, schAlbaranesProveedorClient_Intf, uInventarioController, uBizInventario; var dmGenerarAlbaranesCli: TdmGenerarAlbaranesProv; APedidosProveedorController : IPedidosProveedorController; ADetallesPedidosProveedorController : IDetallesPedidoProveedorController; AAlbaranesProveedorController : IAlbaranesProveedorController; ADetallesAlbaranesController : IDetallesAlbaranProveedorController; AProveedoresController : IProveedoresController; AInventarioController : IInventarioController; { Métodos auxiliares } procedure CopiarPedidoAAlbaran(APedido: IBizPedidoProveedor; AAlbaran : IBizAlbaranProveedor); begin if not Assigned(AAlbaran) then raise Exception.Create ('Albarán no asignado (CopiarPedidoAAlbaran)'); if not Assigned(APedido) then raise Exception.Create ('Pedido no asignado (CopiarPedidoAAlbaran)'); if not APedido.DataTable.Active then APedido.DataTable.Active := True; // El albarán tiene que venir ya abierto y posicionado donde hay que copiar AAlbaran.ID_PROVEEDOR := APedido.ID_PROVEEDOR; AAlbaran.ID_PEDIDO := APedido.ID; //Ojo se asignará al albarán el almacén ddestino que tenga el primer pedido del proveedor determinado AAlbaran.ID_ALMACEN := APedido.ID_ALMACEN; AAlbaran.CALLE := APedido.CALLE; AAlbaran.CODIGO_POSTAL := APedido.CODIGO_POSTAL; AAlbaran.POBLACION := APedido.POBLACION; AAlbaran.PROVINCIA := APedido.PROVINCIA; AAlbaran.PERSONA_CONTACTO := APedido.PERSONA_CONTACTO; AAlbaran.TELEFONO := APedido.TELEFONO; AAlbaran.IMPORTE_NETO := APedido.IMPORTE_NETO; AAlbaran.IMPORTE_PORTE := APedido.IMPORTE_PORTE; AAlbaran.DESCUENTO := APedido.DESCUENTO; AAlbaran.IMPORTE_DESCUENTO := APedido.IMPORTE_DESCUENTO; AAlbaran.BASE_IMPONIBLE := APedido.BASE_IMPONIBLE; AAlbaran.IVA := APedido.IVA; AAlbaran.IMPORTE_IVA := APedido.IMPORTE_IVA; AAlbaran.IMPORTE_TOTAL := APedido.IMPORTE_TOTAL; AAlbaran.DataTable.FieldByName(fld_AlbaranesProveedorOBSERVACIONES).AsVariant := APedido.DataTable.FieldByName(fld_PedidosProveedorOBSERVACIONES).AsVariant; AAlbaran.ID_FORMA_PAGO := APedido.ID_FORMA_PAGO; end; procedure CopiarArticulosPendAAlbaran( APedido: IBizPedidoProveedor; AAlbaran: IBizAlbaranProveedor; AArticulosPendientes: IBizDetallesPedidoProveedorPend); var i : integer; ADetalles : IBizDetallesAlbaranProveedor; ADetallesController : IDetallesAlbaranProveedorController; begin if not Assigned(AAlbaran) then raise Exception.Create ('Albarán no asignado (CopiarArticulosPendAAlbaran)'); if not Assigned(APedido) then raise Exception.Create ('Pedido no asignado (CopiarArticulosPendAAlbaran)'); if not Assigned(AArticulosPendientes) then raise Exception.Create ('Artículos pendientes no asignado (CopiarArticulosPendAAlbaran)'); if not AArticulosPendientes.DataTable.Active then AArticulosPendientes.DataTable.Active := True; // El albarán tiene que venir ya abierto y posicionado donde hay que copiar ADetalles := AAlbaran.Detalles; ADetallesController := TDetallesAlbaranProveedorController.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); AArticulosPendientes.DataTable.First; for i := 0 to AArticulosPendientes.DataTable.RecordCount - 1 do begin APedido.Detalles.First; if (APedido.Detalles.Locate('ID_ARTICULO', AArticulosPendientes.ID_ARTICULO, [])) then if (AArticulosPendientes.CANTIDAD > 0) then begin ADetallesController.Add(ADetalles, TIPO_DETALLE_CONCEPTO); ADetalles.Edit; ADetalles.ID_PEDIDO := APedido.Detalles.ID_PEDIDO; ADetalles.REFERENCIA := APedido.Detalles.REFERENCIA; ADetalles.ID_ARTICULO := APedido.Detalles.ID_ARTICULO; ADetalles.CONCEPTO := APedido.Detalles.CONCEPTO; ADetalles.CANTIDAD := AArticulosPendientes.CANTIDAD; ADetalles.IMPORTE_UNIDAD := APedido.Detalles.IMPORTE_UNIDAD; ADetalles.IMPORTE_TOTAL := APedido.Detalles.IMPORTE_TOTAL; ADetalles.DESCUENTO := APedido.Detalles.DESCUENTO; ADetalles.IMPORTE_PORTE := APedido.Detalles.IMPORTE_PORTE; ADetalles.VISIBLE := APedido.Detalles.VISIBLE; ADetalles.REFERENCIA_PROVEEDOR := APedido.Detalles.REFERENCIA_PROVEEDOR; ADetalles.Post; AArticulosPendientes.Next; end; end; finally ADetallesController.EndUpdate(ADetalles); ADetallesController := NIL; end; end; procedure Inicializar; begin dmGenerarAlbaranesCli := TdmGenerarAlbaranesProv.Create(nil); APedidosProveedorController := TPedidosProveedorController.Create; ADetallesPedidosProveedorController := TDetallesPedidoProveedorController.Create; AAlbaranesProveedorController := TAlbaranesProveedorController.Create; ADetallesAlbaranesController := TDetallesAlbaranProveedorController.Create; AProveedoresController := TProveedoresController.Create; AInventarioController := TInventarioController.Create; end; procedure Finalizar; begin FreeAndNIL(dmGenerarAlbaranesCli); APedidosProveedorController := nil; ADetallesPedidosProveedorController := nil; AAlbaranesProveedorController := nil; ADetallesAlbaranesController := nil; AProveedoresController := nil; AInventarioController := nil; end; function GenerarAlbaranProv(const IDPedido : Integer) : Boolean; overload; var APedido : IBizPedidoProveedor; begin try if not Assigned(APedidosProveedorController) then Inicializar; APedido := APedidosProveedorController.Buscar(IDPedido); Result := GenerarAlbaranProv(APedido); if Assigned(APedidosProveedorController) then Finalizar; finally APedido := NIL; end; end; function GenerarAlbaranProv(APedido : IBizPedidoProveedor) : Boolean; overload; var ARespuesta : Integer; AAlbaran : IBizAlbaranProveedor; AArticulosPendientes: IBizDetallesPedidoProveedorPend; begin Result := False; if not Assigned(APedido) then raise Exception.Create('Pedido de proveedor no asignado (GenerarAlbaranProv)'); if not APedido.DataTable.Active then APedido.DataTable.Active := True; try if not Assigned(APedidosProveedorController) then Inicializar; AArticulosPendientes := ADetallesPedidosProveedorController.ArticulosPendientes(APedido.ID); if not Assigned(AArticulosPendientes) then raise Exception.Create('Error al recuperar los artículos sin albarán del pedido (GenerarAlbaranProv)'); AArticulosPendientes.DataTable.Active := True; if AArticulosPendientes.DataTable.RecordCount = 0 then begin ARespuesta := ShowConfirmMessage('Generar albarán a partir del pedido', 'Todos los artículos de este pedido ya figuran en uno o más albaranes de proveedor.' + #10#13 + '¿Desea generar de todas formas otro albarán para este pedido?'); if (ARespuesta = IDNO) then Exit; // Aunque es un exit, se ejecuta la parte del finally antes de salir. end; AAlbaran := AAlbaranesProveedorController.Nuevo; CopiarPedidoAAlbaran(APedido, AAlbaran); CopiarArticulosPendAAlbaran(APedido, AAlbaran, AArticulosPendientes); //Sustituir por if de guardar if AAlbaranesProveedorController.Guardar(AAlbaran) then begin // ShowWarningMessage('Todos los artículos que contiene el pedido no están en el catálogo, y por lo tanto no se puede generar el albarán'); 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 pedido de cliente' + #10#13, [AAlbaran.REFERENCIA])); Execute; ARespuesta := CustomButtonResult; case ARespuesta of 100 : begin // Ver el albarán AAlbaranesProveedorController.Ver(AAlbaran); end; 200 : // Continuar; end; end; end; Result := True; finally AArticulosPendientes := NIL; if Assigned(APedidosProveedorController) then Finalizar; end; end; function GenerarAlbaranProv : Boolean; overload; var APedido : IBizPedidoProveedor; begin Result := False; try if not Assigned(APedidosProveedorController) then Inicializar; APedido := APedidosProveedorController.ElegirPedidos(APedidosProveedorController.BuscarPendientesRecepcion, 'Elija el pedido de proveedor que desea utilizar para dar de alta el albarán correspondiente.' , False); if Assigned(APedido) then Result := GenerarAlbaranProv(APedido); finally if Assigned(APedidosProveedorController) then Finalizar; end; end; function RecibirPedidoProv(APedido: IBizPedidoProveedor): Boolean; var bGenerarAlbaran : Boolean; ARespuesta : Integer; AArticulosPendientes: IBizDetallesPedidoProveedorPend; AAlbaran : IBizAlbaranProveedor; AInventarioRecibido: IBizInventario; begin Result := False; bGenerarAlbaran := False; AInventarioRecibido := NIL; if not Assigned(AInventarioController) then Inicializar; // ¿Hay almacén asociado al pedido? if APedido.ID_ALMACEN = 0 then begin if (ShowConfirmMessage('Recepción de pedido a proveedor', 'Este pedido no tiene un almacén asociado por lo que se generará el albarán de proveedor correspondiente sin hacer ningún cambio en el stock de los almacenes.' + #10#13 + #10#13 + '¿Desea continuar?') = IDYES) then bGenerarAlbaran := True; end else begin try // En AInventarioRecibido tenemos la lista de articulos que hemos recibido y // que utilizaremos para hacer el albarán AArticulosPendientes := ADetallesPedidosProveedorController.ArticulosPendientes(APedido.ID); if not Assigned(AArticulosPendientes) then raise Exception.Create('Error al recuperar los artículos pendientes de recibir del pedido (GenerarAlbaranProv)'); AArticulosPendientes.DataTable.Active := True; if AArticulosPendientes.DataTable.RecordCount = 0 then begin ARespuesta := ShowConfirmMessage('Generar albarán a partir del pedido', 'Todos los artículos de este pedido ya figuran en uno o más albaranes de proveedor.' + #10#13 + '¿Desea generar de todas formas otro albarán para este pedido?'); if (ARespuesta = IDNO) then Exit; // Aunque es un exit, se ejecuta la parte del finally antes de salir. end; bGenerarAlbaran := AInventarioController.EntradaPedido(nil, APedido, AArticulosPendientes, AInventarioRecibido); except on E : Exception do ShowMessage(E.Message); end; end; if bGenerarAlbaran then begin try AAlbaran := AAlbaranesProveedorController.Nuevo; // En AInventarioRecibido tenemos la lista de articulos que hemos recibido y // que utilizaremos para hacer el albarán if AAlbaranesProveedorController.Anadir(AAlbaran, APedido.ID, AInventarioRecibido) then begin AAlbaranesProveedorController.Guardar(AAlbaran); AAlbaranesProveedorController.Ver(AAlbaran); //Si el pedido tiene obra de reserva, preguntamos si quiere automatizar el proceso de reserva de los materiales if (APedido.ID_OBRA > 0) then begin if Application.MessageBox(PChar('Desea realizar la reserva del material recibido para la obra ' + APedido.NOMBRE_OBRA + ', asociada al pedido'), 'Atención', MB_YESNO) = IDYES then begin AInventarioRecibido.TipoMovimiento := tReserva; AInventarioRecibido.IDAlmacenOrigen := APedido.ID_ALMACEN; AInventarioRecibido.IDAlmacenDestino := APedido.ID_OBRA; AInventarioController.Guardar(AInventarioRecibido, AAlbaran.FECHA_ALBARAN, ('Reserva para obra ' + APedido.NOMBRE_OBRA + ' del pedido ' + APedido.REFERENCIA), False); end; end; end; finally AAlbaran := NIL; AInventarioRecibido := Nil; end; end; if Assigned(AAlbaranesProveedorController) then Finalizar; // actRefrescar.Execute; end; function RecibirPedidoProv: Boolean; overload; var APedido : IBizPedidoProveedor; begin Result := False; try if not Assigned(APedidosProveedorController) then Inicializar; APedido := APedidosProveedorController.ElegirPedidos(APedidosProveedorController.BuscarPendientesRecepcion, 'Elija el pedido de proveedor que desea recibir.' , False); if Assigned(APedido) then Result := RecibirPedidoProv(APedido); finally if Assigned(APedidosProveedorController) then Finalizar; end; end; end.