From ce7f620984b508827135011fc62f1be6f552072b Mon Sep 17 00:00:00 2001 From: user Date: Mon, 12 Aug 2024 15:55:03 +0200 Subject: [PATCH] add: tests --- .../CsvCostCalc/CsvAgentCost.php | 56 +++-- .../CsvCostCalc/CsvMinuteCostCalc.php | 6 +- .../CsvCostCalc/CsvTotalCostCalc.php | 5 +- .../GiteaApiController/GiteaExport.php | 3 +- app/Http/Controllers/ThirdPartyServices.php | 97 ------- .../ThirdPartyServices/EmailService.php | 34 +++ .../ThirdPartyServices/NextcloudService.php | 48 ++++ .../ThirdPartyServices/OpenProjectService.php | 208 +++++++++++++++ .../ThirdPartyServices/ThirdPartyServices.php | 40 +++ app/Utils/utils.php | 10 + .../CsvCostCalc/CsvAgentCostTest.php | 236 +++++++++++++++++- .../ThirdPartyServices/EmailServiceTest.php | 15 ++ .../NextcloudServiceTest.php | 15 ++ .../OpenProjectServiceTest.php | 20 ++ .../ThirdPartyServicesTest.php | 15 ++ .../Controllers/ThirdPartyServicesTest.php | 25 -- 16 files changed, 681 insertions(+), 152 deletions(-) delete mode 100644 app/Http/Controllers/ThirdPartyServices.php create mode 100644 app/Http/Controllers/ThirdPartyServices/EmailService.php create mode 100644 app/Http/Controllers/ThirdPartyServices/NextcloudService.php create mode 100644 app/Http/Controllers/ThirdPartyServices/OpenProjectService.php create mode 100644 app/Http/Controllers/ThirdPartyServices/ThirdPartyServices.php create mode 100644 app/Utils/utils.php create mode 100644 tests/Http/Controllers/ThirdPartyServices/EmailServiceTest.php create mode 100644 tests/Http/Controllers/ThirdPartyServices/NextcloudServiceTest.php create mode 100644 tests/Http/Controllers/ThirdPartyServices/OpenProjectServiceTest.php create mode 100644 tests/Http/Controllers/ThirdPartyServices/ThirdPartyServicesTest.php delete mode 100644 tests/Http/Controllers/ThirdPartyServicesTest.php diff --git a/app/Http/Controllers/CsvController/CsvCostCalc/CsvAgentCost.php b/app/Http/Controllers/CsvController/CsvCostCalc/CsvAgentCost.php index 5374406..6f8d393 100644 --- a/app/Http/Controllers/CsvController/CsvCostCalc/CsvAgentCost.php +++ b/app/Http/Controllers/CsvController/CsvCostCalc/CsvAgentCost.php @@ -2,49 +2,61 @@ namespace App\Http\Controllers\CsvController\CsvCostCalc; +use App\Utils\utils; +use Illuminate\Support\Facades\Log; +use RuntimeException; + class CsvAgentCost { - private $internal_percentage_to_deduct; - private $CsvMinuteCostCalc; - public function __construct() { - $this->internal_percentage_to_deduct = getenv('PRICE_INTERNAL_PERCENTAGE_TO_DEDUCT'); + $this->internal_percentage_to_deduct = (float) getenv('PRICE_INTERNAL_PERCENTAGE_TO_DEDUCT', null); $this->partner_organitation = strtolower(getenv('GITEA_PARTNER_ORGANIZATION')); $this->CsvMinuteCostCalc = new CsvMinuteCostCalc(); } - private function preapare_agents_columns(array $array, array $company_agents) + + + function prepare_agents_columns(array $array, array $company_agents) { - //Add all agents columns - foreach ($company_agents as $company_agent) { - $array[$company_agent] = ''; - $array[$company_agent . ' costo'] = 0; + try { + //Add all agents columns + foreach ($company_agents as $company_agent) { + $array[$company_agent] = ''; + $array[$company_agent . ' costo'] = 0; + } + return $array; + } catch (\Exception $e) { + Log::error('prepare_agents_columns E-AGENT-COLUMNS - ' . $e->getMessage()); + throw new RuntimeException("E-AGENT-COLUMNS - " . $e->getMessage() ); } - return $array; } - private function calculate_agents_cost(array $array, array $agents_time, float $minute_cost) + function calculate_agents_cost(array $array, array $agents_time, float $minute_cost) { + $minute_cost = utils::round_up_to_two_decimals($minute_cost); foreach ($agents_time as $name => $agent_time) { //Identify agents involved in the issue + $agent_cost = utils::round_up_to_two_decimals($agent_time / 60 * $minute_cost); $array[$name] = gmdate('H:i:s', $agent_time); - $array[$name . ' costo'] = $agent_time / 60 * $minute_cost; + $array[$name . ' costo'] = $agent_cost; } - return $array; } function agent_cost_calc(array $array, array $company_agents, array $agents_time) { - $array = $this->preapare_agents_columns($array, $company_agents); - - //Calculate cost, subtract a % from the minute_cost - $minute_cost = $this->CsvMinuteCostCalc->select_correct_cost($array['Request By'], $array['Priority']); - $minute_cost = $minute_cost - ($minute_cost / 100 * $this->internal_percentage_to_deduct); - - $array = $this->calculate_agents_cost($array, $agents_time, $minute_cost); - - return $array; + try { + if(!is_int($this->internal_percentage_to_deduct) && !is_float($this->internal_percentage_to_deduct)) throw new RuntimeException("agent_cost_calc E-AGENT-PERCENTAGE - Internal percentage is not set or NaN"); + $array = $this->prepare_agents_columns($array, $company_agents); + //Calculate cost, subtract a % from the minute_cost + $minute_cost = $this->CsvMinuteCostCalc->select_correct_cost($array['Request By'], $array['Priority']); + $minute_cost = $minute_cost - ($minute_cost / 100 * $this->internal_percentage_to_deduct); + $array = $this->calculate_agents_cost($array, $agents_time, $minute_cost); + return $array; + } catch (\Exception $e) { + Log::error($e->getMessage()); + throw new RuntimeException($e); + } } } diff --git a/app/Http/Controllers/CsvController/CsvCostCalc/CsvMinuteCostCalc.php b/app/Http/Controllers/CsvController/CsvCostCalc/CsvMinuteCostCalc.php index 4f6f9ec..79cb298 100644 --- a/app/Http/Controllers/CsvController/CsvCostCalc/CsvMinuteCostCalc.php +++ b/app/Http/Controllers/CsvController/CsvCostCalc/CsvMinuteCostCalc.php @@ -4,6 +4,7 @@ namespace App\Http\Controllers\CsvController\CsvCostCalc; use Exception; use Illuminate\Support\Facades\Log; +use App\Utils\utils; class CsvMinuteCostCalc { @@ -27,7 +28,7 @@ class CsvMinuteCostCalc private function calculate_minute_cost(int $hourly_cost) { - return $hourly_cost / 60; + return utils::round_up_to_two_decimals($hourly_cost / 60); } private function extract_string_from_label($label) @@ -35,7 +36,8 @@ class CsvMinuteCostCalc return strtolower(substr($label, strpos($label, '/') + 1)); } - function select_correct_cost($requested_by, $priority) + function + select_correct_cost($requested_by, $priority) { $requested_by = $this->extract_string_from_label($requested_by); $priority = $this->extract_string_from_label($priority); diff --git a/app/Http/Controllers/CsvController/CsvCostCalc/CsvTotalCostCalc.php b/app/Http/Controllers/CsvController/CsvCostCalc/CsvTotalCostCalc.php index b61149b..166c5de 100644 --- a/app/Http/Controllers/CsvController/CsvCostCalc/CsvTotalCostCalc.php +++ b/app/Http/Controllers/CsvController/CsvCostCalc/CsvTotalCostCalc.php @@ -1,20 +1,21 @@ CsvMinuteCostCalc = new CsvMinuteCostCalc(); } + function total_time_cost(array $array, int $total_time) { $minute_cost = $this->CsvMinuteCostCalc->select_correct_cost($array['Request By'], $array['Priority']); - $total_cost = $total_time / 60 * $minute_cost; + $total_cost = round_up_to_two_decimals($total_time / 60 * $minute_cost); $array['Tempo totale'] = gmdate('H:i:s', $total_time); $array['Costo totale'] = $total_cost; return $array; diff --git a/app/Http/Controllers/GiteaApiController/GiteaExport.php b/app/Http/Controllers/GiteaApiController/GiteaExport.php index d8382a3..f79a1d9 100644 --- a/app/Http/Controllers/GiteaApiController/GiteaExport.php +++ b/app/Http/Controllers/GiteaApiController/GiteaExport.php @@ -6,8 +6,7 @@ use App\Http\Controllers\Controller; use App\Http\Controllers\CsvController\CsvController; use App\Http\Controllers\CsvController\CsvCostCalc\CsvCostCalc; use App\Http\Controllers\IssueValidationController; -use App\Http\Controllers\ThirdPartyServices; -use Illuminate\Support\Facades\Storage; +use App\Http\Controllers\ThirdPartyServices\ThirdPartyServices; use OwenVoke\Gitea\Client; class GiteaExport extends Controller diff --git a/app/Http/Controllers/ThirdPartyServices.php b/app/Http/Controllers/ThirdPartyServices.php deleted file mode 100644 index 354840c..0000000 --- a/app/Http/Controllers/ThirdPartyServices.php +++ /dev/null @@ -1,97 +0,0 @@ -third_party_integrations_nextcloud = env('THIRD_PARTY_INTEGRATIONS_NEXTCLOUD', false); - $this->third_party_integrations_open_project = env('THIRD_PARTY_INTEGRATIONS_OPEN_PROJECT', false); - $this->nextcloud_url = env('NEXTCLOUD_URL', false); - $this->nextcloud_user = env('NEXTCLOUD_USER', false); - $this->nextcloud_password = env('NEXTCLOUD_PASSWORD', false); - $this->nextcloud_upload_folder_path = env('NEXTCLOUD_UPLOAD_FOLDER_PATH', false); - $this->nextcloud_upload_folder_web_link = env('NEXTCLOUD_UPLOAD_FOLDER_WEB_LINK', false); - $this->openproject_url = env('OPENPROJECT_URL', false); - $this->openproject_token = env('OPENPROJECT_TOKEN', false); - $this->openproject_project = env('OPENPROJECT_PROJECT', false); - $this->openproject_task_name = env('OPENPROJECT_TASK_NAME', false); - $this->email_send_allow = env('EMAIL_SEND_ALLOW', false); - $this->email_address_recepient = env('EMAIL_ADDRESS_RECEPIENT', null); - $this->email_prefix_subject = env('EMAIL_PREFIX_SUBJECT', null); - } - - function nextcloud_upload_csv(string $file_name, string $file_path) - { - try { - $nextcloud_url = $this->nextcloud_url . '/remote.php/dav/files/' . $this->nextcloud_user . '/' . $this->nextcloud_upload_folder_path . '/' . $file_name; - $file_contents = fopen($file_path, 'r'); - try { - $res = Http::withBasicAuth($this->nextcloud_user, $this->nextcloud_password) - ->attach($file_name, $file_contents) - ->put($nextcloud_url); - $res->throw(); - } catch (\Exception $e) { - Log::error('nextcloud_upload_csv Upload error - ' . $e->getMessage()); - throw new RuntimeException("E-NEXTCLOUD-UPLOAD"); - } - // Close the file handle - fclose($file_contents); - return $res; - } catch (\Exception $e) { - return false; - } - } - - function openproject_add_task_to_agent(array $issues, array $company_agents) - { - $openproject_main_group_members_url = $this->openproject_url . '/api/v3/groups/' . $this->openproject_group_id; - try { - $res = Http::withToken($this->openproject_token)->get($openproject_url); - $res->throw(); - } catch (\Exception $e) { - Log::error('nextcloud_upload_csv Upload error - ' . $e->getMessage()); - throw new RuntimeException("E-NEXTCLOUD-UPLOAD"); - } - } - - function send_export_via_email(string $from_date, string $to_date, string $file_name){ - $email_subject = $this->email_prefix_subject . ' '. $from_date.' - '.$to_date; - Mail::to($this->email_address_recepient)->send(new sendExportNotice(['export_date' => $email_subject, 'file_name' => $file_name, 'upload_folder_web_link' => $this->nextcloud_upload_folder_web_link], $email_subject)); - return true; - } - - function handle_third_party_services(string $file_name, string $file_path, array $issues, array $company_agents, string $from_date, string $to_date) - { - $nextcloud_res = $open_project_res = $email_res = false; - if ($this->third_party_integrations_nextcloud) { - $nextcloud_res = $this->nextcloud_upload_csv($file_name, $file_path); - } - if ($this->third_party_integrations_open_project) { - $open_project_res = $this->openproject_add_task_to_agent($issues, $company_agents); - } - if($this->email_send_allow) { - $email_res = $this->send_export_via_email($from_date, $to_date, $file_name); - } - return [$nextcloud_res, $open_project_res, $email_res]; - } -} diff --git a/app/Http/Controllers/ThirdPartyServices/EmailService.php b/app/Http/Controllers/ThirdPartyServices/EmailService.php new file mode 100644 index 0000000..ccbbf71 --- /dev/null +++ b/app/Http/Controllers/ThirdPartyServices/EmailService.php @@ -0,0 +1,34 @@ +email_address_recepient = env('EMAIL_ADDRESS_RECEPIENT', null); + $this->email_prefix_subject = env('EMAIL_PREFIX_SUBJECT', null); + $this->nextcloud_upload_folder_web_link = env('NEXTCLOUD_UPLOAD_FOLDER_WEB_LINK', false); + } + function send_export_via_email(string $from_date, string $to_date, string $file_name){ + try{ + $email_subject = $this->email_prefix_subject . ' '. $from_date.' - '.$to_date; + Mail::to($this->email_address_recepient)->send(new sendExportNotice(['export_date' => $email_subject, 'file_name' => $file_name, 'upload_folder_web_link' => $this->nextcloud_upload_folder_web_link], $email_subject)); + return true; + }catch (\Exception $e) { + Log::error('send_export_via_email Email error - ' . $e->getMessage()); + //throw new RuntimeException("E-EMAIL"); + return false; + } + + } +} diff --git a/app/Http/Controllers/ThirdPartyServices/NextcloudService.php b/app/Http/Controllers/ThirdPartyServices/NextcloudService.php new file mode 100644 index 0000000..8c33ebb --- /dev/null +++ b/app/Http/Controllers/ThirdPartyServices/NextcloudService.php @@ -0,0 +1,48 @@ +nextcloud_url = env('NEXTCLOUD_URL', false); + $this->nextcloud_user = env('NEXTCLOUD_USER', false); + $this->nextcloud_password = env('NEXTCLOUD_PASSWORD', false); + $this->nextcloud_upload_folder_path = env('NEXTCLOUD_UPLOAD_FOLDER_PATH', false); + $this->nextcloud_upload_folder_web_link = env('NEXTCLOUD_UPLOAD_FOLDER_WEB_LINK', false); + } + + function nextcloud_upload_csv(string $file_name, string $file_path) + { + try { + $nextcloud_url = $this->nextcloud_url . '/remote.php/dav/files/' . $this->nextcloud_user . '/' . $this->nextcloud_upload_folder_path . '/' . $file_name; + $file_contents = fopen($file_path, 'r'); + try { + $res = Http::withBasicAuth($this->nextcloud_user, $this->nextcloud_password) + ->attach($file_name, $file_contents) + ->put($nextcloud_url); + $res->throw(); + } catch (\Exception $e) { + Log::error('nextcloud_upload_csv Upload error - ' . $e->getMessage()); + throw new RuntimeException("E-NEXTCLOUD-UPLOAD"); + } + // Close the file handle + fclose($file_contents); + return $res; + } catch (\Exception $e) { + return false; + } + } +} diff --git a/app/Http/Controllers/ThirdPartyServices/OpenProjectService.php b/app/Http/Controllers/ThirdPartyServices/OpenProjectService.php new file mode 100644 index 0000000..cefb82e --- /dev/null +++ b/app/Http/Controllers/ThirdPartyServices/OpenProjectService.php @@ -0,0 +1,208 @@ +open_project_url = env('OPEN_PROJECT_URL', false); + $this->open_project_token = env('OPEN_PROJECT_TOKEN', false); + $this->open_project_project_id = env('OPEN_PROJECT_PROJECT_ID', false); + $this->open_project_task_name = env('OPEN_PROJECT_TASK_NAME', false); + $this->open_project_group_id = env('OPEN_PROJECT_GROUP_ID', false); + $this->open_project_special_nicks_list = env('OPEN_PROJECT_SPECIAL_NICKS_LIST', false); + $this->open_project_work_package_type_id = env('OPEN_PROJECT_WORK_PACKAGE_TYPE_ID', false); + $this->open_project_work_package_user_owner_id = env('OPEN_PROJECT_WORK_PACKAGE_USER_OWNER_ID', false); + } + + private function open_project_project_member_task_id(stdClass $open_project_member) + { + try { + $filter = [ + [ + "subject" => [ + "operator" => "~", + "values" => [$this->open_project_task_name . ' ' . $open_project_member->name] + ] + ] + ]; + $filter = json_encode($filter); + $open_project_project_work_packages_url = $this->open_project_url . '/api/v3/projects/' . $this->open_project_project_id . '/work_packages'; + $open_project_project_member_task_id = Http::withBasicAuth('apikey', $this->open_project_token)->withHeaders(['Accept' => 'application/hal+json'])->get($open_project_project_work_packages_url, [ + 'filters' => $filter + ]); + $open_project_project_member_task_id->throw(); + } catch (\Exception $e) { + Log::error('open_project_add_task_to_agent E-OPEN_PROJECT-URL - ' . $e->getMessage()); + throw new RuntimeException("E-OPEN_PROJECT-URL"); + } + $open_project_project_member_task_id = json_decode($open_project_project_member_task_id->body()); + try { + $open_project_project_member_task_id = $open_project_project_member_task_id->_embedded->elements; + return $open_project_project_member_task_id['0']->id; + } catch (\Exception $e) { + Log::error('open_project_project_member_task_id - No Task ' . $this->open_project_task_name . ' ' . $open_project_member->name . 'found ' . $e->getMessage()); + return null; + } + + } + + private function open_project_get_main_group_members() + { + try { + $open_project_main_group_members_url = $this->open_project_url . '/api/v3/groups/' . $this->open_project_group_id; + $open_project_main_group_members = Http::withBasicAuth('apikey', $this->open_project_token)->withHeaders(['Accept' => 'application/hal+json'])->get($open_project_main_group_members_url); + $open_project_main_group_members->throw(); + } catch (\Exception $e) { + Log::error('open_project_add_task_to_agent E-OPEN_PROJECT-URL - ' . $e->getMessage()); + throw new RuntimeException("E-OPEN_PROJECT-URL"); + } + $open_project_main_group_members = json_decode($open_project_main_group_members->body()); + $open_project_main_group_members = $open_project_main_group_members->_embedded->members; + foreach ($open_project_main_group_members as $open_project_member) { + if (!isset($open_project_member->name)) throw new RuntimeException("E-OPEN_PROJECT-MEMBERS-NO-NAME"); + $open_project_project_member_task_id = $this->open_project_project_member_task_id($open_project_member); + if (!$open_project_project_member_task_id) break; + $open_project_member_list[] = ['name' => strtolower($open_project_member->name), 'id' => $open_project_member->id, 'work_package_id' => $open_project_project_member_task_id, 'total' => 0]; + } + return $open_project_member_list; + } + + private + function git_extract_agents_total_sum(array $issues, array $company_agents) + { + $issues_totals = end($issues); + $agents_total_cost = []; + foreach ($company_agents as $agent_name) { + $agents_total_cost[$agent_name] = $issues_totals[$agent_name . ' costo']; + } + return $agents_total_cost; + } + + private function git_open_project_handle_nick_discrepancies(array $open_project_member_list) + { + try { + $open_project_special_nicks_list = json_decode($this->open_project_special_nicks_list); + foreach ($open_project_member_list as &$open_project_member) { + foreach ($open_project_special_nicks_list as $nick_on_open_project => $nick_on_git) { + if ($open_project_member['name'] == $nick_on_open_project) { + $open_project_member['name'] = $nick_on_git; + } + } + } + return $open_project_member_list; + } catch (\Exception $e) { + Log::error('git_open_project_handle_nick_discrepancies E-OPEN_PROJECT-NICK - ' . $e->getMessage() . ' ' . $e->getFile() . ' ' . $e->getLine()); + throw new RuntimeException("E-OPEN_PROJECT-NICK"); + } + } + + private + function open_project_add_to_members_total(array $open_project_member_list, array $git_extract_agents_total_sum) + { + try { + if (isset($this->open_project_special_nicks_list)) { + $open_project_member_list = $this->git_open_project_handle_nick_discrepancies($open_project_member_list); + } + foreach ($open_project_member_list as &$open_project_member) { + $open_project_member['total'] = $git_extract_agents_total_sum[$open_project_member['name']]; + } + return $open_project_member_list; + } catch (\Exception $e) { + Log::error('open_project_add_to_members_total E-OPEN_PROJECT-ADD-TOTAL - ' . $e->getMessage()); + throw new RuntimeException("E-OPEN_PROJECT-ADD-TOTAL"); + } + } + + private function set_parent_of_child_task($child_id, $parent_id) + { + try { + $open_project_work_package_set_parent = $this->open_project_url . '/api/v3/work_packages/' . $child_id; + $request_body = [ + 'parent' => $parent_id, + ]; + $open_project_work_package_parent = Http::withBasicAuth('apikey', $this->open_project_token)->withHeaders(['Accept' => 'application/hal+json'])->post($open_project_work_package_set_parent, json_encode($request_body)); + $open_project_work_package_parent->throw(); + return true; + } catch (\Exception $e) { + Log::error('open_project_add_task_to_agent E-OPEN_PROJECT-URL - ' . $e->getMessage()); + throw new RuntimeException("E-OPEN_PROJECT-URL"); + } + } + + function open_project_create_tasks(string $package_name, array $open_project_member) + { + try { + $open_project_work_package_creation_url = $this->open_project_url . '/api/v3/projects/' . $this->open_project_project_id . '/work_packages'; + $request_body = [ + 'subject' => $package_name, + 'description' => [ + "format" => 'plain', + "raw" => $open_project_member['total'], + ], + "_links" => [ + "type" => [ + "href" => "/api/v3/types/1".$this->open_project_work_package_type_id + ], + "assignee" => [ + "href" => "/api/v3/users/".$this->open_project_work_package_user_owner_id + ], + "responsible" => [ + "href" => "/api/v3/users/".$this->open_project_work_package_user_owner_id + ], + 'project' => [ + 'href' => '/api/v3/projects/' . $this->open_project_project_id + ]] + ]; + $open_project_work_package_creation = Http::withBasicAuth('apikey', $this->open_project_token)->withHeaders(['Accept' => 'application/hal+json'])->post($open_project_work_package_creation_url, json_encode($request_body)); + $open_project_work_package_creation->throw(); + return $open_project_work_package_creation->json()['id']; + } catch (\Exception $e) { + Log::error('Error creating work package', [ + 'status' => $open_project_work_package_creation->status(), + 'body' => $open_project_work_package_creation->body(), + ]); + Log::error('open_project_create_tasks E-OPEN_PROJECT-CREATE-SINGLE-TASK - ' . $e->getMessage() . ' ' . $e->getFile() . ' ' . $e->getLine()); + throw new RuntimeException("E-OPEN_PROJECT-URL"); + } + } + + private function open_project_handle_tasks_creation(array $open_project_members_with_total, string $from_date, string $to_date) + { + try { + $package_name = $from_date . ' - ' . $to_date; + foreach ($open_project_members_with_total as $open_project_member) { + $child_work_package = $this->open_project_create_tasks($package_name, $open_project_member); + return $this->set_parent_of_child_task($child_work_package, $open_project_member['work_package_id']); + } + } catch (\Exception $e) { + Log::error('open_project_add_task_to_agent E-OPEN_PROJECT-URL - ' . $e->getMessage() . ' ' . $e->getFile() . ' ' . $e->getLine()); + throw new RuntimeException("E-OPEN_PROJECT-URL"); + } + } + + function open_project_add_task_to_agent(array $issues, array $company_agents, string $from_date, string $to_date) + { + try { + $open_project_member_list = $this->open_project_get_main_group_members(); + $git_extract_agents_total_sum = $this->git_extract_agents_total_sum($issues, $company_agents); + $open_project_members_with_total = $this->open_project_add_to_members_total($open_project_member_list, $git_extract_agents_total_sum); + return $this->open_project_handle_tasks_creation($open_project_members_with_total, $from_date, $to_date); + } catch (\Exception $e) { + Log::error('open_project - ' . $e->getMessage()); + return false; + } + } +} diff --git a/app/Http/Controllers/ThirdPartyServices/ThirdPartyServices.php b/app/Http/Controllers/ThirdPartyServices/ThirdPartyServices.php new file mode 100644 index 0000000..2371d19 --- /dev/null +++ b/app/Http/Controllers/ThirdPartyServices/ThirdPartyServices.php @@ -0,0 +1,40 @@ +third_party_integrations_nextcloud = env('THIRD_PARTY_INTEGRATIONS_NEXTCLOUD', false); + $this->third_party_integrations_open_project = env('THIRD_PARTY_INTEGRATIONS_OPEN_PROJECT', false); + $this->email_send_allow = env('EMAIL_SEND_ALLOW', false); + $this->nextcloud_service = new \App\Http\Controllers\ThirdPartyServices\NextcloudService(); + $this->open_project_service = new \App\Http\Controllers\ThirdPartyServices\OpenProjectService(); + $this->email_service = new \App\Http\Controllers\ThirdPartyServices\EmailService(); + $this->calculate_agent_cost = env('GITEA_CALCULATE_AGENT_COST', false); + } + + function handle_third_party_services(string $file_name, string $file_path, array $issues, array $company_agents, string $from_date, string $to_date) + { + $nextcloud_res = $open_project_res = $email_res = false; + if ($this->third_party_integrations_nextcloud) { + $nextcloud_res = $this->nextcloud_service->nextcloud_upload_csv($file_name, $file_path); + } + if ($this->third_party_integrations_open_project && $this->calculate_agent_cost) { + $open_project_res = $this->open_project_service->open_project_add_task_to_agent($issues, $company_agents, $from_date, $to_date); + } + if($this->email_send_allow) { + $email_res = $this->email_service->send_export_via_email($from_date, $to_date, $file_name); + } + return [$nextcloud_res, $open_project_res, $email_res]; + } +} diff --git a/app/Utils/utils.php b/app/Utils/utils.php new file mode 100644 index 0000000..5f4d174 --- /dev/null +++ b/app/Utils/utils.php @@ -0,0 +1,10 @@ +csv_agent_cost = new CsvAgentCost(); + $this->mockCsvMinuteCostCalc = $this->createMock(CsvMinuteCostCalc::class); + $this->csv_agent_cost->CsvMinuteCostCalc = $this->mockCsvMinuteCostCalc; + // Set a value for internal_percentage_to_deduct + $this->csv_agent_cost->internal_percentage_to_deduct = 10; // Example percentage + } + public function testPrepareAgentsColumnsWithValidInput() + { + $array = []; + $company_agents = ['Agent1', 'Agent2']; + + $expected = [ + 'Agent1' => '', + 'Agent1 costo' => 0, + 'Agent2' => '', + 'Agent2 costo' => 0, + ]; + + $result = $this->csv_agent_cost->prepare_agents_columns($array, $company_agents); + $this->assertEquals($expected, $result); + } + + /** + * Test the prepare_agents_columns function with an empty company_agents array. + */ + public function testPrepareAgentsColumnsWithEmptyAgents() + { + $array = ['existing_key' => 'existing_value']; + $company_agents = []; + + $expected = [ + 'existing_key' => 'existing_value', + ]; + + $result = $this->csv_agent_cost->prepare_agents_columns($array, $company_agents); + $this->assertEquals($expected, $result); + } + + /** + * Test the prepare_agents_columns function with pre-existing keys. + */ + public function testPrepareAgentsColumnsWithPreExistingKeys() + { + $array = [ + 'Request By' => 'some_value', + 'Priority' => 5, + ]; + $company_agents = ['Agent1', 'Agent2']; + + $expected = [ + 'Request By' => 'some_value', + 'Priority' => 5, + 'Agent1' => '', + 'Agent1 costo' => 0, + 'Agent2' => '', + 'Agent2 costo' => 0, + ]; + + $result = $this->csv_agent_cost->prepare_agents_columns($array, $company_agents); + $this->assertEquals($expected, $result); + } + + /** + * Test with a basic input. + */ + public function testAgentCostCalcBasicInput() + { + $minute_cost = 5.15552; // Cost per minute + $array = []; + $agents_time = [ + 'Agent A' => 7200, // 2 hours + 'Agent B' => 10800, // 3 hours + ]; + + // Ricordarsi che all'esecuzione della funzione, è gia stata dedotta la percentuale interna + $expected = [ + 'Agent A' => '02:00:00', + 'Agent A costo' => 619.21, // 120 minutes * 5.0 + 'Agent B' => '03:00:00', + 'Agent B costo' => 928.8, // 180 minutes * 5.0 + ]; + + $result = $this->csv_agent_cost->calculate_agents_cost($array, $agents_time, $minute_cost); + + $this->assertEquals($expected, $result); + } + + /** + * Test with zero agent time. + */ + public function testAgentCostCalcZeroAgentTime() + { + $array = []; + $agents_time = [ + 'Agent C' => 0, // 0 hours + ]; + $minute_cost = 5.0; + + $expected = [ + 'Agent C' => '00:00:00', + 'Agent C costo' => 0.0, + ]; + + $result = $this->csv_agent_cost->calculate_agents_cost($array, $agents_time, $minute_cost); + + $this->assertEquals($expected, $result); + } + + /** + * Test with different minute costs. + */ + public function testAgentCostCalcDifferentMinuteCosts() + { + $array = []; + $agents_time = [ + 'Agent E' => 14400, // 4 hours + ]; + $minute_cost = 10.0; // Higher cost per minute + + $expected = [ + 'Agent E' => '04:00:00', + 'Agent E costo' => 2400.0, // 240 minutes * 10.0 + ]; + + $result = $this->csv_agent_cost->calculate_agents_cost($array, $agents_time, $minute_cost); + + $this->assertEquals($expected, $result); + } + + public function testSelectCorrectCostCalculatesCostCorrectly() + { + // percentuale dedotta impostata nel setup + // Costo orario per cliente con issue high, 75.5€/h + $array = [ + 'Progetto' => 'Progetto Test', + '#' => 31, + 'Titolo' => 'Titolo test', + 'URL' => 'https://git.example.net/Cliente/ProgettoTest/issues/31', + 'Aperto_il' => '2024-05-30T15:53:58+02:00', + 'Chiuso_il' => '2024-06-05T10:40:30+02:00', + 'Etichette' => 'Kind/Bug,Priority/High,RequestBy/Cliente,Status/Resolved,', + 'Kind' => 'Kind/Bug', + 'Request By' => 'RequestBy/Client', + 'Priority' => 'Priority/High', + 'Tempo totale' => '00:10:00', + 'Costo totale' => 12.6, + ]; + $company_agents = ['agentTest']; // Populate as necessary + $agents_time = ['agentTest' => 600]; // Populate as necessary + + //Valori presi dalla classe di test di CsvMinuteCostCalcTest + $this->mockCsvMinuteCostCalc + ->expects($this->once()) + ->method('select_correct_cost') + ->with('RequestBy/Client', 'Priority/High') + ->willReturn(1.26); // Mocked return value + + $expected_result = $array; + $expected_result = array_merge($array, [ + 'agentTest' => '00:10:00', + 'agentTest costo' => 11.4 + ]); + + // Call the method being tested + $result = $this->csv_agent_cost->agent_cost_calc($array, $company_agents, $agents_time); + + // Assert the expected outcome + $this->assertEquals($expected_result, $result); + } + + public function testInternalPercentageSetTo0() + { + // Set internal_percentage_to_deduct to 0 to trigger the exception + $this->csv_agent_cost->internal_percentage_to_deduct = 0; + + // percentuale dedotta impostata nel setup + // Costo orario per cliente con issue high, 75.5€/h + $array = [ + 'Progetto' => 'Progetto Test', + '#' => 31, + 'Titolo' => 'Titolo test', + 'URL' => 'https://git.example.net/Cliente/ProgettoTest/issues/31', + 'Aperto_il' => '2024-05-30T15:53:58+02:00', + 'Chiuso_il' => '2024-06-05T10:40:30+02:00', + 'Etichette' => 'Kind/Bug,Priority/High,RequestBy/Cliente,Status/Resolved,', + 'Kind' => 'Kind/Bug', + 'Request By' => 'RequestBy/Client', + 'Priority' => 'Priority/High', + 'Tempo totale' => '00:10:00', + 'Costo totale' => 12.6, + ]; + $company_agents = ['agentTest']; // Populate as necessary + $agents_time = ['agentTest' => 600]; // Populate as necessary + + //Valori presi dalla classe di test di CsvMinuteCostCalcTest + $this->mockCsvMinuteCostCalc + ->expects($this->once()) + ->method('select_correct_cost') + ->with('RequestBy/Client', 'Priority/High') + ->willReturn(1.26); // Mocked return value + + $expected_result = $array; + $expected_result = array_merge($array, [ + 'agentTest' => '00:10:00', + 'agentTest costo' => 12.6 + ]); + + // Call the method being tested + $result = $this->csv_agent_cost->agent_cost_calc($array, $company_agents, $agents_time); + + // Assert the expected outcome + $this->assertEquals($expected_result, $result); + } + + public function testInternalPercentageSetNull() + { + // Imposta a null così da far lanciare l'errore + $this->csv_agent_cost->internal_percentage_to_deduct = null; + + $this->expectException(RuntimeException::class); + + // Prepare input data + $array = [ + 'Request By' => 'Agent A', + 'Priority' => 'High' + ]; + $company_agents = []; // Populate as necessary + $agents_time = []; // Populate as necessary + + // Call the method being tested + $this->csv_agent_cost->agent_cost_calc($array, $company_agents, $agents_time); } } diff --git a/tests/Http/Controllers/ThirdPartyServices/EmailServiceTest.php b/tests/Http/Controllers/ThirdPartyServices/EmailServiceTest.php new file mode 100644 index 0000000..9664ec8 --- /dev/null +++ b/tests/Http/Controllers/ThirdPartyServices/EmailServiceTest.php @@ -0,0 +1,15 @@ +