<?php
namespace Aqarmap\Bundle\ListingBundle\Entity;
use Aqarmap\Bundle\FinancialAidsBundle\Entity\FinancialAid;
use Aqarmap\Bundle\FinancialAidsBundle\Utilities\FinancialAidURL;
use Aqarmap\Bundle\ListingBundle\Constant\CompoundStatus;
use Aqarmap\Bundle\ListingBundle\Constant\EligibleForMortgageData;
use Aqarmap\Bundle\ListingBundle\Constant\ListingCategories;
use Aqarmap\Bundle\ListingBundle\Constant\ListingCustomFields;
use Aqarmap\Bundle\ListingBundle\Constant\ListingFeaturedTypes;
use Aqarmap\Bundle\ListingBundle\Constant\ListingFeatures;
use Aqarmap\Bundle\ListingBundle\Constant\ListingPaymentMethod;
use Aqarmap\Bundle\ListingBundle\Constant\ListingPriceLevel;
use Aqarmap\Bundle\ListingBundle\Constant\ListingPropertyView;
use Aqarmap\Bundle\ListingBundle\Constant\ListingRateConstant;
use Aqarmap\Bundle\ListingBundle\Constant\ListingRateReviewStatus;
use Aqarmap\Bundle\ListingBundle\Constant\ListingRateStatus;
use Aqarmap\Bundle\ListingBundle\Constant\ListingSections;
use Aqarmap\Bundle\ListingBundle\Constant\ListingSellerRoles;
use Aqarmap\Bundle\ListingBundle\Constant\ListingStatus;
use Aqarmap\Bundle\ListingBundle\Constant\PhotoTypes;
use Aqarmap\Bundle\ListingBundle\Constant\PluralCustomFields;
use Aqarmap\Bundle\ListingBundle\Constant\PropertyRegistrationStatusOption;
use Aqarmap\Bundle\ListingBundle\Document\ScrapedListing;
use Aqarmap\Bundle\ListingBundle\Entity\Traits\CallLog;
use Aqarmap\Bundle\ListingBundle\Security\Authorization\OwnerInterface;
use Aqarmap\Bundle\ListingBundle\Validator\Constraints as AqarMapAssert;
use Aqarmap\Bundle\UserBundle\Constant\TeamCategories;
use Aqarmap\Bundle\UserBundle\Entity\User;
use Aqarmap\Bundle\UserBundle\Model\UserMainPhones;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\Common\Collections\Criteria;
use Doctrine\ORM\Mapping as ORM;
use Gedmo\Mapping\Annotation as Gedmo;
use Gedmo\Translatable\Translatable;
use JMS\Serializer\Annotation as Serializer;
use Symfony\Component\Validator\Constraints as Assert;
/**
* Listing.
*
* @ORM\Table(name="listings", indexes={
*
* @ORM\Index(columns={"pending_photos_status"}),
* @ORM\Index(columns={"pending_payment_status"}),
* @ORM\Index(columns={"relist_status"}),
* @ORM\Index(columns={"featured"}),
* @ORM\Index(columns={"deleted_at"}),
* @ORM\Index(columns={"created_at"}),
* @ORM\Index(columns={"published_at"}),
* @ORM\Index(columns={"user_id", "deleted_at"}),
* @ORM\Index(columns={"user_id", "status"}),
* @ORM\Index(columns={"user_id", "status", "deleted_at"}),
* @ORM\Index(columns={"user_id", "status", "location_id"}),
* @ORM\Index(columns={"user_id", "status", "location_id", "parent_id", "category", "deleted_at"}),
* @ORM\Index(columns={"user_id", "status", "location_id", "property_type_id", "section_id", "parent_id", "category", "deleted_at"}),
* @ORM\Index(columns={"location_id", "section_id", "property_type_id", "status", "published_at"}),
* @ORM\Index(columns={"user_id", "section_id", "leads_counter"}),
* @ORM\Index(columns={"category", "parent_id", "updated_at"}),
* @ORM\Index(columns={"category", "parent_id", "waiting_time"}),
* @ORM\Index(columns={"status", "category", "parent_id"}),
* @ORM\Index(columns={"reference_number"}),
* @ORM\Index(columns={"status", "leads_counter"}),
* @ORM\Index(columns={"user_id", "creation_source", "deleted_at"}),
* @ORM\Index(columns={"status", "location_id", "parent_id", "user_id", "deleted_at"}),
* })
*
* @ORM\HasLifecycleCallbacks
*
* @ORM\Entity(repositoryClass="Aqarmap\Bundle\ListingBundle\Repository\ListingRepository")
*
* @Gedmo\TranslationEntity(class="Aqarmap\Bundle\ListingBundle\Entity\ListingTranslation")
*
* @Gedmo\SoftDeleteable(fieldName="deletedAt", timeAware=false)
*
* @Serializer\ExclusionPolicy("all")
*/
class Listing implements OwnerInterface, Translatable
{
use CallLog;
/**
* @var int
*
* @ORM\Column(name="id", type="integer")
*
* @ORM\Id
*
* @ORM\GeneratedValue(strategy="AUTO")
*
* @Serializer\Groups({
* "Default", "List", "listingDetails", "listingDetailsWithLocationCompound", "Details", "Activity",
* "DataLayer", "ActivitiesData", "DefaultV4", "MyListing", "MyListings", "SearchV4", "ProjectSearchV4",
* "ProjectDetailsV4", "UnitDetails", "Autocomplete", "RelatedListingsV2", "SlugResolver", "locationListingV2",
* "homeCompoundV2", "MyLeads"
* })
*
* @Serializer\Expose
*/
private $id;
/**
* @ORM\OneToMany(targetEntity="Listing", mappedBy="parent")
*
* @ORM\OrderBy({"area" = "ASC"})
*
* @Serializer\Groups({"List", "Details"})
*
* @Serializer\Expose
*
* @Serializer\Until("v2.1")
*/
private $children;
/**
* @ORM\ManyToOne(targetEntity="Listing", inversedBy="children")
*
* @ORM\JoinColumn(name="parent_id", referencedColumnName="id")
*
* @Serializer\Groups({"List", "Details", "DataLayer", "UnitDetails"})
*
* @Serializer\Expose
*
* @Serializer\Until("v2.1")
*
* @Serializer\MaxDepth(1)
*/
private $parent;
/**
* @ORM\OneToOne(targetEntity="Listing")
*
* @ORM\JoinColumn(name="relist_id", referencedColumnName="id")
*/
private $relistParent;
/**
* @ORM\Column(name="title", type="string", length=128, nullable=true)
*
* @Gedmo\Translatable
*
* @Serializer\Groups({
* "Default", "List", "Details", "listingDetails", "listingDetailsWithLocationCompound", "Activity", "Preview",
* "DefaultV4", "MyListing", "MyListings", "SearchV4", "ProjectSearchV4", "ProjectDetailsV4", "Autocomplete",
* "RelatedListingsV2", "SlugResolver","locationListingV2", "homeCompoundV2", "MyLeads"
* })
*
* @Serializer\Expose
*
* @Assert\NotBlank(message="listing.title_required", groups={"step2"})
*/
private ?string $title = null;
/**
* @ORM\Column(name="description", type="text", length=1024, nullable=true)
*
* @Gedmo\Translatable
*
* @Serializer\Groups({"List", "Details", "listingDetails", "Activity", "DefaultV4", "MyListing", "MyListings", "SearchV4", "ProjectDetailsV4"})
*
* @Serializer\Expose
*
* @Assert\NotBlank(message="listing.description_required", groups={"step2"})
*/
private ?string $description = null;
/**
* @ORM\ManyToOne(targetEntity="Section", inversedBy="listings")
*
* @ORM\JoinColumn(name="section_id", referencedColumnName="id")
*
* @Serializer\Groups({"MyListings", "List", "Details", "listingDetails", "DataLayer", "DefaultV4", "MyListing", "SearchV4"})
*
* @Serializer\Expose
*
* @Assert\NotBlank(groups={"API"})
*/
protected $section;
/**
* @var int
*
* @ORM\Column(name="category", type="smallint", nullable=false)
*
* @Serializer\Groups({"List", "Details", "listingDetails"})
*
* @Serializer\Expose
*/
private $category;
/**
* @var int
*
* @ORM\Column(name="pending_photos_status", type="smallint", nullable=true)
*/
private $pendingPhotosStatus;
/**
* @var int
*
* @ORM\Column(name="pending_payment_status", type="smallint", nullable=true)
*/
private $pendingPaymentStatus;
/**
* @var int
*
* @ORM\Column(name="relist_status", type="smallint", nullable=true)
*/
private $relistStatus;
/**
* @ORM\Column(name="seller_role", type="smallint", nullable=true)
*
* @Serializer\Expose
*
* @Serializer\Groups({"Details", "listingDetails"})
*
* @Serializer\Since("v2.1")
*/
private ?int $sellerRole = null;
private $sellerRoleLabel;
/**
* @var int
*
* @ORM\Column(name="area", type="integer", nullable=true)
*
* @Serializer\Groups({"List", "Details", "DefaultV4", "MyListing", "MyListings", "SearchV4", "UnitDetails", "RelatedListingsV2", "listingDetails"})
*
* @Serializer\Expose
*
* @Assert\NotBlank(message="listing.area_required", groups={"step2"})
*
* @Assert\GreaterThan(value = 1, message="listing.area_minimum", groups={"step2"})
*/
private $area;
/**
* CAUTION: type-hint string to avoid unnecessary update on every fetch.
*
* @ORM\Column(name="price", type="bigint", nullable=true)
*
* @Serializer\Groups({"List", "Details", "listingDetails", "Activity", "Preview", "DefaultV4", "MyListing", "MyListings", "SearchV4", "UnitDetails", "RelatedListingsV2"})
*
* @Serializer\Expose
*
* @Assert\NotBlank(message="listing.price_required", groups={"step2"})
*
* @Assert\GreaterThan(value = 100, message="listing.price_minimum", groups={"step2"})
*/
private ?string $price = null;
/**
* @var string
*
* @ORM\Column(name="address", type="text", length=512, nullable=true)
*
* @Gedmo\Translatable
*
* @Serializer\Groups({"List", "Details", "listingDetails", "Activity", "Preview", "DefaultV4", "SearchV4", "RelatedListingsV2", "locationListingV2", "homeCompoundV2", "MyListings"})
*
* @Serializer\Expose
*
* @Assert\Length(max=100)
*
* @Assert\NotBlank(message="listing.address_required", groups={"step2"})
*/
private $address;
/**
* @var float
*
* @ORM\Column(name="center_lat", type="float", nullable=true)
*
* @Serializer\Groups({"List", "Details", "listingDetails"})
*
* @Serializer\Expose
*/
private $centerLat;
/**
* @var float
*
* @ORM\Column(name="center_lng", type="float", nullable=true)
*
* @Serializer\Groups({"List", "Details", "listingDetails"})
*
* @Serializer\Expose
*/
private $centerLng;
/**
* @var int
*
* @ORM\Column(name="status", type="smallint", nullable=true)
*
* @Serializer\Groups({"List", "Details", "Activity", "listingDetails"})
*
* @Serializer\Expose
*/
private $status;
private $statusLabel;
/**
* @var int
*
* @Serializer\Groups({"List", "Details", "listingDetails", "SearchV4"})
*
* @Serializer\Expose
*
* @ORM\Column(name="property_view", type="smallint", nullable=true)
*/
private $propertyView;
private $propertyViewLabel;
/**
* @var int
*
* @Serializer\Groups({"List", "Details"})
*
* @Serializer\Expose
*
* @ORM\Column(name="payment_method", type="smallint", nullable=true)
*/
private $paymentMethod;
private $paymentMethodLabel;
/**
* @var bool
*
* @ORM\Column(name="featured", type="smallint", nullable=true)
*/
private $featured;
/**
* @var int
*
* @ORM\Column(name="views", type="integer", nullable=true)
*
* @Serializer\Groups({"Api", "MyListing"})
*
* @Serializer\Expose
*/
private $views = 0;
/**
* @var int
*
* @ORM\Column(name="phone_counter", type="integer", options={"default" = 0})
*
* @Serializer\Groups({"Api"})
*
* @Serializer\Expose
*/
private $phoneCounter = 0;
/**
* @var int
*
* @ORM\Column(name="messages_counter", type="integer", options={"default" = 0})
*
* @Serializer\Groups({"Api"})
*
* @Serializer\Expose
*/
private $messagesCounter = 0;
/**
* @ORM\Column(name="leads_counter", type="integer", options={"default" = 0})
*
* @Serializer\Groups({"Api"})
*
* @Serializer\Expose
*/
private int $leadsCounter = 0;
/**
* @var int
*
* @ORM\Column(name="sent_notifiers", type="integer", nullable=true)
*/
private $sentNotifiers;
/**
* @var int
*
* @ORM\Column(name="relist_counter", type="integer", nullable=true)
*/
private $relistCounter;
/**
* @var string
*
* @ORM\Column(name="ip", type="string", length=50, nullable=true)
*/
private $ip;
/**
* @var string
*
* @ORM\Column(name="video_url", type="string", length=150, nullable=true)
*
* @AqarMapAssert\IsYoutubeUrlOrNull
*
* @Serializer\Groups({"List", "Details", "listingDetails", "Activity", "DefaultV4", "ProjectSearchV4", "ProjectDetailsV4"})
*
* @Serializer\Expose
*/
private $videoUrl;
/**
* @ORM\Column(name="slug", length=128, nullable=true)
*
* @Serializer\Groups({"locationListingV2", "SearchV4", "listingDetails"})
*
* @Serializer\Expose
*/
private $slug;
/**
* @ORM\Column(name="custom_slug", length=50, unique=true, nullable=true)
*
* @Serializer\Groups({"DataLayer"})
*
* @Serializer\Expose
*/
private $customSlug;
/**
* @var int
*
* @ORM\Column(name="score", type="float", nullable=true)
*/
private $score;
/**
* @ORM\Column(name="created_at", type="datetime", nullable=true)
*
* @Serializer\Groups({"MyListings"})
*
* @Serializer\Expose()
*/
private $createdAt;
/**
* @var \DateTime
*
* @ORM\Column(name="updated_at", type="datetime", nullable=true)
*
* @Serializer\Groups({"Details", "DefaultV4", "List", "SearchV4", "listingDetails"})
*
* @Serializer\Expose()
*/
private $updatedAt;
/**
* @var \DateTime
*
* @ORM\Column(name="pending_status_created_at", type="datetime", nullable=true)
*
* @Serializer\Groups({"Details", "DefaultV4", "List","SearchV4"})
*
* @Serializer\Expose()
*/
private $pendingStatusCreatedAt;
/**
* @var \DateTime
*
* @ORM\Column(name="published_at", type="datetime", nullable=true)
*
* @Serializer\Groups({"List", "Details", "DefaultV4", "SearchV4", "ProjectSearchV4", "ProjectDetailsV4", "MyListings"})
*
* @Serializer\Expose
*
* @Assert\Range(
* max = "now",
* maxMessage = "listing.date_not_allowed"
* )
*/
private $publishedAt;
/**
* @var \DateTime;
*/
private $aggregatedPublishedAt;
/**
* @var \DateTime
*
* @ORM\Column(name="expires_at", type="datetime", nullable=true)
*
* @Serializer\Groups({"DefaultV4", "MyListing", "MyListings"})
*
* @Serializer\Expose
*/
private $expiresAt;
/**
* @ORM\Column(name="deleted_at", type="datetime", nullable=true)
*
* @Serializer\Groups({"listingDetails"})
*
* @Serializer\Expose
*/
private $deletedAt;
/**
* @ORM\Column(name="rejected_at", type="datetime", nullable=true)
*/
private $rejectedAt;
/**
* @ORM\OrderBy({"averagePricePerMeter" = "DESC"})
*
* @ORM\OneToMany(targetEntity="CompoundAveragePrice", mappedBy="parentCompound", cascade={"all"})
**/
private $compoundAveragePrices;
/**
* @ORM\ManyToOne(targetEntity="PropertyType", inversedBy="listings")
*
* @ORM\JoinColumn(name="property_type_id", referencedColumnName="id")
*
* @Serializer\Groups({"MyListings", "List", "Details", "listingDetails", "Activity", "DefaultV4", "SearchV4", "MyLeads"})
*
* @Serializer\Expose
*
* @Assert\NotBlank(groups={"API"})
*/
protected $propertyType;
/**
* @ORM\ManyToOne(targetEntity="Location", inversedBy="listings")
*
* @ORM\JoinColumn(name="location_id", referencedColumnName="id")
*
* @Serializer\Groups({"List", "Details", "listingDetails", "Activity", "DefaultV4", "SearchV4", "ProjectDetailsV4", "RelatedListingsV2"})
*
* @Serializer\Expose
*/
protected $location;
/**
* @ORM\ManyToMany(targetEntity="Location")
*
* @ORM\JoinTable(
* name="listings_locations",
* joinColumns={@ORM\JoinColumn(name="listing_id", referencedColumnName="id")},
* inverseJoinColumns={@ORM\JoinColumn(name="location_id", referencedColumnName="id")}
* )
**/
protected $locations;
/**
* @ORM\ManyToOne(targetEntity="CompoundLocation", inversedBy="listings")
*
* @ORM\JoinColumn(name="compound_location_id", referencedColumnName="id", nullable=true)
*
* @Serializer\Groups({"Default", "ProjectSearchV4"})
*
* @Serializer\Expose
**/
protected $compoundLocation;
/**
* @ORM\ManyToOne(targetEntity="\Aqarmap\Bundle\UserBundle\Entity\User", inversedBy="listings")
*
* @ORM\JoinColumn(name="user_id", referencedColumnName="id", onDelete="CASCADE", nullable=false)
*
* @Serializer\Groups({"List", "Details", "listingDetails", "DefaultV4", "MyListing", "SearchV4", "ProjectDetailsV4", "ProjectSearchV4", "RelatedListingsV2", "MyListings", "MyLeads"})
*
* @Serializer\Expose
*/
protected $user;
/**
* @ORM\ManyToMany(targetEntity="\Aqarmap\Bundle\UserBundle\Entity\User", fetch="EXTRA_LAZY")
*
* @ORM\JoinTable(
* name="listings_participants",
* joinColumns={@ORM\JoinColumn(name="listing_id", referencedColumnName="id")},
* inverseJoinColumns={@ORM\JoinColumn(name="user_id", referencedColumnName="id")}
* )
**/
protected $participants;
/**
* @ORM\OneToMany(targetEntity="ListingAttribute", mappedBy="listing", cascade={"all"}, orphanRemoval=true)
*
* @Serializer\Groups({"List", "Details", "Preview", "listingDetails"})
*
* @Serializer\Expose
*
* @Assert\Valid
**/
protected $attributes;
/**
* @ORM\OneToMany(
* targetEntity="ListingPhone",
* mappedBy="listing",
* cascade={"all"},
* orphanRemoval=true
* )
*
* @Assert\Valid
**/
protected $phones;
/**
* @ORM\OneToMany(targetEntity="ListingPhoto", mappedBy="listing", cascade={"persist", "remove"}, orphanRemoval=true)
**/
protected $photos;
/**
* @ORM\OneToMany(
* targetEntity="ListingTranslation",
* mappedBy="object",
* cascade={"all"},
* orphanRemoval=true
* )
*/
private $translations;
/**
* @ORM\OneToMany(targetEntity="Aqarmap\Bundle\ListingBundle\Entity\ListingLead", mappedBy="listing", fetch="EXTRA_LAZY")
**/
protected $leads;
/**
* @ORM\OneToMany(targetEntity="ListingFeature", mappedBy="listing")
**/
protected $listingFeatures;
/**
* @ORM\OneToMany(targetEntity="ListingNotification", mappedBy="listing")
**/
protected $ListingNotifications;
/**
* @ORM\ManyToMany(targetEntity="Rejection")
*
* @ORM\JoinTable(name="listings_rejections",
* joinColumns={@ORM\JoinColumn(name="listing_id", referencedColumnName="id")},
* inverseJoinColumns={@ORM\JoinColumn(name="rejection_id", referencedColumnName="id")}
* )
*
* @Serializer\Groups({"userListing"})
*
* @Serializer\Expose
*
**/
protected $rejections;
/**
* @var string
*
* @ORM\Column(name="campaign", type="string", length=50, nullable=true)
*
* @Serializer\Groups({"List", "Details", "DefaultV4", "MyListing"})
*
* @Serializer\Expose
*/
private $campaign;
/**
* @var int
*
* @ORM\Column(name="final_price", type="integer", nullable=true)
*/
private $finalPrice;
/**
* @var string
*
* @ORM\Column(name="source_of_sale", type="string", nullable=true)
*/
private $sourceOfSale;
/**
* @var string
*
* @ORM\Column(name="delete_reason", type="string", length=100, nullable=true)
*/
private $deleteReason;
/**
* @var string
*
* @ORM\Column(name="delete_reason_details", type="text", nullable=true)
*/
private $deleteReasonDetails;
/**
* @ORM\OneToMany(targetEntity="Aqarmap\Bundle\ListingBundle\Entity\Interaction",mappedBy="listing")
*/
private $interactions;
/**
* @var string
*/
private $userLogo;
/**
* @var string
*/
private $listingLogo;
/**
* @Gedmo\Locale()
*/
private $locale;
/**
* @ORM\Column(name="source",type="string",nullable=true)
*/
private $source;
private $elasticSearchScore;
/**
* @var float
*/
private $qualityScore;
/**
* @ORM\Column(name="impressions", type="integer", options={"default" = 0})
*
* @Serializer\SerializedName("impressions_count")
*
* @Serializer\Groups({"List", "Details", "MyListing", "MyListings"})
*
* @Serializer\Expose
*/
private int $impressions = 0;
/**
* @ORM\Column(name="impressions_monthly_count", type="integer", options={"default" = 0})
*
* @Serializer\SerializedName("impressions_monthly_count")
*
* @Serializer\Groups({"List", "Details"})
*
* @Serializer\Expose
*/
private int $impressionsMonthlyCount = 0;
/**
* @ORM\Column(name="impressions_weekly_count", type="integer", options={"default" = 0})
*
* @Serializer\SerializedName("impressions_weekly_count")
*
* @Serializer\Groups({"List", "Details"})
*
* @Serializer\Expose
*/
private int $impressionsWeeklyCount = 0;
/**
* @var \DateTime
*
* @ORM\Column(name="impression_updated_at", type="datetime", nullable=true)
*/
private $impressionUpdatedAt;
/**
* @ORM\Column(name="price_level", type="smallint", nullable=true)
*
* @Serializer\Expose
*/
private $priceLevel;
/**
* @var string
*/
private $priceLevelLabel;
/**
* @ORM\Column(name="compound_status", type="smallint", nullable=true)
*
* @Serializer\Expose
*/
private $compoundStatus;
/**
* @var string
*/
private $compoundStatusLabel;
/**
* @ORM\Column(name="price_per_meter", type="float", nullable=true)
*
* @Serializer\Expose
*
* @Serializer\Groups({"listingDetails"})
*/
private $pricePerMeter;
/**
* @ORM\Column(name="is_bumped", type="boolean", nullable=true)
*/
private ?bool $isBumped = false;
/**
* @ORM\Column(name="is_send_email", type="boolean", options={"default" = 1})
*
* @Serializer\Expose()
*
* @Serializer\Groups({"DefaultV4", "SearchV4", "RelatedListingsV2"})
*/
private $isSendEmail = true;
/**
* @ORM\Column(name="market_property_type", type="smallint", nullable=true)
*
* @Serializer\Groups({"DefaultV4","SearchV4","Details"})
*
* @Serializer\Expose
*/
private ?int $marketPropertyType = null;
/**
* @var int
*
* @ORM\Column(name="creation_source", type="smallint", nullable=true)
*/
private $creationSource;
/**
* @deprecated
*
* @var int
*
* @ORM\Column(name="click_through_rate", type="float", options={"default" = 0})
*/
private $clickThroughRate = 0;
/**
* @var int
*
* @ORM\Column(name="label", type="smallint", nullable=true)
*/
private $label;
/**
* @ORM\Column(name="is_top_picks", type="boolean", options={"default" = 0})
*/
private $isTopPicks = false;
/**
* @var int
*
* @ORM\Column(name="contact_rate", type="float", options={"default" = 0})
*/
private $contactRate = 0;
/**
* @ORM\OneToMany(targetEntity="Aqarmap\Bundle\ListingBundle\Entity\ListingRate", mappedBy="listing", fetch="EXTRA_LAZY")
*/
private $rates;
/**
* @var int
*/
private $totalRates;
/**
* @var ArrayCollection
*/
private $rateReasonsCollection;
/**
* @ORM\Column(name="synced", type="boolean")
*/
private $synced = false;
/**
* @ORM\Column(name="reference_id", type="integer", nullable=true)
*/
private $referenceId;
private $featuredTypeLabel;
/**
* @ORM\OneToMany(targetEntity="Aqarmap\Bundle\ListingBundle\Entity\Favourite", mappedBy="listing")
*/
protected $favourite;
/**
* @ORM\OneToMany(targetEntity="Aqarmap\Bundle\ValueEngineBundle\Entity\ValueEngineListingsLocations", mappedBy="listing")
**/
protected $valueEngineListingsLocations;
/**
* @ORM\Column(name="is_pending_featuring", type="boolean", nullable=true)
*/
private $isPendingFeaturing = false;
/**
* @ORM\Column(name="pending_featuring_type", type="integer", nullable=true)
*/
private $pendingFeaturingType;
/**
* @ORM\OneToMany(targetEntity="Aqarmap\Bundle\ListingBundle\Entity\ListingNote", mappedBy="listing")
*/
protected $notes;
/**
* @var bool
*/
private $isFavourite = false;
/**
* @var string
*/
private $userNote;
/**
* @ORM\Column(name="rate_status", type="smallint", nullable=true)
*/
private $rateStatus;
/**
* @ORM\Column(name="is_rate_reviewed", type="boolean", nullable=true, options={"default" = 0})
*/
private $isRateReviewed = false;
/**
* @ORM\Column(name="is_call_request", type="boolean", options={"default" = 0})
*
* @Serializer\SerializedName("isCallRequest")
*
* @Serializer\Groups({"List", "Details", "Search", "DefaultV4", "SearchV4","ProjectDetailsV4", "RelatedListingsV2", "listingDetails"})
*
* @Serializer\Expose
*/
private $isCallRequest = false;
/**
* @ORM\Column(name="is_shown_in_homepage", type="boolean", options={"default" = 0})
*
* @Serializer\Groups({"List", "Details", "DefaultV4"})
*
* @Serializer\Expose
*/
private $isShownInHomepage = false;
/**
* @var DateTime
*/
private $reportedDate;
/**
* @var Listing
*/
private $parentOfSimilarListing;
/**
* @Serializer\SerializedName("attributes")
*
* @Serializer\Groups({"NotesDetails"})
*
* @Serializer\Expose()
*/
private $listingAttributes = [];
/**
* TODO:This Field Is maily Related To Compounds Will Be removed with new project compounds Valu.
*
* @var int
*
* @ORM\Column(name="is_commercial", type="smallint", nullable=true)
*/
private $isCommercial = false;
/**
* @var array
*/
private $mappedPhotos = [];
/**
* @var array
*/
private $v4Translations = [];
private ?array $mappedMainPhoto = null;
/**
* @var bool
*
* @ORM\Column(name="is_resale", type="boolean", options={"default" = 0})
*
* @Serializer\SerializedName("isResale")
*
* @Serializer\Groups({"List", "Details", "Search", "DefaultV4", "SearchV4", "ProjectDetailsV4"})
*
* @Serializer\Expose
*/
private $isResale = false;
/**
* @var bool
*
* @ORM\Column(name="is_rent", type="boolean", options={"default" = 0})
*
* @Serializer\SerializedName("isRent")
*
* @Serializer\Groups({"List", "Details", "Search", "DefaultV4", "SearchV4", "ProjectDetailsV4"})
*
* @Serializer\Expose
*/
private $isRent = false;
/**
* @var bool
*
* @ORM\Column(name="is_primary", type="boolean", options={"default" = 0})
*
* @Serializer\SerializedName("isPrimary")
*
* @Serializer\Groups({"List", "Details", "Search", "DefaultV4", "SearchV4", "ProjectDetailsV4"})
*
* @Serializer\Expose
*/
private $isPrimary = false;
/**
* @var bool
*
* @ORM\Column(name="is_mortgage_approved", type="boolean", nullable=true)
*
* @Serializer\SerializedName("isMortgageApproved")
*
* @Serializer\Groups({"List", "Details", "Search", "DefaultV4", "SearchV4", "listingDetails"})
*
* @Serializer\Expose
*/
private $isMortgageApproved;
/**
* @ORM\OneToMany(targetEntity="Aqarmap\Bundle\ListingBundle\Entity\ListingsRatesNote", mappedBy="listing")
*
* @Serializer\Groups({"List", "Details"})
*
* @Serializer\Expose
*/
private $ratesNotes = [];
/**
* @var string
*
* @ORM\Column(name="meta_title", type="string", length=128, nullable=true)
*
* @Gedmo\Translatable
*/
private $metaTitle;
/**
* @var string
*
* @ORM\Column(name="meta_description", type="text", length=1024, nullable=true)
*
* @Gedmo\Translatable
*/
private $metaDescription;
/**
* @var bool
*
* @ORM\Column(name="is_mortgage", type="boolean", options={"default" = 0})
*
* @Serializer\SerializedName("isMortgage")
*
* @Serializer\Groups({"List", "Details", "Search", "DefaultV4", "SearchV4", "RelatedListingsV2"})
*
* @Serializer\Expose
*/
private $isMortgage = false;
/**
* @var CompoundField
*
* @ORM\OneToOne(targetEntity="Aqarmap\Bundle\ListingBundle\Entity\CompoundField")
*
* @ORM\JoinColumn(name="compound_field_id", referencedColumnName="id")
*/
protected $compoundField;
/** @var array
*
* @ORM\Column(name="eligible_for_mortgage", type="array", nullable=true)
*/
private $eligibleForMortgage;
/**
* @var array
*/
private $propertyRegistrationStatusOptions;
/**
* @var array
*/
private $eligibleForMortgageData;
/**
* property Registration Status , default I'm not know = 4.
*
* @var int
*
* @ORM\Column(name="property_registration_status", type="integer", nullable=true ,options={"default" = 4})
*
* @Serializer\SerializedName("propertyRegistrationStatus")
*
* @Serializer\Groups({"List", "Details", "Search", "DefaultV4", "SearchV4"})
*
* @Serializer\Expose
*/
private $propertyRegistrationStatus;
/**
* @var array
*
* @Serializer\SerializedName("propertyTypeChildren")
*
* @Serializer\Groups({"ProjectDetailsV4"})
*
* @Serializer\Expose
*/
private $propertyTypeChilden = [];
/**
* @var float
*/
private $compoundElasticScore;
/**
* @var FinancialAid
*/
private $financialAid;
/**
* @deprecated It's bad design, and cause a performance issues
*/
private int $similarListingsCount = 0;
/**
* @deprecated It's bad design, and cause a performance issues
*/
private array $similarListingsIds = [];
/**
* @var string|null
*
* @ORM\Column(name="advertiser_number", type="string", nullable=true)
*
* @Serializer\SerializedName("advertiserNumber")
*
* @Serializer\Groups({"List", "Details", "Search", "DefaultV4", "SearchV4"})
*
* @Serializer\Expose
*/
private $advertiserNumber;
/**
* @var string|null
*
* @ORM\Column(name="authorization_number", type="string", nullable=true)
*
* @Serializer\SerializedName("authorizationNumber")
*
* @Serializer\Groups({"List", "Details", "Search", "DefaultV4", "SearchV4"})
*
* @Serializer\Expose
*/
private $authorizationNumber;
/**
* @var float
*/
private $costPerLead = 0;
/**
* @Serializer\Groups({"ProjectDetailsV4"})
*
* @Serializer\SerializedName("resaleCount")
*
* @Serializer\Expose
*/
private $resaleCount = 0;
/**
* @Serializer\Groups({ "ProjectDetailsV4"})
*
* @Serializer\SerializedName("rentCount")
*
* @Serializer\Expose
*/
private $rentCount = 0;
/**
* @var \DateTime
*
* @ORM\Column(name="freezed_at", type="datetime", nullable=true)
*/
private $freezedAt;
/**
* @ORM\Column(name="eligible_for_bumpup", type="boolean", options={"default" = 0})
*/
private $eligibleForBumpUp = false;
/**
* @ORM\Column(name="waiting_time", type="string", length=50, nullable=true)
*
* @var string
*/
private $waitingTime;
/**
* @ORM\Column(name="reference_number", type="string", length=128, nullable=true)
*
* @Serializer\Groups({"Default", "MyListing", "MyListings", "listingDetails", "MyLeads"})
*
* @Serializer\Expose
*/
private ?string $referenceNumber = null;
/**
* @Serializer\Groups({"SearchV4"})
*
* @Serializer\Expose
*/
public $debug;
/**
* Constructor.
*/
public function __construct()
{
$this->children = new ArrayCollection();
$this->attributes = new ArrayCollection();
$this->phones = new ArrayCollection();
$this->photos = new ArrayCollection();
$this->leads = new ArrayCollection();
$this->rates = new ArrayCollection();
$this->listingFeatures = new ArrayCollection();
$this->ListingNotifications = new ArrayCollection();
$this->translations = new ArrayCollection();
$this->rejections = new ArrayCollection();
$this->participants = new ArrayCollection();
$this->rateReasonsCollection = new ArrayCollection();
$this->favourite = new ArrayCollection();
}
/**
* Clone.
*/
public function __clone()
{
$this->id = null;
$this->slug = null;
$this->children = null;
$this->title = null;
$this->address = null;
$this->description = null;
$this->translations = null;
$this->leads = new ArrayCollection();
$this->participants = null;
$this->featured = 0;
$this->views = 0;
$this->customSlug = null;
$this->relistCounter = 0;
$this->messagesCounter = 0;
$this->phoneCounter = 0;
$this->sentNotifiers = 0;
$this->isBumped = false;
$this->ratesNotes = new ArrayCollection();
$this->compoundField = null;
$this->compoundAveragePrices = null;
}
/**
* @ORM\PrePersist
*/
public function onPrePersist(): void
{
if (!$this->getCreatedAt()) {
$this->setCreatedAt(new \DateTime());
}
if (!$this->getUpdatedAt()) {
$this->setUpdatedAt(new \DateTime());
}
}
/**
* Get id.
*
* @return int
*/
public function getId()
{
return $this->id;
}
/**
* Set title.
*
* @param string $title
*
* @return Listing
*/
public function setTitle($title)
{
$this->title = $title;
return $this;
}
/**
* Get title.
*
* @return string
*/
public function getTitle()
{
return $this->title;
}
/**
* Set description.
*
* @param string $description
*
* @return Listing
*/
public function setDescription($description)
{
$this->description = $description;
return $this;
}
/**
* Get description.
*
* @return string
*/
public function getDescription()
{
return $this->description;
}
/**
* Set section.
*
* @return Listing
*/
public function setSection(?Section $section = null)
{
$this->section = $section;
return $this;
}
/**
* Get section.
*
* @return Section
*/
public function getSection()
{
return $this->section;
}
/**
* Set category.
*
* @param int $category
*
* @return Listing
*/
public function setCategory($category)
{
$this->category = $category;
return $this;
}
/**
* Get category.
*
* @return int
*/
public function getCategory()
{
return $this->category;
}
/**
* Get category name.
*
* @return string
*/
public function getCategoryName()
{
return ListingCategories::getLabel($this->category);
}
/**
* @return bool
*/
public function isDraft()
{
return ListingStatus::DRAFT == $this->status;
}
/**
* @return bool
*/
public function isLive()
{
return ListingStatus::LIVE == $this->status;
}
/**
* Set pendingPhotosStatus.
*
* @param int $pendingPhotosStatus
*
* @return Listing
*/
public function setPendingPhotosStatus($pendingPhotosStatus)
{
$this->pendingPhotosStatus = $pendingPhotosStatus;
return $this;
}
/**
* Get pendingPhotosStatus.
*
* @return int
*/
public function getPendingPhotosStatus()
{
return $this->pendingPhotosStatus;
}
/**
* Set pendingPaymentStatus.
*
* @param int $pendingPaymentStatus
*
* @return Listing
*/
public function setPendingPaymentStatus($pendingPaymentStatus)
{
$this->pendingPaymentStatus = $pendingPaymentStatus;
return $this;
}
/**
* Get pendingPaymentStatus.
*
* @return int
*/
public function getPendingPaymentStatus()
{
return $this->pendingPaymentStatus;
}
/**
* Set relistStatus.
*
* @param int $relistStatus
*
* @return Listing
*/
public function setRelistStatus($relistStatus)
{
$this->relistStatus = $relistStatus;
return $this;
}
/**
* Get relistStatus.
*
* @return int
*/
public function getRelistStatus()
{
return $this->relistStatus;
}
/**
* Set sellerRole.
*/
public function setSellerRole(?int $sellerRole): self
{
$this->sellerRole = $sellerRole;
return $this;
}
/**
* Get sellerRole.
*/
public function getSellerRole(): ?int
{
return $this->sellerRole;
}
/**
* @Serializer\VirtualProperty
*
* @Serializer\SerializedName("seller_role")
*
* @Serializer\Groups({"List", "Details", "listingDetails"})
*
* @Serializer\Until("v2.0")
*
* @return string
*/
public function getSellerRoleLabel()
{
return ListingSellerRoles::getLabel($this->getSellerRole());
}
public function setSellerRoleLabel($label): void
{
$this->sellerRoleLabel = $label;
}
/**
* @Serializer\VirtualProperty
*
* @Serializer\SerializedName("seller_role_label")
*
* @Serializer\Groups({"List", "Details"})
*
* @Serializer\Since("v2.1")
*
* @Serializer\Until("v2.11")
*
* @return string
*/
public function getSellerRoleAsLabel()
{
return self::getSellerRoleLabel();
}
/**
* @Serializer\VirtualProperty
*
* @Serializer\SerializedName("seller_role_label")
*
* @Serializer\Groups({"List", "Details", "DefaultV4"})
*
* @Serializer\Since("v2.12")
*
* @return string
*/
public function getSellerRoleTranslated()
{
return $this->sellerRoleLabel;
}
/**
* @Serializer\VirtualProperty
*
* @Serializer\SerializedName("accepts_messages")
*
* @Serializer\Groups({"List", "Details", "listingDetails"})
*
* @return bool
*/
public function isAcceptsMessages()
{
return !$this->getUser()->hasRole('ROLE_TROOP');
}
/**
* Set area.
*
* @param int $area
*
* @return Listing
*/
public function setArea($area)
{
$this->area = $area;
return $this;
}
/**
* Get area.
*
* @return int
*/
public function getArea()
{
return (int) $this->area;
}
/**
* Set price.
*
* @return Listing
*/
public function setPrice(?int $price)
{
$this->price = $price;
return $this;
}
/**
* Get price.
*/
public function getPrice(): ?int
{
return $this->price;
}
/**
* Set address.
*
* @param string $address
*
* @return Listing
*/
public function setAddress($address)
{
$this->address = $address;
return $this;
}
/**
* Get address.
*
* @return string
*/
public function getAddress()
{
return $this->address;
}
/**
* Set centerLat.
*
* @param float $centerLat
*
* @return Listing
*/
public function setCenterLat($centerLat)
{
$this->centerLat = $centerLat;
return $this;
}
/**
* Get centerLat.
*
* @return float
*/
public function getCenterLat()
{
return $this->centerLat;
}
/**
* Set centerLng.
*
* @param float $centerLng
*
* @return Listing
*/
public function setCenterLng($centerLng)
{
$this->centerLng = $centerLng;
return $this;
}
/**
* Get centerLng.
*
* @return float
*/
public function getCenterLng()
{
return $this->centerLng;
}
/**
* Set featured.
*
* @param int $featured
*
* @return Listing
*/
public function setFeatured($featured)
{
$this->featured = $featured;
return $this;
}
/**
* Get featured.
*
* @return int
*/
public function getFeatured()
{
return $this->featured;
}
/**
* @Serializer\VirtualProperty
*
* @Serializer\SerializedName("is_featured")
*
* @Serializer\Groups({"List", "Details", "DataLayer", "MyListing", "MyListings", "listingDetails"})
*
* @return bool
*/
public function isFeatured()
{
return (bool) $this->getFeatured();
}
/**
* @Serializer\VirtualProperty
*
* @Serializer\SerializedName("isFeatured")
*
* @Serializer\Groups({"DefaultV4", "SearchV4"})
*
* @return bool
*/
public function getFeaturingStatus()
{
return (bool) $this->getFeatured();
}
/**
* @return string
*/
public function getFeaturedLabel()
{
return ListingFeaturedTypes::getLabel($this->getFeatured());
}
/**
* Set views.
*
* @param int $views
*
* @return Listing
*/
public function setViews($views)
{
$this->views = $views;
return $this;
}
/**
* Get views.
*
* @return int
*/
public function getViews()
{
return $this->views ? $this->views : 0;
}
/**
* Get views count.
*
* @return int
*/
public function getTotalViews()
{
$totalViews = $this->getViews();
if ($this->getChildren()) {
foreach ($this->getChildren() as $listing) {
$totalViews += $listing->getViews();
}
}
return $totalViews;
}
/**
* Set relistCounter.
*
* @param int $relistCounter
*
* @return Listing
*/
public function setRelistCounter($relistCounter)
{
$this->relistCounter = $relistCounter;
return $this;
}
/**
* Get relistCounter.
*
* @return int
*/
public function getRelistCounter()
{
return $this->relistCounter;
}
/**
* Set sentNotifiers.
*
* @param int $sentNotifiers
*
* @return Listing
*/
public function setSentNotifiers($sentNotifiers)
{
$this->sentNotifiers = $sentNotifiers;
return $this;
}
/**
* Get sentNotifiers.
*
* @return int
*/
public function getSentNotifiers()
{
return $this->sentNotifiers;
}
/**
* Set status.
*
* @param int $status
*
* @return Listing
*/
public function setStatus($status)
{
$this->status = $status;
return $this;
}
/**
* Get status.
*
* @return int
*/
public function getStatus()
{
return $this->status;
}
/**
* @Serializer\VirtualProperty
*
* @Serializer\SerializedName("status_label")
*
* @Serializer\Groups({"List", "Details", "listingDetails"})
*
* @Serializer\Until("v2.11")
*
* @return string
*/
public function getStatusLabel()
{
return ListingStatus::getLabel($this->getStatus());
}
/**
* @Serializer\VirtualProperty
*
* @Serializer\SerializedName("status_label")
*
* @Serializer\Groups({"List", "Details"})
*
* @Serializer\Since("v2.12")
*
* @return string
*/
public function getStatusTranslated()
{
return $this->statusLabel;
}
public function setStatusLabel($label): void
{
$this->statusLabel = $label;
}
/**
* @return string
*/
public function getStatusDescription()
{
return ListingStatus::getDescription($this->getStatus());
}
/**
* Set ip.
*
* @param string $ip
*
* @return Listing
*/
public function setIp($ip)
{
$this->ip = $ip;
return $this;
}
/**
* Get ip.
*
* @return string
*/
public function getIp()
{
return $this->ip;
}
/**
* @param string $videoUrl
*
* @return $this
*/
public function setVideoUrl($videoUrl)
{
$this->videoUrl = $videoUrl;
return $this;
}
/**
* @return string
*/
public function getVideoUrl()
{
return $this->videoUrl;
}
/**
* Set slug.
*
* @param string $slug
*
* @return Listing
*/
public function setSlug($slug)
{
$this->slug = $slug;
return $this;
}
/**
* Get slug.
*
* @return string
*/
public function getSlug()
{
return $this->slug;
}
/**
* Set customSlug.
*
* @param string $customSlug
*
* @return Listing
*/
public function setCustomSlug($customSlug)
{
$this->customSlug = str_replace(' ', '-', strtolower($customSlug));
return $this;
}
/**
* Get customSlug.
*
* @param bool $force
*
* @return string
*/
public function getCustomSlug($force = false)
{
if ($force && empty($this->customSlug)) {
return $this->slug;
}
return $this->customSlug;
}
/**
* Set score.
*
* @param float $score
*
* @return Listing
*/
public function setScore($score)
{
$this->score = $score;
return $this;
}
/**
* Get score.
*
* @return float
*/
public function getScore()
{
return $this->score;
}
/**
* Set maxPrice.
*
* @param int $maxPrice
*
* @return Listing
*/
public function setMaxPrice($maxPrice)
{
$this->maxPrice = $maxPrice;
return $this;
}
/**
* Get maxPrice.
*
* @return int
*/
public function getMaxPrice()
{
return $this->maxPrice;
}
/**
* Set createdAt.
*
* @param \DateTime $createdAt
*
* @return Listing
*/
public function setCreatedAt($createdAt)
{
$this->createdAt = $createdAt;
return $this;
}
/**
* Get createdAt.
*
* @Serializer\VirtualProperty()
*
* @Serializer\Groups({"MyListing"})
*
* @Serializer\Expose
*
* @return \DateTime
*/
public function getCreatedAt()
{
return $this->createdAt;
}
/**
* Set updatedAt.
*
* @param \DateTime $updatedAt
*
* @return Listing
*/
public function setUpdatedAt($updatedAt)
{
$this->updatedAt = $updatedAt;
return $this;
}
/**
* Get updatedAt.
*
* @return \DateTime
*/
public function getUpdatedAt()
{
return $this->updatedAt;
}
/**
* Set pendingStatusCreatedAt.
*
* @param \DateTime $pendingStatusCreatedAt
*
* @return Listing
*/
public function setPendingStatusCreatedAt($pendingStatusCreatedAt)
{
$this->pendingStatusCreatedAt = $pendingStatusCreatedAt;
return $this;
}
/**
* Get pendingStatusCreatedAt.
*
* @return \DateTime
*/
public function getPendingStatusCreatedAt()
{
return $this->pendingStatusCreatedAt;
}
/**
* Set publishedAt.
*
* @return Listing
*/
public function setPublishedAt(?\DateTime $publishedAt = null)
{
$this->publishedAt = $publishedAt;
return $this;
}
/**
* Get publishedAt.
*
* @return \DateTime
*/
public function getPublishedAt()
{
return $this->publishedAt;
}
/**
* @Serializer\VirtualProperty()
*
* @return \DateTime|ArrayCollection|Collection
*/
public function getAggregatedPublishedAt()
{
$lastBump = $this->getLastAutoBumpUp();
/** @var ListingFeature $lastFeature */
$lastFeature = $this->getLastListingFeature();
$listingFeature = null;
if ($lastBump && $lastFeature) {
$listingFeature = ($lastBump->getLastBumpedAt() > $lastFeature->getCreatedAt()) ? $lastBump : $lastFeature;
} elseif ($lastBump) {
$listingFeature = $lastBump;
} elseif ($lastFeature) {
$listingFeature = $lastFeature;
}
if (!$listingFeature) {
return $this->getPublishedAt();
}
return (ListingFeatures::BUMP_UP == $listingFeature->getType() && $listingFeature->getLastBumpedAt()) ?
$listingFeature->getLastBumpedAt() : $listingFeature->getCreatedAt();
}
/**
* Set expiresAt.
*
* @param \DateTime $expiresAt
*
* @return Listing
*/
public function setExpiresAt($expiresAt)
{
$this->expiresAt = $expiresAt;
return $this;
}
/**
* Get expiresAt.
*
* @return \DateTime
*/
public function getExpiresAt()
{
return $this->expiresAt;
}
public function setDeletedAt(?\DateTime $deletedAt): Listing
{
$this->deletedAt = $deletedAt;
return $this;
}
/**
* Get deletedAt.
*
* @return \DateTime
*/
public function getDeletedAt()
{
return $this->deletedAt;
}
/**
* Set rejectedAt.
*
* @param \DateTime $rejectedAt
*
* @return Listing
*/
public function setRejectedAt($rejectedAt)
{
$this->rejectedAt = $rejectedAt;
return $this;
}
/**
* Get rejectedAt.
*
* @return \DateTime
*/
public function getRejectedAt()
{
return $this->rejectedAt;
}
/**
* Add children.
*
* @return Listing
*/
public function addChild(self $children)
{
$this->children[] = $children;
return $this;
}
/**
* Remove children.
*/
public function removeChild(self $children): void
{
$this->children->removeElement($children);
}
/**
* Get children.
*
* @return Collection
*/
public function getChildren()
{
$criteria = Criteria::create()
->orderBy(['id' => Criteria::ASC]);
if (!$this->children) {
return null;
}
return $this->children->matching($criteria);
}
/**
* Get only live listing children (live units) and order by area.
*/
public function getLiveChildren(?PropertyType $propertyType = null)
{
$criteria = Criteria::create()->where(Criteria::expr()->eq('status', ListingStatus::LIVE));
if ($propertyType) {
$criteria->where(Criteria::expr()->eq('propertyType', $propertyType));
}
$criteria->orderBy(['area' => Criteria::ASC]);
if (empty($this->children)) {
return null;
}
return $this->children->matching($criteria);
}
public function getLiveChildrenIDs()
{
$ids = [];
foreach ($this->getLiveChildren() as $listing) {
$ids[] = $listing->getId();
}
return $ids;
}
/**
* Get only pending listing children (live units) and order by area.
*/
public function getPendingChildren()
{
$criteria = Criteria::create()
->where(Criteria::expr()->in('status', ListingStatus::$pendingStatusArray))
->orderBy(['area' => Criteria::ASC]);
return $this->children->matching($criteria);
}
/**
* Set parent.
*
* @return Listing
*/
public function setParent(?self $parent = null)
{
$this->parent = $parent;
return $this;
}
/**
* Get parent.
*
* @return Listing
*/
public function getParent()
{
return $this->parent;
}
/**
* Get Relist Parent.
*
* @return Listing
*/
public function getRelistParent()
{
return $this->relistParent;
}
public function setRelistParent(self $relistParent): void
{
$this->relistParent = $relistParent;
}
/**
* Set propertyType.
*
* @return Listing
*/
public function setPropertyType(?PropertyType $propertyType = null)
{
$this->propertyType = $propertyType;
return $this;
}
/**
* Get propertyType.
*
* @return PropertyType
*/
public function getPropertyType()
{
return $this->propertyType;
}
/**
* Set location.
*
* @return Listing
*/
public function setLocation(?Location $location = null)
{
$this->location = $location;
return $this;
}
/**
* Get location.
*
* @return Location
*/
public function getLocation()
{
return $this->location;
}
/**
* Add location.
*
* @return Listing
*/
public function addLocation(Location $location)
{
$this->locations[] = $location;
return $this;
}
/**
* Has location.
*
* @return bool
*/
public function hasLocation(Location $location)
{
return $this->locations->contains($location);
}
/**
* Set Locations.
*
* @return Listing
*/
public function setLocations($locations)
{
foreach ($locations as $location) {
$this->addLocation($location);
}
return $this;
}
/**
* Remove location.
*/
public function removeLocation(Location $location): void
{
$this->locations->removeElement($location);
}
/**
* Get locations.
*
* @return Collection
*/
public function getLocations()
{
return $this->locations;
}
/**
* @return $this
*/
public function setCompoundLocation(?CompoundLocation $compoundLocation = null)
{
$this->compoundLocation = $compoundLocation;
return $this;
}
/**
* @return CompoundLocation
*/
public function getCompoundLocation()
{
if (!$this->compoundLocation && $this->hasParent()) {
return $this->getParent()->getCompoundLocation();
}
return $this->compoundLocation;
}
/**
* @return mixed|string
*/
public function getCompoundLocationTitle()
{
$compoundLocation = $this->getCompoundLocation();
if ($compoundLocation instanceof CompoundLocation) {
return $compoundLocation->getTitle();
}
return '';
}
/**
* Set user.
*
* @return Listing
*/
public function setUser(?User $user = null)
{
$this->user = $user;
return $this;
}
/**
* Get user.
*
* @return User
*/
public function getUser()
{
return $this->user;
}
/**
* Add participants.
*
* @return Listing
*/
public function addParticipant(User $participants)
{
$this->participants[] = $participants;
return $this;
}
/**
* Remove participants.
*/
public function removeParticipant(User $participants): void
{
$this->participants->removeElement($participants);
}
/**
* Get participants.
*
* @return Collection
*/
public function getParticipants()
{
return $this->participants;
}
/**
* Has participant.
*
* @return bool
*/
public function hasParticipant(User $participant)
{
$participants = $this->getParticipants();
if (\is_object($participants)) {
return $this->getParticipants()->contains($participant) ? true : false;
}
return false;
}
/**
* @return ArrayCollection
*/
public function getAllParticipants()
{
$participants = new ArrayCollection();
$participants->add($this->getUser());
foreach ($this->getParticipants() as $participant) {
if (!$participants->contains($participant)) {
$participants->add($participant);
}
}
if ($this->getParent()) {
foreach ($this->getParent()->getAllParticipants() as $participant) {
if (!$participants->contains($participant)) {
$participants->add($participant);
}
}
}
return $participants;
}
/**
* @return ArrayCollection
*/
public function getAllLocations()
{
$locations = new ArrayCollection();
$locations->add($this->getLocation());
foreach ($this->getLocations() as $location) {
if (!$locations->contains($location)) {
$locations->add($location);
}
}
return $locations;
}
/**
* @return array
*/
public function getAllLocationsIDs()
{
$locations = new ArrayCollection();
$locations->add($this->getLocation()->getId());
foreach ($this->getLocations() as $location) {
if (!$locations->contains($location->getId())) {
$locations->add($location->getId());
}
}
return $locations->toArray();
}
/**
* Add attribute.
*
* @return Listing
*/
public function addAttribute(ListingAttribute $attribute)
{
if (!$attribute->isValid()) {
return $this;
}
$attribute->setListing($this);
$this->attributes[] = $attribute;
return $this;
}
/**
* Set attributes.
*
* @return Listing
*/
public function setAttributes($attributes)
{
foreach ($attributes as $attribute) {
if (
$attribute instanceof ListingAttribute
&& !$attribute->isValid()
) {
continue;
}
$this->addAttribute($attribute);
}
return $this;
}
/**
* Remove attribute.
*/
public function removeAttribute(ListingAttribute $attribute): void
{
$this->attributes->removeElement($attribute);
}
/**
* Clear attributes.
*/
public function clearAttributes(): void
{
$this->attributes->clear();
}
/**
* Get attributes.
*
* @return Collection
*/
public function getAttributes()
{
return $this->attributes;
}
/**
* Get Attributes in List.
*
* @return array
*/
public function getAttributesList()
{
$attributeList = [];
foreach ($this->attributes as $attribute) {
$value = $attribute->getValue();
if (
PluralCustomFields::MAX_VALUE == $value
&& \in_array($attribute->getCustomField()->getName(), PluralCustomFields::getChoices())
) {
$value = PluralCustomFields::MAX_VALUE_LABEL;
}
$attributeList[$attribute->getCustomField()->getName()] = $value;
if (ListingCustomFields::FINISH_TYPE_NAME == $attribute->getCustomField()->getName()) {
$attributeList[$attribute->getCustomField()->getName()] = $attribute->getValue();
}
}
return $attributeList;
}
/**
* Get attributes.
*
* @return Collection
*/
public function getAttribute($attrName)
{
foreach ($this->attributes as $attribute) {
if ($attrName == $attribute->getCustomField()->getName()) {
return $attribute;
}
}
}
/**
* Add phones.
*
* @param ListingPhone $phone
*
* @return Listing
*/
public function addPhone($phone)
{
$phone->setListing($this); // Synchronously updating inverse side
$criteria = Criteria::create()->where(Criteria::expr()->eq('number', $phone->getNumber()));
if ($this->getPhones()->matching($criteria)->isEmpty()) {
$this->phones[] = $phone;
}
return $this;
}
/**
* Set Phones.
*
* @return Listing
*/
public function setPhones($phones)
{
foreach ($phones as $phone) {
$this->addPhone($phone);
}
return $this;
}
/**
* Remove phone.
*/
public function removePhone(ListingPhone $phone): void
{
$phone->setListing(null);
$this->phones->removeElement($phone);
}
public function removePhones(): void
{
foreach ($this->phones as $phone) {
$this->removePhone($phone);
}
}
/**
* Get phones.
*
* @Serializer\Groups({"List", "Details", "RelatedListingsV2", "listingDetails"})
*
* @Serializer\VirtualProperty
*
* @Serializer\Expose
*
* @return ArrayCollection
*/
public function getPhones()
{
return $this->listMainListingPhonesFromUser();
}
/**
* Get Mapped Phones For V4.
*
* @Serializer\Groups({"DefaultV4", "SearchV4", "ProjectDetailsV4", "ProjectSearchV4","locationListingV2"})
*
* @Serializer\VirtualProperty
*
* @Serializer\SerializedName("phones")
*
* @Serializer\Expose
*
* @return array
*/
public function getMappedPhones()
{
$phones = [];
/** @var $phone ListingPhone */
foreach ($this->getPhones() as $phone) {
$phones[] = $phone->getPhone();
}
return $phones;
}
/**
* Get phones for listing from the user phones.
*
* @Serializer\Groups({"List", "Details", "listingDetails", "SearchV4"})
*
* @Serializer\VirtualProperty
*
* @Serializer\Expose
*/
public function getListingPhones(): ArrayCollection
{
$phones = new ArrayCollection();
$i = 0;
/** @var UserPhone $phone */
foreach ($this->getUser()->getPhones() as $phone) {
if ($i > 2) {
break;
}
$criteria = Criteria::create()->where(Criteria::expr()->eq('number', $phone->getNumber()));
if ($phones->matching($criteria)->isEmpty() && $phone->getPhone() instanceof Phone) {
$phones->add($phone->getPhone());
}
++$i;
}
return $phones;
}
/**
* Add photos.
*
* @return Listing
*/
public function addPhoto(ListingPhoto $photo)
{
$photo->setListing($this);
$this->photos->add($photo);
return $this;
}
/**
* Set photos.
*
* @return Listing
*/
public function setPhotos($photos)
{
foreach ($photos as $photo) {
$this->addPhoto($photo);
}
return $this;
}
/**
* Remove photos.
*/
public function removePhoto(ListingPhoto $photo): void
{
$this->photos->removeElement($photo);
}
/**
* @return $this
*/
public function clearPhotos()
{
$this->photos->clear();
return $this;
}
/**
* @return $this
*/
public function clearPhones()
{
$this->phones->clear();
return $this;
}
/**
* @return CompoundAveragePrice|null
*/
public function getCompoundAveragePrices()
{
return $this->compoundAveragePrices;
}
/**
* @param CompoundAveragePrice|null
*/
public function setCompoundAveragePrices(?CompoundAveragePrice $compoundAveragePrices): void
{
$this->compoundAveragePrices = $compoundAveragePrices;
}
/**
* @return ArrayCollection
*/
public function getPhotos($excludedTypes = [])
{
$criteria = Criteria::create();
if (!empty($excludedTypes)) {
$criteria->andWhere(Criteria::expr()->notIn('type', $excludedTypes));
}
$criteria->orderBy(['order' => Criteria::ASC]);
return $this->photos->matching($criteria);
}
/**
* @Serializer\Groups({"List", "Details", "listingDetails"})
*
* @Serializer\VirtualProperty
*
* @Serializer\SerializedName("photos")
*
* @return ArrayCollection
*/
public function getPhotosForSlider()
{
$slider = new ArrayCollection();
// Set the main photo as the first photo in the slider
if ($this->getMainPhoto()) {
$slider->add($this->getMainPhoto());
}
// Add all other photos, except the main photo, because It's already added
/** @var ListingPhoto $photo */
foreach ($this->getPhotos() as $photo) {
if (!$slider->contains($photo) && PhotoTypes::LOGO_PHOTO != $photo->getType()) {
$slider->add($photo);
}
}
return $slider;
}
public function buildMappedMainPhoto(): self
{
// Important for API
if ($this->getPhotos()->count() <= 0) {
return $this;
}
/* @var ListingPhoto $photo */
$mainPhotos = $this->photos->filter(fn ($photo) => PhotoTypes::MAIN_PHOTO == $photo->getType());
$mappedMainPhoto = $mainPhotos->first() ?: $this->getPhotos()->first();
if ($mappedMainPhoto instanceof ListingPhoto) {
$this->mappedMainPhoto = $this->mapPhoto($mappedMainPhoto);
}
return $this;
}
public function setMappedMainPhoto(?array $mainPhoto): self
{
$this->mappedMainPhoto = $mainPhoto;
return $this;
}
/**
* @Serializer\Groups({"DefaultV4", "MyListing", "MyListings", "SearchV4", "ProjectSearchV4", "RelatedListingsV2", "locationListingV2", "homeCompoundV2"})
*
* @Serializer\VirtualProperty
*
* @Serializer\SerializedName("mainPhoto")
*/
public function getMappedMainPhoto(): ?array
{
return $this->mappedMainPhoto;
}
private function mapPhoto(ListingPhoto $listingPhoto): array
{
return [
'id' => $listingPhoto->getId(),
'name' => $listingPhoto->getName(),
'caption' => $listingPhoto->getCaption(),
'order' => $listingPhoto->getOrder(),
'type' => $listingPhoto->getTypeName(),
'photo' => $listingPhoto->getFile(),
'file' => $listingPhoto->getPath(),
'thumbnails' => [],
];
}
public function buildMappedPhotos(): self
{
$mainPhotoId = null;
// Set the main photo as the first photo in the slider
if ($this->getMainPhoto() instanceof ListingPhoto) {
$mainPhoto = $this->getMainPhoto();
$mainPhotoId = $mainPhoto->getId();
$this->mappedPhotos[] = $this->mapPhoto($mainPhoto);
}
/** @var ListingPhoto $photo */
foreach ($this->getPhotos() as $photo) {
if (PhotoTypes::LOGO_PHOTO != $photo->getType()) {
if (($mainPhotoId && $mainPhotoId == $photo->getId()) || !$photo instanceof ListingPhoto) {
continue;
}
$this->mappedPhotos[] = $this->mapPhoto($photo);
}
}
return $this;
}
/**
* @Serializer\Groups({"DefaultV4", "SearchV4", "ProjectDetailsV4", "RelatedListingsV2"})
*
* @Serializer\VirtualProperty
*
* @Serializer\SerializedName("photos")
*
* @return array
*/
public function getMappedPhotos()
{
return $this->mappedPhotos;
}
public function setMappedPhotos(array $mappedPhotos): self
{
$this->mappedPhotos = $mappedPhotos;
return $this;
}
/**
* @Serializer\Groups({"List", "Api", "Preview"})
*
* @Serializer\VirtualProperty
*/
public function getMainPhoto(): ?ListingPhoto
{
// Important for API
if ($this->getPhotos()->count() <= 0) {
return null;
}
/* @var ListingPhoto $photo */
$mainPhotos = $this->photos->filter(fn ($photo) => PhotoTypes::MAIN_PHOTO == $photo->getType());
return $mainPhotos->first() ?: $this->getPhotos()->first();
}
/**
* @Serializer\Groups({"DefaultV4", "MyListing", "SearchV4", "ProjectSearchV4"})
*
* @Serializer\VirtualProperty
*
* @return int
*/
public function getPhotosCount()
{
return $this->getPhotos()->count();
}
/**
* @return ListingPhoto|null
*/
public function getLogo()
{
/** @var ArrayCollection $logos */
$logos = $this->photos->filter(fn (ListingPhoto $photo) => PhotoTypes::LOGO_PHOTO == $photo->getType());
return $logos->first() ?: null;
}
/**
* @return ArrayCollection
*/
public function getLeads()
{
return $this->leads;
}
/**
* Count leads.
*
* @return int
*/
public function getLeadsCount()
{
return $this->getLeadsCounter();
}
/**
* Count all leads with children.
*
* @return int
*/
public function getTotalLeadsCount()
{
$leadsCount = $this->getLeadsCounter();
if ($this->getChildren()) {
/** @var self $listing */
foreach ($this->getChildren() as $listing) {
$leadsCount += $listing->getLeadsCounter();
}
}
return $leadsCount;
}
public function setLeads($leads): void
{
$this->leads = $leads;
}
/**
* @Serializer\VirtualProperty()
*
* @return int
*/
public function getAggregatedLeadsCount()
{
/** @var ListingFeature $lastBump */
$lastBump = $this->getLastAutoBumpUp();
/** @var ListingFeature $lastFeature */
$lastFeature = $this->getLastListingFeature();
$listingFeature = null;
if ($lastBump && $lastFeature) {
$listingFeature = ($lastBump->getLastBumpedAt() > $lastFeature->getCreatedAt()) ? $lastBump : $lastFeature;
} elseif ($lastBump) {
$listingFeature = $lastBump;
} elseif ($lastFeature) {
$listingFeature = $lastFeature;
}
return $listingFeature ?
$this->getLeadsCounter() - $listingFeature->getLeadsCountSnapshot() :
$this->getLeadsCounter();
}
/**
* Add listingFeatures.
*
* @return Listing
*/
public function addListingFeature(ListingFeature $listingFeatures)
{
$this->listingFeatures[] = $listingFeatures;
return $this;
}
/**
* Remove listingFeatures.
*/
public function removeListingFeature(ListingFeature $listingFeatures): void
{
$this->listingFeatures->removeElement($listingFeatures);
}
/**
* Get listingFeatures.
*
* @return Collection
*/
public function getListingFeatures()
{
return $this->listingFeatures;
}
/**
* @return ListingFeature
*/
public function getLastAutoBumpUp()
{
$criteria = new Criteria();
$criteria
->where(Criteria::expr()->eq('type', ListingFeatures::BUMP_UP))
->andWhere(Criteria::expr()->gte('expiresAt', new \DateTime()))
->orWhere(Criteria::expr()->isNull('expiresAt'))
->orderBy([
'id' => Criteria::DESC,
])
;
return $this->listingFeatures->matching($criteria)->first();
}
/**
* @Serializer\VirtualProperty
*
* @Serializer\SerializedName("was_featured")
*
* @Serializer\Groups({"List", "Details", "listingDetails"})
*
* @return bool
*/
public function wasFeatured()
{
return !$this->getCurrentListingFeature() && $this->getLastListingFeature() ? true : false;
}
/**
* Get current listing feature.
*
* @return ListingFeatures
*/
public function getCurrentListingFeature()
{
$criteria = Criteria::create()
->where(Criteria::expr()->gte('expiresAt', new \DateTime('now')))
->andWhere(Criteria::expr()->neq('type', ListingFeatures::PAID))
->andWhere(Criteria::expr()->neq('type', ListingFeatures::BUMP_UP))
->orderBy(['id' => Criteria::DESC])
->setMaxResults(1);
return $this->getListingFeatures()->matching($criteria)->first();
}
/**
* Get current listing feature expiry date.
*
* @return \DateTime|null
*
* @Serializer\VirtualProperty()
*
* @Serializer\Groups({"DefaultV4", "MyListing"})
*
* @Serializer\SerializedName("feature_expires_at")
*
* @Serializer\Expose
*/
public function getCurrentListingFeatureExpiryDate()
{
/* @var ListingFeature $listingFeature */
if ($this->isFeatured()) {
$listingFeature = $this->getCurrentListingFeature();
return $listingFeature ? $listingFeature->getExpiresAt() : null;
}
return null;
}
/**
* Get all current active listing features.
*
* @return ListingFeatures
*/
public function getCurrentListingFeatures()
{
$criteria = Criteria::create()
->where(Criteria::expr()->orX(
Criteria::expr()->isNull('expiresAt'),
Criteria::expr()->gte('expiresAt', new \DateTime('now'))
))
->orderBy(['id' => Criteria::DESC]);
return $this->getListingFeatures()->matching($criteria);
}
/**
* Get last listing feature.
*/
public function getLastListingFeature()
{
$criteria = Criteria::create()
->andWhere(Criteria::expr()->neq('type', ListingFeatures::PAID))
->andWhere(Criteria::expr()->neq('type', ListingFeatures::BUMP_UP))
->orderBy(['id' => Criteria::DESC])
->setMaxResults(1);
return $this->getListingFeatures()->matching($criteria)->first();
}
/**
* Get the latest featured credit transaction for listing publishing.
*
* @param mixed $type = null
*
* @throws \Exception
*/
public function getFeaturedPublicationCredit($type = null)
{
if (!$type) {
$lastFeaturedType = $this->getLastListingFeature() ? $this->getLastListingFeature()->getType() : [];
$type = !empty($lastFeaturedType) ? [$lastFeaturedType] : [ListingFeatures::FEATURED, ListingFeatures::SPOTLIGHT, ListingFeatures::PREMIUM, ListingFeatures::SPONSORED];
}
$criteria = Criteria::create()
->where(Criteria::expr()->orX(
Criteria::expr()->isNull('expiresAt'),
Criteria::expr()->gte('expiresAt', new \DateTime('now'))
))
->andWhere(Criteria::expr()->in('type', $type))
->orderBy(['id' => Criteria::DESC])
->setMaxResults(1);
return $this->getListingFeatures()->matching($criteria)->first();
}
/**
* Get the latest credit transaction for listing publishing.
*
* @return ListingFeature
*/
public function getPublicationCredit()
{
$criteria = Criteria::create()
->where(Criteria::expr()->orX(
Criteria::expr()->isNull('expiresAt'),
Criteria::expr()->gte('expiresAt', new \DateTime('now'))
))
->andWhere(Criteria::expr()->eq('type', ListingFeatures::PAID))
->orderBy(['id' => Criteria::DESC])
->setMaxResults(1);
return $this->getListingFeatures()->matching($criteria)->first();
}
/**
* Get the latest credit transaction for special add listing publishing.
*
* @return ListingFeature
*/
public function getSpecialPublicationCredit()
{
$criteria = Criteria::create()
->where(Criteria::expr()->orX(
Criteria::expr()->isNull('expiresAt'),
Criteria::expr()->gte('expiresAt', new \DateTime('now'))
))
->andWhere(Criteria::expr()->in('type', [ListingFeatures::SPONSORED, ListingFeatures::SPOTLIGHT]))
->orderBy(['id' => Criteria::DESC])
->setMaxResults(1);
return $this->getListingFeatures()->matching($criteria)->first();
}
/**
* Get all credit transactions for listing that not expired yet.
*
* @return ListingFeature
*/
public function getNotExpiredCredit()
{
$criteria = Criteria::create()
->where(Criteria::expr()->orX(
Criteria::expr()->isNull('expiresAt'),
Criteria::expr()->gte('expiresAt', new \DateTime('now'))
))
->orderBy(['id' => Criteria::DESC]);
return $this->getListingFeatures()->matching($criteria)->toArray();
}
/**
* Get translations.
*
* @Serializer\VirtualProperty
*
* @Serializer\Groups({"Default", "List"})
*
* @Serializer\SerializedName("translations")
*
* @Serializer\Expose
*
* @return ArrayCollection
*/
public function getTranslations()
{
return $this->translations;
}
public function deleteExistingTranslation($field, $locale): void
{
/** @var ListingTranslation $translation */
foreach ($this->getTranslations() as $translation) {
if ($translation->getField() == $field && $translation->getLocale() == $locale) {
$this->removeTranslation($translation);
}
}
}
/**
* Add translation.
*
* @return Listing
*/
public function addTranslation(ListingTranslation $translation)
{
if (!$this->translations->contains($translation)) {
$this->translations->add($translation);
$translation->setObject($this);
}
return $this;
}
/**
* Set Translations.
*
* @return Listing
*/
public function setTranslations($translations)
{
foreach ($translations as $translation) {
$this->addTranslation($translation);
}
return $this;
}
/**
* Remove translation.
*
* @return Listing
*/
public function removeTranslation(ListingTranslation $translation)
{
if ($this->translations->contains($translation)) {
$this->translations->removeElement($translation);
}
return $this;
}
/**
* @return $this
*/
public function clearTranslations()
{
$this->translations->clear();
return $this;
}
/**
* Set campaign.
*
* @param string $campaign
*
* @return Listing
*/
public function setCampaign($campaign)
{
$this->campaign = $campaign;
return $this;
}
/**
* Get campaign.
*
* @return string
*/
public function getCampaign()
{
return $this->campaign;
}
/**
* Set propertyView.
*
* @param int $propertyView
*
* @return Listing
*/
public function setPropertyView($propertyView)
{
$this->propertyView = $propertyView;
return $this;
}
/**
* Get propertyView.
*
* @return int
*/
public function getPropertyView()
{
return $this->propertyView;
}
/**
* @Serializer\SerializedName("property_view_label")
*
* @Serializer\VirtualProperty()
*
* @Serializer\Groups({"Details", "listingDetails"})
*
* @Serializer\Expose
*/
public function getPropertyViewLabel()
{
return ListingPropertyView::getLabel($this->getPropertyView());
}
/**
* @Serializer\SerializedName("property_view_label")
*
* @Serializer\VirtualProperty()
*
* @Serializer\Since("v2.12")
*
* @Serializer\Expose()
*/
public function getPropertyViewTranslatedLabel()
{
return $this->getTranslatedPropertyViewLabel();
}
/**
* @Serializer\SerializedName("property_view")
*
* @Serializer\VirtualProperty()
*
* @Serializer\Groups({"DefaultV4"})
*
* @Serializer\Expose()
*/
public function getPropertyViewName()
{
return ListingPropertyView::getNameByConstant($this->getPropertyView());
}
/**
* @return $this
*/
public function setPropertyViewLabel($label)
{
$this->propertyViewLabel = $label;
return $this;
}
/**
* Set paymentMethod.
*
* @param int $paymentMethod
*
* @return Listing
*/
public function setPaymentMethod($paymentMethod)
{
if (
ListingSections::FOR_RENT == $this->getSection()->getId()
) {
$paymentMethod = ListingPaymentMethod::CASH;
}
$this->paymentMethod = $paymentMethod;
return $this;
}
/**
* Set paymentMethod Label.
*
* @param int $paymentMethod
*
* @return Listing
*/
public function setPaymentMethodLabel($paymentMethod)
{
$this->paymentMethodLabel = $paymentMethod;
return $this;
}
/**
* @Serializer\SerializedName("payment_method_label")
*
* @Serializer\VirtualProperty()
*
* @Serializer\Since("v2.12")
*
* @Serializer\Expose()
*/
public function getPaymentMethodLabelTranslated()
{
return $this->paymentMethodLabel;
}
/**
* @Serializer\SerializedName("user")
*
* @Serializer\VirtualProperty()
*
* @Serializer\Groups({"DefaultV4"})
*
* @Serializer\Expose()
*
* @return int|null
*/
public function getUserId()
{
return $this->getUser() instanceof User ? $this->getUser()->getId() : null;
}
/**
* Get paymentMethod.
*
* @return int
*/
public function getPaymentMethod()
{
if (
ListingSections::FOR_RENT == $this->getSection()->getId()
) {
$this->paymentMethod = ListingPaymentMethod::CASH;
}
return $this->paymentMethod;
}
/**
* @Serializer\SerializedName("paymentMethodLabel")
*
* @Serializer\VirtualProperty()
*
* @Serializer\Groups({"Default", "SearchV4", "listingDetails"})
*
* @Serializer\Expose()
*/
public function getPaymentMethodLabel()
{
return ListingPaymentMethod::getLabel($this->getPaymentMethod());
}
/**
* Add listingNotification.
*
* @return Listing
*/
public function addListingNotification(ListingNotification $listingNotification)
{
$this->ListingNotifications[] = $listingNotification;
return $this;
}
/**
* Remove listingNotification.
*/
public function removeListingNotification(ListingNotification $listingNotification): void
{
$this->ListingNotifications->removeElement($listingNotification);
}
/**
* Get listingNotifications.
*
* @return Collection
*/
public function getListingNotifications()
{
return $this->ListingNotifications;
}
/**
* Add rejections.
*
* @return Listing
*/
public function addRejection(Rejection $rejections)
{
$this->rejections[] = $rejections;
return $this;
}
/**
* Add rejections.
*
* @param ArrayCollection $rejections
*
* @return Listing
*/
public function addRejections($rejections)
{
$this->rejections = $rejections;
return $this;
}
/**
* Remove rejections.
*/
public function removeRejections(Rejection $rejections): void
{
$this->rejections->removeElement($rejections);
}
/**
* Get rejections.
*
* @return Collection
*/
public function getRejections()
{
return $this->rejections;
}
public function setRejections($rejections): void
{
$this->rejections = $rejections;
}
/**
* Set phoneCounter.
*
* @param int $phoneCounter
*
* @return Listing
*/
public function setPhoneCounter($phoneCounter)
{
$this->phoneCounter = $phoneCounter;
return $this;
}
/**
* Get phoneCounter.
*
* @return int
*/
public function getPhoneCounter()
{
return $this->phoneCounter;
}
/**
* Set messagesCounter.
*
* @param int $messagesCounter
*
* @return Listing
*/
public function setMessagesCounter($messagesCounter)
{
$this->messagesCounter = $messagesCounter;
return $this;
}
/**
* Get messagesCounter.
*
* @return int
*/
public function getMessagesCounter()
{
return $this->messagesCounter;
}
/**
* @return int
*/
public function getFinalPrice()
{
return $this->finalPrice;
}
/**
* @param int $finalPrice
*/
public function setFinalPrice($finalPrice): void
{
$this->finalPrice = $finalPrice;
}
/**
* @return string
*/
public function getSourceOfSale()
{
return $this->sourceOfSale;
}
/**
* @param string $sourceOfSale
*/
public function setSourceOfSale($sourceOfSale): void
{
$this->sourceOfSale = $sourceOfSale;
}
/**
* @return string
*/
public function getDeleteReason()
{
return $this->deleteReason;
}
/**
* @param string $deleteReason
*/
public function setDeleteReason($deleteReason): void
{
$this->deleteReason = $deleteReason;
}
/**
* @return string
*/
public function getDeleteReasonDetails()
{
return $this->deleteReasonDetails;
}
/**
* @param string $deleteReasonDetails
*/
public function setDeleteReasonDetails($deleteReasonDetails): void
{
$this->deleteReasonDetails = $deleteReasonDetails;
}
public function getInteractions()
{
return $this->interactions;
}
public function setInteractions($interactions): void
{
$this->interactions = $interactions;
}
/**
* @Serializer\VirtualProperty
*
* @Serializer\SerializedName("logo")
*
* @Serializer\Groups({"ProjectSearchV4", "ProjectDetailsV4", "locationListingV2"})
*/
public function getSerializedLogo()
{
// Giving priority for listing logo then userLogo. value set on ListingPreSerializerListener.
return $this->getListingLogo() ?: ($this->getUserLogo() ?: null);
}
/**
* @return string
*/
public function getUserLogo()
{
return $this->userLogo;
}
/**
* @param string $userLogo
*/
public function setUserLogo($userLogo): void
{
$this->userLogo = $userLogo;
}
public function getValidUserLogo(): ?Photo
{
if ($user = $this->getUser()) {
if ($user->hasValidAccessToLogoExposure()) {
return $user->getLogo();
}
}
return null;
}
/**
* @return string
*/
public function getListingLogo()
{
return $this->listingLogo;
}
/**
* @param string $listingLogo
*/
public function setListingLogo($listingLogo): void
{
$this->listingLogo = $listingLogo;
}
public function setTranslatableLocale($locale): void
{
$this->locale = $locale;
}
/**
* @return bool
*/
public function canChangeScrapedListing()
{
return ListingCategories::SCRAPPED == $this->category
&& ScrapedListing::USER_EMAIL === $this->getUser()->getEmail();
}
/**
* @param null $hash
*
* @return bool
*/
public function validateScrapedListingHash($hash = null)
{
$secretHash = md5($this->getPhones()->first()->getNumber().''.$this->getId());
if ($hash === $secretHash) {
return true;
}
return false;
}
public function getSource()
{
return $this->source;
}
public function setSource($source): void
{
$this->source = $source;
}
public function setElasticSearchScore($elasticSearchScore): void
{
$this->elasticSearchScore = $elasticSearchScore;
}
/**
* @return float
*/
public function getElasticSearchScore()
{
return $this->elasticSearchScore;
}
/**
* @param float $qualityScore
*/
public function setQualityScore($qualityScore): void
{
$this->qualityScore = $qualityScore;
}
/**
* @return float
*/
public function getQualityScore()
{
return $this->photos->count();
}
public function getLeadsCounter(): int
{
return $this->leadsCounter;
}
/**
* @param int $leadsCounter
*
* @return Listing
*/
public function setLeadsCounter($leadsCounter)
{
$this->leadsCounter = $leadsCounter;
return $this;
}
/**
* Get price per meter.
*
* @return int|null
*/
public function calculatePricePerMeter()
{
if (!$this->getArea()) {
return null;
}
$area = ($this->getArea() > 0) ? $this->getArea() : 1;
return $this->getPrice() / $area;
}
/**
* @return int
*/
public function getImpressions()
{
return $this->impressions;
}
/**
* @param int $impressions
*
* @return Listing
*/
public function setImpressions($impressions)
{
$this->impressions = $impressions;
return $this;
}
/**
* @return $this
*/
public function setImpressionsMonthlyCount(?int $impressions = null)
{
$this->impressionsMonthlyCount = $impressions;
return $this;
}
/**
* @return int
*/
public function getImpressionsMonthlyCount()
{
return $this->impressionsMonthlyCount;
}
/**
* @return $this
*/
public function setImpressionsWeeklyCount(?int $impressions = null)
{
$this->impressionsWeeklyCount = $impressions;
return $this;
}
public function getImpressionsWeeklyCount()
{
return $this->impressionsWeeklyCount;
}
/**
* Get impressionUpdatedAt.
*
* @return \DateTime
*/
public function getImpressionUpdatedAt()
{
return $this->impressionUpdatedAt;
}
/**
* Set impressionUpdatedAt.
*
* @param \DateTime $impressionUpdatedAt
*
* @return Listing
*/
public function setImpressionUpdatedAt($impressionUpdatedAt)
{
$this->impressionUpdatedAt = $impressionUpdatedAt;
return $this;
}
public function getCompoundStatus()
{
return $this->compoundStatus;
}
public function setCompoundStatus($compoundStatus)
{
$this->compoundStatus = $compoundStatus;
return $this;
}
/**
* @Serializer\VirtualProperty
*
* @Serializer\SerializedName("compound_status")
*
* @return string
*/
public function getCompoundStatusLabel()
{
return CompoundStatus::getLabel($this->getCompoundStatus());
}
public function setCompoundStatusLabel($label): void
{
$this->compoundStatusLabel = $label;
}
public function getPriceLevel()
{
return $this->priceLevel;
}
public function setPriceLevel($priceLevel)
{
$this->priceLevel = $priceLevel;
return $this;
}
/**
* @Serializer\VirtualProperty
*
* @Serializer\SerializedName("price_level")
*
* @return string
*/
public function getPriceLevelLabel()
{
if (!$this->getPriceLevel() && $this->hasParent()) {
return ListingPriceLevel::getLabel($this->getParent()->getPriceLevel());
}
return ListingPriceLevel::getLabel($this->getPriceLevel());
}
/**
* Check if the Listing desn't have the flag and fall back to the parent.
*
* @return string
*/
public function isParentCommercial()
{
if (!$this->isCommercial() && $this->hasParent()) {
return $this->getParent()->isCommercial();
}
return $this->isCommercial();
}
public function setPriceLevelLabel($label): void
{
$this->priceLevelLabel = $label;
}
public function getPricePerMeter()
{
return $this->pricePerMeter;
}
public function setPricePerMeter($pricePerMeter)
{
$this->pricePerMeter = $pricePerMeter;
return $this;
}
public function getChildrenArea()
{
$result = [];
if (empty($this->getChildren())) {
return;
}
foreach ($this->getChildren() as $child) {
$result['area'] = (int) $child->getArea();
}
return $result;
}
public function getChildrenPrice()
{
$result = [];
if (empty($this->getChildren())) {
return;
}
foreach ($this->getChildren() as $child) {
$result['price'] = (int) $child->getPrice();
}
return $result;
}
public function getChildrenPricePerMeter()
{
$result = [];
if (empty($this->getChildren())) {
return;
}
foreach ($this->getChildren() as $child) {
$result['pricePerMeter'] = (int) $child->getPricePerMeter();
}
return $result;
}
public function getChildrenAttributesList()
{
$result = [];
if (empty($this->getChildren())) {
return;
}
foreach ($this->getChildren() as $child) {
foreach ($child->getAttributes() as $attribute) {
$result[$attribute->getCustomField()->getName()] = $attribute->getValue();
}
}
return $result;
}
/**
* Returns array of children's property types.
*/
public function getChildrenPropertyType()
{
$propertyType = [];
if (empty($this->getLiveChildren())) {
return;
}
foreach ($this->getLiveChildren() as $child) {
$propertyType['id'] = $child->getPropertyType()->getId();
}
return $propertyType;
}
/**
* Returns array of children's property types.
*
* @Serializer\VirtualProperty
*
* @Serializer\SerializedName("childrenPropertyTypes")
*
* @Serializer\Groups({"locationListingV2", "homeCompoundV2"})
*
* @Serializer\Expose
*/
public function getChildrenPropertyTypeTitle(): array
{
$propertyTypes = [];
if (empty($this->getLiveChildren())) {
return [];
}
foreach ($this->getLiveChildren() as $child) {
$propertyTypes[] = $child->getPropertyType()->getTitle();
}
return array_values(array_unique($propertyTypes));
}
public function isBumped(): bool
{
return (bool) $this->isBumped;
}
public function setBumped(bool $status = true): self
{
$this->isBumped = $status;
return $this;
}
/**
* @return bool
*/
public function isSendEmail()
{
return $this->isSendEmail;
}
/**
* @return $this
*/
public function setIsSendEmail(bool $isSendEmail = true)
{
$this->isSendEmail = $isSendEmail;
return $this;
}
/**
* @Serializer\VirtualProperty()
*
* @Serializer\Groups({"DataLayer", "Details", "Search", "DefaultV4", "SearchV4", "listingDetails"})
*
* @Serializer\Expose
*
* @return bool
*/
public function hasParent()
{
return !empty($this->parent);
}
/**
* @Serializer\VirtualProperty()
*
* @Serializer\Groups({"Details", "Search", "DefaultV4", "SearchV4", "listingDetails"})
*
* @Serializer\Expose
*/
public function isProjectOrUnit(): bool
{
return $this->hasParent() || $this->isProject();
}
/**
* @Serializer\VirtualProperty()
*
* @Serializer\Groups({"DataLayer"})
*
* @Serializer\Expose
*/
public function hasChildren(): bool
{
return $this->isProject();
}
/**
* Gets Geo point.
*/
public function getGeoPoint()
{
if (!$this->getCenterLat() || !$this->getCenterLng()) {
return;
}
return implode(',', [$this->getCenterLat(), $this->getCenterLng()]);
}
/**
* @return ArrayCollection
*/
public function getRates(?\DateTime $startDate = null)
{
$criteria = Criteria::create()
->andWhere(Criteria::expr()->lt(
'createdAt',
new \DateTime()
))
->andWhere(Criteria::expr()->gt(
'createdAt',
$startDate ?? new \DateTime(sprintf('-%d Days', ListingRateConstant::DATE_RANGE_START))
));
return $this->rates->matching($criteria);
}
/**
* @Serializer\VirtualProperty
*
* @Serializer\Groups({"Rates"})
*
* @Serializer\Expose
*
* @return int
*/
public function getTotalRates(?\DateTime $startDate = null)
{
$totalRates = $this->getRates($startDate)->count();
if (!$totalRates) {
return null;
}
return round(($this->getPositiveRatesCount($startDate) / $totalRates) * 100);
}
/**
* @Serializer\VirtualProperty()
*
* @Serializer\Groups({"DefaultV4", "MyListing"})
*
* @Serializer\SerializedName("score")
*
* @Serializer\Expose
*/
public function getRateScore()
{
return $this->getTotalRates();
}
public function setTotalRates($totalRates): self
{
$this->totalRates = $totalRates;
return $this;
}
/**
* @Serializer\VirtualProperty
*
* @Serializer\Groups({"Rates"})
*
* @Serializer\SerializedName("positive_rates")
*
* @Serializer\Expose
*/
public function getPositiveRatesCount(?\DateTime $startDate = null)
{
$criteria = Criteria::create()
->where(Criteria::expr()->eq('rate', ListingRateConstant::SATISFYING));
return $this->getRates($startDate)->matching($criteria)->count();
}
/**
* @Serializer\VirtualProperty
*
* @Serializer\Groups({"Rates"})
*
* @Serializer\SerializedName("negative_rates")
*
* @Serializer\Expose
*
* @return int
*/
public function getNegativeRatesCount(?\DateTime $startDate = null)
{
$criteria = Criteria::create()
->where(Criteria::expr()->eq('rate', ListingRateConstant::UNSATISFYING));
return $this->getRates($startDate)->matching($criteria)->count();
}
/**
* @Serializer\VirtualProperty
*
* @Serializer\Groups({"Rates"})
*
* @Serializer\SerializedName("rates_reasons")
*
* @Serializer\Expose
*
* @return array
*/
public function getRateReasonsCollection()
{
return $this->rateReasonsCollection;
}
/**
* @return array
*/
public function setRateReasonsCollection(array $rateReasonsCollection): self
{
$this->rateReasonsCollection = new ArrayCollection($rateReasonsCollection);
return $this;
}
/**
* @Serializer\VirtualProperty
*
* @Serializer\Groups({"Rates"})
*
* @Serializer\SerializedName("rates_comments")
*
* @Serializer\Expose
*
* @return array
*/
public function getRatesComments()
{
$criteria = Criteria::create()
->orderBy(['createdAt' => Criteria::DESC]);
$comments = [];
foreach ($this->getRates()->matching($criteria) as $rate) {
$comments[] = $rate->getcomment();
}
return $comments;
}
public function getSynced()
{
return $this->synced;
}
/**
* @return self
*/
public function setSynced(bool $synced)
{
$this->synced = $synced;
return $this;
}
/**
* @deprecated used to migrate to Skull service. Not needed anymore.
*
* @Serializer\VirtualProperty
*
* @Serializer\Groups({"Details", "Default", "ActivitiesData"})
*
* @Serializer\Expose
*/
public function getReferenceId()
{
return $this->id;
}
/**
* @param int $referenceId
*
* @return self
*/
public function setReferenceId($referenceId)
{
$this->referenceId = $referenceId;
return $this;
}
public function setFeaturedTypeLabel($featuredTypeLabel): void
{
$this->featuredTypeLabel = $featuredTypeLabel;
}
/**
* @Serializer\VirtualProperty
*
* @Serializer\SerializedName("featuredType")
*
* @Serializer\Groups({"List", "Details", "listingDetails", "RelatedListingsV2"})
*
* @Serializer\Expose
*/
public function getFeaturedType()
{
return ['type' => $this->getFeatured(), 'label' => $this->featuredTypeLabel];
}
/**
* @Serializer\VirtualProperty
*
* @Serializer\SerializedName("featuredType")
*
* @Serializer\Groups({"DefaultV4", "SearchV4", "ProjectSearchV4", "locationListingV2", "MyListings"})
*/
public function getFeaturedName()
{
return ListingFeaturedTypes::getFeaturedName($this->getFeatured());
}
/**
* @Serializer\VirtualProperty
*
* @Serializer\SerializedName("referenceId")
*
* @Serializer\Expose()
*
* @Serializer\Groups({"DefaultV4", "SearchV4"})
*/
public function getReferencedV4Id()
{
return $this->getId();
}
/**
* @return favourite
*/
public function getFavourite()
{
return $this->favourite;
}
public function setFavourite(array $favourites): self
{
foreach ($favourites as $favourite) {
$this->addFavourite($favourites);
}
return $this;
}
/**
* Add favourite.
*
* @return Listing
*/
public function addFavourite(Favourite $favourite)
{
$favourite->setListing($this);
$this->favourite[] = $favourite;
return $this;
}
public function isPendingFeaturing()
{
return $this->isPendingFeaturing;
}
/**
* @return $this
*/
public function setPendingFeaturing($pendingFeaturing)
{
$this->isPendingFeaturing = $pendingFeaturing;
return $this;
}
public function getPendingFeaturingType()
{
return $this->pendingFeaturingType;
}
/**
* @return Listing
*/
public function setPendingFeaturingType($pendingFeaturingType)
{
$this->pendingFeaturingType = $pendingFeaturingType;
return $this;
}
/**
* @Serializer\VirtualProperty
*
* @Serializer\SerializedName("is_favourite")
*
* @Serializer\Groups({"List", "Details"})
*
* @return bool
*/
public function getIsFavourite()
{
return $this->isFavourite;
}
/**
* @return Listing
*/
public function setIsFavourite(bool $isFavourite)
{
$this->isFavourite = $isFavourite;
return $this;
}
/**
* @Serializer\VirtualProperty
*
* @Serializer\SerializedName("user_note")
*
* @Serializer\Groups({"List", "Details"})
*
* @return string
*/
public function getUserNote()
{
return $this->userNote;
}
/**
* @return Listing
*/
public function setUserNote(?string $userNote)
{
$this->userNote = $userNote;
return $this;
}
public function isProject(): bool
{
return ListingCategories::PROJECTS == $this->getCategory();
}
/**
* @return int
*/
public function getListingFeaturesFromFeaturedType()
{
switch ($this->getFeatured()) {
case ListingFeaturedTypes::SPOTLIGHT:
return ListingFeatures::SPOTLIGHT;
case ListingFeaturedTypes::SPONSORED:
return ListingFeatures::SPONSORED;
case ListingFeaturedTypes::PREMIUM:
return ListingFeatures::PREMIUM;
default:
return ListingFeatures::FEATURED;
}
}
/**
* @Serializer\VirtualProperty
*
* @Serializer\SerializedName("isExcludedFromWhatsApp")
*
* @Serializer\Groups({"List", "Details", "DefaultV4"})
*
* @return bool
*/
public function getIsExcludedFromWhatsApp()
{
if (
!empty($this->getUser()->getTeam())
&& TeamCategories::EXCLUDED_FROM_WHATSAPP == $this->getUser()->getTeam()->getCategory()
&& ListingCategories::PROJECTS == $this->getCategory()
) {
return true;
}
return false;
}
/**
* @return int|null
*/
public function getRateStatus()
{
return $this->rateStatus;
}
/**
* @return Listing
*/
public function setRateStatus(?int $rateStatus)
{
$this->rateStatus = $rateStatus;
return $this;
}
/**
* @Serializer\VirtualProperty
*
* @return string
*/
public function getRateStatusLabel()
{
return ListingRateStatus::getLabel($this->getRateStatus());
}
/**
* @return boolean||null
*/
public function getIsRateReviewed()
{
return $this->isRateReviewed;
}
/**
* @return Listing
*/
public function setIsRateReviewed(?bool $isRateReviewed)
{
$this->isRateReviewed = $isRateReviewed;
return $this;
}
/**
* @Serializer\VirtualProperty
*/
public function getRateReviewStatusLabel(): string
{
return ListingRateReviewStatus::getLabel($this->getIsRateReviewed() ? ListingRateReviewStatus::REVIEWED : ListingRateReviewStatus::PENDING_REVIEW);
}
/**
* @Serializer\VirtualProperty
*
* @Serializer\Groups({"Rates"})
*
* @Serializer\SerializedName("reported_date")
*
* @Serializer\Expose
*
* @return array
*/
public function getReportedDate()
{
return $this->reportedDate;
}
/**
* @param \DateTime|string $reportedDate
*
* @return array
*/
public function setReportedDate($reportedDate): self
{
$this->reportedDate = $reportedDate;
return $this;
}
/**
* @return array
*/
public function getReasonIds()
{
$rateReasonsCollection = $this->getRateReasonsCollection();
if (!isset($rateReasonsCollection['reason_ids'])) {
return [];
}
$reasonsIds = [];
foreach ($rateReasonsCollection['reason_ids'] as $key => $value) {
$reasonsIds[] = [
'key' => $key,
'value' => $value,
];
}
return $reasonsIds;
}
/**
* @return array
*/
public function getReasonLabels()
{
$rateReasonsCollection = $this->getRateReasonsCollection();
if (!isset($rateReasonsCollection['reason_labels'])) {
return [];
}
$reasonLabels = [];
foreach ($rateReasonsCollection['reason_labels'] as $label => $count) {
$reasonLabels[] = [
'label' => $label,
'count' => $count,
];
}
return $reasonLabels;
}
private function listMainListingPhonesFromUser(): ArrayCollection
{
$phones = new ArrayCollection();
if ($this->getUser()) {
foreach ($this->getUser()->getMainPhones(UserMainPhones::BUILD_FORMATTER_USER_PHONES) as $phone) {
if ($phone) {
$phones->add($this->castUserPhonesAsListingPhones($phone));
}
}
}
return $phones;
}
private function castUserPhonesAsListingPhones(UserPhone $userPhone): ListingPhone
{
$phone = $userPhone->getPhone();
$phone->setWhatsApp($userPhone->isWhatsApp());
return new ListingPhone(
convert_arabic_numbers($phone->getNumber()),
$this,
$phone->getCountryCode(),
$phone
);
}
/**
* @param Listing $parentOfSimilarListing
*
* @return Listing
*/
public function setParentOfSimilarListing($parentOfSimilarListing)
{
$this->parentOfSimilarListing = $parentOfSimilarListing;
return $this;
}
/**
* @Serializer\VirtualProperty
*
* @Serializer\SerializedName("parentOfSimilarListing")
*
* @Serializer\Groups({"SimilarListings"})
*
* @Serializer\Expose()
*
* @return Listing
*/
public function getParentOfSimilarListing()
{
return $this->parentOfSimilarListing;
}
public function isCallRequest(): bool
{
return $this->isCallRequest;
}
public function setIsCallRequest(bool $isCallRequest): self
{
$this->isCallRequest = $isCallRequest;
return $this;
}
public function getNotMigratedFields()
{
return [
'impressionUpdatedAt',
'impressions',
];
}
public function generateCoordinates(): self
{
if ($this->getLocation() && (!$this->centerLat || !$this->centerLng)) {
/** @var Location $location */
$location = $this->location;
$this->setCenterLat($location->getLat());
$this->setCenterLng($location->getLon());
}
return $this;
}
public function buildListingAttributes(): self
{
/** @var ListingAttribute $attribute */
foreach ($this->attributes as $attribute) {
if (!$attribute->getCustomField() instanceof CustomField) {
continue;
}
$attributeName = $attribute->getFormattedAttributeName();
$attributeValue = $attribute->getValue();
if (null != $attributeValue) {
$this->listingAttributes[$attributeName] = $attributeValue;
}
if (ListingCustomFields::FINISH_TYPE_VALUE == $attributeName) {
$this->listingAttributes[ListingCustomFields::FINISH_TYPE_LABEL_VALUE] = $attributeValue;
}
}
return $this;
}
/**
* @Serializer\VirtualProperty
*
* @Serializer\SerializedName("attributes")
*
* @Serializer\Groups({"DefaultV4", "SearchV4", "RelatedListingsV2", "MyListings"})
*
* @Serializer\Expose()
*
* @return array
*/
public function getListingAttributesList()
{
if (empty($this->listingAttributes)) {
return null;
}
return $this->listingAttributes;
}
/**
* @return array
*/
public function setListingAttributesList(array $attributesList)
{
$this->listingAttributes = $attributesList;
return $this->listingAttributes;
}
/**
* @Serializer\VirtualProperty
*
* @Serializer\SerializedName("latitude")
*
* @Serializer\Groups({"DefaultV4", "SearchV4", "RelatedListingsV2"})
*
* @Serializer\Expose()
*
* @return float
*/
public function getLatitude()
{
return $this->centerLat;
}
/**
* @Serializer\VirtualProperty
*
* @Serializer\SerializedName("longitude")
*
* @Serializer\Groups({"DefaultV4", "SearchV4", "RelatedListingsV2"})
*
* @Serializer\Expose()
*
* @return float
*/
public function getLongitude()
{
return $this->centerLng;
}
/**
* @Serializer\VirtualProperty
*
* @Serializer\SerializedName("status")
*
* @Serializer\Groups({"DefaultV4", "MyListing", "MyListings"})
*
* @Serializer\Expose()
*
* @return string
*/
public function getLabeledStatus()
{
return ListingStatus::getName($this->getStatus());
}
/**
* @Serializer\SerializedName("propertyViewLabel")
*
* @Serializer\VirtualProperty()
*
* @Serializer\Groups({"DefaultV4","SearchV4"})
*
* @Serializer\Expose()
*/
public function getTranslatedPropertyViewLabel()
{
return $this->propertyViewLabel;
}
/**
* @Serializer\SerializedName("paymentMethodLabel")
*
* @Serializer\VirtualProperty()
*
* @Serializer\Groups({"DefaultV4"})
*
* @Serializer\Expose()
*/
public function getTranslatedPaymentMethodLabel()
{
return $this->getPaymentMethodLabelTranslated();
}
/**
* @Serializer\SerializedName("paymentMethod")
*
* @Serializer\VirtualProperty()
*
* @Serializer\Groups({"DefaultV4"})
*
* @Serializer\Expose()
*/
public function getPaymentMethodText()
{
return ListingPaymentMethod::getText($this->paymentMethod);
}
/**
* @Serializer\SerializedName("sellerRole")
*
* @Serializer\VirtualProperty()
*
* @Serializer\Groups({"Details", "DefaultV4", "SearchV4"})
*
* @Serializer\Expose()
*/
public function getSellerRoleText()
{
return ListingSellerRoles::getName($this->getSellerRole());
}
public function generateAddress(): self
{
if ($this->address || !$this->location) {
return $this;
}
$this->setAddress($this->getLocation()->getTitleFullPath());
return $this;
}
public function setIsPriceNegotiable(bool $isPriceNegotiable, ?CustomField $isPriceNegotiableAttribute = null): self
{
if (!$isPriceNegotiableAttribute) {
return $this;
}
/** @var ListingAttribute $attribute */
foreach ($this->attributes as $attribute) {
if ($attribute->getCustomField()->getId() === $isPriceNegotiableAttribute->getId()) {
$attribute->setValue($isPriceNegotiable);
return $this;
}
}
$listingAttribute = new ListingAttribute();
$listingAttribute->setCustomField($isPriceNegotiableAttribute);
$listingAttribute->setValue($isPriceNegotiable);
$this->addAttribute($listingAttribute);
return $this;
}
/**
* @Serializer\SerializedName("isPriceNegotiable")
*
* @Serializer\VirtualProperty()
*
* @Serializer\Groups({"DefaultV4", "SearchV4"})
*
* @Serializer\Expose()
*/
public function getIsPriceNegotiable(): bool
{
/** @var ListingAttribute $attribute */
foreach ($this->attributes as $attribute) {
if (ListingCustomFields::IS_NEGOTIABLE_NAME === $attribute->getCustomField()->getName()) {
return true;
}
}
return false;
}
/**
* @Serializer\VirtualProperty()
*
* @Serializer\Groups({"Statistics"})
*
* @Serializer\SerializedName("clickRate")
*
* @Serializer\Expose()
*/
public function getClickRate(): float
{
$impressions = $this->getImpressions() > 0 ? $this->getImpressions() : 1;
$views = $this->getViews() > 0 ? $this->getViews() : 1;
return round(($views / $impressions) * 100, 2);
}
/**
* @return int|null
*
* @Serializer\VirtualProperty()
*
* @Serializer\Groups({"Statistics"})
*
* @Serializer\SerializedName("contactRate")
*
* @Serializer\Expose()
*
* @return float|int
*/
public function getContactRate()
{
return ($this->getLeadsCounter() / ($this->getViewsCount() ?: 1)) * 100;
}
/**
* @return float|int
*/
public function getComputedContactRate()
{
if (empty($this->leadsCounter) || empty($this->views)) {
return 0;
}
return round($this->leadsCounter / $this->views * 100, 2);
}
/**
* @param float
*
* @return self
*/
public function setContactRate(float $contactRate)
{
$this->contactRate = $contactRate;
return $this;
}
/**
* @Serializer\VirtualProperty()
*
* @Serializer\Groups({"Statistics", "MyListing"})
*
* @Serializer\SerializedName("impressionsCount")
*
* @Serializer\Expose()
*
* @return float|int
*/
public function getImpressionsCount()
{
return $this->getImpressions() ?: 0;
}
/**
* @Serializer\VirtualProperty()
*
* @Serializer\Groups({"Statistics", "MyListing", "MyListings"})
*
* @Serializer\SerializedName("viewsCount")
*
* @Serializer\Expose()
*
* @return float|int
*/
public function getViewsCount()
{
return $this->getViews() ?: 0;
}
/**
* @Serializer\VirtualProperty()
*
* @Serializer\Groups({"Statistics", "MyListing", "MyListings"})
*
* @Serializer\SerializedName("leadsCount")
*
* @Serializer\Expose()
*
* @return float|int
*/
public function getLeadCount()
{
return $this->getLeadsCounter() ?: 0;
}
/**
* @return int|null
*/
public function isCommercial()
{
return $this->isCommercial;
}
public function setIsCommercial(int $isCommercial): void
{
$this->isCommercial = $isCommercial;
}
/**
* @Serializer\VirtualProperty()
*
* @Serializer\Groups({"DefaultV4", "SearchV4"})
*
* @Serializer\SerializedName("category")
*
* @Serializer\Expose()
*
* @return string|null
*/
public function getCategoryByName()
{
return ListingCategories::getLabel($this->getCategory());
}
/**
* @Serializer\VirtualProperty()
*
* @Serializer\Groups({"Default", "Details", "listingDetails"})
*
* @Serializer\SerializedName("categoryLabel")
*
* @Serializer\Expose()
*/
public function getCategoryLabel(): ?string
{
return $this->getCategoryName();
}
/**
* @Serializer\VirtualProperty()
*
* @Serializer\Groups({"Statistics", "MyListing"})
*
* @Serializer\SerializedName("messagesCount")
*
* @Serializer\Expose()
*
* @return int|null
*/
public function getMessagesCount()
{
return $this->getMessagesCounter() ?: 0;
}
/**
* Get WhatsApp Number.
*
* @Serializer\VirtualProperty
*
* @Serializer\SerializedName("whatsAppNumber")
*
* @Serializer\Groups({"DefaultV4", "SearchV4", "ProjectDetailsV4", "ProjectSearchV4", "RelatedListingsV2", "locationListingV2", "listingDetails"})
*/
public function getWhatsAppNumber()
{
$user = $this->getUser();
if ($user->getWhatsAppNumber()) {
$whatsAppNumber = $user->getWhatsAppNumber()->getNumber();
if (!preg_match('/^\+\d+$/', $whatsAppNumber)) {
return $user->getCountryCode().$whatsAppNumber;
}
return $whatsAppNumber;
}
return null;
}
public function getTranslatableLocale()
{
return $this->locale;
}
/**
* @return Listing
*/
public function setV4Translations($translations)
{
$this->v4Translations = $translations;
return $this;
}
/**
* Get translations.
*
* @Serializer\VirtualProperty
*
* @Serializer\Groups({"DefaultV4", "MyListing"})
*
* @Serializer\SerializedName("translations")
*
* @Serializer\Expose
*
* @return array
*/
public function getV4Translations()
{
return $this->v4Translations;
}
/**
* @Serializer\VirtualProperty
*
* @Serializer\Groups({"DefaultV4", "MyListing", "MyListings"})
*
* @Serializer\Expose
*
* @return ArrayCollection
*/
public function getRejectionReasons()
{
return $this->rejections;
}
/**
* @return array
*/
public function getExistingTranslationsLanguages()
{
$existingLanguages = [];
/** @var ListingTranslation $translation */
foreach ($this->getTranslations() as $translation) {
if ((!('title' == $translation->getField() || 'description' == $translation->getField()))
|| \in_array($translation->getLocale(), $existingLanguages) || !$translation->getContent()
) {
continue;
}
$existingLanguages[] = $translation->getLocale();
}
return $existingLanguages;
}
public function isShownInHomepage(): bool
{
return $this->isShownInHomepage;
}
public function setIsShownInHomepage(bool $isShownInHomepage): self
{
$this->isShownInHomepage = $isShownInHomepage;
return $this;
}
public function isResale(): bool
{
return $this->isResale;
}
public function setIsResale(bool $isResale): self
{
$this->isResale = $isResale;
return $this;
}
public function setIsRent(bool $isRent): self
{
$this->isRent = $isRent;
return $this;
}
public function isRent(): bool
{
return $this->isRent;
}
public function setIsPrimary(bool $isPrimary): self
{
$this->isPrimary = $isPrimary;
return $this;
}
public function isPrimary(): bool
{
return $this->isPrimary;
}
/**
* @return boolean||null
*/
public function getIsMortgageApproved()
{
return $this->isMortgageApproved;
}
public function setIsMortgageApproved(?bool $isMortgageApproved): self
{
$this->isMortgageApproved = $isMortgageApproved;
return $this;
}
public function getRatesNotes()
{
return $this->ratesNotes;
}
public function getRatesNote()
{
if ($this->ratesNotes->isEmpty()) {
return null;
}
return $this->ratesNotes->last();
}
public function setRatesNotes($ratesNotes): void
{
$this->ratesNotes = $ratesNotes;
}
public function getMetaTitle(): ?string
{
return $this->metaTitle;
}
public function setMetaTitle(?string $metaTitle): self
{
$this->metaTitle = $metaTitle;
return $this;
}
public function getMetaDescription(): ?string
{
return $this->metaDescription;
}
public function setMetaDescription(?string $metaDescription): self
{
$this->metaDescription = $metaDescription;
return $this;
}
public function getIsMortgage(): bool
{
return $this->isMortgage;
}
public function setIsMortgage(bool $isMortgage): self
{
$this->isMortgage = $isMortgage;
return $this;
}
/**
* @Serializer\VirtualProperty()
*
* @Serializer\SerializedName("compound_field")
*
* @Serializer\Groups({"Default", "DefaultV4","ProjectSearchV4", "ProjectDetailsV4", "locationListingV2", "homeCompoundV2"})
*
* @Serializer\Expose
*/
public function getCompoundField(): ?CompoundField
{
$compoundField = $this->compoundField;
if ($this->hasParent()) {
$compoundField = $this->getParent()->getCompoundField();
}
return $compoundField;
}
public function setCompoundField(?CompoundField $compoundField): void
{
$this->compoundField = $compoundField;
}
/**
* @return array|null
*/
public function getEligibleForMortgage()
{
return $this->eligibleForMortgage;
}
public function setEligibleForMortgage(?array $eligibleForMortgage = null): self
{
$this->eligibleForMortgage = $eligibleForMortgage;
return $this;
}
public function setPropertyRegistrationStatusOptions(?array $propertyRegistrationStatusOptions = null): self
{
$this->propertyRegistrationStatusOptions = $propertyRegistrationStatusOptions;
return $this;
}
/**
* Get Mortgage Options.
*
* @return array|null
*
* @Serializer\VirtualProperty()
*
* @Serializer\Groups({"DefaultV4"})
*
* @Serializer\SerializedName("property_registration_status_options")
*
* @Serializer\Expose
*/
public function getPropertyRegistrationStatusOptions()
{
return $this->propertyRegistrationStatusOptions;
}
/**
* @return bool
*/
public function hasPropertyRegistrationStatusOptions()
{
if (!$this->getSection() || !$this->getLocation()) {
return false;
}
return $this->getLocation()->getEligibleForMortgage()
&& (ListingSections::FOR_SALE == $this->getSection()->getId());
}
/**
* Get Eligible For Mortgage Data.
*
* @return array|null
*
* @Serializer\VirtualProperty()
*
* @Serializer\Groups({"DefaultV4", "SearchV4", "Default", "listingDetails"})
*
* @Serializer\SerializedName("eligibleForMortgageData")
*
* @Serializer\Expose
*/
public function getEligibleForMortgageData()
{
return $this->eligibleForMortgageData;
}
public function setEligibleForMortgageData(?array $eligibleForMortgageData = null): self
{
$this->eligibleForMortgageData = $eligibleForMortgageData;
return $this;
}
/**
* Get Eligible For Mortgage with Label.
*
* @return array
*/
public function getEligibleForMortgageWithLabel()
{
$eligibleForMortgageWithLabel = [];
if (!empty($this->getEligibleForMortgage())) {
foreach ($this->getEligibleForMortgage() as $mortgage) {
$eligibleForMortgageWithLabel[] = [
'id' => $mortgage,
'title' => EligibleForMortgageData::getLabel($mortgage),
];
}
}
return $eligibleForMortgageWithLabel;
}
/**
* @return PropertyTypeChildren
*/
public function setPropertyTypeChildren($propertyTypeChilden)
{
$this->propertyTypeChilden = $propertyTypeChilden;
return $this;
}
/**
* Get PropertyTypeChildren.
*
* @return array
*/
public function getPropertyTypeChildren()
{
return $this->propertyTypeChilden;
}
/**
* @return float
*/
public function getCompoundElasticScore()
{
return $this->compoundElasticScore;
}
/**
* @param float $compoundElasticScore
*
* @return Listing
*/
public function setCompoundElasticScore($compoundElasticScore)
{
$this->compoundElasticScore = $compoundElasticScore;
return $this;
}
/**.
* @return int|null
*/
public function getPropertyRegistrationStatus()
{
return $this->propertyRegistrationStatus;
}
public function setPropertyRegistrationStatus(?int $propertyRegistrationStatus): self
{
$this->propertyRegistrationStatus = $propertyRegistrationStatus;
return $this;
}
/**
* Get property registration status data options.
*
* @return array|null
*
* @Serializer\VirtualProperty()
*
* @Serializer\Groups({"List", "Details", "Search", "DefaultV4", "SearchV4"})
*
* @Serializer\SerializedName("property_registration_status_data")
*
* @Serializer\Expose
*/
public function getPropertyRegistrationStatusData()
{
if (empty($this->propertyRegistrationStatus)) {
return null;
}
return [
'id' => $this->propertyRegistrationStatus,
'title' => PropertyRegistrationStatusOption::getLabel($this->propertyRegistrationStatus),
];
}
/**
* @Serializer\VirtualProperty()
*
* @Serializer\Groups({"Details", "DefaultV4","SearchV4"})
*
* @Serializer\SerializedName("financialAidURL")
*
* @Serializer\Expose
*/
public function getFinancialAidURL(): ?string
{
// Deprecated. Return null for now.
return null;
}
public function setFinancialAid(FinancialAid $financialAid): void
{
$this->financialAid = $financialAid;
}
/**
* @return bool
*/
public function isExcludedFromClientServed()
{
$user = $this->getUser();
if ($user && $user->hasRole('ROLE_HOME_EG')) {
return true;
}
return false;
}
/**
* @Serializer\VirtualProperty()
*
* @Serializer\Groups({"Details", "DefaultV4","SearchV4"})
*
* @Serializer\SerializedName("hasSimilarListings")
*
* @Serializer\Expose
*/
public function hasSimilarListings(): bool
{
return !empty($this->getSimilarListingsCount());
}
/**
* @Serializer\VirtualProperty()
*
* @Serializer\Groups({"Details", "DefaultV4","SearchV4"})
*
* @Serializer\SerializedName("similarListingsCount")
*
* @Serializer\Expose
*/
public function getSimilarListingsCount(): int
{
return $this->similarListingsCount;
}
public function setSimilarListingsCount(int $count): self
{
$this->similarListingsCount = $count;
return $this;
}
/**
* Set similar listings ids.
*/
public function setSimilarListingsIds(array $arrayOfIds): self
{
$this->similarListingsIds = $arrayOfIds;
return $this;
}
/**
* @Serializer\VirtualProperty()
*
* @Serializer\Groups({"Details", "DefaultV4","SearchV4"})
*
* @Serializer\SerializedName("similarListingsIds")
*
* @Serializer\Expose
*/
public function getSimilarListingsIds(): array
{
return $this->similarListingsIds;
}
public function getAdvertiserNumber(): ?string
{
return $this->advertiserNumber;
}
public function setAdvertiserNumber(?string $advertiserNumber): void
{
$this->advertiserNumber = $advertiserNumber;
}
public function getAuthorizationNumber(): ?string
{
return $this->authorizationNumber;
}
public function setAuthorizationNumber(?string $authorizationNumber): void
{
$this->authorizationNumber = $authorizationNumber;
}
/**
* Get the value of marketPropertyType.
*
* @return int|null
*/
public function getMarketPropertyType()
{
return $this->marketPropertyType;
}
/**
* Set the value of marketPropertyType.
*
* @return self
*/
public function setMarketPropertyType(?int $marketPropertyType)
{
$this->marketPropertyType = $marketPropertyType;
return $this;
}
/**
* Get the value of creationSource.
*
* @return int
*/
public function getCreationSource()
{
return $this->creationSource;
}
/**
* Set the value of creationSource.
*
* @return self
*/
public function setCreationSource(int $creationSource)
{
$this->creationSource = $creationSource;
return $this;
}
/**
* @return float
*
* @Serializer\VirtualProperty()
*
* @Serializer\Groups({"Statistics"})
*
* @Serializer\SerializedName("costPerLead")
*
* @Serializer\Expose
*/
public function getCostPerLead()
{
return $this->costPerLead;
}
/**
* Set the value of costPerLead.
*
* @return self
*/
public function setCostPerLead(float $costPerLead)
{
$this->costPerLead = $costPerLead;
return $this;
}
/**
* Get the value of resaleCount.
*
* @return int
*/
public function getResaleCount()
{
return $this->resaleCount;
}
/**
* Set the value of resaleCount.
*
* @return self
*/
public function setResaleCount(int $resaleCount)
{
$this->resaleCount = $resaleCount;
return $this;
}
/**
* Get the value of resaleCount.
*
* @return int
*/
public function getRentCount()
{
return $this->rentCount;
}
/**
* Set the value of rentCount.
*
* @return self
*/
public function setRentCount(int $rentCount)
{
$this->rentCount = $rentCount;
return $this;
}
/**
* Get the value of clickThroughRate.
*/
public function getClickThroughRate(): float
{
return $this->getClickRate();
}
/**
* Set the value of clickThroughRate.
*/
public function setClickThroughRate(float $clickThroughRate): self
{
$this->clickThroughRate = $clickThroughRate;
return $this;
}
/**
* Get the value of label.
*
* @return int
*/
public function getLabel()
{
return $this->label;
}
/**
* Set the value of label.
*
* @return self
*/
public function setLabel($label)
{
$this->label = $label;
return $this;
}
/**
* Get the value of isTopPicks.
*/
public function getIsTopPicks()
{
return $this->isTopPicks;
}
/**
* Set the value of isTopPicks.
*
* @return self
*/
public function setIsTopPicks($isTopPicks)
{
$this->isTopPicks = $isTopPicks;
return $this;
}
/**
* Get freezedAt date.
*
* @return \DateTime
*/
public function getFreezedAt()
{
return $this->freezedAt;
}
/**
* Set freezedAt date.
*
* @return Listing
*/
public function setFreezedAt($freezedAt)
{
$this->freezedAt = $freezedAt;
return $this;
}
public function getEligibleForBumpUp(): bool
{
return $this->eligibleForBumpUp;
}
public function setEligibleForBumpUp(bool $eligibleForBumpUp): self
{
$this->eligibleForBumpUp = $eligibleForBumpUp;
return $this;
}
/**
* Get waiting time.
*
* @return string
*/
public function getWaitingTime()
{
return $this->waitingTime;
}
/**
* Set waiting time.
*
* @param string $waitingTime
*
* @return Listing
*/
public function setWaitingTime($waitingTime)
{
$this->waitingTime = $waitingTime;
return $this;
}
/**
* Get reference number.
*/
public function getReferenceNumber(): ?string
{
return $this->referenceNumber;
}
/**
* Set reference number.
*
* @param string $referenceNumber
*/
public function setReferenceNumber($referenceNumber): self
{
$this->referenceNumber = $referenceNumber;
return $this;
}
}