|
|
|
|
@ -17,9 +17,11 @@ import androidx.fragment.app.Fragment
|
|
|
|
|
import androidx.navigation.fragment.navArgs
|
|
|
|
|
import androidx.recyclerview.widget.LinearLayoutManager
|
|
|
|
|
import com.cyb3rko.techniklogger.*
|
|
|
|
|
import com.cyb3rko.techniklogger.data.objects.Member
|
|
|
|
|
import com.cyb3rko.techniklogger.data.objects.Mission
|
|
|
|
|
import com.cyb3rko.techniklogger.data.ParseController
|
|
|
|
|
import com.cyb3rko.techniklogger.databinding.FragmentMissionBinding
|
|
|
|
|
import com.cyb3rko.techniklogger.data.Participation
|
|
|
|
|
import com.cyb3rko.techniklogger.data.objects.Participation
|
|
|
|
|
import com.cyb3rko.techniklogger.recycler.ParticipationAdapter
|
|
|
|
|
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
|
|
|
|
import com.google.android.material.timepicker.MaterialTimePicker
|
|
|
|
|
@ -27,7 +29,6 @@ import com.google.android.material.timepicker.TimeFormat
|
|
|
|
|
import com.parse.ParseObject
|
|
|
|
|
import es.dmoral.toasty.Toasty
|
|
|
|
|
import java.sql.Time
|
|
|
|
|
import java.text.DecimalFormat
|
|
|
|
|
|
|
|
|
|
@SuppressLint("SetTextI18n")
|
|
|
|
|
class MissionFragment : Fragment() {
|
|
|
|
|
@ -35,10 +36,10 @@ class MissionFragment : Fragment() {
|
|
|
|
|
private lateinit var myContext: Context
|
|
|
|
|
private val args: MissionFragmentArgs by navArgs()
|
|
|
|
|
|
|
|
|
|
private lateinit var technikerAdapter: ParticipationAdapter
|
|
|
|
|
private lateinit var participationAdapter: ParticipationAdapter
|
|
|
|
|
private var adminMode = false
|
|
|
|
|
private var objectId = ""
|
|
|
|
|
private var dauer = ""
|
|
|
|
|
private var duration = 0f
|
|
|
|
|
private lateinit var sharedPref: SharedPreferences
|
|
|
|
|
private var time = ""
|
|
|
|
|
|
|
|
|
|
@ -58,9 +59,9 @@ class MissionFragment : Fragment() {
|
|
|
|
|
|
|
|
|
|
objectId = args.objectId
|
|
|
|
|
|
|
|
|
|
technikerAdapter = ParticipationAdapter {
|
|
|
|
|
participationAdapter = ParticipationAdapter {
|
|
|
|
|
if (adminMode || it.name == sharedPref.getString(NAME, "")) {
|
|
|
|
|
val uhrzeit = if (it.uhrzeit == "0") time else it.uhrzeit
|
|
|
|
|
val uhrzeit = if (it.time == "0") time else it.time
|
|
|
|
|
val message = "<strong><u>Arbeitszeit:</u></strong><br/>$uhrzeit Uhr<br/><br/>" +
|
|
|
|
|
"Wie möchtest du diesen Eintrag bearbeiten?"
|
|
|
|
|
|
|
|
|
|
@ -81,8 +82,8 @@ class MissionFragment : Fragment() {
|
|
|
|
|
var minute: String
|
|
|
|
|
var hoursInMillis: Long
|
|
|
|
|
var minutesInMillis: Long
|
|
|
|
|
if (it.uhrzeit != "0") {
|
|
|
|
|
val times = it.uhrzeit.split(" - ")
|
|
|
|
|
if (it.time != "0") {
|
|
|
|
|
val times = it.time.split(" - ")
|
|
|
|
|
builder.setHour(times[0].split(":")[0].toInt())
|
|
|
|
|
.setMinute(times[0].split(":")[1].toInt())
|
|
|
|
|
builder2.setHour(times[1].split(":")[0].toInt())
|
|
|
|
|
@ -127,32 +128,20 @@ class MissionFragment : Fragment() {
|
|
|
|
|
return@addOnPositiveButtonClickListener
|
|
|
|
|
}
|
|
|
|
|
tempTime += "${hour}:${minute}"
|
|
|
|
|
it.uhrzeit = tempTime
|
|
|
|
|
val tempDauer = DecimalFormat("#.#").format((time2.time - time1.time) / 3600 / 1000.toFloat())
|
|
|
|
|
it.dauer = tempDauer.replace(",", ".")
|
|
|
|
|
it.setTime(tempTime)
|
|
|
|
|
val tempDauer = (time2.time - time1.time) / 3600 / 1000.toFloat()
|
|
|
|
|
it.setDuration(tempDauer)
|
|
|
|
|
|
|
|
|
|
if (it.teilnahmeKey != "0") {
|
|
|
|
|
val dauerFloat = it.dauer.toFloat()
|
|
|
|
|
ParseObject.createWithoutData(CLASS_TEILNAHME, it.teilnahmeKey).apply {
|
|
|
|
|
put(COLUMN_EINSATZ_DAUER, dauerFloat)
|
|
|
|
|
put(COLUMN_EINSATZ_UHRZEIT, it.uhrzeit)
|
|
|
|
|
saveInBackground()
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
ParseController.fetchParticipation(objectId, it.objectId) { entry, e ->
|
|
|
|
|
if (e == null) {
|
|
|
|
|
it.teilnahmeKey = entry!!.objectId
|
|
|
|
|
val dauerFloat = it.dauer.toFloat()
|
|
|
|
|
ParseObject.createWithoutData(CLASS_TEILNAHME, it.teilnahmeKey).apply {
|
|
|
|
|
put(COLUMN_TEILNAHME_DAUER, dauerFloat)
|
|
|
|
|
put(COLUMN_TEILNAHME_UHRZEIT, it.uhrzeit)
|
|
|
|
|
saveInBackground {
|
|
|
|
|
loadData()
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
it.apply {
|
|
|
|
|
setDuration(duration)
|
|
|
|
|
setTime(it.time)
|
|
|
|
|
saveInBackground {
|
|
|
|
|
if (it == null) {
|
|
|
|
|
Toasty.success(myContext, "Arbeitszeit geändert").show()
|
|
|
|
|
loadParticipations()
|
|
|
|
|
} else {
|
|
|
|
|
Toasty.error(myContext, "Fehler bei Techniker-Abfrage").show()
|
|
|
|
|
Log.e("TechnikLogger.TechSuche", e.message.toString())
|
|
|
|
|
Toasty.error(myContext, "Fehler bei Speicherung").show()
|
|
|
|
|
Log.e("TechnikLogger.TechEdit", it.message.toString())
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
@ -160,31 +149,16 @@ class MissionFragment : Fragment() {
|
|
|
|
|
activity?.let { it1 -> picker.show(it1.supportFragmentManager, picker.tag) }
|
|
|
|
|
}
|
|
|
|
|
.setNegativeButton("Entfernen") { _, _ ->
|
|
|
|
|
val list = technikerAdapter.currentList.toMutableList()
|
|
|
|
|
val list = participationAdapter.currentList.toMutableList()
|
|
|
|
|
list.remove(it)
|
|
|
|
|
technikerAdapter.submitList(list)
|
|
|
|
|
participationAdapter.submitList(list)
|
|
|
|
|
updateTechnikerCount(list.size)
|
|
|
|
|
if (list.isEmpty()) {
|
|
|
|
|
showDivider(false)
|
|
|
|
|
}
|
|
|
|
|
if (it.teilnahmeKey != "0") {
|
|
|
|
|
ParseObject.createWithoutData(CLASS_TEILNAHME, it.teilnahmeKey).deleteInBackground()
|
|
|
|
|
} else {
|
|
|
|
|
ParseController.fetchParticipation(objectId, it.objectId) { entry, e ->
|
|
|
|
|
if (e == null) {
|
|
|
|
|
entry!!.deleteInBackground {
|
|
|
|
|
if (it != null) {
|
|
|
|
|
Toasty.error(myContext, "Fehler bei Techniker-Löschung").show()
|
|
|
|
|
Log.e("TechnikLogger.TechLösch", it.message.toString())
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
Toasty.error(myContext, "Fehler bei Techniker-Abfrage").show()
|
|
|
|
|
Log.e("TechnikLogger.TechSuche", e.message.toString())
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (technikerAdapter.currentList.size == 0) showDivider(false)
|
|
|
|
|
Participation.emptyObject(it.objectId).deleteInBackground()
|
|
|
|
|
if (participationAdapter.currentList.size == 0) showDivider(false)
|
|
|
|
|
loadParticipations()
|
|
|
|
|
}
|
|
|
|
|
.show()
|
|
|
|
|
}
|
|
|
|
|
@ -193,7 +167,7 @@ class MissionFragment : Fragment() {
|
|
|
|
|
loadData()
|
|
|
|
|
|
|
|
|
|
binding.recyclerView.layoutManager = LinearLayoutManager(myContext)
|
|
|
|
|
binding.recyclerView.adapter = technikerAdapter
|
|
|
|
|
binding.recyclerView.adapter = participationAdapter
|
|
|
|
|
|
|
|
|
|
binding.addButton.setOnClickListener {
|
|
|
|
|
val name = sharedPref.getString(NAME, "invalid")!!
|
|
|
|
|
@ -216,7 +190,7 @@ class MissionFragment : Fragment() {
|
|
|
|
|
ParseController.fetchParticipations(objectId, false) { entries, e ->
|
|
|
|
|
if (e == null) {
|
|
|
|
|
ParseObject.deleteAllInBackground(entries)
|
|
|
|
|
technikerAdapter.submitList(listOf())
|
|
|
|
|
participationAdapter.submitList(listOf())
|
|
|
|
|
showDivider(false)
|
|
|
|
|
updateTechnikerCount(0)
|
|
|
|
|
} else {
|
|
|
|
|
@ -249,44 +223,17 @@ class MissionFragment : Fragment() {
|
|
|
|
|
private fun loadData() {
|
|
|
|
|
ParseController.fetchMission(objectId) { mission, e ->
|
|
|
|
|
if (e == null) {
|
|
|
|
|
binding.titleView.text = mission!!.getString(COLUMN_EINSATZ_NAME)
|
|
|
|
|
binding.locationView.text = mission.getString(COLUMN_EINSATZ_ORT)
|
|
|
|
|
binding.titleView.text = mission!!.name
|
|
|
|
|
binding.locationView.text = mission.location
|
|
|
|
|
val dates = mission.getString(COLUMN_EINSATZ_DATUM)!!.split(",")
|
|
|
|
|
val dateParts = dates[0].split(".")
|
|
|
|
|
val date = "${dateParts[2]}.${dateParts[1]}.${dateParts[0]}"
|
|
|
|
|
dauer = mission.getNumber(COLUMN_EINSATZ_DAUER)!!.toString()
|
|
|
|
|
duration = mission.duration
|
|
|
|
|
if (dates.size > 1) time = dates[1]
|
|
|
|
|
val time = if (dates.size > 1) ", ${dates[1]}" else ", $dauer h"
|
|
|
|
|
val time = if (dates.size > 1) ", ${dates[1]}" else ", $duration h"
|
|
|
|
|
binding.dateView.text = date + time
|
|
|
|
|
|
|
|
|
|
ParseController.fetchParticipations(objectId, true) { entries, e2 ->
|
|
|
|
|
if (e2 == null) {
|
|
|
|
|
if (entries.isNotEmpty()) {
|
|
|
|
|
val techniker = mutableListOf<Participation>()
|
|
|
|
|
entries.forEach {
|
|
|
|
|
val teilnehmenderTechniker = it.getParseObject(COLUMN_TEILNAHME_VON)!!
|
|
|
|
|
val dauerEntry = it.getNumber(COLUMN_EINSATZ_DAUER)!!
|
|
|
|
|
val dauer = if (dauerEntry == 0) mission.getNumber(COLUMN_TEILNAHME_DAUER)!!.toString() else dauerEntry.toString()
|
|
|
|
|
val time = it.getString(COLUMN_EINSATZ_UHRZEIT)!!
|
|
|
|
|
techniker.add(
|
|
|
|
|
Participation(
|
|
|
|
|
dauer,
|
|
|
|
|
teilnehmenderTechniker.getString(COLUMN_EINSATZ_NAME)!!,
|
|
|
|
|
teilnehmenderTechniker.objectId,
|
|
|
|
|
it.objectId,
|
|
|
|
|
time
|
|
|
|
|
)
|
|
|
|
|
)
|
|
|
|
|
}
|
|
|
|
|
technikerAdapter.submitList(techniker)
|
|
|
|
|
updateTechnikerCount(techniker.size)
|
|
|
|
|
showDivider()
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
Toasty.error(myContext, "Fehler bei Teilnehmer-Abfrage").show()
|
|
|
|
|
Log.e("TechnikLogger.TechSuche", e2.message.toString())
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
loadParticipations()
|
|
|
|
|
} else {
|
|
|
|
|
if (e.message != null) {
|
|
|
|
|
if (e.message != "results not cached") {
|
|
|
|
|
@ -301,9 +248,28 @@ class MissionFragment : Fragment() {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private fun technikerExists(name: String): Boolean {
|
|
|
|
|
for (techniker in technikerAdapter.currentList) {
|
|
|
|
|
if (name == techniker.name) {
|
|
|
|
|
private fun loadParticipations() {
|
|
|
|
|
ParseController.fetchParticipations(objectId, true) { participations, e2 ->
|
|
|
|
|
if (e2 == null) {
|
|
|
|
|
if (participations.isNotEmpty()) {
|
|
|
|
|
participations.forEach {
|
|
|
|
|
if (it.duration == 0f) it.setDuration(duration)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
participationAdapter.submitList(participations)
|
|
|
|
|
updateTechnikerCount(participations.size)
|
|
|
|
|
showDivider()
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
Toasty.error(myContext, "Fehler bei Teilnehmer-Abfrage").show()
|
|
|
|
|
Log.e("TechnikLogger.TechSuche", e2.message.toString())
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private fun memberExists(name: String): Boolean {
|
|
|
|
|
for (member in participationAdapter.currentList) {
|
|
|
|
|
if (name == member.name) {
|
|
|
|
|
return true
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
@ -323,21 +289,17 @@ class MissionFragment : Fragment() {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private fun selfAdd(name: String, skip: Boolean = false) {
|
|
|
|
|
if (!technikerExists(name)) {
|
|
|
|
|
if (!memberExists(name)) {
|
|
|
|
|
if (!skip) {
|
|
|
|
|
MaterialAlertDialogBuilder(myContext)
|
|
|
|
|
.setMessage("Möchtest du dich als involvierter Techniker eintragen?")
|
|
|
|
|
.setPositiveButton("Ja") { _, _ ->
|
|
|
|
|
val technikerObject = ParseObject.createWithoutData(CLASS_TECHNIKER, sharedPref.getString(TECHNIKER_ID, "")!!)
|
|
|
|
|
technikerObject.put(COLUMN_TECHNIKER_NAME, sharedPref.getString(NAME, "")!!)
|
|
|
|
|
addTechniker(listOf(technikerObject))
|
|
|
|
|
addTechniker(listOf(sharedPref.getString(TECHNIKER_ID, "")!!))
|
|
|
|
|
}
|
|
|
|
|
.setNegativeButton("Abbrechen", null)
|
|
|
|
|
.show()
|
|
|
|
|
} else {
|
|
|
|
|
val technikerObject = ParseObject.createWithoutData(CLASS_TECHNIKER, sharedPref.getString(TECHNIKER_ID, "")!!)
|
|
|
|
|
technikerObject.put(COLUMN_TECHNIKER_NAME, sharedPref.getString(NAME, "")!!)
|
|
|
|
|
addTechniker(listOf(technikerObject))
|
|
|
|
|
addTechniker(listOf(sharedPref.getString(TECHNIKER_ID, "")!!))
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
MaterialAlertDialogBuilder(myContext)
|
|
|
|
|
@ -348,11 +310,11 @@ class MissionFragment : Fragment() {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private fun otherAdd() {
|
|
|
|
|
ParseController.fetchTechniker { techniker, names, e ->
|
|
|
|
|
ParseController.fetchMembers { members, memberNames, e ->
|
|
|
|
|
if (e == null) {
|
|
|
|
|
val currentSelection = BooleanArray(techniker.size)
|
|
|
|
|
names.forEachIndexed { index, name ->
|
|
|
|
|
technikerAdapter.currentList.forEach {
|
|
|
|
|
val currentSelection = BooleanArray(members.size)
|
|
|
|
|
memberNames.forEachIndexed { index, name ->
|
|
|
|
|
participationAdapter.currentList.forEach {
|
|
|
|
|
if (name == it.name) {
|
|
|
|
|
currentSelection[index] = true
|
|
|
|
|
}
|
|
|
|
|
@ -360,16 +322,16 @@ class MissionFragment : Fragment() {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
val checkedNames = mutableListOf<String>()
|
|
|
|
|
|
|
|
|
|
val previousSelection = currentSelection.toList()
|
|
|
|
|
|
|
|
|
|
MaterialAlertDialogBuilder(myContext)
|
|
|
|
|
.setMultiChoiceItems(names.toTypedArray(), currentSelection) { dialogInterface, index, isChecked ->
|
|
|
|
|
val name = names[index]
|
|
|
|
|
.setMultiChoiceItems(memberNames.toTypedArray(), currentSelection) { dialogInterface, index, isChecked ->
|
|
|
|
|
println(memberNames[index])
|
|
|
|
|
val name = memberNames[index]
|
|
|
|
|
if (previousSelection[index]) {
|
|
|
|
|
var disabledIndex = -1
|
|
|
|
|
val listView = (dialogInterface as AlertDialog).listView
|
|
|
|
|
while (disabledIndex + 1 < names.size && (listView[disabledIndex + 1] as TextView).text != name) {
|
|
|
|
|
while (disabledIndex + 1 < memberNames.size && (listView[disabledIndex + 1] as TextView).text != name) {
|
|
|
|
|
disabledIndex++
|
|
|
|
|
}
|
|
|
|
|
if (disabledIndex != -1) (listView[disabledIndex + 1] as CheckedTextView).isChecked = true
|
|
|
|
|
@ -384,22 +346,15 @@ class MissionFragment : Fragment() {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
.setPositiveButton("Hinzufügen") { _, _ ->
|
|
|
|
|
val newNameObjects = mutableListOf<ParseObject>()
|
|
|
|
|
techniker.forEach {
|
|
|
|
|
if (checkedNames.contains(it.getString(COLUMN_TECHNIKER_NAME)!!)) {
|
|
|
|
|
newNameObjects.add(it)
|
|
|
|
|
val newParticipationMemberIds = mutableListOf<String>()
|
|
|
|
|
members.forEach {
|
|
|
|
|
if (checkedNames.contains(it.name)) {
|
|
|
|
|
newParticipationMemberIds.add(it.objectId)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
addTechniker(newNameObjects)
|
|
|
|
|
addTechniker(newParticipationMemberIds)
|
|
|
|
|
}
|
|
|
|
|
.create().apply {
|
|
|
|
|
setOnShowListener {
|
|
|
|
|
val dialogList = (it as AlertDialog).listView
|
|
|
|
|
currentSelection.forEachIndexed { index, b ->
|
|
|
|
|
if (b) dialogList[index].isEnabled = false
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}.show()
|
|
|
|
|
.show()
|
|
|
|
|
} else {
|
|
|
|
|
Toasty.error(myContext, "Fehler bei Techniker-Suche").show()
|
|
|
|
|
Log.e("TechnikLogger.TechSuche", e.message.toString())
|
|
|
|
|
@ -407,16 +362,19 @@ class MissionFragment : Fragment() {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private fun addTechniker(newTechniker: List<ParseObject>) {
|
|
|
|
|
val project = ParseObject.createWithoutData(CLASS_EINSATZ, objectId)
|
|
|
|
|
val entryList = mutableListOf<ParseObject>()
|
|
|
|
|
newTechniker.forEach {
|
|
|
|
|
val entryObject = ParseObject(CLASS_TEILNAHME)
|
|
|
|
|
entryObject.put(COLUMN_TEILNAHME_VON, it)
|
|
|
|
|
entryObject.put(COLUMN_TEILNAHME_AN, project)
|
|
|
|
|
entryList.add(entryObject)
|
|
|
|
|
private fun addTechniker(memberIds: List<String>) {
|
|
|
|
|
val members = mutableListOf<Member>()
|
|
|
|
|
memberIds.forEach { members.add(Member.emptyObject(it)) }
|
|
|
|
|
val mission = Mission.emptyObject(objectId)
|
|
|
|
|
val newParticipations = mutableListOf<Participation>()
|
|
|
|
|
members.forEach {
|
|
|
|
|
Participation().apply {
|
|
|
|
|
put(Participation.COLUMN_BY, it)
|
|
|
|
|
put(Participation.COLUMN_IN, mission)
|
|
|
|
|
newParticipations.add(this)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
ParseObject.saveAllInBackground(entryList) {
|
|
|
|
|
ParseObject.saveAllInBackground(newParticipations) {
|
|
|
|
|
if (it == null) {
|
|
|
|
|
loadData()
|
|
|
|
|
} else {
|
|
|
|
|
@ -435,7 +393,7 @@ class MissionFragment : Fragment() {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private fun emptyCheck() {
|
|
|
|
|
if (technikerAdapter.currentList.isEmpty()) {
|
|
|
|
|
if (participationAdapter.currentList.isEmpty()) {
|
|
|
|
|
binding.divider.visibility = View.GONE
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|