To Do: CyrpusVillasDirect (Complete)

/
Project #
CyrpusVillasDirect #: 25
27-Oct-2026
09:57

Multi-language handling

  • Handling of dates in availability calendar when changing to GR
  • Refreshing the page reverts to English, if not logged in.  A problem in ATS not CDV specfically
Complete
27-Oct-2026
09:57

Batch Scrape — Add "Scrape All Villas" Button

The existing Batch Scrape functionality is complete and working. I would like to extend it to support scraping multiple villas in a single operation.

1. Existing functionality (no changes)

Keep the current Batch Scrape option, which accepts:

  • Villa ID (selected from villas with an Airbnb URL)
  • First Start Date (e.g. 22-Oct-2026)
  • Number of Dates (e.g. 10)

This runs the existing scraper and creates one PriceHistory record per start date for the selected villa.

2. New functionality — Scrape All Villas

Add a second button labelled "Scrape All Villas".

This should use the same First Start Date and Number of Dates inputs, but automatically run the existing Batch Scrape process for every villa that meets both conditions:

  • Villa Status is Live or Market Intelligence.
  • Villa has a valid Airbnb URL.

Villas marked Draft should be excluded.

3. Processing

  • Reuse the existing Batch Scrape service rather than duplicating the scraping logic.
  • Process each qualifying villa using the same date range.
  • Save the resulting PriceHistory records against the correct Villa.
  • One villa failing should not prevent the remaining villas from being processed.
  • Display a summary showing the number of villas processed, PriceHistory records created and any failures.

4. Example

If there are 100 qualifying villas and the Number of Dates is set to 10:

  • 100 villas × 10 start dates = 1,000 PriceHistory records.
  • Each record contains the existing T+1 to T+30 price observations.
  • Total: up to 30,000 price observations.

5. Additional considerations

As this could involve thousands of Airbnb requests, the process should ideally run in the background using a Symfony Messenger queue or equivalent, rather than within a single HTTP request?

The interface should display progress and prevent accidentally launching the same batch multiple times.

Complete
27-Oct-2026
09:43

Villa screen

  • When clicking on the Previous/Next month, the screen jumps down so you can't read the full page
Complete
27-Oct-2026
09:32

Villa Status — Replace “testingMode” field

Rename the existing testingMode field in the Villa entity to villaStatus.

The field should have three possible values:

  • Live — Villa is published on the public booking website and available for customers to browse and book.
  • Draft — Villa is being prepared for publication. It can be edited by authorised users but is not visible to customers.
  • Market Intelligence — Villa is maintained solely for competitor monitoring, Airbnb price discovery and market analysis. It is not available for booking through our platform.

Implementation requirements

  • Reuse the existing Testing Mode field if practical, renaming it to status.
  • Update the Villa form to use a dropdown with the three options above.
  • Only villas with status Live should appear on the public villa listings, search results and booking selection pages.
  • Both Draft and Market Intelligence villas must be excluded from all public booking pages.
  • All three statuses should remain visible in the admin Villa index, with a status filter and colour-coded labels:
    • Live — Green
    • Draft — Amber
    • Market Intelligence — Blue
  • New villas created through the normal admin interface should default to Draft.
  • Villas automatically imported through Airbnb Villa Discovery should default to Market Intelligence.The Market Intelligence and Price History tools should be able to access villas of any status, provided they have a valid Airbnb URL.
  • Allow administrators to change a villa's status at any time, including promoting a Market Intelligence villa to Draft or Live.
  • Migrate existing Testing Mode values appropriately, ensuring no villas are inadvertently published or hidden.

Important: Villa Status determines whether a villa is displayed publicly. It should not restrict its inclusion in market intelligence reporting or price discovery.

Complete
27-Oct-2026
09:10

Adding Region to the Discovery process

  • In the Discover Villas form, add a Resort dropdown (linked to the existing Resort entity). 
    • When new Villa records are created through the discovery process, automatically populate their Resort field using the selected Region.
  • This will ensure that all villas discovered in a particular search are assigned to the correct resort without requiring manual updates.
