SAP Business One B1WS: editar oferta de ventas II

Hace poco tuve que modificar unos documentos de márketing (ofertas y pedidos de ventas) vía B1WS/Di Server. Hasta el momento, sólo había creado documentos de SAP y supuse que la edición seguiría el mismo proceso que con los UDO, con los que tengo bastante más manejo. Básicamente, el proceso con un UDO es:

  • Obtengo el objeto sin modificar vía B1WS.
  • Modifico los campos de la cabecera con los datos nuevos.
  • Con el array de líneas, agrego las nuevas, elimino las que hay que borrar y modifico los campos de las que hay que modificar.
  • Le vuelvo a enviar todo a SAP.

Con las líneas, que es lo que me importa aquí, el proceso es como éste, siendo Origen el objeto con los cambios que envía la capa de lógica de negocio y Destino, el objeto sin modificar recuperado de SAP. Como pueden observar, hay una propiedad en las filas origen que me indica qué debo hacer con ellas:

Private Sub RellenarLineas(Origen As IHorasCabecera, Destino As Horas.Horas)
    Dim oLineas As List(Of Horas.HorasCDA_HOR1)
    Dim oLinea As Horas.HorasCDA_HOR1
    If Destino.CDA_HOR1Collection?.Length > 0Then
        oLineas = Destino.CDA_HOR1Collection.ToList
    Else
        oLineas = New List(Of Horas.HorasCDA_HOR1)
    End If
    If Origen.Detalles?.Any Then
        For Each mLinea In Origen.Detalles
            Select Case mLinea.OperacionGuardado
                Case EGuardadoTipoOperacion.Nuevo
                    oLinea = New Horas.HorasCDA_HOR1
                    RellenarLinea(mLinea, oLinea)
                    oLineas.Add(oLinea)
                Case EGuardadoTipoOperacion.Modificar
                    oLinea = oLineas.Where(Function(x) x.LineId = mLinea.LineNum).FirstOrDefault
                    If oLinea IsNot Nothing Then
                        RellenarLinea(mLinea, oLinea)
                    End If
                Case EGuardadoTipoOperacion.Eliminar
                    oLinea = oLineas.Where(Function(x) x.LineId = mLinea.LineNum).FirstOrDefault
                    If oLinea IsNot Nothing Then
                        oLineas.Remove(oLinea)
                    End If
            End Select
        Next
    End If
    Destino.CDA_HOR1Collection = oLineas.ToArray
End Sub

Teniendo esto, supuse que con documentos propios de SAP el proceso sería el mismo. Sí, a mi edad sigo siendo así de iluso.

En fin, si intentas hacer algo así con ofertas o pedidos de ventas e intentes eliminar y añadir filas en el mismo golpe, el resultado es un lío mayúsculo, modificándose líneas que no querías tocar y cosas por el estilo. Me puse a bucear por foros y notas de SAP, intentando descubrir qué estaba haciendo mal. La respuesta la encontré en un tema no relacionado en el que me fijé que el autor del ejemplo de solución forzaba la numeración de las líneas. Era un ejemplo de añadir un documento, no de edición. Pero como la diferencia más llamativa entre las líneas de objetos nativos de SAP y las líneas de UDO es que las primeras empiezan a numerarse en 0 y las segundas, en 1, pensé que por ahí podían ir los tiros y probé lo siguiente:

Private Sub RellenarLineas(origen As ICabecera, destino As Document)
    Dim oLineas As List(Of DocumentDocumentLine)
    Dim oLinea As DocumentDocumentLine
    Dim MaxLin As Long
    If destino.DocumentLines?.Length > 0 Then
        oLineas = destino.DocumentLines.ToList
        MaxLin = oLineas.Max(Function(x) x.LineNum) + 1
    Else
        oLineas = New List(Of DocumentDocumentLine)
        MaxLin = 0
    End If
    If origen.Detalles?.Any Then
        For Each mLinea In origen.Detalles
            Select Case mLinea.OperacionGuardado
                Case EGuardadoTipoOperacion.Nuevo
                    oLinea = New DocumentDocumentLine
                    Me.RellenarLinea(mLinea, oLinea)
                    oLinea.LineNum = MaxLin
                    oLinea.LineNumSpecified = True
                    MaxLin += 1
                    oLineas.Add(oLinea)
                Case EGuardadoTipoOperacion.Modificar
                    oLinea = oLineas.Where(Function(x) x.LineNum = mLinea.LineNum).FirstOrDefault
                    If oLinea IsNot Nothing Then
                        Me.RellenarLinea(mLinea, oLinea)
                    End If
                Case EGuardadoTipoOperacion.Eliminar
                    oLinea = oLineas.Where(Function(x) x.LineNum = mLinea.LineNum).FirstOrDefault
                    If oLinea IsNot Nothing Then
                        oLineas.Remove(oLinea)
                    End If
            End Select
        Next
    End If
    destino.DocumentLines = oLineas.ToArray
End Sub

¡Bingo!

Deja un comentario

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.