<?php
namespace App\Controller;
use App\Clases\MultivendeClass;
use App\Entity\Empresa;
use App\Entity\MultivendeAssoc;
use App\Entity\WebhookMultivende;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
use FOS\RestBundle\Controller\AbstractFOSRestController;
use FOS\RestBundle\Controller\Annotations as Rest;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Doctrine\ORM\EntityManagerInterface;
use Psr\Log\LoggerInterface;
/**
* API Multivende Controller.
* @Route("/api/multivende", name="api_multivendeController_")
*/
class ApiMultivendeController extends AbstractFOSRestController
{
const CONTROLLER_NAME = 'ApiMultivendeController';
/**
* @var LoggerInterface
*/
private $logger;
private $em;
private $logController;
public function __construct(LoggerInterface $logger,EntityManagerInterface $em, LogController $logController)
{
$this->logger = $logger;
$this->em = $em;
$this->logController = $logController;
}
/**
* Captura los webhooks de Multivende
* @Rest\Post("/callback")
*
* @return Response
*/
public function callbackMultivende(Request $request){
$em = $this->getDoctrine()->getManager();
$jsonContent = $request->getContent();
$jsonArr = json_decode($jsonContent, true);
$response = new JsonResponse();
$responseMessage = [];
try{
$ruta = $this->logController->getFolder('1-9', null, 'webhook');
$webhookResource = $jsonArr['resource'];
$webhookFileName = $webhookResource . '_' . date('Ymd_His');
file_put_contents($ruta .'/'. $webhookFileName . ".json", $jsonContent);
$responseMessage['messages'][] = 'Recepcion del webhook ' . $webhookResource . ' - OK';
}
catch(\Exception $e){
$lineNumber = $e->getLine();
$response->setStatusCode(400);
$responseMessage['status'] = 'ERR';
$responseMessage['message'] = $e->getMessage() . ' En la linea: ' . $lineNumber . ' - ' . __FUNCTION__ . ' - ' . self::CONTROLLER_NAME;
$this->logger->error($e->getMessage() . ' En la linea: ' . $lineNumber . ' - ' . __FUNCTION__ . ' - ' . self::CONTROLLER_NAME);
}
$response->setJson(json_encode($responseMessage));
return $response;
}
/**
* Esta funcion recibe la empresaId y verifica si existe creada previamente en el sistema
* en caso de no existir, se procede a la instalacion de la app en multivende
* en caso de existir, se debe realizar el status del code (expiration_time)
* @Rest\Get("/verifyMultivendeInstall/{empresaId}")
*
* @return Response
*/
public function verifyMultivendeInstall(Request $request, $empresaId){
$em = $this->getDoctrine()->getManager();
$response = new JsonResponse();
$responseMessage = array();
// $multivendeClass = new MultivendeClass();
// $jsonArr = json_decode($request->getContent(), true);
// $empresaId = $jsonArr['empresaId'] ?? '';
if($empresaId){
$empresaEntity = $em->getRepository(Empresa::class)->findOneBy(array('webfactura_id' => $empresaId));
if($empresaEntity){
//Empresa con app instalada
$responseMessage['install'] = false;
$responseMessage['updateCode'] = false;
//Verificar status Code
$multivendeEntity = $em->getRepository(MultivendeAssoc::class)->findOneBy(array('empresa_id' => $empresaId));
$accessToken = MultivendeClass::verifyToken($em, $multivendeEntity);
if($accessToken){
// Token obtenido correctamente
$responseMessage['status'] = 'OK';
$responseMessage['expiration'] = $multivendeEntity->getExpiresAt()->format('Y-m-d H:i:s');
}
else{
// El token ha expirado, se requiere actualizar code
$responseMessage['status'] = 'ERR';
$responseMessage['updateCode'] = true;
}
}
else{
//Empresa Nueva retornar Url multivende
$scopes = 'read:stocks,write:stocks,read:checkouts,read:products,write:products,read:clients';
$url = MultivendeClass::getPermisionUrl($request, $scopes);
$responseMessage['install'] = true;
$responseMessage['returnMultivendeUrl'] = $url;
}
}
else{
$response->setStatusCode(400);
$responseMessage['status'] = 'ERR';
$responseMessage['message'] = 'Debe incluir empresaId';
}
$response->setJson(json_encode($responseMessage));
return $response;
}
/**
* Esta funcion recibe la empresaId y el nuevo code a actualizar
* JSON {"empresaId": 1, "code": "XXX"}
* @Rest\POST("/updateCode")
*
* @return Response
*/
public function updateCode(Request $request){
$em = $this->getDoctrine()->getManager();
$response = new JsonResponse();
$responseMessage = array();
$jsonArr = json_decode($request->getContent(), true);
$empresaId = $jsonArr['empresaId'] ?? '';
$code = $jsonArr['code'] ?? '';
if($empresaId && $code){
$multivendeEntity = $em->getRepository(MultivendeAssoc::class)->findOneBy(array('empresa_id' => $empresaId));
if($multivendeEntity){
$multivendeEntity->setCode($code);
$em->persist($multivendeEntity);
$em->flush();
$responseMessage['code'] = 'Codigo actualizado correctamente';
//Obtener nuevo Access Token con el nuevo Code
$accessToken = MultivendeClass::getAccessToken($em, $multivendeEntity);
if($accessToken){
$responseMessage['status'] = 'OK';
$responseMessage['message'] = 'Token de acceso: ' . $accessToken;
}
else{
$responseMessage['message'] = 'No se pudo obtener el token, actualize access token.';
$responseMessage['updateCode'] = true;
}
}
else{
$response->setStatusCode(400);
$responseMessage['message'] = 'No se encontro la instalacion de la empresa';
}
}
else{
$response->setStatusCode(400);
$responseMessage['status'] = 'ERR';
$responseMessage['message'] = 'Debe incluir empresaId y codigo';
}
$response->setJson(json_encode($responseMessage));
return $response;
}
/**
* Funcion que recibe un json con los datos de la empresa y crea la conexion
* JSON {"empresaId": 1, "empresaRut": "XXX", "empresaRazonSocial": "XXX", "wfClientId": "1_XXX", "wfClientSecret": "***" }
* @Rest\POST("/createMultivendeConection")
*
* @return Response
*/
public function createMultivendeConection(Request $request){
$em = $this->getDoctrine()->getManager();
$response = new JsonResponse();
$responseMessage = array();
$jsonArr = json_decode($request->getContent(), true);
$empresaId = $jsonArr['empresaId'] ?? '';
try{
if($empresaId){
$empresaRut = $jsonArr['empresaRut'] ?? '';
$empresaRazonSocial = $jsonArr['empresaRazonSocial'] ?? '';
$wfClientId = $jsonArr['wfClientId'] ?? '';
$wfClientSecret = $jsonArr['wfClientSecret'] ?? '';
$empresaGiro = $jsonArr['empresaGiro'] ?? '';
$empresaDireccion = $jsonArr['empresaDireccion'] ?? '';
$empresaComuna = $jsonArr['empresaComuna'] ?? '';
$empresaCiudad = $jsonArr['empresaCiudad'] ?? '';
$empresaTelefono = $jsonArr['empresaTelefono'] ?? '';
$empresaCorreo = $jsonArr['empresaCorreo'] ?? '';
$empresaPrecioBruto = $jsonArr['empresaPrecioBruto'] ?? '';
$empresaPrecioNeto = $jsonArr['empresaPrecioNeto'] ?? '';
$empresaActividadEconomica = $jsonArr['empresaActividadEconomica'] ?? '';
$empresaEntity = $em->getRepository(Empresa::class)->findOneBy(array('webfactura_id' => $empresaId));
if(!$empresaEntity){
$empresaEntity = new Empresa;
}
$empresaEntity->setEmpresaRut($empresaRut);
$empresaEntity->setEmpresaRazonSocial($empresaRazonSocial);
$empresaEntity->setWebfacturaId($empresaId);
$empresaEntity->setWebfacturaClientId($wfClientId);
$empresaEntity->setWebfacturaClientSecret($wfClientSecret);
$empresaEntity->setEmpresaGiro($empresaGiro);
$empresaEntity->setEmpresaDireccion($empresaDireccion);
$empresaEntity->setEmpresaComuna($empresaComuna);
$empresaEntity->setEmpresaCiudad($empresaCiudad);
$empresaEntity->setEmpresaTelefono($empresaTelefono);
$empresaEntity->setEmpresaCorreo($empresaCorreo);
$empresaEntity->setPrecioBruto($empresaPrecioBruto);
$empresaEntity->setPrecioNeto($empresaPrecioNeto);
$empresaEntity->setEmpresaActividadEconomica($empresaActividadEconomica);
$em->persist($empresaEntity);
$em->flush();
$multivendeEntity = $em->getRepository(MultivendeAssoc::class)->findOneBy(array('empresa_id' => $empresaId));
if(!$multivendeEntity){
$multivendeEntity = new MultivendeAssoc;
}
$multivendeEntity->setEmpresaId($empresaId);
$multivendeEntity->setActive(1);
$multivendeEntity->setClientId(MultivendeClass::CLIENT_ID);
$multivendeEntity->setClientSecret(MultivendeClass::CLIENT_SECRET);
$em->persist($multivendeEntity);
$em->flush();
$responseMessage['status'] = 'OK';
$responseMessage['message'] = 'Conexion Creada correctamente';
}
else{
$response->setStatusCode(400);
$responseMessage['status'] = 'ERR';
$responseMessage['message'] = 'Debe incluir empresaId y codigo';
}
}
catch(\Exception $e){
$lineNumber = $e->getLine();
$response->setStatusCode(400);
$responseMessage['status'] = 'ERR';
$responseMessage['message'] = $e->getMessage() . ' En la linea: ' . $lineNumber . ' - ' . __FUNCTION__ . ' - ' . self::CONTROLLER_NAME;
$this->logger->error($e->getMessage() . ' En la linea: ' . $lineNumber . ' - ' . __FUNCTION__ . ' - ' . self::CONTROLLER_NAME);
}
$response->setJson(json_encode($responseMessage));
return $response;
}
/**
* procesa estructura de refreshToken
* @Rest\POST("/refreshTokenJson")
*
* @return Response
*/
public function refreshTokenJson(Request $request){
$em = $this->getDoctrine()->getManager();
$response = new JsonResponse();
$responseMessage = array();
$jsonArr = json_decode($request->getContent(), true);
$merchantId = $jsonArr['MerchantId'] ?? '';
if($merchantId){
$multivendeEntity = $em->getRepository(MultivendeAssoc::class)->findOneBy(array('merchant_id' => $merchantId));
$accessToken = $jsonArr['token'] ?? '';
$refreshToken = $jsonArr['refreshToken'] ?? '';
$expiresAt = $jsonArr['expiresAt'] ?? '';
$refreshTokenExpiresAt = $jsonArr['refreshTokenExpiresAt'] ?? '';
if($accessToken){
$multivendeEntity->setAccessToken($accessToken);
}
else{
$responseMessage['message'][] = 'No incluye el AccessToken';
}
if($refreshToken){
$multivendeEntity->setRefreshToken($refreshToken);
}
else{
$responseMessage['message'][] = 'No incluye el refreshToken';
}
if($expiresAt){
$utcDateTime = new \DateTime($expiresAt, new \DateTimeZone("UTC"));
$chileTimeZone = new \DateTimeZone("America/Santiago");
$chileDateTime = $utcDateTime->setTimezone($chileTimeZone);
$multivendeEntity->setExpiresAt($chileDateTime);
}
else{
$responseMessage['message'][] = 'No incluye el expiresAt';
}
if($refreshTokenExpiresAt){
$utcRefreshDateTime = new \DateTime($refreshTokenExpiresAt, new \DateTimeZone("UTC"));
$chileRefreshTimeZone = new \DateTimeZone("America/Santiago");
$chileRefreshTimeZone = $utcRefreshDateTime->setTimezone($chileRefreshTimeZone);
$multivendeEntity->setRefreshTokenExpiresAt($chileRefreshTimeZone);
}
else{
$responseMessage['message'][] = 'No incluye el refreshTokenExpiresAt';
}
$em->persist($multivendeEntity);
$em->flush();
$responseMessage['message'][] = 'Se modifica multivendeEntity con los datos proporcionados';
$responseMessage['contenido'] = $jsonArr;
}
else{
$response->setStatusCode(400);
$responseMessage['message'] = 'Debe incluir el merchantId en el json';
$responseMessage['status'] = 'ERR';
}
$response->setJson(json_encode($responseMessage));
return $response;
}
/**
* Verifica Obtencion AccessToken de una empresa
* @Rest\GET("/getAccessToken/{empresaId}")
*
* @return Response
*/
public function getAccessToken(Request $request, $empresaId){
$em = $this->em;
$response = new JsonResponse();
$responseMessage = array();
$multivendeEntity = $em->getRepository(MultivendeAssoc::class)->findOneBy(array('empresa_id' => $empresaId));
try{
if($multivendeEntity){
$accessToken = MultivendeClass::verifyToken($em, $multivendeEntity);
if($accessToken){
$responseMessage['Message'] = 'Access Token obtenido correctamente';
$responseMessage['status'] = 'OK';
$responseMessage['accessToken'] = $accessToken;
}
else{
$response->setStatusCode(400);
$responseMessage['Message'] = 'Error al obtener el token, actualice el code para la empresa ID: ' . $empresaId;
$responseMessage['status'] = 'ERR';
}
}
else{
$response->setStatusCode(400);
$responseMessage['Message'] = 'No se pudo encontrar la instalacion con Multivende para la empresa ID: ' . $empresaId;
$responseMessage['status'] = 'ERR';
}
}
catch(\Exception $e){
$lineNumber = $e->getLine();
$response->setStatusCode(400);
$responseMessage['Message'] = 'Error: '. $e->getMessage() . ' En la linea: ' . $lineNumber . ' - ' . __FUNCTION__ . ' - ' . self::CONTROLLER_NAME;
$responseMessage['status'] = 'ERR';
$this->logger->error($e->getMessage() . ' En la linea: ' . $lineNumber . ' - ' . __FUNCTION__ . ' - ' . self::CONTROLLER_NAME);
}
$response->setJson(json_encode($responseMessage));
return $response;
}
}