Complete
23-Oct-2026
10:22

ICS export  (AirbnbIcalSyncCommand)

  • Is this working for each villa?   Test with TheaVista?
Complete
23-Oct-2026
08:46

CyprusVillasDirect — Market Intelligence

1. Background

We want to build a Market Intelligence feature for CyprusVillasDirect that collects pricing and availability information for holiday villas listed on Airbnb.

For example, we could collect data for villas in Pissouri and market this information to other villa owners in Pissouri, helping them understand whether they are overpricing or underpricing their properties relative to competitors.

The commercial objective is to develop a historical database that tells us:

  • What each villa is charging for different arrival dates and lengths of stay.
  • Which dates appear available or unavailable.
  • What minimum-stay restrictions appear to apply.
  • Whether discounts are being offered.
  • How prices and availability change over time.
  • How competitively each villa is priced relative to other villas.

Over time, this should allow us to estimate occupancy, identify pricing trends and compare the performance of competing properties.

Today's task is to build the collection and storage functionality, not the analytics or reporting.

2. Existing application

Villa entity

Already exists and contains:

  • villaName
  • airbnbUrl

PriceHistory entity

Already created with:

  • Villa — ManyToOne relationship
  • StartDate — proposed arrival date
  • T1Price through T30Price — total prices for stays of 1–30 nights
  • createdAt — timestamp recording when the information was collected

There is also an existing CRUD interface, including an index showing all 30 prices and a manual form.

Each collection should create a new record rather than overwrite an existing record, allowing us to track historical price changes.

No new entities or changes to existing entities are required.

3. Data collection methodology

For each villa, investigate every possible arrival date over the next six months (initially 180 days).

For each arrival date, obtain prices for stays of between 1 and 30 nights.

For example:

Villa: TheaVista
Arrival date: 1 July 2027

  • 1 night: Checkout 2 July 2027 — Price £xxx
  • 2 nights: Checkout 3 July 2027 — Price £xxx
  • 3 nights: Checkout 4 July 2027 — Price £xxx
  • And so on, up to:
  • 30 nights: Checkout 31 July 2027 — Price £xxx

The checkout date is always calculated as:  checkoutDate = startDate + numberOfNights

The proposed coverage per villa is: 180 arrival dates × 30 stay lengths = 5,400 quotes.

Some requests will not return a price because dates are unavailable, minimum-stay rules prevent booking, or another restriction applies.

Where no valid price is returned, store NULL, not zero.

A missing price does not necessarily mean the villa is occupied.

If we collect prices today and again tomorrow, both observations must be retained for historical comparison.

All prices should be collected in a consistent currency (GBP initially) and represent the total quoted price for the requested stay.

4. Implementation

Create a Symfony service named:

VillaMarketIntelligenceService

The service should accept:

  • Villa ID
  • Arrival date

The service will:

  • Load the Villa entity.
  • Check that airbnbUrl exists and an authorised pricing data source is available.
  • For the specified arrival date, request prices for stays of 1–30 nights, or obtain equivalent information in bulk if the source supports it.
  • Parse and validate the returned information.
  • Create a new PriceHistory record with the Villa, StartDate and collection timestamp.
  • Save the prices in T1Price through T30Price.
  • Record errors in the application logs without aborting the complete collection.

Batch collection

Also provide a method that accepts:

  • Villa ID
  • Start date
  • Number of arrival dates to investigate (default 180)

This should call the single-arrival-date method for each date.

For 180 arrival dates, the process should create 180 PriceHistory records per villa, each containing up to 30 prices.

Use a permitted data source, respect its rate limits and avoid unnecessary requests where equivalent bulk pricing information is available.

5. Testing

Initially, test the functionality on one villa and one arrival date.

