diff --git a/.circleci/config.yml b/.circleci/config.yml new file mode 100644 index 0000000..25569fc --- /dev/null +++ b/.circleci/config.yml @@ -0,0 +1,32 @@ +version: 2 +jobs: + build: + working_directory: ~/SEG2105-Olympus/OlympusServices + docker: + - image: circleci/android:api-28-alpha + environment: + JVM_OPTS: -Xmx3200m + steps: + - checkout: + path: ~/SEG2105-Olympus + - restore_cache: + key: jars-{{ checksum "build.gradle" }}-{{ checksum "app/build.gradle" }} + - run: + name: Chmod permissions + command: sudo chmod +x ./gradlew + - run: + name: Download Dependencies + command: ./gradlew androidDependencies + - save_cache: + paths: + - ~/.gradle + key: jars-{{ checksum "build.gradle" }}-{{ checksum "app/build.gradle" }} + - run: + name: Run UnitTest + command: ./gradlew test + - store_artifacts: + path: app/build/outputs/apk/debug/ + destination: apks/ + - store_test_results: + path: app/build/test-results + diff --git a/Deliverable2.zip b/Deliverable2.zip new file mode 100644 index 0000000..a5338f4 Binary files /dev/null and b/Deliverable2.zip differ diff --git a/OlympusServices/.idea/assetWizardSettings.xml b/OlympusServices/.idea/assetWizardSettings.xml new file mode 100644 index 0000000..6b96cf0 --- /dev/null +++ b/OlympusServices/.idea/assetWizardSettings.xml @@ -0,0 +1,14 @@ + + + + + + \ No newline at end of file diff --git a/OlympusServices/app/build.gradle b/OlympusServices/app/build.gradle index b9ba7b2..313fb68 100644 --- a/OlympusServices/app/build.gradle +++ b/OlympusServices/app/build.gradle @@ -24,7 +24,7 @@ android { } dependencies { - implementation fileTree(dir: 'libs', include: ['*.jar']) + implementation 'com.android.support:appcompat-v7:28.0.0' implementation 'com.android.support:design:28.0.0' implementation 'com.android.support.constraint:constraint-layout:1.1.3' @@ -39,6 +39,7 @@ dependencies { implementation 'com.jaredrummler:material-spinner:1.2.5' implementation 'com.android.support:design:28.0.0-alpha3' implementation 'com.rengwuxian.materialedittext:library:2.1.4' + implementation 'com.android.support:recyclerview-v7:28.0.0' } repositories { diff --git a/OlympusServices/app/src/main/AndroidManifest.xml b/OlympusServices/app/src/main/AndroidManifest.xml index f8bc8ab..d2c0e60 100644 --- a/OlympusServices/app/src/main/AndroidManifest.xml +++ b/OlympusServices/app/src/main/AndroidManifest.xml @@ -30,18 +30,45 @@ - - + + + + + + + \ No newline at end of file diff --git a/OlympusServices/app/src/main/java/com/uottawa/olympus/olympusservices/Admin.java b/OlympusServices/app/src/main/java/com/uottawa/olympus/olympusservices/Admin.java index 4d2938b..8b658b4 100644 --- a/OlympusServices/app/src/main/java/com/uottawa/olympus/olympusservices/Admin.java +++ b/OlympusServices/app/src/main/java/com/uottawa/olympus/olympusservices/Admin.java @@ -1,10 +1,28 @@ package com.uottawa.olympus.olympusservices; +/** + * The class Admin is a child of the class userType. The class gives + * admin permission over the app such that the user can add and delete services + * and can add and delete other users from the database of the app. + * + */ + public class Admin extends UserType { + /** + * The constructor for the admin object with predefined fields. + * There should only be one admin object for the entire app. + */ Admin(){ super("admin", "admin", "Admin", "Admin"); } + /** + * The getRole() method returns a string "Admin" + * the app gets role of user type objects for access + * app permission purposes. + * + * @return String object "Admin" + */ public String getRole(){ return "Admin"; } } diff --git a/OlympusServices/app/src/main/java/com/uottawa/olympus/olympusservices/AdminServicesList.java b/OlympusServices/app/src/main/java/com/uottawa/olympus/olympusservices/AdminServicesList.java new file mode 100644 index 0000000..b54eaa4 --- /dev/null +++ b/OlympusServices/app/src/main/java/com/uottawa/olympus/olympusservices/AdminServicesList.java @@ -0,0 +1,213 @@ +package com.uottawa.olympus.olympusservices; + +import android.content.Context; +import android.support.annotation.NonNull; +import android.support.v4.app.DialogFragment; +import android.support.v7.app.AppCompatActivity; +import android.os.Bundle; +import android.support.v7.widget.LinearLayoutManager; +import android.support.v7.widget.RecyclerView; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.TextView; +import android.widget.Toast; + +import java.util.Iterator; +import java.util.List; + +/** + * Creates the view and dialog listener for List of services + * which the admin can view and manipulate. + * + */ +public class AdminServicesList extends AppCompatActivity implements NewServiceDialogFragment.NoticeDialogListener, EditServiceDialogFragment.NoticeDialogListener{ + + //field for RecyclerView + private RecyclerView mRecyclerView; + //field for adapter of Recycler view + private RecyclerView.Adapter mAdapter; + //field for layout manager of Recyler view. + private RecyclerView.LayoutManager mLayoutManager; + + /** + * On creation loads up the xml, and generates the services list, + * and fillsout the recylerView fields. + * + * @param savedInstanceState Bundle to transfer information. + */ + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_admin_services_list); + DBHelper dbHelper = new DBHelper(this); + List serviceslist = dbHelper.getAllServices(); + Service[] services = new Service[(serviceslist.size())]; + Iterator iter = serviceslist.iterator(); + for (int i=0; i { + + private Service[] services; + private Context context; + + // Provide a reference to the views for each data item + // Complex data items may need more than one view per item, and + // you provide access to all the views for a data item in a view holder + + // Provide a suitable constructor (depends on the kind of dataset) + public MyAdapter(Service[] services, Context context) { + this.services = services; + } + + // Create new views (invoked by the layout manager) + @NonNull + @Override + public ServicesHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + View v = LayoutInflater.from(parent.getContext()) + .inflate(R.layout.list_item, parent, false); + ServicesHolder vh = new ServicesHolder(v); + return vh; + } + + // Replace the contents of a view (invoked by the layout manager) + @Override + public void onBindViewHolder(ServicesHolder holder, int position) { + Service service = services[position]; + holder.name.setText(service.getName()); + holder.rate.setText(String.format("$%,.2f", service.getRate())); + + + + } + + // Return the size of your dataset (invoked by the layout manager) + @Override + public int getItemCount() { + return services.length; + } + + class ServicesHolder extends RecyclerView.ViewHolder implements View.OnClickListener{ + + TextView name; + TextView rate; + + public ServicesHolder(View row){ + super(row); + name = row.findViewById(R.id.Name); + rate = row.findViewById(R.id.Rate); + row.setOnClickListener(this); + } + @Override + public void onClick(View view) { + TextView nameview = (TextView)view.findViewById(R.id.Name); + String name = nameview.getText().toString(); + editService(view, name); + + } + + + } + + + } + +} \ No newline at end of file diff --git a/OlympusServices/app/src/main/java/com/uottawa/olympus/olympusservices/AdminWelcome.java b/OlympusServices/app/src/main/java/com/uottawa/olympus/olympusservices/AdminWelcome.java index 0068236..f8e2861 100644 --- a/OlympusServices/app/src/main/java/com/uottawa/olympus/olympusservices/AdminWelcome.java +++ b/OlympusServices/app/src/main/java/com/uottawa/olympus/olympusservices/AdminWelcome.java @@ -5,29 +5,72 @@ import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.view.View; +/** + * The Admin Welcome class is the welcome + * screen for admin users when they have logged into the + * app. The admin welcome screen has features such as the + * user list and service list which it can only access. + * + */ + public class AdminWelcome extends AppCompatActivity { + /** + * Creates the xml pages for the class object + * on creation of the object. + * + * @param savedInstanceState Bundle for transfer of data. + */ @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_admin_welcome); } + + /** + * Override so that nothing occurs when pressing the + * back button on this activity of the app. + * + */ @Override public void onBackPressed(){ } + /** + * Logs out the user and returns them back to + * main activity. End all current user activity + * for security purposes. + * + * @param view View object of current activity. + */ public void LogOut(View view){ Intent intent = new Intent(getApplicationContext(), Main.class); startActivity(intent); finish(); } + + /** + * On click of list of user button that goes to + * UserList screen for the admin to edit the user list + * of the app. + * + * @param view View object of current activity + */ public void goToUsers(View view){ Intent intent = new Intent(getApplicationContext(), UsersList.class); startActivity(intent); } + + /** + * On click of list of services button goes to + * ServiceList screen for the admin to edit the + * service list of the app. + * + * @param view + */ public void goToServices(View view){ - Intent intent = new Intent(getApplicationContext(), ServicesList.class); + Intent intent = new Intent(getApplicationContext(), AdminServicesList.class); startActivity(intent); } } diff --git a/OlympusServices/app/src/main/java/com/uottawa/olympus/olympusservices/Appointment.java b/OlympusServices/app/src/main/java/com/uottawa/olympus/olympusservices/Appointment.java index 93cd7a0..536383e 100644 --- a/OlympusServices/app/src/main/java/com/uottawa/olympus/olympusservices/Appointment.java +++ b/OlympusServices/app/src/main/java/com/uottawa/olympus/olympusservices/Appointment.java @@ -1,5 +1,11 @@ package com.uottawa.olympus.olympusservices; +/** + * This class is the class for Appointments + * which has not been implemented yet. This + * feature shall be expanded upon next deliverable. + * + */ public class Appointment { Service service; ServiceProvider provider; diff --git a/OlympusServices/app/src/main/java/com/uottawa/olympus/olympusservices/DBHelper.java b/OlympusServices/app/src/main/java/com/uottawa/olympus/olympusservices/DBHelper.java index 452473d..d4d1f92 100644 --- a/OlympusServices/app/src/main/java/com/uottawa/olympus/olympusservices/DBHelper.java +++ b/OlympusServices/app/src/main/java/com/uottawa/olympus/olympusservices/DBHelper.java @@ -6,6 +6,7 @@ import android.database.sqlite.SQLiteOpenHelper; import android.database.Cursor; import android.content.ContentValues; +import java.util.ArrayList; import java.util.LinkedList; import java.util.List; @@ -22,7 +23,7 @@ import java.util.List; public class DBHelper extends SQLiteOpenHelper { //version of db used for update method - private static final int DB_VERSION = 2; + private static final int DB_VERSION = 3; //name of db in app data private static final String DB_NAME = "UsersDB.db"; @@ -40,15 +41,44 @@ public class DBHelper extends SQLiteOpenHelper { private static final String COLUMN_FIRSTNAME = "firstName"; private static final String COLUMN_LASTNAME = "lastName"; private static final String COLUMN_USERTYPE = "userType"; - -// private static final String TABLE_SERVICEPROVIDERS = "serviceProviders"; + private static final String COLUMN_ADDRESS = "address"; + private static final String COLUMN_PHONE = "phone"; + private static final String COLUMN_COMPANY = "company"; + private static final String COLUMN_LICENSED = "licensed"; //name of table containing services and rates private static final String TABLE_SERVICES = "services"; - //columns of TABLE_LOGIN + //columns of TABLE_SERVICES private static final String COLUMN_SERVICE = "service"; private static final String COLUMN_RATE = "rate"; + //name of table containing service provider information + private static final String TABLE_SERVICEPROVIDERS = "serviceProviders"; + //columns of TABLE_SERVICEPROVIDERS + private static final String COLUMN_SERVICEPROVIDERNAME = "username"; + private static final String COLUMN_SERVICEPROVIDERSERVICE = "service"; + + //name of table containing service provider availability + //availability is stored as number of minutes from 00:00 + private static final String TABLE_AVAILABILITY = "availability"; + //columns of TABLE_AVAILABILITY + private static final String COLUMN_AVAILABILITYNAME = "username"; + private static final String COLUMN_MONSTART = "mondaystart"; + private static final String COLUMN_MONEND = "mondayend"; + private static final String COLUMN_TUESTART = "tuesdaystart"; + private static final String COLUMN_TUEEND = "tuesdayend"; + private static final String COLUMN_WEDSTART = "wednesdaystart"; + private static final String COLUMN_WEDEND = "wednesdayend"; + private static final String COLUMN_THUSTART = "thursdaystart"; + private static final String COLUMN_THUEND = "thursdayend"; + private static final String COLUMN_FRISTART = "fridaystart"; + private static final String COLUMN_FRIEND = "fridayend"; + private static final String COLUMN_SATSTART = "saturdaystart"; + private static final String COLUMN_SATEND = "saturdayend"; + private static final String COLUMN_SUNSTART = "sundaystart"; + private static final String COLUMN_SUNEND = "sundayend"; + + /** * Creates an instance of DBHelper to allow activities to access and @@ -71,10 +101,15 @@ public class DBHelper extends SQLiteOpenHelper { //making the table containing user login information String CREATE_LOGIN_TABLE = "CREATE TABLE "+ TABLE_LOGIN + "(" + COLUMN_USERNAME + " TEXT UNIQUE NOT NULL PRIMARY KEY ON CONFLICT ROLLBACK," - + COLUMN_PASSWORD + " TEXT NOT NULL," + + COLUMN_PASSWORD + " TEXT," + COLUMN_FIRSTNAME + " TEXT DEFAULT 'FirstName'," + COLUMN_LASTNAME + " TEXT DEFAULT 'LastName'," - + COLUMN_USERTYPE + " TEXT NOT NULL" + ")"; + + COLUMN_USERTYPE + " TEXT NOT NULL, " + + COLUMN_ADDRESS + " TEXT, " + + COLUMN_PHONE + " TEXT, " + + COLUMN_COMPANY + " TEXT, " + + COLUMN_LICENSED + " TEXT " + + ")"; db.execSQL(CREATE_LOGIN_TABLE); //making the table containing services and their rates @@ -82,6 +117,38 @@ public class DBHelper extends SQLiteOpenHelper { + COLUMN_SERVICE + " TEXT UNIQUE NOT NULL PRIMARY KEY ON CONFLICT ROLLBACK," + COLUMN_RATE + " REAL DEFAULT 0.0" + ")"; db.execSQL(CREATE_SERVICES_TABLE); + + //making the table containing service providers and offered services + String CREATE_SERVICEPROVIDERS_TABLE = "CREATE TABLE "+ TABLE_SERVICEPROVIDERS + "(" + + COLUMN_SERVICEPROVIDERNAME + " TEXT, " + + COLUMN_SERVICEPROVIDERSERVICE + " TEXT, " + //service provider name is foreign key + + " FOREIGN KEY(" + COLUMN_SERVICEPROVIDERNAME + + ") REFERENCES " + TABLE_LOGIN + "(" + COLUMN_USERNAME +"), " + //service is also foreign key + + " FOREIGN KEY(" + COLUMN_SERVICEPROVIDERSERVICE + + ") REFERENCES " + TABLE_SERVICES + "(" + COLUMN_SERVICE +") " + + ")"; + db.execSQL(CREATE_SERVICEPROVIDERS_TABLE); + + //making the table containing services and their rates + String CREATE_AVAILABILITY_TABLE = "CREATE TABLE "+ TABLE_AVAILABILITY + "(" + + COLUMN_AVAILABILITYNAME + " TEXT UNIQUE NOT NULL PRIMARY KEY ON CONFLICT ROLLBACK, " + + COLUMN_MONSTART + " REAL, " + + COLUMN_MONEND + " REAL, " + + COLUMN_TUESTART + " REAL, " + + COLUMN_TUEEND + " REAL, " + + COLUMN_WEDSTART + " REAL, " + + COLUMN_WEDEND + " REAL, " + + COLUMN_THUSTART + " REAL, " + + COLUMN_THUEND + " REAL, " + + COLUMN_FRISTART + " REAL, " + + COLUMN_FRIEND + " REAL, " + + COLUMN_SATSTART + " REAL, " + + COLUMN_SATEND + " REAL, " + + COLUMN_SUNSTART + " REAL, " + + COLUMN_SUNEND + " REAL)"; + db.execSQL(CREATE_AVAILABILITY_TABLE); } @Override @@ -97,6 +164,39 @@ public class DBHelper extends SQLiteOpenHelper { db.execSQL("CREATE TABLE IF NOT EXISTS "+ TABLE_SERVICES + "(" + COLUMN_SERVICE + " TEXT UNIQUE NOT NULL PRIMARY KEY ON CONFLICT ROLLBACK," + COLUMN_RATE + " REAL DEFAULT 0.0" + ")"); + + case 2: //going from db versions 1-2 to 3 + db.execSQL("CREATE TABLE IF NOT EXISTS "+ TABLE_SERVICEPROVIDERS + "(" + + COLUMN_SERVICEPROVIDERNAME + " TEXT NOT NULL, " + + COLUMN_SERVICEPROVIDERSERVICE + " TEXT NOT NULL, " + //service provider name is foreign key + + " FOREIGN KEY(" + COLUMN_SERVICEPROVIDERNAME + + ") REFERENCES " + TABLE_LOGIN + "(" + COLUMN_USERNAME +"), " + //service is also foreign key + + " FOREIGN KEY(" + COLUMN_SERVICEPROVIDERSERVICE + + ") REFERENCES " + TABLE_SERVICES + "(" + COLUMN_SERVICE +") " + + ")"); + db.execSQL("CREATE TABLE IF NOT EXISTS "+ TABLE_AVAILABILITY + "(" + + COLUMN_AVAILABILITYNAME + " TEXT UNIQUE NOT NULL PRIMARY KEY ON CONFLICT ROLLBACK, " + + COLUMN_MONSTART + " REAL, " + + COLUMN_MONEND + " REAL, " + + COLUMN_TUESTART + " REAL, " + + COLUMN_TUEEND + " REAL, " + + COLUMN_WEDSTART + " REAL, " + + COLUMN_WEDEND + " REAL, " + + COLUMN_THUSTART + " REAL, " + + COLUMN_THUEND + " REAL, " + + COLUMN_FRISTART + " REAL, " + + COLUMN_FRIEND + " REAL, " + + COLUMN_SATSTART + " REAL, " + + COLUMN_SATEND + " REAL, " + + COLUMN_SUNSTART + " REAL, " + + COLUMN_SUNEND + " REAL)"); + + db.execSQL("ALTER TABLE " + TABLE_LOGIN + " ADD COLUMN " + COLUMN_ADDRESS + " TEXT"); + db.execSQL("ALTER TABLE " + TABLE_LOGIN + " ADD COLUMN " + COLUMN_PHONE + " TEXT"); + db.execSQL("ALTER TABLE " + TABLE_LOGIN + " ADD COLUMN " + COLUMN_COMPANY + " TEXT"); + db.execSQL("ALTER TABLE " + TABLE_LOGIN + " ADD COLUMN " + COLUMN_LICENSED + " TEXT"); } } @@ -117,6 +217,7 @@ public class DBHelper extends SQLiteOpenHelper { * @return whether adding user was successful */ public boolean addUser(UserType userType){ + if (userType == null) return false; //Check for duplicate username by querying login table Cursor cursor = writeDB.query(TABLE_LOGIN, new String[] {COLUMN_USERNAME}, @@ -137,10 +238,35 @@ public class DBHelper extends SQLiteOpenHelper { values.put(COLUMN_FIRSTNAME, userType.getFirstname()); values.put(COLUMN_LASTNAME, userType.getLastname()); values.put(COLUMN_USERTYPE, userType.getClass().getSimpleName()); + if (userType instanceof ServiceProvider){ + ServiceProvider serviceProvider = (ServiceProvider)userType; + + String address = serviceProvider.getAddress(); + if (address != null){ + values.put(COLUMN_ADDRESS, address); + } + + String phone = serviceProvider.getPhonenumber(); + if (phone != null){ + values.put(COLUMN_PHONE, phone); + } + + String company = serviceProvider.getCompanyname(); + if (company != null){ + values.put(COLUMN_COMPANY, company); + } + + boolean licensed = serviceProvider.isLicensed(); + values.put(COLUMN_LICENSED, Boolean.toString(licensed)); + + } + writeDB.insert(TABLE_LOGIN, null, values); + return true; } + /** * Looks in database for user with requested username, and returns an * object of UserType corresponding to said user's role. @@ -150,7 +276,8 @@ public class DBHelper extends SQLiteOpenHelper { * @return object representing user found */ public UserType findUserByUsername(String username){ - UserType usertype; + if (username == null) return null; + UserType usertype = null; Cursor cursor = readDB.rawQuery("SELECT * FROM " + TABLE_LOGIN + " WHERE " + COLUMN_USERNAME + " = ?", new String[]{username}); @@ -159,18 +286,24 @@ public class DBHelper extends SQLiteOpenHelper { String password = cursor.getString(1); String firstname = cursor.getString(2); String lastname = cursor.getString(3); + String address = cursor.getString(5); + String phonenumber = cursor.getString(6); + String companyname = cursor.getString(7); + boolean licensed = Boolean.parseBoolean(cursor.getString(8)); if (cursor.getString(4) .equals("Admin")){ usertype = new Admin(); } else if (cursor.getString(4) .equals("ServiceProvider")){ - usertype = new ServiceProvider(username, password, firstname, lastname); + ServiceProvider serviceProvider = new ServiceProvider(username, password, firstname, lastname, address, phonenumber, companyname, licensed); + getAllServicesProvidedByUser(serviceProvider); + getAvailabilities(serviceProvider); + usertype = serviceProvider; } else { usertype = new HomeOwner(username, password, firstname, lastname); } - } else { - usertype = null; } + cursor.close(); return usertype; } @@ -189,14 +322,27 @@ public class DBHelper extends SQLiteOpenHelper { * @return whether updating user information was successful */ public boolean updateUserInfo(String username, String password, String firstname, String lastname){ + return updateUserInfo(username, password, firstname, lastname, + null, null, null, null); + } + + + + + public boolean updateUserInfo(String username, String password, String firstname, String lastname, + String address, String phonenumber, String companyname, Boolean licensed){ ContentValues values = new ContentValues(); - values.put(COLUMN_PASSWORD, password); - values.put(COLUMN_FIRSTNAME, firstname); - values.put(COLUMN_LASTNAME, lastname); + if (password != null && !password.equals("")) values.put(COLUMN_PASSWORD, password); + if (firstname != null && !firstname.equals("")) values.put(COLUMN_FIRSTNAME, firstname); + if (lastname != null && !lastname.equals(""))values.put(COLUMN_LASTNAME, lastname); + if (address != null && !address.equals(""))values.put(COLUMN_ADDRESS, address); + if (phonenumber != null && !phonenumber.equals(""))values.put(COLUMN_PHONE, phonenumber); + if (companyname != null && !companyname.equals(""))values.put(COLUMN_COMPANY, companyname); + if (licensed != null)values.put(COLUMN_LICENSED, Boolean.toString(licensed)); + return writeDB.update(TABLE_LOGIN, values, COLUMN_USERNAME+" = ?", new String[]{username}) > 0; - } /** @@ -236,11 +382,12 @@ public class DBHelper extends SQLiteOpenHelper { * @return whether adding service was successful */ public boolean addService(Service service){ - //Check for duplicate username by querying login table + if (service == null) return false; + //Check for duplicate username by querying services table Cursor cursor = writeDB.query(TABLE_SERVICES, new String[] {COLUMN_SERVICE}, COLUMN_SERVICE + " = ?", - new String[]{service.getName()}, + new String[]{service.getName().toLowerCase().trim()}, null, null, null, "1"); //If cursor has 1+ elements in it, username already exists in table @@ -251,7 +398,7 @@ public class DBHelper extends SQLiteOpenHelper { cursor.close(); ContentValues values = new ContentValues(); - values.put(COLUMN_SERVICE, service.getName()); + values.put(COLUMN_SERVICE, service.getName().toLowerCase().trim()); values.put(COLUMN_RATE, service.getRate()); writeDB.insert(TABLE_SERVICES, null, values); return true; @@ -266,7 +413,10 @@ public class DBHelper extends SQLiteOpenHelper { * @return object representing service found */ public Service findService(String serviceName){ + if (serviceName == null) return null; + Service service; + serviceName = serviceName.toLowerCase().trim(); Cursor cursor = readDB.rawQuery("SELECT * FROM " + TABLE_SERVICES + " WHERE " + COLUMN_SERVICE + " = ?", new String[]{serviceName}); @@ -293,11 +443,12 @@ public class DBHelper extends SQLiteOpenHelper { * @return whether updating service information was successful */ public boolean updateService(Service service){ + if (service == null) return false; ContentValues values = new ContentValues(); values.put(COLUMN_RATE, service.getRate()); return writeDB.update(TABLE_SERVICES, values, COLUMN_SERVICE+" = ?", - new String[]{service.getName()}) > 0; + new String[]{service.getName().toLowerCase().trim()}) > 0; } /** @@ -312,6 +463,9 @@ public class DBHelper extends SQLiteOpenHelper { * @return whether updating service information was successful */ public boolean updateService(String name, double rate){ + if (name == null) return false; + + name = name.toLowerCase().trim(); ContentValues values = new ContentValues(); if (rate > 0) values.put(COLUMN_RATE, rate); @@ -322,16 +476,38 @@ public class DBHelper extends SQLiteOpenHelper { /** * Looks in database for a service, and deletes the corresponding - * entry. Returns true if a user was deleted, false otherwise. + * entry. Returns true if a service was deleted, false otherwise. * * @param service service of entry to delete * @return whether the service was deleted */ public boolean deleteService(String service) { - return writeDB.delete(TABLE_SERVICES, COLUMN_SERVICE+" = ?", + if (service == null) return false; + + boolean deleted; + String nullify = null; + service = service.toLowerCase().trim(); + ContentValues contentValues = new ContentValues(); + contentValues.put(COLUMN_SERVICEPROVIDERSERVICE, nullify); + writeDB.update(TABLE_SERVICEPROVIDERS, contentValues, COLUMN_SERVICEPROVIDERSERVICE+" = ?", + new String[]{service}); + + deleted = writeDB.delete(TABLE_SERVICES, COLUMN_SERVICE+" = ?", new String[]{service}) > 0; + + if (deleted) { + writeDB.delete(TABLE_SERVICEPROVIDERS, COLUMN_SERVICEPROVIDERSERVICE+" = ?", + new String[]{service}); + } else { + ContentValues restoreContentValues = new ContentValues(); + restoreContentValues.put(COLUMN_SERVICEPROVIDERSERVICE, service); + writeDB.update(TABLE_SERVICEPROVIDERS, restoreContentValues, COLUMN_SERVICEPROVIDERSERVICE+" = ?", + null); + } + return deleted; } + /** * Returns a list of String arrays containing the service categories, * names and hourly rates. @@ -339,7 +515,184 @@ public class DBHelper extends SQLiteOpenHelper { * @return list of arrays of [service, rate] */ public List getAllServices(){ - return getAll("SELECT * FROM " + TABLE_SERVICES); + return getAll("SELECT * FROM " + TABLE_SERVICES + " ORDER BY " + COLUMN_SERVICE); + } + + public boolean addServiceProvidedByUser(ServiceProvider serviceProvider, Service service){ + if (serviceProvider == null || service == null) return false; + return addServiceProvidedByUser(serviceProvider.getUsername(), service.getName()); + } + + public boolean addServiceProvidedByUser(ServiceProvider serviceProvider, String serviceName){ + if (serviceProvider == null || serviceName == null) return false; + return addServiceProvidedByUser(serviceProvider.getUsername(), serviceName); + } + + public boolean addServiceProvidedByUser(String serviceProviderUsername, String serviceName){ + if (serviceProviderUsername == null || serviceName == null) return false; + + //TODO: Check if serviceProviderUsername and serviceName are in db before adding + + serviceName = serviceName.toLowerCase().trim(); + + //Check for duplicate username/service combination by querying login table + Cursor cursor = writeDB.query(TABLE_SERVICEPROVIDERS, + new String[] {COLUMN_SERVICEPROVIDERNAME}, + COLUMN_SERVICEPROVIDERNAME + " = ? AND " + + COLUMN_SERVICEPROVIDERSERVICE + " = ?", + new String[]{serviceProviderUsername, serviceName}, + null, null, null, + "1"); + //If cursor has 1+ elements in it, username already exists in table + if (cursor != null && cursor.getCount() > 0){ + cursor.close(); + return false; + } + cursor.close(); + + ContentValues values = new ContentValues(); + values.put(COLUMN_SERVICEPROVIDERNAME, serviceProviderUsername); + values.put(COLUMN_SERVICEPROVIDERSERVICE, serviceName); + writeDB.insert(TABLE_SERVICEPROVIDERS, null, values); + return true; + } + + public boolean deleteServiceProvidedByUser(ServiceProvider serviceProvider, Service service){ + if (serviceProvider == null || service == null) return false; + return deleteServiceProvidedByUser(serviceProvider.getUsername(), service.getName()); + } + + public boolean deleteServiceProvidedByUser(ServiceProvider serviceProvider, String serviceName){ + if (serviceProvider == null || serviceName == null) return false; + return deleteServiceProvidedByUser(serviceProvider.getUsername(), serviceName); + } + + public boolean deleteServiceProvidedByUser(String serviceProviderUsername, String serviceName){ + if (serviceProviderUsername == null || serviceName == null) return false; + serviceName = serviceName.toLowerCase().trim(); + return writeDB.delete(TABLE_SERVICEPROVIDERS, + COLUMN_SERVICEPROVIDERNAME + " = ? AND " + + COLUMN_SERVICEPROVIDERSERVICE + " = ?", + new String[]{serviceProviderUsername, serviceName}) > 0; + } + + public List getAllServicesProvidedByUser(ServiceProvider serviceProvider){ + if (serviceProvider == null) return new ArrayList<>(); + + return getAllServicesProvidedByUser(serviceProvider.getUsername()); + } + + public List getAllServicesProvidedByUser(String serviceProviderName){ + if (serviceProviderName == null) return new ArrayList<>(); + + return getAll("SELECT " + TABLE_SERVICES + "." + COLUMN_SERVICE + ", " + + TABLE_SERVICES + "." + COLUMN_RATE + + " FROM " + TABLE_SERVICES + + " JOIN " + TABLE_SERVICEPROVIDERS + + " ON " + TABLE_SERVICEPROVIDERS + "." + COLUMN_SERVICEPROVIDERSERVICE + " = " + + TABLE_SERVICES + "." + COLUMN_SERVICE + + " AND " + TABLE_SERVICEPROVIDERS + "." + COLUMN_SERVICEPROVIDERNAME + + "= '" + serviceProviderName + "'"); + } + + public List getAllProvidersByService(Service service){ + if (service == null) return new ArrayList<>(); + + return getAllProvidersByService(service.getName()); + } + + public List getAllProvidersByService(String serviceName){ + if (serviceName == null) return new ArrayList<>(); + + serviceName = serviceName.toLowerCase().trim(); + return getAll("SELECT " + COLUMN_SERVICEPROVIDERNAME + + " FROM " + TABLE_SERVICEPROVIDERS + + " WHERE " + COLUMN_SERVICEPROVIDERSERVICE + " = '" + + serviceName + "'"); + } + + public boolean updateAvailability(ServiceProvider serviceProvider){ + //availability is stored as number of minutes from 00:00 + if (serviceProvider == null) return false; + int[][] availabilities = serviceProvider.getAvailabilities(); + if (availabilities == null) return false; + + Cursor cursor = readDB.rawQuery("SELECT * FROM " + TABLE_AVAILABILITY + + " WHERE " + COLUMN_AVAILABILITYNAME + " = ?", + new String[]{serviceProvider.getUsername()}); + + ContentValues contentValues = new ContentValues(); + addAvailabilityToContentValues(contentValues, COLUMN_MONSTART, COLUMN_MONEND, availabilities[0]); + addAvailabilityToContentValues(contentValues, COLUMN_TUESTART, COLUMN_TUEEND, availabilities[1]); + addAvailabilityToContentValues(contentValues, COLUMN_WEDSTART, COLUMN_WEDEND, availabilities[2]); + addAvailabilityToContentValues(contentValues, COLUMN_THUSTART, COLUMN_THUEND, availabilities[3]); + addAvailabilityToContentValues(contentValues, COLUMN_FRISTART, COLUMN_FRIEND, availabilities[4]); + addAvailabilityToContentValues(contentValues, COLUMN_SATSTART, COLUMN_SATEND, availabilities[5]); + addAvailabilityToContentValues(contentValues, COLUMN_SUNSTART, COLUMN_SUNEND, availabilities[6]); + if (!cursor.moveToFirst()){ + contentValues.put(COLUMN_AVAILABILITYNAME, serviceProvider.getUsername()); + writeDB.insert(TABLE_AVAILABILITY, null, contentValues); + } else { + writeDB.update(TABLE_AVAILABILITY, contentValues, + COLUMN_AVAILABILITYNAME + " = ?", new String[]{serviceProvider.getUsername()}); + } + return true; + } + + private void addAvailabilityToContentValues(ContentValues contentValues, + String startColumn, String endColumn, + int[] startAndEndTimes){ + if (startAndEndTimes == null){ + contentValues.put(startColumn, 0); + contentValues.put(endColumn, 0); + } else { + int startTime = startAndEndTimes[0]*60+startAndEndTimes[1]; + int endTime = startAndEndTimes[2]*60+startAndEndTimes[3]; + if (endTime - startTime <=0 || startTime > 1439 || startTime <= 0 + || endTime > 1439 || endTime <= 0) { + contentValues.put(startColumn, 0); + contentValues.put(endColumn, 0); + } else { + contentValues.put(startColumn, startTime); + contentValues.put(endColumn, endTime); + } + } + + } + + + //note that this method overwrites serviceProvider's availability if it exists + public int[][] getAvailabilities(ServiceProvider serviceProvider){ + if (serviceProvider==null) return new int[7][4]; + Cursor cursor = readDB.rawQuery("SELECT * FROM " + TABLE_AVAILABILITY + + " WHERE " + COLUMN_AVAILABILITYNAME + " = ?", + new String[]{serviceProvider.getUsername()}); + if (cursor.moveToFirst()){ + for (int i = 0; i < 7; i++) { + int start = cursor.getInt(i*2+1); + int end = cursor.getInt(i*2+2); + serviceProvider.setAvailabilities(i, start/60, start%60, + end/60, end%60); + } + } + return serviceProvider.getAvailabilities(); + } + + public int[][] getAvailabilities(String serviceProviderName){ + int[][] availabilities = new int[7][4]; + if (serviceProviderName==null) return availabilities; + + Cursor cursor = readDB.rawQuery("SELECT * FROM " + TABLE_AVAILABILITY + + " WHERE " + COLUMN_AVAILABILITYNAME + " = ?", + new String[]{serviceProviderName}); + if (cursor.moveToFirst()){ + for (int i = 0; i < 7; i++) { + int start = cursor.getInt(i*2+1); + int end = cursor.getInt(i*2+2); + availabilities[i] = new int[]{start/60, start%60, end/60, end%60}; + } + } + return availabilities; } /** @@ -363,6 +716,11 @@ public class DBHelper extends SQLiteOpenHelper { } + /** + * Gets all items in a table + * @param rawQuery SELECT * query + * @return list of array representing all items in raw query + */ private List getAll(String rawQuery){ List list = new LinkedList<>(); String[] infoArray; @@ -383,3 +741,4 @@ public class DBHelper extends SQLiteOpenHelper { } } + diff --git a/OlympusServices/app/src/main/java/com/uottawa/olympus/olympusservices/DeleteServiceDialogFragment.java b/OlympusServices/app/src/main/java/com/uottawa/olympus/olympusservices/DeleteServiceDialogFragment.java new file mode 100644 index 0000000..031cfae --- /dev/null +++ b/OlympusServices/app/src/main/java/com/uottawa/olympus/olympusservices/DeleteServiceDialogFragment.java @@ -0,0 +1,64 @@ +package com.uottawa.olympus.olympusservices; + +import android.app.AlertDialog; +import android.app.Dialog; +import android.content.Context; +import android.content.DialogInterface; +import android.os.Bundle; +import android.support.v4.app.DialogFragment; +import android.view.LayoutInflater; +import android.widget.EditText; +import android.widget.Toast; + +public class DeleteServiceDialogFragment extends DialogFragment{ + public interface NoticeDialogListener { + public void onDialogDelete(DialogFragment dialog); + public void onDialogNevermind(DialogFragment dialog); + } + DeleteServiceDialogFragment.NoticeDialogListener mListener; + + @Override + public void onAttach(Context context) { + super.onAttach(context); + // Verify that the host activity implements the callback interface + try { + // Instantiate the NoticeDialogListener so we can send events to the host + mListener = (DeleteServiceDialogFragment.NoticeDialogListener) context; + } catch (ClassCastException e) { + // The activity doesn't implement the interface, throw exception + throw new ClassCastException(this.toString() + + " must implement NoticeDialogListener"); + } + } + @Override + public Dialog onCreateDialog(Bundle savedInstanceState) { + AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); + // Get the layout inflater + LayoutInflater inflater = getActivity().getLayoutInflater(); + + // Inflate and set the layout for the dialog + // Pass null as the parent view because its going in the dialog layout + builder.setView(inflater.inflate(R.layout.dialog_service_delete, null)) + // Add action buttons + .setPositiveButton(R.string.remove, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int id) { + Bundle args = new Bundle(); + args.putString("name", (String)getArguments().get("name")); + DeleteServiceDialogFragment.this.setArguments(args); + mListener.onDialogDelete(DeleteServiceDialogFragment.this); + + + } + }) + .setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int id) { + Bundle args = new Bundle(); + args.putString("name", (String)getArguments().get("name")); + mListener.onDialogNevermind(DeleteServiceDialogFragment.this); + } + }) + .setTitle((String)getArguments().get("name")); + return builder.create(); + } +} diff --git a/OlympusServices/app/src/main/java/com/uottawa/olympus/olympusservices/EditProfile.java b/OlympusServices/app/src/main/java/com/uottawa/olympus/olympusservices/EditProfile.java new file mode 100644 index 0000000..b673fbc --- /dev/null +++ b/OlympusServices/app/src/main/java/com/uottawa/olympus/olympusservices/EditProfile.java @@ -0,0 +1,92 @@ +package com.uottawa.olympus.olympusservices; + +import android.content.Intent; +import android.support.v7.app.AppCompatActivity; +import android.os.Bundle; +import android.view.View; +import android.widget.CheckBox; +import android.widget.TextView; +import android.widget.Toast; + +public class EditProfile extends AppCompatActivity { + String username; + DBHelper dbHelper; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_edit_profile); + Bundle bundle = getIntent().getExtras(); + username = bundle.getString("username"); + dbHelper = new DBHelper(this); + ServiceProvider user; + user = (ServiceProvider)dbHelper.findUserByUsername(username); + TextView firstname = findViewById(R.id.FirstNameInput); + TextView lastname = findViewById(R.id.LastNameInput); + TextView password = findViewById(R.id.PasswordInput); + TextView companyname = findViewById(R.id.CompanyNameInput); + TextView address = findViewById(R.id.AddressInput); + TextView phonenumber = findViewById(R.id.PhoneNumberInput); + CheckBox licensed = findViewById(R.id.LicensedInput); + + + firstname.setText(user.getFirstname()); + lastname.setText(user.getLastname()); + password.setText(user.getPassword()); + companyname.setText(user.getCompanyname()); + address.setText(user.getAddress()); + phonenumber.setText(user.getPhonenumber()); + licensed.setChecked(user.isLicensed()); + + + } + + /** + * Override so that previous screen refreshes when pressing the + * back button on this activity of the app. + * + */ + @Override + public void onBackPressed(){ + Intent intent = new Intent(getApplicationContext(),ServiceProviderWelcome.class); + intent.putExtra("username", username); + startActivity(intent); + finish(); + } + public void Save(View view){ + TextView firstname = findViewById(R.id.FirstNameInput); + TextView lastname = findViewById(R.id.LastNameInput); + TextView password = findViewById(R.id.PasswordInput); + TextView companyname = findViewById(R.id.CompanyNameInput); + TextView address = findViewById(R.id.AddressInput); + TextView phonenumber = findViewById(R.id.PhoneNumberInput); + CheckBox licensed = findViewById(R.id.LicensedInput); + + if(password.getText().toString().length()>=5 && firstname.getText().toString().length()>0 + && lastname.getText().toString().length()>0 && companyname.getText().toString().length()>0 + && address.getText().toString().length()>0 && phonenumber.getText().toString().length()>0 + && password.getText().toString().matches("[a-zA-Z0-9]*") + && firstname.getText().toString().matches("[a-zA-Z]*") + && lastname.getText().toString().matches("[a-zA-Z]*") + && companyname.getText().toString().matches("^[a-zA-Z0-9_ ]*$") + && address.getText().toString().matches("^[a-zA-Z0-9_ ]*$") + && phonenumber.getText().toString().matches("^(\\+\\d{1,2}\\s)?\\(?\\d{3}\\)?[\\s.-]?\\d{3}[\\s.-]?\\d{4}$") + ) { + + if(dbHelper.updateUserInfo(username, password.getText().toString(), firstname.getText().toString(), lastname.getText().toString(), + address.getText().toString(), phonenumber.getText().toString(), companyname.getText().toString(), licensed.isChecked())){ + Toast.makeText(this, "Profile has been updated", Toast.LENGTH_LONG).show(); + } + else{ + Toast.makeText(this, "Could not update profile ", Toast.LENGTH_LONG).show(); + + } + + } + else{ + Toast.makeText(this, "Fields cannot be empty and must be formatted correctly", Toast.LENGTH_LONG).show(); + } + } + + +} diff --git a/OlympusServices/app/src/main/java/com/uottawa/olympus/olympusservices/EditServiceDialogFragment.java b/OlympusServices/app/src/main/java/com/uottawa/olympus/olympusservices/EditServiceDialogFragment.java index ecdd495..722a410 100644 --- a/OlympusServices/app/src/main/java/com/uottawa/olympus/olympusservices/EditServiceDialogFragment.java +++ b/OlympusServices/app/src/main/java/com/uottawa/olympus/olympusservices/EditServiceDialogFragment.java @@ -7,12 +7,19 @@ import android.content.DialogInterface; import android.os.Bundle; import android.support.v4.app.DialogFragment; import android.view.LayoutInflater; +import android.widget.EditText; +import android.widget.Toast; public class EditServiceDialogFragment extends DialogFragment{ -public interface NoticeDialogListener { - public void onDialogEdit(DialogFragment dialog); - public void onDialogDelete(DialogFragment dialog); + /** + * Creates a NoticeDialogListener interface for other classes to + * implement to have this class be functional in the other classes. + * + */ + public interface NoticeDialogListener { + public void onDialogEdit(DialogFragment dialog); + public void onDialogDelete(DialogFragment dialog); } EditServiceDialogFragment.NoticeDialogListener mListener; @@ -30,6 +37,14 @@ public interface NoticeDialogListener { + " must implement NoticeDialogListener"); } } + + /** + * Edit the Dialog to change rate of a service that the + * admin wants to change. + * + * @param savedInstanceState Bundle to transfer information. + * @return Dialog that is sent to admin for information. + */ @Override public Dialog onCreateDialog(Bundle savedInstanceState) { AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); @@ -44,24 +59,32 @@ public interface NoticeDialogListener { @Override public void onClick(DialogInterface dialog, int id) { Bundle args = new Bundle(); - //@anshu: get the name and rate to come from the dialog_service_new dialog - args.putString("name", "hey"); - args.putDouble("rate", 2.5); - // - EditServiceDialogFragment.this.setArguments(args); - mListener.onDialogEdit(EditServiceDialogFragment.this); + args.putString("name", (String)getArguments().get("name")); + EditText rateInput = (EditText) ((AlertDialog) dialog).findViewById(R.id.RateInput); + if(rateInput.getText().toString().length()>0 && !rateInput.getText().toString().equals(".")){ + Double rate = Double.parseDouble(rateInput.getText().toString()); + args.putDouble("rate", rate); + + EditServiceDialogFragment.this.setArguments(args); + mListener.onDialogEdit(EditServiceDialogFragment.this); + } + else{ + Toast.makeText(getContext(), "Rate cannot be empty", Toast.LENGTH_LONG).show(); + + } + } }) .setNegativeButton(R.string.delete, new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int id) { Bundle args = new Bundle(); - //@anshu: get the name and rate to come from the dialog_service_new dialog - args.putString("name", "hey"); - // + args.putString("name", (String)getArguments().get("name")); + EditServiceDialogFragment.this.setArguments(args); mListener.onDialogDelete(EditServiceDialogFragment.this); } - }); + }) + .setTitle((String)getArguments().get("name")); return builder.create(); } } diff --git a/OlympusServices/app/src/main/java/com/uottawa/olympus/olympusservices/HomeOwner.java b/OlympusServices/app/src/main/java/com/uottawa/olympus/olympusservices/HomeOwner.java index 4807fa2..690ff19 100644 --- a/OlympusServices/app/src/main/java/com/uottawa/olympus/olympusservices/HomeOwner.java +++ b/OlympusServices/app/src/main/java/com/uottawa/olympus/olympusservices/HomeOwner.java @@ -1,12 +1,35 @@ package com.uottawa.olympus.olympusservices; +/** + * The class HomeOwner is a child of the class userType. The class permission + * to the user of a standard homeowner hence users with homeowner permissions + * are able to book service providers. Has not been implemented yet. + * + */ + public class HomeOwner extends UserType { + /** + * Constructor of the HomeOwner object that takes the username, password, + * lastname, and firstname as parameters to use for the creation of a + * HomeOwner object. + * + * @param username String for username. + * @param password String for password. + * @param firstname String for firstname. + * @param lastname String for lastname. + */ HomeOwner(String username, String password, String firstname, String lastname){ super(username, password, firstname, lastname); } + /** + * Returns the type of role the user is for this class. + * will return the string "HomeOwner". + * + * @return "HomeOwner" String object. + */ public String getRole(){ return "HomeOwner"; } } diff --git a/OlympusServices/app/src/main/java/com/uottawa/olympus/olympusservices/LogIn.java b/OlympusServices/app/src/main/java/com/uottawa/olympus/olympusservices/LogIn.java index 6afde1a..4fb387a 100644 --- a/OlympusServices/app/src/main/java/com/uottawa/olympus/olympusservices/LogIn.java +++ b/OlympusServices/app/src/main/java/com/uottawa/olympus/olympusservices/LogIn.java @@ -7,14 +7,34 @@ import android.widget.EditText; import android.view.View; import android.widget.Toast; +/** + * The login activity for the app that checks + * credentials of users to allow them to log in and use + * the functionality of the app. + * + */ + public class LogIn extends AppCompatActivity { + /** + * On creation of this activity the login xml file + * is loaded up. + * + * @param savedInstanceState Bundle object for transfer of information. + */ @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_log_in); } + /** + * On click of the login button the app checks if all specification + * for login credentials are met and then either sends an error toast + * or logs the user in. + * + * @param view View object that contains all the buttons and editTexts. + */ public void onClickLogIn(View view){ String username = ((EditText) findViewById(R.id.UsernameInput)).getText().toString(); String password = ((EditText) findViewById(R.id.PasswordInput)).getText().toString(); @@ -30,6 +50,12 @@ public class LogIn extends AppCompatActivity { startActivity(intent); finish(); } + else if(user.getRole()=="ServiceProvider"){ + Intent intent = new Intent(getApplicationContext(),ServiceProviderWelcome.class); + intent.putExtra("username", username); + startActivity(intent); + finish(); + } else { Intent intent = new Intent(getApplicationContext(),Welcome.class); intent.putExtra("username", username); @@ -54,6 +80,12 @@ public class LogIn extends AppCompatActivity { } + + /** + * app closes the the activity when back is pressed and + * no user information written down is saved in the EditText for + * security purposes. + */ @Override public void onBackPressed(){ Intent intent = new Intent(getApplicationContext(), Main.class); diff --git a/OlympusServices/app/src/main/java/com/uottawa/olympus/olympusservices/Main.java b/OlympusServices/app/src/main/java/com/uottawa/olympus/olympusservices/Main.java index 6245cb1..eb86354 100644 --- a/OlympusServices/app/src/main/java/com/uottawa/olympus/olympusservices/Main.java +++ b/OlympusServices/app/src/main/java/com/uottawa/olympus/olympusservices/Main.java @@ -5,8 +5,21 @@ import android.os.Bundle; import android.content.Intent; import android.view.View; +/** + * The starting page of the app which contains two buttons + * of either registering for the app or logging into an existing + * account. + * + */ + public class Main extends AppCompatActivity { + /** + * On creation of the object the app loads up the xml page + * for the class and creates dbHelper object and Admin object + * and then add the admin into the database. + * @param savedInstanceState + */ @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); @@ -18,6 +31,11 @@ public class Main extends AppCompatActivity { } + /** + * On click of the sign up button loads up the sign up activity + * + * @param view View object containing the buttons. + */ public void onClickSignUp(View view){ Intent intent = new Intent(getApplicationContext(),SignUp.class); startActivity(intent); @@ -25,6 +43,11 @@ public class Main extends AppCompatActivity { } + /** + * On click of the Login button loads up the login activity. + * + * @param view View object containing the buttons. + */ public void onClickLogIn(View view){ Intent intent = new Intent(getApplicationContext(),LogIn.class); startActivity(intent); diff --git a/OlympusServices/app/src/main/java/com/uottawa/olympus/olympusservices/NewServiceDialogFragment.java b/OlympusServices/app/src/main/java/com/uottawa/olympus/olympusservices/NewServiceDialogFragment.java index 2e35941..09cc543 100644 --- a/OlympusServices/app/src/main/java/com/uottawa/olympus/olympusservices/NewServiceDialogFragment.java +++ b/OlympusServices/app/src/main/java/com/uottawa/olympus/olympusservices/NewServiceDialogFragment.java @@ -8,8 +8,29 @@ import android.os.Bundle; import android.support.v4.app.DialogFragment; import android.view.LayoutInflater; +import android.content.res.Resources; +import android.os.Bundle; +import android.support.annotation.NonNull; +import android.support.annotation.Nullable; +import android.view.ViewGroup; +import android.widget.EditText; +import android.view.View; +import android.widget.Toast; + +import com.rengwuxian.materialedittext.MaterialEditText; + +/** + * Creates a dialog whenever admin adds a new service into the + * service list which the admin fills in to provide the fields of + * the service. + */ public class NewServiceDialogFragment extends DialogFragment { + /** + * Creates a NoticeDialogListener interface for other classes to + * implement to have this class be functional in the other classes. + * + */ public interface NoticeDialogListener { public void onDialogNew(DialogFragment dialog); public void onDialogNevermind(DialogFragment dialog); @@ -30,26 +51,48 @@ public class NewServiceDialogFragment extends DialogFragment { + " must implement NoticeDialogListener"); } } + + /** + * Creates the Dialog to add the name and rate of a new service that + * the admin has added to the list of services. + * + * @param savedInstanceState Bundle to transfer information. + * @return Dialog that is sent to admin for information. + */ @Override public Dialog onCreateDialog(Bundle savedInstanceState) { + AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); // Get the layout inflater LayoutInflater inflater = getActivity().getLayoutInflater(); + View view = inflater.inflate(R.layout.dialog_service_new, null); + // Inflate and set the layout for the dialog // Pass null as the parent view because its going in the dialog layout - builder.setView(inflater.inflate(R.layout.dialog_service_new, null)) + builder.setView(view) // Add action buttons .setPositiveButton(R.string.add, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int id) { - Bundle args = new Bundle(); - //@anshu: get the name and rate to come from the dialog_service_new dialog - args.putString("name", "hey"); - args.putDouble("rate", 2.5); - /// - NewServiceDialogFragment.this.setArguments(args); - mListener.onDialogNew(NewServiceDialogFragment.this); + EditText nameInput = (EditText) ((AlertDialog) dialog).findViewById(R.id.NameInput); + EditText rateInput = (EditText) ((AlertDialog) dialog).findViewById(R.id.RateInput); + String name = nameInput.getText().toString(); + DBHelper dbHelper = new DBHelper(getContext()); + if (rateInput.getText().toString().length()>0 && !rateInput.getText().toString().equals(".") && name.length()>0 && name.matches("^[a-zA-Z0-9_ ]*$") && dbHelper.findService(name)==null){ + Double rate = Double.parseDouble(rateInput.getText().toString()); + Bundle args = new Bundle(); + args.putString("name", name); + args.putDouble("rate", rate); + NewServiceDialogFragment.this.setArguments(args); + mListener.onDialogNew(NewServiceDialogFragment.this); + } + else if(!(rateInput.getText().toString().length()>0) || !(name.length()>0)|| !name.matches("[a-zA-Z]*") || !rateInput.getText().toString().equals(".")){ + Toast.makeText(getContext(), "Service must have an alphanumeric name and a rate", Toast.LENGTH_LONG).show(); + } + else{ + Toast.makeText(getContext(), "Service already exists", Toast.LENGTH_LONG).show(); + } } }) .setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() { diff --git a/OlympusServices/app/src/main/java/com/uottawa/olympus/olympusservices/Service.java b/OlympusServices/app/src/main/java/com/uottawa/olympus/olympusservices/Service.java index 266115a..1c311ef 100644 --- a/OlympusServices/app/src/main/java/com/uottawa/olympus/olympusservices/Service.java +++ b/OlympusServices/app/src/main/java/com/uottawa/olympus/olympusservices/Service.java @@ -3,33 +3,78 @@ package com.uottawa.olympus.olympusservices; import java.util.ArrayList; import java.util.List; +/** + * creates a service object that can be managed by admin and service providers + * and be viewed by the homeowner for the sale of service which is the main + * functionality of the app. + * + */ + public class Service { + //name of the service field. private String name; + //rate of the service field. private double rate; + //list of services the providers that offers this service. private List serviceProviders; + /** + * Constructor for a new service which uses the parameters + * to fill in the fields of the service and creates an arrayList + * for all the providers that provide that service. + * + * @param name String of the name of service. + * @param rate double of the price of service. + */ Service(String name, double rate) { this.name = name; this.rate = rate; serviceProviders = new ArrayList(); } + /** + * Gets the Name field of the service. + * + * @return String of the name. + */ public String getName() { return name; } + /** + * Gets the Rate field of the service. + * + * @return double of the rate. + */ public double getRate() { return rate; } + /** + * Changes the name field of the object to parameter given. + * + * @param name String object of new name + */ public void setName(String name) { this.name = name; } + /** + * Changes the rate field of the object to parameter given. + * + * @param rate double of new rate. + */ public void setRate(double rate) { this.rate = rate; } + /** + * Adds a new service provider that offers this service into the list + * of service providers that offer this service. + * + * @param user Service Provider object which is added to the service's list. + * @return boolean of if the Service provider has been added. + */ public boolean addServiceProvider(ServiceProvider user){ for (ServiceProvider listUser : serviceProviders){ if (user.getUsername().equals(listUser.getUsername())){ diff --git a/OlympusServices/app/src/main/java/com/uottawa/olympus/olympusservices/ServiceProvider.java b/OlympusServices/app/src/main/java/com/uottawa/olympus/olympusservices/ServiceProvider.java index 15bfde4..b768ad8 100644 --- a/OlympusServices/app/src/main/java/com/uottawa/olympus/olympusservices/ServiceProvider.java +++ b/OlympusServices/app/src/main/java/com/uottawa/olympus/olympusservices/ServiceProvider.java @@ -1,19 +1,72 @@ package com.uottawa.olympus.olympusservices; import java.util.ArrayList; +import java.util.Date; import java.util.List; +/** + * The service provider is the child userType class. The service provider + * class provides services which the homeowner can buy in the app. + * + */ + public class ServiceProvider extends UserType { + //Field for list of services that service provider offers. private List services; + //Field for array of availabilities + /* + DO NOT CHANGE THIS ARRAY. The 2D array size is hard coded such that the first array has a size + of 7 and the array inside has an array size of 4. The array is setup such that the index represent a day of the + week. Monday is 0, Tuesday is 1, Wednesday is 2, Thursday is 3, Friday is 4, Saturday is 5, + Sunday is 6. so, [Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday]. Inside each of + the arrays there is a another array containing int values such that index 0,1,2,3 is startHour, + startMin, endHour, endMin respectively. + */ + private int[][] availabilities; - ServiceProvider(String username, String password, String firstname, String lastname){ + private String address; + private String phonenumber; + private String companyname; + private boolean licensed; + + + + + /** + * Constructor for the service object which takes the parameters to + * fill out the service providers field. + * + * @param username String of the username. + * @param password String of the password. + * @param firstname String of the firstname. + * @param lastname String of the lastname. + */ + ServiceProvider(String username, String password, String firstname, String lastname, String address, + String phonenumber, String companyname, boolean licensed){ super(username, password, firstname, lastname); services = new ArrayList<>(); + availabilities = new int[7][4]; + this.address = address; + this.phonenumber = phonenumber; + this.companyname = companyname; + this.licensed = licensed; } + /** + * gets the role of the UserType. + * + * @return String "Service Provider" + */ public String getRole(){ return "ServiceProvider"; } + /** + * adds service to the to service list if the service is in the + * database list of services. + * + * @param service Service object which is added to the services field. + * @return boolean whether service is added. + */ public boolean addService(Service service){ for (Service listService : services){ if (service.getName().equals(listService.getName())){ @@ -24,8 +77,65 @@ public class ServiceProvider extends UserType { return true; } + /** + * Gets the services list field of service provider. + * + * @return arrayList of Services + */ + + + + public void setAvailabilities(int day, int startHour, int startMin, int endHour, int endMin){ + availabilities[day][0] = startHour; + availabilities[day][1] = startMin; + availabilities[day][2] = endHour; + availabilities[day][3] = endMin; + } + + public int[][] getAvailabilities(){ + return availabilities; + } + + public void setAvailabilities(int[][] availabilities) { + this.availabilities = availabilities; + } + public void setServices(List services) { + this.services = services; + } + public List getServices(){ return services; } -} + public String getAddress() { + return address; + } + + public void setAddress(String address) { + this.address = address; + } + + public String getPhonenumber() { + return phonenumber; + } + + public void setPhonenumber(String phonenumber) { + this.phonenumber = phonenumber; + } + + public String getCompanyname() { + return companyname; + } + + public void setCompanyname(String companyname) { + this.companyname = companyname; + } + + public boolean isLicensed() { + return licensed; + } + + public void setLicensed(boolean licensed) { + this.licensed = licensed; + } +} \ No newline at end of file diff --git a/OlympusServices/app/src/main/java/com/uottawa/olympus/olympusservices/ServiceProviderAvailabilities.java b/OlympusServices/app/src/main/java/com/uottawa/olympus/olympusservices/ServiceProviderAvailabilities.java new file mode 100644 index 0000000..d1ea01e --- /dev/null +++ b/OlympusServices/app/src/main/java/com/uottawa/olympus/olympusservices/ServiceProviderAvailabilities.java @@ -0,0 +1,70 @@ +package com.uottawa.olympus.olympusservices; + +import android.app.TimePickerDialog; +import android.content.Intent; +import android.support.v7.app.AppCompatActivity; +import android.os.Bundle; +import android.view.View; +import android.widget.Button; +import android.widget.TimePicker; + +import java.util.Calendar; + +public class ServiceProviderAvailabilities extends AppCompatActivity { + private String username; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_service_provider_availabilities); + Bundle bundle = getIntent().getExtras(); + username = bundle.getString("username"); + } + + + public void onClick(View v) { + // Get Current Time + final Calendar c = Calendar.getInstance(); + int hour = c.get(Calendar.HOUR_OF_DAY); + int minute = c.get(Calendar.MINUTE); + + final Button button = (Button)v; + + // Launch Time Picker Dialog + TimePickerDialog timePickerDialog = new TimePickerDialog(this, + new TimePickerDialog.OnTimeSetListener() { + + @Override + public void onTimeSet(TimePicker view, int hourOfDay, + int minute) { + if (minute==0){ + button.setText(hourOfDay + ":00"); + } + else { + button.setText(hourOfDay + ":" + minute); + } + + //set availibility for service provider and check start time is less than finish + } + + }, hour, minute, false); + timePickerDialog.show(); + } + + public void onRemove(View view){ + //set time to Start/End, set availibility for start and end to null + } + + /** + * Override so that previous screen refreshes when pressing the + * back button on this activity of the app. + * + */ + @Override + public void onBackPressed(){ + Intent intent = new Intent(getApplicationContext(),ServiceProviderWelcome.class); + intent.putExtra("username", username); + startActivity(intent); + finish(); + } +} diff --git a/OlympusServices/app/src/main/java/com/uottawa/olympus/olympusservices/ServiceProviderServicesList.java b/OlympusServices/app/src/main/java/com/uottawa/olympus/olympusservices/ServiceProviderServicesList.java new file mode 100644 index 0000000..d2b8184 --- /dev/null +++ b/OlympusServices/app/src/main/java/com/uottawa/olympus/olympusservices/ServiceProviderServicesList.java @@ -0,0 +1,238 @@ +package com.uottawa.olympus.olympusservices; + +import android.content.Context; +import android.content.Intent; +import android.support.annotation.NonNull; +import android.support.design.widget.Snackbar; +import android.support.v4.app.DialogFragment; +import android.support.v7.app.AppCompatActivity; +import android.os.Bundle; +import android.support.v7.widget.LinearLayoutManager; +import android.support.v7.widget.RecyclerView; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ArrayAdapter; +import android.widget.ListAdapter; +import android.widget.TextView; +import android.widget.Toast; + +import com.jaredrummler.materialspinner.MaterialSpinner; + +import java.util.Iterator; +import java.util.List; + +/** + * Creates the view and dialog listener for List of services + * which the admin can view and manipulate. + * + */ +public class ServiceProviderServicesList extends AppCompatActivity implements DeleteServiceDialogFragment.NoticeDialogListener{ + + //field for RecyclerView + private RecyclerView mRecyclerView; + //field for adapter of Recycler view + private RecyclerView.Adapter mAdapter; + //field for layout manager of Recyler view. + private RecyclerView.LayoutManager mLayoutManager; + + private String username; + + /** + * On creation loads up the xml, and generates the services list, + * and fillsout the recylerView fields. + * + * @param savedInstanceState Bundle to transfer information. + */ + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_service_provider_services_list); + + Bundle bundle = getIntent().getExtras(); + username = bundle.getString("username"); + DBHelper dbHelper = new DBHelper(this); + + //grid + List serviceslist2 = dbHelper.getAllServicesProvidedByUser(username); + Service[] services2 = new Service[(serviceslist2.size())]; + Iterator iter2 = serviceslist2.iterator(); + for (int i=0; i serviceslist = dbHelper.getAllServices(); + String[] services = new String[(serviceslist.size())]; + Iterator iter = serviceslist.iterator(); + for (int i=0; i servicesadapter = new ArrayAdapter + (this, android.R.layout.simple_spinner_item, services); + + servicesadapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); + + spinner.setAdapter(servicesadapter); + + spinner.setOnItemSelectedListener(new MaterialSpinner.OnItemSelectedListener() { + + @Override public void onItemSelected(MaterialSpinner view, int position, long id, String item) { + Snackbar.make(view, "Clicked " + item, Snackbar.LENGTH_LONG).show(); + } + }); + + } + + + /** + * Override so that previous screen refreshes when pressing the + * back button on this activity of the app. + * + */ + @Override + public void onBackPressed(){ + Intent intent = new Intent(getApplicationContext(),ServiceProviderWelcome.class); + intent.putExtra("username", username); + startActivity(intent); + finish(); + } + + /** + * Deletes services from the list. + * + * @param view View object contains the generated list and buttons + */ + public void deleteService(View view, String name) { + DialogFragment newFragment = new DeleteServiceDialogFragment(); + newFragment.show(getSupportFragmentManager(), "addService"); + Bundle args = new Bundle(); + args.putString("name", name); + newFragment.setArguments(args); + } + + /** + * Adds service to the list. + * + * @param view View object contains the generated list and buttons + */ + public void addService(View view) { + MaterialSpinner spinner = findViewById(R.id.ServicesInput); + String servicename = spinner.getText().toString(); + DBHelper dbHelper = new DBHelper(this); + if(dbHelper.addServiceProvidedByUser(username, servicename)){ + this.recreate(); + } + else{ + Toast.makeText(this, "Could not add service", Toast.LENGTH_SHORT).show(); + } + + } + + + + /** + * Uses Dialog to delete a service from the serviceList. + * + * @param dialog DialogFragment that contains the delete service button. + */ + + @Override + public void onDialogDelete(DialogFragment dialog) { + DBHelper dbHelper = new DBHelper(this); + String name = (String)dialog.getArguments().get("name"); + dbHelper.deleteServiceProvidedByUser(username, name); + dialog.dismiss(); + this.recreate(); + } + + /** + * Does nothing + * + * @param dialog DialogFragment that contains the cancel button. + */ + @Override + public void onDialogNevermind(DialogFragment dialog) { + + } + + public class MyAdapter extends RecyclerView.Adapter { + + private Service[] services; + private Context context; + + // Provide a reference to the views for each data item + // Complex data items may need more than one view per item, and + // you provide access to all the views for a data item in a view holder + + // Provide a suitable constructor (depends on the kind of dataset) + public MyAdapter(Service[] services, Context context) { + this.services = services; + } + + // Create new views (invoked by the layout manager) + @NonNull + @Override + public ServicesHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + View v = LayoutInflater.from(parent.getContext()) + .inflate(R.layout.list_item, parent, false); + ServicesHolder vh = new ServicesHolder(v); + return vh; + } + + // Replace the contents of a view (invoked by the layout manager) + @Override + public void onBindViewHolder(ServicesHolder holder, int position) { + Service service = services[position]; + holder.name.setText(service.getName()); + holder.rate.setText(String.format("$%,.2f", service.getRate())); + + + + } + + // Return the size of your dataset (invoked by the layout manager) + @Override + public int getItemCount() { + return services.length; + } + + class ServicesHolder extends RecyclerView.ViewHolder implements View.OnClickListener{ + + TextView name; + TextView rate; + + public ServicesHolder(View row){ + super(row); + name = row.findViewById(R.id.Name); + rate = row.findViewById(R.id.Rate); + row.setOnClickListener(this); + } + @Override + public void onClick(View view) { + TextView nameview = (TextView)view.findViewById(R.id.Name); + String name = nameview.getText().toString(); + deleteService(view, name); + + } + + + } + + + } + +} \ No newline at end of file diff --git a/OlympusServices/app/src/main/java/com/uottawa/olympus/olympusservices/ServiceProviderWelcome.java b/OlympusServices/app/src/main/java/com/uottawa/olympus/olympusservices/ServiceProviderWelcome.java new file mode 100644 index 0000000..efa2570 --- /dev/null +++ b/OlympusServices/app/src/main/java/com/uottawa/olympus/olympusservices/ServiceProviderWelcome.java @@ -0,0 +1,84 @@ +package com.uottawa.olympus.olympusservices; + +import android.support.v7.app.AppCompatActivity; +import android.os.Bundle; +import android.view.View; +import android.widget.TextView; +import android.content.Intent; + +/** + * Welcome class creates the welcome screen for the HomeOwners and ServiceProviders + * as a temporary screen until full functionality of those two a classes are + * implemented. + * + */ +public class ServiceProviderWelcome extends AppCompatActivity { + String username; + + /** + * On creation of this object the app will display the xml file for + * the welcome page which gets the role and username of the UserType + * object and welcomes the user with a message. + * + * @param savedInstanceState Bundle to transfer data + */ + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_service_provider_welcome); + Bundle bundle = getIntent().getExtras(); + username = bundle.getString("username"); + DBHelper dbHelper = new DBHelper(this); + UserType user; + user = dbHelper.findUserByUsername(username); + TextView welcome = findViewById(R.id.Welcome); + welcome.setText("Welcome "+user.getFirstname()+ " you are logged in as a Service Provider"); + + + + } + + /** + * Override so that nothing occurs when pressing the + * back button on this activity of the app. + * + */ + @Override + public void onBackPressed(){ + } + + /** + * Logs out the user and returns them back to + * main activity. End all current user activity + * for security purposes. + * + * @param view View object of current activity. + */ + public void LogOut(View view){ + Intent intent = new Intent(getApplicationContext(), Main.class); + startActivity(intent); + finish(); + } + + public void EditProfile(View view){ + Intent intent = new Intent(getApplicationContext(),EditProfile.class); + intent.putExtra("username", username); + startActivity(intent); + finish(); + } + + public void EditServices(View view){ + Intent intent = new Intent(getApplicationContext(),ServiceProviderServicesList.class); + intent.putExtra("username", username); + startActivity(intent); + finish(); + } + public void EditAvailabilities(View view){ + Intent intent = new Intent(getApplicationContext(),ServiceProviderAvailabilities.class); + intent.putExtra("username", username); + startActivity(intent); + finish(); + } + + +} diff --git a/OlympusServices/app/src/main/java/com/uottawa/olympus/olympusservices/ServicesList.java b/OlympusServices/app/src/main/java/com/uottawa/olympus/olympusservices/ServicesList.java deleted file mode 100644 index 8f29a44..0000000 --- a/OlympusServices/app/src/main/java/com/uottawa/olympus/olympusservices/ServicesList.java +++ /dev/null @@ -1,86 +0,0 @@ -package com.uottawa.olympus.olympusservices; - -import android.support.v4.app.DialogFragment; -import android.support.v7.app.AppCompatActivity; -import android.os.Bundle; -import android.view.View; -import android.widget.AdapterView; -import android.widget.ArrayAdapter; -import android.widget.GridView; -import android.widget.TextView; - -import java.util.Iterator; -import java.util.List; - -public class ServicesList extends AppCompatActivity implements NewServiceDialogFragment.NoticeDialogListener, EditServiceDialogFragment.NoticeDialogListener{ - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - setContentView(R.layout.activity_services_list); - DBHelper dbHelper = new DBHelper(this); - List users = dbHelper.getAllServices(); - String[] services = new String[(users.size()+1)*2]; - services[0] = "Name"; - services[1] = "Rate"; - Iterator iter = users.iterator(); - for (int i=0; i(this, R.layout.simple_list_item_1_customized, services); - GridView gridView = findViewById(R.id.Services); - gridView.setAdapter(adapter); - gridView.setOnItemClickListener(new AdapterView.OnItemClickListener() { - @Override - public void onItemClick(AdapterView parent, View view, - int position, long id) { - editService(view); - } - }); - } - public void addService(View view) { - DialogFragment newFragment = new NewServiceDialogFragment(); - newFragment.show(getSupportFragmentManager(), "addService"); - } - public void editService(View view) { - DialogFragment newFragment = new EditServiceDialogFragment(); - newFragment.show(getSupportFragmentManager(), "editService"); - } - //add new service - @Override - public void onDialogNew(DialogFragment dialog) { - DBHelper dbHelper = new DBHelper(this); - String name = (String)dialog.getArguments().get("name"); - Double rate = (Double)dialog.getArguments().get("rate"); - dbHelper.addService(new Service(name,rate)); - dialog.dismiss(); - this.recreate(); - } - //user clicked cancel - @Override - public void onDialogNevermind(DialogFragment dialog) { - - } - //edits service with info from dialog - @Override - public void onDialogEdit(DialogFragment dialog) { - DBHelper dbHelper = new DBHelper(this); - String name = (String)dialog.getArguments().get("name"); - Double rate = (Double)dialog.getArguments().get("rate"); - dbHelper.updateService(new Service(name,rate)); - dialog.dismiss(); - this.recreate(); - } - //deletes service with info from dialog - @Override - public void onDialogDelete(DialogFragment dialog) { - DBHelper dbHelper = new DBHelper(this); - String name = (String)dialog.getArguments().get("name"); - dbHelper.deleteService(name); - dialog.dismiss(); - this.recreate(); - } - -} \ No newline at end of file diff --git a/OlympusServices/app/src/main/java/com/uottawa/olympus/olympusservices/SignUp.java b/OlympusServices/app/src/main/java/com/uottawa/olympus/olympusservices/SignUp.java index d4d8e38..9d9300d 100644 --- a/OlympusServices/app/src/main/java/com/uottawa/olympus/olympusservices/SignUp.java +++ b/OlympusServices/app/src/main/java/com/uottawa/olympus/olympusservices/SignUp.java @@ -9,7 +9,21 @@ import android.widget.EditText; import android.view.View; import android.widget.Toast; +/** + * This class is used to create new userType where the user + * fills in his information and his data is sent to to the database + * to create a new userType object. + * + */ + public class SignUp extends AppCompatActivity { + + /** + * On creation of this class the xml page is loaded up onto the app and + * the EditTexts are set up to accept the information of the user. + * + * @param savedInstanceState Bundle for transferring information + */ @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); @@ -25,6 +39,13 @@ public class SignUp extends AppCompatActivity { } + /** + * On click creates a new user if the the user information + * fits the criteria specified by the documentation and is + * not a duplicate of another user. + * + * @param view View object that contains all the editText and buttons used. + */ public void onClickSignUp(View view){ UserType newUser; String username = ((EditText) findViewById(R.id.UsernameInput)).getText().toString(); @@ -32,41 +53,66 @@ public class SignUp extends AppCompatActivity { String firstname = ((EditText) findViewById(R.id.FirstNameInput)).getText().toString(); String lastname = ((EditText) findViewById(R.id.LastNameInput)).getText().toString(); MaterialSpinner spinner = findViewById(R.id.RoleInput); - //TODO add message conditional to check if every EditText is filled up to standards - if(username.length()>=5 && password.length()>5 && firstname.length()>0 && lastname.length()>0 && username.matches("[a-zA-Z0-9]*") && password.matches("[a-zA-Z0-9]*") + + if(username.length()>=5 && password.length()>=5 && firstname.length()>0 && lastname.length()>0 && username.matches("[a-zA-Z0-9]*") && password.matches("[a-zA-Z0-9]*") && firstname.matches("[a-zA-Z]*") && lastname.matches("[a-zA-Z]*")){ + DBHelper dbHelper = new DBHelper(this); + Intent intent = new Intent(getApplicationContext(),LogIn.class); switch(spinner.getText().toString()){ case "Home Owner": newUser = new HomeOwner(username,password,firstname,lastname); + if(dbHelper.addUser(newUser)){ + startActivity(intent); + finish(); + }else{ + Toast.makeText(this,"Username is taken",Toast.LENGTH_LONG).show(); + } break; case "Service Provider": - newUser = new ServiceProvider(username,password,firstname,lastname); + if(dbHelper.findUserByUsername(username)==null) { + Intent intent2 = new Intent(getApplicationContext(), SignUpPart2.class); + intent2.putExtra("firstname", firstname); + intent2.putExtra("lastname", lastname); + intent2.putExtra("username", username); + intent2.putExtra("password", password); + startActivity(intent2); + finish(); + }else{ + Toast.makeText(this,"Username is taken",Toast.LENGTH_LONG).show(); + } break; + default: newUser = new HomeOwner(username,password,firstname,lastname); //if nothing is enter then defaults to user role. + + if(dbHelper.addUser(newUser)){ + startActivity(intent); + finish(); + }else{ + Toast.makeText(this,"Username is taken",Toast.LENGTH_LONG).show(); + } break; } - DBHelper dbHelper = new DBHelper(this); - Intent intent = new Intent(getApplicationContext(),LogIn.class); //TODO check if signup should take to the login page or automatically login - if(dbHelper.addUser(newUser)){ - startActivity(intent); - finish(); - }else{ - Toast.makeText(this,"Username is taken",Toast.LENGTH_LONG).show(); - } } else if(firstname.length()==0 || lastname.length()==0 || username.length()==0 || password.length()==0){ Toast.makeText(this, "Fields cannot be empty", Toast.LENGTH_LONG).show(); } - else if (username.length()<=5 || password.length()<=5 ){ + else if (username.length()<5 || password.length()<5 ){ Toast.makeText(this, "Password and username must be longer than 4 characters", Toast.LENGTH_LONG).show(); } else{ Toast.makeText(this, "Fields may only contain alphanumeric values", Toast.LENGTH_LONG).show(); } } + + /** + * app closes the the activity when back is pressed and + * no user information written down is saved in the EditText for + * security purposes. + */ + @Override public void onBackPressed(){ Intent intent = new Intent(getApplicationContext(), Main.class); diff --git a/OlympusServices/app/src/main/java/com/uottawa/olympus/olympusservices/SignUpPart2.java b/OlympusServices/app/src/main/java/com/uottawa/olympus/olympusservices/SignUpPart2.java new file mode 100644 index 0000000..d3b4672 --- /dev/null +++ b/OlympusServices/app/src/main/java/com/uottawa/olympus/olympusservices/SignUpPart2.java @@ -0,0 +1,54 @@ +package com.uottawa.olympus.olympusservices; + +import android.content.Intent; +import android.support.v7.app.AppCompatActivity; +import android.os.Bundle; +import android.view.View; +import android.widget.CheckBox; +import android.widget.EditText; +import android.widget.Toast; + +public class SignUpPart2 extends AppCompatActivity { + private String username; + private String password; + private String firstname; + private String lastname; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_sign_up_part2); + Bundle bundle = getIntent().getExtras(); + username = bundle.getString("username"); + password = bundle.getString("password"); + firstname = bundle.getString("firstname"); + lastname = bundle.getString("lastname"); + } + + public void SignUp(View view){ + DBHelper dbHelper = new DBHelper(this); + Intent intent = new Intent(getApplicationContext(),LogIn.class); + String companyname = ((EditText) findViewById(R.id.CompanyNameInput)).getText().toString(); + String phonenumber = ((EditText) findViewById(R.id.PhoneNumberInput)).getText().toString(); + String address = ((EditText) findViewById(R.id.AddressInput)).getText().toString(); + boolean licensed = ((CheckBox) findViewById(R.id.LicensedInput)).isChecked(); + + if(companyname.length()>0 && address.length()>0 && phonenumber.length()>0 + && companyname.matches("^[a-zA-Z0-9_ ]*$") && address.matches("^[a-zA-Z0-9_ ]*$") + && phonenumber.matches("^(\\+\\d{1,2}\\s)?\\(?\\d{3}\\)?[\\s.-]?\\d{3}[\\s.-]?\\d{4}$")) { + + ServiceProvider serviceProvider = new ServiceProvider(username, password, firstname, lastname, + address, phonenumber, companyname, licensed); + if(dbHelper.addUser(serviceProvider)){ + startActivity(intent); + finish(); + }else{ + Toast.makeText(this,"Could not create account",Toast.LENGTH_LONG).show(); + } + } + else{ + Toast.makeText(this, "Fields cannot be empty and must be formatted correctly", Toast.LENGTH_LONG).show(); + } + + } +} diff --git a/OlympusServices/app/src/main/java/com/uottawa/olympus/olympusservices/UserType.java b/OlympusServices/app/src/main/java/com/uottawa/olympus/olympusservices/UserType.java index 7539a2a..98f4766 100644 --- a/OlympusServices/app/src/main/java/com/uottawa/olympus/olympusservices/UserType.java +++ b/OlympusServices/app/src/main/java/com/uottawa/olympus/olympusservices/UserType.java @@ -3,16 +3,33 @@ package com.uottawa.olympus.olympusservices; import java.io.Serializable; +/** + * UserType is the abstract object that is the parent class + * of all users in this program with all common methods and + * fields set in this one class. + */ + public abstract class UserType { + //field for the username attached to the userType. String username; + //field for the password attached to the userType. String password; + //field for the firstname attached to the userType. String firstname; + //field for the lastname attached to the userType. String lastname; - - + /** + * Constructor filling out all the field values with given parameters + * entered by a new user for the app. + * + * @param username String object containing the username. + * @param password String object containing the password. + * @param firstname String object containing the firstname. + * @param lastname String object containing the lastname. + */ UserType(String username, String password, String firstname, String lastname){ this.username = username; this.password = password; @@ -20,25 +37,54 @@ public abstract class UserType { this.lastname = lastname; } + /** + * Abstract method to get the role of each userType child in the app. + * + * @return String object specifying the role of userType. + */ public abstract String getRole(); + /** + * Gets the username field of userType. + * + * @return String of the username. + */ public String getUsername() { return username; } + /** + * Gets the password field of userType. + * + * @return String of the password. + */ public String getPassword() { return password; } + /** + * Gets the firstname field of userType. + * + * @return String of firstname + */ public String getFirstname() { return firstname; } + /** + * Gets the lastname field of userType. + * + * @return String of lastname + */ public String getLastname() { return lastname; } - + /** + * Sets the username field with given parameters. + * + * @param username String for new username. + */ public void setUsername(String username) { //remember to call updateUser(String username, String password, String firstname, String lastname) //in activity whenever a setter is called. DBHelper requires a Context (Activity) to be initialized @@ -47,6 +93,11 @@ public abstract class UserType { } + /** + * Sets the password field with given parameters. + * + * @param password String of new password. + */ public void setPassword(String password) { //remember to call updateUser(String username, String password, String firstname, String lastname) //in activity whenever a setter is called. DBHelper requires a Context (Activity) to be initialized @@ -54,6 +105,11 @@ public abstract class UserType { this.password = password; } + /** + * Sets the firstname field with given parameters. + * + * @param firstname String of new firstname. + */ public void setFirstname(String firstname) { //remember to call updateUser(String username, String password, String firstname, String lastname) //in activity whenever a setter is called. DBHelper requires a Context (Activity) to be initialized @@ -68,7 +124,11 @@ public abstract class UserType { this.lastname = lastname; } - + /** + * Compares this userType and another userType to see if there fields are equal. + * + * @param other Usertype object that is compared to this userType. + */ public boolean equals(UserType other){ if(this.username.equals(other.username)&&this.password.equals(other.password)&& this.firstname.equals(other.firstname)&&this.lastname.equals(other.lastname)){ diff --git a/OlympusServices/app/src/main/java/com/uottawa/olympus/olympusservices/UsersList.java b/OlympusServices/app/src/main/java/com/uottawa/olympus/olympusservices/UsersList.java index 4cb5afb..b1f34d7 100644 --- a/OlympusServices/app/src/main/java/com/uottawa/olympus/olympusservices/UsersList.java +++ b/OlympusServices/app/src/main/java/com/uottawa/olympus/olympusservices/UsersList.java @@ -8,8 +8,22 @@ import android.widget.GridView; import java.util.Iterator; import java.util.List; +/** + * screen for user list that the admin can access + * and manage all users in the program. Userlist is generated through + * the database using DBHelper class. + * + */ + public class UsersList extends AppCompatActivity { + /** + * on Creation of this class the app loads up the xml page for + * activity_user_list and generates a gridview using the database + * for all the users in the app. + * + * @param savedInstanceState bundle to transfer data + */ @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); @@ -17,14 +31,12 @@ public class UsersList extends AppCompatActivity { DBHelper dbHelper = new DBHelper(this); List users = dbHelper.getAllUsers(); - String[] usernames = new String[(users.size()+1)*2]; - usernames[0] = "Username"; - usernames[1] = "User Type"; + String[] usernames = new String[(users.size())*2]; Iterator iter = users.iterator(); for (int i=0; i(this, R.layout.simple_list_item_1_customized, usernames); GridView gridView = findViewById(R.id.Users); diff --git a/OlympusServices/app/src/main/java/com/uottawa/olympus/olympusservices/Welcome.java b/OlympusServices/app/src/main/java/com/uottawa/olympus/olympusservices/Welcome.java index 4389f62..24ac48c 100644 --- a/OlympusServices/app/src/main/java/com/uottawa/olympus/olympusservices/Welcome.java +++ b/OlympusServices/app/src/main/java/com/uottawa/olympus/olympusservices/Welcome.java @@ -6,8 +6,21 @@ import android.view.View; import android.widget.TextView; import android.content.Intent; +/** + * Welcome class creates the welcome screen for the HomeOwners and ServiceProviders + * as a temporary screen until full functionality of those two a classes are + * implemented. + * + */ public class Welcome extends AppCompatActivity { + /** + * On creation of this object the app will display the xml file for + * the welcome page which gets the role and username of the UserType + * object and welcomes the user with a message. + * + * @param savedInstanceState Bundle to transfer data + */ @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); @@ -24,9 +37,23 @@ public class Welcome extends AppCompatActivity { } + + /** + * Override so that nothing occurs when pressing the + * back button on this activity of the app. + * + */ @Override public void onBackPressed(){ } + + /** + * Logs out the user and returns them back to + * main activity. End all current user activity + * for security purposes. + * + * @param view View object of current activity. + */ public void LogOut(View view){ Intent intent = new Intent(getApplicationContext(), Main.class); startActivity(intent); diff --git a/OlympusServices/app/src/main/res/layout/activity_admin_services_list.xml b/OlympusServices/app/src/main/res/layout/activity_admin_services_list.xml new file mode 100644 index 0000000..2c19a56 --- /dev/null +++ b/OlympusServices/app/src/main/res/layout/activity_admin_services_list.xml @@ -0,0 +1,81 @@ + + + + + + + + + + + + + + + + +