Skip to content

Commit

Permalink
Added Support for SPUTNIK V; Fixed the Issue with Issue in Availabili…
Browse files Browse the repository at this point in the history
…ty in FetchAPI
  • Loading branch information
SRvSaha committed May 16, 2021
1 parent b9d84f9 commit 44da530
Show file tree
Hide file tree
Showing 5 changed files with 92 additions and 28 deletions.
4 changes: 4 additions & 0 deletions CoWin.Core/CoWin.Core.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,10 @@
- Fixed minor bugs; improved UX</PackageReleaseNotes>
</PropertyGroup>

<ItemGroup>
<Compile Remove="Models\UserInputModel.cs" />
</ItemGroup>

<ItemGroup>
<None Remove="appsettings.json" />
<None Include="..\data\Banner.png">
Expand Down
80 changes: 60 additions & 20 deletions CoWin.Core/Models/CovidVaccinationCenter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,14 @@
using Newtonsoft.Json;
using System.Web;
using System.Collections.Specialized;
using CoWin.Core.Models;

namespace CoWiN.Models
{
public class CovidVaccinationCenter
{
private readonly IConfiguration _configuration;
public static bool IS_BOOKING_SUCCESSFUL = false;
public static bool IS_BOOKING_SUCCESSFUL = false;

public CovidVaccinationCenter(IConfiguration configuration)
{
Expand All @@ -25,7 +26,7 @@ public CovidVaccinationCenter(IConfiguration configuration)
public void GetSlotsByDistrictId(string districtId, string searchDate, string vaccineType)
{
IRestResponse response = FetchAllSlotsForDistict(districtId, searchDate, vaccineType);
if(response.StatusCode == HttpStatusCode.OK)
if (response.StatusCode == HttpStatusCode.OK)
{
var covidVaccinationCenters = JsonConvert.DeserializeObject<CovidVaccinationCenters>(response.Content);
GetAvailableSlots(covidVaccinationCenters);
Expand Down Expand Up @@ -75,7 +76,8 @@ private IRestResponse FetchAllSlotsForDistict(string districtId, string searchDa
builder = new UriBuilder(_configuration["CoWinAPI:ProtectedAPI:FetchCalenderByDistrictUrl"]);
queryString = HttpUtility.ParseQueryString(builder.Query);

if (!string.IsNullOrEmpty(vaccineType)){
if (!string.IsNullOrEmpty(vaccineType))
{
queryString["vaccine"] = vaccineType;
}
}
Expand Down Expand Up @@ -129,7 +131,7 @@ private IRestResponse FetchAllSlotsForPINCode(string pinCode, string searchDate,

private void GetAvailableSlots(CovidVaccinationCenters covidVaccinationCenters)
{
string captcha = "";
string captcha = "";
foreach (var cvc in covidVaccinationCenters.Centers)
{
foreach (var session in cvc?.Sessions)
Expand Down Expand Up @@ -163,24 +165,61 @@ private void GetAvailableSlots(CovidVaccinationCenters covidVaccinationCenters)

private bool IsFiltrationCriteraSatisfied(Center cvc, Session session)
{
var minimumAgeLimitFilter = (session.MinAgeLimit >= Convert.ToInt16(_configuration["CoWinAPI:MinAgeLimit"]));
var maximumAgeLimitFilter = (session.MinAgeLimit < Convert.ToInt16(_configuration["CoWinAPI:MaxAgeLimit"]));
var minimumVaccineAvailabiltyFilter = session.AvailableCapacity >= Convert.ToInt16(_configuration["CoWinAPI:MinimumVaccineAvailability"]);

var mandatoryFilters = minimumAgeLimitFilter && maximumAgeLimitFilter && minimumVaccineAvailabiltyFilter;

// Filter Based on VaccineFeeType only when fee type is provided; otherwise don't filter. Keep both Paid and Free Slots
var vaccineFeeTypeFilter = string.IsNullOrEmpty(_configuration["CoWinAPI:VaccineFeeType"]) || (cvc.FeeType == _configuration["CoWinAPI:VaccineFeeType"]);
bool isAgeCriteriaMet = IsAgeFilterSatisfied(session);
bool isVaccineAvailable = IsMinimumVaccinateAvailabilityFilterSatisfied(session);
bool vaccineFeeTypeFilter = IsVacineFeeTypeFilterSatisfied(cvc);
bool vaccinationCentreNameWiseFilter = IsVaccinationCentreNameFilterSatified(cvc);
return FilteredResult(isAgeCriteriaMet, isVaccineAvailable, vaccineFeeTypeFilter, vaccinationCentreNameWiseFilter);
}

// Filter Based on VaccinationCentreName when there are multiple CVCs in one PIN/District but user wants slot in a specific CVC
var vaccinationCentreNameWiseFilter = string.IsNullOrEmpty(_configuration["CoWinAPI:VaccinationCentreName"]) || (cvc.Name == _configuration["CoWinAPI:VaccinationCentreName"]);

private static bool FilteredResult(bool isAgeCriteriaMet, bool isVaccineAvailable, bool vaccineFeeTypeFilter, bool vaccinationCentreNameWiseFilter)
{
var mandatoryFilters = isAgeCriteriaMet && isVaccineAvailable;
var optionalFilters = vaccineFeeTypeFilter && vaccinationCentreNameWiseFilter;

return mandatoryFilters && optionalFilters;
}

private static void DisplaySlotInfo(Center cvc, Session session)
private bool IsVaccinationCentreNameFilterSatified(Center cvc)
{
// Filter Based on VaccinationCentreName when there are multiple CVCs in one PIN/District but user wants slot in a specific CVC
return string.IsNullOrEmpty(_configuration["CoWinAPI:VaccinationCentreName"]) || (cvc.Name == _configuration["CoWinAPI:VaccinationCentreName"]);
}

private bool IsVacineFeeTypeFilterSatisfied(Center cvc)
{
// Filter Based on VaccineFeeType only when fee type is provided; otherwise don't filter. Keep both Paid and Free Slots
return string.IsNullOrEmpty(_configuration["CoWinAPI:VaccineFeeType"]) || (cvc.FeeType == _configuration["CoWinAPI:VaccineFeeType"]);
}

private bool IsAgeFilterSatisfied(Session session)
{
bool minimumAgeLimitFilter = (session.MinAgeLimit >= Convert.ToInt16(_configuration["CoWinAPI:MinAgeLimit"]));
bool maximumAgeLimitFilter = (session.MinAgeLimit < Convert.ToInt16(_configuration["CoWinAPI:MaxAgeLimit"]));
return minimumAgeLimitFilter && maximumAgeLimitFilter;
}

private bool IsMinimumVaccinateAvailabilityFilterSatisfied(Session session)
{
bool minimumVaccineAvailabiltyFilter;
var availableVaccines = GetVaccineAvailabiltyForDoseType(session);
minimumVaccineAvailabiltyFilter = availableVaccines >= Convert.ToInt16(_configuration["CoWinAPI:MinimumVaccineAvailability"]);
return minimumVaccineAvailabiltyFilter;
}

private long GetVaccineAvailabiltyForDoseType(Session session)
{
if (Convert.ToInt16(_configuration["CoWinAPI:MinimumVaccineAvailability"]) == (int)DoseTypeModel.FIRSTDOSE)
{
return session.AvailableCapacityFirstDose;
}
else
{
return session.AvailableCapacitySecondDose;
}
}

private void DisplaySlotInfo(Center cvc, Session session)
{
Console.ResetColor();
Console.WriteLine("\n***************************************************************************************************************");
Expand All @@ -193,9 +232,10 @@ private static void DisplaySlotInfo(Center cvc, Session session)
Console.ResetColor();
Console.WriteLine("District: " + cvc.DistrictName);
Console.WriteLine("FeeType: " + cvc.FeeType);
Console.WriteLine("DoseType: " + Enum.GetName(typeof(DoseTypeModel), Convert.ToInt16(_configuration["CoWinAPI:MinimumVaccineAvailability"])));
Console.WriteLine("VaccineType: " + session.Vaccine);
Console.ForegroundColor = ConsoleColor.Green;
Console.WriteLine("AvailableCapacity: " + session.AvailableCapacity);
Console.WriteLine("AvailableCapacity: " + GetVaccineAvailabiltyForDoseType(session).ToString());
Console.ForegroundColor = ConsoleColor.Cyan;
Console.WriteLine("DateOfAvailability: " + session.Date);
Console.ResetColor();
Expand All @@ -208,7 +248,7 @@ private bool BookAvailableSlot(string sessionId, string slot, string captcha)
string endpoint = "";
bool isBookingSuccessful = false;
List<string> beneficiaries = new List<string>();

if (Convert.ToBoolean(_configuration["CoWinAPI:ProtectedAPI:IsToBeUsed"]))
{
endpoint = _configuration["CoWinAPI:ProtectedAPI:ScheduleAppointmentUrl"];
Expand All @@ -227,7 +267,7 @@ private bool BookAvailableSlot(string sessionId, string slot, string captcha)

IRestResponse response = new APIFacade(_configuration).Post(endpoint, requestBody);

if(response.StatusCode == HttpStatusCode.OK)
if (response.StatusCode == HttpStatusCode.OK)
{
Console.ForegroundColor = ConsoleColor.Green;
Console.WriteLine($"[INFO] CONGRATULATIONS! Booking Success - ResponseCode: {response.StatusDescription} ResponseData: {response.Content}");
Expand Down
12 changes: 12 additions & 0 deletions CoWin.Core/Models/DoseTypeModel.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
using System;
using System.Collections.Generic;
using System.Text;

namespace CoWin.Core.Models
{
public enum DoseTypeModel
{
FIRSTDOSE = 1,
SECONDDOSE = 2
}
}
6 changes: 6 additions & 0 deletions CoWin.Core/Models/SlotsModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -72,5 +72,11 @@ public partial class Session

[JsonProperty("slots")]
public List<string> Slots { get; set; }

[JsonProperty("available_capacity_dose1")]
public long AvailableCapacityFirstDose { get; set; }

[JsonProperty("available_capacity_dose2")]
public long AvailableCapacitySecondDose { get; set; }
}
}
18 changes: 10 additions & 8 deletions CoWin.Core/appsettings.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,21 +26,23 @@
"MinAgeLimit": 18,
"MaxAgeLimit": 45,
"MinimumVaccineAvailability": 1,
"VaccineType": "", // Blank Implies Any VaccineType: COVISHIELD OR COVAXIN; Default is Both
"VaccineType": "", // Blank Implies Any VaccineType: COVISHIELD OR COVAXIN OR SPUTNIK V; Default is any type of Vaccine
"DoseType": 1,
"VaccineFeeType": "Free", // Blank Implies Any VaccineFeeType: Free or Paid; Default is Free
"VaccinationCentreName": "", // Blank implies All Vaccination Centres in the District/PINCodes, which is default
"IsSearchToBeDoneByPINCode": true,
"IsSearchToBeDoneByPINCode": true, // Set this as True if you want to set by PINCode
"PINCodes": {
"Andheri": 400058,
"Bhandara": 441906
// "PlaceName": PinCode
"<REPLACE_ME_KEY-1st>": "<REPLACE_ME_VALUE-1st>",
"<REPLACE_ME_KEY-2nd>": "<REPLACE_ME_VALUE-2nd>"
},
"IsSearchToBeDoneByDistrict": false,
"IsSearchToBeDoneByDistrict": false, // Set this is True if you want to search By District
"Districts": {
"Mumbai": 395,
"Thane": 392
// "DistrictName": DistrictCode
"<REPLACE_ME_KEY-1st>": "<REPLACE_ME_VALUE-1st>",
"<REPLACE_ME_KEY-2nd>": "<REPLACE_ME_VALUE-2nd>"
},
"DateToSearch": "" // DD-MM-YYYY Format, Blank implies tomorrow's day
"DateToSearch": "" // DD-MM-YYYY Format, Blank implies tomorrow's day; Date Searched is upto 7 days from the date in DateToSearch
},
"Proxy": {
"IsToBeUsed": "false",
Expand Down

0 comments on commit 44da530

Please sign in to comment.