diff --git a/app/src/main/java/org/fossasia/openevent/general/attendees/AttendeeFragment.kt b/app/src/main/java/org/fossasia/openevent/general/attendees/AttendeeFragment.kt index bc24b50814..4402a7c3c6 100644 --- a/app/src/main/java/org/fossasia/openevent/general/attendees/AttendeeFragment.kt +++ b/app/src/main/java/org/fossasia/openevent/general/attendees/AttendeeFragment.kt @@ -1,8 +1,6 @@ package org.fossasia.openevent.general.attendees -import android.app.Activity.RESULT_OK import android.app.AlertDialog -import android.content.Intent import android.content.pm.PackageManager import android.os.Bundle import android.text.Editable @@ -61,7 +59,6 @@ import kotlinx.android.synthetic.main.fragment_attendee.view.time import kotlinx.android.synthetic.main.fragment_attendee.view.view import kotlinx.android.synthetic.main.fragment_attendee.view.year import kotlinx.android.synthetic.main.fragment_attendee.view.yearText -import org.fossasia.openevent.general.AuthActivity import org.fossasia.openevent.general.R import org.fossasia.openevent.general.attendees.forms.CustomForm import org.fossasia.openevent.general.event.Event @@ -80,8 +77,6 @@ import org.koin.androidx.viewmodel.ext.android.viewModel import java.util.Currency private const val STRIPE_KEY = "com.stripe.android.API_KEY" -private const val PRIVACY_POLICY = "https://eventyay.com/privacy-policy/" -private const val TERMS_OF_SERVICE = "https://eventyay.com/terms/" class AttendeeFragment : Fragment() { @@ -103,7 +98,6 @@ class AttendeeFragment : Fragment() { private var singleTicket = false private var identifierList = ArrayList() private var editTextList = ArrayList() - private val AUTH_REQUEST_CODE = 1 private var amount: Float = 0.0f override fun onCreate(savedInstanceState: Bundle?) { @@ -127,14 +121,14 @@ class AttendeeFragment : Fragment() { rootView = inflater.inflate(R.layout.fragment_attendee, container, false) val activity = activity as? AppCompatActivity activity?.supportActionBar?.setDisplayHomeAsUpEnabled(true) - activity?.supportActionBar?.title = "Attendee Details" + activity?.supportActionBar?.title = getString(R.string.attendee_details) setHasOptionsMenu(true) val paragraph = SpannableStringBuilder() - val startText = "I accept the " - val termsText = "terms of service " - val middleText = "and have read the " - val privacyText = "privacy policy." + val startText = getString(R.string.start_text) + val termsText = getString(R.string.terms_text) + val middleText = getString(R.string.middle_text) + val privacyText = getString(R.string.privacy_text) paragraph.append(startText) paragraph.append(termsText) @@ -149,7 +143,7 @@ class AttendeeFragment : Fragment() { override fun onClick(widget: View) { context?.let { - Utils.openUrl(it, TERMS_OF_SERVICE) + Utils.openUrl(it, getString(R.string.terms_of_service)) } } } @@ -162,7 +156,7 @@ class AttendeeFragment : Fragment() { override fun onClick(widget: View) { context?.let { - Utils.openUrl(it, PRIVACY_POLICY) + Utils.openUrl(it, getString(R.string.privacy_policy)) } } } @@ -191,8 +185,8 @@ class AttendeeFragment : Fragment() { attendeeViewModel.updatePaymentSelectorVisibility(ticketIdAndQty) val paymentOptions = ArrayList() - paymentOptions.add("PayPal") - paymentOptions.add("Stripe") + paymentOptions.add(getString(R.string.paypal)) + paymentOptions.add(getString(R.string.stripe)) attendeeViewModel.paymentSelectorVisibility .nonNull() .observe(this, Observer { @@ -211,7 +205,7 @@ class AttendeeFragment : Fragment() { override fun onItemSelected(p0: AdapterView<*>?, p1: View?, p2: Int, p3: Long) { selectedPaymentOption = paymentOptions[p2] - if (selectedPaymentOption == "Stripe") + if (selectedPaymentOption == getString(R.string.stripe)) rootView.stripePayment.visibility = View.VISIBLE else rootView.stripePayment.visibility = View.GONE @@ -275,27 +269,6 @@ class AttendeeFragment : Fragment() { } } - attendeeViewModel.loadEvent(id) - - if (attendeeViewModel.isLoggedIn()) { - loadUser() - } else { - redirectToLogin() - Toast.makeText(context, "You need to log in first!", Toast.LENGTH_LONG).show() - } - - attendeeViewModel.ticketSoldOut - .nonNull() - .observe(this, Observer { - showTicketSoldOutDialog(it) - }) - return rootView - } - - private fun loadUser() { - attendeeViewModel.loadUser(attendeeViewModel.getId()) - attendeeViewModel.loadEvent(id) - attendeeViewModel.message .nonNull() .observe(this, Observer { @@ -357,6 +330,9 @@ class AttendeeFragment : Fragment() { openOrderCompletedFragment() }) + attendeeViewModel.loadUser() + attendeeViewModel.loadEvent(id) + attendeeViewModel.attendee .nonNull() .observe(this, Observer { user -> @@ -368,7 +344,7 @@ class AttendeeFragment : Fragment() { rootView.signOut.setOnClickListener { attendeeViewModel.logout() - redirectToLogin() + activity?.onBackPressed() } attendeeViewModel.getCustomFormsForAttendees(eventId.id) @@ -388,9 +364,6 @@ class AttendeeFragment : Fragment() { }) rootView.register.setOnClickListener { - if (selectedPaymentOption == "Stripe") - sendToken() - val attendees = ArrayList() if (singleTicket) { val pos = ticketIdAndQty?.map { it.second }?.indexOf(1) @@ -410,38 +383,32 @@ class AttendeeFragment : Fragment() { } val country = if (country.text.isEmpty()) country.text.toString() else null attendeeViewModel.createAttendees(attendees, country, selectedPaymentOption) + + attendeeViewModel.isAttendeeCreated.observe(this, Observer { isAttendeeCreated -> + if (isAttendeeCreated && selectedPaymentOption == getString(R.string.stripe)) { + sendToken() + } + }) } + + attendeeViewModel.ticketSoldOut + .nonNull() + .observe(this, Observer { + showTicketSoldOutDialog(it) + }) + + return rootView } private fun showTicketSoldOutDialog(show: Boolean) { if (show) { val builder = AlertDialog.Builder(context) - builder.setMessage(context?.resources?.getString(R.string.tickets_sold_out)) - .setPositiveButton(context?.resources?.getString(R.string.ok)) { dialog, _ -> dialog.cancel() } + builder.setMessage(getString(R.string.tickets_sold_out)) + .setPositiveButton(getString(R.string.ok)) { dialog, _ -> dialog.cancel() } builder.show() } } - private fun redirectToLogin() { - val intent = Intent(activity, AuthActivity::class.java) - val bundle = Bundle() - bundle.putLong(EVENT_ID, id) - if (ticketIdAndQty != null) - bundle.putSerializable(TICKET_ID_AND_QTY, ticketIdAndQty as ArrayList) - intent.putExtras(bundle) - startActivityForResult(intent, AUTH_REQUEST_CODE) - } - - override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { - if (requestCode == AUTH_REQUEST_CODE) { - if (resultCode == RESULT_OK) - loadUser() - else - Toast.makeText(context, "Sign in failed!", Toast.LENGTH_SHORT).show() - } - super.onActivityResult(requestCode, resultCode, data) - } - private fun sendToken() { val card = Card(cardNumber.text.toString(), expiryMonth, expiryYear.toInt(), cvc.text.toString()) card.addressCountry = country.text.toString() @@ -451,24 +418,20 @@ class AttendeeFragment : Fragment() { rootView.selectCard.text = "Pay by ${card.brand}" val validDetails: Boolean? = card.validateCard() - if (validDetails != null && !validDetails) { + if (validDetails != null && !validDetails) Toast.makeText(context, "Invalid card data", Toast.LENGTH_LONG).show() - } - - Stripe(requireContext()).createToken( - card, - API_KEY, - object : TokenCallback { - override fun onSuccess(token: Token) { - // Send this token to server - val charge = Charge(attendeeViewModel.getId().toInt(), token.id, null) - attendeeViewModel.completeOrder(charge) - } + else + Stripe(requireContext()).createToken( card, API_KEY, object : TokenCallback { + override fun onSuccess(token: Token) { + // Send this token to server + val charge = Charge(attendeeViewModel.getId().toInt(), token.id, null) + attendeeViewModel.completeOrder(charge) + } - override fun onError(error: Exception) { - Toast.makeText(context, error.localizedMessage.toString(), Toast.LENGTH_LONG).show() - } - }) + override fun onError(error: Exception) { + Toast.makeText(context, error.localizedMessage.toString(), Toast.LENGTH_LONG).show() + } + }) } private fun loadEventDetails(event: Event) { diff --git a/app/src/main/java/org/fossasia/openevent/general/attendees/AttendeeViewModel.kt b/app/src/main/java/org/fossasia/openevent/general/attendees/AttendeeViewModel.kt index 30c9039635..1ef4cb1d38 100644 --- a/app/src/main/java/org/fossasia/openevent/general/attendees/AttendeeViewModel.kt +++ b/app/src/main/java/org/fossasia/openevent/general/attendees/AttendeeViewModel.kt @@ -60,6 +60,8 @@ class AttendeeViewModel( val tickets: LiveData> = mutableTickets private val mutableForms = MutableLiveData>() val forms: LiveData> = mutableForms + private val mutableIsAttendeeCreated = MutableLiveData() + val isAttendeeCreated: LiveData = mutableIsAttendeeCreated val month = ArrayList() val year = ArrayList() @@ -76,8 +78,6 @@ class AttendeeViewModel( fun getId() = authHolder.getId() - fun isLoggedIn() = authHolder.isLoggedIn() - fun initializeSpinner() { // initialize months month.add("Month") @@ -163,6 +163,7 @@ class AttendeeViewModel( private fun createAttendee(attendee: Attendee, totalAttendee: Int) { if (attendee.email.isNullOrEmpty() || attendee.firstname.isNullOrEmpty() || attendee.lastname.isNullOrEmpty()) { mutableMessage.value = "Please fill in all the fields" + mutableIsAttendeeCreated.value = false return } @@ -179,6 +180,7 @@ class AttendeeViewModel( attendees.add(it) if (attendees.size == totalAttendee) { loadTicketsAndCreateOrder() + mutableIsAttendeeCreated.value = true mutableMessage.value = "Attendees created successfully!" } Timber.d("Success! %s", attendees.toList().toString()) @@ -365,7 +367,8 @@ class AttendeeViewModel( ) } - fun loadUser(id: Long) { + fun loadUser() { + val id = getId() if (id == -1L) { throw IllegalStateException("ID should never be -1") } diff --git a/app/src/main/java/org/fossasia/openevent/general/auth/LoginFragment.kt b/app/src/main/java/org/fossasia/openevent/general/auth/LoginFragment.kt index 2acae051b0..7d666f1ea7 100644 --- a/app/src/main/java/org/fossasia/openevent/general/auth/LoginFragment.kt +++ b/app/src/main/java/org/fossasia/openevent/general/auth/LoginFragment.kt @@ -24,9 +24,7 @@ import kotlinx.android.synthetic.main.fragment_login.view.sentEmailLayout import kotlinx.android.synthetic.main.fragment_login.view.tick import org.fossasia.openevent.general.MainActivity import org.fossasia.openevent.general.R -import org.fossasia.openevent.general.order.LAUNCH_TICKETS -import org.fossasia.openevent.general.ticket.EVENT_ID -import org.fossasia.openevent.general.ticket.TICKET_ID_AND_QTY +import org.fossasia.openevent.general.ticket.REDIRECTED_FROM_TICKETS import org.fossasia.openevent.general.utils.Utils import org.fossasia.openevent.general.utils.Utils.hideSoftKeyboard import org.fossasia.openevent.general.utils.extensions.nonNull @@ -37,17 +35,10 @@ class LoginFragment : Fragment() { private val loginViewModel by viewModel() private lateinit var rootView: View private var bundle: Bundle? = null - private var ticketIdAndQty: List>? = null - private var id: Long = -1 override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - val bundle = this.arguments - if (bundle != null && !bundle.getBoolean(LAUNCH_TICKETS)) { - id = bundle.getLong(EVENT_ID, -1) - ticketIdAndQty = bundle.getSerializable(TICKET_ID_AND_QTY) as List> - } - this.bundle = bundle + bundle = this.arguments } override fun onCreateView( @@ -136,7 +127,7 @@ class LoginFragment : Fragment() { private fun redirectToMain(bundle: Bundle?) { val intent = Intent(activity, MainActivity::class.java) if (bundle != null) { - if (id != -1L && ticketIdAndQty != null) { + if (bundle.getBoolean(REDIRECTED_FROM_TICKETS)) { activity?.setResult(RESULT_OK, intent) } else { intent.putExtras(bundle) diff --git a/app/src/main/java/org/fossasia/openevent/general/di/Modules.kt b/app/src/main/java/org/fossasia/openevent/general/di/Modules.kt index e471161d05..691a613ac0 100644 --- a/app/src/main/java/org/fossasia/openevent/general/di/Modules.kt +++ b/app/src/main/java/org/fossasia/openevent/general/di/Modules.kt @@ -129,7 +129,7 @@ val viewModelModule = module { viewModel { AttendeeViewModel(get(), get(), get(), get(), get(), get()) } viewModel { SearchLocationViewModel(get()) } viewModel { SearchTimeViewModel(get()) } - viewModel { TicketsViewModel(get(), get()) } + viewModel { TicketsViewModel(get(), get(), get()) } viewModel { AboutEventViewModel(get()) } viewModel { SocialLinksViewModel(get()) } viewModel { FavouriteEventsViewModel(get()) } diff --git a/app/src/main/java/org/fossasia/openevent/general/ticket/TicketsFragment.kt b/app/src/main/java/org/fossasia/openevent/general/ticket/TicketsFragment.kt index c29bf6f9c3..7ef71c286f 100644 --- a/app/src/main/java/org/fossasia/openevent/general/ticket/TicketsFragment.kt +++ b/app/src/main/java/org/fossasia/openevent/general/ticket/TicketsFragment.kt @@ -1,6 +1,8 @@ package org.fossasia.openevent.general.ticket +import android.app.Activity import android.app.AlertDialog +import android.content.Intent import android.os.Bundle import android.view.LayoutInflater import android.view.MenuItem @@ -22,6 +24,7 @@ import kotlinx.android.synthetic.main.fragment_tickets.view.ticketInfoTextView import kotlinx.android.synthetic.main.fragment_tickets.view.ticketTableHeader import kotlinx.android.synthetic.main.fragment_tickets.view.ticketsRecycler import kotlinx.android.synthetic.main.fragment_tickets.view.time +import org.fossasia.openevent.general.AuthActivity import org.fossasia.openevent.general.MainActivity import org.fossasia.openevent.general.R import org.fossasia.openevent.general.attendees.AttendeeFragment @@ -34,6 +37,7 @@ import org.koin.androidx.viewmodel.ext.android.viewModel const val EVENT_ID: String = "EVENT_ID" const val CURRENCY: String = "CURRENCY" const val TICKET_ID_AND_QTY: String = "TICKET_ID_AND_QTY" +const val REDIRECTED_FROM_TICKETS = "REDIRECTED_FROM_TICKETS" class TicketsFragment : Fragment() { private val ticketsRecyclerAdapter: TicketsRecyclerAdapter = TicketsRecyclerAdapter() @@ -43,6 +47,7 @@ class TicketsFragment : Fragment() { private lateinit var rootView: View private lateinit var linearLayoutManager: LinearLayoutManager private var ticketIdAndQty = ArrayList>() + private val AUTH_REQUEST_CODE = 1 override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) @@ -121,16 +126,7 @@ class TicketsFragment : Fragment() { rootView.register.setOnClickListener { if (!ticketsViewModel.totalTicketsEmpty(ticketIdAndQty)) { - val fragment = AttendeeFragment() - val bundle = Bundle() - bundle.putLong(EVENT_ID, id) - bundle.putSerializable(TICKET_ID_AND_QTY, ticketIdAndQty) - fragment.arguments = bundle - activity?.supportFragmentManager - ?.beginTransaction() - ?.replace(R.id.rootLayout, fragment) - ?.addToBackStack(null) - ?.commit() + checkForAuthentication() } else { handleNoTicketsSelected() } @@ -139,6 +135,45 @@ class TicketsFragment : Fragment() { return rootView } + private fun checkForAuthentication() { + if (ticketsViewModel.isLoggedIn()) + redirectToAttendee() + else { + Toast.makeText(context, "You need to log in first!", Toast.LENGTH_LONG).show() + redirectToLogin() + } + } + + private fun redirectToAttendee() { + val fragment = AttendeeFragment() + val bundle = Bundle() + bundle.putLong(EVENT_ID, id) + bundle.putSerializable(TICKET_ID_AND_QTY, ticketIdAndQty) + fragment.arguments = bundle + activity?.supportFragmentManager + ?.beginTransaction() + ?.replace(R.id.rootLayout, fragment) + ?.addToBackStack(null) + ?.commit() + } + + private fun redirectToLogin() { + val intent = Intent(activity, AuthActivity::class.java) + val bundle = Bundle() + bundle.putBoolean(REDIRECTED_FROM_TICKETS, true) + intent.putExtras(bundle) + startActivityForResult(intent, AUTH_REQUEST_CODE) + } + + override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { + if (requestCode == AUTH_REQUEST_CODE) { + if (resultCode == Activity.RESULT_OK) + redirectToAttendee() + else + Toast.makeText(context, "Sign in failed!", Toast.LENGTH_SHORT).show() + } + } + private fun handleTicketSelect(id: Int, quantity: Int) { val pos = ticketIdAndQty.map { it.first }.indexOf(id) if (pos == -1) { diff --git a/app/src/main/java/org/fossasia/openevent/general/ticket/TicketsViewModel.kt b/app/src/main/java/org/fossasia/openevent/general/ticket/TicketsViewModel.kt index cd2cb5ccf7..cab999a9ec 100644 --- a/app/src/main/java/org/fossasia/openevent/general/ticket/TicketsViewModel.kt +++ b/app/src/main/java/org/fossasia/openevent/general/ticket/TicketsViewModel.kt @@ -6,13 +6,15 @@ import androidx.lifecycle.ViewModel import io.reactivex.android.schedulers.AndroidSchedulers import io.reactivex.disposables.CompositeDisposable import io.reactivex.schedulers.Schedulers +import org.fossasia.openevent.general.auth.AuthHolder import org.fossasia.openevent.general.event.Event import org.fossasia.openevent.general.event.EventService import timber.log.Timber class TicketsViewModel( private val ticketService: TicketService, - private val eventService: EventService + private val eventService: EventService, + private val authHolder: AuthHolder ) : ViewModel() { private val compositeDisposable = CompositeDisposable() @@ -27,6 +29,8 @@ class TicketsViewModel( private val mutableTicketTableVisibility = MutableLiveData() val ticketTableVisibility: LiveData = mutableTicketTableVisibility + fun isLoggedIn() = authHolder.isLoggedIn() + fun loadTickets(id: Long) { if (id == -1L) { mutableError.value = "Error fetching tickets" diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index caaca3e5be..220ea0de5d 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -152,5 +152,15 @@ Nothing Planned ..yet? Find something to do!! + + Attendee Details + I accept the + terms of service + and have read the + privacy policy + https://eventyay.com/privacy-policy/ + https://eventyay.com/terms/ + Stripe + PayPal