<commit_before>/**
 * @license
 * Copyright 2020 The FOAM Authors. All Rights Reserved.
 * http://www.apache.org/licenses/LICENSE-2.0
 */

foam.CLASS({
  package: 'foam.nanos.crunch.lite.ruler',
  name: 'CapableCreateApprovalsRuleAction',

  documentation: `
    TODO:
  `,

  javaImports: [
    'foam.core.ContextAwareAgent',
    'foam.core.FObject',
    'foam.core.X',
    'foam.dao.DAO',
    'foam.dao.ArraySink',
    'foam.nanos.auth.User',
    'foam.nanos.approval.Approvable',
    'foam.nanos.approval.ApprovalRequest',
    'foam.nanos.approval.ApprovalStatus',
    'foam.nanos.ruler.Operations',
    'foam.nanos.auth.Subject',
    'java.util.Map',
    'java.util.ArrayList',
    'java.util.List',
    'foam.util.SafetyUtil',
    'foam.nanos.crunch.Capability',
    'foam.nanos.crunch.lite.Capable',
    'foam.nanos.crunch.lite.CapablePayload',
    'foam.nanos.logger.Logger'
  ],

  implements: ['foam.nanos.ruler.RuleAction'],

  properties: [
    { 
      name: 'capabilitiesToApprove',
      class: 'List',
      of: 'String',
      javaType: 'java.util.List<String>',
      factory: function() {
        return [];
      },
      javaFactory: 'return new java.util.ArrayList();'
    },
    {
      class: 'String',
      name: 'daoToReput',
      required: true
    },
    {
      class: 'String',
      name: 'groupToNotify',
      value: 'fraud-ops'
    }
  ],

  methods: [
    {
      name: 'applyAction',
      javaCode: `
        User user = ((Subject) x.get("subject")).getUser();

        Logger logger = (Logger) x.get("logger");

        List<String> capabilitiesToApprove = getCapabilitiesToApprove();

        FObject clonedObj = obj.fclone();

        Capable capableObj = (Capable) clonedObj;

        agency.submit(x, new ContextAwareAgent() {
          
          @Override
          public void execute(X x) {
            for ( CapablePayload capablePayload : capableObj.getCapablePayloads() ){

              if ( 
                capablePayload.getObjId() == null || 
                SafetyUtil.isEmpty(String.valueOf(capablePayload.getObjId()))
              ){
                capablePayload.setObjId(obj.getProperty("id"));
                capablePayload.setHasSafeStatus(true);
              }

              Capability capability = capablePayload.getCapability();

              if ( ! getCapabilitiesToApprove().contains(capability.getId()) ){
                capablePayload.setStatus(foam.nanos.crunch.CapabilityJunctionStatus.GRANTED);
                capablePayload.setHasSafeStatus(true);
                continue;
              }

              capablePayload.setStatus(foam.nanos.crunch.CapabilityJunctionStatus.PENDING);
              capablePayload.setHasSafeStatus(true);

              // TODO: Review with Eric
              capablePayload.setNeedsApproval(true);

              DAO approvalRequestDAO = (DAO) getX().get("approvalRequestDAO");
              DAO approvableDAO = (DAO) getX().get("approvableDAO");

              Operations operation = Operations.CREATE;

              String hashedId = new StringBuilder("d")
                .append(capablePayload.getDaoKey())
                .append(":o")
                .append(String.valueOf(capablePayload.getObjId()))
                .append(":c")
                .append(capability.getId())
                .toString();

              List approvablesPending = ((ArraySink) approvableDAO
                .where(foam.mlang.MLang.AND(
                  foam.mlang.MLang.EQ(Approvable.LOOKUP_ID, hashedId),
                  foam.mlang.MLang.EQ(Approvable.STATUS, ApprovalStatus.REQUESTED)
                )).inX(getX()).select(new ArraySink())).getArray();
              
              if ( approvablesPending.size() > 0 ){
                logger.warning("Approvable already  exists for: " + hashedId);
                // TODO: throw an error once we add the paymentId checks as this is supposed  to be  unexpected
                // but because no paymentid check, then we end up in  an infinite loop just need to return
                return;
              }

              try {
                FObject objectToDiffAgainst = (FObject) capablePayload.getClassInfo().newInstance();
              
                Map propertiesToApprove = objectToDiffAgainst.diff(capablePayload);

                Approvable approvable = (Approvable) approvableDAO.put_(getX(), new Approvable.Builder(getX())
                  .setLookupId(hashedId)
                  .setDaoKey(capablePayload.getDaoKey())
                  .setServerDaoKey(capablePayload.getDaoKey())
                  .setStatus(ApprovalStatus.REQUESTED)
                  .setObjId(capablePayload.getObjId())
                  .setOperation(operation)
                  .setOf(capablePayload.getClassInfo())
                  .setIsUsingNestedJournal(true)
                  .setPropertiesToUpdate(propertiesToApprove).build());

                ApprovalRequest  approvalRequest = new ApprovalRequest.Builder(getX())
                  .setDaoKey("approvableDAO")
                  .setObjId(approvable.getId())
                  .setOperation(operation)
                  .setCreatedBy(user.getId())
                  .setGroup(getGroupToNotify())
                  .setClassification(
                    capability.getName() + 
                    " for " + 
                    obj.getClassInfo().getObjClass().getSimpleName() + 
                    " - id:" + 
                    capablePayload.getObjId()
                  )
                  .setStatus(ApprovalStatus.REQUESTED).build();

                approvalRequestDAO.put_(getX(), approvalRequest);
              } catch (Exception e){
                throw new RuntimeException(e);
              }
            }

            // everything at this point  is either PENDING or GRANTED we need to reput
            if ( ! clonedObj.equals(obj) ){
              DAO daoToReput = (DAO) x.get(getDaoToReput());

              daoToReput.put(clonedObj);
            }
          }

        }, "Sent out approval requests for needed payloads and granted the others");
      `
    }
  ]
});
<commit_msg>Added throw uerFeedbackException need to inspect a bit more<commit_after>/**
 * @license
 * Copyright 2020 The FOAM Authors. All Rights Reserved.
 * http://www.apache.org/licenses/LICENSE-2.0
 */

