HEX
Server: Apache/2.4.41 (Ubuntu)
System: Linux ip-172-31-42-149 5.15.0-1084-aws #91~20.04.1-Ubuntu SMP Fri May 2 07:00:04 UTC 2025 aarch64
User: ubuntu (1000)
PHP: 7.4.33
Disabled: pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_get_handler,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,pcntl_async_signals,pcntl_unshare,
Upload Files
File: /var/www/vhost/disk-apps/qas.sports-crowd.com/app/Core/Membership/Application/MembershipService.php
<?php

declare(strict_types=1);

namespace App\Core\Membership\Application;

use App\Address;
use App\CorporateIdentity;
use App\Core\Academy\Application\MembershipPaymentService;
use App\Core\Membership\Domain\ValueObjects\MembershipOrderStatus;
use App\Core\Membership\Domain\ValueObjects\MembershipStatus;
use App\Core\Parameter\Application\ParameterService;
use App\Core\Payment\Application\PaymentTransactionService;
use App\Core\Servientrega\Application\ServientregaService;
use App\Core\User\Application\UserService;
use App\Erp;
use App\ErpLog;
use App\ErpParameter;
use App\ErpCustomItem;
use App\Events\Memberships\SubscriptionRevoked;
use App\Events\Memberships\SubscriptionConfirmed;
use App\Http\Controllers\ShopifyController;
use App\Models\Membership\Membership;
use App\Models\Membership\MembershipSubscriber;
use App\PaymentTransaction;
use Carbon\Carbon;
use Exception;

// TODO: think in MembershipSubscriptionService
class MembershipService
{
    private $ERPPrefix = 'M';
    private $membershipPaymentService;
    private $userService;
    private $servientregaService;
    private $paymentTransactionService;
    private $parameterService;

    public function __construct()
    {
        $this->membershipPaymentService = new MembershipPaymentService();
        $this->userService = new UserService();
        $this->servientregaService = new ServientregaService();
        $this->paymentTransactionService = new PaymentTransactionService();
        $this->parameterService = new ParameterService();
    }

    public function find(int $membershipSubscriberId)
    {
        return MembershipSubscriber::findOrFail($membershipSubscriberId);
    }

    public function createMembershipSubscription($membership, $user, $startDate = null, $deliveryPrice = null)
    {
        if (!$deliveryPrice && $membership->deliverable) {
            $lastUsedAddress = $this->userService->getLastUsedAddress($user);
            $deliveryPrice = $this->servientregaService->getDeliveryPrice($lastUsedAddress)->price;
        }

        $membershipSubscriber = new MembershipSubscriber();
        $membershipSubscriber->membership_id = $membership->id;
        $membershipSubscriber->user_id = $user->id;
        $membershipSubscriber->status = MembershipStatus::PENDING;
        $membershipSubscriber->price = $membership->price;
        $membershipSubscriber->delivery = $deliveryPrice ?? 0;
        $membershipSubscriber->start_date = $startDate ?? now();
        $membershipSubscriber->end_date = $this->calculateEndDate(
            $membershipSubscriber->start_date,
            $membershipSubscriber->membership->billing_interval
        );
        $membershipSubscriber->auto_renew = false;
        $membershipSubscriber->is_renewal = false;
        $membershipSubscriber->save();

        return $membershipSubscriber;
    }

    public function createFromMembershipSubscription($membershipSubscription)
    {
        $newMembershipSubscription = new MembershipSubscriber();
        $newMembershipSubscription->membership_id = $membershipSubscription->membership_id;
        $newMembershipSubscription->user_id = $membershipSubscription->user_id;
        $newMembershipSubscription->status = MembershipStatus::PENDING;
        $newMembershipSubscription->price = $membershipSubscription->membership->price;
        $newMembershipSubscription->start_date = now();
        $newMembershipSubscription->end_date = $this->calculateEndDate(
            now(),
            $membershipSubscription->membership->billing_interval
        );
        $newMembershipSubscription->is_renewal = true;
        $newMembershipSubscription->save();

        $paymentTransaction = $this->membershipPaymentService->getPaymentTransaction(
            $newMembershipSubscription
        );

        $this->paymentTransactionService->setPaymentGatewayId(
            $paymentTransaction,
            $membershipSubscription->payment_transaction->gateway_payments_id,
        );

        return $newMembershipSubscription;
    }

