Merge branch 'master' of git.freeside.biz:/home/git/freeside
[freeside.git] / FS / t / suite / 06-prorate_defer_bill.t
1 #!/usr/bin/perl
2
3 =head2 DESCRIPTION
4
5 Tests the prorate_defer_bill behavior when a package is started on the cutoff day,
6 and when it's started later in the month.
7
8 Correct: The package started on the cutoff day should be charged a setup fee and a
9 full period. The package started later in the month should be charged a setup fee,
10 a full period, and the partial period.
11
12 =cut
13
14 use strict;
15 use Test::More tests => 11;
16 use FS::Test;
17 use Date::Parse 'str2time';
18 use Date::Format 'time2str';
19 use Test::MockTime qw(set_fixed_time);
20 use FS::cust_main;
21 use FS::cust_pkg;
22 use FS::Conf;
23 my $FS= FS::Test->new;
24
25 my $error;
26
27 my $old_part_pkg = $FS->qsearchs('part_pkg', { pkgpart => 2 });
28 my $part_pkg = $old_part_pkg->clone;
29 BAIL_OUT("existing pkgpart 2 is not a prorated monthly package")
30   unless $part_pkg->freq eq '1' and $part_pkg->plan eq 'prorate';
31 $error = $part_pkg->insert(
32   options => {  $old_part_pkg->options,
33                 'prorate_defer_bill' => 1,
34                 'cutoff_day' => 1,
35                 'setup_fee'  => 100,
36                 'recur_fee'  => 30,
37               }
38 );
39 BAIL_OUT("can't configure package: $error") if $error;
40
41 my $cust = $FS->new_customer('Prorate defer');
42 $error = $cust->insert;
43 BAIL_OUT("can't create test customer: $error") if $error;
44
45 my @pkgs;
46 foreach my $start_day (1, 11) {
47   diag("prorate package starting on day $start_day");
48   # Create and bill the first package.
49   my $date = str2time("2016-04-$start_day");
50   set_fixed_time($date);
51   my $pkg = FS::cust_pkg->new({ pkgpart => $part_pkg->pkgpart });
52   $error = $cust->order_pkg({ 'cust_pkg' => $pkg });
53   BAIL_OUT("can't order package: $error") if $error;
54
55   # bill the customer on the order date
56   $error = $cust->bill_and_collect;
57   $pkg = $pkg->replace_old;
58   push @pkgs, $pkg;
59   my ($cust_bill_pkg) = $pkg->cust_bill_pkg;
60   if ( $start_day == 1 ) {
61     # then it should bill immediately
62     ok($cust_bill_pkg, "package was billed") or next;
63     ok($cust_bill_pkg->setup == 100, "setup fee was charged");
64     ok($cust_bill_pkg->recur == 30, "one month was charged");
65   } elsif ( $start_day == 11 ) {
66     # then not
67     ok(!$cust_bill_pkg, "package billing was deferred");
68     ok($pkg->setup == $date, "package setup date was set");
69   }
70 }
71 diag("first of month billing...");
72 my $date = str2time('2016-05-01');
73 set_fixed_time($date);
74 my @bill;
75 $error = $cust->bill_and_collect(return_bill => \@bill);
76 # examine the invoice...
77 my $cust_bill = $bill[0] or BAIL_OUT("neither package was billed");
78 for my $pkg ($pkgs[0]) {
79   diag("package started day 1:");
80   my ($cust_bill_pkg) = grep {$_->pkgnum == $pkg->pkgnum} $cust_bill->cust_bill_pkg;
81   ok($cust_bill_pkg, "was billed") or next;
82   ok($cust_bill_pkg->setup == 0, "no setup fee was charged");
83   ok($cust_bill_pkg->recur == 30, "one month was charged");
84 }
85 for my $pkg ($pkgs[1]) {
86   diag("package started day 11:");
87   my ($cust_bill_pkg) = grep {$_->pkgnum == $pkg->pkgnum} $cust_bill->cust_bill_pkg;
88   ok($cust_bill_pkg, "was billed") or next;
89   ok($cust_bill_pkg->setup == 100, "setup fee was charged");
90   ok($cust_bill_pkg->recur == 50, "twenty days + one month was charged");
91 }
92