package CMS::Drupal::Modules::MembershipEntity::Stats;
$CMS::Drupal::Modules::MembershipEntity::Stats::VERSION = '0.90';
# ABSTRACT: Generate statistics about MembershipEntity memberships on a Drupal site. 

use Moo;
use Types::Standard qw/ :all /;
use base 'Exporter::Tiny'; 
our @EXPORT = qw/
  count_memberships
  count_expired_memberships
  count_active_memberships
  count_cancelled_memberships
  count_pending_memberships
  count_were_renewal_memberships
  pct_active_memberships
  pct_expired_memberships
  pct_active_memberships_were_renewal
/;

use CMS::Drupal::Modules::MembershipEntity::Membership;

use Data::Dumper;
use Carp qw/ carp croak confess /;

has dbh    => ( is => 'ro', isa => InstanceOf['DBI::db'], required => 1 );
has prefix => ( is => 'ro', isa => Maybe[Str] );


sub count_memberships {
  my $self = shift;
  if ($self->{'_memberships'}) {
    $self->{'_count_memberships'} = scalar keys %{$self->{'_memberships'}};
  } else {
    my $sql = q{ SELECT COUNT(mid) FROM membership_entity };
    $self->{'_count_memberships'} = $self->{'dbh'}->selectrow_array($sql);
  }
  return $self->{'_count_memberships'};
}


sub count_expired_memberships {
  my $self = shift;
  if ($self->{'_memberships'}) {
    my $count = 0;
    while ( my ($mid, $mem) = each %{$self->{'_memberships'}} ) {
      $count++ if $mem->is_expired;
    }
    $self->{'_count_expired_memberships'} = $count;
  } else {
    my $sql = q{ select count(mid) from membership_entity where status = 0 };
    $self->{'_count_expired_memberships'} = $self->{'dbh'}->selectrow_array($sql);
  }
  return $self->{'_count_expired_memberships'};
}


sub count_active_memberships {
  my $self = shift;
  if ($self->{'_memberships'}) {
    my $count = 0;
    while ( my ($mid, $mem) = each %{$self->{'_memberships'}} ) {
      $count++ if $mem->is_active;
    }
    $self->{'_count_active_memberships'} = $count;
  } else {
    my $sql = q{ SELECT COUNT(mid) FROM membership_entity WHERE status = 1 };
    $self->{'_count_active_memberships'} = $self->{'dbh'}->selectrow_array($sql);
  }
  return $self->{'_count_active_memberships'};
}


sub count_cancelled_memberships {
  my $self = shift;
  if ($self->{'_memberships'}) {
    my $count = 0;
    while ( my ($mid, $mem) = each %{$self->{'_memberships'}} ) {
      $count++ if $mem->is_cancelled;
    }
    $self->{'_count_cancelled_memberships'} = $count;
  } else {
    my $sql = q{ SELECT COUNT(mid) FROM membership_entity WHERE status = 2 };
    $self->{'_count_cancelled_memberships'} = $self->{'dbh'}->selectrow_array($sql);
  }
  return $self->{'_count_cancelled_memberships'};
}


sub count_pending_memberships {
  my $self = shift;
  if ($self->{'_memberships'}) {
    my $count = 0;
    while ( my ($mid, $mem) = each %{$self->{'_memberships'}} ) {
      $count++ if $mem->is_pending;
    }
    $self->{'_count_pending_memberships'} = $count;
  } else {
    my $sql = q{ select count(mid) from membership_entity where status = 3 };
    $self->{'_count_pending_memberships'} = $self->{'dbh'}->selectrow_array($sql);
  }
  return $self->{'_count_pending_memberships'};
}


sub count_were_renewal_memberships {
  my $self = shift;
  if ($self->{'_memberships'}) {
    $self->{'_count_were_renewal_memberships'} = ();
    while ( my ($mid, $mem) = each %{$self->{'_memberships'}} ) {
      if ( $mem->current_was_renewal ) {
        $self->{'_count_were_renewal_memberships'}++;
      }
    }
  }
  return $self->{'_count_were_renewal_memberships'};
}


sub pct_active_memberships {
  my $self = shift;
  my $precision = shift || 2;
  $self->{'_pct_active_memberships'} =
    sprintf("%.${precision}f", (100 *
    ($self->count_active_memberships / $self->count_memberships)));
  return $self->{'_pct_active_memberships'};
}


sub pct_expired_memberships {
  my $self = shift;
  my $precision = shift || 2;
  $self->{'_pct_expired_memberships'} =
    sprintf("%.${precision}f", (100 *
    ($self->count_expired_memberships / $self->count_memberships)));
  return $self->{'_pct_expired_memberships'};
}


sub pct_active_memberships_were_renewal {
  my $self = shift;
  my $precision = shift || 2;
  
  $self->{'_pct_active_memberships_were_renewal'} =
    sprintf("%.${precision}f", (100 *
    ($self->count_were_renewal_memberships / $self->count_active_memberships)));

  return $self->{'_pct_active_memberships_were_renewal'};
}

1; ## return true to end package CMS::Drupal::Modules::MembershipEntity

__END__

=pod

=encoding UTF-8

=head1 NAME

CMS::Drupal::Modules::MembershipEntity::Stats - Generate statistics about MembershipEntity memberships on a Drupal site. 

=head1 VERSION

version 0.90

=head1 SYNOPSIS

  use CMS::Drupal::Modules::MembershipEntity;
  use CMS::Drupal::Modules::MembershipEntity::Stats { into => 'CMS::Drupal::Modules::MembershipEntity' };
  
  my $ME = CMS::Drupal::Modules::MembershipEntity->new( dbh => $dbh ); 
  $ME->fetch_memberships();
  
  print $ME->count_active_memberships;
  print $ME->pct_active_memberships_were_renewal; 
 
  ...

=head1 METHODS

=head2 count_memberships

Returns the number of Memberships in the set.

=head2 count_expired_memberships

Returns the number of Memberships from the set that have status of 'expired'.

=head2 count_active_memberships

Returns the number of Memberships from the set that have status of 'active'.

=head2 count_cancelled_memberships

Returns the number of Memberships from the set that have status of 'cancelled'.

=head2 count_pending_memberships

Returns the number of Memberships from the set that have status of 'pending'.

=head2 count_were_renewal_memberships

Returns the number of Memberships from the set whose current Term was a renewal.

=head2 pct_active_memberships

Returns the percentage of all Memberships that currently have status of
'active'.

Accepts an integer value representing floating point precision as the single
parameter; this parameter is optional and defaults to 2.

  $ME->pct_active_memberships(4); # returns like 99.9999
  $ME->pct_active_memberships;    # returns like 99.99

=head2 pct_expired_memberships

Returns the percentage of all Memberships that currently have status of
'expired'.

Accepts an integer value representing floating point precision as the single
parameter; this parameter is optional and defaults to 2.

  $ME->pct_expired_memberships(4); # returns like 99.9999
  $ME->pct_expired_memberships;    # returns like 99.99

=head2 pct_active_memberships_were_renewal

Returns the percentage of active Memberships for which the current Term was
not the first Term in the Membership.

Accepts an integer value representing floating point precision as the single
parameter; this parameter is optional and defaults to 2.

  $ME->pct_active_memberships_were_renewal(4); # returns like 99.9999
  $ME->pct_active_memberships_were_renewal;    # returns like 99.99

=head1 AUTHOR

Nick Tonkin <tonkin@cpan.org>

=head1 COPYRIGHT AND LICENSE

This software is copyright (c) 2015 by Nick Tonkin.

This is free software; you can redistribute it and/or modify it under
the same terms as the Perl 5 programming language system itself.

=cut
