MetaPermissionRule deleted after import

Hello everyone,

I am trying to import MetaPermission and MetaPermissionRule, but after import some of MetaPermissionRule’s gets deleted.

Please advise.

I’ve also noticed the following behaviour:
If I split auth_role_field_permission_rules.csv by model (that is 1 file for Country and 1 file for City) and import Country first, all MetaPermissionRule’s are imported but after importing City rules, some of Country MetaPermissionRule’s gets deleted.

Binding file:

<?xml version="1.0" encoding="UTF-8"?>
<csv-inputs xmlns="http://axelor.com/xml/ns/data-import"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://axelor.com/xml/ns/data-import http://axelor.com/xml/ns/data-import/data-import_5.4.xsd">

  <input file="auth_role_field_permissions.csv" separator=";"
    type="com.axelor.meta.db.MetaPermission" search="self.name = :name"
    call="com.abc.csv.script.ImportMetaPermission:importPermissionToRoles"/>

  <input file="auth_role_field_permission_rules.csv" separator=";"
    type="com.axelor.meta.db.MetaPermissionRule" search="self.field = :field"
    call="com.abc.csv.script.ImportMetaPermissionRule:importPermissionRule">
    <bind to="metaPermission" column="metaPermission" search="self.name = :metaPermission"/>
    <bind to="canRead" eval="can_read == 'x' ? 'true' : 'false'"/>
    <bind to="canWrite" eval="can_write == 'x' ? 'true' : 'false'"/>
    <bind to="canExport" eval="can_export == 'x' ? 'true' : 'false'"/>
  </input>

</csv-inputs>

auth_role_field_permissions.csv file:

"name";"object";"active";"role"
"perm.supplier.all.Country";"com.axelor.apps.base.db.Country";"true";"Supplier user|Supplier manager user"
"perm.supplier.all.City";"com.axelor.apps.base.db.City";"true";"Supplier user|Supplier manager user"

auth_role_field_permission_rules.csv file:

"metaPermission";"field";"can_read";"can_write";"can_export"
"perm.supplier.all.Country";"alpha2Code";"x";"";""
"perm.supplier.all.Country";"alpha3Code";"x";"";""
"perm.supplier.all.Country";"archived";"";"";""
"perm.supplier.all.Country";"attrs";"";"";""
"perm.supplier.all.Country";"citizenship";"";"";""
"perm.supplier.all.Country";"cog";"";"";""
"perm.supplier.all.Country";"createdBy";"";"";""
"perm.supplier.all.Country";"createdOn";"";"";""
"perm.supplier.all.Country";"economicArea";"";"";""
"perm.supplier.all.Country";"id";"";"";""
"perm.supplier.all.Country";"importId";"";"";""
"perm.supplier.all.Country";"importOrigin";"";"";""
"perm.supplier.all.Country";"isIspmRequired";"";"";""
"perm.supplier.all.Country";"name";"x";"";""
"perm.supplier.all.Country";"numericCode";"x";"";""
"perm.supplier.all.Country";"phonePrefix";"";"";""
"perm.supplier.all.Country";"processInstanceId";"";"";""
"perm.supplier.all.Country";"updatedBy";"";"";""
"perm.supplier.all.Country";"updatedOn";"";"";""
"perm.supplier.all.Country";"version";"";"";""
"perm.supplier.all.City";"archived";"";"";""
"perm.supplier.all.City";"artmin";"";"";""
"perm.supplier.all.City";"attrs";"";"";""
"perm.supplier.all.City";"canton";"";"";""
"perm.supplier.all.City";"country";"r";"";""
"perm.supplier.all.City";"createdBy";"";"";""
"perm.supplier.all.City";"createdOn";"";"";""
"perm.supplier.all.City";"department";"";"";""
"perm.supplier.all.City";"hasZipOnRight";"";"";""
"perm.supplier.all.City";"id";"";"";""
"perm.supplier.all.City";"importId";"";"";""
"perm.supplier.all.City";"importOrigin";"";"";""
"perm.supplier.all.City";"inseeCode";"";"";""
"perm.supplier.all.City";"name";"x";"";""
"perm.supplier.all.City";"nbInhCommune";"";"";""
"perm.supplier.all.City";"processInstanceId";"";"";""
"perm.supplier.all.City";"updatedBy";"";"";""
"perm.supplier.all.City";"updatedOn";"";"";""
"perm.supplier.all.City";"version";"";"";""
"perm.supplier.all.City";"zip";"x";"";""

com.abc.csv.script.ImportMetaPermission:

import com.axelor.auth.db.Role;
import com.axelor.auth.db.repo.RoleRepository;
import com.axelor.inject.Beans;
import com.axelor.meta.db.MetaPermission;
import com.axelor.meta.db.repo.MetaPermissionRepository;
import com.google.common.base.Strings;
import com.google.inject.Inject;
import com.google.inject.persist.Transactional;
import java.util.Arrays;
import java.util.Map;

public class ImportMetaPermission {

  @Inject protected MetaPermissionRepository metaPermissionRepository;

  @Transactional
  public Object importPermissionToRoles(Object bean, Map<String, Object> values) {
    assert bean instanceof MetaPermission;

    try {
      RoleRepository roleRepository = Beans.get(RoleRepository.class);

      MetaPermission permission = (MetaPermission) bean;
      String roles = (String) values.get("role");
      if (permission.getId() != null) {
        if (roles != null && !roles.isEmpty()) {
          for (Role role :
              roleRepository
                  .all()
                  .filter("name in ?1", Arrays.asList(roles.split("\\|")))
                  .fetch()) {
            role.addMetaPermission(metaPermissionRepository.find(permission.getId()));
            roleRepository.save(role);
          }
        }
      }
      return permission;
    } catch (Exception e) {
      e.printStackTrace();
    }
    return bean;
  }
}

com.abc.csv.script.ImportMetaPermissionRule:

import com.axelor.inject.Beans;
import com.axelor.meta.db.MetaPermission;
import com.axelor.meta.db.MetaPermissionRule;
import com.axelor.meta.db.repo.MetaPermissionRepository;
import com.google.common.base.Strings;
import com.google.inject.persist.Transactional;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.lang.invoke.MethodHandles;
import java.util.Map;

public class ImportMetaPermissionRule {

  private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());

  @Transactional
  public Object importPermissionRule(Object bean, Map<String, Object> values) {
    assert bean instanceof MetaPermissionRule;

    MetaPermissionRule permissionRule = (MetaPermissionRule) bean;
    String metaPermission = values.get("metaPermission").toString();
    if (Strings.isNullOrEmpty(metaPermission)) {
      return bean;
    }

    MetaPermissionRepository repository = Beans.get(MetaPermissionRepository.class);
    MetaPermission permission = repository.findByName(metaPermission);

    if (permission == null) {
      return bean;
    }

    permission.addRule(permissionRule);
    repository.save(permission);

    log.info("Added rule for field '" + permissionRule.getField() + "' to '" + metaPermission + "' field permission");

    return bean;
  }
}