diff --git a/lib/NGCP/Panel/Controller/API/BillingFees.pm b/lib/NGCP/Panel/Controller/API/BillingFees.pm index 5212f25d5c..b5898a9eee 100644 --- a/lib/NGCP/Panel/Controller/API/BillingFees.pm +++ b/lib/NGCP/Panel/Controller/API/BillingFees.pm @@ -164,6 +164,32 @@ sub POST :Allow { my $form = NGCP::Panel::Form::BillingFee->new; my $billing_profile_id = $resource->{billing_profile_id} // undef; + + my $profile; + + # in case of implicit zone declaration (name/detail instead of id), + # find or create the zone + if(!defined $resource->{billing_zone_id} && + defined $resource->{billing_profile_id} && + defined $resource->{billing_zone_zone} && + defined $resource->{billing_zone_detail}) { + + $profile = $schema->resultset('billing_profiles')->find($resource->{billing_profile_id}); + if($profile) { + my $zone = $profile->billing_zones->find({ + zone => $resource->{billing_zone_zone}, + detail => $resource->{billing_zone_detail}, + }); + $zone = $profile->billing_zones->create({ + zone => $resource->{billing_zone_zone}, + detail => $resource->{billing_zone_detail}, + }) unless $zone; + $resource->{billing_zone_id} = $zone->id; + delete $resource->{billing_zone_zone}; + delete $resource->{billing_zone_detail}; + } + } + $resource->{billing_zone_id} //= undef; last unless $self->validate_form( c => $c, @@ -172,7 +198,7 @@ sub POST :Allow { ); $resource->{billing_profile_id} = $billing_profile_id; - my $profile = $schema->resultset('billing_profiles')->find($resource->{billing_profile_id}); + $profile //= $schema->resultset('billing_profiles')->find($resource->{billing_profile_id}); unless($profile) { $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "Invalid 'billing_profile_id'."); last; diff --git a/lib/NGCP/Panel/Role/API/BillingFees.pm b/lib/NGCP/Panel/Role/API/BillingFees.pm index 254f51bb06..b78e4b567c 100644 --- a/lib/NGCP/Panel/Role/API/BillingFees.pm +++ b/lib/NGCP/Panel/Role/API/BillingFees.pm @@ -82,6 +82,31 @@ sub update_fee { $form //= NGCP::Panel::Form::BillingFee->new; # TODO: for some reason, formhandler lets missing profile/zone id my $billing_profile_id = $resource->{billing_profile_id} // undef; + + # in case of implicit zone declaration (name/detail instead of id), + # find or create the zone + my $profile; + if(!defined $resource->{billing_zone_id} && + defined $resource->{billing_profile_id} && + defined $resource->{billing_zone_zone} && + defined $resource->{billing_zone_detail}) { + + $profile = $c->model('DB')->resultset('billing_profiles')->find($resource->{billing_profile_id}); + if($profile) { + my $zone = $profile->billing_zones->find({ + zone => $resource->{billing_zone_zone}, + detail => $resource->{billing_zone_detail}, + }); + $zone = $profile->billing_zones->create({ + zone => $resource->{billing_zone_zone}, + detail => $resource->{billing_zone_detail}, + }) unless $zone; + $resource->{billing_zone_id} = $zone->id; + delete $resource->{billing_zone_zone}; + delete $resource->{billing_zone_detail}; + } + } + $resource->{billing_zone_id} //= undef; return unless $self->validate_form( c => $c, @@ -94,7 +119,7 @@ sub update_fee { $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "Invalid 'billing_profile_id'"); return; } elsif($old_resource->{billing_profile_id} != $resource->{billing_profile_id}) { - my $profile = $c->model('DB')->resultset('billing_profiles') + $profile //= $c->model('DB')->resultset('billing_profiles') ->find($resource->{billing_profile_id}); unless($profile) { $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "Invalid 'billing_profile_id'"); diff --git a/t/api-billingfees.t b/t/api-billingfees.t index c71002d8f6..147dc44ba3 100644 --- a/t/api-billingfees.t +++ b/t/api-billingfees.t @@ -250,8 +250,75 @@ my @allfees = (); } while($nexturi); ok(keys %fees == 0, "check if all test billing fees have been found"); + + # try to create fee with implicit zone which already exists + $req = HTTP::Request->new('POST', $uri.'/api/billingfees/'); + $req->header('Content-Type' => 'application/json'); + $req->content(JSON::to_json({ + billing_profile_id => $billing_profile_id, + billing_zone_zone => 'testzone', + billing_zone_detail => 'test zone from api', + destination => "^1234", + direction => "out", + onpeak_init_rate => 1, + onpeak_init_interval => 60, + onpeak_follow_rate => 1, + onpeak_follow_interval => 30, + offpeak_init_rate => 0.5, + offpeak_init_interval => 60, + offpeak_follow_rate => 0.5, + offpeak_follow_interval => 30, + })); + $res = $ua->request($req); + ok($res->code == 201, "create profile fee with existing implicit zone"); + $req = HTTP::Request->new('GET', $uri.$res->header('Location')); + $res = $ua->request($req); + ok($res->code == 200, "fetch profile fee with existing implicit zone"); + my $z_fee = JSON::from_json($res->decoded_content); + ok(exists $z_fee->{billing_zone_id} && $z_fee->{billing_zone_id} == $billing_zone_id, "check if implicit zone returns the correct zone id"); + + $req = HTTP::Request->new('DELETE', $uri.$z_fee->{_links}->{'self'}->{href}); + $res = $ua->request($req); + ok($res->code == 204, "delete fee of existing implicit zone"); + + # try to create fee with implicit zone which doesn't exist yet + my $t = time; + $req = HTTP::Request->new('POST', $uri.'/api/billingfees/'); + $req->header('Content-Type' => 'application/json'); + $req->content(JSON::to_json({ + billing_profile_id => $billing_profile_id, + billing_zone_zone => 'testzone new'.$t, + billing_zone_detail => 'test zone from api new'.$t, + destination => "^1234", + direction => "out", + onpeak_init_rate => 1, + onpeak_init_interval => 60, + onpeak_follow_rate => 1, + onpeak_follow_interval => 30, + offpeak_init_rate => 0.5, + offpeak_init_interval => 60, + offpeak_follow_rate => 0.5, + offpeak_follow_interval => 30, + })); + $res = $ua->request($req); + ok($res->code == 201, "create profile fee with new implicit zone"); + $req = HTTP::Request->new('GET', $uri.$res->header('Location')); + $res = $ua->request($req); + ok($res->code == 200, "fetch profile fee with new implicit zone"); + $z_fee = JSON::from_json($res->decoded_content); + ok(exists $z_fee->{billing_zone_id} && $z_fee->{billing_zone_id} > $billing_zone_id, "check if implicit zone returns a new zone id"); + + $req = HTTP::Request->new('DELETE', $uri.$z_fee->{_links}->{'ngcp:billingzones'}->{href}); + $res = $ua->request($req); + ok($res->code == 204, "delete new implicit zone"); + + $req = HTTP::Request->new('GET', $uri.$z_fee->{_links}->{'self'}->{href}); + $res = $ua->request($req); + ok($res->code == 404, "check if fee is deleted when zone is deleted"); } + + # test fee item { $req = HTTP::Request->new('OPTIONS', $uri.'/'.$firstfee);