Skip to content

fix: Retain ticket locally when logged in #1761

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
May 18, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ import org.fossasia.openevent.general.ticket.TicketIdConverter

@Database(entities = [Event::class, User::class, SocialLink::class, Ticket::class, Attendee::class,
EventTopic::class, Order::class, CustomForm::class, Speaker::class, SpeakerWithEvent::class, Sponsor::class,
SponsorWithEvent::class, Session::class], version = 5)
SponsorWithEvent::class, Session::class], version = 6)
@TypeConverters(EventIdConverter::class, EventTopicConverter::class, EventTypeConverter::class,
EventSubTopicConverter::class, TicketIdConverter::class, MicroLocationConverter::class,
AttendeeIdConverter::class, ListAttendeeIdConverter::class, SessionTypeConverter::class)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ data class Attendee(
@ColumnInfo(index = true)
@Relationship("event")
var event: EventId? = null,
@ColumnInfo(index = true)
@Relationship("ticket")
var ticket: TicketId? = null
)
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,14 @@ interface AttendeeDao {
fun insertCustomForms(customForms: List<CustomForm>)

@Query("DELETE FROM Attendee")
fun deleteAll()
fun deleteAllAttendees()

@Query("SELECT * from Attendee WHERE id in (:ids)")
fun getAttendeesWithIds(ids: List<Long>): Single<List<Attendee>>

@Query("SELECT * from CustomForm WHERE event = :eventId")
fun getCustomFormsForId(eventId: Long): Single<List<CustomForm>>

@Query("SELECT * FROM Attendee")
fun getAllAttendees(): Single<List<Attendee>>
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package org.fossasia.openevent.general.attendees
import androidx.room.TypeConverter
import com.fasterxml.jackson.core.type.TypeReference
import com.fasterxml.jackson.databind.ObjectMapper
import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper

class ListAttendeeIdConverter {

Expand All @@ -14,7 +15,7 @@ class ListAttendeeIdConverter {

@TypeConverter
fun toListAttendeeId(attendeeList: String): List<AttendeeId> {
val objectMapper = ObjectMapper()
val objectMapper = jacksonObjectMapper()
val mapType = object : TypeReference<List<AttendeeId>>() {}
return objectMapper.readValue(attendeeList, mapType)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,22 @@ package org.fossasia.openevent.general.auth

import io.reactivex.Completable
import io.reactivex.Single
import org.fossasia.openevent.general.attendees.AttendeeDao
import org.fossasia.openevent.general.auth.change.ChangeRequestToken
import org.fossasia.openevent.general.auth.change.ChangeRequestTokenResponse
import org.fossasia.openevent.general.auth.change.Password
import org.fossasia.openevent.general.auth.forgot.Email
import org.fossasia.openevent.general.auth.forgot.RequestToken
import org.fossasia.openevent.general.auth.forgot.RequestTokenResponse
import org.fossasia.openevent.general.order.OrderDao
import timber.log.Timber

class AuthService(
private val authApi: AuthApi,
private val authHolder: AuthHolder,
private val userDao: UserDao
private val userDao: UserDao,
private val orderDao: OrderDao,
private val attendeeDao: AttendeeDao
) {
fun login(username: String, password: String): Single<LoginResponse> {
if (username.isEmpty() || password.isEmpty())
Expand Down Expand Up @@ -55,6 +59,8 @@ class AuthService(
return Completable.fromAction {
authHolder.token = null
userDao.deleteUser(authHolder.getId())
orderDao.deleteAllOrders()
attendeeDao.deleteAllAttendees()
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,7 @@ val apiModule = module {
}

factory { AuthHolder(get()) }
factory { AuthService(get(), get(), get()) }
factory { AuthService(get(), get(), get(), get(), get()) }

factory { EventService(get(), get(), get(), get(), get(), get(), get(), get()) }
factory { SpeakerService(get(), get(), get()) }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@ interface EventDao {
@Query("SELECT * from Event WHERE id = :id")
fun getEvent(id: Long): Flowable<Event>

@Query("SELECT * FROM event WHERE id = :eventId")
fun getEventById(eventId: Long): Single<Event>

@Query("SELECT * from Event WHERE id in (:ids)")
fun getEventWithIds(ids: List<Long>): Single<List<Event>>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -109,13 +109,25 @@ class EventService(
return eventDao.getEvent(id)
}

fun getEventFromApi(id: Long): Single<Event> {
return eventApi.getEventFromApi(id)
fun getEventById(eventId: Long): Single<Event> {
return eventDao.getEventById(eventId)
.onErrorResumeNext {
eventApi.getEventFromApi(eventId).map {
eventDao.insertEvent(it)
it
}
}
}

fun getEventsUnderUser(eventIds: List<Long>): Single<List<Event>> {
val query = buildQuery(eventIds)
return eventApi.eventsUnderUser(query)
.map {
eventDao.insertEvents(it)
it
}.onErrorResumeNext {
eventDao.getEventWithIds(eventIds).map { it }
}
}

fun setFavorite(eventId: Long, favorite: Boolean): Completable {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package org.fossasia.openevent.general.order

import androidx.room.ColumnInfo
import androidx.room.Entity
import androidx.room.ForeignKey
import androidx.room.PrimaryKey
import com.fasterxml.jackson.databind.PropertyNamingStrategy
import com.fasterxml.jackson.databind.annotation.JsonNaming
Expand All @@ -11,18 +10,12 @@ import com.github.jasminb.jsonapi.annotations.Id
import com.github.jasminb.jsonapi.annotations.Relationship
import com.github.jasminb.jsonapi.annotations.Type
import io.reactivex.annotations.NonNull
import org.fossasia.openevent.general.attendees.Attendee
import org.fossasia.openevent.general.attendees.AttendeeId
import org.fossasia.openevent.general.event.Event
import org.fossasia.openevent.general.event.EventId

@Type("order")
@JsonNaming(PropertyNamingStrategy.KebabCaseStrategy::class)
@Entity(foreignKeys = [
(ForeignKey(entity = Event::class, parentColumns = ["id"],
childColumns = ["event"], onDelete = ForeignKey.CASCADE)),
(ForeignKey(entity = Attendee::class, parentColumns = ["id"],
childColumns = ["attendees"], onDelete = ForeignKey.CASCADE))])
@Entity
data class Order(
@Id(IntegerIdHandler::class)
@PrimaryKey
Expand Down
11 changes: 11 additions & 0 deletions app/src/main/java/org/fossasia/openevent/general/order/OrderDao.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ package org.fossasia.openevent.general.order
import androidx.room.Dao
import androidx.room.Insert
import androidx.room.OnConflictStrategy
import androidx.room.Query
import io.reactivex.Single

@Dao
interface OrderDao {
Expand All @@ -11,4 +13,13 @@ interface OrderDao {

@Insert(onConflict = OnConflictStrategy.REPLACE)
fun insertOrder(order: Order)

@Query("SELECT * FROM `order`")
fun getAllOrders(): Single<List<Order>>

@Query("DELETE FROM `order`")
fun deleteAllOrders()

@Query("SELECT * FROM `order` WHERE id = :orderId")
fun getOrderById(orderId: Long): Single<Order>
}
Original file line number Diff line number Diff line change
Expand Up @@ -48,20 +48,18 @@ class OrderDetailsFragment : Fragment() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)

ordersRecyclerAdapter.setOrderIdentifier(safeArgs.orders)
ordersRecyclerAdapter.setOrderIdentifier(safeArgs.orderIdentifier)

orderDetailsViewModel.event
.nonNull()
.observe(this, Observer {
ordersRecyclerAdapter.setEvent(it)
ordersRecyclerAdapter.notifyDataSetChanged()
})

orderDetailsViewModel.attendees
.nonNull()
.observe(this, Observer {
ordersRecyclerAdapter.addAll(it)
ordersRecyclerAdapter.notifyDataSetChanged()
Timber.d("Fetched attendees of size %s", ordersRecyclerAdapter.itemCount)
})
}
Expand Down Expand Up @@ -127,7 +125,7 @@ class OrderDetailsFragment : Fragment() {
})

orderDetailsViewModel.loadEvent(safeArgs.eventId)
orderDetailsViewModel.loadAttendeeDetails(safeArgs.orders)
orderDetailsViewModel.loadAttendeeDetails(safeArgs.orderId)

return rootView
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,12 @@ class OrderDetailsRecyclerAdapter : RecyclerView.Adapter<OrderDetailsViewHolder>
if (attendees.isNotEmpty())
this.attendees.clear()
this.attendees.addAll(attendeeList)
notifyDataSetChanged()
}

fun setEvent(event: Event?) {
this.event = event
notifyDataSetChanged()
}

fun setSeeEventListener(listener: EventDetailsListener) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ class OrderDetailsViewModel(
throw IllegalStateException("ID should never be -1")
}

compositeDisposable += eventService.getEventFromApi(id)
compositeDisposable += eventService.getEventById(id)
.withDefaultSchedulers()
.subscribe({
mutableEvent.value = it
Expand All @@ -46,21 +46,34 @@ class OrderDetailsViewModel(
})
}

fun loadAttendeeDetails(id: String) {
if (id.equals(-1)) {
throw IllegalStateException("ID should never be -1")
}
fun loadAttendeeDetails(orderId: Long) {
if (orderId == -1L) return

compositeDisposable += orderService.attendeesUnderOrder(id)
compositeDisposable += orderService.getOrderById(orderId)
.withDefaultSchedulers()
.doOnSubscribe {
mutableProgress.value = true
}.doFinally {
mutableProgress.value = false
}.subscribe({
loadAttendeeUnderOrder(it)
}, {
Timber.e(it, "Error fetching attendee details")
mutableProgress.value = false
message.value = resource.getString(R.string.error_fetching_attendee_details_message)
})
}

private fun loadAttendeeUnderOrder(order: Order) {
val orderIdentifier = order.identifier ?: return

compositeDisposable += orderService
.getAttendeesUnderOrder(orderIdentifier, order.attendees.map { it.id })
.withDefaultSchedulers()
.subscribe({
mutableAttendees.value = it
mutableProgress.value = false
}, {
Timber.e(it, "Error fetching attendee details")
mutableProgress.value = false
message.value = resource.getString(R.string.error_fetching_attendee_details_message)
})
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,10 @@ class OrderService(
fun placeOrder(order: Order): Single<Order> {
return orderApi.placeOrder(order)
.map { order ->
val attendeeIds = order.attendees?.map { order.id }
if (attendeeIds != null) {
attendeeDao.getAttendeesWithIds(attendeeIds).map {
if (it.size == attendeeIds.size) {
orderDao.insertOrder(order)
}
val attendeeIds = order.attendees.map { order.id }
attendeeDao.getAttendeesWithIds(attendeeIds).map {
if (it.size == attendeeIds.size) {
orderDao.insertOrder(order)
}
}
order
Expand All @@ -32,11 +30,27 @@ class OrderService(
return orderApi.confirmOrder(identifier, order)
}

fun orderUser(userId: Long): Single<List<Order>> {
fun getOrdersOfUser(userId: Long): Single<List<Order>> {
return orderApi.ordersUnderUser(userId)
.map {
orderDao.insertOrders(it)
it
}.onErrorResumeNext {
orderDao.getAllOrders().map { it }
}
}

fun attendeesUnderOrder(orderIdentifier: String): Single<List<Attendee>> {
fun getOrderById(orderId: Long): Single<Order> {
return orderDao.getOrderById(orderId)
}

fun getAttendeesUnderOrder(orderIdentifier: String, attendeesIds: List<Long>): Single<List<Attendee>> {
return orderApi.attendeesUnderOrder(orderIdentifier)
.map {
attendeeDao.insertAttendees(it)
it
}.onErrorResumeNext {
attendeeDao.getAttendeesWithIds(attendeesIds)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,19 +8,19 @@ import org.fossasia.openevent.general.event.Event

class OrdersRecyclerAdapter : RecyclerView.Adapter<OrdersViewHolder>() {

private val eventAndOrderIdentifier = ArrayList<Pair<Event, String>>()
private val showExpired = false
private val eventAndOrderIdentifier = ArrayList<Pair<Event, Order>>()
private var showExpired = false
private var clickListener: OrderClickListener? = null
var attendeesNumber = listOf<Int>()

fun setListener(listener: OrderClickListener) {
clickListener = listener
}

fun addAllPairs(list: List<Pair<Event, String>>, showExpired: Boolean) {
fun addAllPairs(list: List<Pair<Event, Order>>, showExpired: Boolean) {
if (eventAndOrderIdentifier.isNotEmpty())
this.eventAndOrderIdentifier.clear()
eventAndOrderIdentifier.addAll(list)
this.showExpired = showExpired
}

override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): OrdersViewHolder {
Expand All @@ -29,23 +29,14 @@ class OrdersRecyclerAdapter : RecyclerView.Adapter<OrdersViewHolder>() {
}

override fun onBindViewHolder(holder: OrdersViewHolder, position: Int) {
attendeesNumber[position]?.let {
holder.bind(eventAndOrderIdentifier[position].first,
clickListener,
eventAndOrderIdentifier[position].second,
it, showExpired)
}
holder.bind(eventAndOrderIdentifier[position], showExpired, clickListener)
}

override fun getItemCount(): Int {
return eventAndOrderIdentifier.size
}

fun setAttendeeNumber(number: List<Int>) {
attendeesNumber = number
}

interface OrderClickListener {
fun onClick(eventID: Long, orderIdentifier: String)
fun onClick(eventID: Long, orderIdentifier: String, orderId: Long)
}
}
Loading