Editable Grid: Save Into not working Properly

Hi! I have the following editable grid, in which some values are passed from another record and other ones are completed by the user

When I run the process model, it seems to work properly, auto-generated values appear and the user completes the rest of values:

But after this, the auto-completed values don´t appear in the record! I´m using a WriteRecords function directly in the interface, not in the process model

My configuration is the following one:

I´m using the fv!item to save the values into the local variables, the appending to create new rows and finally using the writeRecords function. But it fails for the variables in which the value is a rule input from a previous interface (idFactura, idPedido, proveedor). The rest of them are saved correctly. What can I do? Thanks a lot!

My code is the following:

a!localVariables(
  local!data,
  {
    a!gridLayout(
      label: "A continuación, incorpore las líneas de factura correspondientes y pulse el botón de creación",
      headerCells: {
        a!gridLayoutHeaderCell(label: "Factura"),
        a!gridLayoutHeaderCell(label: "Pedido"),
        a!gridLayoutHeaderCell(label: "Proveedor"),
        a!gridLayoutHeaderCell(label: "Material"),
        a!gridLayoutHeaderCell(label: "Precio Unitario"),
        a!gridLayoutHeaderCell(label: "Cantidad"),
        a!gridLayoutHeaderCell(label: "Importe Total"),
        a!gridLayoutHeaderCell()


      },
      columnConfigs: {
        a!gridLayoutColumnConfig(width:"DISTRIBUTE"),
        a!gridLayoutColumnConfig(width:"DISTRIBUTE"),
        a!gridLayoutColumnConfig(width:"DISTRIBUTE"),
        a!gridLayoutColumnConfig(width:"DISTRIBUTE"),
        a!gridLayoutColumnConfig(width:"DISTRIBUTE"),
        a!gridLayoutColumnConfig(width:"DISTRIBUTE"),
        a!gridLayoutColumnConfig(width:"DISTRIBUTE"),
        a!gridLayoutColumnConfig(width:"ICON")


      },
      rows: a!forEach(
        items: local!data,
        expression: a!gridRowLayout(
          contents: {
            a!textField(value:ri!recordFact['recordType!{51d44df6-c727-4443-8114-aef8a7509b41}CPF Maestro Facturas.fields.{6f993c32-7f64-424a-859f-d779194c4a18}id_factura'], saveInto: {fv!item['recordType!{6e637180-b344-49d2-a1f7-f87eed0041ba}CPF Lineas Factura.fields.{9c440183-9c71-423b-a300-eb4c3ea747fb}idFactura']}
            ),
            a!textField(value:ri!recordFact['recordType!{51d44df6-c727-4443-8114-aef8a7509b41}CPF Maestro Facturas.fields.{e8009662-ca1c-43da-9c72-2840463214be}id_pedido'], saveInto: {fv!item['recordType!{6e637180-b344-49d2-a1f7-f87eed0041ba}CPF Lineas Factura.fields.{60774c8e-9b47-486f-9fea-b32c525c05fd}idPedido']}
            ),
            a!textField(value:ri!recordFact['recordType!{51d44df6-c727-4443-8114-aef8a7509b41}CPF Maestro Facturas.fields.{c2a60669-567e-41b8-acdd-29729912b3e5}nomProveedor'], saveInto: {fv!item['recordType!{6e637180-b344-49d2-a1f7-f87eed0041ba}CPF Lineas Factura.fields.{844be35b-6de5-434e-9c69-e7c7b8a148dd}proveedor']}
            ),
            a!textField(value:fv!item['recordType!{6e637180-b344-49d2-a1f7-f87eed0041ba}CPF Lineas Factura.fields.{019eb28b-727b-4e2c-8160-1bcf8a747ef1}material'], saveInto: {fv!item['recordType!{6e637180-b344-49d2-a1f7-f87eed0041ba}CPF Lineas Factura.fields.{019eb28b-727b-4e2c-8160-1bcf8a747ef1}material']}
            ),
            a!floatingPointField( value: fv!item['recordType!{6e637180-b344-49d2-a1f7-f87eed0041ba}CPF Lineas Factura.fields.{eda9bda7-ae57-44e7-a651-d097c8581021}precioUnit'],
            saveInto: {fv!item['recordType!{6e637180-b344-49d2-a1f7-f87eed0041ba}CPF Lineas Factura.fields.{eda9bda7-ae57-44e7-a651-d097c8581021}precioUnit'], a!save(fv!item['recordType!{6e637180-b344-49d2-a1f7-f87eed0041ba}CPF Lineas Factura.fields.{53f231a2-9bf7-40a1-af07-74373fa7bd9f}importe'],if(
              or(isnull(fv!item['recordType!{6e637180-b344-49d2-a1f7-f87eed0041ba}CPF Lineas Factura.fields.{b1b5fc0b-5be4-45be-8342-381cdc56017d}cantidad']), isnull(fv!item['recordType!{6e637180-b344-49d2-a1f7-f87eed0041ba}CPF Lineas Factura.fields.{eda9bda7-ae57-44e7-a651-d097c8581021}precioUnit'])),
              0,
              fv!item['recordType!{6e637180-b344-49d2-a1f7-f87eed0041ba}CPF Lineas Factura.fields.{b1b5fc0b-5be4-45be-8342-381cdc56017d}cantidad'] * fv!item['recordType!{6e637180-b344-49d2-a1f7-f87eed0041ba}CPF Lineas Factura.fields.{eda9bda7-ae57-44e7-a651-d097c8581021}precioUnit']
            ) )},
            required: true,
            validations: {if(a!isNotNullOrEmpty(fv!item['recordType!{6e637180-b344-49d2-a1f7-f87eed0041ba}CPF Lineas Factura.fields.{eda9bda7-ae57-44e7-a651-d097c8581021}precioUnit'])=false,"", if(
              fv!item['recordType!{6e637180-b344-49d2-a1f7-f87eed0041ba}CPF Lineas Factura.fields.{eda9bda7-ae57-44e7-a651-d097c8581021}precioUnit'] < 0,
              "El precio unitario debe ser superior a cero",
              ""
            ))}),
            a!integerField( value: fv!item['recordType!{6e637180-b344-49d2-a1f7-f87eed0041ba}CPF Lineas Factura.fields.{b1b5fc0b-5be4-45be-8342-381cdc56017d}cantidad'],
            saveInto:{fv!item['recordType!{6e637180-b344-49d2-a1f7-f87eed0041ba}CPF Lineas Factura.fields.{b1b5fc0b-5be4-45be-8342-381cdc56017d}cantidad'], a!save(fv!item['recordType!{6e637180-b344-49d2-a1f7-f87eed0041ba}CPF Lineas Factura.fields.{53f231a2-9bf7-40a1-af07-74373fa7bd9f}importe'],if(
              or(isnull(fv!item['recordType!{6e637180-b344-49d2-a1f7-f87eed0041ba}CPF Lineas Factura.fields.{b1b5fc0b-5be4-45be-8342-381cdc56017d}cantidad']), isnull(fv!item['recordType!{6e637180-b344-49d2-a1f7-f87eed0041ba}CPF Lineas Factura.fields.{eda9bda7-ae57-44e7-a651-d097c8581021}precioUnit'])),
              0,
              fv!item['recordType!{6e637180-b344-49d2-a1f7-f87eed0041ba}CPF Lineas Factura.fields.{b1b5fc0b-5be4-45be-8342-381cdc56017d}cantidad'] * fv!item['recordType!{6e637180-b344-49d2-a1f7-f87eed0041ba}CPF Lineas Factura.fields.{eda9bda7-ae57-44e7-a651-d097c8581021}precioUnit']
            ) )},
            required: true,
            validations: {if(a!isNotNullOrEmpty(fv!item['recordType!{6e637180-b344-49d2-a1f7-f87eed0041ba}CPF Lineas Factura.fields.{b1b5fc0b-5be4-45be-8342-381cdc56017d}cantidad'])=false,"", if(
              fv!item['recordType!{6e637180-b344-49d2-a1f7-f87eed0041ba}CPF Lineas Factura.fields.{b1b5fc0b-5be4-45be-8342-381cdc56017d}cantidad'] < 1,
              "La cantidad debe ser superior a cero",
              ""
            ))}),
            a!floatingPointField(
              value: if(
                or(isnull(fv!item['recordType!{6e637180-b344-49d2-a1f7-f87eed0041ba}CPF Lineas Factura.fields.{b1b5fc0b-5be4-45be-8342-381cdc56017d}cantidad']), isnull(fv!item['recordType!{6e637180-b344-49d2-a1f7-f87eed0041ba}CPF Lineas Factura.fields.{eda9bda7-ae57-44e7-a651-d097c8581021}precioUnit'])),
                0,
                fv!item['recordType!{6e637180-b344-49d2-a1f7-f87eed0041ba}CPF Lineas Factura.fields.{b1b5fc0b-5be4-45be-8342-381cdc56017d}cantidad'] * fv!item['recordType!{6e637180-b344-49d2-a1f7-f87eed0041ba}CPF Lineas Factura.fields.{eda9bda7-ae57-44e7-a651-d097c8581021}precioUnit']
              ),
              saveInto: {fv!item['recordType!{6e637180-b344-49d2-a1f7-f87eed0041ba}CPF Lineas Factura.fields.{53f231a2-9bf7-40a1-af07-74373fa7bd9f}importe']},
              required: true,
              validations: {if(a!isNotNullOrEmpty(fv!item['recordType!{6e637180-b344-49d2-a1f7-f87eed0041ba}CPF Lineas Factura.fields.{53f231a2-9bf7-40a1-af07-74373fa7bd9f}importe'])=false,"", if(
                fv!item['recordType!{6e637180-b344-49d2-a1f7-f87eed0041ba}CPF Lineas Factura.fields.{53f231a2-9bf7-40a1-af07-74373fa7bd9f}importe'] < 0,
                "El importe debe ser superior a cero",
                ""
              ))},
              align: "RIGHT"
            ),
            a!richTextDisplayField(
              value: {
                a!richTextIcon(
                  icon: "times-circle",
                  link: a!dynamicLink(
                    value: remove(local!data, fv!index),
                    saveInto: local!data
                  ),
                  linkstyle: "STANDALONE",
                  color: "NEGATIVE"
                )

              }
            )

          }
        )
      ),
      addrowlink: a!dynamicLink(
        label: "Añadir nueva Línea de Factura",
        value: append(
          local!data,                             
          'recordType!{6e637180-b344-49d2-a1f7-f87eed0041ba}CPF Lineas Factura'()
        ),
        saveInto: local!data
      )
    )
    ,
    a!buttonLayout(
      primaryButtons: {
        a!buttonWidget(
          label: "Completar Creación Factura",
          saveInto: a!writeRecords(
            records:local!data,
            onSuccess: {a!save(local!data, fv!recordsUpdated)  
          
            }
          ),
          submit: true,
          style: "PRIMARY",
          validate:true
        )
      },
      secondaryButtons: {
        a!buttonWidget(
          label: "Cancelar",
          value: true,
          saveInto: ri!cancel2,
          submit: true,
          style: "NORMAL",
          validate: false
        )
      }
    )

  }
)

  Discussion posts and replies are publicly visible

  • +1
    Certified Lead Developer

    This is probably because in the grid, you mix data from rule inputs and local variables. Then you store the local variables to the database, but not the rule inputs. And then you do something with the data coming from the rule inputs flowing to process variables.

    In my experience, the most important step to solve such a situation, is to simplify it down to a level that you really understand end-to-end. Then, step by step, add more to it. And for each step, test, check and validate the result.

    Another advice, do not mix writeRecords in the interface with writeRecords in process. As you are using a process, remove it from the button and persist the data in process.

  • Alright, thank you so much Stefan! I know maybe this is so basic, but can I use the Write Records form the process directly to save the local variables into the record? Until now I just used It to write input tasks directly referenced to the record, not with local data. Should I have any considerations to do it with local variables?

  • 0
    Certified Lead Developer
    in reply to carlosp5114

    I am not sure I understand ...

    https://www.youtube.com/watch?v=fofrLNviRTA

    The normal way is:

    - Build interface using locals for UI status management and rule inputs for persisting data.

    - Map all rule inputs to process variables

    - Update database in process from process variables.

  • 0
    Certified Lead Developer

    I hate to seem overly nitpicky but this (non) indentation and spacing style makes it nearly impossible to read.  I'm all in favor of condensing lines of code where Appian might automatically insert too many linebreaks, but IMHO you should still be indenting the contents of a component to one additional level beyond the rule call, to make things at least minimally reabable...

  • 0
    Certified Lead Developer

    And the problem with your first 3 columns is, the data you're using to auto-populate the values would never actually be saved into the saveInto target - because as always, the saveInto for a component only ever executes after the user has interacted with the component (i.e. has entered a changed value for it).  If you wish the values in question to also appear in the local!data record value, you'd need to make sure each row in local!data already has the necessary value at the point of creation, in which case you'd be able to set the "value" and "saveInto" parameters both to reference the fv!item[field] data you've already stored.

  • 0
    Certified Lead Developer
    in reply to Mike Schmitt

    FWIW, i've amended your AddRowLink code to (approximately) represent what you'd need to do to initialize the values for those three columns appropriately, considering you seem to be loading them based on the static value of a single-row Rule Input upon creation.  You'll need to adjust the "record type data" calls manually after putting this back into your interface, since the references don't translate to/from Plaintext very well.

    addrowlink: a!dynamicLink(
      label: "Añadir nueva Línea de Factura",
      
      /* the "value" parameter here is 100% unnecessary - just do everything within your a!save() statement */
      /* value: append(
        local!data,                             
        'recordType!{6e637180-b344-49d2-a1f7-f87eed0041ba}'(
          idFactura: ri!recordFact[id_factura],
          idPedido: ri!recordFact[id_pedido],
          nomProveedor: ri!recordFact[proveedor]
        )
      ), */
      saveInto: a!save(
        target: local!data,
        value: append(
          local!data,
          'recordType!{6e637180-b344-49d2-a1f7-f87eed0041ba}'(
            idFactura: ri!recordFact[id_factura],
            idPedido: ri!recordFact[id_pedido],
            nomProveedor: ri!recordFact[proveedor]
          )
        )
      )
    )

  • First of all, I apologize for the structure of my code. It was not my intention to make it difficult to read.

    On the other hand, Thanks Mike, I understand what you are saying, the user is not interacting with those fields so they won´t be saved. My question is, how can I assure the data has the value before the creation? What do you exactly mean with the creation point? By now, I´m using the "value" parameter to reference the value from another record

  • Thanks a lot! I I was writing the first response and did not see it until I send the message. I´m going to try this to see if I can make this work properly!

  • +1
    Certified Lead Developer
    in reply to carlosp5114
    I apologize for the structure of my code.

    At the end of the day it's your code.  But as someone who's been doing this for 11+ years and has coached an endless stream of newer developers, I hope you'll trust me when I say that coming up with a consistent and readable indentation scheme will make your life 10x easier.

    For instance I manually re-formatted some of your above code and, though it takes up some more lines, I find it to be quite a bit more readable (even given the terrible plaintext conversion of the RecordType references, which is not your fault of course), and would be VERY readable when actually showing the friendly names for these.

  • 0
    Certified Lead Developer
    in reply to carlosp5114
    I´m going to try this to see if I can make this work properly!

    Great, please keep me posted!