+#these should be auto-generated or $AUTOLOADed or something
+sub invoiced_12mo {
+ my( $self, $speriod, $eperiod, $agentnum ) = @_;
+ $speriod = $self->_subtract_11mo($speriod);
+ $self->invoiced($speriod, $eperiod, $agentnum);
+}
+
+sub netsales_12mo {
+ my( $self, $speriod, $eperiod, $agentnum ) = @_;
+ $speriod = $self->_subtract_11mo($speriod);
+ $self->netsales($speriod, $eperiod, $agentnum);
+}
+
+sub receipts_12mo {
+ my( $self, $speriod, $eperiod, $agentnum ) = @_;
+ $speriod = $self->_subtract_11mo($speriod);
+ $self->receipts($speriod, $eperiod, $agentnum);
+}
+
+sub payments_12mo {
+ my( $self, $speriod, $eperiod, $agentnum ) = @_;
+ $speriod = $self->_subtract_11mo($speriod);
+ $self->payments($speriod, $eperiod, $agentnum);
+}
+
+sub credits_12mo {
+ my( $self, $speriod, $eperiod, $agentnum ) = @_;
+ $speriod = $self->_subtract_11mo($speriod);
+ $self->credits($speriod, $eperiod, $agentnum);
+}
+
+#not being too bad with the false laziness
+use Time::Local qw(timelocal);
+sub _subtract_11mo {
+ my($self, $time) = @_;
+ my ($sec,$min,$hour,$mday,$mon,$year) = (localtime($time) )[0,1,2,3,4,5];
+ $mon -= 11;
+ if ( $mon < 0 ) { $mon+=12; $year--; }
+ timelocal($sec,$min,$hour,$mday,$mon,$year);
+}
+
+sub cust_bill_pkg {
+ my( $self, $speriod, $eperiod, $agentnum, %opt ) = @_;
+
+ my $where = '';
+ if ( $opt{'classnum'} =~ /^(\d+)$/ ) {
+ if ( $1 == 0 ) {
+ $where = "classnum IS NULL";
+ } else {
+ $where = "classnum = $1";
+ }
+ }
+
+ $agentnum ||= $opt{'agentnum'};
+
+ $self->scalar_sql("
+ SELECT SUM(cust_bill_pkg.setup + cust_bill_pkg.recur)
+ FROM cust_bill_pkg
+ LEFT JOIN cust_bill USING ( invnum )
+ LEFT JOIN cust_main USING ( custnum )
+ LEFT JOIN cust_pkg USING ( pkgnum )
+ LEFT JOIN part_pkg USING ( pkgpart )
+ WHERE pkgnum != 0
+ AND $where
+ AND ". $self->in_time_period_and_agent($speriod, $eperiod, $agentnum)
+ );
+
+}
+
+sub setup_pkg { shift->pkg_field( @_, 'setup' ); }
+sub susp_pkg { shift->pkg_field( @_, 'susp' ); }
+sub cancel_pkg { shift->pkg_field( @_, 'cancel'); }
+
+sub pkg_field {
+ my( $self, $speriod, $eperiod, $agentnum, $field ) = @_;
+ $self->scalar_sql("
+ SELECT COUNT(*) FROM cust_pkg
+ LEFT JOIN cust_main USING ( custnum )
+ WHERE ". $self->in_time_period_and_agent( $speriod,
+ $eperiod,
+ $agentnum,
+ "cust_pkg.$field",
+ )
+ );
+
+}
+
+#this is going to be harder..
+#sub unsusp_pkg {
+# my( $self, $speriod, $eperiod, $agentnum ) = @_;
+# $self->scalar_sql("
+# SELECT COUNT(*) FROM h_cust_pkg
+# WHERE
+#
+#}
+
+sub in_time_period_and_agent {
+ my( $self, $speriod, $eperiod, $agentnum ) = splice(@_, 0, 4);
+ my $col = @_ ? shift() : '_date';
+
+ my $sql = "$col >= $speriod AND $col < $eperiod";
+
+ #agent selection
+ $sql .= " AND cust_main.agentnum = $agentnum"
+ if $agentnum;
+
+ #agent virtualization
+ $sql .= ' AND '.
+ $FS::CurrentUser::CurrentUser->agentnums_sql( 'table'=>'cust_main' );
+
+ $sql;