    public function confirmMembershipOrder($membershipOrder)
    {
        if ($membershipOrder->status != MembershipOrderStatus::PENDING) {
            throw new Exception("You can not confirm this membership", 1);
        }

        foreach ($membershipOrder->items as $item) {
            $membershipSubscription = $this->createMembershipSubscription($item->membership, $item->subscriber);
            $this->confirmMembership($membershipSubscription);
        }

        $membershipOrder->status = MembershipOrderStatus::CONFIRMED;
        $membershipOrder->save();
    }

    public function confirmMembership($membershipSubscription)
    {
        if ($membershipSubscription->status != MembershipStatus::PENDING) {
            throw new Exception("You can not confirm this membership", 1);
        }

        $previousMembership = $this->userService->hasMembership(
            $membershipSubscription->user,
            $membershipSubscription
        );

        if ($previousMembership) {
            $startDate =  max($previousMembership->end_date, $membershipSubscription->start_date);
            $membershipSubscription->end_date = $this->calculateEndDate(
                $startDate,
                $membershipSubscription->membership->billing_interval
            );
            $membershipSubscription->is_renewal = true;
            $previousMembership->status = MembershipStatus::EXPIRED;
            $previousMembership->auto_renew = false;
            $previousMembership->save();
        }

        $membershipSubscription->status = MembershipStatus::CONFIRMED;
        $membershipSubscription->save();

        SubscriptionConfirmed::dispatch($membershipSubscription);
    }

    public function sendConfimationEmail($membershipSubscription)
    {
        $tags = $membershipSubscription->membership->tags;
        $appStoreUrl = $this->parameterService->appStoreUrl();
        $playStoreUrl = $this->parameterService->playStoreUrl();
        $corporateIdentity = CorporateIdentity::first();

        $shopifyController = new ShopifyController();
        $shopifyController->sendConfirmationEmail(
            $membershipSubscription->user->toArray(),
            $tags->first()->name,
            [
                'appStoreUrl'   => $appStoreUrl,
                'playStoreUrl'  => $playStoreUrl,
                'corporateIdentity' => $corporateIdentity
            ]
        );
    }

    public function revokeMembership($membershipSubscription)
    {
        $membershipSubscription->update([
            'status' => MembershipStatus::EXPIRED,
            'auto_renew' => false
        ]);

        SubscriptionRevoked::dispatch($membershipSubscription);

        $this->syncERP($membershipSubscription);
    }

    public function setAsNoRenewable($membershipSubscription)
    {
        $membershipSubscription->auto_renew = false;
        $membershipSubscription->save();
    }