Verify that:

  • The correct Airbnb listing is identified.
  • The 30 checkout dates are calculated correctly.
  • Valid returned prices are saved against the correct T1Price–T30Price fields.
  • Missing prices are saved as NULL.
  • The existing collection timestamp is populated.
  • Running the same collection twice creates two separate historical records.
  • An individual quote failure does not stop the other quotes being collected.

Once this works, test collecting several arrival dates for the same villa.

6. Scope for today

Build:

  • VillaMarketIntelligenceService.
  • Pricing collection for 1–30 nights.
  • Storage of collected prices in the existing PriceHistory entity.
  • Historical snapshots without overwriting previous collections.
  • Batch collection across multiple arrival dates.
  • Basic error handling and testing.

Do not build today:

  • Any new entities or entity changes.
  • Competitor comparison reports.
  • Occupancy calculations.
  • Pricing recommendations.
  • Charts or dashboards.
  • Automatic scheduled collections.

The priority is to establish a reliable database of historical prices using the existing PriceHistory entity. We can develop the analytics once the underlying data collection is working.

Complete
23-Oct-2026
08:45

Objective: Automatically discover and import villas from an Airbnb search results page into our existing Villa database (eg villas in Pissouri or Coral Bay).  

Example: https://www.airbnb.co.uk/s/Coral-Bay--Pegeia/homes?place_id=ChIJEe9tmjwI5xQRb4uBfixUqUc&refinement_paths%5B%5D=%2Fhomes&location_bb=Qgt6hkIBiHtCC2PYQgFrnQ%3D%3D&acp_id=t-g-ChIJEe9tmjwI5xQRb4uBfixUqUc&date_picker_type=calendar&search_type=autocomplete_click 

Search URL Input

  • Create a page where an administrator can paste an Airbnb search URL (e.g. a search for villas in Pissouri, Cyprus).
  • Add a "Discover Villas" button to initiate the process.

Scrape Airbnb Search Results

  • Open the supplied URL and extract all villas returned by the search.
  • Handle pagination/infinite scrolling to capture all available results, not just the first page.
  • For each villa, capture:
    • Airbnb listing URL (permanent URL without search dates or tracking parameters).
    • Airbnb listing ID.
    • Property title/name.
    • Maximum number of guests (sleeps X).
    • Number of bedrooms, beds and bathrooms (where available).
    • Location/area.
    • Main property image URL (if available).

