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/Deliverable1.zip b/Deliverable1.zip new file mode 100644 index 0000000..fd97b0b Binary files /dev/null and b/Deliverable1.zip differ 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/.idea/caches/build_file_checksums.ser b/OlympusServices/.idea/caches/build_file_checksums.ser index 24e3c6b..1253c2c 100644 Binary files a/OlympusServices/.idea/caches/build_file_checksums.ser and b/OlympusServices/.idea/caches/build_file_checksums.ser differ diff --git a/OlympusServices/.idea/codeStyles/Project.xml b/OlympusServices/.idea/codeStyles/Project.xml index 30aa626..af2f2e3 100644 --- a/OlympusServices/.idea/codeStyles/Project.xml +++ b/OlympusServices/.idea/codeStyles/Project.xml @@ -1,5 +1,29 @@ + + + + + + + + + + + - + diff --git a/OlympusServices/.idea/vcs.xml b/OlympusServices/.idea/vcs.xml index 94a25f7..6c0b863 100644 --- a/OlympusServices/.idea/vcs.xml +++ b/OlympusServices/.idea/vcs.xml @@ -1,6 +1,6 @@ - + \ No newline at end of file diff --git a/OlympusServices/app/build.gradle b/OlympusServices/app/build.gradle index 4a8aefa..313fb68 100644 --- a/OlympusServices/app/build.gradle +++ b/OlympusServices/app/build.gradle @@ -16,18 +16,32 @@ android { proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } } + testOptions { + unitTests { + includeAndroidResources = true + } + } } 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' testImplementation 'junit:junit:4.12' + testImplementation 'androidx.test:core:1.0.0' + testImplementation 'org.mockito:mockito-core:1.10.19' + testImplementation 'org.robolectric:robolectric:4.0-alpha-3-SNAPSHOT' androidTestImplementation 'com.android.support.test:runner:1.0.2' + androidTestImplementation 'com.android.support.test:rules:1.0.2' androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2' + androidTestImplementation 'org.hamcrest:hamcrest-library:1.3' 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 { + maven { url "https://oss.sonatype.org/content/repositories/snapshots" } } diff --git a/OlympusServices/app/src/androidTest/java/com/uottawa/olympus/olympusservices/LogInTest.java b/OlympusServices/app/src/androidTest/java/com/uottawa/olympus/olympusservices/LogInTest.java new file mode 100644 index 0000000..0487845 --- /dev/null +++ b/OlympusServices/app/src/androidTest/java/com/uottawa/olympus/olympusservices/LogInTest.java @@ -0,0 +1,22 @@ +package com.uottawa.olympus.olympusservices; + +import android.support.test.rule.ActivityTestRule; +import android.support.test.runner.AndroidJUnit4; + + +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; + + +@RunWith(AndroidJUnit4.class) +public class LogInTest { + + @Rule + public ActivityTestRule mActivityTestRule = new ActivityTestRule(LogIn.class); + + @Test + public void checkSignIn() throws Exception{ + + } +} \ No newline at end of file diff --git a/OlympusServices/app/src/androidTest/java/com/uottawa/olympus/olympusservices/SignUpTest.java b/OlympusServices/app/src/androidTest/java/com/uottawa/olympus/olympusservices/SignUpTest.java new file mode 100644 index 0000000..b299158 --- /dev/null +++ b/OlympusServices/app/src/androidTest/java/com/uottawa/olympus/olympusservices/SignUpTest.java @@ -0,0 +1,90 @@ +package com.uottawa.olympus.olympusservices; + +import android.support.test.rule.ActivityTestRule; +import android.support.test.runner.AndroidJUnit4; +import android.widget.TextView; + +import org.junit.After; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; + +import static android.support.test.espresso.Espresso.onData; +import static android.support.test.espresso.Espresso.onView; +import static android.support.test.espresso.action.ViewActions.click; +import static android.support.test.espresso.action.ViewActions.closeSoftKeyboard; +import static android.support.test.espresso.action.ViewActions.typeText; +import static android.support.test.espresso.matcher.ViewMatchers.withId; +import static android.support.test.espresso.matcher.ViewMatchers.withSpinnerText; +import static java.util.regex.Pattern.matches; +import static org.hamcrest.CoreMatchers.containsString; +import static org.hamcrest.CoreMatchers.instanceOf; +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.core.AllOf.allOf; +import static org.junit.Assert.*; + +@RunWith(AndroidJUnit4.class) +public class SignUpTest { + + @Rule + public ActivityTestRule mActivityTestRule = new ActivityTestRule(SignUp.class); + private SignUp mActivity=null; + private TextView text; + + @Before + public void setUp() throws Exception { + mActivity = mActivityTestRule.getActivity(); + } + + @Test + public void checkSignUp1() throws Exception{ + onView(withId(R.id.UsernameInput)).perform(typeText("John123"), closeSoftKeyboard()); + onView(withId(R.id.PasswordInput)).perform(typeText("1234567890"), closeSoftKeyboard()); + onView(withId(R.id.FirstNameInput)).perform(typeText("John"), closeSoftKeyboard()); + onView(withId(R.id.LastNameInput)).perform(typeText("Doe"), closeSoftKeyboard()); + onView(withId(R.id.SignUp)).perform(click()); + } + + @Test + public void checkSignUp2() throws Exception{ + onView(withId(R.id.RoleInput)).perform(click()); + onData(allOf(is(instanceOf(String.class)), is("Service Provider"))).perform(click()); + onView(withId(R.id.UsernameInput)).perform(typeText("Service123"), closeSoftKeyboard()); + onView(withId(R.id.PasswordInput)).perform(typeText("1234567890"), closeSoftKeyboard()); + onView(withId(R.id.FirstNameInput)).perform(typeText("Jane"), closeSoftKeyboard()); + onView(withId(R.id.LastNameInput)).perform(typeText("Doe"), closeSoftKeyboard()); + onView(withId(R.id.SignUp)).perform(click()); + } + + @Test + public void checkSignUp3() throws Exception{ + onView(withId(R.id.UsernameInput)).perform(typeText(""), closeSoftKeyboard()); + onView(withId(R.id.PasswordInput)).perform(typeText(""), closeSoftKeyboard()); + onView(withId(R.id.FirstNameInput)).perform(typeText(""), closeSoftKeyboard()); + onView(withId(R.id.LastNameInput)).perform(typeText(""), closeSoftKeyboard()); + onView(withId(R.id.SignUp)).perform(click()); + } + + @Test + public void checkSignUp4() throws Exception{ + onView(withId(R.id.UsernameInput)).perform(typeText("$$$$$$"), closeSoftKeyboard()); + onView(withId(R.id.PasswordInput)).perform(typeText("$$$$$$"), closeSoftKeyboard()); + onView(withId(R.id.FirstNameInput)).perform(typeText("$$$$$$"), closeSoftKeyboard()); + onView(withId(R.id.LastNameInput)).perform(typeText("$$$$$$"), closeSoftKeyboard()); + onView(withId(R.id.SignUp)).perform(click()); + } + + public void checkSignUp5() throws Exception{ + onView(withId(R.id.UsernameInput)).perform(typeText("user"), closeSoftKeyboard()); + onView(withId(R.id.PasswordInput)).perform(typeText("pass"), closeSoftKeyboard()); + onView(withId(R.id.FirstNameInput)).perform(typeText("Honda"), closeSoftKeyboard()); + onView(withId(R.id.LastNameInput)).perform(typeText("Gokuchi"), closeSoftKeyboard()); + onView(withId(R.id.SignUp)).perform(click()); + } + + @After + public void tearDown() throws Exception { + mActivity=null; + } +} \ No newline at end of file diff --git a/OlympusServices/app/src/main/AndroidManifest.xml b/OlympusServices/app/src/main/AndroidManifest.xml index 167ae5c..fe68bbe 100644 --- a/OlympusServices/app/src/main/AndroidManifest.xml +++ b/OlympusServices/app/src/main/AndroidManifest.xml @@ -9,15 +9,14 @@ - + android:screenOrientation="portrait"> @@ -29,13 +28,48 @@ android:name="preloaded_fonts" android:resource="@array/preloaded_fonts" /> - - - - - + + + + + + + + + + + \ No newline at end of file diff --git a/OlympusServices/app/src/main/ic_launcher-web.png b/OlympusServices/app/src/main/ic_launcher-web.png new file mode 100644 index 0000000..547c096 Binary files /dev/null and b/OlympusServices/app/src/main/ic_launcher-web.png differ 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 new file mode 100644 index 0000000..8b658b4 --- /dev/null +++ b/OlympusServices/app/src/main/java/com/uottawa/olympus/olympusservices/Admin.java @@ -0,0 +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..ad967ff --- /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.service_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 new file mode 100644 index 0000000..f8e2861 --- /dev/null +++ b/OlympusServices/app/src/main/java/com/uottawa/olympus/olympusservices/AdminWelcome.java @@ -0,0 +1,76 @@ +package com.uottawa.olympus.olympusservices; + +import android.content.Intent; +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(), 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 new file mode 100644 index 0000000..536383e --- /dev/null +++ b/OlympusServices/app/src/main/java/com/uottawa/olympus/olympusservices/Appointment.java @@ -0,0 +1,12 @@ +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 new file mode 100644 index 0000000..7ef3b65 --- /dev/null +++ b/OlympusServices/app/src/main/java/com/uottawa/olympus/olympusservices/DBHelper.java @@ -0,0 +1,779 @@ +package com.uottawa.olympus.olympusservices; + +import android.content.Context; +import android.database.sqlite.SQLiteDatabase; +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; + +/** + * The class DBHelper allows the Android application to access and perform + * CRUD (Create, Read, Update, Delete) operations on the tables of the SQLite database. + * There is currently one table of all users' login information and names. + * Table of service providers and services to come soon. + * + * To use, create an object of this class with the current activity as context. + * + */ + +public class DBHelper extends SQLiteOpenHelper { + + //version of db used for update method + private static final int DB_VERSION = 4; + //name of db in app data + private static final String DB_NAME = "UsersDB.db"; + + //SQLiteDatabase for reading + private static SQLiteDatabase readDB; + + //SQLiteDatabase for writing + private static SQLiteDatabase writeDB; + + //name of table containing user login information and names + private static final String TABLE_LOGIN = "userInfo"; + //columns of TABLE_LOGIN + private static final String COLUMN_USERNAME = "username"; + private static final String COLUMN_PASSWORD = "password"; + 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 COLUMN_ADDRESS = "address"; + private static final String COLUMN_PHONE = "phone"; + private static final String COLUMN_COMPANY = "company"; + private static final String COLUMN_LICENSED = "licensed"; + private static final String COLUMN_DESCRIPTION = "description"; + private static final String COLUMN_SALT = "salt"; + + //name of table containing services and rates + private static final String TABLE_SERVICES = "services"; + //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 + * perform CRUD operations on the database via DBHelper's methods + * + * @param context current activity calling DBHelper + */ + public DBHelper(Context context){ + super(context, DB_NAME, null, DB_VERSION); + //since these methods take a while we will call them once and store the returned dbs + readDB = this.getReadableDatabase(); + writeDB = this.getWritableDatabase(); + //pre-add the admin user + addUser(new Admin()); + addUser(new ServiceProvider("testing", "testing", "testing", "testing", + "testing", "0000000000", "testing", true, "testing")); + } + + @Override + public void onCreate(SQLiteDatabase db){ + + //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," + + COLUMN_FIRSTNAME + " TEXT DEFAULT 'FirstName'," + + COLUMN_LASTNAME + " TEXT DEFAULT 'LastName'," + + COLUMN_USERTYPE + " TEXT NOT NULL, " + + COLUMN_ADDRESS + " TEXT, " + + COLUMN_PHONE + " TEXT, " + + COLUMN_COMPANY + " TEXT, " + + COLUMN_LICENSED + " TEXT, " + + COLUMN_DESCRIPTION + " TEXT, " + + COLUMN_SALT + " TEXT " + + ")"; + db.execSQL(CREATE_LOGIN_TABLE); + + //making the table containing services and their rates + String CREATE_SERVICES_TABLE = "CREATE TABLE "+ TABLE_SERVICES + "(" + + 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 + public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion){ + switch(oldVersion){ + case 1: //going from db version 1 to 2 + //change usertype of Users to Homeowner + ContentValues values = new ContentValues(); + values.put(COLUMN_USERTYPE, "HomeOwner"); + db.update(TABLE_LOGIN, values, COLUMN_USERTYPE + " = ?", new String[]{"User"}); + + //if services table is not created, create it + 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"); + case 3: + db.execSQL("ALTER TABLE " + TABLE_LOGIN + " ADD COLUMN " + COLUMN_DESCRIPTION + " TEXT"); + db.execSQL("ALTER TABLE " + TABLE_LOGIN + " ADD COLUMN " + COLUMN_SALT + " TEXT"); + + } + } + + @Override + public void onDowngrade(SQLiteDatabase db, int oldVersion, int newVersion) { + onUpgrade(db, oldVersion, newVersion); + } + + + //methods for table of users + + /** + * Adds a user to the database. Returns false if there is a user already + * existing in the database with the same username. Returns true if + * successful in adding user to database. + * + * @param userType user to be added + * @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}, + COLUMN_USERNAME + " = ?", + new String[]{userType.getUsername()}, + 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_USERNAME, userType.getUsername()); + values.put(COLUMN_PASSWORD, userType.getPassword()); + 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); + } + + String licensed = String.valueOf(serviceProvider.isLicensed()); + values.put(COLUMN_LICENSED, licensed); + + String description = serviceProvider.getDescription(); + if (description != null){ + values.put(COLUMN_DESCRIPTION, description); + } + + } + + 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. + * Returns null if no such user found. + * + * @param username username to look up + * @return object representing user found + */ + public UserType findUserByUsername(String username){ + if (username == null) return null; + UserType usertype = null; + Cursor cursor = readDB.rawQuery("SELECT * FROM " + TABLE_LOGIN + + " WHERE " + COLUMN_USERNAME + " = ?", + new String[]{username}); + + if (cursor.moveToFirst()){ + 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)); + String description = cursor.getString(9); + if (cursor.getString(4) + .equals("Admin")){ + usertype = new Admin(); + } else if (cursor.getString(4) + .equals("ServiceProvider")){ + ServiceProvider serviceProvider = new ServiceProvider(username, password, firstname, lastname, address, phonenumber, companyname, licensed, description); + getAllServicesProvidedByUser(serviceProvider); + getAvailabilities(serviceProvider); + usertype = serviceProvider; + } else { + usertype = new HomeOwner(username, password, firstname, lastname); + } + } + + cursor.close(); + return usertype; + } + + /** + * Updates user login information and name for user with requested username. + * Returns true if a user of said username was found and entry updated. + * Returns false if no user was found of said username. + * + * + * @param username username of entry to update + * @param password new password + * @param firstname new first name + * @param lastname new last name + * + * @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, null); + } + + + + public boolean updateUserInfo(String username, String password, String firstname, String lastname, + String address, String phonenumber, String companyname, Boolean licensed, + String description){ + ContentValues values = new ContentValues(); + 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, String.valueOf(licensed)); + if (description != null )values.put(COLUMN_DESCRIPTION, description); + + + return writeDB.update(TABLE_LOGIN, values, COLUMN_USERNAME+" = ?", + new String[]{username}) > 0; + } + + /** + * Looks in database for user with requested username, and deletes the corresponding + * entry. Returns true if a user was deleted, false otherwise. + * + * @param username username of entry to delete + * @return whether a user was deleted + */ + public boolean deleteUser(String username) { + if (username == null) return false; + + Cursor cursor = readDB.rawQuery("SELECT * FROM " + TABLE_LOGIN + + " WHERE " + COLUMN_USERNAME + " = ?", + new String[]{username}); + + if (!cursor.moveToFirst()) return false; + + boolean deleted; + if (cursor.getString(4).equals("ServiceProvider")) { + deleted = writeDB.delete(TABLE_LOGIN, COLUMN_USERNAME+" = ?", + new String[]{username}) > 0; + + if (deleted) { + writeDB.delete(TABLE_SERVICEPROVIDERS, COLUMN_SERVICEPROVIDERNAME + " = ?", + new String[]{username}); + writeDB.delete(TABLE_AVAILABILITY, COLUMN_AVAILABILITYNAME + " = ?", + new String[]{username}); + } + cursor.close(); + return deleted; + } else { + cursor.close(); + return writeDB.delete(TABLE_LOGIN, COLUMN_USERNAME+" = ?", + new String[]{username}) > 0; + } + } + + /** + * Returns a list of String arrays containing the username, first name, + * last name, and user type of every user in TABLE_LOGIN. + * + * @return list of arrays of [username, first name, last name, user type] + */ + public List getAllUsers(){ + return getAll("SELECT " + COLUMN_USERNAME + ", " + + COLUMN_FIRSTNAME + ", " + + COLUMN_LASTNAME + ", " + + COLUMN_USERTYPE + + " FROM "+TABLE_LOGIN); + } + + //methods for table of services + + /** + * Adds a service to the database. Returns false if service already + * exists in the database. + * Returns true if successful in adding service to database. + * + * @param service service to be added + * @return whether adding service was successful + */ + public boolean addService(Service service){ + 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().toLowerCase().trim()}, + 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_SERVICE, service.getName().toLowerCase().trim()); + values.put(COLUMN_RATE, service.getRate()); + writeDB.insert(TABLE_SERVICES, null, values); + return true; + } + + /** + * Looks in database for service with specified, and returns an + * object of Service if found. + * Returns null if no such service found. + * + * @param serviceName service to look up + * @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}); + + if (cursor.moveToFirst()){ + String servName = cursor.getString(0); + double rate = cursor.getDouble(1); + service = new Service(servName, rate); + } else { + service = null; + } + cursor.close(); + return service; + } + + /** + * Updates service rate using a Service object. + * Returns true if a service was found and entry updated. + * Returns false if no service was found. + * + * + * @param service service object containing updated values + * + * @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().toLowerCase().trim()}) > 0; + } + + /** + * Updates service rate using input of service name and rate. + * Returns true if a service was found and entry updated. + * Returns false if no service was found. + * + * + * @param name name of service + * @param rate rate of service + * + * @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); + + return writeDB.update(TABLE_SERVICES, values, COLUMN_SERVICE+" = ?", + new String[]{name}) > 0; + } + + /** + * Looks in database for a service, and deletes the corresponding + * 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) { + if (service == null) return false; + + boolean deleted; + String nullify = null; + service = service.toLowerCase().trim(); + + deleted = writeDB.delete(TABLE_SERVICES, COLUMN_SERVICE+" = ?", + new String[]{service}) > 0; + + if (deleted) { + writeDB.delete(TABLE_SERVICEPROVIDERS, COLUMN_SERVICEPROVIDERSERVICE + " = ?", + new String[]{service}); + } + return deleted; + } + + + /** + * Returns a list of String arrays containing the service categories, + * names and hourly rates. + * + * @return list of arrays of [service, rate] + */ + public List getAllServices(){ + 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/service combination 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); + } + } else { + return new int[7][4]; + } + 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; + } + + /** + * Prints all entries of table. One row is printed per line. Columns are + * separated by spaces. + * + * @param tableName name of table to print + */ + void printTable(String tableName){ + Cursor cursor = readDB.rawQuery("SELECT * FROM "+tableName, null); + cursor.moveToFirst(); + for (int i = 0; i getAll(String rawQuery){ + List list = new LinkedList<>(); + String[] infoArray; + Cursor cursor = readDB.rawQuery(rawQuery,null); + + if (cursor.moveToFirst()) { + for (int i = 0; i < cursor.getCount(); i++) { + infoArray = new String[cursor.getColumnNames().length]; + for (int j = 0; j < cursor.getColumnNames().length; j++) { + infoArray[j] = cursor.getString(j); + } + list.add(infoArray); + cursor.moveToNext(); + } + } + cursor.close(); + return list; + } + +} + 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..57ebfe9 --- /dev/null +++ b/OlympusServices/app/src/main/java/com/uottawa/olympus/olympusservices/EditProfile.java @@ -0,0 +1,108 @@ +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; + + /** + * Prepoplates the fields with user information when the activity is created + * @param savedInstanceState + */ + @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); + TextView description = findViewById(R.id.DescriptionInput); + 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()); + description.setText(user.getDescription()); + 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(); + } + + /** + * Saves updated user information to the database + * @param view + */ + 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); + TextView description = findViewById(R.id.DescriptionInput); + CheckBox licensed = findViewById(R.id.LicensedInput); + + //Checks for the fields + 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_ ]*$") + && description.getText().toString().matches("^[a-zA-Z0-9_ ]*$") + && phonenumber.getText().toString().matches("^(\\+\\d{1,2}\\s)?\\(?\\d{3}\\)?[\\s.-]?\\d{3}[\\s.-]?\\d{4}$") + && address.getText().toString().replaceAll("\\s+","").length()>0) { + + if(dbHelper.updateUserInfo(username, password.getText().toString(), firstname.getText().toString(), lastname.getText().toString(), + address.getText().toString(), phonenumber.getText().toString(), companyname.getText().toString(), licensed.isChecked(), description.getText().toString())){ + //add comment method here + 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 new file mode 100644 index 0000000..722a410 --- /dev/null +++ b/OlympusServices/app/src/main/java/com/uottawa/olympus/olympusservices/EditServiceDialogFragment.java @@ -0,0 +1,90 @@ +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 EditServiceDialogFragment 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 onDialogEdit(DialogFragment dialog); + public void onDialogDelete(DialogFragment dialog); + } + EditServiceDialogFragment.NoticeDialogListener mListener; + + // Override the Fragment.onAttach() method to instantiate the NoticeDialogListener + @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 = (EditServiceDialogFragment.NoticeDialogListener) context; + } catch (ClassCastException e) { + // The activity doesn't implement the interface, throw exception + throw new ClassCastException(this.toString() + + " 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()); + // 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_edit, null)) + // Add action buttons + .setPositiveButton(R.string.update, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int id) { + Bundle args = new Bundle(); + 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(); + 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 new file mode 100644 index 0000000..690ff19 --- /dev/null +++ b/OlympusServices/app/src/main/java/com/uottawa/olympus/olympusservices/HomeOwner.java @@ -0,0 +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 02ed1f3..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 @@ -2,12 +2,98 @@ package com.uottawa.olympus.olympusservices; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; +import android.content.Intent; +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(); + DBHelper dbHelper = new DBHelper(this); + if(username.matches("[a-zA-Z0-9]*")&&password.matches("[a-zA-Z0-9]*") + && password.length()>0 && username.length()>0) { + if (dbHelper.findUserByUsername(username) != null) { + UserType user = dbHelper.findUserByUsername(username); + if (user.getUsername().equals(username) && + user.getPassword().equals(password)) { + if(user.getRole()=="Admin"){ + Intent intent = new Intent(getApplicationContext(),AdminWelcome.class); + 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); + startActivity(intent); + finish(); + } + + + } else { + Toast.makeText(this, "Wrong Password", Toast.LENGTH_LONG).show(); + } + } else { + Toast.makeText(this, "Account does not exist", Toast.LENGTH_LONG).show(); + } + } + else if(username.length()==0 || password.length()==0){ + Toast.makeText(this, "Fields cannot be empty", 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); + startActivity(intent); + finish(); + } + + + + } 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 f5722d9..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,13 +5,53 @@ 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); setContentView(R.layout.activity_main); + UserType admin = new Admin(); + DBHelper dbHelper = new DBHelper(this); + dbHelper.addUser(admin); + } -} + /** + * 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); + finish(); + + } + + /** + * 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); + finish(); + } + +} \ No newline at end of file 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 new file mode 100644 index 0000000..09cc543 --- /dev/null +++ b/OlympusServices/app/src/main/java/com/uottawa/olympus/olympusservices/NewServiceDialogFragment.java @@ -0,0 +1,106 @@ +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.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); + } + NoticeDialogListener mListener; + + // Override the Fragment.onAttach() method to instantiate the NoticeDialogListener + @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 = (NoticeDialogListener) context; + } catch (ClassCastException e) { + // The activity doesn't implement the interface, throw exception + throw new ClassCastException(this.toString() + + " 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(view) + // Add action buttons + .setPositiveButton(R.string.add, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int id) { + 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() { + public void onClick(DialogInterface dialog, int id) { + NewServiceDialogFragment.this.getDialog().cancel(); + } + }); + return builder.create(); + } + +} 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 new file mode 100644 index 0000000..1c311ef --- /dev/null +++ b/OlympusServices/app/src/main/java/com/uottawa/olympus/olympusservices/Service.java @@ -0,0 +1,91 @@ +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())){ + return false; + } + } + serviceProviders.add(user); + return true; + } + + public List getServiceProviders(){ + return serviceProviders; + } +} 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 new file mode 100644 index 0000000..16f190c --- /dev/null +++ b/OlympusServices/app/src/main/java/com/uottawa/olympus/olympusservices/ServiceProvider.java @@ -0,0 +1,165 @@ +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; + + private String address; + private String phonenumber; + private String companyname; + private boolean licensed; + private String description; + + + + + /** + * 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; + this.description = ""; + } + + ServiceProvider(String username, String password, String firstname, String lastname, String address, + String phonenumber, String companyname, boolean licensed, String description){ + 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; + this.description = description; + } + + /** + * 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())){ + return false; + } + } + services.add(service); + 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; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + +} \ 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..2898772 --- /dev/null +++ b/OlympusServices/app/src/main/java/com/uottawa/olympus/olympusservices/ServiceProviderAvailabilities.java @@ -0,0 +1,241 @@ +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 android.widget.Toast; + +import java.util.Calendar; + +/** + * + * This class is the java class for the Service Provider's Availabilities menu. This class generates the menu from + * the saved Availabilities that the user has set previously or on default set no Availabilities. + * The menu gives the option to change availabilities for each day of the week or remove his availability on that + * day. User will receive a toast if they set impossible availabilities or they will receive a toast saying + * that their availabilities have been saved. + * + */ + +public class ServiceProviderAvailabilities extends AppCompatActivity { + private String username; + + /** + * This class generates the availabilities from the serviceProvider class fields + * on creation of this menu so the user can edit and change it on the menu. + * + * @param savedInstanceState + */ + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_service_provider_availabilities); + Bundle bundle = getIntent().getExtras(); + username = bundle.getString("username"); + DBHelper dbHelper = new DBHelper(this); + ServiceProvider user = (ServiceProvider) dbHelper.findUserByUsername(username); + int[][] days = user.getAvailabilities(); + String startTime; + String endTime; + int i = 0; + for(int[] times: days){ + startTime = formatTime(times[0],times[1]); + endTime = formatTime(times[2],times[3]); + if(times[0]==0&×[1]==0&×[2]==0&×[3]==0){ + startTime = "START"; + endTime = "END"; + } + if(i==0){ + ((Button)findViewById(R.id.MondayStart)).setText(startTime); + ((Button)findViewById(R.id.MondayEnd)).setText(endTime); + }else if(i==1){ + ((Button)findViewById(R.id.TuesdayStart)).setText(startTime); + ((Button)findViewById(R.id.TuesdayEnd)).setText(endTime); + }else if(i==2){ + ((Button)findViewById(R.id.WednesdayStart)).setText(startTime); + ((Button)findViewById(R.id.WednesdayEnd)).setText(endTime); + }else if(i==3){ + ((Button)findViewById(R.id.ThursdayStart)).setText(startTime); + ((Button)findViewById(R.id.ThursdayEnd)).setText(endTime); + }else if(i==4){ + ((Button)findViewById(R.id.FridayStart)).setText(startTime); + ((Button)findViewById(R.id.FridayEnd)).setText(endTime); + }else if(i==5){ + ((Button)findViewById(R.id.SaturdayStart)).setText(startTime); + ((Button)findViewById(R.id.SaturdayEnd)).setText(endTime); + }else if(i==6){ + ((Button)findViewById(R.id.SundayStart)).setText(startTime); + ((Button)findViewById(R.id.SundayEnd)).setText(endTime); + } + i++; + } + } + + + 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) { + String time = ""; + + button.setText(formatTime(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 + Button start; + Button end; + if(view.getId()==R.id.DeleteMon){ + start = findViewById(R.id.MondayStart); + end = findViewById(R.id.MondayEnd); + start.setText("START"); + end.setText("END"); + }else if(view.getId()==R.id.DeleteTuesday){ + start = findViewById(R.id.TuesdayStart); + end = findViewById(R.id.TuesdayEnd); + start.setText("START"); + end.setText("END"); + }else if(view.getId()==R.id.DeleteWednesday){ + start = findViewById(R.id.WednesdayStart); + end = findViewById(R.id.WednesdayEnd); + start.setText("START"); + end.setText("END"); + }else if(view.getId()==R.id.DeleteThursday){ + start = findViewById(R.id.ThursdayStart); + end = findViewById(R.id.ThursdayEnd); + start.setText("START"); + end.setText("END"); + }else if(view.getId()==R.id.DeleteFriday){ + start = findViewById(R.id.FridayStart); + end = findViewById(R.id.FridayEnd); + start.setText("START"); + end.setText("END"); + }else if(view.getId()==R.id.DeleteSaturday){ + start = findViewById(R.id.SaturdayStart); + end = findViewById(R.id.SaturdayEnd); + start.setText("START"); + end.setText("END"); + }else{ + start = findViewById(R.id.SundayStart); + end = findViewById(R.id.SundayEnd); + start.setText("START"); + end.setText("END"); + } + } + + /** + * Parses the views of the UI to generate 2D int array and updates the database and user with + * the new 2D on click of the setTime button. + * + * @param view + */ + public void onSetTimes(View view){ + int[] mondayTime = parseTime( ((Button)findViewById(R.id.MondayStart)).getText().toString(),((Button)findViewById(R.id.MondayEnd)).getText().toString() ); + int[] tuesdayTime = parseTime( ((Button)findViewById(R.id.TuesdayStart)).getText().toString(),((Button)findViewById(R.id.TuesdayEnd)).getText().toString() ); + int[] wednesdayTime = parseTime( ((Button)findViewById(R.id.WednesdayStart)).getText().toString(),((Button)findViewById(R.id.WednesdayEnd)).getText().toString() ); + int[] thursdayTime = parseTime( ((Button)findViewById(R.id.ThursdayStart)).getText().toString(),((Button)findViewById(R.id.ThursdayEnd)).getText().toString() ); + int[] fridayTime = parseTime( ((Button)findViewById(R.id.FridayStart)).getText().toString(), ((Button)findViewById(R.id.FridayEnd)).getText().toString() ); + int[] saturdayTime = parseTime( ((Button)findViewById(R.id.SaturdayStart)).getText().toString(),((Button)findViewById(R.id.SaturdayEnd)).getText().toString() ); + int[] sundayTime = parseTime( ((Button)findViewById(R.id.SundayStart)).getText().toString(),((Button)findViewById(R.id.SundayEnd)).getText().toString() ); + int[][] availabilities = {mondayTime,tuesdayTime,wednesdayTime,thursdayTime,fridayTime,saturdayTime,sundayTime}; + boolean validation = true; + for(int[] times: availabilities){ + if(!validateTime(times)){ + validation = false; + } + } + if(validation){ + DBHelper dbHelper = new DBHelper(this); + ServiceProvider user = (ServiceProvider) dbHelper.findUserByUsername(username); + user.setAvailabilities(availabilities); + dbHelper.updateAvailability(user); + Toast.makeText(this, "New Availabilities have been set.", Toast.LENGTH_LONG).show(); + } else{ + Toast.makeText(this, "All end times must be later then start times.", Toast.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(); + } + + private String formatTime(int hours, int minutes){ + String time = ""; + if(hours<10){ + time = time+"0"+hours+":"; + }else{ + time = time+hours+":"; + } + if (minutes<10){ + time = time+"0"+minutes; + } + else { + time = time+minutes; + } + return time; + } + + private int[] parseTime(String startTime, String endTime){ + int[] times = new int[4]; + if(startTime.equals("START")){ + times[0]=0; + times[1]=0; + }else{ + times[0] = Integer.parseInt(startTime.substring(0,2)); + times[1] = Integer.parseInt(startTime.substring(3)); + } + if(endTime.equals("END")){ + times[2]=0; + times[3]=0; + }else{ + times[2] = Integer.parseInt(endTime.substring(0,2)); + times[3] = Integer.parseInt(endTime.substring(3)); + } + return times; + } + + private boolean validateTime(int[] time){ + if(time[0]==0&&time[1]==0&&time[2]==0&&time[3]==0){ + return true; + } + if(time[2]>time[0]){ + return true; + }else{ + if(time[2]==time[0]&&time[3]>time[1]){ + return true; + }else{ + return false; + } + } + } +} 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..21b47d3 --- /dev/null +++ b/OlympusServices/app/src/main/java/com/uottawa/olympus/olympusservices/ServiceProviderServicesList.java @@ -0,0 +1,241 @@ +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.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 fills out 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() { + + @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.service_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; + } + + //nested class for the items in the recycler view + 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); + } + + /** + * Onclick function for the items in the recycler view + * @param view + */ + @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/SignUp.java b/OlympusServices/app/src/main/java/com/uottawa/olympus/olympusservices/SignUp.java index 770795e..299c5ee 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 @@ -4,22 +4,123 @@ import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import com.jaredrummler.materialspinner.MaterialSpinner; import android.support.design.widget.Snackbar; +import android.content.Intent; +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); setContentView(R.layout.activity_sign_up); MaterialSpinner spinner = findViewById(R.id.RoleInput); - spinner.setItems("Ice Cream Sandwich", "Jelly Bean", "KitKat", "Lollipop", "Marshmallow"); + spinner.setItems("Home Owner", "Service Provider"); 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(); } }); - } - public static void main(String[] args){ } + + /** + * 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(); + String password = ((EditText) findViewById(R.id.PasswordInput)).getText().toString(); + String firstname = ((EditText) findViewById(R.id.FirstNameInput)).getText().toString(); + String lastname = ((EditText) findViewById(R.id.LastNameInput)).getText().toString(); + MaterialSpinner spinner = findViewById(R.id.RoleInput); + + 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": + 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; + + } + + } + 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 ){ + 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); + startActivity(intent); + finish(); + } + + + } 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..7eb5913 --- /dev/null +++ b/OlympusServices/app/src/main/java/com/uottawa/olympus/olympusservices/SignUpPart2.java @@ -0,0 +1,58 @@ +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(); + String description = ((EditText) findViewById(R.id.DescriptionInput)).getText().toString(); + + 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}$") + && description.matches("^[a-zA-Z0-9_ ]*$") + && companyname.replaceAll("\\s+","").length()>0 + && address.replaceAll("\\s+","").length()>0) { + + ServiceProvider serviceProvider = new ServiceProvider(username, password, firstname, lastname, + address, phonenumber, companyname, licensed, description); + 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 new file mode 100644 index 0000000..98f4766 --- /dev/null +++ b/OlympusServices/app/src/main/java/com/uottawa/olympus/olympusservices/UserType.java @@ -0,0 +1,139 @@ +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; + this.firstname = firstname; + 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 + //so cannot be initialized in this class + this.username = username; + + } + + /** + * 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 + //so cannot be initialized in this class + 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 + //so cannot be initialized in this class + this.firstname = firstname; + } + + public void setLastname(String lastname) { + //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 + //so cannot be initialized in this class + 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)){ + return true; + } + return false; + } +} 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 new file mode 100644 index 0000000..f407880 --- /dev/null +++ b/OlympusServices/app/src/main/java/com/uottawa/olympus/olympusservices/UsersList.java @@ -0,0 +1,129 @@ +package com.uottawa.olympus.olympusservices; + +import android.content.Context; +import android.support.annotation.NonNull; +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.GridView; +import android.widget.TextView; + +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 + */ + + //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 DBHelper dbHelper; + + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_users_list); + + dbHelper = new DBHelper(this); + List users = dbHelper.getAllUsers(); + String[] usernames = new String[(users.size())]; + Iterator iter = users.iterator(); + for (int i=0; i { + + private String[] users; + 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(String[] users, Context context) { + this.users = users; + } + + // Create new views (invoked by the layout manager) + @NonNull + @Override + public UsersHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + View v = LayoutInflater.from(parent.getContext()) + .inflate(R.layout.user_list_item, parent, false); + return new UsersHolder(v); + } + + // Replace the contents of a view (invoked by the layout manager) + @Override + public void onBindViewHolder(UsersHolder holder, int position) { + UserType user = dbHelper.findUserByUsername(users[position]); + holder.name.setText(user.getUsername()); + holder.rate.setText(user.getRole()); + + + + } + + // Return the size of your dataset (invoked by the layout manager) + @Override + public int getItemCount() { + return users.length; + } + + class UsersHolder extends RecyclerView.ViewHolder{ + + TextView name; + TextView rate; + + public UsersHolder(View row){ + super(row); + name = row.findViewById(R.id.Name); + rate = row.findViewById(R.id.Role); + } + + } + + + } + + +} 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 8cf6848..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 @@ -2,12 +2,63 @@ 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 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); setContentView(R.layout.activity_welcome); + Bundle bundle = getIntent().getExtras(); + String username = bundle.getString("username"); + DBHelper dbHelper = new DBHelper(this); + UserType user; + user = dbHelper.findUserByUsername(username); + TextView role = findViewById(R.id.Role); + TextView name = findViewById(R.id.name); + role.setText(user.getRole()); + name.setText(user.getFirstname()); + + } + + /** + * 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(); + } + + } diff --git a/OlympusServices/app/src/main/res/drawable/logo.JPG b/OlympusServices/app/src/main/res/drawable/logo.JPG new file mode 100644 index 0000000..65459c1 Binary files /dev/null and b/OlympusServices/app/src/main/res/drawable/logo.JPG differ 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 @@ + + + + + + + + + + + + + + + + +