Files
api-extranetwork/app/Core/Service/PropertyService.php
ExtraNetwork e5c4b6aa13 first commit
2026-05-12 17:04:54 +03:00

691 lines
28 KiB
PHP

<?php
namespace App\Core\Service;
use App\Core\Repository\Property\PropertyRepository;
use App\Core\Validator\Property\PropertySearchValidator;
use App\Core\Validator\Property\PropertyCreateValidator;
use App\Core\Validator\Property\PropertyUpdateValidator;
use App\Core\Service\PropertyAdditionalInfo\PropertyAdditionalInfoService;
use App\Core\Service\UserPropertyMappingService;
use App\Core\Service\PermissionService;
use App\Core\Service\LanguageService;
use App\Core\Repository\PropertyLanguageSpoken\PropertyLanguageSpokenRepository;
use App\Core\Service\NotificationService;
use GuzzleHttp\Client;
use GuzzleHttp\Exception\RequestException;
use Illuminate\Http\Request;
use App;
use Illuminate\Support\Facades\File;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Config;
use Exception;
use App\Exceptions\ApiErrorException;
use Illuminate\Support\Facades\DB;
class PropertyService
{
private $propertyRepository;
private $propertySearchValidator;
private $propertyCreateValidator;
private $propertyAdditionalInfoService;
private $userPropertyMappingService;
private $permissionService;
private $propertyUpdateValidator;
const CHAIN_ID = 1; // Independent
private $minimumAgePolicies;
private $languageService;
private $propertyLanguageSpokenRepository;
public function __construct
(
Request $request,
UserPropertyMappingService $userPropertyMappingService,
PropertyAdditionalInfoService $propertyAdditionalInfoService,
PropertyRepository $propertyRepository,
PropertyCreateValidator $propertyCreateValidator,
PermissionService $permissionService,
PropertySearchValidator $propertySearchValidator,
LanguageService $languageService,
PropertyLanguageSpokenRepository $propertyLanguageSpokenRepository,
PropertyUpdateValidator $propertyUpdateValidator,
NotificationService $notificationService,
Client $restClient
)
{
$this->request = $request;
$this->userPropertyMappingService = $userPropertyMappingService;
$this->propertyAdditionalInfoService = $propertyAdditionalInfoService;
$this->propertyRepository = $propertyRepository;
$this->propertySearchValidator = $propertySearchValidator;
$this->propertyCreateValidator = $propertyCreateValidator;
$this->permissionService = $permissionService;
$this->propertyUpdateValidator = $propertyUpdateValidator;
$this->languageService = $languageService;
$this->notificationService = $notificationService;
$this->restClient = $restClient;
$this->minimumAgePolicies = [
[
'value' => 0,
'language_key' => 'enw-input-all_ages'
],
];
$this->propertyLanguageSpokenRepository = $propertyLanguageSpokenRepository;
for ($i = 1; $i <= 18; $i++) {
$this->minimumAgePolicies[] = [
'value' => $i,
'language_key' => "{$i}+",
];
}
}
public function select($param = [], $column = ['*'])
{
$response = ['status' => -1, 'message' => '', 'data' => null];
try {
$data = $this->propertyRepository->findByCriteria($param, $column);
$response = [
'status' => true,
'data' => $data,
];
} catch (ApiErrorException $e) {
$response['message'] = $e->getMessage();
} catch (Exception $e) {
$message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage();
Log::error($message);
$response['message'] = $e->getMessage();
}
return output($response);
}
public function create($param = [])
{
$response = ['status' => -1, 'message' => '', 'data' => null];
try {
$propertyData =
[
"name" => fillOnUndefined($param, "name"),
"country" => fillOnUndefined($param, "country"),
"property_type_id" => fillOnUndefined($param, "property_type_id"),
"chain_id" => fillOnUndefined($param, "chain_id"),
"rating" => fillOnUndefined($param, "rating"),
"official_name" => fillOnUndefined($param, "official_name"),
"tax_office" => fillOnUndefined($param, "tax_office"),
"tax_number" => fillOnUndefined($param, "tax_number"),
"currency_type" => fillOnUndefined($param, "currency_type"),
"status" => fillOnUndefined($param, "status", 0),
"created_by" => fillOnUndefined($param, "created_by"),
"updated_by" => fillOnUndefined($param, "updated_by"),
"created_at" => time(),
"updated_at" => time(),
];
$validationResult = $this->propertyCreateValidator->validate($propertyData);
if ($validationResult->errors()->first()) {
$errors = $validationResult->errors()->all();
throw new ApiErrorException($errors);
}
$propertyCreateResult = $this->propertyRepository->create($propertyData);
if ($propertyCreateResult['status'] != 'success') {
throw new Exception('api-unknown_error');
}
$response = [
'status' => true,
'data' => $propertyCreateResult["data"]
];
} catch (ApiErrorException $e) {
$response['message'] = implode(', ', $e->getMessageArr());
} catch (Exception $e) {
$message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage();
Log::error($message);
$response['message'] = $e->getMessage();
}
return output($response);
}
public function update($id, $param = [])
{
$response = ['status' => -1, 'message' => '', 'data' => null];
try {
$updateResult = $this->propertyRepository->update($id, $param);
if ($updateResult['status'] != 'success') {
throw new Exception('api-unknown_error');
}
$updateData = $updateResult["data"];
$response = [
'status' => true,
'data' => $updateData,
];
} catch (ApiErrorException $e) {
$response['message'] = implode(', ', $e->getMessageArr());
} catch (Exception $e) {
$message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage();
Log::error($message);
$response['message'] = $e->getMessage();
}
return output($response);
}
public function getProperty($params)
{
$response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500];
try {
$return = [];
$propertyRequest = [
'criteria' => [
['field' => 'id', 'condition' => '=', 'value' => $params['property_id']],
//['field' => 'status', 'condition' => '=', 'value' => 1],
],
'with' => ['propertyLanguageSpoken'],
'firstRow' => true
];
$getPropertyFields = ['id', 'name', 'property_type_id', 'chain_id', 'rating', 'official_name', 'tax_office', 'tax_number', 'currency_type', 'country'];
$propertyData = $this->select($propertyRequest, $getPropertyFields);
$propertyLanguageSpokenArray = collect($propertyData['data']['property_language_spoken'])->keyBy('language_code')->keys()->all();
$languageSpokenRequest['selected_languages'] = $propertyLanguageSpokenArray;
$languageSpokenData = $this->languageService->propertyLanguageSpoken($languageSpokenRequest);
if ($languageSpokenData['status'] != 'success') {
throw new ApiErrorException($languageSpokenData['message']);
}
if ($propertyData['data']['chain_id'] === NULL) {
$propertyData['data']['chain_id'] = self::CHAIN_ID;
}
$return['property_info'] = $propertyData['data'];
unset($return['property_info']['property_language_spoken']);
$return['property_info']['has_locale_name'] = false;
$return['property_language_spoken'] = $languageSpokenData['data'];
$propertyAdditionalInfo = $this->propertyAdditionalInfoService->getPropertyAdditionalInfo2KeyBy($params);
if (isset($propertyAdditionalInfo['data'])) {
$return['additional_info'] = $propertyAdditionalInfo['data'];
if (isset($return['additional_info']['locale_name']) && $return['additional_info']['locale_name']) {
$return['property_info']['has_locale_name'] = true;
}
}
$response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => ['get_property' => $return, 'minimum_age_policies' => $this->minimumAgePolicies]];
} catch
(ApiErrorException $e) {
$response['message'] = implode(', ', $e->getMessageArr());
$response['statusCode'] = 400;
} catch (Exception $e) {
$message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage();
Log::error($message);
$response['message'] = $e->getMessage();
$response['statusCode'] = 500;
}
return output($response);
}
public function getPropertyList($params)
{
$response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500];
try {
$propertyRequest = [
'criteria' => [
['field' => 'status', 'condition' => '=', 'value' => 1],
['field' => 'user_id', 'condition' => '=', 'value' => $params['user_id']],
],
'with' => ['property.defaultPropertyPhoto']
];
$propertyData = $this->userPropertyMappingService->select($propertyRequest);
if ($propertyData['status'] != 'success') {
throw new ApiErrorException(lang('Property data not loaded'));
}
$propertyList = collect($propertyData['data'])->map(function ($value) use ($params) {
$menuParams = [
'user_id' => $params['user_id'],
'property_id' => $value['property']['id'],
'locale' => $params['locale']
];
if (is_array($value['property']) && $value['property']['status'] != 0) {
$defaultPhoto = isset($value['property']['default_property_photo']) ? $value['property']['default_property_photo'] : null;
$photoUrlThumbFilePath = '/assets/img/placeholder.png';
if (isset($defaultPhoto['photo_name'])) {
$photoUrlThumbFilePath = Config::get('app.fileSystemDriver') . "/property-photos/{$value['property']['id']}" . "/{$defaultPhoto['photo_name']}_200x200.{$defaultPhoto['file_ext']}";
if (File::exists($photoUrlThumbFilePath)) {
$photoUrlThumbFilePath = Config::get('app.imageUrl') . "/property-photos/{$value['property']['id']}" . "/{$defaultPhoto['photo_name']}_200x200.{$defaultPhoto['file_ext']}";
} else {
$photoUrlThumbFilePath = Config::get('app.imageUrl') . "/property-photos/{$value['property']['id']}" . "/{$defaultPhoto['photo_name']}_thumbnail.{$defaultPhoto['file_ext']}";
}
}
return $value['property'] = [
'id' => $value['property']['id'],
'name' => $value['property']['name'],
'default_photo' => $photoUrlThumbFilePath,
'property_menu' => $this->permissionService->getMenuTreeForUser($menuParams)
];
}
})->toArray();
$response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => ['property_list' => $propertyList]];
} catch (ApiErrorException $e) {
$response['message'] = implode(', ', $e->getMessageArr());
$response['statusCode'] = 400;
} catch (Exception $e) {
$message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage();
Log::error($message);
$response['message'] = $e->getMessage();
$response['statusCode'] = 500;
}
return output($response);
}
public function propertyUpdate($params)
{
$response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500];
try {
DB::beginTransaction();
$return = [];
$propertyData = fillOnUndefined($params, 'property_info');
$validationResult = $this->propertyUpdateValidator->validate($params);
if ($validationResult->errors()->first()) {
$errors = $validationResult->errors()->all();
throw new ApiErrorException($errors);
}
$updateData = [];
$validateKeys = ['name', 'property_type_id', 'chain_id', 'rating', 'currency_type', 'currency_type', 'checkin_time', 'checkout_time', 'official_name', 'tax_office', 'tax_number', 'country', 'content_code'];
foreach ($propertyData as $key => $value) {
if (!in_array($key, $validateKeys)) {
throw new ApiErrorException(lang('Error Columns'));
}
$updateData[$key] = $value;
}
if ($updateData) {
$updateData['updated_by'] = $params['user_id'];
$updateData['updated_at'] = time();
}
$propertyRequest = [
'criteria' => [
['field' => 'id', 'condition' => '=', 'value' => $params['property_id']]
],
'firstRow' => true
];
$propertyData = $this->propertyRepository->findByCriteria($propertyRequest, ['status']);
if (!empty($propertyData)) {
if ($propertyData['status'] === 2) {
$updateData['status'] = 1;
}
}
$propertyUpdateResult = $this->update($params['property_id'], $updateData);
if ($propertyUpdateResult['status'] != 'success') {
throw new ApiErrorException($propertyUpdateResult['message']);
}
$return['property_info'] = $propertyUpdateResult['data'];
$return['property_info']['has_locale_name'] = false;
$propertyLanguageSpokeRequest = [
'criteria' => [
['field' => 'property_id', 'condition' => '=', 'value' => $params['property_id']],
],
];
$propertyLanguageEraseData = $this->propertyLanguageSpokenRepository->findByCriteria($propertyLanguageSpokeRequest, ['id']);
$propertyLanguageEraseData = $propertyLanguageEraseData ? $propertyLanguageEraseData : [];
$deleteThisIds = collect($propertyLanguageEraseData)->keyBy('id')->keys()->all();
if ($deleteThisIds) {
$deleteThisArray = $this->propertyLanguageSpokenRepository->destroy($deleteThisIds);
if ($deleteThisArray['status'] != 'success') {
throw new Exception('api-unknown_error');
}
}
$insertPropertyLanguageSpoken = [];
foreach ($params['property_language_spoken'] as $langCode) {
$insertItem = [
'property_id' => $params['property_id'],
'language_code' => $langCode,
'status' => 1,
'created_by' => $params['user_id'],
'updated_by' => $params['user_id'],
'created_at' => time(),
'updated_at' => time(),
];
$insertPropertyLanguageSpoken[] = $insertItem;
}
$insertRoomRatePrices = $this->propertyLanguageSpokenRepository->insert($insertPropertyLanguageSpoken);
if ($insertRoomRatePrices['status'] != 'success') {
throw new ApiErrorException($insertRoomRatePrices['message']);
}
$updateAdditionalInfoData = [
'locale' => fillOnUndefined($params, 'locale'),
'additional_info' => fillOnUndefined($params, 'additional_info'),
'property_id' => fillOnUndefined($params, 'property_id'),
'user_id' => $params['user_id'],
];
$updateAdditionalInfo = $this->propertyAdditionalInfoService->updateOrCreatePropertyAdditionalInfo($updateAdditionalInfoData);
if ($updateAdditionalInfo['status'] != 'success') {
throw new ApiErrorException($updateAdditionalInfo['message']);
}
if (!$params['has_locale_name']) {
$deleteRequest = [
'key_array' => ['locale_name_language', 'locale_name'],
'property_id' => $params['property_id']
];
$this->propertyAdditionalInfoService->deletePropertyAdditionalInfos($deleteRequest);
}
$propertyAdditionalInfo = $this->propertyAdditionalInfoService->getPropertyAdditionalInfo2KeyBy($params);
if (isset($propertyAdditionalInfo['data'])) {
$return['additional_info'] = $propertyAdditionalInfo['data'];
if (isset($return['additional_info']['locale_name']) && $return['additional_info']['locale_name_language']) {
$return['property_info']['has_locale_name'] = true;
}
}
$languageSpokenRequest['selected_languages'] = $params['property_language_spoken'] ? $params['property_language_spoken'] : [];
$languageSpokenData = $this->languageService->propertyLanguageSpoken($languageSpokenRequest);
if ($languageSpokenData['status'] != 'success') {
throw new ApiErrorException($languageSpokenData['message']);
}
$return['property_language_spoken'] = $languageSpokenData['data'];
$response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => ['get_property' => $return]];
DB::commit();
} catch
(ApiErrorException $e) {
DB::rollBack();
$response['message'] = implode(', ', $e->getMessageArr());
$response['statusCode'] = 400;
} catch (Exception $e) {
DB::rollBack();
$message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage();
Log::error($message);
$response['message'] = $e->getMessage();
$response['statusCode'] = 500;
}
if ($response['status']) {
//PUSH NOTIFICATION
$newBookingNotificationParam = ['property_id' => $params['property_id']];
$this->notificationService->sendLogNotification($newBookingNotificationParam);
//PUSH NOTIFICATION
}
return output($response);
}
public function getPropertyDetail($params)
{
$response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500];
try {
$return = [];
$propertyRequest = [
'criteria' => [
['field' => 'id', 'condition' => '=', 'value' => $params['property_id']],
['field' => 'status', 'condition' => '=', 'value' => 1],
],
'with' => ['propertyType', 'propertyChain'],
'firstRow' => true
];
$getPropertyFields = ['id', 'name', 'property_type_id', 'chain_id', 'rating', 'official_name', 'tax_office', 'tax_number', 'currency_type'];
$propertyData = $this->select($propertyRequest, $getPropertyFields);
$return = $propertyData['data'];
$propertyAdditionalInfo = $this->propertyAdditionalInfoService->getPropertyAdditionalInfo2KeyBy($params);
if (isset($propertyAdditionalInfo['data'])) {
$return['additional_info'] = $propertyAdditionalInfo['data'];
}
$response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $return];
} catch (ApiErrorException $e) {
$response['message'] = implode(', ', $e->getMessageArr());
$response['statusCode'] = 400;
} catch (Exception $e) {
$message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage();
Log::error($message);
$response['message'] = $e->getMessage();
$response['statusCode'] = 500;
}
return output($response);
}
public function kommoApiPost($method, $payloadJson, $token = null)
{
$response = ['status' => false, 'message' => '', 'data' => null];
try {
$headers['Content-Type'] = 'application/json';
$headers['Authorization'] = 'Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImp0aSI6ImE5ZWMxNDUwMjM0NDQ5NWZiZjY0YjVmNTBkZWQzODMzYWQyMGM3NGZmYWIyZWIyMmE4NTg5ZjBlMjk5Njg4NWQzYzI1MGUyMmEzMzM0Njc2In0.eyJhdWQiOiJiM2E4ZmI2NC0yODRkLTQ2ODctYTFhMC0yMGMwMDY0MWEwN2YiLCJqdGkiOiJhOWVjMTQ1MDIzNDQ0OTVmYmY2NGI1ZjUwZGVkMzgzM2FkMjBjNzRmZmFiMmViMjJhODU4OWYwZTI5OTY4ODVkM2MyNTBlMjJhMzMzNDY3NiIsImlhdCI6MTc2NjY3NDY2MiwibmJmIjoxNzY2Njc0NjYyLCJleHAiOjE4OTMzNjk2MDAsInN1YiI6IjE0NDY4NTAwIiwiZ3JhbnRfdHlwZSI6IiIsImFjY291bnRfaWQiOjM1NDc3MTE5LCJiYXNlX2RvbWFpbiI6ImtvbW1vLmNvbSIsInZlcnNpb24iOjIsInNjb3BlcyI6WyJjcm0iLCJmaWxlcyIsImZpbGVzX2RlbGV0ZSIsIm5vdGlmaWNhdGlvbnMiLCJwdXNoX25vdGlmaWNhdGlvbnMiXSwiaGFzaF91dWlkIjoiNmZlNzhmYjYtNDQ4ZC00MGNiLWE2ZDYtNzg5Y2MyYTIyNzBkIiwidXNlcl9mbGFncyI6MCwiYXBpX2RvbWFpbiI6ImFwaS1nLmtvbW1vLmNvbSJ9.dUcX6NUXRZOK0MhywNloo_5o6dFfjTLSDj9LinVNS2c66NHlsEmWRg2h8kP0NB75VeiYVP624kQMMMztR4trcjQuvvNElBWEw5kCAlIUMD4IZDmyduSvZ6JGYnC24ukVnH6voMW7uN3wyGgBrI3EOsrExAZwP10sQZBQNDqeUBb8ZWFXMaBiFeWEpoZpcaG_DMNgD3BEYLeYSsjSwUsOOyaLpKroJktrYnFjIgdH4qhoImpXmM0rL3z_VXpz85X-7sVp7vLwsyZH48yrReDIL1RQu__sIQVPr40_k8XbQ2vLQLYSFjT52Hajh98IdGpb7DgQUEKVF0z_hByDXo5PJQ';
$serviceUrl = 'https://extranetwork.kommo.com/api/v4/' . $method;
$result = $this->restClient->post($serviceUrl,
[
'headers' => $headers,
'body' => json_encode($payloadJson)
]
);
$getResponseBody = $result->getBody()->getContents();
$getResponse = json_decode($getResponseBody, 1);
$response = [
'status' => true,
'data' => $getResponse,
//'message' => $getResponse['message']
];
} catch (RequestException $e) {
$getResponse = json_decode($e->getResponse()->getBody()->getContents(), 1);
$message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage();
Log::error($message);
$response['message'] = $getResponse['message'];
} catch (Exception $e) {
$message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage();
Log::error($message);
$response['message'] = $e->getMessage();
}
return output($response);
}
public function kommoCreateLead($params)
{
$response = ['status' => false, 'message' => '', 'data' => null];
try {
$kommoCompanyParam = [
[
"name" => $params['property'],
"custom_fields_values" => [
[
"field_code" => "PHONE",
"values" => [
[
"value" => $params['phone_number']
]
]
],
[
"field_code" => "EMAIL",
"values" => [
[
"value" => $params['email']
]
]
]
]
]
];
$kommoCompany = $this->kommoApiPost('companies', $kommoCompanyParam);
$kommoCompany = $kommoCompany['status'] == 'success' && !empty($kommoCompany['status']) ? $kommoCompany['data'] : null;
$kommoCompanyId = reset($kommoCompany['_embedded']['companies'])['id'];
$kommoContactParam = [
[
"name" => $params['name_surname'],
"custom_fields_values" => [
[
"field_code" => "PHONE",
"values" => [
[
"value" => $params['phone_number']
]
]
],
[
"field_code" => "EMAIL",
"values" => [
[
"value" => $params['email']
]
]
]
]
]
];
$kommoContact = $this->kommoApiPost('contacts', $kommoContactParam);
$kommoContact = $kommoContact['status'] == 'success' && !empty($kommoContact['status']) ? $kommoContact['data'] : null;
$kommoContactId = reset($kommoContact['_embedded']['contacts'])['id'];
$kommoLeadParam = [
[
"name" => $params['property'],
"pipeline_id" => 12343583,
"status_id" => 95388747,
"_embedded" => [
"companies" => [
[
"id" => $kommoCompanyId
]
],
"contacts" => [
[
"id" => $kommoContactId
]
]
],
"custom_fields_values" => [
[
"field_id" => 2522776,
"values" => [
[
"value" => "Web Form"
]
]
]
]
]
];
$kommoLead = $this->kommoApiPost('leads', $kommoLeadParam);
$kommoLead = $kommoLead['status'] == 'success' && !empty($kommoLead['status']) ? $kommoLead['data'] : null;
$response = [
'status' => true,
'data' => $kommoLead
];
} catch (RequestException $e) {
$getResponse = json_decode($e->getResponse()->getBody()->getContents(), 1);
$message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage();
Log::error($message);
$response['message'] = $getResponse['message'];
} catch (Exception $e) {
$message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage();
Log::error($message);
$response['message'] = $e->getMessage();
}
return output($response);
}
}