Create Villa Records

  • Check whether each Airbnb listing (eg the villa's unique ID) already exists in our Villa database, using the Airbnb listing ID or canonical URL to identify duplicates.
  • If it exists, skip it (do not overwrite existing data).
  • If it does not exist, create a new Villa entity and populate the available fields, including airBnBUrl.
  • Reuse the existing Villa entity and fields wherever possible. Do not create another entity.

 

Results Summary

  • Display the number of villas discovered.
  • Number of new Villa records created.
  • Number already in the database (skipped).
  • Number of failures, with error details.

 

Other Considerations

  • The process should work for any Airbnb search URL, allowing us to discover villas in Pissouri, Aphrodite Hills, Coral Bay, Polis, etc.
  • Avoid duplicate records when the same villa appears in multiple searches.
  • Handle missing property information without failing the entire import.

Purpose: Build up our database of competing villas automatically so that our existing Market Intelligence / Price History functionality can subsequently track their prices, availability and pricing trends.

Complete
23-Oct-2026
08:45

Batch Scrape

  • Create a service that has 3 inputs
    • VillaID (eg Columbia) - selected from Villas with a AirBnBUrl
    • First Start Date (e.g. 22-Oct26)
    • Number of Dates to run  (e.g. 10)
  • This will create 10 records in the database, changing the StartDate (22-Oct, 23-Oct, …. 2 Nov)
  • Run the scraper we had before 
  • …. So this will get 10 x 300 prices, saved in 10 records. 
Complete
16-Oct-2026
09:45

Amenities

  • If the Amenity description is not in the Translations list, show a warning sign
Complete
14-Oct-2026
16:13

Client-show-villa

  • Photos don't size/re-size properly and cut off heads etc
Complete
14-Oct-2026
16:13

HomePage

  • Add region search to the search box 
Complete
13-Oct-2026
14:04

Confirmation email

  • Villa address is incorrect - needs to be villa specific
  • Contact tel number is incorrect  - needs to be villa specific
Complete
09-Oct-2026
06:56

Seasonal rates. 

  • Include a Villa field in each seasonal rate (DONE)
  • Index view:
    • Not available to non-logged in users
    • Non-Admin Users (ie ROLE_USERS) see only their villas (as defined in Owner entity)
    • ROLE_ADMIN users see all
  • The view should be by single villa (you never want to see all villas on one page) - so you select the villa you want to see
  • The error messages (checking continuity) are by villa (Make sense?)
  • And finally it might be great to show a graph of prices by dates.  Again ROLE_ADMIN see all graphs, ROLE_USER see their own only. 
Complete
09-Oct-2026
06:56

Export and imports 

  • Build export and import for Bookings (SN to do)
Complete
09-Oct-2026
06:56

New Booking

  • In booking/new,  the user (non ROLE_ADMIN) should not be able to edit:   
    • Status
    • isAirBnB booking
    • Checkin & Checkout Dates (should be set from the button and depends on availability)
      • OK to made these editable so long as it knows the availability schedule
  • Handling availability in the booking dropdown: We need to handle cases where the available booking basis changes between Daily and Weekly during the period shown.  
    • For example: 1–3 January is available on a daily basis.
      • From 4 January onwards, availability is weekly only:
        • 4–10 January
        • 11–17 January
        • 18–24 January, etc.
      • In this case, the permitted departure dates for an arrival on 1 January should be:
        • 2 Jan, 3 Jan, 4 Jan, 10 Jan, 17 Jan, 24 Jan, etc.
        • It should not allow departure dates such as 5–9 January or 11–16 January, because once the booking crosses into the weekly-only period, the departure date must align with the end of one of the available weekly blocks.
        • The dropdown therefore needs to build valid departure dates by considering changes in the availability/rate basis across the booking period, rather than assuming the entire stay is either daily or weekly.
Complete
07-Oct-2026
07:52

On mobile

  • Date fields are not aligned nicely
Complete
07-Oct-2026
06:47

Homepage

  • At the bottom of index_homepage.html.twig: Include a map of the island with each villa location shown.  
    • Restrict the map markers to those that meet the search criteria
    • Hovering over the map maker shows the name of the villa, and number of bedrooms in brackets and price (lowest daily/weekly rate in the date range)
    • Clicking on the map marker launches the show-villa page
Complete
06-Oct-2026
09:44

Show villa

  • Remove “Select an available date on the calendar to book this villa directly.  Direct booking. About 15% cheaper than Airbnb”
  • Change text to: “Save versus AirBnB by booking direct. Compare price: ” then include the AirBnB link under the AirBnB icon  
  • For ROLE_ADMIN include an icon (next to the map-marker?) with a link to their unique site
Complete
01-Oct-2026
11:11

Seasonal Rates

  • There are 2 new fields in Seasonal Rates -  “weeklyBookingsOnly” flag and “weekStartDay”
  • These are used if a villa only allows bookings by the week- eg Saturday→Saturday.   
    • This is common in ski resorts so that they don't have 1 of 2 days empty as the visitors don't fit exactly
  • So if this Boolean is checked, then customers can only book in 1 week slots (eg Saturday to Saturday).  In that case the price per night is really price per week (so multiply by 7),  And the weekday (eg Saturday) is controlled here too. 
  • Also we need to change the Booking calendar to only accept week-long bookings
Complete
01-Oct-2026
11:11

Main CyprusVillasDirectHomePage

  • This should show ALL villas
  • See https://www.villaplus.com/  
    • See how you can search by dates, # bedrooms, and then click on a villa. 
    • The info section gives a good example of the extra fields we need to add in the Villa entity (I will do that)
Complete
01-Oct-2026
11:11

HomePage (VillaIndex)

  • Make the HomePageIndex the homepage (settings?)
  • Make the “View villa URL”,  Show (eye) and Edit (Pen) buttons only available to ROLE_ADMIN.  
  • Clicking on the picture of villa should launch the villa's show page (not their OWN website) which includes the Availability

 

Search functionality

  • Initially the Homepage should show all villas
  • Once the Search function (dates, #bedrooms) is selected, it should only show villas that are available in the full date range and meets the bedroom and region criteria
  • Can we add a dropdown list of Amenities that the villa needs to have (eg must have swimming pool)

 

Villa-Show

  • Move the Availability to top right
  • Remove the Villa Location box.
    • Make the map-market at the top of the page launch the map/directions page,  
    • Looks like you have replaced the map-marker icon with the villa favicon - no…. it should be the map-marker and pressing it should open the location/directions page

Availability grid

  • Info icon appears on days when you can't book (hide it)  
  • When I have Sep highlighted it looks like you can't book 1-4 Oct... which you can
  • Weekly only doesn't look good on mobile   
  • When the villa is weekly booking only, I think we need to change the display and just show the weeks.  And not show the weekly price in every day.  Perhaps only show the price on the [Saturday] and change the text to $700/week
    • Clicking on Book should show only bookings for 1 or 2 weeks from the prescribed start date
  • Remove the  word "Book" - it is implied 
Complete
23-Sep-2026
08:34

Individual websites

  • This is the key challenge.
  • Let's assume to begin with that each villa holds their ‘unique’ villa website on the atts-systems.com domain…
  • Then what I would ideally like to happen is that as soon as we create a villa entry for a new villla  (eg Villa RogerFederer,   website:  www.villarogerfederer@atts-systms.com) then it is immediately available as a unique site (rather than a directory under villacyprusdirect). Is that possible?
  • Let's assume each villa wants their own URL (which is not part of atts-system  eg VillaRogerFederer.com), I am sure we have to buy the URL and redirect in the DNS our own sub-directory to that external, non ATS, site)?
    • Is that how you would do it?

 Controlling the CMS on each individual website

  • We can;t use the CmsCopy entity in CyprusVillaDirect to control the CMS on say “TheaVistaPissouri.com” because the CMSCopy has no unique villa ID
  • And we can't add villa_id to the CmsCopy entity (and CmsPhoto entity) as that will be over-written by ATS copy bat file (and we need the CmsCopy for the CyprusVillaDirect site…. 
  • So what do we do. I think we need to create a villa-specific CmsCopy and CmsPhoto entities. 
    • Do you agree?  If you agree let's call them:  CmsCopyVilla  and CmsPhotoVilla
Complete
23-Sep-2026
08:15

Villa slug into other entities

  • Photos
  • CmsCopyItems

Think about

  • Weather: How to handle more than one weather location
  • Business Contacts: Should these be unique by villa? Seems a shame not to share.  Thoughts

 

Complete
23-Sep-2026
08:15

Calendar synchronisation with Airbnb

  • Objective; To avoid double-bookings between the two platforms
  • Both systems support iCal calendar synchronisation. In practice this means the two calendars exchange availability information automatically:
    • The website will publish a calendar feed showing dates that are already booked or blocked. Airbnb can read this and automatically mark those dates as unavailable on Airbnb.
    • Airbnb also provides its own calendar feed. 
    • The website will read that feed regularly and automatically block those dates on the website if an Airbnb booking is made.
  • I have made that link in the TheaVistaPissouri project to make bookings made on our site available to AirBnB, but not the reverse – can you research?

ToDo:

  • In the ‘pull’ from AirBnB can you display the name of the booking?
Complete