    // TODO: Candidate to be a MembershipQueryService
    public function queryDashboard($request)
    {
        $page = ($request->start / $request->length) + 1;
        $request->merge(['page' => $page]);

        $orderBy = $request->columns[$request->order[0]['column']]['name'];
        $orderDirection = $request->order[0]['dir'];

        if ($orderBy == 'users.name') {
            $orderBy = 'users.first_name';
        }

        $response = MembershipSubscriber::select([
            'membership_subscribers.*',
            'memberships.*',
            'users.*',
            'payment_transactions.*',
            'membership_subscribers.created_at',
        ])
            ->leftJoin('memberships', function ($join) {
                $join->on('memberships.id', '=', 'membership_subscribers.membership_id');
            })
            ->leftJoin('users', function ($join) {
                $join->on('users.id', '=', 'membership_subscribers.user_id');
            })
            ->leftJoin('payment_transactions', function ($join) {
                $join->on('payment_transactions.id', '=', 'membership_subscribers.payment_transaction_id');
            })
            ->when($request->search['value'], function ($query) use ($request) {
                $query->where(function ($query) use ($request) {
                    $query->orWhere('state', 'like', '%' . $request->search['value'] . '%');
                    $query->orWhere('name', 'like', '%' . $request->search['value'] . '%');
                    $query->orWhere('first_name', 'like', '%' . $request->search['value'] . '%');
                    $query->orWhere('last_name', 'like', '%' . $request->search['value'] . '%');
                    $query->orWhere('document', 'like', '%' . $request->search['value'] . '%');
                    $query->orWhere('reference', 'like', '%' . $request->search['value'] . '%');
                    $query->orWhere('gateway_transaction_id', 'like', '%' . $request->search['value'] . '%');
                });
            })
            ->when(!is_null($request->states), function ($query) use ($request) {
                $query->whereIn('membership_subscribers.status', $request->states);
            })
            ->when(!is_null($request->is_renewal), function ($query) use ($request) {
                $query->whereIn('membership_subscribers.is_renewal', $request->is_renewal);
            })
            ->when(!is_null($request->start_date), function ($query) use ($request) {
                $query->where('membership_subscribers.start_date', '>=', $request->start_date);
            })
            ->when(!is_null($request->end_date), function ($query) use ($request) {
                $query->where('membership_subscribers.end_date', '<=', $request->end_date);
            })
            ->orderBy($orderBy, $orderDirection)
            ->paginate();

        return response()->json($response);
    }

    public function queryDownloadReport($request)
    {
        $response = MembershipSubscriber::select([
            'membership_subscribers.id',
            'users.first_name',
            'users.last_name',
            'users.email',
            'users.document',
            'membership_subscribers.status as membership_status',
            'payment_transactions.state as payment_status',
            'membership_subscribers.start_date',
            'membership_subscribers.end_date',
            'membership_subscribers.is_renewal',
            'membership_subscribers.auto_renew',
            'membership_subscribers.tracking_code',
        ])
            ->leftJoin('users', function ($join) {
                $join->on('users.id', '=', 'membership_subscribers.user_id');
            })
            ->leftJoin('payment_transactions', function ($join) {
                $join->on('payment_transactions.id', '=', 'membership_subscribers.payment_transaction_id');
            })
            ->when(!is_null($request->states), function ($query) use ($request) {
                $query->whereIn('membership_subscribers.status', $request->states);
            })
            ->when(!is_null($request->is_renewal), function ($query) use ($request) {
                $query->whereIn('membership_subscribers.is_renewal', $request->is_renewal);
            })
            ->when(!is_null($request->start_date), function ($query) use ($request) {
                $query->where('membership_subscribers.start_date', '>=', $request->start_date);
            })
            ->when(!is_null($request->end_date), function ($query) use ($request) {
                $query->where('membership_subscribers.end_date', '<=', $request->end_date);
            })
            ->get();

        return $response;
    }

    public function createConfirmedMembershipSubscription($params)
    {
        $previousMembershipSubscription = MembershipSubscriber::select('membership_subscribers.id')
            ->join('payment_transactions', 'payment_transactions.id', '=', 'membership_subscribers.payment_transaction_id')
            ->where('payment_transactions.reference', $params->transactionReference)
            ->first();

        if ($previousMembershipSubscription) {
            return;
        }

        $membershipSubscription = $this->createMembershipSubscription(
            $params->membership,
            $params->user,
            $params->startDate,
            $params->deliveryPrice
        );

        $paymentTransaction = PaymentTransaction::create([
            'state' => 'CONFIRMED',
            'origin_class' => get_class($this),
            'gateway_transaction_id' =>  $params->transactionReference
        ]);

        $membershipSubscription->payment_transaction_id = $paymentTransaction->id;
        $membershipSubscription->sync_with_erp = true;
        $membershipSubscription->update();

        $this->confirmMembership($membershipSubscription);
    }