foam.CLASS({
  package: 'foam.nanos.crunch.lite.ruler',
  name: 'CapableCreateApprovalsRuleAction',

  documentation: `
    TODO:
  `,

  javaImports: [
    'foam.core.ContextAwareAgent',
    'foam.core.FObject',
    'foam.core.X',
    'foam.dao.DAO',
    'foam.dao.ArraySink',
    'foam.nanos.auth.User',
    'foam.nanos.approval.Approvable',
    'foam.nanos.approval.ApprovalRequest',
    'foam.nanos.approval.ApprovalStatus',
    'foam.comics.v2.userfeedback.UserFeedback',
    'foam.comics.v2.userfeedback.UserFeedbackException',
    'foam.comics.v2.userfeedback.UserFeedbackStatus',
    'foam.nanos.ruler.Operations',
    'foam.nanos.auth.Subject',
    'java.util.Map',
    'java.util.ArrayList',
    'java.util.List',
    'foam.util.SafetyUtil',
    'foam.nanos.crunch.Capability',
    'foam.nanos.crunch.lite.Capable',
    'foam.nanos.crunch.lite.CapablePayload',
    'foam.nanos.logger.Logger'
  ],

  implements: ['foam.nanos.ruler.RuleAction'],

  properties: [
    { 
      name: 'capabilitiesToApprove',
      class: 'List',
      of: 'String',
      javaType: 'java.util.List<String>',
      factory: function() {
        return [];
      },
      javaFactory: 'return new java.util.ArrayList();'
    },
    {
      class: 'String',
      name: 'daoToReput',
      required: true
    },
    {
      class: 'String',
      name: 'groupToNotify',
      value: 'fraud-ops'
    }
  ],

    messages: [
    { name: 'REQUEST_SEND_MSG', message: 'An approval request has been sent out.' }
  ],

  methods: [
    {
      name: 'applyAction',
      javaCode: `
        User user = ((Subject) x.get("subject")).getUser();

        Logger logger = (Logger) x.get("logger");

        List<String> capabilitiesToApprove = getCapabilitiesToApprove();

        FObject clonedObj = obj.fclone();

        Capable capableObj = (Capable) clonedObj;

        agency.submit(x, new ContextAwareAgent() {
          
          @Override
          public void execute(X x) {
            for ( CapablePayload capablePayload : capableObj.getCapablePayloads() ){

              if ( 
                capablePayload.getObjId() == null || 
                SafetyUtil.isEmpty(String.valueOf(capablePayload.getObjId()))
              ){
                capablePayload.setObjId(obj.getProperty("id"));
                capablePayload.setHasSafeStatus(true);
              }

              Capability capability = capablePayload.getCapability();

              if ( ! getCapabilitiesToApprove().contains(capability.getId()) ){
                capablePayload.setStatus(foam.nanos.crunch.CapabilityJunctionStatus.GRANTED);
                capablePayload.setHasSafeStatus(true);
                continue;
              }

              capablePayload.setStatus(foam.nanos.crunch.CapabilityJunctionStatus.PENDING);
              capablePayload.setHasSafeStatus(true);

              // TODO: Review with Eric
              capablePayload.setNeedsApproval(true);

              DAO approvalRequestDAO = (DAO) getX().get("approvalRequestDAO");
              DAO approvableDAO = (DAO) getX().get("approvableDAO");

              Operations operation = Operations.CREATE;

              String hashedId = new StringBuilder("d")
                .append(capablePayload.getDaoKey())
                .append(":o")
                .append(String.valueOf(capablePayload.getObjId()))
                .append(":c")
                .append(capability.getId())
                .toString();

              List approvablesPending = ((ArraySink) approvableDAO
                .where(foam.mlang.MLang.AND(
                  foam.mlang.MLang.EQ(Approvable.LOOKUP_ID, hashedId),
                  foam.mlang.MLang.EQ(Approvable.STATUS, ApprovalStatus.REQUESTED)
                )).inX(getX()).select(new ArraySink())).getArray();
              
              if ( approvablesPending.size() > 0 ){
                logger.warning("Approvable already  exists for: " + hashedId);
                // TODO: throw an error once we add the paymentId checks as this is supposed  to be  unexpected
                // but because no paymentid check, then we end up in  an infinite loop just need to return
                return;
              }

              try {
                FObject objectToDiffAgainst = (FObject) capablePayload.getClassInfo().newInstance();
              
                Map propertiesToApprove = objectToDiffAgainst.diff(capablePayload);

                Approvable approvable = (Approvable) approvableDAO.put_(getX(), new Approvable.Builder(getX())
                  .setLookupId(hashedId)
                  .setDaoKey(capablePayload.getDaoKey())
                  .setServerDaoKey(capablePayload.getDaoKey())
                  .setStatus(ApprovalStatus.REQUESTED)
                  .setObjId(capablePayload.getObjId())
                  .setOperation(operation)
                  .setOf(capablePayload.getClassInfo())
                  .setIsUsingNestedJournal(true)
                  .setPropertiesToUpdate(propertiesToApprove).build());

                ApprovalRequest  approvalRequest = new ApprovalRequest.Builder(getX())
                  .setDaoKey("approvableDAO")
                  .setObjId(approvable.getId())
                  .setOperation(operation)
                  .setCreatedBy(user.getId())
                  .setGroup(getGroupToNotify())
                  .setClassification(
                    capability.getName() + 
                    " for " + 
                    obj.getClassInfo().getObjClass().getSimpleName() + 
                    " - id:" + 
                    capablePayload.getObjId()
                  )
                  .setStatus(ApprovalStatus.REQUESTED).build();

                approvalRequestDAO.put_(getX(), approvalRequest);
              } catch (Exception e){
                throw new RuntimeException(e);
              }
            }

            // everything at this point  is either PENDING or GRANTED we need to reput
            if ( ! clonedObj.equals(obj) ){
              DAO daoToReput = (DAO) x.get(getDaoToReput());

              daoToReput.put(clonedObj);

              // TODO: for some reason the UpdateTransactionOnInvoiceValidationRule fires after throwing
              throw new UserFeedbackException.Builder(x)
                .setUserFeedback(new UserFeedback.Builder(x)
                  .setStatus(UserFeedbackStatus.SUCCESS)
                  .setMessage(REQUEST_SEND_MSG)
                  .build()
                ).build();
            }
          }

        }, "Sent out approval requests for needed payloads and granted the others");
      `
    }
  ]
});

{'fraction_non_alphanumeric': 0.11378403465346534, 'fraction_numerical': 0.0013149752475247526, 'mean_word_length': 1.849680405554331, 'pattern_counts': {'":': 4, '<': 7, '<?xml version=': 0, '>': 9, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6346814', 'n_tokens_mistral': 3768, 'n_tokens_neox': 3613, 'n_words': 592}