From ea3abf2056b092460d895949645c92c646e8ffe7 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Tue, 30 Jul 2019 10:33:45 +0530 Subject: [PATCH 01/53] chore(deps): bump com.diffplug.gradle.spotless from 3.23.1 to 3.24.0 (#2207) Bumps com.diffplug.gradle.spotless from 3.23.1 to 3.24.0. Signed-off-by: dependabot-preview[bot] --- app/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/build.gradle b/app/build.gradle index 02cc05d3dc..8e675ae9ce 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -1,5 +1,5 @@ plugins { - id "com.diffplug.gradle.spotless" version "3.23.1" + id "com.diffplug.gradle.spotless" version "3.24.0" } apply plugin: 'com.android.application' From b0ea9f4cfb41a692b8b9eec1cfc50807fa07d2e7 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Tue, 30 Jul 2019 11:15:37 +0530 Subject: [PATCH 02/53] chore(deps): bump rxkotlin from 2.3.0 to 2.4.0 (#2209) Bumps [rxkotlin](https://github.com/ReactiveX/RxKotlin) from 2.3.0 to 2.4.0. - [Release notes](https://github.com/ReactiveX/RxKotlin/releases) - [Commits](https://github.com/ReactiveX/RxKotlin/compare/2.3.0...2.4.0) Signed-off-by: dependabot-preview[bot] --- app/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/build.gradle b/app/build.gradle index 8e675ae9ce..a564e1442a 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -181,7 +181,7 @@ dependencies { // RxJava implementation 'io.reactivex.rxjava2:rxandroid:2.1.1' - implementation 'io.reactivex.rxjava2:rxkotlin:2.3.0' + implementation 'io.reactivex.rxjava2:rxkotlin:2.4.0' implementation 'io.reactivex.rxjava2:rxjava:2.2.10' implementation 'com.squareup.retrofit2:adapter-rxjava2:2.6.0' From 5d273d059a6741ffce4d7a8d93863651e6465c8f Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Tue, 30 Jul 2019 13:09:19 +0530 Subject: [PATCH 03/53] chore(deps): bump material from 1.1.0-alpha08 to 1.1.0-alpha09 (#2208) Bumps [material](https://github.com/material-components/material-components-android) from 1.1.0-alpha08 to 1.1.0-alpha09. - [Release notes](https://github.com/material-components/material-components-android/releases) - [Commits](https://github.com/material-components/material-components-android/commits) Signed-off-by: dependabot-preview[bot] --- app/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/build.gradle b/app/build.gradle index a564e1442a..e6d1ad2062 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -136,7 +136,7 @@ dependencies { implementation 'androidx.constraintlayout:constraintlayout:2.0.0-beta2' implementation 'androidx.cardview:cardview:1.0.0' implementation 'androidx.recyclerview:recyclerview:1.1.0-beta01' - implementation 'com.google.android.material:material:1.1.0-alpha08' + implementation 'com.google.android.material:material:1.1.0-alpha09' implementation "androidx.browser:browser:1.0.0" implementation 'androidx.exifinterface:exifinterface:1.0.0' implementation "androidx.lifecycle:lifecycle-extensions:${lifecycle_version}" From 3be222fe7d647e3a96d9e76587494218ba4995bf Mon Sep 17 00:00:00 2001 From: Harshit Khandelwal Date: Wed, 31 Jul 2019 00:23:05 +0530 Subject: [PATCH 04/53] feat: Open external ticket URL (#2215) --- .../openevent/general/event/EventDetailsFragment.kt | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/org/fossasia/openevent/general/event/EventDetailsFragment.kt b/app/src/main/java/org/fossasia/openevent/general/event/EventDetailsFragment.kt index 7748797710..1ee95f20db 100644 --- a/app/src/main/java/org/fossasia/openevent/general/event/EventDetailsFragment.kt +++ b/app/src/main/java/org/fossasia/openevent/general/event/EventDetailsFragment.kt @@ -135,7 +135,13 @@ class EventDetailsFragment : Fragment() { setupSimilarEvents() rootView.buttonTickets.setOnClickListener { - loadTicketFragment() + val ticketUrl = currentEvent?.ticketUrl + if (Uri.parse(ticketUrl).host != getString(R.string.FRONTEND_HOST) && + !ticketUrl.isNullOrEmpty()) { + Utils.openUrl(requireContext(), ticketUrl) + } else { + loadTicketFragment() + } } eventViewModel.popMessage From e207a98a2ef524fd7ae1964c648d57e45f399efe Mon Sep 17 00:00:00 2001 From: Harshit Khandelwal Date: Wed, 31 Jul 2019 00:25:37 +0530 Subject: [PATCH 05/53] feat: Add tax for tickets (#2206) --- .../9.json | 2199 +++++++++++++++++ .../openevent/general/OpenEventDatabase.kt | 6 +- .../general/attendees/AttendeeFragment.kt | 9 + .../fossasia/openevent/general/di/Modules.kt | 17 +- .../openevent/general/event/tax/Tax.kt | 36 + .../openevent/general/event/tax/TaxApi.kt | 11 + .../openevent/general/event/tax/TaxDao.kt | 17 + .../openevent/general/event/tax/TaxService.kt | 21 + .../general/ticket/TicketViewHolder.kt | 20 +- .../general/ticket/TicketsFragment.kt | 17 +- .../general/ticket/TicketsRecyclerAdapter.kt | 8 +- .../general/ticket/TicketsViewModel.kt | 31 +- .../openevent/general/utils/HttpErrors.kt | 1 + app/src/main/res/layout/fragment_attendee.xml | 55 + app/src/main/res/layout/item_ticket.xml | 56 +- .../main/res/layout/item_ticket_details.xml | 1 - .../main/res/navigation/navigation_graph.xml | 6 + app/src/main/res/values/strings.xml | 2 + 18 files changed, 2482 insertions(+), 31 deletions(-) create mode 100644 app/schemas/org.fossasia.openevent.general.OpenEventDatabase/9.json create mode 100644 app/src/main/java/org/fossasia/openevent/general/event/tax/Tax.kt create mode 100644 app/src/main/java/org/fossasia/openevent/general/event/tax/TaxApi.kt create mode 100644 app/src/main/java/org/fossasia/openevent/general/event/tax/TaxDao.kt create mode 100644 app/src/main/java/org/fossasia/openevent/general/event/tax/TaxService.kt diff --git a/app/schemas/org.fossasia.openevent.general.OpenEventDatabase/9.json b/app/schemas/org.fossasia.openevent.general.OpenEventDatabase/9.json new file mode 100644 index 0000000000..a5c38dd34b --- /dev/null +++ b/app/schemas/org.fossasia.openevent.general.OpenEventDatabase/9.json @@ -0,0 +1,2199 @@ +{ + "formatVersion": 1, + "database": { + "version": 9, + "identityHash": "07e6469355d66c3bfab3448a10d6e381", + "entities": [ + { + "tableName": "Event", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER NOT NULL, `name` TEXT NOT NULL, `identifier` TEXT NOT NULL, `startsAt` TEXT NOT NULL, `endsAt` TEXT NOT NULL, `timezone` TEXT NOT NULL, `privacy` TEXT NOT NULL, `paymentCountry` TEXT, `paypalEmail` TEXT, `thumbnailImageUrl` TEXT, `schedulePublishedOn` TEXT, `paymentCurrency` TEXT, `ownerDescription` TEXT, `originalImageUrl` TEXT, `onsiteDetails` TEXT, `ownerName` TEXT, `largeImageUrl` TEXT, `deletedAt` TEXT, `ticketUrl` TEXT, `locationName` TEXT, `codeOfConduct` TEXT, `state` TEXT, `searchableLocationName` TEXT, `description` TEXT, `pentabarfUrl` TEXT, `xcalUrl` TEXT, `logoUrl` TEXT, `externalEventUrl` TEXT, `iconImageUrl` TEXT, `icalUrl` TEXT, `createdAt` TEXT, `bankDetails` TEXT, `chequeDetails` TEXT, `isComplete` INTEGER NOT NULL, `latitude` REAL, `longitude` REAL, `refundPolicy` TEXT, `canPayByStripe` INTEGER NOT NULL, `canPayByCheque` INTEGER NOT NULL, `canPayByBank` INTEGER NOT NULL, `canPayByPaypal` INTEGER NOT NULL, `canPayOnsite` INTEGER NOT NULL, `isSponsorsEnabled` INTEGER NOT NULL, `hasOwnerInfo` INTEGER NOT NULL, `isSessionsSpeakersEnabled` INTEGER NOT NULL, `isTicketingEnabled` INTEGER NOT NULL, `isTaxEnabled` INTEGER NOT NULL, `isMapShown` INTEGER NOT NULL, `favorite` INTEGER NOT NULL, `favoriteEventId` INTEGER, `eventTopic` TEXT, `eventType` TEXT, `eventSubTopic` TEXT, `speakersCall` TEXT, PRIMARY KEY(`id`))", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "name", + "columnName": "name", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "identifier", + "columnName": "identifier", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "startsAt", + "columnName": "startsAt", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "endsAt", + "columnName": "endsAt", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "timezone", + "columnName": "timezone", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "privacy", + "columnName": "privacy", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "paymentCountry", + "columnName": "paymentCountry", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "paypalEmail", + "columnName": "paypalEmail", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "thumbnailImageUrl", + "columnName": "thumbnailImageUrl", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "schedulePublishedOn", + "columnName": "schedulePublishedOn", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "paymentCurrency", + "columnName": "paymentCurrency", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "ownerDescription", + "columnName": "ownerDescription", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "originalImageUrl", + "columnName": "originalImageUrl", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "onsiteDetails", + "columnName": "onsiteDetails", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "ownerName", + "columnName": "ownerName", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "largeImageUrl", + "columnName": "largeImageUrl", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "deletedAt", + "columnName": "deletedAt", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "ticketUrl", + "columnName": "ticketUrl", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "locationName", + "columnName": "locationName", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "codeOfConduct", + "columnName": "codeOfConduct", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "state", + "columnName": "state", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "searchableLocationName", + "columnName": "searchableLocationName", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "description", + "columnName": "description", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "pentabarfUrl", + "columnName": "pentabarfUrl", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "xcalUrl", + "columnName": "xcalUrl", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "logoUrl", + "columnName": "logoUrl", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "externalEventUrl", + "columnName": "externalEventUrl", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "iconImageUrl", + "columnName": "iconImageUrl", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "icalUrl", + "columnName": "icalUrl", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "createdAt", + "columnName": "createdAt", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "bankDetails", + "columnName": "bankDetails", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "chequeDetails", + "columnName": "chequeDetails", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "isComplete", + "columnName": "isComplete", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "latitude", + "columnName": "latitude", + "affinity": "REAL", + "notNull": false + }, + { + "fieldPath": "longitude", + "columnName": "longitude", + "affinity": "REAL", + "notNull": false + }, + { + "fieldPath": "refundPolicy", + "columnName": "refundPolicy", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "canPayByStripe", + "columnName": "canPayByStripe", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "canPayByCheque", + "columnName": "canPayByCheque", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "canPayByBank", + "columnName": "canPayByBank", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "canPayByPaypal", + "columnName": "canPayByPaypal", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "canPayOnsite", + "columnName": "canPayOnsite", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "isSponsorsEnabled", + "columnName": "isSponsorsEnabled", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "hasOwnerInfo", + "columnName": "hasOwnerInfo", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "isSessionsSpeakersEnabled", + "columnName": "isSessionsSpeakersEnabled", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "isTicketingEnabled", + "columnName": "isTicketingEnabled", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "isTaxEnabled", + "columnName": "isTaxEnabled", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "isMapShown", + "columnName": "isMapShown", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "favorite", + "columnName": "favorite", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "favoriteEventId", + "columnName": "favoriteEventId", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "eventTopic", + "columnName": "eventTopic", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "eventType", + "columnName": "eventType", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "eventSubTopic", + "columnName": "eventSubTopic", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "speakersCall", + "columnName": "speakersCall", + "affinity": "TEXT", + "notNull": false + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": false + }, + "indices": [ + { + "name": "index_Event_eventTopic", + "unique": false, + "columnNames": [ + "eventTopic" + ], + "createSql": "CREATE INDEX `index_Event_eventTopic` ON `${TABLE_NAME}` (`eventTopic`)" + }, + { + "name": "index_Event_eventType", + "unique": false, + "columnNames": [ + "eventType" + ], + "createSql": "CREATE INDEX `index_Event_eventType` ON `${TABLE_NAME}` (`eventType`)" + }, + { + "name": "index_Event_eventSubTopic", + "unique": false, + "columnNames": [ + "eventSubTopic" + ], + "createSql": "CREATE INDEX `index_Event_eventSubTopic` ON `${TABLE_NAME}` (`eventSubTopic`)" + }, + { + "name": "index_Event_speakersCall", + "unique": false, + "columnNames": [ + "speakersCall" + ], + "createSql": "CREATE INDEX `index_Event_speakersCall` ON `${TABLE_NAME}` (`speakersCall`)" + } + ], + "foreignKeys": [] + }, + { + "tableName": "User", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER NOT NULL, `firstName` TEXT, `lastName` TEXT, `email` TEXT, `contact` TEXT, `details` TEXT, `thumbnailImageUrl` TEXT, `iconImageUrl` TEXT, `smallImageUrl` TEXT, `avatarUrl` TEXT, `facebookUrl` TEXT, `twitterUrl` TEXT, `instagramUrl` TEXT, `googlePlusUrl` TEXT, `originalImageUrl` TEXT, `isVerified` INTEGER NOT NULL, `isAdmin` INTEGER, `isSuperAdmin` INTEGER, `createdAt` TEXT, `lastAccessedAt` TEXT, `deletedAt` TEXT, PRIMARY KEY(`id`))", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "firstName", + "columnName": "firstName", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "lastName", + "columnName": "lastName", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "email", + "columnName": "email", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "contact", + "columnName": "contact", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "details", + "columnName": "details", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "thumbnailImageUrl", + "columnName": "thumbnailImageUrl", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "iconImageUrl", + "columnName": "iconImageUrl", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "smallImageUrl", + "columnName": "smallImageUrl", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "avatarUrl", + "columnName": "avatarUrl", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "facebookUrl", + "columnName": "facebookUrl", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "twitterUrl", + "columnName": "twitterUrl", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "instagramUrl", + "columnName": "instagramUrl", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "googlePlusUrl", + "columnName": "googlePlusUrl", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "originalImageUrl", + "columnName": "originalImageUrl", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "isVerified", + "columnName": "isVerified", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "isAdmin", + "columnName": "isAdmin", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "isSuperAdmin", + "columnName": "isSuperAdmin", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "createdAt", + "columnName": "createdAt", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "lastAccessedAt", + "columnName": "lastAccessedAt", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "deletedAt", + "columnName": "deletedAt", + "affinity": "TEXT", + "notNull": false + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": false + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "SocialLink", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER NOT NULL, `link` TEXT NOT NULL, `name` TEXT NOT NULL, `event` INTEGER, PRIMARY KEY(`id`), FOREIGN KEY(`event`) REFERENCES `Event`(`id`) ON UPDATE NO ACTION ON DELETE CASCADE )", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "link", + "columnName": "link", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "name", + "columnName": "name", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "event", + "columnName": "event", + "affinity": "INTEGER", + "notNull": false + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": false + }, + "indices": [ + { + "name": "index_SocialLink_event", + "unique": false, + "columnNames": [ + "event" + ], + "createSql": "CREATE INDEX `index_SocialLink_event` ON `${TABLE_NAME}` (`event`)" + } + ], + "foreignKeys": [ + { + "table": "Event", + "onDelete": "CASCADE", + "onUpdate": "NO ACTION", + "columns": [ + "event" + ], + "referencedColumns": [ + "id" + ] + } + ] + }, + { + "tableName": "Ticket", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER NOT NULL, `description` TEXT, `type` TEXT, `name` TEXT NOT NULL, `maxOrder` INTEGER NOT NULL, `isFeeAbsorbed` INTEGER, `isDescriptionVisible` INTEGER, `price` REAL NOT NULL, `position` TEXT, `quantity` TEXT, `isHidden` INTEGER, `salesStartsAt` TEXT, `salesEndsAt` TEXT, `minOrder` INTEGER NOT NULL, `event` INTEGER, PRIMARY KEY(`id`), FOREIGN KEY(`event`) REFERENCES `Event`(`id`) ON UPDATE NO ACTION ON DELETE CASCADE )", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "description", + "columnName": "description", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "type", + "columnName": "type", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "name", + "columnName": "name", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "maxOrder", + "columnName": "maxOrder", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "isFeeAbsorbed", + "columnName": "isFeeAbsorbed", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "isDescriptionVisible", + "columnName": "isDescriptionVisible", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "price", + "columnName": "price", + "affinity": "REAL", + "notNull": true + }, + { + "fieldPath": "position", + "columnName": "position", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "quantity", + "columnName": "quantity", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "isHidden", + "columnName": "isHidden", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "salesStartsAt", + "columnName": "salesStartsAt", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "salesEndsAt", + "columnName": "salesEndsAt", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "minOrder", + "columnName": "minOrder", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "event", + "columnName": "event", + "affinity": "INTEGER", + "notNull": false + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": false + }, + "indices": [ + { + "name": "index_Ticket_event", + "unique": false, + "columnNames": [ + "event" + ], + "createSql": "CREATE INDEX `index_Ticket_event` ON `${TABLE_NAME}` (`event`)" + } + ], + "foreignKeys": [ + { + "table": "Event", + "onDelete": "CASCADE", + "onUpdate": "NO ACTION", + "columns": [ + "event" + ], + "referencedColumns": [ + "id" + ] + } + ] + }, + { + "tableName": "Attendee", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER NOT NULL, `firstname` TEXT, `lastname` TEXT, `email` TEXT, `address` TEXT, `city` TEXT, `state` TEXT, `country` TEXT, `jobTitle` TEXT, `phone` TEXT, `taxBusinessInfo` TEXT, `billingAddress` TEXT, `homeAddress` TEXT, `shippingAddress` TEXT, `company` TEXT, `workAddress` TEXT, `workPhone` TEXT, `website` TEXT, `blog` TEXT, `github` TEXT, `facebook` TEXT, `twitter` TEXT, `gender` TEXT, `isCheckedIn` INTEGER, `checkinTimes` TEXT, `isCheckedOut` INTEGER NOT NULL, `pdfUrl` TEXT, `ticketId` TEXT, `event` INTEGER, `ticket` INTEGER, PRIMARY KEY(`id`), FOREIGN KEY(`event`) REFERENCES `Event`(`id`) ON UPDATE NO ACTION ON DELETE CASCADE , FOREIGN KEY(`ticket`) REFERENCES `Ticket`(`id`) ON UPDATE NO ACTION ON DELETE CASCADE )", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "firstname", + "columnName": "firstname", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "lastname", + "columnName": "lastname", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "email", + "columnName": "email", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "address", + "columnName": "address", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "city", + "columnName": "city", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "state", + "columnName": "state", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "country", + "columnName": "country", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "jobTitle", + "columnName": "jobTitle", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "phone", + "columnName": "phone", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "taxBusinessInfo", + "columnName": "taxBusinessInfo", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "billingAddress", + "columnName": "billingAddress", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "homeAddress", + "columnName": "homeAddress", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "shippingAddress", + "columnName": "shippingAddress", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "company", + "columnName": "company", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "workAddress", + "columnName": "workAddress", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "workPhone", + "columnName": "workPhone", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "website", + "columnName": "website", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "blog", + "columnName": "blog", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "github", + "columnName": "github", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "facebook", + "columnName": "facebook", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "twitter", + "columnName": "twitter", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "gender", + "columnName": "gender", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "isCheckedIn", + "columnName": "isCheckedIn", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "checkinTimes", + "columnName": "checkinTimes", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "isCheckedOut", + "columnName": "isCheckedOut", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "pdfUrl", + "columnName": "pdfUrl", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "ticketId", + "columnName": "ticketId", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "event", + "columnName": "event", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "ticket", + "columnName": "ticket", + "affinity": "INTEGER", + "notNull": false + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": false + }, + "indices": [ + { + "name": "index_Attendee_event", + "unique": false, + "columnNames": [ + "event" + ], + "createSql": "CREATE INDEX `index_Attendee_event` ON `${TABLE_NAME}` (`event`)" + }, + { + "name": "index_Attendee_ticket", + "unique": false, + "columnNames": [ + "ticket" + ], + "createSql": "CREATE INDEX `index_Attendee_ticket` ON `${TABLE_NAME}` (`ticket`)" + } + ], + "foreignKeys": [ + { + "table": "Event", + "onDelete": "CASCADE", + "onUpdate": "NO ACTION", + "columns": [ + "event" + ], + "referencedColumns": [ + "id" + ] + }, + { + "table": "Ticket", + "onDelete": "CASCADE", + "onUpdate": "NO ACTION", + "columns": [ + "ticket" + ], + "referencedColumns": [ + "id" + ] + } + ] + }, + { + "tableName": "EventTopic", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER NOT NULL, `name` TEXT NOT NULL, `slug` TEXT NOT NULL, `event` INTEGER, PRIMARY KEY(`id`), FOREIGN KEY(`event`) REFERENCES `Event`(`id`) ON UPDATE NO ACTION ON DELETE CASCADE )", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "name", + "columnName": "name", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "slug", + "columnName": "slug", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "event", + "columnName": "event", + "affinity": "INTEGER", + "notNull": false + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": false + }, + "indices": [ + { + "name": "index_EventTopic_event", + "unique": false, + "columnNames": [ + "event" + ], + "createSql": "CREATE INDEX `index_EventTopic_event` ON `${TABLE_NAME}` (`event`)" + } + ], + "foreignKeys": [ + { + "table": "Event", + "onDelete": "CASCADE", + "onUpdate": "NO ACTION", + "columns": [ + "event" + ], + "referencedColumns": [ + "id" + ] + } + ] + }, + { + "tableName": "Order", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER NOT NULL, `paymentMode` TEXT, `country` TEXT, `status` TEXT, `amount` REAL NOT NULL, `identifier` TEXT, `orderNotes` TEXT, `completedAt` TEXT, `city` TEXT, `address` TEXT, `createdAt` TEXT, `zipcode` TEXT, `paidVia` TEXT, `discountCodeId` TEXT, `ticketsPdfUrl` TEXT, `transactionId` TEXT, `isBillingEnabled` INTEGER NOT NULL, `taxBusinessInfo` TEXT, `company` TEXT, `event` INTEGER, `attendees` TEXT NOT NULL, PRIMARY KEY(`id`))", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "paymentMode", + "columnName": "paymentMode", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "country", + "columnName": "country", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "status", + "columnName": "status", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "amount", + "columnName": "amount", + "affinity": "REAL", + "notNull": true + }, + { + "fieldPath": "identifier", + "columnName": "identifier", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "orderNotes", + "columnName": "orderNotes", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "completedAt", + "columnName": "completedAt", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "city", + "columnName": "city", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "address", + "columnName": "address", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "createdAt", + "columnName": "createdAt", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "zipcode", + "columnName": "zipcode", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "paidVia", + "columnName": "paidVia", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "discountCodeId", + "columnName": "discountCodeId", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "ticketsPdfUrl", + "columnName": "ticketsPdfUrl", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "transactionId", + "columnName": "transactionId", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "isBillingEnabled", + "columnName": "isBillingEnabled", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "taxBusinessInfo", + "columnName": "taxBusinessInfo", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "company", + "columnName": "company", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "event", + "columnName": "event", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "attendees", + "columnName": "attendees", + "affinity": "TEXT", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": false + }, + "indices": [ + { + "name": "index_Order_event", + "unique": false, + "columnNames": [ + "event" + ], + "createSql": "CREATE INDEX `index_Order_event` ON `${TABLE_NAME}` (`event`)" + } + ], + "foreignKeys": [] + }, + { + "tableName": "CustomForm", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER NOT NULL, `form` TEXT NOT NULL, `fieldIdentifier` TEXT NOT NULL, `type` TEXT NOT NULL, `isRequired` INTEGER NOT NULL, `isIncluded` INTEGER NOT NULL, `isFixed` INTEGER, `ticketsNumber` INTEGER, `event` INTEGER, PRIMARY KEY(`id`), FOREIGN KEY(`event`) REFERENCES `Event`(`id`) ON UPDATE NO ACTION ON DELETE CASCADE )", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "form", + "columnName": "form", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "fieldIdentifier", + "columnName": "fieldIdentifier", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "type", + "columnName": "type", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "isRequired", + "columnName": "isRequired", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "isIncluded", + "columnName": "isIncluded", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "isFixed", + "columnName": "isFixed", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "ticketsNumber", + "columnName": "ticketsNumber", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "event", + "columnName": "event", + "affinity": "INTEGER", + "notNull": false + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": false + }, + "indices": [], + "foreignKeys": [ + { + "table": "Event", + "onDelete": "CASCADE", + "onUpdate": "NO ACTION", + "columns": [ + "event" + ], + "referencedColumns": [ + "id" + ] + } + ] + }, + { + "tableName": "Speaker", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER NOT NULL, `name` TEXT, `email` TEXT, `photoUrl` TEXT, `shortBiography` TEXT, `longBiography` TEXT, `speakingExperience` TEXT, `position` TEXT, `mobile` TEXT, `location` TEXT, `country` TEXT, `city` TEXT, `organisation` TEXT, `gender` TEXT, `website` TEXT, `twitter` TEXT, `facebook` TEXT, `linkedin` TEXT, `github` TEXT, `isFeatured` INTEGER NOT NULL, `event` INTEGER, `user` INTEGER, PRIMARY KEY(`id`))", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "name", + "columnName": "name", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "email", + "columnName": "email", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "photoUrl", + "columnName": "photoUrl", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "shortBiography", + "columnName": "shortBiography", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "longBiography", + "columnName": "longBiography", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "speakingExperience", + "columnName": "speakingExperience", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "position", + "columnName": "position", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "mobile", + "columnName": "mobile", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "location", + "columnName": "location", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "country", + "columnName": "country", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "city", + "columnName": "city", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "organisation", + "columnName": "organisation", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "gender", + "columnName": "gender", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "website", + "columnName": "website", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "twitter", + "columnName": "twitter", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "facebook", + "columnName": "facebook", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "linkedin", + "columnName": "linkedin", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "github", + "columnName": "github", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "isFeatured", + "columnName": "isFeatured", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "event", + "columnName": "event", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "user", + "columnName": "user", + "affinity": "INTEGER", + "notNull": false + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": false + }, + "indices": [ + { + "name": "index_Speaker_event", + "unique": false, + "columnNames": [ + "event" + ], + "createSql": "CREATE INDEX `index_Speaker_event` ON `${TABLE_NAME}` (`event`)" + }, + { + "name": "index_Speaker_user", + "unique": false, + "columnNames": [ + "user" + ], + "createSql": "CREATE INDEX `index_Speaker_user` ON `${TABLE_NAME}` (`user`)" + } + ], + "foreignKeys": [] + }, + { + "tableName": "SpeakerWithEvent", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`event_id` INTEGER NOT NULL, `speaker_id` INTEGER NOT NULL, PRIMARY KEY(`event_id`, `speaker_id`), FOREIGN KEY(`event_id`) REFERENCES `Event`(`id`) ON UPDATE NO ACTION ON DELETE NO ACTION , FOREIGN KEY(`speaker_id`) REFERENCES `Speaker`(`id`) ON UPDATE NO ACTION ON DELETE NO ACTION )", + "fields": [ + { + "fieldPath": "eventId", + "columnName": "event_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "speakerId", + "columnName": "speaker_id", + "affinity": "INTEGER", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "event_id", + "speaker_id" + ], + "autoGenerate": false + }, + "indices": [ + { + "name": "index_SpeakerWithEvent_event_id", + "unique": false, + "columnNames": [ + "event_id" + ], + "createSql": "CREATE INDEX `index_SpeakerWithEvent_event_id` ON `${TABLE_NAME}` (`event_id`)" + }, + { + "name": "index_SpeakerWithEvent_speaker_id", + "unique": false, + "columnNames": [ + "speaker_id" + ], + "createSql": "CREATE INDEX `index_SpeakerWithEvent_speaker_id` ON `${TABLE_NAME}` (`speaker_id`)" + } + ], + "foreignKeys": [ + { + "table": "Event", + "onDelete": "NO ACTION", + "onUpdate": "NO ACTION", + "columns": [ + "event_id" + ], + "referencedColumns": [ + "id" + ] + }, + { + "table": "Speaker", + "onDelete": "NO ACTION", + "onUpdate": "NO ACTION", + "columns": [ + "speaker_id" + ], + "referencedColumns": [ + "id" + ] + } + ] + }, + { + "tableName": "Sponsor", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER NOT NULL, `name` TEXT, `description` TEXT, `url` TEXT, `logoUrl` TEXT, `level` INTEGER NOT NULL, `type` TEXT, PRIMARY KEY(`id`))", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "name", + "columnName": "name", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "description", + "columnName": "description", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "url", + "columnName": "url", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "logoUrl", + "columnName": "logoUrl", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "level", + "columnName": "level", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "type", + "columnName": "type", + "affinity": "TEXT", + "notNull": false + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": false + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "SponsorWithEvent", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`event_id` INTEGER NOT NULL, `sponsor_id` INTEGER NOT NULL, PRIMARY KEY(`event_id`, `sponsor_id`), FOREIGN KEY(`event_id`) REFERENCES `Event`(`id`) ON UPDATE NO ACTION ON DELETE NO ACTION , FOREIGN KEY(`sponsor_id`) REFERENCES `Sponsor`(`id`) ON UPDATE NO ACTION ON DELETE NO ACTION )", + "fields": [ + { + "fieldPath": "eventId", + "columnName": "event_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "sponsorId", + "columnName": "sponsor_id", + "affinity": "INTEGER", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "event_id", + "sponsor_id" + ], + "autoGenerate": false + }, + "indices": [ + { + "name": "index_SponsorWithEvent_event_id", + "unique": false, + "columnNames": [ + "event_id" + ], + "createSql": "CREATE INDEX `index_SponsorWithEvent_event_id` ON `${TABLE_NAME}` (`event_id`)" + }, + { + "name": "index_SponsorWithEvent_sponsor_id", + "unique": false, + "columnNames": [ + "sponsor_id" + ], + "createSql": "CREATE INDEX `index_SponsorWithEvent_sponsor_id` ON `${TABLE_NAME}` (`sponsor_id`)" + } + ], + "foreignKeys": [ + { + "table": "Event", + "onDelete": "NO ACTION", + "onUpdate": "NO ACTION", + "columns": [ + "event_id" + ], + "referencedColumns": [ + "id" + ] + }, + { + "table": "Sponsor", + "onDelete": "NO ACTION", + "onUpdate": "NO ACTION", + "columns": [ + "sponsor_id" + ], + "referencedColumns": [ + "id" + ] + } + ] + }, + { + "tableName": "Session", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER NOT NULL, `shortAbstract` TEXT, `comments` TEXT, `longAbstract` TEXT, `level` TEXT, `signupUrl` TEXT, `endsAt` TEXT, `language` TEXT, `title` TEXT, `startsAt` TEXT, `slidesUrl` TEXT, `averageRating` REAL, `submittedAt` TEXT, `deletedAt` TEXT, `subtitle` TEXT, `createdAt` TEXT, `state` TEXT, `lastModifiedAt` TEXT, `videoUrl` TEXT, `audioUrl` TEXT, `sessionType` TEXT, `microlocation` TEXT, `track` TEXT, `event` INTEGER, PRIMARY KEY(`id`))", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "shortAbstract", + "columnName": "shortAbstract", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "comments", + "columnName": "comments", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "longAbstract", + "columnName": "longAbstract", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "level", + "columnName": "level", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "signupUrl", + "columnName": "signupUrl", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "endsAt", + "columnName": "endsAt", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "language", + "columnName": "language", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "title", + "columnName": "title", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "startsAt", + "columnName": "startsAt", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "slidesUrl", + "columnName": "slidesUrl", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "averageRating", + "columnName": "averageRating", + "affinity": "REAL", + "notNull": false + }, + { + "fieldPath": "submittedAt", + "columnName": "submittedAt", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "deletedAt", + "columnName": "deletedAt", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "subtitle", + "columnName": "subtitle", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "createdAt", + "columnName": "createdAt", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "state", + "columnName": "state", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "lastModifiedAt", + "columnName": "lastModifiedAt", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "videoUrl", + "columnName": "videoUrl", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "audioUrl", + "columnName": "audioUrl", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "sessionType", + "columnName": "sessionType", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "microlocation", + "columnName": "microlocation", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "track", + "columnName": "track", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "event", + "columnName": "event", + "affinity": "INTEGER", + "notNull": false + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": false + }, + "indices": [ + { + "name": "index_Session_sessionType", + "unique": false, + "columnNames": [ + "sessionType" + ], + "createSql": "CREATE INDEX `index_Session_sessionType` ON `${TABLE_NAME}` (`sessionType`)" + }, + { + "name": "index_Session_microlocation", + "unique": false, + "columnNames": [ + "microlocation" + ], + "createSql": "CREATE INDEX `index_Session_microlocation` ON `${TABLE_NAME}` (`microlocation`)" + }, + { + "name": "index_Session_track", + "unique": false, + "columnNames": [ + "track" + ], + "createSql": "CREATE INDEX `index_Session_track` ON `${TABLE_NAME}` (`track`)" + }, + { + "name": "index_Session_event", + "unique": false, + "columnNames": [ + "event" + ], + "createSql": "CREATE INDEX `index_Session_event` ON `${TABLE_NAME}` (`event`)" + } + ], + "foreignKeys": [] + }, + { + "tableName": "SpeakersCall", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER NOT NULL, `announcement` TEXT NOT NULL, `startsAt` TEXT NOT NULL, `endsAt` TEXT NOT NULL, `hash` TEXT, `privacy` TEXT, PRIMARY KEY(`id`))", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "announcement", + "columnName": "announcement", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "startsAt", + "columnName": "startsAt", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "endsAt", + "columnName": "endsAt", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "hash", + "columnName": "hash", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "privacy", + "columnName": "privacy", + "affinity": "TEXT", + "notNull": false + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": false + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "Feedback", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER, `rating` TEXT, `comment` TEXT, `event` INTEGER, `user` INTEGER, PRIMARY KEY(`id`))", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "rating", + "columnName": "rating", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "comment", + "columnName": "comment", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "event", + "columnName": "event", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "user", + "columnName": "user", + "affinity": "INTEGER", + "notNull": false + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": false + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "Notification", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER NOT NULL, `message` TEXT, `receivedAt` TEXT, `isRead` INTEGER NOT NULL, `title` TEXT, `deletedAt` TEXT, PRIMARY KEY(`id`))", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "message", + "columnName": "message", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "receivedAt", + "columnName": "receivedAt", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "isRead", + "columnName": "isRead", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "title", + "columnName": "title", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "deletedAt", + "columnName": "deletedAt", + "affinity": "TEXT", + "notNull": false + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": false + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "Settings", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER, `appName` TEXT, `tagline` TEXT, `isPaypalActivated` INTEGER NOT NULL, `isStripeActivated` INTEGER NOT NULL, `isOmiseActivated` INTEGER NOT NULL, `frontendUrl` TEXT, `cookiePolicy` TEXT, `cookiePolicyLink` TEXT, `orderExpiryTime` INTEGER, PRIMARY KEY(`id`))", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "appName", + "columnName": "appName", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "tagline", + "columnName": "tagline", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "isPaypalActivated", + "columnName": "isPaypalActivated", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "isStripeActivated", + "columnName": "isStripeActivated", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "isOmiseActivated", + "columnName": "isOmiseActivated", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "frontendUrl", + "columnName": "frontendUrl", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "cookiePolicy", + "columnName": "cookiePolicy", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "cookiePolicyLink", + "columnName": "cookiePolicyLink", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "orderExpiryTime", + "columnName": "orderExpiryTime", + "affinity": "INTEGER", + "notNull": false + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": false + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "Proposal", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER, `title` TEXT, `language` TEXT, `shortAbstract` TEXT, `comments` TEXT, `startsAt` TEXT, `endsAt` TEXT, `track` TEXT, `event` INTEGER, `speakers` TEXT NOT NULL, PRIMARY KEY(`id`))", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "title", + "columnName": "title", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "language", + "columnName": "language", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "shortAbstract", + "columnName": "shortAbstract", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "comments", + "columnName": "comments", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "startsAt", + "columnName": "startsAt", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "endsAt", + "columnName": "endsAt", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "track", + "columnName": "track", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "event", + "columnName": "event", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "speakers", + "columnName": "speakers", + "affinity": "TEXT", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": false + }, + "indices": [ + { + "name": "index_Proposal_track", + "unique": false, + "columnNames": [ + "track" + ], + "createSql": "CREATE INDEX `index_Proposal_track` ON `${TABLE_NAME}` (`track`)" + }, + { + "name": "index_Proposal_event", + "unique": false, + "columnNames": [ + "event" + ], + "createSql": "CREATE INDEX `index_Proposal_event` ON `${TABLE_NAME}` (`event`)" + }, + { + "name": "index_Proposal_speakers", + "unique": false, + "columnNames": [ + "speakers" + ], + "createSql": "CREATE INDEX `index_Proposal_speakers` ON `${TABLE_NAME}` (`speakers`)" + } + ], + "foreignKeys": [] + }, + { + "tableName": "Tax", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER, `name` TEXT, `rate` REAL, `taxId` TEXT, `registeredCompany` TEXT, `address` TEXT, `city` TEXT, `stare` TEXT, `zip` TEXT, `invoiceFooter` TEXT, `isInvoiceSend` INTEGER NOT NULL, `isTaxIncludedInPrice` INTEGER NOT NULL, `shouldSendInvoice` INTEGER NOT NULL, `eventId` INTEGER, PRIMARY KEY(`id`))", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "name", + "columnName": "name", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "rate", + "columnName": "rate", + "affinity": "REAL", + "notNull": false + }, + { + "fieldPath": "taxId", + "columnName": "taxId", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "registeredCompany", + "columnName": "registeredCompany", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "address", + "columnName": "address", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "city", + "columnName": "city", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "stare", + "columnName": "stare", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "zip", + "columnName": "zip", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "invoiceFooter", + "columnName": "invoiceFooter", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "isInvoiceSend", + "columnName": "isInvoiceSend", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "isTaxIncludedInPrice", + "columnName": "isTaxIncludedInPrice", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "shouldSendInvoice", + "columnName": "shouldSendInvoice", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "eventId", + "columnName": "eventId", + "affinity": "INTEGER", + "notNull": false + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": false + }, + "indices": [ + { + "name": "index_Tax_eventId", + "unique": false, + "columnNames": [ + "eventId" + ], + "createSql": "CREATE INDEX `index_Tax_eventId` ON `${TABLE_NAME}` (`eventId`)" + } + ], + "foreignKeys": [] + } + ], + "views": [], + "setupQueries": [ + "CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)", + "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '07e6469355d66c3bfab3448a10d6e381')" + ] + } +} \ No newline at end of file diff --git a/app/src/main/java/org/fossasia/openevent/general/OpenEventDatabase.kt b/app/src/main/java/org/fossasia/openevent/general/OpenEventDatabase.kt index 4b2c3cae5b..99819b75be 100644 --- a/app/src/main/java/org/fossasia/openevent/general/OpenEventDatabase.kt +++ b/app/src/main/java/org/fossasia/openevent/general/OpenEventDatabase.kt @@ -15,6 +15,8 @@ import org.fossasia.openevent.general.event.Event import org.fossasia.openevent.general.event.EventDao import org.fossasia.openevent.general.event.EventIdConverter import org.fossasia.openevent.general.event.subtopic.EventSubTopicConverter +import org.fossasia.openevent.general.event.tax.Tax +import org.fossasia.openevent.general.event.tax.TaxDao import org.fossasia.openevent.general.event.topic.EventTopic import org.fossasia.openevent.general.event.topic.EventTopicConverter import org.fossasia.openevent.general.event.topic.EventTopicsDao @@ -54,7 +56,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, SpeakersCall::class, Feedback::class, Notification::class, - Settings::class, Proposal::class], version = 8) + Settings::class, Proposal::class, Tax::class], version = 9) @TypeConverters(EventIdConverter::class, EventTopicConverter::class, EventTypeConverter::class, EventSubTopicConverter::class, TicketIdConverter::class, MicroLocationConverter::class, UserIdConverter::class, AttendeeIdConverter::class, ListAttendeeIdConverter::class, SessionTypeConverter::class, TrackConverter::class, @@ -92,4 +94,6 @@ abstract class OpenEventDatabase : RoomDatabase() { abstract fun notificationDao(): NotificationDao abstract fun settingsDao(): SettingsDao + + abstract fun taxDao(): TaxDao } 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 7522a1a899..578fdcc804 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 @@ -88,6 +88,10 @@ import kotlinx.android.synthetic.main.fragment_attendee.view.signInTextLayout import kotlinx.android.synthetic.main.fragment_attendee.view.signInLayout import kotlinx.android.synthetic.main.fragment_attendee.view.signOutLayout import kotlinx.android.synthetic.main.fragment_attendee.view.paymentTitle +import kotlinx.android.synthetic.main.fragment_attendee.view.taxLayout +import kotlinx.android.synthetic.main.fragment_attendee.view.taxPrice +import kotlinx.android.synthetic.main.fragment_attendee.view.totalAmountLayout +import kotlinx.android.synthetic.main.fragment_attendee.view.totalPrice import org.fossasia.openevent.general.BuildConfig import org.fossasia.openevent.general.R import org.fossasia.openevent.general.auth.User @@ -313,6 +317,11 @@ class AttendeeFragment : Fragment(), ComplexBackPressFragment { rootView.ticketsRecycler.adapter = ticketsRecyclerAdapter rootView.ticketsRecycler.isNestedScrollingEnabled = false + rootView.taxLayout.isVisible = safeArgs.taxAmount > 0f + rootView.taxPrice.text = "${safeArgs.currency}${"%.2f".format(safeArgs.taxAmount)}" + rootView.totalAmountLayout.isVisible = safeArgs.amount > 0f + rootView.totalPrice.text = "${safeArgs.currency}${"%.2f".format(safeArgs.amount)}" + rootView.ticketTableDetails.setOnClickListener { attendeeViewModel.ticketDetailsVisible = !attendeeViewModel.ticketDetailsVisible loadTicketDetailsTableUI(attendeeViewModel.ticketDetailsVisible) 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 7ec38c43c2..3436123ac7 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 @@ -79,6 +79,9 @@ import org.fossasia.openevent.general.sessions.Session import org.fossasia.openevent.general.sessions.SessionApi import org.fossasia.openevent.general.sessions.SessionService import org.fossasia.openevent.general.event.faq.EventFAQViewModel +import org.fossasia.openevent.general.event.tax.Tax +import org.fossasia.openevent.general.event.tax.TaxApi +import org.fossasia.openevent.general.event.tax.TaxService import org.fossasia.openevent.general.favorite.FavoriteEvent import org.fossasia.openevent.general.favorite.FavoriteEventApi import org.fossasia.openevent.general.feedback.FeedbackViewModel @@ -209,6 +212,10 @@ val apiModule = module { val retrofit: Retrofit = get() retrofit.create(SettingsApi::class.java) } + single { + val retrofit: Retrofit = get() + retrofit.create(TaxApi::class.java) + } factory { AuthHolder(get()) } factory { AuthService(get(), get(), get(), get(), get(), get(), get()) } @@ -224,6 +231,7 @@ val apiModule = module { factory { NotificationService(get(), get()) } factory { FeedbackService(get(), get()) } factory { SettingsService(get(), get()) } + factory { TaxService(get(), get()) } } val viewModelModule = module { @@ -241,7 +249,7 @@ val viewModelModule = module { viewModel { SearchLocationViewModel(get(), get()) } viewModel { SearchTimeViewModel(get()) } viewModel { SearchTypeViewModel(get(), get(), get()) } - viewModel { TicketsViewModel(get(), get(), get(), get(), get()) } + viewModel { TicketsViewModel(get(), get(), get(), get(), get(), get()) } viewModel { AboutEventViewModel(get(), get()) } viewModel { EventFAQViewModel(get(), get()) } viewModel { FavoriteEventsViewModel(get(), get(), get()) } @@ -310,7 +318,7 @@ val networkModule = module { EventSubTopic::class.java, Feedback::class.java, Speaker::class.java, FavoriteEvent::class.java, Session::class.java, SessionType::class.java, MicroLocation::class.java, SpeakersCall::class.java, Sponsor::class.java, EventFAQ::class.java, Notification::class.java, Track::class.java, - DiscountCode::class.java, Settings::class.java, Proposal::class.java) + DiscountCode::class.java, Settings::class.java, Proposal::class.java, Tax::class.java) Retrofit.Builder() .client(get()) @@ -408,4 +416,9 @@ val databaseModule = module { val database: OpenEventDatabase = get() database.settingsDao() } + + factory { + val database: OpenEventDatabase = get() + database.taxDao() + } } diff --git a/app/src/main/java/org/fossasia/openevent/general/event/tax/Tax.kt b/app/src/main/java/org/fossasia/openevent/general/event/tax/Tax.kt new file mode 100644 index 0000000000..a6dbd2adca --- /dev/null +++ b/app/src/main/java/org/fossasia/openevent/general/event/tax/Tax.kt @@ -0,0 +1,36 @@ +package org.fossasia.openevent.general.event.tax + +import androidx.room.ColumnInfo +import androidx.room.Entity +import androidx.room.PrimaryKey +import com.fasterxml.jackson.databind.PropertyNamingStrategy +import com.fasterxml.jackson.databind.annotation.JsonNaming +import com.github.jasminb.jsonapi.IntegerIdHandler +import com.github.jasminb.jsonapi.annotations.Id +import com.github.jasminb.jsonapi.annotations.Relationship +import com.github.jasminb.jsonapi.annotations.Type +import org.fossasia.openevent.general.event.EventId + +@Type("tax") +@JsonNaming(PropertyNamingStrategy.KebabCaseStrategy::class) +@Entity +class Tax( + @Id(IntegerIdHandler::class) + @PrimaryKey + val id: Int? = null, + val name: String? = null, + val rate: Float? = null, + val taxId: String? = null, + val registeredCompany: String? = null, + val address: String? = null, + val city: String? = null, + val stare: String? = null, + val zip: String? = null, + val invoiceFooter: String? = null, + val isInvoiceSend: Boolean = false, + val isTaxIncludedInPrice: Boolean = false, + val shouldSendInvoice: Boolean = false, + @ColumnInfo(index = true) + @Relationship("event") + val eventId: EventId? = null +) diff --git a/app/src/main/java/org/fossasia/openevent/general/event/tax/TaxApi.kt b/app/src/main/java/org/fossasia/openevent/general/event/tax/TaxApi.kt new file mode 100644 index 0000000000..fa1150359f --- /dev/null +++ b/app/src/main/java/org/fossasia/openevent/general/event/tax/TaxApi.kt @@ -0,0 +1,11 @@ +package org.fossasia.openevent.general.event.tax + +import io.reactivex.Single +import retrofit2.http.GET +import retrofit2.http.Path + +interface TaxApi { + + @GET("events/{event_identifier}/tax?include=event") + fun getTaxDetails(@Path("event_identifier") identifier: String): Single +} diff --git a/app/src/main/java/org/fossasia/openevent/general/event/tax/TaxDao.kt b/app/src/main/java/org/fossasia/openevent/general/event/tax/TaxDao.kt new file mode 100644 index 0000000000..c0d33816b9 --- /dev/null +++ b/app/src/main/java/org/fossasia/openevent/general/event/tax/TaxDao.kt @@ -0,0 +1,17 @@ +package org.fossasia.openevent.general.event.tax + +import androidx.room.Dao +import androidx.room.Insert +import androidx.room.OnConflictStrategy +import androidx.room.Query +import io.reactivex.Single + +@Dao +interface TaxDao { + + @Insert(onConflict = OnConflictStrategy.REPLACE) + fun insertTax(tax: Tax) + + @Query("SELECT * from Tax WHERE eventId = :eventId") + fun getTaxDetails(eventId: Long): Single +} diff --git a/app/src/main/java/org/fossasia/openevent/general/event/tax/TaxService.kt b/app/src/main/java/org/fossasia/openevent/general/event/tax/TaxService.kt new file mode 100644 index 0000000000..93f10d6879 --- /dev/null +++ b/app/src/main/java/org/fossasia/openevent/general/event/tax/TaxService.kt @@ -0,0 +1,21 @@ +package org.fossasia.openevent.general.event.tax + +import io.reactivex.Single +import timber.log.Timber + +class TaxService( + private val taxApi: TaxApi, + private val taxDao: TaxDao +) { + + fun getTax(eventId: Long): Single { + return taxApi.getTaxDetails(eventId.toString()) + .onErrorResumeNext { + Timber.e(it, "Error fetching tax") + taxDao.getTaxDetails(eventId) + }.map { + taxDao.insertTax(it) + it + } + } +} diff --git a/app/src/main/java/org/fossasia/openevent/general/ticket/TicketViewHolder.kt b/app/src/main/java/org/fossasia/openevent/general/ticket/TicketViewHolder.kt index 9187db5129..fe106ffb8e 100644 --- a/app/src/main/java/org/fossasia/openevent/general/ticket/TicketViewHolder.kt +++ b/app/src/main/java/org/fossasia/openevent/general/ticket/TicketViewHolder.kt @@ -17,6 +17,7 @@ import kotlinx.android.synthetic.main.item_ticket.view.discountPrice import kotlinx.android.synthetic.main.item_ticket.view.donationInput import kotlinx.android.synthetic.main.item_ticket.view.orderQtySection import kotlinx.android.synthetic.main.item_ticket.view.priceSection +import kotlinx.android.synthetic.main.item_ticket.view.taxInfo import org.fossasia.openevent.general.R import org.fossasia.openevent.general.data.Resource import kotlinx.android.synthetic.main.item_ticket.view.priceInfo @@ -28,6 +29,7 @@ import kotlinx.android.synthetic.main.item_ticket.view.description import org.fossasia.openevent.general.discount.DiscountCode import org.fossasia.openevent.general.event.EventUtils import org.fossasia.openevent.general.event.EventUtils.getFormattedDate +import org.fossasia.openevent.general.event.tax.Tax import org.threeten.bp.DateTimeUtils import java.util.Date import kotlin.collections.ArrayList @@ -47,7 +49,8 @@ class TicketViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { eventTimeZone: String?, ticketQuantity: Int, donationAmount: Float, - discountCode: DiscountCode? = null + discountCode: DiscountCode? = null, + tax: Tax? ) { itemView.ticketName.text = ticket.name setupTicketSaleDate(ticket, eventTimeZone) @@ -76,6 +79,13 @@ class TicketViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { itemView.orderRange.performClick() } + var ticketPrice = ticket.price + if (tax?.rate != null) { + val taxPrice = (ticketPrice * tax.rate / 100) + ticketPrice += taxPrice + itemView.taxInfo.text = "(+ $eventCurrency$taxPrice ${tax.name})" + } + when (ticket.type) { TICKET_TYPE_DONATION -> { itemView.price.text = resource.getString(R.string.donation) @@ -90,14 +100,14 @@ class TicketViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { itemView.donationInput.isVisible = false } TICKET_TYPE_PAID -> { - itemView.price.text = "$eventCurrency${"%.2f".format(ticket.price)}" + itemView.price.text = "$eventCurrency${"%.2f".format(ticketPrice)}" itemView.priceSection.isVisible = true itemView.donationInput.isVisible = false } } setupQtyPicker(minQty, maxQty, selectedListener, ticket, ticketQuantity) - val priceInfo = "${resource.getString(R.string.price)}: ${itemView.price.text}" + val priceInfo = "${resource.getString(R.string.price)}: ${ticket.price}" itemView.priceInfo.text = Html.fromHtml(priceInfo) if (ticket.description.isNullOrEmpty()) { @@ -111,8 +121,8 @@ class TicketViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { itemView.discountPrice.visibility = View.VISIBLE itemView.price.paintFlags = Paint.STRIKE_THRU_TEXT_FLAG itemView.discountPrice.text = - if (discountCode.type == AMOUNT) "$eventCurrency${ticket.price - discountCode.value}" - else "$eventCurrency${"%.2f".format(ticket.price - (ticket.price * discountCode.value / 100))}" + if (discountCode.type == AMOUNT) "$eventCurrency${ticketPrice - discountCode.value}" + else "$eventCurrency${"%.2f".format(ticketPrice - (ticketPrice * discountCode.value / 100))}" } } 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 6a6f3e796b..d3abf52a05 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 @@ -137,6 +137,7 @@ class TicketsFragment : Fragment() { rootView.retry.setOnClickListener { loadTickets() + loadTaxDetails() } rootView.applyDiscountCode.setOnClickListener { @@ -177,7 +178,10 @@ class TicketsFragment : Fragment() { ticketsViewModel.connection .nonNull() .observe(viewLifecycleOwner, Observer { isConnected -> - loadTickets() + if (isConnected) { + loadTickets() + loadTaxDetails() + } showNoInternetScreen(!isConnected && ticketsViewModel.tickets.value == null) }) @@ -220,6 +224,7 @@ class TicketsFragment : Fragment() { ticketIdAndQty = wrappedTicketAndQty, currency = safeArgs.currency, amount = totalAmount, + taxAmount = ticketsViewModel.totalTaxAmount, hasPaidTickets = ticketsViewModel.hasPaidTickets )) ticketsViewModel.hasPaidTickets = false @@ -295,6 +300,16 @@ class TicketsFragment : Fragment() { } } + private fun loadTaxDetails() { + ticketsViewModel.getTaxDetails(safeArgs.eventId) + ticketsViewModel.taxInfo + .nonNull() + .observe(viewLifecycleOwner, Observer { + ticketsRecyclerAdapter.applyTax(it) + ticketsRecyclerAdapter.notifyDataSetChanged() + }) + } + private fun showNoInternetScreen(show: Boolean) { rootView.noInternetCard.isVisible = show rootView.ticketTableHeader.isVisible = !show diff --git a/app/src/main/java/org/fossasia/openevent/general/ticket/TicketsRecyclerAdapter.kt b/app/src/main/java/org/fossasia/openevent/general/ticket/TicketsRecyclerAdapter.kt index 07c1aefd0d..b77d7ddfbd 100644 --- a/app/src/main/java/org/fossasia/openevent/general/ticket/TicketsRecyclerAdapter.kt +++ b/app/src/main/java/org/fossasia/openevent/general/ticket/TicketsRecyclerAdapter.kt @@ -5,6 +5,7 @@ import android.view.LayoutInflater import android.view.ViewGroup import org.fossasia.openevent.general.R import org.fossasia.openevent.general.discount.DiscountCode +import org.fossasia.openevent.general.event.tax.Tax class TicketsRecyclerAdapter : RecyclerView.Adapter() { @@ -12,6 +13,7 @@ class TicketsRecyclerAdapter : RecyclerView.Adapter() { private var eventCurrency: String? = null private var eventTimeZone: String? = null private var discountCode: DiscountCode? = null + private var tax: Tax? = null private var selectedListener: TicketSelectedListener? = null private lateinit var ticketAndQuantity: List> @@ -38,6 +40,10 @@ class TicketsRecyclerAdapter : RecyclerView.Adapter() { this.discountCode = discountCode } + fun applyTax(tax: Tax) { + this.tax = tax + } + fun cancelDiscountCode() { this.discountCode = null } @@ -64,7 +70,7 @@ class TicketsRecyclerAdapter : RecyclerView.Adapter() { } } - holder.bind(ticket, selectedListener, eventCurrency, eventTimeZone, qty, donation, currentDiscountCode) + holder.bind(ticket, selectedListener, eventCurrency, eventTimeZone, qty, donation, currentDiscountCode, tax) } override fun getItemCount(): Int { 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 248a26b279..0de463e7ca 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 @@ -14,6 +14,9 @@ import org.fossasia.openevent.general.data.Resource import org.fossasia.openevent.general.discount.DiscountCode import org.fossasia.openevent.general.event.Event import org.fossasia.openevent.general.event.EventService +import org.fossasia.openevent.general.event.tax.Tax +import org.fossasia.openevent.general.event.tax.TaxService +import org.fossasia.openevent.general.utils.HttpErrors import retrofit2.HttpException import timber.log.Timber @@ -22,6 +25,7 @@ class TicketsViewModel( private val eventService: EventService, private val authHolder: AuthHolder, private val resource: Resource, + private val taxService: TaxService, private val mutableConnectionLiveData: MutableConnectionLiveData ) : ViewModel() { @@ -37,7 +41,10 @@ class TicketsViewModel( val event: LiveData = mutableEvent private val mutableDiscountCodes = MutableLiveData() val discountCode: LiveData = mutableDiscountCodes + private val mutableTaxInfo = MutableLiveData() + val taxInfo: LiveData = mutableTaxInfo var appliedDiscountCode: DiscountCode? = null + var totalTaxAmount = 0f val mutableAmount = MutableLiveData() val amount: LiveData = mutableAmount private val mutableTicketTableVisibility = MutableLiveData() @@ -103,6 +110,7 @@ class TicketsViewModel( fun getAmount(ticketIdAndQty: List>) { val ticketIds = ArrayList() val qty = ArrayList() + val taxRate = taxInfo.value?.rate ?: 0f ticketIdAndQty.forEach { if (it.second > 0) { ticketIds.add(it.first) @@ -122,6 +130,7 @@ class TicketsViewModel( val code = appliedDiscountCode tickets.forEach { ticket -> var price = ticket.price + totalTaxAmount += (ticket.price * taxRate / 100) * qty[index] if (code?.value != null) { appliedDiscountCode?.tickets?.forEach { ticketId -> if (ticket.id == ticketId.id.toInt()) { @@ -129,16 +138,36 @@ class TicketsViewModel( } } } - price.let { prices += price * qty[index++] } + price.let { prices += price * qty[index] } if (ticket.type == TICKET_TYPE_PAID) hasPaidTickets = true + index++ } + prices += totalTaxAmount mutableAmount.value = prices + donation }, { Timber.e(it, "Error Loading tickets!") }) } + fun getTaxDetails(eventId: Long) { + compositeDisposable += taxService.getTax(eventId) + .withDefaultSchedulers() + .doOnSubscribe { + mutableProgress.value = true + }.doFinally { + mutableProgress.value = false + }.subscribe({ + mutableTaxInfo.value = it + }, { + if (it is HttpException) + if (it.code() == HttpErrors.NOT_FOUND) + Timber.e(it, "No tax for this event") + else + Timber.e(it, "Error fetching tax details") + }) + } + fun isConnected(): Boolean = mutableConnectionLiveData.value ?: false fun totalTicketsEmpty(ticketIdAndQty: List>): Boolean { diff --git a/app/src/main/java/org/fossasia/openevent/general/utils/HttpErrors.kt b/app/src/main/java/org/fossasia/openevent/general/utils/HttpErrors.kt index 131cd44e9a..a369f1a2d8 100644 --- a/app/src/main/java/org/fossasia/openevent/general/utils/HttpErrors.kt +++ b/app/src/main/java/org/fossasia/openevent/general/utils/HttpErrors.kt @@ -3,4 +3,5 @@ package org.fossasia.openevent.general.utils object HttpErrors { const val CONFLICT = 409 const val UNAUTHORIZED = 401 + const val NOT_FOUND = 404 } diff --git a/app/src/main/res/layout/fragment_attendee.xml b/app/src/main/res/layout/fragment_attendee.xml index 8859fb68a6..8f43e5fad7 100644 --- a/app/src/main/res/layout/fragment_attendee.xml +++ b/app/src/main/res/layout/fragment_attendee.xml @@ -159,10 +159,65 @@ + + + + + + + + + + + + + + + - - - - + android:layout_marginBottom="@dimen/layout_margin_medium" + android:background="@drawable/filled_border" + android:orientation="vertical" + android:padding="@dimen/padding_medium" + android:visibility="gone" + tools:visibility="visible"> + + + + + + + + + + + + Used Eventyay before? for fast and easy ordering Please sign in to order the ticket + Total: + Tax: Logged in Automatically! From a52d37f69d4bd11d803a7c1e6103ce0d5cdf4dfe Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Wed, 31 Jul 2019 10:44:33 +0530 Subject: [PATCH 06/53] chore(deps): bump leakcanary-android from 2.0-alpha-3 to 2.0-beta-1 (#2217) Bumps [leakcanary-android](https://github.com/square/leakcanary) from 2.0-alpha-3 to 2.0-beta-1. - [Release notes](https://github.com/square/leakcanary/releases) - [Changelog](https://github.com/square/leakcanary/blob/master/docs/changelog.md) - [Commits](https://github.com/square/leakcanary/commits) Signed-off-by: dependabot-preview[bot] --- app/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/build.gradle b/app/build.gradle index e6d1ad2062..865540c7df 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -215,7 +215,7 @@ dependencies { testImplementation 'com.github.iamareebjamal:stetho-noop:1.2.1' //LeakCanary - debugImplementation 'com.squareup.leakcanary:leakcanary-android:2.0-alpha-3' + debugImplementation 'com.squareup.leakcanary:leakcanary-android:2.0-beta-1' // Paging implementation "androidx.paging:paging-runtime:$paging_version" From e6100b098ce1f22f86de9007eadf9a48fdf39e4e Mon Sep 17 00:00:00 2001 From: Harshit Khandelwal Date: Wed, 31 Jul 2019 11:07:44 +0530 Subject: [PATCH 07/53] fix: Date format and feedback button style (#2213) (#2214) --- .../java/org/fossasia/openevent/general/event/EventUtils.kt | 2 +- app/src/main/res/layout/content_event.xml | 3 +-- .../org/fossasia/openevent/general/event/EventUtilsTest.kt | 6 +++--- 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/app/src/main/java/org/fossasia/openevent/general/event/EventUtils.kt b/app/src/main/java/org/fossasia/openevent/general/event/EventUtils.kt index 2f6cec4669..89180cf736 100644 --- a/app/src/main/java/org/fossasia/openevent/general/event/EventUtils.kt +++ b/app/src/main/java/org/fossasia/openevent/general/event/EventUtils.kt @@ -51,7 +51,7 @@ object EventUtils { } fun getFormattedDate(date: ZonedDateTime): String { - val dateFormat: DateTimeFormatter = DateTimeFormatter.ofPattern("EEEE, MMM d, y") + val dateFormat: DateTimeFormatter = DateTimeFormatter.ofPattern("EEEE, MMMM d, y") return try { dateFormat.format(date) } catch (e: IllegalArgumentException) { diff --git a/app/src/main/res/layout/content_event.xml b/app/src/main/res/layout/content_event.xml index 1aae5762d3..4305d0638a 100644 --- a/app/src/main/res/layout/content_event.xml +++ b/app/src/main/res/layout/content_event.xml @@ -557,8 +557,7 @@