    public function syncERP($membershipSubscription, $action = null)
    {
        try {
            $erpSync = ErpParameter::where('key', 'shop_sync')->first();
            if (!$erpSync || $erpSync->value == 'false') {
                return;
            }

            $erps = Erp::select('id', 'class')->where('active', true)->get();
            foreach ($erps as $index => $erp) {
                $classPath = $erp->class;
                $ERPRepository = new $classPath($erp->id);

                if ($membershipSubscription->status != MembershipStatus::EXPIRED) {
                    if (!$this->validateSyncWithERPPayment($membershipSubscription)) {
                        return;
                    }

                    $previousBill = $ERPRepository->getBill($this->ERPPrefix . $membershipSubscription->id);
                    if ($previousBill['r'] && count($previousBill['d']->detalle->Table)) {
                        return;
                    }
                }

                switch ($action) {
                    case 'createOrder':
                        $this->createOrderERP(
                            $membershipSubscription,
                            $ERPRepository
                        );
                        break;
                    case 'createRC':
                        $this->createRCERP(
                            $membershipSubscription,
                            $ERPRepository
                        );
                        break;
                    case 'createBill':
                        $this->createBillERP(
                            $membershipSubscription,
                            $ERPRepository
                        );
                        break;
                    default:
                        $this->createThirdClientERP(
                            $membershipSubscription,
                            $ERPRepository
                        );
                        break;
                }
            }
        } catch (Exception $e) {
            $error = [
                'message'               => $e->getMessage(),
                'getFile'               => $e->getFile(),
                'getLine'               => $e->getLine(),
            ];
            $this->saveERPLog($membershipSubscription->id, json_encode($error), 'syncERP');
        }
    }

    private function createThirdClientERP($membershipSubscription, $ERPRepository)
    {
        $addressObj = Address::with('city')
            ->where('user_id', $membershipSubscription->user->id)
            ->where('last_used', true)
            ->first();

        if (!$addressObj) {
            $address   = 'Calle 90 #19-41';
            $shortAddress  = $address;
            $country    = 'Colombia';
            $province   = 'Bogotá';
            $city       = 'Bogotá, D.C.';
        } else {
            $address   = $addressObj->direction . ' | ' . $addressObj->district;
            $shortAddress  = $addressObj->direction;

            if ($addressObj->city) {
                $country    = $addressObj->city->state->country->name;
                $province   = $addressObj->city->state->name;
                $city       = $addressObj->city->name;
            }
        }

        $user = $membershipSubscription->user;
        $siesaThirdClient = $ERPRepository->thirdClientValidate($user->document);
        $expired = $membershipSubscription->status == MembershipStatus::EXPIRED;

        $params = new \stdClass();
        $third  = new \stdClass();
        $client = new \stdClass();

        $third->document            = $user->document;
        $third->firstName           = $user->first_name;
        $third->lastName            = $user->last_name;
        $third->contact             = $user->last_name . ' ' . $user->first_name;
        $third->phone               = $user->phone;
        $third->email               = $user->email;
        $third->isNew               = count($siesaThirdClient) == 0;
        $third->documentType        = $ERPRepository->mapDocumentType($user->documentType->alias);
        $third->birthDate           = Carbon::parse($user->userInfo->dob)->format('Ymd');
        $third->typeThird           = 'NATURAL_PERSON';
        $third->gender              = $ERPRepository->mapGender($user->userInfo->sex);
        $third->socialReason        = $third->contact;
        $third->establishmentName   = $third->contact;
        $third->ciiu                = null;

        $client->document       = $user->document;
        $client->contact        = $user->last_name . ' ' . $user->first_name;
        $client->phone          = $user->phone;
        $client->email          = $user->email;

        $params->third          = $third;
        $params->client         = $client;
        $params->address        = $address;
        $params->shortAddress   = $shortAddress;
        $params->country        = $country ?? null;
        $params->province       = $province ?? null;
        $params->city           = $city ?? null;
        $params->sucursal       = '001';
        $params->price_list     = '001';
        $params->typeClient     =  $expired ? 'CTDS' : 'CHED';
        $params->hasTaxes       = '1';
        $params->createThirdPos = true;
        $params->idCriteria     = $expired ? '103' : '105';
        $params->criteria       = $expired ? '1032' : '1051';
        $params->currency       = 'COP';
        $params->latitude       = $addressObj ? $addressObj->lat : null;
        $params->longitude       = $addressObj ? $addressObj->long : null;

        $response = $ERPRepository->createThirdClient($params);
        if (!$response['r']) {
            $this->saveERPLog($membershipSubscription->id, json_encode($response['d']), 'createThirdClient');
            return;
        }

        if (!$expired) {
            $this->createOrderERP($membershipSubscription, $ERPRepository);
        }
    }

