Skip to content

Instantly share code, notes, and snippets.

@bayareawebpro
Created October 16, 2019 00:32
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bayareawebpro/51fa2d86b01cd428a1611d1234be393f to your computer and use it in GitHub Desktop.
Save bayareawebpro/51fa2d86b01cd428a1611d1234be393f to your computer and use it in GitHub Desktop.
<?php declare(strict_types=1);
namespace App\Leads;
use Carbon\Carbon;
use Illuminate\Support\Arr;
use Illuminate\Support\Str;
use Illuminate\Support\Collection;
use Illuminate\Session\Store as Session;
use Illuminate\Config\Repository as Config;
use Illuminate\Contracts\Support\Arrayable;
use App\Vehicle;
use App\Location;
use App\Leads\Requests\LeadRequest;
use App\Leads\Events\LeadCaptured;
class Lead implements Arrayable
{
const LEAD_SOURCE = 'a1auto';
const DATE_FORMAT = "m-d-Y";
const AUTO_DOMESTIC = "auto";
const AUTO_INTERNATIONAL = "auto_intl";
const MOVING_DOMESTIC = "house_ping_post";
const MOVING_INTERNATIONAL = "house_intl";
const DATE_OFFSET_DAYS = 6;
const DEFAULT_ROOMS = 3;
protected $request, $session, $config;
public function __construct(LeadRequest $request, Session $session, Config $config)
{
$this->request = $request;
$this->session = $session;
$this->config = $config;
}
/**
* Make new instance of self.
* @return static
*/
public static function make(): self
{
return app(self::class);
}
/**
* Get the form type attribute.
* @return string
*/
public function getFormType(): string
{
return (string)$this->session->get('lead.form_type', 'automobile');
}
/**
* Determine the lead form_type attribute matches.
* @param string|array $type
* @return bool
*/
public function isType($type): bool
{
return (bool)(in_array($this->getFormType(), Arr::wrap($type)));
}
/**
* Determine the lead form_type or upsell_form_type attribute matches.
* @param string|array $type
* @return bool
*/
public function isAnyType($type){
return (bool) ($this->isType($type) || $this->isUpSell($type));
}
/**
* Get the lead source attribute.
* @return string
*/
public function getLeadSource(): string
{
return (string)static::LEAD_SOURCE;
}
/**
* Get the formversion attribute.
* @return string
*/
public function getFormVersion():string
{
return (string) $this->session->get('lead.form_version', 'full');
}
/**
* Get the upsell formversion attribute.
* @return string
*/
public function getUpSellFormVersion()
{
if ($this->getFormStep() > 1 && $this->isUpSell()) {
return ($this->isStep(2) ? 'checkbox' : 'thankyou');
}
return null;
}
/**
* Get the form_step attribute.
* @return int
*/
public function getFormStep(): int
{
return (int)$this->session->get('lead.form_step', 1);
}
/**
* Determine the lead form_step attribute matches.
* @param int $step
* @return bool
*/
public function isStep($step = 1): bool
{
return (bool)($this->getFormStep() === $step);
}
/**
* Increment form_step to next step.
* @return $this
*/
public function nextStep(): self
{
if (!$this->isStep(3)) {
$this->session->increment('lead.form_step');
}
return $this;
}
/**
* Determine the lead upsell attribute matches.
* @param null $upsell
* @return bool
*/
public function isUpSell($upsell = null): bool
{
return isset($upsell) ? (bool)(in_array($this->getUpSell(), Arr::wrap($upsell))) : !empty($this->getUpSell());
}
/**
* Get the upsell attribute.
* @return mixed
*/
public function getUpSell()
{
return $this->session->get("lead.upSell");
}
/**
* Get the leadtype attribute.
* @return string
*/
public function getLeadType(): string
{
if ($this->isType('moving')) {
return ($this->isInternational() ? static::MOVING_INTERNATIONAL : static::MOVING_DOMESTIC);
}
return ($this->isInternational() ? static::AUTO_INTERNATIONAL : static::AUTO_DOMESTIC);
}
/**
* Get the upsell attribute.
* @return string
*/
public function getUpSellLeadType()
{
if ($this->isUpSell()) {
if ($this->isUpSell('moving')) {
return ($this->isInternational() ? static::MOVING_INTERNATIONAL : static::MOVING_DOMESTIC);
}
return ($this->isInternational() ? static::AUTO_INTERNATIONAL : static::AUTO_DOMESTIC);
}
return null;
}
/**
* Is the lead (from) domestic?
* @return bool
*/
public function isFromDomestic(): bool
{
return (bool)($this->session->get('lead.pickup_location.iso', 'US') === 'US');
}
/**
* Is the lead (to) domestic?
* @return bool
*/
public function isToDomestic(): bool
{
return (bool)($this->session->get('lead.dropoff_location.iso', 'US') === 'US');
}
/**
* Is the lead (from/to) international?
* @return bool
*/
public function isInternational(): bool
{
return (!$this->isToDomestic() || !$this->isFromDomestic());
}
/**
* Is the lead (from/to) international?
* @return bool
*/
public function isDomestic(): bool
{
return ($this->isToDomestic() && $this->isFromDomestic());
}
/**
* Get the user IP address attribute.
* @return string
*/
public function getIp():string
{
return (string)$this->request->ip();
}
/**
* Get the shipping date attribute.
* @param string $format
* @return string
*/
public function getShipDate($format = self::DATE_FORMAT):string
{
return (string)Carbon::now()->addDays(static::DATE_OFFSET_DAYS)->format($format);
}
/**
* Get the first name attribute.
* @return string
*/
public function getFirstName(): string
{
return (string)Collection::make(explode(' ', $this->getName()))->first();
}
/**
* Get the last name attribute.
* @return string
*/
public function getLastName(): string
{
return (string)Collection::make(explode(' ', $this->getName()))->last();
}
/**
* Get the name attribute.
* @return string
*/
public function getName()
{
return (string)$this->session->get('lead.name', 'John Doe');
}
/**
* Get the email attribute.
* @return string
*/
public function getEmail():string
{
return (string)$this->session->get('lead.email', null);
}
/**
* Get the phone attribute.
* @return string
*/
public function getPhone():string
{
return (string)$this->session->get('lead.phone', null);
}
/**
* Get the vehicle year attribute.
* @return string
*/
public function getYear():string
{
return (string)$this->session->get('lead.year', date('Y'));
}
/**
* Get the vehicle make attribute.
* @return string
*/
public function getMake():string
{
return (string)Str::upper($this->session->get('lead.make', 'Other'));
}
/**
* Get the vehicle model attribute.
* @return string
*/
public function getModel():string
{
return (string)Str::upper($this->session->get('lead.model', 'Other'));
}
/**
* Get the vehicle style attribute.
* @return string
*/
public function getStyle():string
{
if($this->isType(['heavy_equipment', 'freight'])){
return (string)Str::upper(str_replace('_', ' ', $this->getFormType()));
}
return (string)Str::upper(Vehicle::getStyleByName($this->getModel()));
}
/**
* Get the moving rooms count attribute.
* @return string|null
*/
public function getRooms()
{
if ($this->isAnyType('moving')) {
$rooms = (int)$this->session->get('lead.rooms', static::DEFAULT_ROOMS);
return ($rooms <= static::DEFAULT_ROOMS ? $rooms : static::DEFAULT_ROOMS);
}
return null;
}
/**
* Format the moving rooms count as "x bedrooms".
* @return string|null
*/
public function getBedRooms()
{
if ($rooms = $this->getRooms()) {
return "{$rooms} " . Str::plural("Bedroom", $rooms);
}
return null;
}
/**
* Get the Marketing ID attribute.
* @return string
*/
public function getMarketingId():string
{
return (string)$this->session->get('referrer_id', 'unknown');
}
/**
* Get the Referer attribute.
* @return string
*/
public function getReferer():string
{
return (string)$this->session->get('lead.referer', url('/'));
}
/**
* Get the to city attribute.
* @return string
*/
public function getToCity():string
{
return (string)Str::upper((string)$this->session->get("lead.dropoff_location.city"));
}
/**
* Get the from city attribute.
* @return string
*/
public function getFromCity():string
{
return (string)Str::upper((string)$this->session->get("lead.pickup_location.city"));
}
/**
* Get the to capital city attribute.
* @return string|null
*/
public function getToCapital()
{
$query = Location::query()
->where('capital', 1)
->where('iso', $this->getToISO());
if ($this->isToDomestic()) {
$query->where('state', $this->getToState());
}
return Str::upper(optional($query->first())->city) ?? null;
}
/**
* Get the from city capital attribute.
* @return string|null
*/
public function getFromCapital()
{
$query = Location::query()
->where('capital', 1)
->where('iso', $this->getFromISO());
if ($this->isFromDomestic()) {
$query->where('state', $this->getFromState());
}
return Str::upper(optional($query->first())->city) ?? null;
}
/**
* Get the to state attribute.
* @return string
*/
public function getToState():string
{
return (string)Str::upper((string)$this->session->get("lead.dropoff_location.state"));
}
/**
* Get the from state attribute.
* @return string
*/
public function getFromState():string
{
return (string)Str::upper((string)$this->session->get("lead.pickup_location.state"));
}
/**
* Get the to zip attribute.
* @return string
*/
public function getToZip():string
{
return (string)Str::limit((string)$this->session->get("lead.dropoff_location.zip"), 5, '');
}
/**
* Get the from zip attribute.
* @return string
*/
public function getFromZip():string
{
return (string)Str::limit((string)$this->session->get("lead.pickup_location.zip"), 5, '');
}
/**
* Get the to country attribute.
* @return string
*/
public function getToCountry():string
{
return (string)Str::upper($this->session->get("lead.dropoff_location.country", "UNITED STATES"));
}
/**
* Get the from country attribute.
* @return string
*/
public function getFromCountry():string
{
return (string)Str::upper($this->session->get("lead.pickup_location.country"));
}
/**
* Get the to ISO attribute.
* @return string
*/
public function getToISO():string
{
return (string)$this->session->get("lead.dropoff_location.iso", "US");
}
/**
* Get the from ISO attribute.
* @return string
*/
public function getFromISO():string
{
return (string)$this->session->get("lead.pickup_location.iso");
}
/**
* Get the to latitude attribute.
* @return float|null
*/
public function getToLatitude()
{
return $this->session->get("lead.dropoff_location.latitude");
}
/**
* Get the from latitude attribute.
* @return float|null
*/
public function getFromLatitude()
{
return $this->session->get("lead.pickup_location.latitude");
}
/**
* Get the to longitude attribute.
* @return float|null
*/
public function getToLongitude()
{
return $this->session->get("lead.dropoff_location.longitude");
}
/**
* Get the from longitude attribute.
* @return float|null
*/
public function getFromLongitude()
{
return $this->session->get("lead.pickup_location.longitude");
}
/**
* Merge request attributes with session.
* @return $this
*/
public function saveSession()
{
$this->appendReferer();
$this->session->put('lead', array_merge($this->session->get('lead', []), $this->request->validated()));
$this->handleSubmissions();
return $this;
}
/**
* Append the referer attribute.
* @return $this
*/
protected function appendReferer(): self
{
if ($this->isStep(1)) {
$this->session->put('lead.referer',
url($this->request->headers->get('referer', $this->session->previousUrl() ?? $this->request->fullUrl()))
);
}
return $this;
}
/**
* Handle submissions via events.
* @return $this
*/
protected function handleSubmissions(): self
{
if ($this->getFormStep() > 1) {
LeadCaptured::dispatch($this);
}
return $this;
}
/**
* Get the instance as a collection.
* @return Collection
*/
public function toCollection(): Collection
{
return Collection::make($this->toArray());
}
/**
* Get the instance as an array.
* @return array
*/
public function toArray(): array
{
return [
'ip' => $this->getIp(),
'referer' => $this->getReferer(),
'lead_source' => $this->getLeadSource(),
'marketing_id' => $this->getMarketingId(),
'leadtype' => $this->getLeadType(),
'formversion' => $this->getFormVersion(),
'shipdate' => $this->getShipDate(),
'form_type' => $this->getFormType(),
'form_step' => $this->getFormStep(),
'upsell' => $this->getUpSell(),
'upsell_leadtype' => $this->getUpSellLeadType(),
'upsell_formversion' => $this->getUpSellFormVersion(),
//Person
'name' => $this->getName(),
'email' => $this->getEmail(),
'phone' => $this->getPhone(),
//Vehicle: veh_year
'vehicle_year' => $this->getYear(),
'vehicle_make' => $this->getMake(),
'vehicle_model' => $this->getModel(),
'vehicle_type' => $this->getStyle(),
'rooms' => $this->getRooms(),
'bedrooms' => $this->getBedRooms(),
//Pickup Location: fcity
'from_iso' => $this->getFromISO(),
'from_zip' => $this->getFromZip(),
'from_city' => $this->getFromCity(),
'from_state' => $this->getFromState(),
'from_country' => $this->getFromCountry(),
'from_capital' => $this->getFromCapital(),
'from_latitude' => $this->getFromLatitude(),
'from_longitude' => $this->getFromLongitude(),
'from_isDomestic' => $this->isFromDomestic(),
//Dropoff Location: tcity
'to_iso' => $this->getToISO(),
'to_zip' => $this->getToZip(),
'to_city' => $this->getToCity(),
'to_state' => $this->getToState(),
'to_country' => $this->getToCountry(),
'to_capital' => $this->getToCapital(),
'to_latitude' => $this->getToLatitude(),
'to_longitude' => $this->getToLongitude(),
'to_isDomestic' => $this->isToDomestic(),
];
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment