package NGCP::Panel::Role::API::CustomerFraudEvents; use NGCP::Panel::Utils::Generic qw(:all); use Sipwise::Base; use parent 'NGCP::Panel::Role::API'; use boolean qw(true); use Data::HAL qw(); use Data::HAL::Link qw(); use HTTP::Status qw(:constants); use NGCP::Panel::Utils::BillingMappings qw(); use NGCP::Panel::Utils::DateTime qw(); use DateTime::Format::Strptime qw(); sub _item_rs { my ($self, $c, $id) = @_; my %cond = (); if ($c->user->roles eq "admin" || $c->user->roles eq "ccareadmin") { if (my $reseller_id = $c->request->param('reseller_id')) { $cond{'contact.reseller_id'} = $reseller_id; } } elsif ($c->user->roles eq "reseller" || $c->user->roles eq "ccare") { $cond{'contact.reseller_id'} = $c->user->reseller_id; } if (my $contract_id = $c->request->param('contract_id')) { $cond{'me.contract_id'} = $contract_id; } if (my $notify_status = $c->request->param('notify_status')) { $cond{'notify_status'} = $notify_status; } if ($id) { $cond{'me.id'} = $id; } my $attr = { join => { 'contract' => 'contact' }, }; my $dtf = $c->model('DB')->storage->datetime_parser; my $now; my $datetime_fmt = DateTime::Format::Strptime->new( pattern => '%Y-%m-%d', ); unless ($now = $datetime_fmt->parse_datetime($c->request->param('date'))) { $now = NGCP::Panel::Utils::DateTime::current_local(); } my $first_of_month = $now->clone; $first_of_month->set_day(1); my $day_rs = $c->model('DB')->resultset('cdr_period_costs')->search_rs({ 'period' => 'day', 'period_date' => $dtf->format_date($now), 'direction' => 'out', 'fraud_limit_exceeded' => 1, 'contract.status' => 'active', %cond, },$attr); $now->subtract(days => 1); my $previous_day_rs = $c->model('DB')->resultset('cdr_period_costs')->search_rs({ 'period' => 'day', 'period_date' => $dtf->format_date($now), 'direction' => 'out', 'fraud_limit_exceeded' => 1, 'contract.status' => 'active', %cond, },$attr); my $month_rs = $c->model('DB')->resultset('cdr_period_costs')->search_rs({ 'period' => 'month', 'period_date' => $dtf->format_date($first_of_month), 'direction' => 'out', 'fraud_limit_exceeded' => 1, 'contract.status' => 'active', %cond, },$attr); my $interval = $c->request->param('interval'); my $rs; if (defined $interval and $interval eq 'day') { $rs = $day_rs->union_all($previous_day_rs); } elsif (defined $interval and $interval eq 'month') { $rs = $month_rs; } elsif (not defined $interval) { $rs = $day_rs->union_all([$previous_day_rs, $month_rs]); } else { $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "Invalid interval '$interval'"); return; } return $rs; } sub get_form { my ($self, $c) = @_; if ($c->user->roles eq "admin" || $c->user->roles eq "ccareadmin") { return NGCP::Panel::Form::get("NGCP::Panel::Form::CustomerFraudEvents::Admin", $c); } elsif ($c->user->roles eq "reseller" || $c->user->roles eq "ccare") { return NGCP::Panel::Form::get("NGCP::Panel::Form::CustomerFraudEvents::Reseller", $c); } } sub resource_from_item { my ($self, $c, $item) = @_; #$form my %cpc = $item->get_inflated_columns; my %resource; my $billing_mapping = NGCP::Panel::Utils::BillingMappings::get_actual_billing_mapping(c => $c, now => NGCP::Panel::Utils::DateTime::epoch_local($item->last_cdr_start_time), contract => $item->contract, ); my $billing_profile = $billing_mapping->billing_profile; my $contract_fraud_preference = $item->contract->contract_fraud_preference; $resource{'contract_id'} = $item->contract->id; $resource{'reseller_id'} = $item->contract->contact->reseller_id; $resource{'interval'} = $cpc{'period'}; $resource{'type'} = $cpc{'fraud_limit_type'}; $resource{'type'} = 'account_limit' if $resource{'type'} eq 'contract'; $resource{'type'} = 'profile_limit' if $resource{'type'} eq 'billing_profile'; if ($billing_profile->fraud_use_reseller_rates) { $resource{'interval_cost'} = $cpc{'reseller_cost'}; } else { $resource{'interval_cost'} = $cpc{'customer_cost'}; } $resource{'interval_cost'} = sprintf("%.2f",$resource{'interval_cost'}) if (defined $resource{'interval_cost'} and length($resource{'interval_cost'}) > 0); if ('month' eq $cpc{'period'}) { if ('contract' eq $cpc{'fraud_limit_type'}) { if ($contract_fraud_preference) { $resource{'interval_limit'} = $contract_fraud_preference->fraud_interval_limit; $resource{'interval_lock'} = $contract_fraud_preference->fraud_interval_lock; $resource{'interval_notify'} = $contract_fraud_preference->fraud_interval_notify; } else { $self->debug($c, "no contract fraud preference any more for contract ID $cpc{contract_id}"); $resource{'interval_limit'} = undef; $resource{'interval_lock'} = undef; $resource{'interval_notify'} = undef; } } elsif ('billing_profile' eq $cpc{'fraud_limit_type'}) { $resource{'interval_limit'} = $billing_profile->fraud_interval_limit; $resource{'interval_lock'} = $billing_profile->fraud_interval_lock; $resource{'interval_notify'} = $billing_profile->fraud_interval_notify; } else { $self->debug($c, "unsupported fraud limit type '$cpc{fraud_limit_type}'"); $resource{'interval_limit'} = undef; $resource{'interval_lock'} = undef; $resource{'interval_notify'} = undef; } } elsif ('day' eq $cpc{'period'}) { if ('contract' eq $cpc{'fraud_limit_type'}) { if ($contract_fraud_preference) { $resource{'interval_limit'} = $contract_fraud_preference->fraud_daily_limit; $resource{'interval_lock'} = $contract_fraud_preference->fraud_daily_lock; $resource{'interval_notify'} = $contract_fraud_preference->fraud_daily_notify; } else { } } elsif ('billing_profile' eq $cpc{'fraud_limit_type'}) { $resource{'interval_limit'} = $billing_profile->fraud_daily_limit; $resource{'interval_lock'} = $billing_profile->fraud_daily_lock; $resource{'interval_notify'} = $billing_profile->fraud_daily_notify; } else { $self->debug($c, "unsupported fraud limit type '$cpc{fraud_limit_type}'"); $resource{'interval_limit'} = undef; $resource{'interval_lock'} = undef; $resource{'interval_notify'} = undef; } } else { $self->debug($c, "unsupported fraud interval '$cpc{'period'}'"); $resource{'interval_limit'} = undef; $resource{'interval_lock'} = undef; $resource{'interval_notify'} = undef; } $resource{'use_reseller_rates'} = $billing_profile->fraud_use_reseller_rates; $resource{'notify_status'} = $cpc{'notify_status'}; my $datetime_fmt = DateTime::Format::Strptime->new( pattern => '%F %T', ); $resource{'notified_at'} = undef; $resource{'notified_at'} = $datetime_fmt->format_datetime($cpc{notified_at}) if defined $cpc{notified_at}; return \%resource; } sub item_by_id { my ($self, $c, $id) = @_; return $self->item_rs($c,$id)->first; } sub update_item { my ($self, $c, $item, $old_resource, $resource, $form) = @_; undef $resource->{interval_lock} if (defined $resource->{interval_lock} and $resource->{interval_lock} eq '0'); $form //= $self->get_form($c); return unless $self->validate_form( c => $c, form => $form, resource => $resource, ); try { # only update r/w fields $item->update({ map { $_ => $resource->{$_} } qw(notify_status notified_at) })->discard_changes; } catch($e) { $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Failed to update customer fraud event.", $e); return; }; return $item; } 1;