Appian Community and Appian Academy are being upgraded. From July 24–August 3, the Appian Community will be in read-only mode. During this time, the site will be read-only and user registration will be disabled. We apologize for any inconvenience this may cause, but a more secure, stable, and performant Community experience is coming soon!

The new Appian Community launches August 3, followed by Appian Academy on August 7. During the migration, Appian Community Edition, Appian Academy, Documentation, Certifications, Instructor-led Customer Training, Partner Sales Training & Accreditation, and Forum (for Appian Partners and Customers only) will remain available.

Need to store comments from four assessors in list of map

Certified Associate Developer

HI guys

I'm chasing my tail here.

We are assessing software against 4 criteria per software title.

For each criterion we have a different assessor group.

The software titles are kept in a list of map since they are not yet approved for our Allow List and we don't want to keep the data if they are not approved.

We have a custom comments record type which has a many-to-one relationship with the software table.

Issue:

For each software title we need to keep 4 comments, but I find I am only able to overwrite the comments value, not append.

Here's the code for my approval details interface:

a!localVariables(
  local!softwareCategoryList: rule!getSoftwareCategoryList(
    includeDisabled: false,
    includedSoftwareCategoryID: if(
      a!isNullOrEmpty(
        ri!mappedValue.software[Global Software.fields.id']
      ),
      null,
      ri!mappedValue.software['recordType!Global Software.fields.softwareCategoryID']
    )
  ),
  a!gridLayout(
    label: "Approve Software",
    labelPosition: "COLLAPSED",
    headerCells: {
      a!gridLayoutHeaderCell(label: "Software Name"),
      a!gridLayoutHeaderCell(label: "Category Name"),
      a!gridLayoutHeaderCell(label: "Vendor Name"),
      a!gridLayoutHeaderCell(
        label: "",
        showWhen: and(not(ri!readOnly), not(ri!edit))
      ),
      a!gridLayoutHeaderCell(
        label: "Comment",
        showWhen: rule!APP_isTrue(ri!mappedValue.decision),
        align: "LEFT"
      ),
      a!gridLayoutHeaderCell(
        label: "Status",
        showWhen: and(ri!readOnly, not(ri!edit))
      )
    },
    columnConfigs: {
      a!gridLayoutColumnConfig(width: "DISTRIBUTE", weight: 3),
      a!gridLayoutColumnConfig(width: "DISTRIBUTE", weight: 3),
      a!gridLayoutColumnConfig(width: "DISTRIBUTE", weight: 3),
      a!gridLayoutColumnConfig(width: "NARROW", weight: null),
      a!gridLayoutColumnConfig(width: "MEDIUM"),
      a!gridLayoutColumnConfig(width: "DISTRIBUTE")
    },
    rows: a!forEach(
      items: ri!mappedValue,
      expression: {
        a!gridRowLayout(
          id: fv!index,
          contents: {
            a!textField(
              label: "Software Name",
              labelPosition: "COLLAPSED",
              value: fv!item.software['recordType!Global Software.fields.name'],
              saveInto: fv!item.software['recordType!Global Software.fields.name'],
              readOnly: or(ri!readOnly, not(ri!edit))
            ),
            a!richTextDisplayField(
              label: "Category Name",
              labelPosition: "ADJACENT",
              value: {
                a!richTextItem(
                  text: fv!item.software['recordType! Global Software.relationships.softwareCategory.fields.name']
                ),
                char(32),
                a!richTextIcon(
                  icon: "question-circle-o",
                  caption: fv!item.software['recordType!Global Software.relationships.softwareCategory.fields.description'],
                  showWhen: a!isNotNullOrEmpty(
                    fv!item.software['recordType!Global Software.relationships.softwareCategory.fields.description']
                  ),
                  color: "#b3d1e6",
                  size: "MEDIUM"
                )
              },
              showWhen: or(ri!readOnly, not(ri!edit))
            ),
            a!dropdownField(
              choiceLabels: local!softwareCategoryList['recordType!Software Category.fields.name'],
              choiceValues: local!softwareCategoryList['recordType!Software Category.fields.id'],
              label: "Software Category",
              labelPosition: "ADJACENT",
              placeholder: "--- Select a software category  ---",
              value: fv!item.software['recordType!Global Software.fields.softwareCategoryID'],
              saveInto: {
                fv!item.software['recordType!Global Software.fields.softwareCategoryID'],
                a!save(
                  fv!item.software['recordType! Global Software.relationships.softwareCategory'],
                  index(
                    local!softwareCategoryList,
                    wherecontains(
                      save!value,
                      local!softwareCategoryList['recordType!Software Category.fields.id']
                    ),
                    null
                  )
                )
              },
              showWhen: and(not(ri!readOnly), (ri!edit)),
              required: true
            ),
            a!textField(
              label: "Vendor Name",
              labelPosition: "COLLAPSED",
              value: fv!item.software['recordType!Global Software.fields.vendorName'],
              saveInto: fv!item.software['recordType!Global Software.fields.vendorName'],
              readOnly: or(ri!readOnly, not(ri!edit))
            ),
            a!radioButtonField(
              choiceLabels: { "Approve", "Rejected" },
              choiceValues: { true, false },
              label: "Approve",
              labelPosition: "COLLAPSED",
              value: fv!item.decision,
              saveInto: { fv!item.decision },
              showWhen: and(not(ri!readOnly), not(ri!edit)),
              required: true,
              choiceLayout: "COMPACT",
              choiceStyle: "CARDS"
            ),
            a!paragraphField(
              label: "Comments",
              labelPosition: "ABOVE",
              placeholder: "Please add any comments you may have",
              value: ri!mappedValue.software['recordType!Global Software.relationships.comments.fields.comment'],
              saveInto: {
                ri!mappedValue.software['recordType!Global Software.relationships.comments.fields.comment']
              },
              refreshAfter: "UNFOCUS",
              height: "MEDIUM",
              showWhen: rule!APP_isTrue(ri!mappedValue.decision),
              readOnly: rule!APP_isTrue(ri!readOnly),
              disabled: false
            ),
            a!tagField(
              labelPosition: "COLLAPSED",
              tags: {
                a!match(
                  value: true,
                  equals: fv!item.decision,
                  then: a!tagItem(
                    text: "APPROVED",
                    backgroundColor: "#0c9aba"
                  ),
                  default: a!tagItem(
                    text: "NOT APPROVED",
                    backgroundColor: "#FF9B78"
                  )
                )
              },
              showWhen: and(ri!readOnly, not(ri!edit))
            )
          },
          selectionDisabled: false
        )
      }
    ),
    selectionSaveInto: {},
    allowRowReordering: false,
    validations: {},
    shadeAlternateRows: false,
    borderStyle: "LIGHT"
  )
)

I know there's probably a simple answer but I am drowning in a lake of overthink!

Any help will be gratefully accepted

Blessings

Stephen

  Discussion posts and replies are publicly visible

Parents
  • 0
    Certified Lead Developer

    You're overwriting the comment relationship field instead of appending new comment records. Since you have a one-to-many relationship between software and comments, you need to create new comment records and append them to the existing array.

    saveInto: {
      a!save(
        ri!mappedValue.software['recordType!Global Software.relationships.comments'],
    append(
    ri!mappedValue.software['recordType!Global Software.relationships.comments'],
    'recordType!Comments'(
    'recordType!Comments.fields.comment': save!value,
    'recordType!Comments.fields.softwareId': fv!item.software['recordType!Global Software.fields.id'],
    /* Add a field to identify which criterion/assessor this comment is for */
    'recordType!Comments.fields.criterionId': ri!currentCriterionId
    )
    )
    )
    }
    
    


  • 0
    Certified Associate Developer
    in reply to Shubham Aware

    Thank you, appreciated.

    The issue is that I don't have a software ID for the global software record type, as we don't wish to write the record until the software is approved.

    We need this to work both for single and multiple values (multiple uploaded via Excel)

  • 0
    Certified Lead Developer
    in reply to Stephen Kane

    Since you don't have software Ids yet, store comments temporarily in the map and create the relationship later(You need to add a comments field to your map structure. When you initially create your software maps (likely in a process model or parent interface)):

    saveInto: {
      a!save(
        fv!item.comments,
        append(
          if(a!isNullOrEmpty(fv!item.comments), {}, fv!item.comments),
          a!map(
            comment: save!value,
            criterionId: ri!currentCriterionId,
            assessorGroup: ri!currentAssessorGroup,
            timestamp: now()
          )
        )
      )
    }

    When approving, iterate through the comments array and create actual comment records with the newly generated software Id:
    a!forEach(
      items: fv!item.comments,
      expression: 'recordType!Comments'(
        'recordType!Comments.fields.comment': fv!item.comment,
        'recordType!Comments.fields.softwareId': local!newSoftwareId,
        'recordType!Comments.fields.criterionId': fv!item.criterionId
      )
    )


    Give it a try let me know if that works for you.

Reply
  • 0
    Certified Lead Developer
    in reply to Stephen Kane

    Since you don't have software Ids yet, store comments temporarily in the map and create the relationship later(You need to add a comments field to your map structure. When you initially create your software maps (likely in a process model or parent interface)):

    saveInto: {
      a!save(
        fv!item.comments,
        append(
          if(a!isNullOrEmpty(fv!item.comments), {}, fv!item.comments),
          a!map(
            comment: save!value,
            criterionId: ri!currentCriterionId,
            assessorGroup: ri!currentAssessorGroup,
            timestamp: now()
          )
        )
      )
    }

    When approving, iterate through the comments array and create actual comment records with the newly generated software Id:
    a!forEach(
      items: fv!item.comments,
      expression: 'recordType!Comments'(
        'recordType!Comments.fields.comment': fv!item.comment,
        'recordType!Comments.fields.softwareId': local!newSoftwareId,
        'recordType!Comments.fields.criterionId': fv!item.criterionId
      )
    )


    Give it a try let me know if that works for you.

Children
No Data