    private function createOrderERP($membershipSubscription, $ERPRepository)
    {
        $paymentTransaction = PaymentTransaction::where('id', $membershipSubscription->payment_transaction_id)->first();
        $response = $ERPRepository->getOrder($this->ERPPrefix . $membershipSubscription->id);
        if ($response['r']) {
            $previousOrders = array_filter($response['d']->detalle->Table, function ($siesaOrder) use ($paymentTransaction) {
                $match = str_contains($siesaOrder->Notas, $paymentTransaction->gateway_transaction_id) ||
                    str_contains($siesaOrder->Notas, $paymentTransaction->reference);
                return $match;
            }, ARRAY_FILTER_USE_BOTH);

            if (count($previousOrders)) {
                $this->createRCERP($membershipSubscription, $ERPRepository);
                return;
            }
        }

        $orderParams                    = new \stdClass();
        $orderParams->operationCenter   = '601';
        $orderParams->document          = $membershipSubscription->user->document;
        $orderParams->sucursal          = '001';
        $orderParams->costCenter        = '4001';
        $orderParams->date              = Carbon::parse($paymentTransaction->payment_date)->format('Ymd');
        $orderParams->customerType      = 'CHED';
        $orderParams->note              = $membershipSubscription->membership->name . '-' . $paymentTransaction->reference;
        $orderParams->reference         = $this->ERPPrefix . $membershipSubscription->id;

        $orderParams->items = [
            array(
                'f431_id_co'                => $orderParams->operationCenter,
                'f431_consec_docto'         => '1',
                'f431_nro_registro'         => '1',
                'f431_referencia_item'      => '', //$productVariant['sku'],
                'f431_codigo_barras'        => $membershipSubscription->is_renewal ? '3103144520224' : '1104424520023',
                'f431_id_bodega'            => 'BDHED',
                'f431_id_motivo'            => '60',
                'f431_id_co_movto'          => '601',
                'f431_id_un_movto'          => '104',
                'f431_id_ccosto_movto'      => '1201',
                'f431_fecha_entrega'        => $orderParams->date,
                'f431_id_lista_precio'      => '001',
                'f431_id_unidad_medida'     => 'UND',
                'f431_cant_pedida_base'     => 1,
                'f431_precio_unitario'      => $membershipSubscription->membership->price,
                'f431_ind_precio'           => '1',
                'f431_ind_obsequio'         => '0',
                'f431_ind_impto_asumido'    => '0'
            )
        ];

        if ($membershipSubscription->delivery > 0) {
            $delivery = array(
                'f431_id_co'                => $orderParams->operationCenter,
                'f431_consec_docto'         => '1',
                'f431_nro_registro'         => '1',
                'f431_referencia_item'      => '110440022',
                'f431_codigo_barras'        => '',
                'f431_id_bodega'            => 'BDHED',
                'f431_id_motivo'            => '05',
                'f431_id_co_movto'          => $orderParams->operationCenter,
                'f431_id_un_movto'          => '102',
                'f431_id_ccosto_movto'      => '4001',
                'f431_fecha_entrega'        => $orderParams->date,
                'f431_id_lista_precio'      => '005',
                'f431_id_unidad_medida'     => 'UND',
                'f431_cant_pedida_base'     => '1',
                'f431_precio_unitario'      => (int) $membershipSubscription->delivery,
                'f431_ind_precio'           => '2',
                'f431_ind_obsequio'         => '0',
                'f431_ind_impto_asumido'    => '0'
            );
            array_push($orderParams->items, $delivery);
        }

        $erpCustomItems = ErpCustomItem::where('active', true)
            ->where('amount', '>', 0)
            ->where('modules', 'like', '%membership%')
            ->where(function ($query) {
                $query->orWhereNull('labels');
                $query->orWhere('labels', '');
            })
            ->get();

        foreach ($erpCustomItems as $erpCustomItem) {
            $customItem = array(
                'f431_id_co'                => $orderParams->operationCenter,
                'f431_consec_docto'         => '1',
                'f431_nro_registro'         => count($orderParams->items) + 1,
                'f431_referencia_item'      => $erpCustomItem->reference ?? '',
                'f431_codigo_barras'        => $erpCustomItem->barcode ?? '',
                'f431_id_bodega'            => 'BDHED',
                'f431_id_motivo'            => $erpCustomItem->is_gift ? '08' : '60',
                'f431_id_co_movto'          => '601',
                'f431_id_un_movto'          => '104',
                'f431_id_ccosto_movto'      => '1201',
                'f431_fecha_entrega'        => $orderParams->date,
                'f431_id_lista_precio'      => $erpCustomItem->is_gift ? '015' : '001',
                'f431_id_unidad_medida'     => 'UND',
                'f431_cant_pedida_base'     => $erpCustomItem->amount,
                'f431_precio_unitario'      => 1,
                'f431_ind_precio'           => '1',
                'f431_ind_obsequio'         => $erpCustomItem->is_gift ? '1' : '0',
                'f431_ind_impto_asumido'    => $erpCustomItem->is_gift ? '1' : '0'
            );
            array_push($orderParams->items, $customItem);
        }

        $discounts = [];
        $orderParams->discounts = $discounts;

        $response = $ERPRepository->createOrder($orderParams);
        if (!$response['r']) {
            $this->saveERPLog($membershipSubscription->id, json_encode($response['d']), 'createOrder');
            return;
        }
        $this->createRCERP($membershipSubscription, $ERPRepository);
    }

