Si no quieres vender…

En el trabajo andamos buscando tablets. Descartado Android tras una serie de pruebas, el siguiente paso es Windows. La duda está en si 8, RT o CE. Para no entramparnos en comprar una tablet profesional (cuestan una pasta) decidimos buscar una baratita para pruebas en el departamento y luego decidir. Encontramos la Acer Iconia W3 como candidata ideal. Barata y con Windows 8 (8,1» de pantalla y una memoria interna ridícula, pues sólo vemos la versión de 32GB; vamos, que no me la compraba para mí ni loco).

Mi jefe de departamento se acerca a El Corte Inglés, donde la tienen clasificada como con Windows RT y el vendedor dice que tiene RT (y echa pestes del sistema; entiendo que se pueda considerar «capado» con respecto a Windows 8, pero Android e iOS entran en el mismo saco), así que ante la duda vuelve con las manos vacías.

Consultamos la página del fabricante. Queda bien claro. Procesador Atom, Windows 8… Encontramos de paso otro sitio donde está más barato, así que vamos allí, la pescamos y vuelta.

El tiempo que pierdes porque no te quieren vender.

Operador Update

El otro día necesitaba actualizar valores en una colección de DataRows tipadas y echaba de menos no poder hacerlo con LINQ, así que me puse a buscar. Y buscando, buscando, encontré el código para un método de extensión Update que soluciona la papeleta. El código está aquí en C# y en Visual Basic quedaría así:

Public Delegate Sub Func(Of TArg0)(element As TArg0)

''' <summary>
''' Executes an Update statement block on all elements in an IEnumerable(T) sequence.
''' </summary>
''' <typeparam name=TSource">The source element type.</typeparam>"
''' <param name=source">The source sequence.</param>"
''' <param name=Updater">The update statement to execute for each element.</param>"
''' <returns>The numer of records affected.</returns>
<System.Runtime.CompilerServices.Extension> _
Public Function Update(Of TSource)(source As IEnumerable(Of TSource), Updater As Func(Of TSource)) As Integer
    If source Is Nothing Then
        Throw New ArgumentNullException("source")
    End If
    If Updater Is Nothing Then
        Throw New ArgumentNullException("update")
    End If
    If GetType(TSource).IsValueType Then
        Throw New NotSupportedException("value type elements are not supported by update.")
    End If

    Dim count As Integer = 0
    For Each element As TSource In source
        Updater(element)
        count += 1
    Next
    Return count
End Function

Su uso sería algo así:

TareasParaArticulo.Where(Function(x) x.IdUsuario = 0).Update(Function(x) x.IdUsuario = JefeProyecto)

Donde TareasParaArticulo es un conjunto de datarows tipadas (un list, un datatable…, tanto da). Lo que hace esta parte de la aplicación, para ponernos en situación, es crear una serie de tareas (tomadas de una plantilla de tareas) cuando un artículo es añadido a un proyecto. El uso del Update permite asignar aquellas tareas que en la plantilla tienen como IdUsuario el 0 al jefe del proyecto de una forma sencilla.

Eficiencia alemana

Con la actualización a SAP Business One 9.0 se decidió cambiar la nomenclatura de los almacenes. En la práctica, esto supuso crear almacenes nuevos y mover masimavente la mercancía en el sistema (necesario, de todas formas, para aprovechar el nuevo sistema de ubicaciones). Para evitar que los usuarios metieran accidentalmente mercancía en los almacenes viejos, se marcaron como Inactivos (un bonito check en el formulario de almacenes, que se corresponde con el campo Inactive de la tabla correspondiente). Hasta ahí, sin problemas.

Como baja colateral, el enlace entre el gestor de proyectos (desarrollo propio) y SAP dejó de funcionar. El enlace permite tanto crear artículos en SAP desde el gestor como actualizarlos después y supuso un gran ahorro de trabajo en el departamento, que hasta entonces debía copiar los datos logísticos de un nuevo producto a mano desde el gestor a SAP.

El error que da al actualizar el artículo es que hay almacenes inactivos. Guay. La cosa se pone interesante porque el código del error no aparece en la documentación (he descubierto estos meses que lo raro es que aparezca). Es más, buscando en la documentación de la DI Api (la interfaz de datos que se usa para comunicarse con SAP) el dichoso campo Inactive no aparece en el objeto Almacén.

Vale, puede ser que yo sea un cegato y venga con otro nombre (no es raro), así que me voy a la documentación de la base de datos para ver si la descripción del campo me da alguna pista sobre qué nombre buscar en la DI Api.

Y no lo encuentro. En la documentación de la base de datos de la versión 9.0 no viene, para la tabla maestra de almacenes, el campo Inactive. Por más que exista y por más que tenga un bonito check en el formulario de gestión de almacenes. Con un par.

A eso se le llama «eficiencia alemana».