This repository has been archived on 2023-08-16. You can view files and clone it, but cannot push or open issues or pull requests.
Foodloop-Server/lib/Pear/LocalLoop/Schema/ResultSet/Leaderboard.pm

111 lines
2.8 KiB
Perl
Raw Normal View History

package Pear::LocalLoop::Schema::ResultSet::Leaderboard;
use strict;
use warnings;
use base 'DBIx::Class::ResultSet';
use DateTime;
sub get_latest {
2021-03-20 12:09:50 +00:00
my $self = shift;
my $type = shift;
2021-03-20 12:09:50 +00:00
my $type_result = $self->find_by_type($type);
2021-03-20 12:09:50 +00:00
return unless defined $type_result;
2021-03-20 12:09:50 +00:00
my $latest = $type_result->search_related(
'sets',
{},
{
order_by => { -desc => 'date' },
}
)->first;
2021-03-20 12:09:50 +00:00
return $latest;
}
sub create_new {
2021-03-20 12:09:50 +00:00
my $self = shift;
my $type = shift;
my $date = shift;
2021-03-20 12:09:50 +00:00
my $type_result = $self->find_by_type($type);
2021-03-20 12:09:50 +00:00
return unless $type_result;
2021-03-20 12:09:50 +00:00
return $type_result->create_new($date);
}
sub find_by_type {
2021-03-20 12:09:50 +00:00
my $self = shift;
my $type = shift;
2021-03-20 12:09:50 +00:00
return $self->find( { type => $type } );
}
sub recalculate_all {
2021-03-20 12:09:50 +00:00
my $self = shift;
for my $leaderboard_result ( $self->all ) {
my $lb_type = $leaderboard_result->type;
if ( $lb_type =~ /^daily/ ) {
# Recalculating a daily set. This is calculated from the start of the
# day, so we need yesterdays date:
my $date = DateTime->today->subtract( days => 1 );
$self->_recalculate_leaderboard( $leaderboard_result, $date,
'days' );
}
elsif ( $lb_type =~ /^weekly/ ) {
# Recalculating a weekly set. This is calculated from a Monday, of the
# week before.
my $date =
DateTime->today->truncate( to => 'week' )->subtract( weeks => 1 );
$self->_recalculate_leaderboard( $leaderboard_result, $date,
'weeks' );
}
elsif ( $lb_type =~ /^monthly/ ) {
# Recalculate a monthly set. This is calculated from the first of the
# month, for the month before.
my $date = DateTime->today->truncate( to => 'month' )
->subtract( months => 1 );
$self->_recalculate_leaderboard( $leaderboard_result, $date,
'months' );
}
elsif ( $lb_type =~ /^all_time/ ) {
# Recalculate for an all time set. This is calculated similarly to
# daily, but is calculated from an end time.
my $date = DateTime->today;
$self->_recalculate_leaderboard( $leaderboard_result, $date,
'days' );
}
else {
warn "Unrecognised Set";
}
}
}
sub _recalculate_leaderboard {
2021-03-20 12:09:50 +00:00
my ( $self, $lb_result, $date, $diff ) = @_;
$self->result_source->schema->txn_do(
sub {
$lb_result->sets->related_resultset('values')->delete_all;
$lb_result->sets->delete_all;
$lb_result->create_new( $date->clone->subtract( $diff => 1 ) );
$lb_result->create_new($date);
}
);
}
1;