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