    private function createRCERP($membershipSubscription, $ERPRepository)
    {
        $paymentTransaction = PaymentTransaction::where('id', $membershipSubscription->payment_transaction_id)->first();
        $response = $ERPRepository->getOrder($this->ERPPrefix . $membershipSubscription->id);
        if (!$response['r']) {
            $this->saveERPLog($membershipSubscription->id, json_encode($response['d']), 'createRC');
            return;
        }

        $user = $membershipSubscription->user;
        $price = $membershipSubscription->membership->price + $membershipSubscription->delivery;
        foreach ($response['d']->detalle->Table as $index => $siesaOrder) {
            $response = $ERPRepository->getRC($user->document, $siesaOrder->CentroDeOperacion);
            if ($response['r']) {
                $previousRC = array_filter($response['d']->detalle->Table, function ($item) use ($paymentTransaction, $price) {
                    return str_contains($item->Notas, $paymentTransaction->reference) && $item->TotalRecibo == $price;
                }, ARRAY_FILTER_USE_BOTH);

                if (count($previousRC)) {
                    $this->createBillERP($membershipSubscription, $ERPRepository);
                    continue;
                }
            }

            $parameters = new \stdClass();
            $parameters->paymentDate = Carbon::parse($paymentTransaction->payment_date)->format('Ymd');
            $parameters->idThird = $user->document;
            $parameters->currency = 'COP';
            $parameters->siesaOrder = $siesaOrder;
            $parameters->fe = '1104';
            $parameters->note = $membershipSubscription->membership->name . '-' . $paymentTransaction->reference;
            $parameters->assistant = '28050507';
            $parameters->sucursal = '001';
            $parameters->paymetMethod = 'WOM';
            $parameters->UN = '104';
            $parameters->price = $price;

            $response = $ERPRepository->createRC($parameters);
            if (!$response['r']) {
                $this->saveERPLog($membershipSubscription->id, json_encode($response['d']), 'createRC');
                return;
            }
            $this->createBillERP($membershipSubscription, $ERPRepository);
        }
    }

