RT# 32238 Billing Event cust_birthdate
[freeside.git] / FS / FS / part_event / Condition / cust_birthdate.pm
1 package FS::part_event::Condition::cust_birthdate;
2 use base qw( FS::part_event::Condition );
3 use strict;
4 use warnings;
5 use DateTime;
6
7 =head2 NAME
8
9 FS::part_event::Condition::cust_birthdate
10
11 =head1 DESCRIPTION
12
13 Billing event triggered by the time until the customer's next
14 birthday (cust_main.birthdate)
15
16 =cut
17
18 sub description {
19   'Customer birthdate occurs within the given timeframe';
20 }
21
22 sub option_fields {
23   (
24     timeframe => {
25       label => 'Timeframe',
26       type   => 'freq',
27       value  => '1m',
28     }
29   );
30 }
31
32 sub condition {
33   my( $self, $object, %opt ) = @_;
34   my $cust_main = $self->cust_main($object);
35
36   my $birthdate = $cust_main->birthdate || return 0;
37
38   my %timeframe;
39   if ( $self->option('timeframe') =~ /(\d+)([mwdh])/ ) {
40     my $k = {qw|m months w weeks d days h hours|}->{$2};
41     $timeframe{ $k } = $1;
42   } else {
43     die "Unparsable timeframe given: ".$self->option('timeframe');
44   }
45
46   my $ck_dt = DateTime->from_epoch( epoch => $opt{time} );
47   my $bd_dt = DateTime->from_epoch( epoch => $birthdate );
48
49   # Find the birthday for this calendar year.  If customer birthday
50   # has already passed this year, find the birthday for next year.
51   my $next_bd_dt = DateTime->new(
52     month => $bd_dt->month,
53     day   => $bd_dt->day,
54     year  => $ck_dt->year,
55   );
56   $next_bd_dt->add( years => 1 )
57     if DateTime->compare( $next_bd_dt, $ck_dt ) == -1;
58
59   # Does next birthday occur between now and specified duration?
60   $ck_dt->add( %timeframe );
61   DateTime->compare( $next_bd_dt, $ck_dt ) != 1 ? 1 : 0;
62 }
63
64 1;