summaryrefslogtreecommitdiff
path: root/FS/FS/part_event
diff options
context:
space:
mode:
authorivan <ivan>2008-11-22 22:17:28 +0000
committerivan <ivan>2008-11-22 22:17:28 +0000
commit58f99accce35aa76abe9ff852f6c6ee84e8ce712 (patch)
tree4403996ba0953f5826d5b84b99d9f99f6629683e /FS/FS/part_event
parent1d84feb7fe821b547e211ad03e5c200c8f218797 (diff)
referral credits overhaul, use billing events, agents can self-configure, limit to once-per-customer, depend on any time from referred package, referred customer payment, specific packages, partial staged credits, RT#3983
Diffstat (limited to 'FS/FS/part_event')
-rw-r--r--FS/FS/part_event/Action/addpost.pm8
-rw-r--r--FS/FS/part_event/Action/apply.pm8
-rw-r--r--FS/FS/part_event/Action/bill.pm8
-rw-r--r--FS/FS/part_event/Action/cancel.pm11
-rw-r--r--FS/FS/part_event/Action/collect.pm8
-rw-r--r--FS/FS/part_event/Action/cust_bill_batch.pm12
-rw-r--r--FS/FS/part_event/Action/cust_bill_comp.pm12
-rw-r--r--FS/FS/part_event/Action/cust_bill_fee_percent.pm8
-rw-r--r--FS/FS/part_event/Action/cust_bill_realtime_card.pm8
-rw-r--r--FS/FS/part_event/Action/cust_bill_realtime_check.pm8
-rw-r--r--FS/FS/part_event/Action/cust_bill_realtime_lec.pm8
-rw-r--r--FS/FS/part_event/Action/cust_bill_send.pm8
-rw-r--r--FS/FS/part_event/Action/cust_bill_send_agent.pm4
-rw-r--r--FS/FS/part_event/Action/cust_bill_send_alternate.pm8
-rw-r--r--FS/FS/part_event/Action/cust_bill_send_csv_ftp.pm12
-rw-r--r--FS/FS/part_event/Action/cust_bill_send_if_newest.pm4
-rw-r--r--FS/FS/part_event/Action/cust_bill_spool_csv.pm12
-rw-r--r--FS/FS/part_event/Action/cust_bill_suspend_if_balance.pm14
-rw-r--r--FS/FS/part_event/Action/fee.pm10
-rw-r--r--FS/FS/part_event/Action/pkg_referral_credit.pm60
-rw-r--r--FS/FS/part_event/Action/pkg_referral_credit_pkg.pm57
-rw-r--r--FS/FS/part_event/Action/suspend.pm10
-rw-r--r--FS/FS/part_event/Action/suspend_if_pkgpart.pm12
-rw-r--r--FS/FS/part_event/Action/suspend_unless_pkgpart.pm12
-rw-r--r--FS/FS/part_event/Condition.pm36
-rw-r--r--FS/FS/part_event/Condition/balance.pm2
-rw-r--r--FS/FS/part_event/Condition/balance_age.pm31
-rw-r--r--FS/FS/part_event/Condition/balance_under.pm2
-rw-r--r--FS/FS/part_event/Condition/cust_bill_age.pm35
-rw-r--r--FS/FS/part_event/Condition/cust_bill_has_service.pm2
-rw-r--r--FS/FS/part_event/Condition/cust_bill_owed.pm2
-rw-r--r--FS/FS/part_event/Condition/cust_bill_owed_under.pm2
-rw-r--r--FS/FS/part_event/Condition/cust_payments.pm43
-rw-r--r--FS/FS/part_event/Condition/has_referral_custnum.pm24
-rw-r--r--FS/FS/part_event/Condition/once_percust.pm67
-rw-r--r--FS/FS/part_event/Condition/pkg_age.pm58
-rw-r--r--FS/FS/part_event/Condition/pkg_notchange.pm31
-rw-r--r--FS/FS/part_event/Condition/pkg_pkgpart.pm39
-rw-r--r--FS/FS/part_event/Condition/pkg_recurring.pm31
-rw-r--r--FS/FS/part_event/Condition/pkg_unless_pkgpart.pm39
40 files changed, 553 insertions, 213 deletions
diff --git a/FS/FS/part_event/Action/addpost.pm b/FS/FS/part_event/Action/addpost.pm
index e0e3fa8..f92e72e 100644
--- a/FS/FS/part_event/Action/addpost.pm
+++ b/FS/FS/part_event/Action/addpost.pm
@@ -3,13 +3,9 @@ package FS::part_event::Action::addpost;
use strict;
use base qw( FS::part_event::Action );
-sub description {
- 'Add postal invoicing';
-}
+sub description { 'Add postal invoicing'; }
-sub default_weight {
- 20;
-}
+sub default_weight { 20; }
sub do_action {
my( $self, $cust_object ) = @_;
diff --git a/FS/FS/part_event/Action/apply.pm b/FS/FS/part_event/Action/apply.pm
index f91c604..823d1e0 100644
--- a/FS/FS/part_event/Action/apply.pm
+++ b/FS/FS/part_event/Action/apply.pm
@@ -7,13 +7,9 @@ sub description {
'Apply unapplied payments and credits';
}
-sub deprecated {
- 1;
-}
+sub deprecated { 1; }
-sub default_weight {
- 70;
-}
+sub default_weight { 70; }
sub do_action {
my( $self, $cust_object ) = @_;
diff --git a/FS/FS/part_event/Action/bill.pm b/FS/FS/part_event/Action/bill.pm
index fec025f..b96614d 100644
--- a/FS/FS/part_event/Action/bill.pm
+++ b/FS/FS/part_event/Action/bill.pm
@@ -8,13 +8,9 @@ sub description {
'Generate invoices (normally only used with a Late Fee event)';
}
-sub deprecated {
- 1;
-}
+sub deprecated { 1; }
-sub default_weight {
- 60;
-}
+sub default_weight { 60; }
sub do_action {
my( $self, $cust_object ) = @_;
diff --git a/FS/FS/part_event/Action/cancel.pm b/FS/FS/part_event/Action/cancel.pm
index 94f3146..b9d6d29 100644
--- a/FS/FS/part_event/Action/cancel.pm
+++ b/FS/FS/part_event/Action/cancel.pm
@@ -3,9 +3,7 @@ package FS::part_event::Action::cancel;
use strict;
use base qw( FS::part_event::Action );
-sub description {
- 'Cancel';
-}
+sub description { 'Cancel'; }
sub option_fields {
(
@@ -14,13 +12,10 @@ sub option_fields {
'reason_class' => 'C',
},
);
-
-};
-
-sub default_weight {
- 20;
}
+sub default_weight { 20; }
+
sub do_action {
my( $self, $cust_object ) = @_;
diff --git a/FS/FS/part_event/Action/collect.pm b/FS/FS/part_event/Action/collect.pm
index fa94b7d..9881440 100644
--- a/FS/FS/part_event/Action/collect.pm
+++ b/FS/FS/part_event/Action/collect.pm
@@ -8,13 +8,9 @@ sub description {
'Collect on invoices (normally only used with a Late Fee and Generate Invoice events)';
}
-sub deprecated {
- 1;
-}
+sub deprecated { 1; }
-sub default_weight {
- 80;
-}
+sub default_weight { 80; }
sub do_action {
my( $self, $cust_object ) = @_;
diff --git a/FS/FS/part_event/Action/cust_bill_batch.pm b/FS/FS/part_event/Action/cust_bill_batch.pm
index aec0925..50c306a 100644
--- a/FS/FS/part_event/Action/cust_bill_batch.pm
+++ b/FS/FS/part_event/Action/cust_bill_batch.pm
@@ -3,21 +3,15 @@ package FS::part_event::Action::cust_bill_batch;
use strict;
use base qw( FS::part_event::Action );
-sub description {
- 'Add card or check to a pending batch';
-}
+sub description { 'Add card or check to a pending batch'; }
-sub deprecated {
- 1;
-}
+sub deprecated { 1; }
sub eventtable_hashref {
{ 'cust_bill' => 1 };
}
-sub default_weight {
- 40;
-}
+sub default_weight { 40; }
sub do_action {
my( $self, $cust_bill ) = @_;
diff --git a/FS/FS/part_event/Action/cust_bill_comp.pm b/FS/FS/part_event/Action/cust_bill_comp.pm
index 636a66d..76fd274 100644
--- a/FS/FS/part_event/Action/cust_bill_comp.pm
+++ b/FS/FS/part_event/Action/cust_bill_comp.pm
@@ -3,21 +3,15 @@ package FS::part_event::Action::cust_bill_comp;
use strict;
use base qw( FS::part_event::Action );
-sub description {
- 'Pay invoice with a complimentary "payment"';
-}
+sub description { 'Pay invoice with a complimentary "payment"'; }
-sub deprecated {
- 1;
-}
+sub deprecated { 1; }
sub eventtable_hashref {
{ 'cust_bill' => 1 };
}
-sub default_weight {
- 30;
-}
+sub default_weight { 30; }
sub do_action {
my( $self, $cust_bill ) = @_;
diff --git a/FS/FS/part_event/Action/cust_bill_fee_percent.pm b/FS/FS/part_event/Action/cust_bill_fee_percent.pm
index 100fc8b..570fd63 100644
--- a/FS/FS/part_event/Action/cust_bill_fee_percent.pm
+++ b/FS/FS/part_event/Action/cust_bill_fee_percent.pm
@@ -3,9 +3,7 @@ package FS::part_event::Action::cust_bill_fee_percent;
use strict;
use base qw( FS::part_event::Action );
-sub description {
- 'Late fee (percentage of invoice)';
-}
+sub description { 'Late fee (percentage of invoice)'; }
sub eventtable_hashref {
{ 'cust_bill' => 1 };
@@ -18,9 +16,7 @@ sub option_fields {
);
}
-sub default_weight {
- 10;
-}
+sub default_weight { 10; }
sub do_action {
my( $self, $cust_bill ) = @_;
diff --git a/FS/FS/part_event/Action/cust_bill_realtime_card.pm b/FS/FS/part_event/Action/cust_bill_realtime_card.pm
index 471c946..c1fdba9 100644
--- a/FS/FS/part_event/Action/cust_bill_realtime_card.pm
+++ b/FS/FS/part_event/Action/cust_bill_realtime_card.pm
@@ -8,17 +8,13 @@ sub description {
'Run card with a Business::OnlinePayment realtime gateway';
}
-sub deprecated {
- 1;
-}
+sub deprecated { 1; }
sub eventtable_hashref {
{ 'cust_bill' => 1 };
}
-sub default_weight {
- 30;
-}
+sub default_weight { 30; }
sub do_action {
my( $self, $cust_bill ) = @_;
diff --git a/FS/FS/part_event/Action/cust_bill_realtime_check.pm b/FS/FS/part_event/Action/cust_bill_realtime_check.pm
index 9a52830..11b13a9 100644
--- a/FS/FS/part_event/Action/cust_bill_realtime_check.pm
+++ b/FS/FS/part_event/Action/cust_bill_realtime_check.pm
@@ -8,17 +8,13 @@ sub description {
'Run check with a Business::OnlinePayment realtime gateway';
}
-sub deprecated {
- 1;
-}
+sub deprecated { 1; }
sub eventtable_hashref {
{ 'cust_bill' => 1 };
}
-sub default_weight {
- 30;
-}
+sub default_weight { 30; }
sub do_action {
my( $self, $cust_bill ) = @_;
diff --git a/FS/FS/part_event/Action/cust_bill_realtime_lec.pm b/FS/FS/part_event/Action/cust_bill_realtime_lec.pm
index db091da..cd03ddc 100644
--- a/FS/FS/part_event/Action/cust_bill_realtime_lec.pm
+++ b/FS/FS/part_event/Action/cust_bill_realtime_lec.pm
@@ -8,17 +8,13 @@ sub description {
'Run phone bill ("LEC") billing with a Business::OnlinePayment realtime gateway';
}
-sub deprecated {
- 1;
-}
+sub deprecated { 1; }
sub eventtable_hashref {
{ 'cust_bill' => 1 };
}
-sub default_weight {
- 30;
-}
+sub default_weight { 30; }
sub do_action {
my( $self, $cust_bill ) = @_;
diff --git a/FS/FS/part_event/Action/cust_bill_send.pm b/FS/FS/part_event/Action/cust_bill_send.pm
index 9330c61..663caf1 100644
--- a/FS/FS/part_event/Action/cust_bill_send.pm
+++ b/FS/FS/part_event/Action/cust_bill_send.pm
@@ -3,17 +3,13 @@ package FS::part_event::Action::cust_bill_send;
use strict;
use base qw( FS::part_event::Action );
-sub description {
- 'Send invoice (email/print/fax)';
-}
+sub description { 'Send invoice (email/print/fax)'; }
sub eventtable_hashref {
{ 'cust_bill' => 1 };
}
-sub default_weight {
- 50;
-}
+sub default_weight { 50; }
sub do_action {
my( $self, $cust_bill ) = @_;
diff --git a/FS/FS/part_event/Action/cust_bill_send_agent.pm b/FS/FS/part_event/Action/cust_bill_send_agent.pm
index fcf0007..670a32c 100644
--- a/FS/FS/part_event/Action/cust_bill_send_agent.pm
+++ b/FS/FS/part_event/Action/cust_bill_send_agent.pm
@@ -24,9 +24,7 @@ sub option_fields {
);
}
-sub default_weight {
- 50;
-}
+sub default_weight { 50; }
sub do_action {
my( $self, $cust_bill ) = @_;
diff --git a/FS/FS/part_event/Action/cust_bill_send_alternate.pm b/FS/FS/part_event/Action/cust_bill_send_alternate.pm
index 6afb89a..cfd9264 100644
--- a/FS/FS/part_event/Action/cust_bill_send_alternate.pm
+++ b/FS/FS/part_event/Action/cust_bill_send_alternate.pm
@@ -3,9 +3,7 @@ package FS::part_event::Action::cust_bill_send_alternate;
use strict;
use base qw( FS::part_event::Action );
-sub description {
- 'Send invoice (email/print/fax) with alternate template';
-}
+sub description { 'Send invoice (email/print/fax) with alternate template'; }
sub eventtable_hashref {
{ 'cust_bill' => 1 };
@@ -19,9 +17,7 @@ sub option_fields {
);
}
-sub default_weight {
- 50;
-}
+sub default_weight { 50; }
sub do_action {
my( $self, $cust_bill ) = @_;
diff --git a/FS/FS/part_event/Action/cust_bill_send_csv_ftp.pm b/FS/FS/part_event/Action/cust_bill_send_csv_ftp.pm
index db3554e..bf47268 100644
--- a/FS/FS/part_event/Action/cust_bill_send_csv_ftp.pm
+++ b/FS/FS/part_event/Action/cust_bill_send_csv_ftp.pm
@@ -3,13 +3,9 @@ package FS::part_event::Action::cust_bill_send_csv_ftp;
use strict;
use base qw( FS::part_event::Action );
-sub description {
- 'Upload CSV invoice data to an FTP server';
-}
+sub description { 'Upload CSV invoice data to an FTP server'; }
-sub deprecated {
- 1;
-}
+sub deprecated { 1; }
sub eventtable_hashref {
{ 'cust_bill' => 1 };
@@ -31,9 +27,7 @@ sub option_fields {
);
}
-sub default_weight {
- 50;
-}
+sub default_weight { 50; }
sub do_action {
my( $self, $cust_bill ) = @_;
diff --git a/FS/FS/part_event/Action/cust_bill_send_if_newest.pm b/FS/FS/part_event/Action/cust_bill_send_if_newest.pm
index 916983e..083da8b 100644
--- a/FS/FS/part_event/Action/cust_bill_send_if_newest.pm
+++ b/FS/FS/part_event/Action/cust_bill_send_if_newest.pm
@@ -24,9 +24,7 @@ sub option_fields {
);
}
-sub default_weight {
- 50;
-}
+sub default_weight { 50; }
sub do_action {
my( $self, $cust_bill ) = @_;
diff --git a/FS/FS/part_event/Action/cust_bill_spool_csv.pm b/FS/FS/part_event/Action/cust_bill_spool_csv.pm
index 4300b61..f20ee46 100644
--- a/FS/FS/part_event/Action/cust_bill_spool_csv.pm
+++ b/FS/FS/part_event/Action/cust_bill_spool_csv.pm
@@ -3,13 +3,9 @@ package FS::part_event::Action::cust_bill_spool_csv;
use strict;
use base qw( FS::part_event::Action );
-sub description {
- 'Spool CSV invoice data';
-}
+sub description { 'Spool CSV invoice data'; }
-sub deprecated {
- 1;
-}
+sub deprecated { 1; }
sub eventtable_hashref {
{ 'cust_bill' => 1 };
@@ -43,9 +39,7 @@ sub option_fields {
);
}
-sub default_weight {
- 50;
-}
+sub default_weight { 50; }
sub do_action {
my( $self, $cust_bill ) = @_;
diff --git a/FS/FS/part_event/Action/cust_bill_suspend_if_balance.pm b/FS/FS/part_event/Action/cust_bill_suspend_if_balance.pm
index 6559949..13188ab 100644
--- a/FS/FS/part_event/Action/cust_bill_suspend_if_balance.pm
+++ b/FS/FS/part_event/Action/cust_bill_suspend_if_balance.pm
@@ -3,13 +3,9 @@ package FS::part_event::Action::cust_bill_suspend_if_balance;
use strict;
use base qw( FS::part_event::Action );
-sub description {
- 'Suspend if balance (this invoice and previous) over';
-}
+sub description { 'Suspend if balance (this invoice and previous) over'; }
-sub deprecated {
- 1;
-}
+sub deprecated { 1; }
sub eventtable_hashref {
{ 'cust_bill' => 1 };
@@ -23,12 +19,10 @@ sub option_fields {
'reason_class' => 'S',
},
);
-};
-
-sub default_weight {
- 10;
}
+sub default_weight { 10; }
+
sub do_action {
my( $self, $cust_bill ) = @_;
diff --git a/FS/FS/part_event/Action/fee.pm b/FS/FS/part_event/Action/fee.pm
index 81a8449..3cf50fb 100644
--- a/FS/FS/part_event/Action/fee.pm
+++ b/FS/FS/part_event/Action/fee.pm
@@ -3,21 +3,17 @@ package FS::part_event::Action::fee;
use strict;
use base qw( FS::part_event::Action );
-sub description {
- 'Late fee (flat)';
-}
+sub description { 'Late fee (flat)'; }
sub option_fields {
(
'charge' => { label=>'Amount', type=>'money', }, # size=>7, },
'reason' => 'Reason',
);
-};
-
-sub default_weight {
- 10;
}
+sub default_weight { 10; }
+
sub do_action {
my( $self, $cust_object ) = @_;
diff --git a/FS/FS/part_event/Action/pkg_referral_credit.pm b/FS/FS/part_event/Action/pkg_referral_credit.pm
new file mode 100644
index 0000000..98d9820
--- /dev/null
+++ b/FS/FS/part_event/Action/pkg_referral_credit.pm
@@ -0,0 +1,60 @@
+package FS::part_event::Action::pkg_referral_credit;
+
+use strict;
+use base qw( FS::part_event::Action );
+
+sub description { 'Credit the referring customer a specific amount'; }
+
+sub eventtable_hashref {
+ { 'cust_pkg' => 1 };
+}
+
+sub option_fields {
+ (
+ 'reasonnum' => { 'label' => 'Credit reason',
+ 'type' => 'select-reason',
+ 'reason_class' => 'R',
+ },
+ 'amount' => { 'label' => 'Credit amount',
+ 'type' => 'money',
+ },
+ );
+
+}
+
+#a little false laziness w/pkg_referral_credit_pkg
+sub do_action {
+ my( $self, $cust_pkg ) = @_;
+
+ my $cust_main = $self->cust_main($cust_pkg);
+
+# my $part_pkg = $cust_pkg->part_pkg;
+
+ return 'No referring customer' unless $cust_main->referral_custnum;
+
+ my $referring_cust_main = $cust_main->referring_cust_main;
+ return 'Referring customer is cancelled'
+ if $referring_cust_main->status eq 'cancelled';
+
+ my $amount = $self->_calc_referral_credit($cust_pkg);
+ my $reasonnum = $self->option('reasonnum');
+
+ my $error = $referring_cust_main->credit(
+ $amount,
+ \$reasonnum,
+ 'addlinfo' =>
+ 'for customer #'. $cust_main->display_custnum. ': '.$cust_main->name,
+ );
+ die "Error crediting customer ". $cust_main->referral_custnum.
+ " for referral: $error"
+ if $error;
+
+}
+
+sub _calc_referral_credit {
+ my( $self, $cust_pkg ) = @_;
+
+ $self->option('amount');
+}
+
+1;
diff --git a/FS/FS/part_event/Action/pkg_referral_credit_pkg.pm b/FS/FS/part_event/Action/pkg_referral_credit_pkg.pm
new file mode 100644
index 0000000..08cf9a8
--- /dev/null
+++ b/FS/FS/part_event/Action/pkg_referral_credit_pkg.pm
@@ -0,0 +1,57 @@
+package FS::part_event::Action::pkg_referral_credit_pkg;
+
+use strict;
+use base qw( FS::part_event::Action::pkg_referral_credit );
+
+sub description { 'Credit the referring customer an amount based on the referred package'; }
+
+#sub eventtable_hashref {
+# { 'cust_pkg' => 1 };
+#}
+
+sub option_fields {
+ (
+ 'reasonnum' => { 'label' => 'Credit reason',
+ 'type' => 'select-reason',
+ 'reason_class' => 'R',
+ },
+ 'percent' => { 'label' => 'Percent',
+ 'type' => 'input-percentage',
+ 'default' => '100',
+ },
+ 'what' => { 'label' => 'Of',
+ 'type' => 'select',
+ #also add some way to specify in the package def, no?
+ 'options' => [ qw( base_recur_permonth ) ],
+ 'labels' => { 'base_recur_permonth' => 'Base monthly fee', },
+ },
+ );
+
+}
+
+sub _calc_referral_credit {
+ my( $self, $cust_pkg ) = @_;
+
+ my $cust_main = $self->cust_main($cust_pkg);
+
+ my $part_pkg = $cust_pkg->part_pkg;
+
+ my $what = $self->option('what');
+
+ if ( $what eq 'base_recur_permonth' ) { #huh. yuck.
+ if ( $part_pkg->freq !~ /^\d+$/ ) {
+ die 'WARNING: Not crediting customer '. $cust_main->referral_custnum.
+ ' for package '. $cust_pkg->pkgnum.
+ ' ( customer '. $cust_pkg->custnum. ')'.
+ ' - Referral credits not (yet) available for '.
+ ' packages with '. $part_pkg->freq_pretty. ' frequency';
+ }
+ }
+
+ my $percent = $self->option('percent');
+
+ sprintf('%.2f', $part_pkg->$what($cust_pkg) * $percent / 100 );
+
+}
+
+1;
diff --git a/FS/FS/part_event/Action/suspend.pm b/FS/FS/part_event/Action/suspend.pm
index ec440ff..c77728e 100644
--- a/FS/FS/part_event/Action/suspend.pm
+++ b/FS/FS/part_event/Action/suspend.pm
@@ -3,9 +3,7 @@ package FS::part_event::Action::suspend;
use strict;
use base qw( FS::part_event::Action );
-sub description {
- 'Suspend';
-}
+sub description { 'Suspend'; }
sub option_fields {
(
@@ -14,12 +12,10 @@ sub option_fields {
'reason_class' => 'S',
},
);
-};
-
-sub default_weight {
- 10;
}
+sub default_weight { 10; }
+
sub do_action {
my( $self, $cust_object ) = @_;
diff --git a/FS/FS/part_event/Action/suspend_if_pkgpart.pm b/FS/FS/part_event/Action/suspend_if_pkgpart.pm
index 9bdc9be..6f2007c 100644
--- a/FS/FS/part_event/Action/suspend_if_pkgpart.pm
+++ b/FS/FS/part_event/Action/suspend_if_pkgpart.pm
@@ -3,9 +3,9 @@ package FS::part_event::Action::suspend_if_pkgpart;
use strict;
use base qw( FS::part_event::Action );
-sub description {
- 'Suspend packages';
-}
+sub description { 'Suspend packages'; }
+
+#i should be deprecated in favor of using the if_pkgpart condition
sub option_fields {
(
@@ -18,12 +18,10 @@ sub option_fields {
'reason_class' => 'S',
},
);
-};
-
-sub default_weight {
- 10;
}
+sub default_weight { 10; }
+
sub do_action {
my( $self, $cust_object ) = @_;
diff --git a/FS/FS/part_event/Action/suspend_unless_pkgpart.pm b/FS/FS/part_event/Action/suspend_unless_pkgpart.pm
index f9bf1e8..efc7a2d 100644
--- a/FS/FS/part_event/Action/suspend_unless_pkgpart.pm
+++ b/FS/FS/part_event/Action/suspend_unless_pkgpart.pm
@@ -3,9 +3,9 @@ package FS::part_event::Action::suspend_unless_pkgpart;
use strict;
use base qw( FS::part_event::Action );
-sub description {
- 'Suspend packages except';
-}
+sub description { 'Suspend packages except'; }
+
+#i should be deprecated in favor of using the unless_pkgpart condition
sub option_fields {
(
@@ -18,12 +18,10 @@ sub option_fields {
'reason_class' => 'S',
},
);
-};
-
-sub default_weight {
- 10;
}
+sub default_weight { 10; }
+
sub do_action {
my( $self, $cust_object ) = @_;
diff --git a/FS/FS/part_event/Condition.pm b/FS/FS/part_event/Condition.pm
index 2b71fbb..544b560 100644
--- a/FS/FS/part_event/Condition.pm
+++ b/FS/FS/part_event/Condition.pm
@@ -2,7 +2,7 @@ package FS::part_event::Condition;
use strict;
use base qw( FS::part_event_condition );
-
+use Time::Local qw(timelocal_nocheck);
use FS::UID qw( driver_name );
=head1 NAME
@@ -251,6 +251,40 @@ sub option_label {
=back
+=item option_age_from OPTION FROM_TIMESTAMP
+
+Retreives a condition option, parses it from a frequency (such as "1d", "1w" or
+"12m"), and subtracts that interval from the supplied timestamp. It is
+primarily intended for use in B<condition>.
+
+=cut
+
+sub option_age_from {
+ my( $self, $option, $time ) = @_;
+ my $age = $self->option($option);
+ $age = '0m' unless length($age);
+
+ my ($sec,$min,$hour,$mday,$mon,$year) = (localtime($time) )[0,1,2,3,4,5];
+
+ if ( $age =~ /^(\d+)m$/i ) {
+ $mon -= $1;
+ until ( $mon >= 0 ) { $mon += 12; $year--; }
+ } elsif ( $age =~ /^(\d+)y$/i ) {
+ $year -= $1;
+ } elsif ( $age =~ /^(\d+)w$/i ) {
+ $mday -= $1 * 7;
+ } elsif ( $age =~ /^(\d+)d$/i ) {
+ $mday -= $1;
+ } elsif ( $age =~ /^(\d+)h$/i ) {
+ $hour -= $hour;
+ } else {
+ die "unparsable age: $age";
+ }
+
+ timelocal_nocheck($sec,$min,$hour,$mday,$mon,$year);
+
+}
+
=item condition_sql_option OPTION
This is a class method that returns an SQL fragment for retreiving a condition
diff --git a/FS/FS/part_event/Condition/balance.pm b/FS/FS/part_event/Condition/balance.pm
index 2639413..65670c0 100644
--- a/FS/FS/part_event/Condition/balance.pm
+++ b/FS/FS/part_event/Condition/balance.pm
@@ -40,7 +40,7 @@ sub condition_sql {
my $balance_sql = FS::cust_main->balance_sql;
- "$balance_sql > $over";
+ "$balance_sql > CAST( $over AS numeric )";
}
diff --git a/FS/FS/part_event/Condition/balance_age.pm b/FS/FS/part_event/Condition/balance_age.pm
index ec3624a..f1a9707 100644
--- a/FS/FS/part_event/Condition/balance_age.pm
+++ b/FS/FS/part_event/Condition/balance_age.pm
@@ -1,9 +1,6 @@
package FS::part_event::Condition::balance_age;
-require 5.006;
use strict;
-use Time::Local qw(timelocal_nocheck);
-
use base qw( FS::part_event::Condition );
sub description { 'Customer balance age'; }
@@ -28,29 +25,9 @@ sub condition {
my $over = $self->option('balance');
$over = 0 unless length($over);
- #false laziness w/cust_bill_age
- my $time = $opt{'time'};
- my $age = $self->option('age');
- $age = '0m' unless length($age);
-
- my ($sec,$min,$hour,$mday,$mon,$year) = (localtime($time) )[0,1,2,3,4,5];
- if ( $age =~ /^(\d+)m$/i ) {
- $mon -= $1;
- until ( $mon >= 0 ) { $mon += 12; $year--; }
- } elsif ( $age =~ /^(\d+)y$/i ) {
- $year -= $1;
- } elsif ( $age =~ /^(\d+)w$/i ) {
- $mday -= $1 * 7;
- } elsif ( $age =~ /^(\d+)d$/i ) {
- $mday -= $1;
- } elsif ( $age =~ /^(\d+)h$/i ) {
- $hour -= $hour;
- } else {
- die "unparsable age: $age";
- }
- my $age_date = timelocal_nocheck($sec,$min,$hour,$mday,$mon,$year);
-
- $cust_main->balance_date($age_date) > $over;
+ my $age = $self->option_age_from('age', $opt{'time'} );
+
+ $cust_main->balance_date($age) > $over;
}
sub condition_sql {
@@ -61,7 +38,7 @@ sub condition_sql {
my $balance_sql = FS::cust_main->balance_date_sql( $age );
- "$balance_sql > $over";
+ "$balance_sql > CAST( $over AS numeric )";
}
sub order_sql {
diff --git a/FS/FS/part_event/Condition/balance_under.pm b/FS/FS/part_event/Condition/balance_under.pm
index 5e19034..9c71590 100644
--- a/FS/FS/part_event/Condition/balance_under.pm
+++ b/FS/FS/part_event/Condition/balance_under.pm
@@ -34,7 +34,7 @@ sub condition_sql {
my $balance_sql = FS::cust_main->balance_sql;
- "$balance_sql <= $under";
+ "$balance_sql <= CAST( $under AS numeric )";
}
diff --git a/FS/FS/part_event/Condition/cust_bill_age.pm b/FS/FS/part_event/Condition/cust_bill_age.pm
index 5c1e468..f343673 100644
--- a/FS/FS/part_event/Condition/cust_bill_age.pm
+++ b/FS/FS/part_event/Condition/cust_bill_age.pm
@@ -1,14 +1,9 @@
package FS::part_event::Condition::cust_bill_age;
-require 5.006;
use strict;
-use Time::Local qw(timelocal_nocheck);
-
use base qw( FS::part_event::Condition );
-sub description {
- 'Invoice age';
-}
+sub description { 'Invoice age'; }
sub eventtable_hashref {
{ 'cust_main' => 0,
@@ -17,10 +12,8 @@ sub eventtable_hashref {
};
}
-#something like this
sub option_fields {
(
- #'days' => { label=>'Days', size=>3, },
'age' => { label=>'Age', type=>'freq', },
);
}
@@ -28,34 +21,12 @@ sub option_fields {
sub condition {
my( $self, $cust_bill, %opt ) = @_;
- #false laziness w/balance_age
- my $time = $opt{'time'};
- my $age = $self->option('age');
- $age = '0m' unless length($age);
+ my $age = $self->option_age_from('age', $opt{'time'} );
- my ($sec,$min,$hour,$mday,$mon,$year) = (localtime($time) )[0,1,2,3,4,5];
- if ( $age =~ /^(\d+)m$/i ) {
- $mon -= $1;
- until ( $mon >= 0 ) { $mon += 12; $year--; }
- } elsif ( $age =~ /^(\d+)y$/i ) {
- $year -= $1;
- } elsif ( $age =~ /^(\d+)w$/i ) {
- $mday -= $1 * 7;
- } elsif ( $age =~ /^(\d+)d$/i ) {
- $mday -= $1;
- } elsif ( $age =~ /^(\d+)h$/i ) {
- $hour -= $hour;
- } else {
- die "unparsable age: $age";
- }
- my $age_date = timelocal_nocheck($sec,$min,$hour,$mday,$mon,$year);
-
- $cust_bill->_date <= $age_date;
+ $cust_bill->_date <= $age;
}
-# and seconds <= $time - cust_bill._date
-
sub condition_sql {
my( $class, $table, %opt ) = @_;
diff --git a/FS/FS/part_event/Condition/cust_bill_has_service.pm b/FS/FS/part_event/Condition/cust_bill_has_service.pm
index 7e63e0e..91d75dd 100644
--- a/FS/FS/part_event/Condition/cust_bill_has_service.pm
+++ b/FS/FS/part_event/Condition/cust_bill_has_service.pm
@@ -45,7 +45,7 @@ sub condition_sql {
FROM cust_bill_pkg cbp, cust_svc cs
WHERE cbp.invnum = cust_bill.invnum
AND cs.pkgnum = cbp.pkgnum
- AND cs.svcpart = $servicenum
+ AND cs.svcpart = CAST( $servicenum AS integer )
)
|;
return $sql;
diff --git a/FS/FS/part_event/Condition/cust_bill_owed.pm b/FS/FS/part_event/Condition/cust_bill_owed.pm
index 5e582ef..0fd9922 100644
--- a/FS/FS/part_event/Condition/cust_bill_owed.pm
+++ b/FS/FS/part_event/Condition/cust_bill_owed.pm
@@ -48,7 +48,7 @@ sub condition_sql {
my $owed_sql = FS::cust_bill->owed_sql;
- "$owed_sql > $over";
+ "$owed_sql > CAST( $over AS numeric )";
}
1;
diff --git a/FS/FS/part_event/Condition/cust_bill_owed_under.pm b/FS/FS/part_event/Condition/cust_bill_owed_under.pm
index 460e6a4..a0bf92f 100644
--- a/FS/FS/part_event/Condition/cust_bill_owed_under.pm
+++ b/FS/FS/part_event/Condition/cust_bill_owed_under.pm
@@ -43,7 +43,7 @@ sub condition_sql {
my $owed_sql = FS::cust_bill->owed_sql;
- "$owed_sql <= $under";
+ "$owed_sql <= CAST( $under AS numeric )";
}
1;
diff --git a/FS/FS/part_event/Condition/cust_payments.pm b/FS/FS/part_event/Condition/cust_payments.pm
new file mode 100644
index 0000000..41ef6c7
--- /dev/null
+++ b/FS/FS/part_event/Condition/cust_payments.pm
@@ -0,0 +1,43 @@
+package FS::part_event::Condition::cust_payments;
+
+use strict;
+use base qw( FS::part_event::Condition );
+
+sub description { 'Customer total payments'; }
+
+sub option_fields {
+ (
+ 'over' => { 'label' => 'Customer total payments at least',
+ 'type' => 'money',
+ 'value' => '0.00', #default
+ },
+ );
+}
+
+sub condition {
+ my($self, $object) = @_;
+
+ my $cust_main = $self->cust_main($object);
+
+ my $over = $self->option('over');
+ $over = 0 unless length($over);
+
+ $cust_main->total_paid >= $over;
+
+}
+
+#XXX add for efficiency. could use cust_main::total_paid_sql
+#use FS::cust_main;
+#sub condition_sql {
+# my( $class, $table ) = @_;
+#
+# my $over = $class->condition_sql_option('balance');
+#
+# my $balance_sql = FS::cust_main->balance_sql;
+#
+# "$balance_sql > $over";
+#
+#}
+
+1;
+
diff --git a/FS/FS/part_event/Condition/has_referral_custnum.pm b/FS/FS/part_event/Condition/has_referral_custnum.pm
new file mode 100644
index 0000000..d43d6c0
--- /dev/null
+++ b/FS/FS/part_event/Condition/has_referral_custnum.pm
@@ -0,0 +1,24 @@
+package FS::part_event::Condition::has_referral_custnum;
+
+use strict;
+use FS::cust_main;
+
+use base qw( FS::part_event::Condition );
+
+sub description { 'Customer has a referring customer'; }
+
+sub condition {
+ my($self, $object) = @_;
+
+ my $cust_main = $self->cust_main($object);
+
+ $cust_main->referral_custnum;
+}
+
+sub condition_sql {
+ #my( $class, $table ) = @_;
+
+ "cust_main.referral_custnum IS NOT NULL";
+}
+
+1;
diff --git a/FS/FS/part_event/Condition/once_percust.pm b/FS/FS/part_event/Condition/once_percust.pm
new file mode 100644
index 0000000..b8a8fbf
--- /dev/null
+++ b/FS/FS/part_event/Condition/once_percust.pm
@@ -0,0 +1,67 @@
+package FS::part_event::Condition::once_percust;
+
+use strict;
+use FS::Record qw( qsearch );
+use FS::part_event;
+use FS::cust_event;
+
+use base qw( FS::part_event::Condition );
+
+sub description { "Don't run more than once per customer"; }
+
+sub eventtable_hashref {
+ { 'cust_main' => 0,
+ 'cust_bill' => 1,
+ 'cust_pkg' => 1,
+ };
+}
+
+sub condition {
+ my($self, $object, %opt) = @_;
+
+ my $obj_pkey = $object->primary_key;
+ my $obj_table = $object->table;
+ my $custnum = $object->custnum;
+
+ my @where = (
+ "tablenum IN ( SELECT $obj_pkey FROM $obj_table WHERE custnum = $custnum )"
+ );
+ if ( $opt{'cust_event'}->eventnum =~ /^(\d+)$/ ) {
+ push @where, " eventnum != $1 ";
+ }
+ my $extra_sql = ' AND '. join(' AND ', @where);
+
+ my @existing = qsearch( {
+ 'table' => 'cust_event',
+ 'hashref' => {
+ 'eventpart' => $self->eventpart,
+ #'tablenum' => $tablenum,
+ 'status' => { op=>'!=', value=>'failed' },
+ },
+ 'extra_sql' => $extra_sql,
+ } );
+
+ ! scalar(@existing);
+
+}
+
+#XXX test?
+sub condition_sql {
+ my( $self, $table ) = @_;
+
+ my %pkey = %{ FS::part_event->eventtable_pkey };
+
+ my $pkey = $pkey{$table};
+
+ "0 = ( SELECT COUNT(*) FROM cust_event
+ WHERE cust_event.eventpart = part_event.eventpart
+ AND cust_event.tablenum IN (
+ SELECT $pkey FROM $table AS once_percust
+ WHERE once_percust.custnum = cust_main.custnum )
+ AND status != 'failed'
+ )
+ ";
+
+}
+
+1;
diff --git a/FS/FS/part_event/Condition/pkg_age.pm b/FS/FS/part_event/Condition/pkg_age.pm
new file mode 100644
index 0000000..8b3b4c9
--- /dev/null
+++ b/FS/FS/part_event/Condition/pkg_age.pm
@@ -0,0 +1,58 @@
+package FS::part_event::Condition::pkg_age;
+
+use strict;
+use base qw( FS::part_event::Condition );
+use FS::Record qw( qsearch );
+
+sub description {
+ 'Package Age';
+}
+
+sub eventtable_hashref {
+ { 'cust_main' => 0,
+ 'cust_bill' => 0,
+ 'cust_pkg' => 1,
+ };
+}
+
+#something like this
+sub option_fields {
+ (
+ 'age' => { 'label' => 'Package date age',
+ 'type' => 'freq',
+ },
+ 'field' => { 'label' => 'Compare date',
+ 'type' => 'select',
+ 'options' =>
+ [qw( setup last_bill bill adjourn susp expire cancel )],
+ 'labels' => {
+ 'setup' => 'Setup date',
+ 'last_bill' => 'Last bill date',
+ 'bill' => 'Next bill date',
+ 'adjourn' => 'Adjournment date',
+ 'susp' => 'Suspension date',
+ 'expire' => 'Expiration date',
+ 'cancel' => 'Cancellation date',
+ },
+ },
+ );
+}
+
+sub condition {
+ my( $self, $cust_pkg, %opt ) = @_;
+
+ my $age = $self->option_age_from('age', $opt{'time'} );
+
+ my $pkg_date = $cust_pkg->get( $self->option('field') );
+
+ $pkg_date && $pkg_date <= $age;
+
+}
+
+#XXX write me for efficiency
+#sub condition_sql {
+#
+#}
+
+1;
+
diff --git a/FS/FS/part_event/Condition/pkg_notchange.pm b/FS/FS/part_event/Condition/pkg_notchange.pm
new file mode 100644
index 0000000..4c103c2
--- /dev/null
+++ b/FS/FS/part_event/Condition/pkg_notchange.pm
@@ -0,0 +1,31 @@
+package FS::part_event::Condition::pkg_notchange;
+
+use strict;
+
+use base qw( FS::part_event::Condition );
+use FS::Record qw( qsearch );
+
+sub description {
+ 'Package is a new order, not a change';
+}
+
+sub eventtable_hashref {
+ { 'cust_main' => 0,
+ 'cust_bill' => 0,
+ 'cust_pkg' => 1,
+ };
+}
+
+sub condition {
+ my( $self, $cust_pkg ) = @_;
+
+ ! $cust_pkg->change_date;
+
+}
+
+sub condition_sql {
+ '( cust_pkg.change_date IS NULL OR cust_pkg.change_date = 0 )';
+}
+
+1;
+
diff --git a/FS/FS/part_event/Condition/pkg_pkgpart.pm b/FS/FS/part_event/Condition/pkg_pkgpart.pm
new file mode 100644
index 0000000..6adef8e
--- /dev/null
+++ b/FS/FS/part_event/Condition/pkg_pkgpart.pm
@@ -0,0 +1,39 @@
+package FS::part_event::Condition::pkg_pkgpart;
+
+use strict;
+
+use base qw( FS::part_event::Condition );
+
+sub description { 'Package definitions'; }
+
+sub eventtable_hashref {
+ { 'cust_main' => 0,
+ 'cust_bill' => 0,
+ 'cust_pkg' => 1,
+ };
+}
+
+sub option_fields {
+ (
+ 'if_pkgpart' => { 'label' => 'Only packages: ',
+ 'type' => 'select-part_pkg',
+ 'multiple' => 1,
+ },
+ );
+}
+
+sub condition {
+ my( $self, $cust_pkg) = @_;
+
+ #XXX test
+ my $if_pkgpart = $self->option('if_pkgpart') || {};
+ $if_pkgpart->{ $cust_pkg->pkgpart };
+
+}
+
+#XXX
+#sub condition_sql {
+#
+#}
+
+1;
diff --git a/FS/FS/part_event/Condition/pkg_recurring.pm b/FS/FS/part_event/Condition/pkg_recurring.pm
new file mode 100644
index 0000000..1b66821
--- /dev/null
+++ b/FS/FS/part_event/Condition/pkg_recurring.pm
@@ -0,0 +1,31 @@
+package FS::part_event::Condition::pkg_recurring;
+
+use strict;
+
+use base qw( FS::part_event::Condition );
+
+sub description { 'Package is recurring'; }
+
+sub eventtable_hashref {
+ { 'cust_main' => 0,
+ 'cust_bill' => 0,
+ 'cust_pkg' => 1,
+ };
+}
+
+sub condition {
+ my( $self, $cust_pkg ) = @_;
+
+ $cust_pkg->part_pkg->freq !~ /^0+\D?$/; #just in case, probably just != '0'
+
+}
+
+
+#XXX join part_pkg USING (pkgpart)
+# part_pkg.freq != '0'
+#sub condition_sql {
+#
+#}
+
+1;
+
diff --git a/FS/FS/part_event/Condition/pkg_unless_pkgpart.pm b/FS/FS/part_event/Condition/pkg_unless_pkgpart.pm
new file mode 100644
index 0000000..47fa8c3
--- /dev/null
+++ b/FS/FS/part_event/Condition/pkg_unless_pkgpart.pm
@@ -0,0 +1,39 @@
+package FS::part_event::Condition::pkg_unless_pkgpart;
+
+use strict;
+
+use base qw( FS::part_event::Condition );
+
+sub description { 'Except package definitions'; }
+
+sub eventtable_hashref {
+ { 'cust_main' => 0,
+ 'cust_bill' => 0,
+ 'cust_pkg' => 1,
+ };
+}
+
+sub option_fields {
+ (
+ 'unless_pkgpart' => { 'label' => 'Except packages: ',
+ 'type' => 'select-part_pkg',
+ 'multiple' => 1,
+ },
+ );
+}
+
+sub condition {
+ my( $self, $cust_pkg) = @_;
+
+ #XXX test
+ my $unless_pkgpart = $self->option('unless_pkgpart') || {};
+ ! $unless_pkgpart->{ $cust_pkg->pkgpart };
+
+}
+
+#XXX
+#sub condition_sql {
+#
+#}
+
+1;