LeaderCardUtil.java

  1. package com.hack23.cia.web.impl.ui.application.views.common.pagemode;

  2. import java.util.List;
  3. import java.util.Locale;
  4. import java.util.Map;
  5. import java.util.stream.Collectors;

  6. import org.springframework.beans.factory.annotation.Autowired;
  7. import org.springframework.stereotype.Component;

  8. import com.hack23.cia.model.internal.application.data.ministry.impl.ViewRiksdagenGovermentRoleMember;
  9. import com.hack23.cia.model.internal.application.data.ministry.impl.ViewRiksdagenGovermentRoleMember_;
  10. import com.hack23.cia.model.internal.application.data.party.impl.ViewRiksdagenPartyRoleMember;
  11. import com.hack23.cia.model.internal.application.data.politician.impl.ViewRiksdagenPolitician;
  12. import com.hack23.cia.model.internal.application.data.politician.impl.ViewRiksdagenPoliticianBallotSummary;
  13. import com.hack23.cia.model.internal.application.data.politician.impl.ViewRiksdagenPoliticianExperienceSummary;
  14. import com.hack23.cia.model.internal.application.data.politician.impl.ViewRiksdagenPolitician_;
  15. import com.hack23.cia.service.api.ApplicationManager;
  16. import com.hack23.cia.service.api.DataContainer;
  17. import com.hack23.cia.service.external.esv.api.GovernmentBodyAnnualOutcomeSummary;
  18. import com.hack23.cia.service.external.esv.api.GovernmentBodyAnnualSummary;
  19. import com.hack23.cia.web.impl.ui.application.action.ViewAction;
  20. import com.hack23.cia.web.impl.ui.application.views.common.pagelinks.api.PageLinkFactory;
  21. import com.hack23.cia.web.impl.ui.application.views.common.viewnames.UserViews;
  22. import com.vaadin.icons.VaadinIcons;
  23. import com.vaadin.server.ExternalResource;
  24. import com.vaadin.server.Responsive;
  25. import com.vaadin.shared.ui.ContentMode;
  26. import com.vaadin.ui.HorizontalLayout;
  27. import com.vaadin.ui.Label;
  28. import com.vaadin.ui.Link;
  29. import com.vaadin.ui.Panel;
  30. import com.vaadin.ui.VerticalLayout;

  31. /**
  32.  * The Class LeaderCardUtil.
  33.  */
  34. @Component
  35. public class LeaderCardUtil {

  36.     /** The application manager. */
  37.     @Autowired
  38.     private ApplicationManager applicationManager;

  39.     /** The politician leaderboard util. */
  40.     @Autowired
  41.     private PoliticianLeaderboardUtil politicianLeaderboardUtil;

  42.     /** The page link factory. */
  43.     @Autowired
  44.     public PageLinkFactory pageLinkFactory;

  45.     /**
  46.      * Load active government role members.
  47.      *
  48.      * @return the list
  49.      */
  50.     @SuppressWarnings("unchecked")
  51.     public List<ViewRiksdagenGovermentRoleMember> loadActiveGovernmentRoleMembers() {
  52.         final DataContainer<ViewRiksdagenGovermentRoleMember, String> govermentRoleMemberDataContainer = applicationManager
  53.                 .getDataContainer(ViewRiksdagenGovermentRoleMember.class);
  54.         return govermentRoleMemberDataContainer.findListByProperty(new Object[] { Boolean.TRUE },
  55.                 ViewRiksdagenGovermentRoleMember_.active);
  56.     }

  57.     /**
  58.      * Load active politicians by person id.
  59.      *
  60.      * @return the map
  61.      */
  62.     @SuppressWarnings("unchecked")
  63.     public Map<String, List<ViewRiksdagenPolitician>> loadActivePoliticiansByPersonId() {
  64.         final DataContainer<ViewRiksdagenPolitician, String> politicianDataContainer = applicationManager
  65.                 .getDataContainer(ViewRiksdagenPolitician.class);
  66.         final List<ViewRiksdagenPolitician> activePoliticians = politicianDataContainer
  67.                 .findListByProperty(new Object[] { Boolean.TRUE }, ViewRiksdagenPolitician_.active);
  68.         return activePoliticians.stream().collect(Collectors.groupingBy(ViewRiksdagenPolitician::getPersonId));
  69.     }

  70.     /**
  71.      * Creates the base card.
  72.      *
  73.      * @return the panel
  74.      */
  75.     private Panel createBaseCard() {
  76.         final Panel cardPanel = new Panel();
  77.         cardPanel.addStyleName("leader-baseball-card");
  78.         cardPanel.setSizeFull();
  79.         Responsive.makeResponsive(cardPanel);
  80.         return cardPanel;
  81.     }

  82.     /**
  83.      * Creates the card content.
  84.      *
  85.      * @return the vertical layout
  86.      */
  87.     private VerticalLayout createCardContent() {
  88.         final VerticalLayout cardContent = new VerticalLayout();
  89.         cardContent.setMargin(true);
  90.         cardContent.setSpacing(true);
  91.         cardContent.setSizeFull();
  92.         return cardContent;
  93.     }

  94.     /**
  95.      * Adds the experience row.
  96.      *
  97.      * @param container the container
  98.      * @param govYears the gov years
  99.      * @param partyYears the party years
  100.      * @param parliamentYears the parliament years
  101.      */
  102.     private void addExperienceRow(final VerticalLayout container, final int govYears, final int partyYears, final int parliamentYears) {
  103.         final HorizontalLayout experienceLayout = CardInfoRowUtil.createStandardRow();
  104.         experienceLayout.addStyleName(CardInfoRowUtil.CARD_EXPERIENCE);

  105.         final Label expIcon = CardInfoRowUtil.createIconLabel(VaadinIcons.USER_CHECK, "Political Experience");
  106.         final Label expLabel = new Label("Experience:");
  107.         expLabel.addStyleName("card-experience-text");

  108.         final String expText = String.format(Locale.ENGLISH,
  109.             "Government: %dy, Party: %dy, Parliament: %dy",
  110.             govYears, partyYears, parliamentYears);
  111.         final Label expValue = new Label(expText);
  112.         expValue.addStyleName(CardInfoRowUtil.CARD_INFO_VALUE);

  113.         experienceLayout.addComponents(expIcon, expLabel, expValue);
  114.         container.addComponent(experienceLayout);
  115.     }

  116.     /**
  117.      * Creates the baseball style card.
  118.      *
  119.      * @param govMember the gov member
  120.      * @param politician the politician
  121.      * @param ballotSummary the ballot summary
  122.      * @param governmentBodyByMinistry the government body by ministry
  123.      * @param reportByMinistry the report by ministry
  124.      * @param experienceSummary the experience summary
  125.      * @return the panel
  126.      */
  127.     public Panel createBaseballStyleCard(final ViewRiksdagenGovermentRoleMember govMember,
  128.             final ViewRiksdagenPolitician politician, final ViewRiksdagenPoliticianBallotSummary ballotSummary, final Map<String, List<GovernmentBodyAnnualSummary>> governmentBodyByMinistry,
  129.             final Map<String, List<GovernmentBodyAnnualOutcomeSummary>> reportByMinistry, final ViewRiksdagenPoliticianExperienceSummary experienceSummary) {

  130.         final Panel cardPanel = createBaseCard();
  131.         final VerticalLayout cardContent = createCardContent();
  132.         cardPanel.setContent(cardContent);

  133.         CardInfoRowUtil.createCardHeader(cardContent,govMember.getRoleCode() + " " + govMember.getFirstName() + " " + govMember.getLastName()
  134.             + " (" + govMember.getParty() + ")");
  135.         cardContent.addComponent(pageLinkFactory.createPoliticianPageLink(politician));

  136.         final Link pageLink = new Link("Party " + politician.getParty(),
  137.                 new ExternalResource("#!" + UserViews.PARTY_VIEW_NAME + "/" + politician.getParty()));
  138.         pageLink.setId(ViewAction.VISIT_PARTY_VIEW.name() + "/" + politician.getParty());
  139.         pageLink.setIcon(VaadinIcons.GROUP);

  140.         cardContent.addComponent(pageLink);

  141.         final boolean isPartyLeader = PartyLeaderUtil.isPartyLeader(applicationManager, politician.getPersonId());
  142.         if (isPartyLeader) {
  143.             final ViewRiksdagenPartyRoleMember leaderRole = PartyLeaderUtil.getPartyLeaderRole(applicationManager, politician.getPersonId());
  144.             if (leaderRole != null) {
  145.                 final Label subHeader = new Label(
  146.                         "Partiledare (" + govMember.getParty() + ") since " + leaderRole.getFromDate());
  147.                 subHeader.addStyleName("card-subtitle");
  148.                 cardContent.addComponent(subHeader);
  149.             }
  150.         }

  151.         // After creating the divider following the header/subtitle
  152.         // We create a vertical layout to hold Tenure and Experience on separate rows
  153.         final VerticalLayout statsContainer = CardInfoRowUtil.createStatsContainer();

  154.         // Tenure Row
  155.         final HorizontalLayout tenureLayout = new HorizontalLayout();
  156.         tenureLayout.setSpacing(true);
  157.         tenureLayout.addStyleName("card-tenure");
  158.         final Label tenureIcon = new Label(VaadinIcons.CLOCK.getHtml(), ContentMode.HTML);
  159.         tenureIcon.setDescription("Tenure in days");

  160.         final Label tenureLabel = new Label("Tenure:");
  161.         tenureLabel.addStyleName("card-tenure-text");

  162.         final Label tenureValue = new Label(govMember.getTotalDaysServed() + " days");
  163.         tenureValue.addStyleName("card-tenure-value");

  164.         tenureLayout.addComponents(tenureIcon, tenureLabel, tenureValue);
  165.         statsContainer.addComponent(tenureLayout);

  166.         // Experience Row
  167.         final int govYears = (int) (politician.getTotalDaysServedGovernment() / 365);
  168.         final int partyYears = (int) (politician.getTotalDaysServedParty() / 365);
  169.         final int parliamentYears = (int) (politician.getTotalDaysServedParliament() / 365);
  170.         addExperienceRow(statsContainer, govYears, partyYears, parliamentYears);

  171.         // Add the statsContainer to the cardContent
  172.         cardContent.addComponent(statsContainer);

  173.         // Create grid for the four sections
  174.         final HorizontalLayout sectionsGrid = new HorizontalLayout();
  175.         sectionsGrid.setSpacing(true);
  176.         sectionsGrid.setWidth("100%");

  177.         // Add the four main sections
  178.         final VerticalLayout politicalRoleLayout = CardInfoRowUtil.createSectionLayout("Political Role & Influence");
  179.         addPoliticalRoleMetrics(politicalRoleLayout, govMember, politician, ballotSummary, experienceSummary);
  180.         sectionsGrid.addComponent(politicalRoleLayout);

  181.         final VerticalLayout performanceLayout = CardInfoRowUtil.createSectionLayout("Parliamentary Performance");
  182.         politicianLeaderboardUtil.addParliamentaryPerformanceMetrics(performanceLayout, politician, ballotSummary);
  183.         sectionsGrid.addComponent(performanceLayout);

  184.         cardContent.addComponent(sectionsGrid);

  185.         final HorizontalLayout sections2Grid = new HorizontalLayout();
  186.         sections2Grid.setSpacing(true);
  187.         sections2Grid.setWidth("100%");

  188.         final VerticalLayout legislativeLayout = CardInfoRowUtil.createSectionLayout("Legislative Activity");
  189.         politicianLeaderboardUtil.addLegislativeMetrics(legislativeLayout, politician);
  190.         sections2Grid.addComponent(legislativeLayout);

  191.         final VerticalLayout alignmentLayout = CardInfoRowUtil.createSectionLayout("Party Alignment");
  192.         politicianLeaderboardUtil.addPartyAlignmentMetrics(alignmentLayout, politician, ballotSummary);
  193.         sections2Grid.addComponent(alignmentLayout);
  194.         cardContent.addComponent(sections2Grid);

  195.         politicianLeaderboardUtil.addMinistryRoleSummary(cardContent, govMember, governmentBodyByMinistry, reportByMinistry);

  196.         return cardPanel;
  197.     }

  198.     /**
  199.      * Creates the leader card.
  200.      *
  201.      * @param leader the leader
  202.      * @param ballotSummary the ballot summary
  203.      * @param governmentBodyByMinistry the government body by ministry
  204.      * @param reportByMinistry the report by ministry
  205.      * @param experienceSummary the experience summary
  206.      * @return the panel
  207.      */
  208.     public Panel createLeaderCard(final ViewRiksdagenPolitician leader, final ViewRiksdagenPoliticianBallotSummary ballotSummary,
  209.             final Map<String, List<GovernmentBodyAnnualSummary>> governmentBodyByMinistry,
  210.             final Map<String, List<GovernmentBodyAnnualOutcomeSummary>> reportByMinistry, final ViewRiksdagenPoliticianExperienceSummary experienceSummary) {

  211.         final Panel cardPanel = createBaseCard();
  212.         final VerticalLayout cardContent = createCardContent();
  213.         cardPanel.setContent(cardContent);

  214.         CardInfoRowUtil.createCardHeader(cardContent,"Partiledare " + leader.getFirstName() + " " + leader.getLastName() + " ("
  215.                 + leader.getParty() + ")");

  216.         // Politician detail link
  217.         cardContent.addComponent(pageLinkFactory.createPoliticianPageLink(leader));

  218.         // Party link
  219.         final Link partyLink = new Link("Party " + leader.getParty(),
  220.                 new ExternalResource("#!" + UserViews.PARTY_VIEW_NAME + "/" + leader.getParty()));
  221.         partyLink.setIcon(VaadinIcons.GROUP);
  222.         cardContent.addComponent(partyLink);

  223.         final boolean isPartyLeader = PartyLeaderUtil.isPartyLeader(applicationManager, leader.getPersonId());
  224.         if (isPartyLeader) {
  225.             final ViewRiksdagenPartyRoleMember leaderRole = PartyLeaderUtil.getPartyLeaderRole(applicationManager, leader.getPersonId());
  226.             if (leaderRole != null) {
  227.                 final Label subHeader = new Label("Partiledare (" + leader.getParty() + ") since " + leaderRole.getFromDate());
  228.                 subHeader.addStyleName("card-subtitle");
  229.                 cardContent.addComponent(subHeader);
  230.             }
  231.         }

  232.         // Government or not
  233.         ViewRiksdagenGovermentRoleMember govMember = null;
  234.         if (leader.isActiveGovernment()) {
  235.             final Label govLabel = new Label("Currently in Government");
  236.             govLabel.addStyleName("card-subtitle");
  237.             cardContent.addComponent(govLabel);

  238.             // Add ministry summary if we can identify their ministry
  239.             // The ministry detail is stored in the same structure as the ministry snippet:
  240.             // We need to find which ministry they belong to
  241.             // In the ministry snippet, "govMember.getDetail()" gives ministry detail key.
  242.             // Here we only have leader, not govMember. We must find a corresponding approach:

  243.             // Let's assume we can identify the leader's ministry from active government roles data:
  244.             // we do similar approach: load active government role members and find the one matching this leader
  245.             final ViewRiksdagenPolitician pol = leader; // same as leader
  246.             govMember = findGovernmentRoleForLeader(pol);
  247.             if (govMember != null) {
  248.                 politicianLeaderboardUtil.addMinistryRoleSummary(cardContent, govMember, governmentBodyByMinistry, reportByMinistry);
  249.             }

  250.         } else {
  251.             final Label nonGovLabel = new Label("Not in Government");
  252.             nonGovLabel.addStyleName("card-subtitle-nongov");
  253.             cardContent.addComponent(nonGovLabel);
  254.         }

  255.         // Tenure and Experience rows
  256.         final VerticalLayout statsContainer = CardInfoRowUtil.createStatsContainer();

  257.         // Tenure (assuming leader might have totalDaysServed property)
  258.         final Label tenureIcon = new Label(VaadinIcons.CLOCK.getHtml(), ContentMode.HTML);
  259.         tenureIcon.setDescription("Total Tenure");
  260.         final Label tenureLabel = new Label("Tenure:");
  261.         tenureLabel.addStyleName("card-tenure-text");
  262.         final Label tenureValue = new Label(leader.getTotalDaysServedParty() + " days");
  263.         tenureValue.addStyleName("card-tenure-value");
  264.         final HorizontalLayout tenureLayout = new HorizontalLayout(tenureIcon, tenureLabel, tenureValue);
  265.         tenureLayout.setSpacing(true);
  266.         tenureLayout.addStyleName("card-tenure");
  267.         statsContainer.addComponent(tenureLayout);

  268.         // Experience
  269.         final int govYears = (int) (leader.getTotalDaysServedGovernment() / 365);
  270.         final int partyYears = (int) (leader.getTotalDaysServedParty() / 365);
  271.         final int parliamentYears = (int) (leader.getTotalDaysServedParliament() / 365);
  272.         addExperienceRow(statsContainer, govYears, partyYears, parliamentYears);

  273.         cardContent.addComponent(statsContainer);

  274.         // Create grid for the four sections
  275.         final HorizontalLayout sectionsGrid = new HorizontalLayout();
  276.         sectionsGrid.setSpacing(true);
  277.         sectionsGrid.setWidth("100%");

  278.         // Add the four main sections
  279.         final VerticalLayout politicalRoleLayout = CardInfoRowUtil.createSectionLayout("Political Role & Influence");
  280.         addPoliticalRoleMetrics(politicalRoleLayout, PartyLeaderUtil.getPartyLeaderRole(applicationManager, leader.getPersonId()), govMember, leader, ballotSummary,experienceSummary);
  281.         sectionsGrid.addComponent(politicalRoleLayout);

  282.         final VerticalLayout performanceLayout = CardInfoRowUtil.createSectionLayout("Parliamentary Performance");
  283.         politicianLeaderboardUtil.addParliamentaryPerformanceMetrics(performanceLayout, leader, ballotSummary);
  284.         sectionsGrid.addComponent(performanceLayout);

  285.         cardContent.addComponent(sectionsGrid);

  286.         final HorizontalLayout sections2Grid = new HorizontalLayout();
  287.         sections2Grid.setSpacing(true);
  288.         sections2Grid.setWidth("100%");

  289.         final VerticalLayout legislativeLayout = CardInfoRowUtil.createSectionLayout("Legislative Activity");
  290.         politicianLeaderboardUtil.addLegislativeMetrics(legislativeLayout, leader);
  291.         sections2Grid.addComponent(legislativeLayout);

  292.         final VerticalLayout alignmentLayout = CardInfoRowUtil.createSectionLayout("Party Alignment");
  293.         politicianLeaderboardUtil.addPartyAlignmentMetrics(alignmentLayout, leader, ballotSummary);
  294.         sections2Grid.addComponent(alignmentLayout);
  295.         cardContent.addComponent(sections2Grid);

  296.         return cardPanel;
  297.     }

  298.     /**
  299.      * Adds the political role metrics.
  300.      *
  301.      * @param layout the layout
  302.      * @param govMember the gov member
  303.      * @param politician the politician
  304.      * @param ballotSummary the ballot summary
  305.      * @param experienceSummary the experience summary
  306.      */
  307.     private void addPoliticalRoleMetrics(final VerticalLayout layout, final ViewRiksdagenGovermentRoleMember govMember,
  308.             final ViewRiksdagenPolitician politician, final ViewRiksdagenPoliticianBallotSummary ballotSummary, final ViewRiksdagenPoliticianExperienceSummary experienceSummary) {

  309.         layout.addComponent(CardInfoRowUtil.createInfoRow("Current Role:", govMember.getRoleCode(), VaadinIcons.INSTITUTION,
  310.                 "Current position in parliament"));
  311.         layout.addComponent(CardInfoRowUtil.createInfoRow("Career Length:",
  312.                 String.format(Locale.ENGLISH,"%,d days", govMember.getTotalDaysServed()),
  313.                 VaadinIcons.TIMER, "Years in parliament"));
  314.         layout.addComponent(CardInfoRowUtil.createInfoRow("Total Propositions:",
  315.                 String.format(Locale.ENGLISH,"%,d", govMember.getTotalPropositions()),
  316.                 VaadinIcons.GROUP, "Total Propositions"));
  317.         layout.addComponent(CardInfoRowUtil.createInfoRow("Total Government Bills:",
  318.                 String.format(Locale.ENGLISH,"%,d", govMember.getTotalGovernmentBills()),
  319.                 VaadinIcons.GROUP, "Total Government Bills"));

  320.         politicianLeaderboardUtil.addTopRoles(layout, experienceSummary);
  321.         politicianLeaderboardUtil.addKnowledgeAreas(layout, experienceSummary);
  322.         politicianLeaderboardUtil.addExperienceMetrics(layout,experienceSummary);
  323.         politicianLeaderboardUtil.addPoliticalAnalysisComment(layout, experienceSummary);

  324.     }

  325.     /**
  326.      * Adds the political role metrics.
  327.      *
  328.      * @param layout the layout
  329.      * @param riksdagenPartyRoleMember the riksdagen party role member
  330.      * @param govMember the gov member
  331.      * @param politician the politician
  332.      * @param ballotSummary the ballot summary
  333.      * @param experienceSummary the experience summary
  334.      */
  335.     private void addPoliticalRoleMetrics(final VerticalLayout layout, final ViewRiksdagenPartyRoleMember riksdagenPartyRoleMember, final ViewRiksdagenGovermentRoleMember govMember,
  336.             final ViewRiksdagenPolitician politician, final ViewRiksdagenPoliticianBallotSummary ballotSummary, final ViewRiksdagenPoliticianExperienceSummary experienceSummary) {

  337.         addPartyExperince(layout, riksdagenPartyRoleMember, govMember, politician);

  338.         // Top Roles
  339.         politicianLeaderboardUtil.addTopRoles(layout, experienceSummary);

  340.         // Top Knowledge Areas
  341.         politicianLeaderboardUtil.addKnowledgeAreas(layout, experienceSummary);

  342.         politicianLeaderboardUtil.addExperienceMetrics(layout,experienceSummary);

  343.         politicianLeaderboardUtil.addPoliticalAnalysisComment(layout, experienceSummary);

  344.     }

  345.     /**
  346.      * Adds the party experince.
  347.      *
  348.      * @param layout the layout
  349.      * @param riksdagenPartyRoleMember the riksdagen party role member
  350.      * @param govMember the gov member
  351.      * @param politician the politician
  352.      */
  353.     private void addPartyExperince(final VerticalLayout layout, final ViewRiksdagenPartyRoleMember riksdagenPartyRoleMember,
  354.             final ViewRiksdagenGovermentRoleMember govMember, final ViewRiksdagenPolitician politician) {
  355.         if (govMember != null) {
  356.             layout.addComponent(CardInfoRowUtil.createInfoRow("Role:", govMember != null ? govMember.getRoleCode() : "N/A", VaadinIcons.INSTITUTION,
  357.                     "Current position in Government"));
  358.             layout.addComponent(CardInfoRowUtil.createInfoRow("Career Length Government:",
  359.                     String.format(Locale.ENGLISH,"%,d days", govMember != null ? govMember.getTotalDaysServed() : 0),
  360.                     VaadinIcons.TIMER, "Years in Government"));
  361.         } else {
  362.             layout.addComponent(CardInfoRowUtil.createInfoRow("Career Length Parlimanet:",
  363.                     String.format(Locale.ENGLISH,"%,d days", politician != null ? politician.getTotalDaysServedParliament() : 0),
  364.                     VaadinIcons.TIMER, "Years in Parlimanet"));
  365.         }

  366.         layout.addComponent(CardInfoRowUtil.createInfoRow("Current Party Role:", riksdagenPartyRoleMember != null ? riksdagenPartyRoleMember.getRoleCode() : "N/A", VaadinIcons.INSTITUTION,
  367.                 "Current position in Party"));
  368.         layout.addComponent(CardInfoRowUtil.createInfoRow("Career Length Party Leader:",
  369.                 String.format(Locale.ENGLISH,"%,d days", riksdagenPartyRoleMember != null ? riksdagenPartyRoleMember.getTotalDaysServed() : 0),
  370.                 VaadinIcons.TIMER, "Years as Party Leader"));
  371.     }

  372.     /**
  373.      * Find government role for leader.
  374.      *
  375.      * @param leader the leader
  376.      * @return the view riksdagen goverment role member
  377.      */
  378.     @SuppressWarnings("unchecked")
  379.     private ViewRiksdagenGovermentRoleMember findGovernmentRoleForLeader(final ViewRiksdagenPolitician leader) {
  380.         final DataContainer<ViewRiksdagenGovermentRoleMember, String> govermentRoleMemberDataContainer = applicationManager
  381.                 .getDataContainer(ViewRiksdagenGovermentRoleMember.class);
  382.         final List<ViewRiksdagenGovermentRoleMember> activeGovMembers = govermentRoleMemberDataContainer.findListByProperty(
  383.                 new Object[] { Boolean.TRUE }, ViewRiksdagenGovermentRoleMember_.active);

  384.         return activeGovMembers.stream()
  385.                 .filter(govMember -> govMember.getPersonId().equals(leader.getPersonId()))
  386.                 .findFirst().orElse(null);
  387.     }
  388. }