To Do: CyrpusVillasDirect

/
Priority Project #
1 CyrpusVillasDirect #: 37
1.01

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
1.01

Villa import from Airbnb

  • Can we extract the GPS location?
Pending
1.02

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
1.02

Villa description

  • Need to translate the “About this villa” text into every language.  
    • Should we use the Translation entity or multiple entities in the Villa entity? I think the Translation entity. Agree?
Pending
1.03

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
1.03

New Booking (when not logged in, ie as consumer user, not admin or user)

  • Apply the phone Analyser to the Guest phone field
  • Hide the Language field, but store it (records what language they looked at the website in)
    • Make the confirmation in English and their preferred language
    • bcc sjwn71@gmail.com in all confirmations (as we test)
Pending
1.04

Emails

  • Check that the emails are working (cc'ing the 3 recipients defined in the  villa )
  • Save the emails in database and show link in booking
Pending
1.04

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
1.05

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
1.05

Owner

  • Test logging in as non-Admin, but as an owner and see what you can do.
  • Owners (non-Admin) should be able to edit their villa(s) including the text, rates and see bookings for their villa only.
Pending
1.06

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
1.06

Villa Photos

  • Photos not filling the page very well and being top/tailed on homepage
Pending
1.07

Multi-lingual

  • How do i handle the option that different villas want different languages?
Pending
1.07

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
1.08

Stripe

  • Set up Stripe to take payments
Pending
1.08

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
1.09

"Owner" entity

  • Objective is to define which User (or Users) have admin rights to each villa
  • This entity has two fields:  Villa and User
    • Both are relational fields and the User one is multi
    • Villa field cannot be null
    • Sort each dropdown by fullName (User) and name (villa) respectively. 
    • In the index show some of the key villa_details as a lookup into the Villa entity
      • Address
      • Contact First/Last name
      •  Wesbite URL (which launches in new window)
  • Admin rights enables those permitted users to:
    • Administer the “Villa” settings
    • Set Seasonal Rates
    • See and reply to bookings
  • Have link to it on the Standard Dashboard, say near the seasonal rates
Pending
1.09

On mobile

  • Date fields are not aligned nicely
Complete
1.10

Voucher scheme

  • Establish a discount code system for returner
Pending
1.10

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
1.11

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
1.11

Version of Calendar

  • Create a table view of the Calendar so Users, Admin and Owners can see multiple villas in one view
  • See attached xls to illustrate what it should look like
  • Filter buttons for Month and City of Villa
Pending
1.12

Export and imports 

  • Build export and import for Bookings (SN to do)
Complete
1.12

1. Market Intelligence — highest development priority

Your current scraper collects valuable raw observations: 30 different stay durations for each arrival date, repeated across villas.

But owners won't want to look at 30 columns of numbers. They want to know whether they're charging the right price, how their competitors are performing and what they should change.

Daily price reconstruction

P0- Convert total stay prices into understandable daily rates: Minimum stay and discount detection

P0 - Identify 3-, 7-, 14- and 28-night restrictions or discounts Competitor comparison dashboard

P0 -  Compare similar villas over the same dates. Scheduled scraping

P0 - Automatically build historical price data. Availability change tracking

P1 -Identify newly blocked or reopened dates.Pricing recommendations

P1 -Highlight where an owner appears expensive or cheap.Historical pricing charts

P1 - Show how prices change as arrival dates approach. Automated owner reports

P2 - Send weekly insights by email

 

A. Daily pricing reconstruction

This is probably the most intellectually interesting part of the project.

Your existing T+1 to T+30 observations are total stay prices, not daily prices. The task is to infer underlying nightly rates and distinguish them from length-of-stay discounts.

  • Ordinary nightly rates, potentially varying by day.
  • Minimum stay requirements.
  • Weekly and monthly discounts.
  • Additional cleaning and service fees.
  • Inconsistent or incomplete observations.
  • Prices that cannot be reliably decomposed.

My suggestion: Create a derived DailyRate dataset while preserving the original PriceHistory observations. Assign a confidence level to estimated nightly rates rather than assuming every price can be explained perfectly.

B. Competitor comparison

I would let an owner select their villa and see comparable properties within the same resort.

Importantly, compare like with like. A beachfront four-bedroom villa with a heated pool isn't directly comparable to an inland three-bedroom property.

C. Availability and estimated occupancy

Because you'll collect snapshots over time, you can observe when previously available dates become unavailable.

That gives you a potentially valuable occupancy indicator.

However, unavailable does not necessarily mean booked. The owner may have blocked dates for personal use, maintenance or bookings through another channel.

I would distinguish between:

  • Confirmed bookings on your own platform.
  • Dates unavailable on Airbnb.
  • Estimated booking activity inferred from changes.
  • Uncertain or missing observations.

Market these as estimated occupancy and booking signals, not verified competitor revenue.

2. Direct Booking Platform — what still needs doing

I would concentrate on six areas. You already have pieces of several of these, so the objective is to close the gaps rather than rebuild them.

A. Villa onboarding and website generation

P0 - Make it possible for a new owner to go from an Airbnb listing to a usable direct-booking website with minimal manual work.

Import or enter descriptions, photographs, facilities, bedrooms, occupancy, check-in rules, location and seasonal prices. Add a publication-readiness checklist and website preview.

 

B. Booking and availability reliability

P0 - Ensure the pricing engine handles seasonal boundaries, Saturday-to-Saturday restrictions, gap nights, cleaning fees, deposits, discounts and cancellation rules.

Test overlapping bookings, delayed calendar synchronisation, simultaneous booking requests and failed payments. Provide a booking confirmation and modification workflow.

 

C. Owner portal

P0 -  Owners should be able to update their own photographs, descriptions, rates and blocked dates, view upcoming bookings, and see enquiries and customer details.

Keep permissions restricted to their own properties, with straightforward navigation rather than a large administrative CMS.

 

D. Direct booking conversion

P0-  Add a clear booking quote, mobile-friendly date selection, visible total pricing, WhatsApp enquiry, guest reviews where legitimately available, and a simple reservation process.

Crucially, show the customer the benefit of booking directly rather than through an OTA.

 

E. Repeat-customer marketing and CRM

P1 - You already have Return Clients and discount functionality. Extend this to guest history, discount codes, repeat-booking links, targeted offers and scheduled campaigns.

Include consent/marketing preference records, unsubscribe functionality and access controls.

 

F. Owner financial reporting

P1 - Show booking income, occupancy, average daily rate, revenue per available night and estimated commission savings.

This creates a tangible financial explanation of why owners should continue using CyprusVillasDirect.

One particularly important point is calendar synchronisation. Airbnb currently states that imported calendars refresh automatically every three hours, rather than instantaneously. Your system therefore needs to handle the double-booking risk inherent in iCal synchronisation, especially if you offer instant booking.

 

3. Commercial features — potentially more important than further coding

You need a repeatable way of acquiring and retaining villa owners.

I would build a simple owner acquisition funnel:

Identify villa owners -  Target villas in Pissouri, Aphrodite Hills, Coral Bay and Polis -  Show an individual market report -  How their villa compares with similar local properties -  Offer a direct-booking website -  Demonstrate commission savings and repeat-customer benefits - Convert to paying customer

Booking commission, intelligence subscription or combined package

I'd add an internal sales CRM to track the owner, villa, location, contact status, demonstration, activation and first booking. Keep it very simple.

Potential revenue models

Direct booking

5% of bookings generated

Market Intelligence Basic - €19/month

Market Intelligence Pro -  €49/month

Combined package - 5% booking commission + €29/month

 Your previous assumption was that 100 villas might be achievable and that perhaps 20% of their bookings could migrate away from Airbnb.

The commercial question I'd test first is whether owners will pay for Market Intelligence without first receiving additional bookings. That would make it a much more attractive standalone business.

4. Infrastructure and product risks

There are several areas I'd address before investing heavily in scale.

Airbnb data access. Airbnb's current European terms prohibit unauthorised automated scraping. Your batch scraper therefore has a genuine contractual and business-continuity risk.1

Before making the entire Market Intelligence product dependent on it, evaluate licensed short-term-rental datasets or authorised integration arrangements. Providers such as AirROI advertise market and calendar data products, but coverage, reliability and commercial usage rights need validation.

 

Data integrity. Save observation timestamps, query parameters, currency, guest count, fee treatment, failures and the source of each price. Otherwise, historical price comparisons can easily be misleading.

Scalability. Move bulk acquisition into queued jobs with retries, checkpoints, request limits and monitoring. Keep historical snapshots instead of overwriting earlier observations.

Privacy and payment security. Protect guest contact records, handle consent correctly, use a payment service provider rather than storing payment-card details, and implement role-based access and audit trails. For marketing, existing-customer relationships do not automatically permit unrestricted promotional emailing.

 

5. My recommended development sequence

Given your limited development resources, this is the order I would follow.

Development priorities

Check items off as you implement them

0/12 complete

 

Phase 1 — Make the existing data useful

Daily price reconstruction

Normalise total stay quotes and identify discounts

Competitor comparison screen

Show prices for comparable villas and dates

Scrape scheduling and monitoring

Automate reliable, permitted data acquisition

Initial owner report

Produce a useful, understandable pricing report

Phase 2 — Complete the booking proposition

Villa onboarding

Import or enter a villa and publish it quickly

Booking reliability

Test pricing, payments, synchronisation and double bookings

Owner self-service

Allow owners to maintain their listings and availability

Mobile booking flow

Make guest enquiry and booking straightforward

Phase 3 — Commercialise

Owner acquisition CRM

Track prospective owners and conversion

Pricing and subscriptions

Test paid Market Intelligence plans

Guest marketing

Repeat-customer campaigns and discounts

Owner analytics

Measure bookings, revenue and commission savings

Copy checklist

6. What I would deliberately not build yet

I would postpone native mobile apps, elaborate AI chatbots, sophisticated dynamic-pricing automation, full accounting integrations, multi-country expansion and extensive property-management functionality.

You don't yet need to compete with established property-management systems feature-for-feature.

Your advantage could be a much narrower proposition: a villa owner gets a website for direct bookings, can market to their previous guests, and receives better local competitor intelligence.

I would aim for an initial pilot of 10 real villa owners in Pissouri or Aphrodite Hills. Measure how many activate their websites, whether anyone receives direct bookings, and — most importantly — whether owners find the competitor reports useful enough to pay for.

That will tell you far more about the project's prospects than adding another dozen technical features.

My strongest priority would be the Market Intelligence comparison screen. You already have much of the difficult data-collection work underway; turning those observations into an immediately useful report is the shortest path to determining whether the intelligence product has commercial value.

Pending
1.13

Confirmation email

  • Villa address is incorrect - needs to be villa specific
  • Contact tel number is incorrect  - needs to be villa specific
Complete
1.14

Client-show-villa

  • Photos don't size/re-size properly and cut off heads etc
Complete
1.15

HomePage

  • Add region search to the search box 
Complete
1.16

Amenities

  • If the Amenity description is not in the Translations list, show a warning sign
Complete
1.17

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
1.18

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
1.19

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
1.20

ICS export  (AirbnbIcalSyncCommand)

  • Is this working for each villa?   Test with TheaVista?
Complete
1.21

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
1.22

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
1.23

Villa screen

  • When clicking on the Previous/Next month, the screen jumps down so you can't read the full page
Complete
1.24

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
1.25

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