001    /**
002     * Copyright (c) 2000-2013 Liferay, Inc. All rights reserved.
003     *
004     * This library is free software; you can redistribute it and/or modify it under
005     * the terms of the GNU Lesser General Public License as published by the Free
006     * Software Foundation; either version 2.1 of the License, or (at your option)
007     * any later version.
008     *
009     * This library is distributed in the hope that it will be useful, but WITHOUT
010     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
011     * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
012     * details.
013     */
014    
015    package com.liferay.portal.service.impl;
016    
017    import com.liferay.portal.DuplicateOrganizationException;
018    import com.liferay.portal.OrganizationNameException;
019    import com.liferay.portal.OrganizationParentException;
020    import com.liferay.portal.OrganizationTypeException;
021    import com.liferay.portal.RequiredOrganizationException;
022    import com.liferay.portal.kernel.configuration.Filter;
023    import com.liferay.portal.kernel.dao.orm.QueryUtil;
024    import com.liferay.portal.kernel.exception.PortalException;
025    import com.liferay.portal.kernel.exception.SystemException;
026    import com.liferay.portal.kernel.search.Hits;
027    import com.liferay.portal.kernel.search.Indexer;
028    import com.liferay.portal.kernel.search.IndexerRegistryUtil;
029    import com.liferay.portal.kernel.search.QueryConfig;
030    import com.liferay.portal.kernel.search.SearchContext;
031    import com.liferay.portal.kernel.search.Sort;
032    import com.liferay.portal.kernel.util.ArrayUtil;
033    import com.liferay.portal.kernel.util.GetterUtil;
034    import com.liferay.portal.kernel.util.ListUtil;
035    import com.liferay.portal.kernel.util.OrderByComparator;
036    import com.liferay.portal.kernel.util.PropsKeys;
037    import com.liferay.portal.kernel.util.StringPool;
038    import com.liferay.portal.kernel.util.StringUtil;
039    import com.liferay.portal.kernel.util.TreeModelFinder;
040    import com.liferay.portal.kernel.util.TreePathUtil;
041    import com.liferay.portal.kernel.util.Validator;
042    import com.liferay.portal.kernel.workflow.WorkflowConstants;
043    import com.liferay.portal.model.Company;
044    import com.liferay.portal.model.Group;
045    import com.liferay.portal.model.GroupConstants;
046    import com.liferay.portal.model.LayoutSet;
047    import com.liferay.portal.model.ListTypeConstants;
048    import com.liferay.portal.model.Organization;
049    import com.liferay.portal.model.OrganizationConstants;
050    import com.liferay.portal.model.ResourceConstants;
051    import com.liferay.portal.model.Role;
052    import com.liferay.portal.model.RoleConstants;
053    import com.liferay.portal.model.User;
054    import com.liferay.portal.model.UserGroupRole;
055    import com.liferay.portal.model.impl.OrganizationImpl;
056    import com.liferay.portal.security.permission.PermissionCacheUtil;
057    import com.liferay.portal.service.ServiceContext;
058    import com.liferay.portal.service.base.OrganizationLocalServiceBaseImpl;
059    import com.liferay.portal.util.PropsUtil;
060    import com.liferay.portal.util.PropsValues;
061    import com.liferay.portal.util.comparator.OrganizationIdComparator;
062    import com.liferay.portal.util.comparator.OrganizationNameComparator;
063    import com.liferay.util.dao.orm.CustomSQLUtil;
064    
065    import java.io.Serializable;
066    
067    import java.util.ArrayList;
068    import java.util.Collections;
069    import java.util.Date;
070    import java.util.HashMap;
071    import java.util.HashSet;
072    import java.util.Iterator;
073    import java.util.LinkedHashMap;
074    import java.util.List;
075    import java.util.Map;
076    import java.util.Set;
077    
078    /**
079     * Provides the local service for accessing, adding, deleting, and updating
080     * organizations.
081     *
082     * @author Brian Wing Shun Chan
083     * @author Jorge Ferrer
084     * @author Julio Camarero
085     * @author Hugo Huijser
086     * @author Juan Fern??ndez
087     */
088    public class OrganizationLocalServiceImpl
089            extends OrganizationLocalServiceBaseImpl {
090    
091            /**
092             * Adds the organizations to the group.
093             *
094             * @param  groupId the primary key of the group
095             * @param  organizationIds the primary keys of the organizations
096             * @throws PortalException if a group or organization with the primary key
097             *         could not be found
098             * @throws SystemException if a system exception occurred
099             */
100            @Override
101            public void addGroupOrganizations(long groupId, long[] organizationIds)
102                    throws PortalException, SystemException {
103    
104                    groupPersistence.addOrganizations(groupId, organizationIds);
105    
106                    PermissionCacheUtil.clearCache();
107            }
108    
109            /**
110             * Adds an organization.
111             *
112             * <p>
113             * This method handles the creation and bookkeeping of the organization
114             * including its resources, metadata, and internal data structures. It is
115             * not necessary to make a subsequent call to {@link
116             * #addOrganizationResources(long, Organization)}.
117             * </p>
118             *
119             * @param  userId the primary key of the creator/owner of the organization
120             * @param  parentOrganizationId the primary key of the organization's parent
121             *         organization
122             * @param  name the organization's name
123             * @param  site whether the organization is to be associated with a main
124             *         site
125             * @return the organization
126             * @throws PortalException if a creator or parent organization with the
127             *         primary key could not be found or if the organization's
128             *         information was invalid
129             * @throws SystemException if a system exception occurred
130             */
131            @Override
132            public Organization addOrganization(
133                            long userId, long parentOrganizationId, String name, boolean site)
134                    throws PortalException, SystemException {
135    
136                    return addOrganization(
137                            userId, parentOrganizationId, name,
138                            OrganizationConstants.TYPE_REGULAR_ORGANIZATION, 0, 0,
139                            ListTypeConstants.ORGANIZATION_STATUS_DEFAULT, StringPool.BLANK,
140                            site, null);
141            }
142    
143            /**
144             * Adds an organization.
145             *
146             * <p>
147             * This method handles the creation and bookkeeping of the organization
148             * including its resources, metadata, and internal data structures. It is
149             * not necessary to make a subsequent call to {@link
150             * #addOrganizationResources(long, Organization)}.
151             * </p>
152             *
153             * @param      userId the primary key of the creator/owner of the
154             *             organization
155             * @param      parentOrganizationId the primary key of the organization's
156             *             parent organization
157             * @param      name the organization's name
158             * @param      type the organization's type
159             * @param      recursable whether the permissions of the organization are to
160             *             be inherited by its suborganizations
161             * @param      regionId the primary key of the organization's region
162             * @param      countryId the primary key of the organization's country
163             * @param      statusId the organization's workflow status
164             * @param      comments the comments about the organization
165             * @param      site whether the organization is to be associated with a main
166             *             site
167             * @param      serviceContext the service context to be applied (optionally
168             *             <code>null</code>). Can set asset category IDs, asset tag
169             *             names, and expando bridge attributes for the organization.
170             * @return     the organization
171             * @throws     PortalException if a creator or parent organization with the
172             *             primary key could not be found or if the organization's
173             *             information was invalid
174             * @throws     SystemException if a system exception occurred
175             * @deprecated As of 6.2.0, replaced by {@link #addOrganization(long, long,
176             *             String, String, long, long, int, String, boolean,
177             *             ServiceContext)}
178             */
179            @Override
180            public Organization addOrganization(
181                            long userId, long parentOrganizationId, String name, String type,
182                            boolean recursable, long regionId, long countryId, int statusId,
183                            String comments, boolean site, ServiceContext serviceContext)
184                    throws PortalException, SystemException {
185    
186                    return addOrganization(
187                            userId, parentOrganizationId, name, type, regionId, countryId,
188                            statusId, comments, site, serviceContext);
189            }
190    
191            /**
192             * Adds an organization.
193             *
194             * <p>
195             * This method handles the creation and bookkeeping of the organization
196             * including its resources, metadata, and internal data structures. It is
197             * not necessary to make a subsequent call to {@link
198             * #addOrganizationResources(long, Organization)}.
199             * </p>
200             *
201             * @param  userId the primary key of the creator/owner of the organization
202             * @param  parentOrganizationId the primary key of the organization's parent
203             *         organization
204             * @param  name the organization's name
205             * @param  type the organization's type
206             * @param  regionId the primary key of the organization's region
207             * @param  countryId the primary key of the organization's country
208             * @param  statusId the organization's workflow status
209             * @param  comments the comments about the organization
210             * @param  site whether the organization is to be associated with a main
211             *         site
212             * @param  serviceContext the service context to be applied (optionally
213             *         <code>null</code>). Can set asset category IDs, asset tag names,
214             *         and expando bridge attributes for the organization.
215             * @return the organization
216             * @throws PortalException if a creator or parent organization with the
217             *         primary key could not be found or if the organization's
218             *         information was invalid
219             * @throws SystemException if a system exception occurred
220             */
221            @Override
222            public Organization addOrganization(
223                            long userId, long parentOrganizationId, String name, String type,
224                            long regionId, long countryId, int statusId, String comments,
225                            boolean site, ServiceContext serviceContext)
226                    throws PortalException, SystemException {
227    
228                    // Organization
229    
230                    User user = userPersistence.findByPrimaryKey(userId);
231                    parentOrganizationId = getParentOrganizationId(
232                            user.getCompanyId(), parentOrganizationId);
233                    Date now = new Date();
234    
235                    validate(
236                            user.getCompanyId(), parentOrganizationId, name, type, countryId,
237                            statusId);
238    
239                    long organizationId = counterLocalService.increment();
240    
241                    Organization organization = organizationPersistence.create(
242                            organizationId);
243    
244                    if (serviceContext != null) {
245                            organization.setUuid(serviceContext.getUuid());
246                    }
247    
248                    organization.setCompanyId(user.getCompanyId());
249                    organization.setUserId(user.getUserId());
250                    organization.setUserName(user.getFullName());
251    
252                    if (serviceContext != null) {
253                            organization.setCreateDate(serviceContext.getCreateDate(now));
254                            organization.setModifiedDate(serviceContext.getModifiedDate(now));
255                    }
256                    else {
257                            organization.setCreateDate(now);
258                            organization.setModifiedDate(now);
259                    }
260    
261                    organization.setParentOrganizationId(parentOrganizationId);
262                    organization.setTreePath(organization.buildTreePath());
263                    organization.setName(name);
264                    organization.setType(type);
265                    organization.setRecursable(true);
266                    organization.setRegionId(regionId);
267                    organization.setCountryId(countryId);
268                    organization.setStatusId(statusId);
269                    organization.setComments(comments);
270                    organization.setExpandoBridgeAttributes(serviceContext);
271    
272                    organizationPersistence.update(organization);
273    
274                    // Group
275    
276                    long parentGroupId = GroupConstants.DEFAULT_PARENT_GROUP_ID;
277    
278                    if (parentOrganizationId !=
279                                    OrganizationConstants.DEFAULT_PARENT_ORGANIZATION_ID) {
280    
281                            Organization parentOrganization =
282                                    organizationPersistence.fetchByPrimaryKey(parentOrganizationId);
283    
284                            if (parentOrganization != null) {
285                                    Group parentGroup = parentOrganization.getGroup();
286    
287                                    if (site && parentGroup.isSite()) {
288                                            parentGroupId = parentOrganization.getGroupId();
289                                    }
290                            }
291                    }
292    
293                    Group group = groupLocalService.addGroup(
294                            userId, parentGroupId, Organization.class.getName(), organizationId,
295                            GroupConstants.DEFAULT_LIVE_GROUP_ID, name, null,
296                            GroupConstants.TYPE_SITE_PRIVATE, false,
297                            GroupConstants.DEFAULT_MEMBERSHIP_RESTRICTION, null, site, true,
298                            null);
299    
300                    // Role
301    
302                    Role role = roleLocalService.getRole(
303                            organization.getCompanyId(), RoleConstants.ORGANIZATION_OWNER);
304    
305                    userGroupRoleLocalService.addUserGroupRoles(
306                            userId, group.getGroupId(), new long[] {role.getRoleId()});
307    
308                    // Resources
309    
310                    addOrganizationResources(userId, organization);
311    
312                    // Asset
313    
314                    if (serviceContext != null) {
315                            updateAsset(
316                                    userId, organization, serviceContext.getAssetCategoryIds(),
317                                    serviceContext.getAssetTagNames());
318                    }
319    
320                    // Indexer
321    
322                    if ((serviceContext == null) || serviceContext.isIndexingEnabled()) {
323                            Indexer indexer = IndexerRegistryUtil.nullSafeGetIndexer(
324                                    Organization.class);
325    
326                            indexer.reindex(organization);
327                    }
328    
329                    return organization;
330            }
331    
332            /**
333             * Adds a resource for each type of permission available on the
334             * organization.
335             *
336             * @param  userId the primary key of the creator/owner of the organization
337             * @param  organization the organization
338             * @throws PortalException if a portal exception occurred
339             * @throws SystemException if a system exception occurred
340             */
341            @Override
342            public void addOrganizationResources(long userId, Organization organization)
343                    throws PortalException, SystemException {
344    
345                    String name = Organization.class.getName();
346    
347                    resourceLocalService.addResources(
348                            organization.getCompanyId(), 0, userId, name,
349                            organization.getOrganizationId(), false, false, false);
350            }
351    
352            /**
353             * Assigns the password policy to the organizations, removing any other
354             * currently assigned password policies.
355             *
356             * @param  passwordPolicyId the primary key of the password policy
357             * @param  organizationIds the primary keys of the organizations
358             * @throws SystemException if a system exception occurred
359             */
360            @Override
361            public void addPasswordPolicyOrganizations(
362                            long passwordPolicyId, long[] organizationIds)
363                    throws SystemException {
364    
365                    passwordPolicyRelLocalService.addPasswordPolicyRels(
366                            passwordPolicyId, Organization.class.getName(), organizationIds);
367            }
368    
369            /**
370             * Deletes the logo of the organization.
371             *
372             * @param  organizationId the primary key of the organization
373             * @throws PortalException if an organization or parent organization with
374             *         the primary key could not be found or if the organization's logo
375             *         could not be found
376             * @throws SystemException if a system exception occurred
377             */
378            @Override
379            public void deleteLogo(long organizationId)
380                    throws PortalException, SystemException {
381    
382                    Organization organization = getOrganization(organizationId);
383    
384                    Group group = organization.getGroup();
385    
386                    LayoutSet publicLayoutSet = layoutSetLocalService.getLayoutSet(
387                            group.getGroupId(), false);
388    
389                    if (publicLayoutSet.isLogo()) {
390                            long logoId = publicLayoutSet.getLogoId();
391    
392                            publicLayoutSet.setLogo(false);
393                            publicLayoutSet.setLogoId(0);
394    
395                            layoutSetPersistence.update(publicLayoutSet);
396    
397                            imageLocalService.deleteImage(logoId);
398                    }
399    
400                    LayoutSet privateLayoutSet = layoutSetLocalService.getLayoutSet(
401                            group.getGroupId(), true);
402    
403                    if (privateLayoutSet.isLogo()) {
404                            long logoId = privateLayoutSet.getLogoId();
405    
406                            privateLayoutSet.setLogo(false);
407                            privateLayoutSet.setLogoId(0);
408    
409                            layoutSetPersistence.update(privateLayoutSet);
410    
411                            if (imageLocalService.getImage(logoId) != null) {
412                                    imageLocalService.deleteImage(logoId);
413                            }
414                    }
415            }
416    
417            /**
418             * Deletes the organization. The organization's associated resources and
419             * assets are also deleted.
420             *
421             * @param  organizationId the primary key of the organization
422             * @return the deleted organization
423             * @throws PortalException if an organization with the primary key could not
424             *         be found, if the organization had a workflow in approved status,
425             *         or if the organization was a parent organization
426             * @throws SystemException if a system exception occurred
427             */
428            @Override
429            public Organization deleteOrganization(long organizationId)
430                    throws PortalException, SystemException {
431    
432                    Organization organization = organizationPersistence.findByPrimaryKey(
433                            organizationId);
434    
435                    return deleteOrganization(organization);
436            }
437    
438            /**
439             * Deletes the organization. The organization's associated resources and
440             * assets are also deleted.
441             *
442             * @param  organization the organization
443             * @return the deleted organization
444             * @throws PortalException if the organization had a workflow in approved
445             *         status or if the organization was a parent organization
446             * @throws SystemException if a system exception occurred
447             */
448            @Override
449            public Organization deleteOrganization(Organization organization)
450                    throws PortalException, SystemException {
451    
452                    if ((userLocalService.getOrganizationUsersCount(
453                                    organization.getOrganizationId(),
454                                    WorkflowConstants.STATUS_APPROVED) > 0) ||
455                            (organizationPersistence.countByC_P(
456                                    organization.getCompanyId(),
457                                    organization.getOrganizationId()) > 0)) {
458    
459                            throw new RequiredOrganizationException();
460                    }
461    
462                    // Asset
463    
464                    assetEntryLocalService.deleteEntry(
465                            Organization.class.getName(), organization.getOrganizationId());
466    
467                    // Addresses
468    
469                    addressLocalService.deleteAddresses(
470                            organization.getCompanyId(), Organization.class.getName(),
471                            organization.getOrganizationId());
472    
473                    // Email addresses
474    
475                    emailAddressLocalService.deleteEmailAddresses(
476                            organization.getCompanyId(), Organization.class.getName(),
477                            organization.getOrganizationId());
478    
479                    // Expando
480    
481                    expandoRowLocalService.deleteRows(organization.getOrganizationId());
482    
483                    // Password policy relation
484    
485                    passwordPolicyRelLocalService.deletePasswordPolicyRel(
486                            Organization.class.getName(), organization.getOrganizationId());
487    
488                    // Phone
489    
490                    phoneLocalService.deletePhones(
491                            organization.getCompanyId(), Organization.class.getName(),
492                            organization.getOrganizationId());
493    
494                    // Website
495    
496                    websiteLocalService.deleteWebsites(
497                            organization.getCompanyId(), Organization.class.getName(),
498                            organization.getOrganizationId());
499    
500                    // Group
501    
502                    Group group = organization.getGroup();
503    
504                    if (group.isSite()) {
505                            group.setSite(false);
506    
507                            groupPersistence.update(group);
508                    }
509    
510                    groupLocalService.deleteGroup(group);
511    
512                    // Resources
513    
514                    String name = Organization.class.getName();
515    
516                    resourceLocalService.deleteResource(
517                            organization.getCompanyId(), name,
518                            ResourceConstants.SCOPE_INDIVIDUAL,
519                            organization.getOrganizationId());
520    
521                    // Organization
522    
523                    organizationPersistence.remove(organization);
524    
525                    // Permission cache
526    
527                    PermissionCacheUtil.clearCache();
528    
529                    return organization;
530            }
531    
532            @Override
533            public Organization fetchOrganization(long companyId, String name)
534                    throws SystemException {
535    
536                    return organizationPersistence.fetchByC_N(companyId, name);
537            }
538    
539            @Override
540            public List<Organization> getNoAssetOrganizations() throws SystemException {
541                    return organizationFinder.findByNoAssets();
542            }
543    
544            /**
545             * Returns the organization with the name.
546             *
547             * @param  companyId the primary key of the organization's company
548             * @param  name the organization's name
549             * @return the organization with the name
550             * @throws PortalException if the organization with the name could not be
551             *         found
552             * @throws SystemException if a system exception occurred
553             */
554            @Override
555            public Organization getOrganization(long companyId, String name)
556                    throws PortalException, SystemException {
557    
558                    return organizationPersistence.findByC_N(companyId, name);
559            }
560    
561            /**
562             * Returns the primary key of the organization with the name.
563             *
564             * @param  companyId the primary key of the organization's company
565             * @param  name the organization's name
566             * @return the primary key of the organization with the name, or
567             *         <code>0</code> if the organization could not be found
568             * @throws SystemException if a system exception occurred
569             */
570            @Override
571            public long getOrganizationId(long companyId, String name)
572                    throws SystemException {
573    
574                    Organization organization = organizationPersistence.fetchByC_N(
575                            companyId, name);
576    
577                    if (organization != null) {
578                            return organization.getOrganizationId();
579                    }
580                    else {
581                            return 0;
582                    }
583            }
584    
585            @Override
586            public List<Organization> getOrganizations(
587                            long userId, int start, int end, OrderByComparator obc)
588                    throws PortalException, SystemException {
589    
590                    User user = userPersistence.findByPrimaryKey(userId);
591    
592                    List<Organization> organizations = ListUtil.copy(
593                            userPersistence.getOrganizations(userId));
594    
595                    Iterator<Organization> iterator = organizations.iterator();
596    
597                    while (iterator.hasNext()) {
598                            Organization organization = iterator.next();
599    
600                            if (organization.getCompanyId() != user.getCompanyId()) {
601                                    iterator.remove();
602                            }
603                    }
604    
605                    if (organizations.isEmpty()) {
606                            return organizations;
607                    }
608    
609                    if (obc == null) {
610                            obc = new OrganizationNameComparator(true);
611                    }
612    
613                    Collections.sort(organizations, obc);
614    
615                    return ListUtil.subList(organizations, start, end);
616            }
617    
618            /**
619             * Returns all the organizations belonging to the parent organization.
620             *
621             * @param  companyId the primary key of the organization's company
622             * @param  parentOrganizationId the primary key of the organization's parent
623             *         organization
624             * @return the organizations belonging to the parent organization
625             * @throws SystemException if a system exception occurred
626             */
627            @Override
628            public List<Organization> getOrganizations(
629                            long companyId, long parentOrganizationId)
630                    throws SystemException {
631    
632                    return getOrganizations(
633                            companyId, parentOrganizationId, QueryUtil.ALL_POS,
634                            QueryUtil.ALL_POS);
635            }
636    
637            /**
638             * Returns a range of all the organizations belonging to the parent
639             * organization.
640             *
641             * <p>
642             * Useful when paginating results. Returns a maximum of <code>end -
643             * start</code> instances. <code>start</code> and <code>end</code> are not
644             * primary keys, they are indexes in the result set. Thus, <code>0</code>
645             * refers to the first result in the set. Setting both <code>start</code>
646             * and <code>end</code> to {@link
647             * com.liferay.portal.kernel.dao.orm.QueryUtil#ALL_POS} will return the full
648             * result set.
649             * </p>
650             *
651             * @param  companyId the primary key of the organization's company
652             * @param  parentOrganizationId the primary key of the organization's parent
653             *         organization
654             * @param  start the lower bound of the range of organizations to return
655             * @param  end the upper bound of the range of organizations to return (not
656             *         inclusive)
657             * @return the range of organizations belonging to the parent organization
658             * @throws SystemException if a system exception occurred
659             * @see    com.liferay.portal.service.persistence.OrganizationPersistence#findByC_P(
660             *         long, long, int, int)
661             */
662            @Override
663            public List<Organization> getOrganizations(
664                            long companyId, long parentOrganizationId, int start, int end)
665                    throws SystemException {
666    
667                    if (parentOrganizationId ==
668                                    OrganizationConstants.ANY_PARENT_ORGANIZATION_ID) {
669    
670                            return organizationPersistence.findByCompanyId(
671                                    companyId, start, end);
672                    }
673                    else {
674                            return organizationPersistence.findByC_P(
675                                    companyId, parentOrganizationId, start, end);
676                    }
677            }
678    
679            /**
680             * Returns the organizations with the primary keys.
681             *
682             * @param  organizationIds the primary keys of the organizations
683             * @return the organizations with the primary keys
684             * @throws PortalException if any one of the organizations could not be
685             *         found
686             * @throws SystemException if a system exception occurred
687             */
688            @Override
689            public List<Organization> getOrganizations(long[] organizationIds)
690                    throws PortalException, SystemException {
691    
692                    List<Organization> organizations = new ArrayList<Organization>(
693                            organizationIds.length);
694    
695                    for (long organizationId : organizationIds) {
696                            Organization organization = getOrganization(organizationId);
697    
698                            organizations.add(organization);
699                    }
700    
701                    return organizations;
702            }
703    
704            /**
705             * Returns the number of organizations belonging to the parent organization.
706             *
707             * @param  companyId the primary key of the organization's company
708             * @param  parentOrganizationId the primary key of the organization's parent
709             *         organization
710             * @return the number of organizations belonging to the parent organization
711             * @throws SystemException if a system exception occurred
712             */
713            @Override
714            public int getOrganizationsCount(long companyId, long parentOrganizationId)
715                    throws SystemException {
716    
717                    if (parentOrganizationId ==
718                                    OrganizationConstants.ANY_PARENT_ORGANIZATION_ID) {
719    
720                            return organizationPersistence.countByCompanyId(companyId);
721                    }
722                    else {
723                            return organizationPersistence.countByC_P(
724                                    companyId, parentOrganizationId);
725                    }
726            }
727    
728            /**
729             * Returns the parent organizations in order by closest ancestor. The list
730             * starts with the organization itself.
731             *
732             * @param  organizationId the primary key of the organization
733             * @return the parent organizations in order by closest ancestor
734             * @throws PortalException if an organization with the primary key could not
735             *         be found
736             * @throws SystemException if a system exception occurred
737             */
738            @Override
739            public List<Organization> getParentOrganizations(long organizationId)
740                    throws PortalException, SystemException {
741    
742                    if (organizationId ==
743                                    OrganizationConstants.DEFAULT_PARENT_ORGANIZATION_ID) {
744    
745                            return new ArrayList<Organization>();
746                    }
747    
748                    Organization organization = organizationPersistence.findByPrimaryKey(
749                            organizationId);
750    
751                    return organization.getAncestors();
752            }
753    
754            /**
755             * Returns the suborganizations of the organizations.
756             *
757             * @param  organizations the organizations from which to get
758             *         suborganizations
759             * @return the suborganizations of the organizations
760             * @throws SystemException if a system exception occurred
761             */
762            @Override
763            public List<Organization> getSuborganizations(
764                            List<Organization> organizations)
765                    throws SystemException {
766    
767                    List<Organization> allSuborganizations = new ArrayList<Organization>();
768    
769                    for (int i = 0; i < organizations.size(); i++) {
770                            Organization organization = organizations.get(i);
771    
772                            List<Organization> suborganizations =
773                                    organizationPersistence.findByC_P(
774                                            organization.getCompanyId(),
775                                            organization.getOrganizationId());
776    
777                            addSuborganizations(allSuborganizations, suborganizations);
778                    }
779    
780                    return allSuborganizations;
781            }
782    
783            /**
784             * Returns the suborganizations of the organization.
785             *
786             * @param  companyId the primary key of the organization's company
787             * @param  organizationId the primary key of the organization
788             * @return the suborganizations of the organization
789             * @throws SystemException if a system exception occurred
790             */
791            @Override
792            public List<Organization> getSuborganizations(
793                            long companyId, long organizationId)
794                    throws SystemException {
795    
796                    return organizationPersistence.findByC_P(companyId, organizationId);
797            }
798    
799            /**
800             * Returns the count of suborganizations of the organization.
801             *
802             * @param  companyId the primary key of the organization's company
803             * @param  organizationId the primary key of the organization
804             * @return the count of suborganizations of the organization
805             * @throws SystemException if a system exception occurred
806             */
807            @Override
808            public int getSuborganizationsCount(long companyId, long organizationId)
809                    throws SystemException {
810    
811                    return organizationPersistence.countByC_P(companyId, organizationId);
812            }
813    
814            /**
815             * Returns the intersection of <code>allOrganizations</code> and
816             * <code>availableOrganizations</code>.
817             *
818             * @param  allOrganizations the organizations to check for availability
819             * @param  availableOrganizations the available organizations
820             * @return the intersection of <code>allOrganizations</code> and
821             *         <code>availableOrganizations</code>
822             */
823            @Override
824            public List<Organization> getSubsetOrganizations(
825                    List<Organization> allOrganizations,
826                    List<Organization> availableOrganizations) {
827    
828                    List<Organization> subsetOrganizations = new ArrayList<Organization>();
829    
830                    for (Organization organization : allOrganizations) {
831                            if (availableOrganizations.contains(organization)) {
832                                    subsetOrganizations.add(organization);
833                            }
834                    }
835    
836                    return subsetOrganizations;
837            }
838    
839            /**
840             * Returns all the organizations associated with the user. If
841             * includeAdministrative is <code>true</code>, the result includes those
842             * organizations that are not directly associated to the user but he is an
843             * administrator or an owner of the organization.
844             *
845             * @param  userId the primary key of the user
846             * @param  includeAdministrative whether to includes organizations that are
847             *         indirectly associated to the user because he is an administrator
848             *         or an owner of the organization
849             * @return the organizations associated with the user
850             * @throws PortalException if a user with the primary key could not be found
851             * @throws SystemException if a system exception occurred
852             */
853            @Override
854            public List<Organization> getUserOrganizations(
855                            long userId, boolean includeAdministrative)
856                    throws PortalException, SystemException {
857    
858                    if (!includeAdministrative) {
859                            return getUserOrganizations(userId);
860                    }
861    
862                    Set<Organization> organizations = new HashSet<Organization>();
863    
864                    List<UserGroupRole> userGroupRoles =
865                            userGroupRoleLocalService.getUserGroupRoles(userId);
866    
867                    for (UserGroupRole userGroupRole : userGroupRoles) {
868                            Role role = userGroupRole.getRole();
869    
870                            String roleName = role.getName();
871    
872                            if (roleName.equals(RoleConstants.ORGANIZATION_ADMINISTRATOR) ||
873                                    roleName.equals(RoleConstants.ORGANIZATION_OWNER)) {
874    
875                                    Group group = userGroupRole.getGroup();
876    
877                                    Organization organization =
878                                            organizationPersistence.findByPrimaryKey(
879                                                    group.getOrganizationId());
880    
881                                    organizations.add(organization);
882                            }
883                    }
884    
885                    organizations.addAll(getUserOrganizations(userId));
886    
887                    return new ArrayList<Organization>(organizations);
888            }
889    
890            /**
891             * Returns <code>true</code> if the password policy has been assigned to the
892             * organization.
893             *
894             * @param  passwordPolicyId the primary key of the password policy
895             * @param  organizationId the primary key of the organization
896             * @return <code>true</code> if the password policy has been assigned to the
897             *         organization; <code>false</code> otherwise
898             * @throws SystemException if a system exception occurred
899             */
900            @Override
901            public boolean hasPasswordPolicyOrganization(
902                            long passwordPolicyId, long organizationId)
903                    throws SystemException {
904    
905                    return passwordPolicyRelLocalService.hasPasswordPolicyRel(
906                            passwordPolicyId, Organization.class.getName(), organizationId);
907            }
908    
909            /**
910             * Returns <code>true</code> if the user is a member of the organization,
911             * optionally focusing on suborganizations or the specified organization.
912             * This method is usually called to determine if the user has view access to
913             * a resource belonging to the organization.
914             *
915             * <ol>
916             * <li>
917             * If <code>inheritSuborganizations=<code>false</code></code>:
918             * the method checks whether the user belongs to the organization specified
919             * by <code>organizationId</code>. The parameter
920             * <code>includeSpecifiedOrganization</code> is ignored.
921             * </li>
922             * <li>
923             * The parameter <code>includeSpecifiedOrganization</code> is
924             * ignored unless <code>inheritSuborganizations</code> is also
925             * <code>true</code>.
926             * </li>
927             * <li>
928             * If <code>inheritSuborganizations=<code>true</code></code> and
929             * <code>includeSpecifiedOrganization=<code>false</code></code>: the method
930             * checks
931             * whether the user belongs to one of the child organizations of the one
932             * specified by <code>organizationId</code>.
933             * </li>
934             * <li>
935             * If <code>inheritSuborganizations=<code>true</code></code> and
936             * <code>includeSpecifiedOrganization=<code>true</code></code>: the method
937             * checks whether
938             * the user belongs to the organization specified by
939             * <code>organizationId</code> or any of
940             * its child organizations.
941             * </li>
942             * </ol>
943             *
944             * @param  userId the primary key of the organization's user
945             * @param  organizationId the primary key of the organization
946             * @param  inheritSuborganizations if <code>true</code> suborganizations are
947             *         considered in the determination
948             * @param  includeSpecifiedOrganization if <code>true</code> the
949             *         organization specified by <code>organizationId</code> is
950             *         considered in the determination
951             * @return <code>true</code> if the user has access to the organization;
952             *         <code>false</code> otherwise
953             * @throws PortalException if an organization with the primary key could not
954             *         be found
955             * @throws SystemException if a system exception occurred
956             * @see    com.liferay.portal.service.persistence.OrganizationFinder
957             */
958            @Override
959            public boolean hasUserOrganization(
960                            long userId, long organizationId, boolean inheritSuborganizations,
961                            boolean includeSpecifiedOrganization)
962                    throws PortalException, SystemException {
963    
964                    if (!inheritSuborganizations) {
965                            return userPersistence.containsOrganization(userId, organizationId);
966                    }
967    
968                    LinkedHashMap<String, Object> params =
969                            new LinkedHashMap<String, Object>();
970    
971                    List<Organization> organizationsTree = new ArrayList<Organization>();
972    
973                    Organization organization = organizationPersistence.findByPrimaryKey(
974                            organizationId);
975    
976                    if (!includeSpecifiedOrganization) {
977                            organizationsTree.add(organization);
978                    }
979                    else {
980                            organizationsTree.add(organization.getParentOrganization());
981                    }
982    
983                    params.put("usersOrgsTree", organizationsTree);
984    
985                    if (userFinder.countByUser(userId, params) > 0) {
986                            return true;
987                    }
988    
989                    return false;
990            }
991    
992            /**
993             * Rebuilds the organizations tree.
994             *
995             * <p>
996             * Only call this method if the tree has become stale through operations
997             * other than normal CRUD. Under normal circumstances the tree is
998             * automatically rebuilt whenever necessary.
999             * </p>
1000             *
1001             * @param  companyId the primary key of the organization's company
1002             * @throws PortalException if an organization with the primary key could not
1003             *         be found
1004             * @throws SystemException if a system exception occurred
1005             */
1006            @Override
1007            public void rebuildTree(long companyId)
1008                    throws PortalException, SystemException {
1009    
1010                    TreePathUtil.rebuildTree(
1011                            companyId, OrganizationConstants.DEFAULT_PARENT_ORGANIZATION_ID,
1012                            new TreeModelFinder<Organization>() {
1013    
1014                                    @Override
1015                                    public List<Organization> findTreeModels(
1016                                                    long previousId, long companyId, long parentPrimaryKey,
1017                                                    int size)
1018                                            throws SystemException {
1019    
1020                                            return organizationPersistence.findByO_C_P(
1021                                                    previousId, companyId, parentPrimaryKey,
1022                                                    QueryUtil.ALL_POS, size,
1023                                                    new OrganizationIdComparator());
1024                                    }
1025    
1026                            }
1027                    );
1028            }
1029    
1030            /**
1031             * Returns an ordered range of all the organizations that match the
1032             * keywords, using the indexer. It is preferable to use this method instead
1033             * of the non-indexed version whenever possible for performance reasons.
1034             *
1035             * <p>
1036             * Useful when paginating results. Returns a maximum of <code>end -
1037             * start</code> instances. <code>start</code> and <code>end</code> are not
1038             * primary keys, they are indexes in the result set. Thus, <code>0</code>
1039             * refers to the first result in the set. Setting both <code>start</code>
1040             * and <code>end</code> to {@link
1041             * com.liferay.portal.kernel.dao.orm.QueryUtil#ALL_POS} will return the full
1042             * result set.
1043             * </p>
1044             *
1045             * @param  companyId the primary key of the organization's company
1046             * @param  parentOrganizationId the primary key of the organization's parent
1047             *         organization
1048             * @param  keywords the keywords (space separated), which may occur in the
1049             *         organization's name, street, city, zipcode, type, region or
1050             *         country (optionally <code>null</code>)
1051             * @param  params the finder parameters (optionally <code>null</code>). For
1052             *         more information see {@link
1053             *         com.liferay.portlet.usersadmin.util.OrganizationIndexer}
1054             * @param  start the lower bound of the range of organizations to return
1055             * @param  end the upper bound of the range of organizations to return (not
1056             *         inclusive)
1057             * @param  sort the field and direction by which to sort (optionally
1058             *         <code>null</code>)
1059             * @return the matching organizations ordered by name
1060             * @throws SystemException if a system exception occurred
1061             * @see    com.liferay.portlet.usersadmin.util.OrganizationIndexer
1062             */
1063            @Override
1064            public Hits search(
1065                            long companyId, long parentOrganizationId, String keywords,
1066                            LinkedHashMap<String, Object> params, int start, int end, Sort sort)
1067                    throws SystemException {
1068    
1069                    String name = null;
1070                    String type = null;
1071                    String street = null;
1072                    String city = null;
1073                    String zip = null;
1074                    String region = null;
1075                    String country = null;
1076                    boolean andOperator = false;
1077    
1078                    if (Validator.isNotNull(keywords)) {
1079                            name = keywords;
1080                            type = keywords;
1081                            street = keywords;
1082                            city = keywords;
1083                            zip = keywords;
1084                            region = keywords;
1085                            country = keywords;
1086                    }
1087                    else {
1088                            andOperator = true;
1089                    }
1090    
1091                    if (params != null) {
1092                            params.put("keywords", keywords);
1093                    }
1094    
1095                    return search(
1096                            companyId, parentOrganizationId, name, type, street, city, zip,
1097                            region, country, params, andOperator, start, end, sort);
1098            }
1099    
1100            /**
1101             * Returns a name ordered range of all the organizations that match the
1102             * keywords, type, region, and country, without using the indexer. It is
1103             * preferable to use the indexed version {@link #search(long, long, String,
1104             * LinkedHashMap, int, int, Sort)} instead of this method wherever possible
1105             * for performance reasons.
1106             *
1107             * <p>
1108             * Useful when paginating results. Returns a maximum of <code>end -
1109             * start</code> instances. <code>start</code> and <code>end</code> are not
1110             * primary keys, they are indexes in the result set. Thus, <code>0</code>
1111             * refers to the first result in the set. Setting both <code>start</code>
1112             * and <code>end</code> to {@link
1113             * com.liferay.portal.kernel.dao.orm.QueryUtil#ALL_POS} will return the full
1114             * result set.
1115             * </p>
1116             *
1117             * @param  companyId the primary key of the organization's company
1118             * @param  parentOrganizationId the primary key of the organization's parent
1119             *         organization
1120             * @param  keywords the keywords (space separated), which may occur in the
1121             *         organization's name, street, city, or zipcode (optionally
1122             *         <code>null</code>)
1123             * @param  type the organization's type (optionally <code>null</code>)
1124             * @param  regionId the primary key of the organization's region (optionally
1125             *         <code>null</code>)
1126             * @param  countryId the primary key of the organization's country
1127             *         (optionally <code>null</code>)
1128             * @param  params the finder params. For more information see {@link
1129             *         com.liferay.portal.service.persistence.OrganizationFinder}
1130             * @param  start the lower bound of the range of organizations to return
1131             * @param  end the upper bound of the range of organizations to return (not
1132             *         inclusive)
1133             * @return the matching organizations ordered by name
1134             * @throws SystemException if a system exception occurred
1135             * @see    com.liferay.portal.service.persistence.OrganizationFinder
1136             */
1137            @Override
1138            public List<Organization> search(
1139                            long companyId, long parentOrganizationId, String keywords,
1140                            String type, Long regionId, Long countryId,
1141                            LinkedHashMap<String, Object> params, int start, int end)
1142                    throws SystemException {
1143    
1144                    return search(
1145                            companyId, parentOrganizationId, keywords, type, regionId,
1146                            countryId, params, start, end,
1147                            new OrganizationNameComparator(true));
1148            }
1149    
1150            /**
1151             * Returns an ordered range of all the organizations that match the
1152             * keywords, type, region, and country, without using the indexer. It is
1153             * preferable to use the indexed version {@link #search(long, long, String,
1154             * String, String, String, String, String, String, LinkedHashMap, boolean,
1155             * int, int, Sort)} instead of this method wherever possible for performance
1156             * reasons.
1157             *
1158             * <p>
1159             * Useful when paginating results. Returns a maximum of <code>end -
1160             * start</code> instances. <code>start</code> and <code>end</code> are not
1161             * primary keys, they are indexes in the result set. Thus, <code>0</code>
1162             * refers to the first result in the set. Setting both <code>start</code>
1163             * and <code>end</code> to {@link
1164             * com.liferay.portal.kernel.dao.orm.QueryUtil#ALL_POS} will return the full
1165             * result set.
1166             * </p>
1167             *
1168             * @param  companyId the primary key of the organization's company
1169             * @param  parentOrganizationId the primary key of the organization's parent
1170             *         organization
1171             * @param  keywords the keywords (space separated), which may occur in the
1172             *         organization's name, street, city, or zipcode (optionally
1173             *         <code>null</code>)
1174             * @param  type the organization's type (optionally <code>null</code>)
1175             * @param  regionId the primary key of the organization's region (optionally
1176             *         <code>null</code>)
1177             * @param  countryId the primary key of the organization's country
1178             *         (optionally <code>null</code>)
1179             * @param  params the finder params. For more information see {@link
1180             *         com.liferay.portal.service.persistence.OrganizationFinder}
1181             * @param  start the lower bound of the range of organizations to return
1182             * @param  end the upper bound of the range of organizations to return (not
1183             *         inclusive)
1184             * @param  obc the comparator to order the organizations (optionally
1185             *         <code>null</code>)
1186             * @return the matching organizations ordered by comparator <code>obc</code>
1187             * @throws SystemException if a system exception occurred
1188             * @see    com.liferay.portal.service.persistence.OrganizationFinder
1189             */
1190            @Override
1191            public List<Organization> search(
1192                            long companyId, long parentOrganizationId, String keywords,
1193                            String type, Long regionId, Long countryId,
1194                            LinkedHashMap<String, Object> params, int start, int end,
1195                            OrderByComparator obc)
1196                    throws SystemException {
1197    
1198                    String parentOrganizationIdComparator = StringPool.EQUAL;
1199    
1200                    if (parentOrganizationId ==
1201                                    OrganizationConstants.ANY_PARENT_ORGANIZATION_ID) {
1202    
1203                            parentOrganizationIdComparator = StringPool.NOT_EQUAL;
1204                    }
1205    
1206                    return organizationFinder.findByKeywords(
1207                            companyId, parentOrganizationId, parentOrganizationIdComparator,
1208                            keywords, type, regionId, countryId, params, start, end, obc);
1209            }
1210    
1211            /**
1212             * Returns a name ordered range of all the organizations with the type,
1213             * region, and country, and whose name, street, city, and zipcode match the
1214             * keywords specified for them, without using the indexer. It is preferable
1215             * to use the indexed version {@link #search(long, long, String, String,
1216             * String, String, String, String, String, LinkedHashMap, boolean, int, int,
1217             * Sort)} instead of this method wherever possible for performance reasons.
1218             *
1219             * <p>
1220             * Useful when paginating results. Returns a maximum of <code>end -
1221             * start</code> instances. <code>start</code> and <code>end</code> are not
1222             * primary keys, they are indexes in the result set. Thus, <code>0</code>
1223             * refers to the first result in the set. Setting both <code>start</code>
1224             * and <code>end</code> to {@link
1225             * com.liferay.portal.kernel.dao.orm.QueryUtil#ALL_POS} will return the full
1226             * result set.
1227             * </p>
1228             *
1229             * @param  companyId the primary key of the organization's company
1230             * @param  parentOrganizationId the primary key of the organization's parent
1231             * @param  name the name keywords (space separated, optionally
1232             *         <code>null</code>)
1233             * @param  type the organization's type (optionally <code>null</code>)
1234             * @param  street the street keywords (optionally <code>null</code>)
1235             * @param  city the city keywords (optionally <code>null</code>)
1236             * @param  zip the zipcode keywords (optionally <code>null</code>)
1237             * @param  regionId the primary key of the organization's region (optionally
1238             *         <code>null</code>)
1239             * @param  countryId the primary key of the organization's country
1240             *         (optionally <code>null</code>)
1241             * @param  params the finder parameters (optionally <code>null</code>). For
1242             *         more information see {@link
1243             *         com.liferay.portal.service.persistence.OrganizationFinder}
1244             * @param  andOperator whether every field must match its keywords, or just
1245             *         one field. For example, &quot;organizations with the name
1246             *         'Employees' and city 'Chicago'&quot; vs &quot;organizations with
1247             *         the name 'Employees' or the city 'Chicago'&quot;.
1248             * @param  start the lower bound of the range of organizations to return
1249             * @param  end the upper bound of the range of organizations to return (not
1250             *         inclusive)
1251             * @return the matching organizations ordered by name
1252             * @throws SystemException if a system exception occurred
1253             * @see    com.liferay.portal.service.persistence.OrganizationFinder
1254             */
1255            @Override
1256            public List<Organization> search(
1257                            long companyId, long parentOrganizationId, String name, String type,
1258                            String street, String city, String zip, Long regionId,
1259                            Long countryId, LinkedHashMap<String, Object> params,
1260                            boolean andOperator, int start, int end)
1261                    throws SystemException {
1262    
1263                    return search(
1264                            companyId, parentOrganizationId, name, type, street, city, zip,
1265                            regionId, countryId, params, andOperator, start, end,
1266                            new OrganizationNameComparator(true));
1267            }
1268    
1269            /**
1270             * Returns an ordered range of all the organizations with the type, region,
1271             * and country, and whose name, street, city, and zipcode match the keywords
1272             * specified for them, without using the indexer. It is preferable to use
1273             * the indexed version {@link #search(long, long, String, String, String,
1274             * String, String, String, String, LinkedHashMap, boolean, int, int, Sort)}
1275             * instead of this method wherever possible for performance reasons.
1276             *
1277             * <p>
1278             * Useful when paginating results. Returns a maximum of <code>end -
1279             * start</code> instances. <code>start</code> and <code>end</code> are not
1280             * primary keys, they are indexes in the result set. Thus, <code>0</code>
1281             * refers to the first result in the set. Setting both <code>start</code>
1282             * and <code>end</code> to {@link
1283             * com.liferay.portal.kernel.dao.orm.QueryUtil#ALL_POS} will return the full
1284             * result set.
1285             * </p>
1286             *
1287             * @param  companyId the primary key of the organization's company
1288             * @param  parentOrganizationId the primary key of the organization's parent
1289             *         organization
1290             * @param  name the name keywords (space separated, optionally
1291             *         <code>null</code>)
1292             * @param  type the organization's type (optionally <code>null</code>)
1293             * @param  street the street keywords (optionally <code>null</code>)
1294             * @param  city the city keywords (optionally <code>null</code>)
1295             * @param  zip the zipcode keywords (optionally <code>null</code>)
1296             * @param  regionId the primary key of the organization's region (optionally
1297             *         <code>null</code>)
1298             * @param  countryId the primary key of the organization's country
1299             *         (optionally <code>null</code>)
1300             * @param  params the finder parameters (optionally <code>null</code>). For
1301             *         more information see {@link
1302             *         com.liferay.portal.service.persistence.OrganizationFinder}
1303             * @param  andOperator whether every field must match its keywords, or just
1304             *         one field. For example, &quot;organizations with the name
1305             *         'Employees' and city 'Chicago'&quot; vs &quot;organizations with
1306             *         the name 'Employees' or the city 'Chicago'&quot;.
1307             * @param  start the lower bound of the range of organizations to return
1308             * @param  end the upper bound of the range of organizations to return (not
1309             *         inclusive)
1310             * @param  obc the comparator to order the organizations (optionally
1311             *         <code>null</code>)
1312             * @return the matching organizations ordered by comparator <code>obc</code>
1313             * @throws SystemException if a system exception occurred
1314             * @see    com.liferay.portal.service.persistence.OrganizationFinder
1315             */
1316            @Override
1317            public List<Organization> search(
1318                            long companyId, long parentOrganizationId, String name, String type,
1319                            String street, String city, String zip, Long regionId,
1320                            Long countryId, LinkedHashMap<String, Object> params,
1321                            boolean andOperator, int start, int end, OrderByComparator obc)
1322                    throws SystemException {
1323    
1324                    String parentOrganizationIdComparator = StringPool.EQUAL;
1325    
1326                    if (parentOrganizationId ==
1327                                    OrganizationConstants.ANY_PARENT_ORGANIZATION_ID) {
1328    
1329                            parentOrganizationIdComparator = StringPool.NOT_EQUAL;
1330                    }
1331    
1332                    return organizationFinder.findByC_PO_N_T_S_C_Z_R_C(
1333                            companyId, parentOrganizationId, parentOrganizationIdComparator,
1334                            name, type, street, city, zip, regionId, countryId, params,
1335                            andOperator, start, end, obc);
1336            }
1337    
1338            /**
1339             * Returns an ordered range of all the organizations whose name, type, or
1340             * location fields match the keywords specified for them, using the indexer.
1341             * It is preferable to use this method instead of the non-indexed version
1342             * whenever possible for performance reasons.
1343             *
1344             * <p>
1345             * Useful when paginating results. Returns a maximum of <code>end -
1346             * start</code> instances. <code>start</code> and <code>end</code> are not
1347             * primary keys, they are indexes in the result set. Thus, <code>0</code>
1348             * refers to the first result in the set. Setting both <code>start</code>
1349             * and <code>end</code> to {@link
1350             * com.liferay.portal.kernel.dao.orm.QueryUtil#ALL_POS} will return the full
1351             * result set.
1352             * </p>
1353             *
1354             * @param  companyId the primary key of the organization's company
1355             * @param  parentOrganizationId the primary key of the organization's parent
1356             *         organization
1357             * @param  name the name keywords (space separated, optionally
1358             *         <code>null</code>)
1359             * @param  type the type keywords (optionally <code>null</code>)
1360             * @param  street the street keywords (optionally <code>null</code>)
1361             * @param  city the city keywords (optionally <code>null</code>)
1362             * @param  zip the zipcode keywords (optionally <code>null</code>)
1363             * @param  region the region keywords (optionally <code>null</code>)
1364             * @param  country the country keywords (optionally <code>null</code>)
1365             * @param  params the finder parameters (optionally <code>null</code>). For
1366             *         more information see {@link
1367             *         com.liferay.portlet.usersadmin.util.OrganizationIndexer}.
1368             * @param  andSearch whether every field must match its keywords or just one
1369             *         field
1370             * @param  start the lower bound of the range of organizations to return
1371             * @param  end the upper bound of the range of organizations to return (not
1372             *         inclusive)
1373             * @param  sort the field and direction by which to sort (optionally
1374             *         <code>null</code>)
1375             * @return the matching organizations ordered by <code>sort</code>
1376             * @throws SystemException if a system exception occurred
1377             * @see    com.liferay.portlet.usersadmin.util.OrganizationIndexer
1378             */
1379            @Override
1380            public Hits search(
1381                            long companyId, long parentOrganizationId, String name, String type,
1382                            String street, String city, String zip, String region,
1383                            String country, LinkedHashMap<String, Object> params,
1384                            boolean andSearch, int start, int end, Sort sort)
1385                    throws SystemException {
1386    
1387                    try {
1388                            SearchContext searchContext = new SearchContext();
1389    
1390                            searchContext.setAndSearch(andSearch);
1391    
1392                            Map<String, Serializable> attributes =
1393                                    new HashMap<String, Serializable>();
1394    
1395                            attributes.put("city", city);
1396                            attributes.put("country", country);
1397                            attributes.put("name", name);
1398                            attributes.put("params", params);
1399                            attributes.put(
1400                                    "parentOrganizationId", String.valueOf(parentOrganizationId));
1401                            attributes.put("region", region);
1402                            attributes.put("street", street);
1403                            attributes.put("type", type);
1404                            attributes.put("zip", zip);
1405    
1406                            searchContext.setAttributes(attributes);
1407    
1408                            searchContext.setCompanyId(companyId);
1409                            searchContext.setEnd(end);
1410    
1411                            if (params != null) {
1412                                    String keywords = (String)params.remove("keywords");
1413    
1414                                    if (Validator.isNotNull(keywords)) {
1415                                            searchContext.setKeywords(keywords);
1416                                    }
1417                            }
1418    
1419                            QueryConfig queryConfig = new QueryConfig();
1420    
1421                            queryConfig.setHighlightEnabled(false);
1422                            queryConfig.setScoreEnabled(false);
1423    
1424                            searchContext.setQueryConfig(queryConfig);
1425    
1426                            if (sort != null) {
1427                                    searchContext.setSorts(sort);
1428                            }
1429    
1430                            searchContext.setStart(start);
1431    
1432                            Indexer indexer = IndexerRegistryUtil.nullSafeGetIndexer(
1433                                    Organization.class);
1434    
1435                            return indexer.search(searchContext);
1436                    }
1437                    catch (Exception e) {
1438                            throw new SystemException(e);
1439                    }
1440            }
1441    
1442            /**
1443             * Returns the number of organizations that match the keywords, type,
1444             * region, and country.
1445             *
1446             * @param  companyId the primary key of the organization's company
1447             * @param  parentOrganizationId the primary key of the organization's parent
1448             *         organization
1449             * @param  keywords the keywords (space separated), which may occur in the
1450             *         organization's name, street, city, or zipcode (optionally
1451             *         <code>null</code>)
1452             * @param  type the organization's type (optionally <code>null</code>)
1453             * @param  regionId the primary key of the organization's region (optionally
1454             *         <code>null</code>)
1455             * @param  countryId the primary key of the organization's country
1456             *         (optionally <code>null</code>)
1457             * @param  params the finder parameters (optionally <code>null</code>). For
1458             *         more information see {@link
1459             *         com.liferay.portal.service.persistence.OrganizationFinder}
1460             * @return the number of matching organizations
1461             * @throws SystemException if a system exception occurred
1462             * @see    com.liferay.portal.service.persistence.OrganizationFinder
1463             */
1464            @Override
1465            public int searchCount(
1466                            long companyId, long parentOrganizationId, String keywords,
1467                            String type, Long regionId, Long countryId,
1468                            LinkedHashMap<String, Object> params)
1469                    throws SystemException {
1470    
1471                    String parentOrganizationIdComparator = StringPool.EQUAL;
1472    
1473                    if (parentOrganizationId ==
1474                                    OrganizationConstants.ANY_PARENT_ORGANIZATION_ID) {
1475    
1476                            parentOrganizationIdComparator = StringPool.NOT_EQUAL;
1477                    }
1478    
1479                    return organizationFinder.countByKeywords(
1480                            companyId, parentOrganizationId, parentOrganizationIdComparator,
1481                            keywords, type, regionId, countryId, params);
1482            }
1483    
1484            /**
1485             * Returns the number of organizations with the type, region, and country,
1486             * and whose name, street, city, and zipcode match the keywords specified
1487             * for them.
1488             *
1489             * @param  companyId the primary key of the organization's company
1490             * @param  parentOrganizationId the primary key of the organization's parent
1491             *         organization
1492             * @param  name the name keywords (space separated, optionally
1493             *         <code>null</code>)
1494             * @param  type the organization's type (optionally <code>null</code>)
1495             * @param  street the street keywords (optionally <code>null</code>)
1496             * @param  city the city keywords (optionally <code>null</code>)
1497             * @param  zip the zipcode keywords (optionally <code>null</code>)
1498             * @param  regionId the primary key of the organization's region (optionally
1499             *         <code>null</code>)
1500             * @param  countryId the primary key of the organization's country
1501             *         (optionally <code>null</code>)
1502             * @param  params the finder parameters (optionally <code>null</code>). For
1503             *         more information see {@link
1504             *         com.liferay.portal.service.persistence.OrganizationFinder}
1505             * @param  andOperator whether every field must match its keywords, or just
1506             *         one field. For example, &quot;organizations with the name
1507             *         'Employees' and city 'Chicago'&quot; vs &quot;organizations with
1508             *         the name 'Employees' or the city 'Chicago'&quot;.
1509             * @return the number of matching organizations
1510             * @throws SystemException if a system exception occurred
1511             * @see    com.liferay.portal.service.persistence.OrganizationFinder
1512             */
1513            @Override
1514            public int searchCount(
1515                            long companyId, long parentOrganizationId, String name, String type,
1516                            String street, String city, String zip, Long regionId,
1517                            Long countryId, LinkedHashMap<String, Object> params,
1518                            boolean andOperator)
1519                    throws SystemException {
1520    
1521                    String parentOrganizationIdComparator = StringPool.EQUAL;
1522    
1523                    if (parentOrganizationId ==
1524                                    OrganizationConstants.ANY_PARENT_ORGANIZATION_ID) {
1525    
1526                            parentOrganizationIdComparator = StringPool.NOT_EQUAL;
1527                    }
1528    
1529                    return organizationFinder.countByC_PO_N_T_S_C_Z_R_C(
1530                            companyId, parentOrganizationId, parentOrganizationIdComparator,
1531                            name, type, street, city, zip, regionId, countryId, params,
1532                            andOperator);
1533            }
1534    
1535            /**
1536             * Sets the organizations in the group, removing and adding organizations to
1537             * the group as necessary.
1538             *
1539             * @param  groupId the primary key of the group
1540             * @param  organizationIds the primary keys of the organizations
1541             * @throws PortalException if a portal exception occurred
1542             * @throws SystemException if a system exception occurred
1543             */
1544            @Override
1545            public void setGroupOrganizations(long groupId, long[] organizationIds)
1546                    throws PortalException, SystemException {
1547    
1548                    groupPersistence.setOrganizations(groupId, organizationIds);
1549    
1550                    PermissionCacheUtil.clearCache();
1551            }
1552    
1553            /**
1554             * Removes the organizations from the group.
1555             *
1556             * @param  groupId the primary key of the group
1557             * @param  organizationIds the primary keys of the organizations
1558             * @throws PortalException if a portal exception occurred
1559             * @throws SystemException if a system exception occurred
1560             */
1561            @Override
1562            public void unsetGroupOrganizations(long groupId, long[] organizationIds)
1563                    throws PortalException, SystemException {
1564    
1565                    groupPersistence.removeOrganizations(groupId, organizationIds);
1566    
1567                    PermissionCacheUtil.clearCache();
1568            }
1569    
1570            /**
1571             * Removes the organizations from the password policy.
1572             *
1573             * @param  passwordPolicyId the primary key of the password policy
1574             * @param  organizationIds the primary keys of the organizations
1575             * @throws SystemException if a system exception occurred
1576             */
1577            @Override
1578            public void unsetPasswordPolicyOrganizations(
1579                            long passwordPolicyId, long[] organizationIds)
1580                    throws SystemException {
1581    
1582                    passwordPolicyRelLocalService.deletePasswordPolicyRels(
1583                            passwordPolicyId, Organization.class.getName(), organizationIds);
1584            }
1585    
1586            /**
1587             * Updates the organization's asset with the new asset categories and tag
1588             * names, removing and adding asset categories and tag names as necessary.
1589             *
1590             * @param  userId the primary key of the user
1591             * @param  organization the organization
1592             * @param  assetCategoryIds the primary keys of the asset categories
1593             * @param  assetTagNames the asset tag names
1594             * @throws PortalException if a user with the primary key could not be found
1595             * @throws SystemException if a system exception occurred
1596             */
1597            @Override
1598            public void updateAsset(
1599                            long userId, Organization organization, long[] assetCategoryIds,
1600                            String[] assetTagNames)
1601                    throws PortalException, SystemException {
1602    
1603                    User user = userPersistence.findByPrimaryKey(userId);
1604    
1605                    Company company = companyPersistence.findByPrimaryKey(
1606                            user.getCompanyId());
1607    
1608                    Group companyGroup = company.getGroup();
1609    
1610                    assetEntryLocalService.updateEntry(
1611                            userId, companyGroup.getGroupId(), null, null,
1612                            Organization.class.getName(), organization.getOrganizationId(),
1613                            organization.getUuid(), 0, assetCategoryIds, assetTagNames, false,
1614                            null, null, null, null, organization.getName(), StringPool.BLANK,
1615                            null, null, null, 0, 0, null, false);
1616            }
1617    
1618            /**
1619             * Updates the organization.
1620             *
1621             * @param      companyId the primary key of the organization's company
1622             * @param      organizationId the primary key of the organization
1623             * @param      parentOrganizationId the primary key of organization's parent
1624             *             organization
1625             * @param      name the organization's name
1626             * @param      type the organization's type
1627             * @param      recursable whether permissions of the organization are to be
1628             *             inherited by its suborganizations
1629             * @param      regionId the primary key of the organization's region
1630             * @param      countryId the primary key of the organization's country
1631             * @param      statusId the organization's workflow status
1632             * @param      comments the comments about the organization
1633             * @param      site whether the organization is to be associated with a main
1634             *             site
1635             * @param      serviceContext the service context to be applied (optionally
1636             *             <code>null</code>). Can set asset category IDs and asset tag
1637             *             names for the organization, and merge expando bridge
1638             *             attributes for the organization.
1639             * @return     the organization
1640             * @throws     PortalException if an organization or parent organization
1641             *             with the primary key could not be found or if the new
1642             *             information was invalid
1643             * @throws     SystemException if a system exception occurred
1644             * @deprecated As of 6.2.0, replaced by {@link #updateOrganization(long,
1645             *             long, long, String, String, long, long, int, String, boolean,
1646             *             ServiceContext)}
1647             */
1648            @Override
1649            public Organization updateOrganization(
1650                            long companyId, long organizationId, long parentOrganizationId,
1651                            String name, String type, boolean recursable, long regionId,
1652                            long countryId, int statusId, String comments, boolean site,
1653                            ServiceContext serviceContext)
1654                    throws PortalException, SystemException {
1655    
1656                    return updateOrganization(
1657                            companyId, organizationId, parentOrganizationId, name, type,
1658                            regionId, countryId, statusId, comments, site, serviceContext);
1659            }
1660    
1661            /**
1662             * Updates the organization.
1663             *
1664             * @param  companyId the primary key of the organization's company
1665             * @param  organizationId the primary key of the organization
1666             * @param  parentOrganizationId the primary key of organization's parent
1667             *         organization
1668             * @param  name the organization's name
1669             * @param  type the organization's type
1670             * @param  regionId the primary key of the organization's region
1671             * @param  countryId the primary key of the organization's country
1672             * @param  statusId the organization's workflow status
1673             * @param  comments the comments about the organization
1674             * @param  site whether the organization is to be associated with a main
1675             *         site
1676             * @param  serviceContext the service context to be applied (optionally
1677             *         <code>null</code>). Can set asset category IDs and asset tag
1678             *         names for the organization, and merge expando bridge attributes
1679             *         for the organization.
1680             * @return the organization
1681             * @throws PortalException if an organization or parent organization with
1682             *         the primary key could not be found or if the new information was
1683             *         invalid
1684             * @throws SystemException if a system exception occurred
1685             */
1686            @Override
1687            public Organization updateOrganization(
1688                            long companyId, long organizationId, long parentOrganizationId,
1689                            String name, String type, long regionId, long countryId,
1690                            int statusId, String comments, boolean site,
1691                            ServiceContext serviceContext)
1692                    throws PortalException, SystemException {
1693    
1694                    // Organization
1695    
1696                    parentOrganizationId = getParentOrganizationId(
1697                            companyId, parentOrganizationId);
1698    
1699                    validate(
1700                            companyId, organizationId, parentOrganizationId, name, type,
1701                            countryId, statusId);
1702    
1703                    Organization organization = organizationPersistence.findByPrimaryKey(
1704                            organizationId);
1705    
1706                    long oldParentOrganizationId = organization.getParentOrganizationId();
1707                    String oldName = organization.getName();
1708    
1709                    organization.setModifiedDate(new Date());
1710                    organization.setParentOrganizationId(parentOrganizationId);
1711                    organization.setTreePath(organization.buildTreePath());
1712                    organization.setName(name);
1713                    organization.setType(type);
1714                    organization.setRecursable(true);
1715                    organization.setRegionId(regionId);
1716                    organization.setCountryId(countryId);
1717                    organization.setStatusId(statusId);
1718                    organization.setComments(comments);
1719                    organization.setExpandoBridgeAttributes(serviceContext);
1720    
1721                    organizationPersistence.update(organization);
1722    
1723                    // Group
1724    
1725                    Group group = organization.getGroup();
1726    
1727                    long parentGroupId = group.getParentGroupId();
1728    
1729                    boolean organizationGroup = isOrganizationGroup(
1730                            oldParentOrganizationId, group.getParentGroupId());
1731    
1732                    if (organizationGroup) {
1733                            if (parentOrganizationId !=
1734                                            OrganizationConstants.DEFAULT_PARENT_ORGANIZATION_ID) {
1735    
1736                                    Organization parentOrganization =
1737                                            organizationPersistence.fetchByPrimaryKey(
1738                                                    parentOrganizationId);
1739    
1740                                    Group parentGroup = parentOrganization.getGroup();
1741    
1742                                    if (site && parentGroup.isSite()) {
1743                                            parentGroupId = parentOrganization.getGroupId();
1744                                    }
1745                                    else {
1746                                            parentGroupId = GroupConstants.DEFAULT_PARENT_GROUP_ID;
1747                                    }
1748                            }
1749                            else {
1750                                    parentGroupId = GroupConstants.DEFAULT_PARENT_GROUP_ID;
1751                            }
1752                    }
1753    
1754                    if (!oldName.equals(name) || organizationGroup) {
1755                            groupLocalService.updateGroup(
1756                                    group.getGroupId(), parentGroupId, name, group.getDescription(),
1757                                    group.getType(), group.isManualMembership(),
1758                                    group.getMembershipRestriction(), group.getFriendlyURL(),
1759                                    group.isActive(), null);
1760                    }
1761    
1762                    if (group.isSite() != site) {
1763                            groupLocalService.updateSite(group.getGroupId(), site);
1764                    }
1765    
1766                    // Asset
1767    
1768                    if (serviceContext != null) {
1769                            updateAsset(
1770                                    serviceContext.getUserId(), organization,
1771                                    serviceContext.getAssetCategoryIds(),
1772                                    serviceContext.getAssetTagNames());
1773                    }
1774    
1775                    // Indexer
1776    
1777                    Indexer indexer = IndexerRegistryUtil.nullSafeGetIndexer(
1778                            Organization.class);
1779    
1780                    if (oldParentOrganizationId != parentOrganizationId) {
1781                            long[] organizationIds = getReindexOrganizationIds(organization);
1782    
1783                            indexer.reindex(organizationIds);
1784                    }
1785                    else {
1786                            indexer.reindex(organization);
1787                    }
1788    
1789                    return organization;
1790            }
1791    
1792            protected void addSuborganizations(
1793                            List<Organization> allSuborganizations,
1794                            List<Organization> organizations)
1795                    throws SystemException {
1796    
1797                    for (Organization organization : organizations) {
1798                            if (!allSuborganizations.contains(organization)) {
1799                                    allSuborganizations.add(organization);
1800    
1801                                    List<Organization> suborganizations =
1802                                            organizationPersistence.findByC_P(
1803                                                    organization.getCompanyId(),
1804                                                    organization.getOrganizationId());
1805    
1806                                    addSuborganizations(allSuborganizations, suborganizations);
1807                            }
1808                    }
1809            }
1810    
1811            protected long getParentOrganizationId(
1812                            long companyId, long parentOrganizationId)
1813                    throws SystemException {
1814    
1815                    if (parentOrganizationId !=
1816                                    OrganizationConstants.DEFAULT_PARENT_ORGANIZATION_ID) {
1817    
1818                            // Ensure parent organization exists and belongs to the proper
1819                            // company
1820    
1821                            Organization parentOrganization =
1822                                    organizationPersistence.fetchByPrimaryKey(parentOrganizationId);
1823    
1824                            if ((parentOrganization == null) ||
1825                                    (companyId != parentOrganization.getCompanyId())) {
1826    
1827                                    parentOrganizationId =
1828                                            OrganizationConstants.DEFAULT_PARENT_ORGANIZATION_ID;
1829                            }
1830                    }
1831    
1832                    return parentOrganizationId;
1833            }
1834    
1835            protected long[] getReindexOrganizationIds(Organization organization)
1836                    throws PortalException, SystemException {
1837    
1838                    List<Organization> organizations = organizationPersistence.findByC_T(
1839                            organization.getCompanyId(),
1840                            CustomSQLUtil.keywords(organization.getTreePath())[0],
1841                            QueryUtil.ALL_POS, QueryUtil.ALL_POS,
1842                            new OrganizationNameComparator(true));
1843    
1844                    long[] organizationIds = new long[organizations.size()];
1845    
1846                    for (int i = 0; i < organizations.size(); i++) {
1847                            Organization curOrganization = organizations.get(i);
1848    
1849                            curOrganization.setTreePath(curOrganization.buildTreePath());
1850    
1851                            organizationPersistence.update(curOrganization);
1852    
1853                            organizationIds[i] = curOrganization.getOrganizationId();
1854                    }
1855    
1856                    if (!ArrayUtil.contains(
1857                                    organizationIds, organization.getOrganizationId())) {
1858    
1859                            organizationIds = ArrayUtil.append(
1860                                    organizationIds, organization.getOrganizationId());
1861                    }
1862    
1863                    return organizationIds;
1864            }
1865    
1866            protected boolean isOrganizationGroup(long organizationId, long groupId)
1867                    throws SystemException {
1868    
1869                    if ((organizationId ==
1870                                    OrganizationConstants.DEFAULT_PARENT_ORGANIZATION_ID) &&
1871                            (groupId == GroupConstants.DEFAULT_PARENT_GROUP_ID)) {
1872    
1873                            return true;
1874                    }
1875    
1876                    if (organizationId !=
1877                                    OrganizationConstants.DEFAULT_PARENT_ORGANIZATION_ID) {
1878    
1879                            Organization organization =
1880                                    organizationPersistence.fetchByPrimaryKey(organizationId);
1881    
1882                            if (organization.getGroupId() == groupId) {
1883                                    return true;
1884                            }
1885                    }
1886    
1887                    return false;
1888            }
1889    
1890            protected boolean isParentOrganization(
1891                            long parentOrganizationId, long organizationId)
1892                    throws PortalException, SystemException {
1893    
1894                    // Return true if parentOrganizationId is among the parent organizatons
1895                    // of organizationId
1896    
1897                    if (organizationId ==
1898                                    OrganizationConstants.DEFAULT_PARENT_ORGANIZATION_ID) {
1899    
1900                            return false;
1901                    }
1902    
1903                    Organization organization = organizationPersistence.findByPrimaryKey(
1904                            organizationId);
1905    
1906                    String treePath = organization.getTreePath();
1907    
1908                    if (treePath.contains(
1909                                    StringPool.SLASH + parentOrganizationId + StringPool.SLASH)) {
1910    
1911                            return true;
1912                    }
1913                    else {
1914                            return false;
1915                    }
1916            }
1917    
1918            protected void validate(
1919                            long companyId, long organizationId, long parentOrganizationId,
1920                            String name, String type, long countryId, int statusId)
1921                    throws PortalException, SystemException {
1922    
1923                    if (!ArrayUtil.contains(PropsValues.ORGANIZATIONS_TYPES, type)) {
1924                            throw new OrganizationTypeException(
1925                                    "Invalid organization type " + type);
1926                    }
1927    
1928                    if (parentOrganizationId ==
1929                                    OrganizationConstants.DEFAULT_PARENT_ORGANIZATION_ID) {
1930    
1931                            if (!OrganizationImpl.isRootable(type)) {
1932                                    throw new OrganizationParentException(
1933                                            "Organization of type " + type + " cannot be a root");
1934                            }
1935                    }
1936                    else {
1937                            Organization parentOrganization =
1938                                    organizationPersistence.fetchByPrimaryKey(parentOrganizationId);
1939    
1940                            if (parentOrganization == null) {
1941                                    throw new OrganizationParentException(
1942                                            "Organization " + parentOrganizationId + " doesn't exist");
1943                            }
1944    
1945                            String[] childrenTypes = OrganizationImpl.getChildrenTypes(
1946                                    parentOrganization.getType());
1947    
1948                            if (childrenTypes.length == 0) {
1949                                    throw new OrganizationParentException(
1950                                            "Organization of type " + type + " cannot have children");
1951                            }
1952    
1953                            if ((companyId != parentOrganization.getCompanyId()) ||
1954                                    (parentOrganizationId == organizationId)) {
1955    
1956                                    throw new OrganizationParentException();
1957                            }
1958    
1959                            if (!ArrayUtil.contains(childrenTypes, type)) {
1960                                    throw new OrganizationParentException(
1961                                            "Type " + type + " not allowed as child of " +
1962                                                    parentOrganization.getType());
1963                            }
1964                    }
1965    
1966                    if ((organizationId > 0) &&
1967                            (parentOrganizationId !=
1968                                    OrganizationConstants.DEFAULT_PARENT_ORGANIZATION_ID)) {
1969    
1970                            // Prevent circular organizational references
1971    
1972                            if (isParentOrganization(organizationId, parentOrganizationId)) {
1973                                    throw new OrganizationParentException();
1974                            }
1975                    }
1976    
1977                    if (Validator.isNull(name)) {
1978                            throw new OrganizationNameException();
1979                    }
1980                    else {
1981                            Organization organization = organizationPersistence.fetchByC_N(
1982                                    companyId, name);
1983    
1984                            if ((organization != null) &&
1985                                    StringUtil.equalsIgnoreCase(organization.getName(), name)) {
1986    
1987                                    if ((organizationId <= 0) ||
1988                                            (organization.getOrganizationId() != organizationId)) {
1989    
1990                                            throw new DuplicateOrganizationException(
1991                                                    "There is another organization named " + name);
1992                                    }
1993                            }
1994                    }
1995    
1996                    boolean countryRequired = GetterUtil.getBoolean(
1997                            PropsUtil.get(
1998                                    PropsKeys.ORGANIZATIONS_COUNTRY_REQUIRED, new Filter(type)));
1999    
2000                    if (countryRequired || (countryId > 0)) {
2001                            countryPersistence.findByPrimaryKey(countryId);
2002                    }
2003    
2004                    listTypeService.validate(
2005                            statusId, ListTypeConstants.ORGANIZATION_STATUS);
2006            }
2007    
2008            protected void validate(
2009                            long companyId, long parentOrganizationId, String name, String type,
2010                            long countryId, int statusId)
2011                    throws PortalException, SystemException {
2012    
2013                    validate(
2014                            companyId, 0, parentOrganizationId, name, type, countryId,
2015                            statusId);
2016            }
2017    
2018    }