    private function createBillERP($membershipSubscription, $ERPRepository)
    {
        $response = $ERPRepository->getOrder($this->ERPPrefix . $membershipSubscription->id);
        if (!$response['r']) {
            $this->saveERPLog($membershipSubscription->id, json_encode($response['d']), 'createBill');
            return;
        }

        $paymentTransaction = PaymentTransaction::where('id', $membershipSubscription->payment_transaction_id)->first();
        foreach ($response['d']->detalle->Table as $index => $siesaOrder) {
            $parameters = new \stdClass();
            $parameters->siesaOrder     = $siesaOrder;
            $parameters->thirdDocument  = $membershipSubscription->user->document;
            $parameters->note           = $membershipSubscription->membership->name . '-' . $paymentTransaction->reference;
            $parameters->price          = $membershipSubscription->membership->price + $membershipSubscription->delivery;
            $parameters->typeDocument   = 'FE1';

            $response = $ERPRepository->createBill($parameters);
            if (!$response['r']) {
                $this->saveERPLog($membershipSubscription->id, json_encode($response['d']), 'createBill');
                return;
            }
        }
        $this->confirmSyncERP($membershipSubscription);
    }

    private function validateSyncWithERPPayment($membershipSubscription)
    {
        return !MembershipSubscriber::select('sync_with_erp')
            ->where('id', $membershipSubscription->id)
            ->first()
            ->sync_with_erp;
    }

    public function saveERPLog($data, $message, $action)
    {
        $transactionId = $data;
        ErpLog::updateOrCreate(
            [
                'origin'         => 'membership',
                'transaction_id' => $transactionId,
                'resolved'       => false
            ],
            [
                'origin'         => 'membership',
                'action'         => $action,
                'origin_class'   => get_class($this),
                'data'           => $data,
                'transaction_id' => $transactionId,
                'message'        => $message,
            ]
        );
    }

    public function confirmSyncERP($membershipSubscription)
    {
        $membershipSubscription->sync_with_erp = true;
        $membershipSubscription->update();
    }

    public function retrySyncERP($data, $action)
    {
        $membershipSubscription = MembershipSubscriber::find($data);
        $this->syncERP($membershipSubscription, $action);
    }

    private function calculateEndDate($date, $interval)
    {
        switch ($interval) {
            case 'yearly':
                return $date->addYear();
                break;

            case 'monthly':
                return $date->addMonth();
                break;

            case 'weekly':
                return $date->addWeek();
                break;

            case 'daily':
                return $date->addDay();
                break;

            default:
                return $date->addDay();
                break;
        }
    }

    public function existBySegementation($segmentation)
    {
        $membership = Membership::select('id', 'active')
            ->join('membership_tags', 'membership_tags.membership_id', '=', 'memberships.id')
            ->whereIn('membership_tags.tag_id', $segmentation)
            ->first();

        return $membership ? true : false;
    }

    public function memershipActiveBySegmentation($segmentation)
    {
        $membership = Membership::select('id')
            ->join('membership_tags', 'membership_tags.membership_id', '=', 'memberships.id')
            ->whereIn('membership_tags.tag_id', $segmentation)
            ->where('memberships.active', true)
            ->first();

        return $membership ? true : false;
    }
}