public static Map importParty()

in applications/party/src/main/java/org/apache/ofbiz/party/party/PartyServices.java [2291:2685]


    public static Map<String, Object> importParty(DispatchContext dctx, Map<String, Object> context) {
        Delegator delegator = dctx.getDelegator();
        LocalDispatcher dispatcher = dctx.getDispatcher();
        Locale locale = (Locale) context.get("locale");
        GenericValue userLogin = (GenericValue) context.get("userLogin");
        ByteBuffer fileBytes = (ByteBuffer) context.get("uploadedFile");
        String encoding = System.getProperty("file.encoding");
        String csvString = Charset.forName(encoding).decode(fileBytes).toString();
        Builder csvFormatBuilder = Builder.create().setHeader();
        CSVFormat fmt = csvFormatBuilder.build();
        List<String> errMsgs = new LinkedList<>();
        List<String> newErrMsgs = new LinkedList<>();
        String lastPartyId = null;        // last partyId read from the csv file
        String currentPartyId = null;     // current partyId from the csv file
        String newPartyId = null;        // new to create/update partyId in the system
        String newCompanyPartyId = null;
        int partiesCreated = 0;
        Map<String, Object> result = null;
        String newContactMechId = null;
        String currentContactMechTypeId = null;

        String lastAddress1 = null;
        String lastAddress2 = null;
        String lastCity = null;
        String lastCountryGeoId = null;

        String lastEmailAddress = null;

        String lastCountryCode = null;
        String lastAreaCode = null;
        String lastContactNumber = null;

        String lastContactMechPurposeTypeId = null;
        String currentContactMechPurposeTypeId = null;

        boolean addParty = false; // when modify party, contact mech not added again


        try (BufferedReader csvReader = new BufferedReader(new StringReader(csvString))) {
            for (CSVRecord rec : fmt.parse(csvReader)) {
                if (UtilValidate.isNotEmpty(rec.get("partyId"))) {
                    currentPartyId = rec.get("partyId");
                }
                if (lastPartyId == null || !currentPartyId.equals(lastPartyId)) {
                    newPartyId = null;
                    currentContactMechPurposeTypeId = null;
                    lastAddress1 = null;
                    lastAddress2 = null;
                    lastCity = null;
                    lastCountryGeoId = null;

                    lastEmailAddress = null;

                    lastCountryCode = null;
                    lastAreaCode = null;
                    lastContactNumber = null;

                    // party validation
                    List<GenericValue> currencyCheck = EntityQuery.use(delegator).from("Uom")
                            .where("abbreviation", rec.get("preferredCurrencyUomId"), "uomTypeId", "CURRENCY_MEASURE")
                            .queryList();
                    if (UtilValidate.isNotEmpty(rec.get("preferredCurrencyUomId")) && currencyCheck.isEmpty()) {
                        newErrMsgs.add("Line number " + rec.getRecordNumber() + ": partyId: " + currentPartyId + "Currency code not found for: "
                                + rec.get("preferredCurrencyUomId"));
                    }

                    if (UtilValidate.isEmpty(rec.get("roleTypeId"))) {
                        newErrMsgs.add("Line number " + rec.getRecordNumber()
                                + ": Mandatory roletype is missing, possible values: CUSTOMER, SUPPLIER, EMPLOYEE and more....");
                    } else if (EntityQuery.use(delegator).from("RoleType").where("roleTypeId", rec.get("roleTypeId")).queryOne() == null) {
                        newErrMsgs.add("Line number " + rec.getRecordNumber() + ": RoletypeId is not valid: " + rec.get("roleTypeId"));
                    }

                    if (UtilValidate.isNotEmpty(rec.get("contactMechTypeId"))
                            && EntityQuery.use(delegator).from("ContactMechType").where("contactMechTypeId", rec.get("contactMechTypeId"))
                            .cache().queryOne() == null) {
                        newErrMsgs.add("Line number " + rec.getRecordNumber() + ": partyId: " + currentPartyId
                                + " contactMechTypeId code not found for: "
                                + rec.get("contactMechTypeId"));
                    }

                    if (UtilValidate.isNotEmpty(rec.get("contactMechPurposeTypeId"))
                            && EntityQuery.use(delegator).from("ContactMechPurposeType").where("contactMechPurposeTypeId",
                            rec.get("contactMechPurposeTypeId")).cache().queryOne() == null) {
                        newErrMsgs.add("Line number " + rec.getRecordNumber() + ": partyId: " + currentPartyId
                                + "contactMechPurposeTypeId code not found for: " + rec.get("contactMechPurposeTypeId"));
                    }

                    if (UtilValidate.isNotEmpty(rec.get("contactMechTypeId")) && "POSTAL_ADDRESS".equals(rec.get("contactMechTypeId"))) {
                        if (UtilValidate.isEmpty(rec.get("countryGeoId"))) {
                            newErrMsgs.add("Line number " + rec.getRecordNumber() + ": partyId: " + currentPartyId + "Country code missing");
                        } else {
                            List<GenericValue> countryCheck = EntityQuery.use(delegator).from("Geo")
                                    .where("geoTypeId", "COUNTRY", "abbreviation", rec.get("countryGeoId"))
                                    .queryList();
                            if (countryCheck.isEmpty()) {
                                newErrMsgs.add("Line number " + rec.getRecordNumber() + " partyId: " + currentPartyId + " Invalid Country code: "
                                        + rec.get("countryGeoId"));
                            }
                        }

                        if (UtilValidate.isEmpty(rec.get("city"))) {
                            newErrMsgs.add("Line number " + rec.getRecordNumber() + " partyId: " + currentPartyId + "City name is missing");
                        }

                        if (UtilValidate.isNotEmpty(rec.get("stateProvinceGeoId"))) {
                            List<GenericValue> stateCheck = EntityQuery.use(delegator).from("Geo")
                                    .where("geoTypeId", "STATE", "abbreviation", rec.get("stateProvinceGeoId"))
                                    .queryList();
                            if (stateCheck.isEmpty()) {
                                newErrMsgs.add("Line number " + rec.getRecordNumber() + " partyId: " + currentPartyId
                                        + " Invalid stateProvinceGeoId code: " + rec.get("countryGeoId"));
                            }
                        }
                    }

                    if (UtilValidate.isNotEmpty(rec.get("contactMechTypeId")) && "TELECOM_NUMBER".equals(rec.get("contactMechTypeId"))) {
                        if (UtilValidate.isEmpty(rec.get("telAreaCode")) && UtilValidate.isEmpty(rec.get("telAreaCode"))) {
                            newErrMsgs.add("Line number " + rec.getRecordNumber() + " partyId: " + currentPartyId + " telephone number missing");
                        }
                    }

                    if (UtilValidate.isNotEmpty(rec.get("contactMechTypeId")) && "EMAIL_ADDRESS".equals(rec.get("contactMechTypeId"))) {
                        if (UtilValidate.isEmpty(rec.get("emailAddress"))) {
                            newErrMsgs.add("Line number " + rec.getRecordNumber() + " partyId: " + currentPartyId + " email address missing");
                        }
                    }

                    if (errMsgs.isEmpty()) {
                        List<GenericValue> partyCheck = EntityQuery.use(delegator).from("PartyIdentification")
                                .where("partyIdentificationTypeId", "PARTY_IMPORT", "idValue", rec.get("partyId"))
                                .queryList();
                        addParty = partyCheck.isEmpty();
                        if (!addParty) { // update party
                            newPartyId = EntityUtil.getFirst(partyCheck).getString("partyId");

                            if (UtilValidate.isNotEmpty(rec.get("groupName"))) {
                                Map<String, Object> partyGroup = UtilMisc.toMap(
                                        "partyId", newPartyId,
                                        "preferredCurrencyUomId", rec.get("preferredCurrencyUomId"),
                                        "groupName", rec.get("groupName"),
                                        "userLogin", userLogin);
                                result = dispatcher.runSync("updatePartyGroup", partyGroup);
                                if (ServiceUtil.isError(result)) {
                                    // Eclipse reports here: Resource leak: '<unassigned Closeable value>' is not closed at this location
                                    // but it's OK. As csvReader is in a try-with-ressource it will be closed anyway
                                    // I prefer to not put @SuppressWarnings("resource") to the whole method
                                    // BTW to be consistent Eclipse should also reports the same issue below
                                    return ServiceUtil.returnError(ServiceUtil.getErrorMessage(result));
                                }
                            } else { // person
                                Map<String, Object> person = UtilMisc.toMap(
                                        "partyId", newPartyId,
                                        "firstName", rec.get("firstName"),
                                        "middleName", rec.get("middleName"),
                                        "lastName", rec.get("lastName"),
                                        "preferredCurrencyUomId", rec.get("preferredCurrencyUomId"),
                                        "userLogin", userLogin);
                                result = dispatcher.runSync("updatePerson", person);
                                if (ServiceUtil.isError(result)) {
                                    return ServiceUtil.returnError(ServiceUtil.getErrorMessage(result));
                                }
                            }

                        } else { // create new party
                            if (UtilValidate.isNotEmpty(rec.get("groupName"))) {
                                Map<String, Object> partyGroup = UtilMisc.toMap(
                                        "preferredCurrencyUomId", rec.get("preferredCurrencyUomId"),
                                        "groupName", rec.get("groupName"),
                                        "userLogin", userLogin,
                                        "statusId", "PARTY_ENABLED");
                                result = dispatcher.runSync("createPartyGroup", partyGroup);
                                if (ServiceUtil.isError(result)) {
                                    return ServiceUtil.returnError(ServiceUtil.getErrorMessage(result));
                                }
                            } else { // person
                                Map<String, Object> person = UtilMisc.toMap(
                                        "firstName", rec.get("firstName"),
                                        "middleName", rec.get("middleName"),
                                        "lastName", rec.get("lastName"),
                                        "preferredCurrencyUomId", rec.get("preferredCurrencyUomId"),
                                        "statusId", "PARTY_ENABLED",
                                        "userLogin", userLogin);
                                result = dispatcher.runSync("createPerson", person);
                                if (ServiceUtil.isError(result)) {
                                    return ServiceUtil.returnError(ServiceUtil.getErrorMessage(result));
                                }
                            }
                            newPartyId = (String) result.get("partyId");

                            Map<String, Object> partyIdentification = UtilMisc.toMap("partyId", newPartyId,
                                    "partyIdentificationTypeId", "PARTY_IMPORT", "idValue", rec.get("partyId"), "userLogin", userLogin);

                            result = dispatcher.runSync("createPartyIdentification", partyIdentification);
                            if (ServiceUtil.isError(result)) {
                                return ServiceUtil.returnError(ServiceUtil.getErrorMessage(result));
                            }

                            Map<String, Object> partyRole = UtilMisc.toMap("partyId", newPartyId, "roleTypeId", rec.get("roleTypeId"),
                                    "userLogin", userLogin);
                            dispatcher.runSync("createPartyRole", partyRole);
                            if (ServiceUtil.isError(result)) {
                                return ServiceUtil.returnError(ServiceUtil.getErrorMessage(result));
                            }

                            if (UtilValidate.isNotEmpty(rec.get("companyPartyId"))) {
                                List<GenericValue> companyCheck = EntityQuery.use(delegator).from("PartyIdentification")
                                        .where("partyIdentificationTypeId", "PARTY_IMPORT", "idValue", rec.get("partyId"))
                                        .queryList();
                                if (companyCheck.isEmpty()) { // update party group
                                    // company does not exist so create
                                    Map<String, Object> companyPartyGroup = UtilMisc.toMap(
                                            "partyId", newCompanyPartyId, "statusId", "PARTY_ENABLED", "userLogin", userLogin);
                                    result = dispatcher.runSync("createPartyGroup", companyPartyGroup);
                                    if (ServiceUtil.isError(result)) {
                                        return ServiceUtil.returnError(ServiceUtil.getErrorMessage(result));
                                    }
                                    newCompanyPartyId = (String) result.get("partyId");
                                } else {
                                    newCompanyPartyId = EntityUtil.getFirst(companyCheck).getString("partyId");
                                }

                                Map<String, Object> companyRole = UtilMisc.toMap(
                                        "partyId", newCompanyPartyId, "roleTypeId", "ACCOUNT", "userLogin", userLogin);
                                Map<String, Object> serviceResult = dispatcher.runSync("createPartyRole", companyRole);
                                if (ServiceUtil.isError(serviceResult)) {
                                    return ServiceUtil.returnError(ServiceUtil.getErrorMessage(serviceResult));
                                }

                                // company exist, so create link
                                Map<String, Object> partyRelationship = UtilMisc.toMap("partyIdTo", newPartyId, "partyIdFrom", newCompanyPartyId,
                                        "roleTypeIdFrom", "ACCOUNT", "partyRelationshipTypeId", "EMPLOYMENT", "userLogin", userLogin);
                                result = dispatcher.runSync("createPartyRelationship", partyRelationship);
                                if (ServiceUtil.isError(result)) {
                                    return ServiceUtil.returnError(ServiceUtil.getErrorMessage(result));
                                }
                            }
                        }
                        Debug.logInfo(" New party created with id: " + newPartyId, MODULE);
                        partiesCreated++;
                    } else {
                        errMsgs.addAll(newErrMsgs);
                        newErrMsgs = new LinkedList<>();
                    }
                }

                currentContactMechTypeId = rec.get("contactMechTypeId");
                currentContactMechPurposeTypeId = rec.get("contactMechPurposeTypeId");
                // party correctly created (not updated) and contactMechtype provided?
                if (newPartyId != null && addParty && UtilValidate.isNotEmpty(currentContactMechTypeId)) {

                    // fill maps and check changes
                    Map<String, Object> emailAddress = UtilMisc.toMap("contactMechTypeId", "EMAIL_ADDRESS", "userLogin", userLogin);
                    boolean emailAddressChanged = false;
                    if ("EMAIL_ADDRESS".equals(currentContactMechTypeId)) {
                        emailAddress.put("infoString", rec.get("emailAddress"));
                        emailAddressChanged = lastEmailAddress == null || !lastEmailAddress.equals(rec.get("emailAddress"));
                        lastEmailAddress = rec.get("emailAddress");
                    }

                    Map<String, Object> postalAddress = UtilMisc.toMap("userLogin", (Object) userLogin);
                    // casting is here necessary for some compiler versions

                    boolean postalAddressChanged = false;
                    if ("POSTAL_ADDRESS".equals(currentContactMechTypeId)) {
                        postalAddress.put("address1", rec.get("address1"));
                        postalAddress.put("address2", rec.get("address2"));
                        postalAddress.put("city", rec.get("city"));
                        postalAddress.put("stateProvinceGeoId", rec.get("stateProvinceGeoId"));
                        postalAddress.put("countryGeoId", rec.get("countryGeoId"));
                        postalAddress.put("postalCode", rec.get("postalCode"));
                        postalAddressChanged =
                                lastAddress1 == null || !lastAddress1.equals(postalAddress.get("address1"))
                                || lastAddress2 == null || !lastAddress2.equals(postalAddress.get("address2"))
                                || lastCity == null || !lastCity.equals(postalAddress.get("city"))
                                || lastCountryGeoId == null || !lastCountryGeoId.equals(postalAddress.get("countryGeoId"));
                        lastAddress1 = (String) postalAddress.get("address1");
                        lastAddress2 = (String) postalAddress.get("address2");
                        lastCity = (String) postalAddress.get("city");
                        lastCountryGeoId = (String) postalAddress.get("countryGeoId");
                    }

                    Map<String, Object> telecomNumber = UtilMisc.toMap("userLogin", (Object) userLogin);
                    // casting is here necessary for some compiler versions

                    boolean telecomNumberChanged = false;
                    if ("TELECOM_NUMBER".equals(currentContactMechTypeId)) {
                        telecomNumber.put("countryCode", rec.get("telCountryCode"));
                        telecomNumber.put("areaCode", rec.get("telAreaCode"));
                        telecomNumber.put("contactNumber", rec.get("telContactNumber"));
                        telecomNumberChanged =
                                lastCountryCode == null || !lastCountryCode.equals(telecomNumber.get("countryCode"))
                                || lastAreaCode == null || !lastAreaCode.equals(telecomNumber.get("areaCode"))
                                || lastContactNumber == null || !lastContactNumber.equals(telecomNumber.get("contactNumber"));
                        lastCountryCode = (String) telecomNumber.get("countryCode");
                        lastAreaCode = (String) telecomNumber.get("areaCode");
                        lastContactNumber = (String) telecomNumber.get("contactNumber");
                    }

                    Map<String, Object> partyContactMechPurpose = UtilMisc.toMap("partyId", newPartyId, "userLogin", userLogin);
                    boolean partyContactMechPurposeChanged = false;
                    currentContactMechPurposeTypeId = rec.get("contactMechPurposeTypeId");
                    if (currentContactMechPurposeTypeId != null && ("TELECOM_NUMBER".equals(currentContactMechTypeId)
                            || "POSTAL_ADDRESS".equals(currentContactMechTypeId) || "EMAIL_ADDRESS".equals(currentContactMechTypeId))) {
                        partyContactMechPurpose.put("contactMechPurposeTypeId", currentContactMechPurposeTypeId);
                        partyContactMechPurpose.put("contactMechTypeId", currentContactMechTypeId);
                        partyContactMechPurposeChanged = (lastContactMechPurposeTypeId == null
                                || !lastContactMechPurposeTypeId.equals(currentContactMechPurposeTypeId)) && !telecomNumberChanged
                                && !postalAddressChanged && !emailAddressChanged;
                        Debug.logInfo("Last:" + lastContactMechPurposeTypeId + " current: " + currentContactMechPurposeTypeId + " t :"
                                + telecomNumberChanged + " p: " + postalAddressChanged + " e: " + emailAddressChanged + " result: "
                                + partyContactMechPurposeChanged, MODULE);
                    }
                    lastContactMechPurposeTypeId = currentContactMechPurposeTypeId;

                    // update
                    if (errMsgs.isEmpty()) {

                        if (postalAddressChanged) {
                            result = dispatcher.runSync("createPostalAddress", postalAddress);
                            if (ServiceUtil.isError(result)) {
                                return ServiceUtil.returnError(ServiceUtil.getErrorMessage(result));
                            }
                            newContactMechId = (String) result.get("contactMechId");
                            if (currentContactMechPurposeTypeId == null) {
                                currentContactMechPurposeTypeId = "GENERAL_LOCATION";
                            }
                            Map<String, Object> serviceResult = dispatcher.runSync("createPartyContactMech", UtilMisc.toMap("partyId", newPartyId,
                                    "contactMechId", newContactMechId, "contactMechTypeId", currentContactMechTypeId,
                                    "contactMechPurposeTypeId", currentContactMechPurposeTypeId, "userLogin", userLogin));
                            if (ServiceUtil.isError(serviceResult)) {
                                return ServiceUtil.returnError(ServiceUtil.getErrorMessage(serviceResult));
                            }
                        }

                        if (telecomNumberChanged) {
                            result = dispatcher.runSync("createTelecomNumber", telecomNumber);
                            if (ServiceUtil.isError(result)) {
                                return ServiceUtil.returnError(ServiceUtil.getErrorMessage(result));
                            }
                            newContactMechId = (String) result.get("contactMechId");
                            if (currentContactMechPurposeTypeId == null) {
                                currentContactMechPurposeTypeId = "PHONE_WORK";
                            }
                            Map<String, Object> resultMap = dispatcher.runSync("createPartyContactMech", UtilMisc.toMap("partyId", newPartyId,
                                    "contactMechId", newContactMechId, "contactMechTypeId", currentContactMechTypeId,
                                    "contactMechPurposeTypeId", currentContactMechPurposeTypeId, "userLogin", userLogin));
                            if (ServiceUtil.isError(resultMap)) {
                                return ServiceUtil.returnError(ServiceUtil.getErrorMessage(result));
                            }
                        }

                        if (emailAddressChanged) {
                            result = dispatcher.runSync("createContactMech", emailAddress);
                            if (ServiceUtil.isError(result)) {
                                return ServiceUtil.returnError(ServiceUtil.getErrorMessage(result));
                            }
                            newContactMechId = (String) result.get("contactMechId");
                            if (currentContactMechPurposeTypeId == null) {
                                currentContactMechPurposeTypeId = "PRIMARY_EMAIL";
                            }
                            Map<String, Object> resultMap = dispatcher.runSync("createPartyContactMech", UtilMisc.toMap("partyId", newPartyId,
                                    "contactMechId", newContactMechId, "contactMechTypeId", currentContactMechTypeId,
                                    "contactMechPurposeTypeId", currentContactMechPurposeTypeId, "userLogin", userLogin));
                            if (ServiceUtil.isError(resultMap)) {
                                return ServiceUtil.returnError(ServiceUtil.getErrorMessage(result));
                            }
                        }

                        if (partyContactMechPurposeChanged) {
                            partyContactMechPurpose.put("contactMechId", newContactMechId);
                            result = dispatcher.runSync("createPartyContactMechPurpose", partyContactMechPurpose);
                            if (ServiceUtil.isError(result)) {
                                return ServiceUtil.returnError(ServiceUtil.getErrorMessage(result));
                            }
                        }
                        lastPartyId = currentPartyId;
                        errMsgs.addAll(newErrMsgs);
                        newErrMsgs = new LinkedList<>();
                    }
                }
            }
        } catch (GenericServiceException | GenericEntityException | IOException e) {
            Debug.logError(e, MODULE);
            return ServiceUtil.returnError(e.getMessage());
        }

        if (!errMsgs.isEmpty()) {
            return ServiceUtil.returnError(errMsgs);
        }

        result = ServiceUtil.returnSuccess(UtilProperties.getMessage(RESOURCE, "PartyNewPartiesCreated",
                UtilMisc.toMap("partiesCreated", partiesCreated), locale));
        return result;
    }