more codes
This commit is contained in:
@@ -0,0 +1,98 @@
|
||||
package com.android.trisolarisserver.controller
|
||||
|
||||
import com.android.trisolarisserver.component.EmailStorage
|
||||
import com.android.trisolarisserver.component.PropertyAccess
|
||||
import com.android.trisolarisserver.db.repo.InboundEmailRepo
|
||||
import com.android.trisolarisserver.models.booking.InboundEmail
|
||||
import com.android.trisolarisserver.models.booking.InboundEmailStatus
|
||||
import com.android.trisolarisserver.models.property.Role
|
||||
import com.android.trisolarisserver.repo.PropertyRepo
|
||||
import com.android.trisolarisserver.security.MyPrincipal
|
||||
import com.android.trisolarisserver.service.EmailIngestionService
|
||||
import org.apache.pdfbox.pdmodel.PDDocument
|
||||
import org.apache.pdfbox.text.PDFTextStripper
|
||||
import org.springframework.http.HttpStatus
|
||||
import org.springframework.security.core.annotation.AuthenticationPrincipal
|
||||
import org.springframework.web.bind.annotation.PathVariable
|
||||
import org.springframework.web.bind.annotation.PostMapping
|
||||
import org.springframework.web.bind.annotation.RequestMapping
|
||||
import org.springframework.web.bind.annotation.RequestParam
|
||||
import org.springframework.web.bind.annotation.ResponseStatus
|
||||
import org.springframework.web.bind.annotation.RestController
|
||||
import org.springframework.web.multipart.MultipartFile
|
||||
import org.springframework.web.server.ResponseStatusException
|
||||
import java.time.OffsetDateTime
|
||||
import java.util.UUID
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/properties/{propertyId}/inbound-emails")
|
||||
class InboundEmailManual(
|
||||
private val propertyAccess: PropertyAccess,
|
||||
private val propertyRepo: PropertyRepo,
|
||||
private val inboundEmailRepo: InboundEmailRepo,
|
||||
private val emailStorage: EmailStorage,
|
||||
private val emailIngestionService: EmailIngestionService
|
||||
) {
|
||||
|
||||
@PostMapping("/manual")
|
||||
@ResponseStatus(HttpStatus.CREATED)
|
||||
fun uploadManualPdf(
|
||||
@PathVariable propertyId: UUID,
|
||||
@AuthenticationPrincipal principal: MyPrincipal?,
|
||||
@RequestParam("file") file: MultipartFile
|
||||
): ManualInboundResponse {
|
||||
requirePrincipal(principal)
|
||||
propertyAccess.requireMember(propertyId, principal!!.userId)
|
||||
propertyAccess.requireAnyRole(propertyId, principal.userId, Role.ADMIN, Role.MANAGER)
|
||||
|
||||
if (file.isEmpty) {
|
||||
throw ResponseStatusException(HttpStatus.BAD_REQUEST, "File is empty")
|
||||
}
|
||||
val contentType = file.contentType
|
||||
if (contentType != null && !contentType.equals("application/pdf", ignoreCase = true)) {
|
||||
throw ResponseStatusException(HttpStatus.BAD_REQUEST, "Only PDF is supported")
|
||||
}
|
||||
|
||||
val property = propertyRepo.findById(propertyId).orElseThrow {
|
||||
ResponseStatusException(HttpStatus.NOT_FOUND, "Property not found")
|
||||
}
|
||||
|
||||
val bytes = file.bytes
|
||||
val pdfPath = emailStorage.storeUploadedPdf(propertyId, file.originalFilename, bytes)
|
||||
val text = extractPdfText(bytes)
|
||||
|
||||
val inbound = InboundEmail(
|
||||
property = property,
|
||||
messageId = "manual-${UUID.randomUUID()}",
|
||||
subject = file.originalFilename ?: "manual-upload",
|
||||
fromAddress = null,
|
||||
receivedAt = OffsetDateTime.now(),
|
||||
status = InboundEmailStatus.PENDING,
|
||||
rawPdfPath = pdfPath
|
||||
)
|
||||
|
||||
inboundEmailRepo.save(inbound)
|
||||
emailIngestionService.ingestManualPdf(property, inbound, text)
|
||||
return ManualInboundResponse(inboundId = inbound.id!!)
|
||||
}
|
||||
|
||||
private fun extractPdfText(bytes: ByteArray): String {
|
||||
return try {
|
||||
PDDocument.load(bytes).use { doc ->
|
||||
PDFTextStripper().getText(doc)
|
||||
}
|
||||
} catch (_: Exception) {
|
||||
""
|
||||
}
|
||||
}
|
||||
|
||||
private fun requirePrincipal(principal: MyPrincipal?) {
|
||||
if (principal == null) {
|
||||
throw ResponseStatusException(HttpStatus.UNAUTHORIZED, "Missing principal")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
data class ManualInboundResponse(
|
||||
val inboundId: UUID
|
||||
)
|
||||
Reference in New Issue
Block a user