Browse Source

Merge remote-tracking branch 'origin/master'

# Conflicts:
#	src/main/java/com/ffii/fpsms/modules/deliveryOrder/entity/DoPickOrderRecordRepository.kt
master
CANCERYS\kw093 1 month ago
parent
commit
4aaf013712
6 changed files with 282 additions and 106 deletions
  1. +5
    -0
      src/main/java/com/ffii/fpsms/modules/deliveryOrder/entity/DoPickOrderRecord.kt
  2. +8
    -0
      src/main/java/com/ffii/fpsms/modules/deliveryOrder/entity/DoPickOrderRecordRepository.kt
  3. +19
    -2
      src/main/java/com/ffii/fpsms/modules/deliveryOrder/entity/DoPickOrderRepository.kt
  4. +239
    -103
      src/main/java/com/ffii/fpsms/modules/deliveryOrder/service/DeliveryOrderService.kt
  5. +2
    -0
      src/main/java/com/ffii/fpsms/modules/pickOrder/service/PickOrderService.kt
  6. +9
    -1
      src/main/java/com/ffii/fpsms/modules/stock/service/StockOutLineService.kt

+ 5
- 0
src/main/java/com/ffii/fpsms/modules/deliveryOrder/entity/DoPickOrderRecord.kt View File

@@ -33,6 +33,9 @@ class DoPickOrderRecord {
@Column(name = "delivery_order_code", length = 50)
var deliveryOrderCode: String? = null

@Column(name = "deliveryNoteCode", length = 50)
var deliveryNoteCode: String? = null

@Column(name = "loading_sequence")
var loadingSequence: Int? = null
@Enumerated(EnumType.STRING)
@@ -117,6 +120,7 @@ var handlerName: String? = null
modifiedBy: String? = null,
pickOrderCode: String? = null,
deliveryOrderCode: String? = null,
deliveryNoteCode: String? = null,
loadingSequence: Int? = null,
) {
this.recordId= recordId
@@ -140,6 +144,7 @@ var handlerName: String? = null
this.modifiedBy = modifiedBy
this.pickOrderCode = pickOrderCode
this.deliveryOrderCode = deliveryOrderCode
this.deliveryNoteCode = deliveryNoteCode
this.loadingSequence = loadingSequence
}
}

+ 8
- 0
src/main/java/com/ffii/fpsms/modules/deliveryOrder/entity/DoPickOrderRecordRepository.kt View File

@@ -16,5 +16,13 @@ import java.time.LocalDate
interface DoPickOrderRecordRepository : JpaRepository<DoPickOrderRecord, Long> {
fun findByPickOrderId(pickOrderId: Long): List<DoPickOrderRecord>
fun findByTicketNoStartingWith(ticketPrefix: String): List<DoPickOrderRecord>

@Query("""
SELECT dpor.deliveryNoteCode from DoPickOrderRecord dpor
WHERE dpor.deliveryNoteCode like :prefix%
ORDER BY dpor.deliveryNoteCode desc limit 1
""")
fun findLatestDeliveryNoteCodeByPrefix(prefix: String): String?

fun findByStoreIdAndRequiredDeliveryDateAndTicketStatusIn(storeId: String, requiredDeliveryDate: LocalDate, ticketStatus: List<DoPickOrderStatus>): List<DoPickOrderRecord>
}

+ 19
- 2
src/main/java/com/ffii/fpsms/modules/deliveryOrder/entity/DoPickOrderRepository.kt View File

@@ -31,7 +31,24 @@ fun findByStoreIdAndRequiredDeliveryDateAndTicketStatusIn(
status: List<DoPickOrderStatus>
): List<DoPickOrder>

@Query("SELECT d FROM DoPickOrder d WHERE d.deleted = false ORDER BY d.requiredDeliveryDate ASC, d.truckDepartureTime ASC")
fun findAllByDeletedFalseOrderByTicketReleaseTimeDesc(): List<DoPickOrder>
@Query("SELECT d FROM DoPickOrder d WHERE d.deleted = false ORDER BY d.requiredDeliveryDate ASC, d.truckDepartureTime ASC")
fun findAllByDeletedFalseOrderByTicketReleaseTimeDesc(): List<DoPickOrder>

@Query("""
SELECT COUNT(DISTINCT pol.id)
FROM PickOrderLine pol
WHERE pol.pickOrder.id IN (
SELECT DISTINCT dpol2.pickOrderId
FROM DoPickOrderLine dpol2
WHERE dpol2.doPickOrderId IN (
SELECT DISTINCT dpol1.doPickOrderId
FROM DoPickOrderLine dpol1
WHERE dpol1.pickOrderId = :pickOrderId
AND dpol1.deleted = false
)
AND dpol2.deleted = false
)
AND pol.deleted = false
""")
fun countPickOrderLinesByRelatedPickOrderId(@Param("pickOrderId") pickOrderId: Long): Long
}

+ 239
- 103
src/main/java/com/ffii/fpsms/modules/deliveryOrder/service/DeliveryOrderService.kt View File

@@ -670,133 +670,269 @@ open class DeliveryOrderService(
}


//Delivery Note
@Throws(IOException::class)
@Transactional
open fun exportDeliveryNote(request: ExportDeliveryNoteRequest): Map<String, Any> {
val DELIVERYNOTE_PDF = "DeliveryNote/DeliveryNotePDF.jrxml"
val resource = ClassPathResource(DELIVERYNOTE_PDF)
if (!resource.exists()) {
throw FileNotFoundException("Report file not fount: $DELIVERYNOTE_PDF")
}
val doPickOrder = doPickOrderRepository.findById(request.doPickOrderId).orElseThrow {
NoSuchElementException("DoPickOrder not found with ID: ${request.doPickOrderId}")
}
val pickOrderIds = if (doPickOrder.pickOrderId != null) {
// Single pick order case
listOf(doPickOrder.pickOrderId!!)
} else {
// Merged pick orders case - get from DoPickOrderLine
val doPickOrderLines = doPickOrderLineRepository.findByDoPickOrderIdAndDeletedFalse(doPickOrder.id!!)
val orderIds = doPickOrderLines.mapNotNull { it.pickOrderId }.distinct()
// Delivery Note
@Throws(IOException::class)
@Transactional
open fun exportDeliveryNote(request: ExportDeliveryNoteRequest): Map<String, Any> {

if (orderIds.isEmpty()) {
throw IllegalStateException("DoPickOrder ${request.doPickOrderId} has no associated pick orders")
}
orderIds
}
// INPUT STREAM SETUP
val DELIVERYNOTE_PDF = "DeliveryNote/DeliveryNotePDF.jrxml"
val resource = ClassPathResource(DELIVERYNOTE_PDF)
if (!resource.exists()) {
throw FileNotFoundException("Report file not found: $DELIVERYNOTE_PDF")
}

val deliveryOrderIds = if (doPickOrder.doOrderId != null) {
// Single delivery order case
listOf(doPickOrder.doOrderId!!)
} else {
// Merged delivery orders case - get from DoPickOrderLine
val doPickOrderLines = doPickOrderLineRepository.findByDoPickOrderIdAndDeletedFalse(doPickOrder.id!!)
val orderIds = doPickOrderLines.mapNotNull { it.doOrderId }.distinct()
val inputStream = resource.inputStream
val deliveryNote = JasperCompileManager.compileReport(inputStream)

if (orderIds.isEmpty()) {
throw IllegalStateException("DoPickOrder ${request.doPickOrderId} has no associated delivery orders")
}
orderIds
val fields = mutableListOf<MutableMap<String, Any>>()
val params = mutableMapOf<String, Any>()

// DRAFT & RECORD SEPARATION
if (request.isDraft) {
return exportDeliveryNoteFromDraft(request, deliveryNote, fields, params)
} else {
return exportDeliveryNoteFromRecord(request, deliveryNote, fields, params)
}
}

// DRAFT
private fun exportDeliveryNoteFromDraft(
request: ExportDeliveryNoteRequest,
deliveryNote: net.sf.jasperreports.engine.JasperReport,
fields: MutableList<MutableMap<String, Any>>,
params: MutableMap<String, Any>
): Map<String, Any> {
val doPickOrder = doPickOrderRepository.findById(request.doPickOrderId).orElseThrow {
NoSuchElementException("DoPickOrder not found with ID: ${request.doPickOrderId}")
}

val pickOrderIds = if (doPickOrder.pickOrderId != null) {
// SINGLE DELIVERY ORDER
listOf(doPickOrder.pickOrderId!!)
} else {
// MERGED DELIVERY ORDERS (DOPICKORDERLINE)
val doPickOrderLines = doPickOrderLineRepository.findByDoPickOrderIdAndDeletedFalse(doPickOrder.id!!)
val orderIds = doPickOrderLines.mapNotNull { it.pickOrderId }.distinct()

if (orderIds.isEmpty()) {
throw IllegalStateException("DoPickOrder ${request.doPickOrderId} has no associated pick orders")
}
orderIds
}

val deliveryNoteInfo = deliveryOrderIds.flatMap { deliveryOrderId ->
deliveryOrderRepository.findDeliveryOrderInfoById(deliveryOrderId)
}.toMutableList()
val deliveryOrderIds = if (doPickOrder.doOrderId != null) {
// SINGLE DELIVERY ORDER
listOf(doPickOrder.doOrderId!!)
} else {
// MERGED DELIVERY ORDERS (DOPICKORDERLINE)
val doPickOrderLines = doPickOrderLineRepository.findByDoPickOrderIdAndDeletedFalse(doPickOrder.id!!)
val orderIds = doPickOrderLines.mapNotNull { it.doOrderId }.distinct()

if (deliveryNoteInfo.isEmpty()) {
throw NoSuchElementException("Delivery orders not found for IDs: $deliveryOrderIds")
if (orderIds.isEmpty()) {
throw IllegalStateException("DoPickOrder ${request.doPickOrderId} has no associated delivery orders")
}
orderIds
}

val pickOrderId = pickOrderIds.first()
val deliveryNoteInfo = deliveryOrderIds.flatMap { deliveryOrderId ->
deliveryOrderRepository.findDeliveryOrderInfoById(deliveryOrderId)
}.toMutableList()

val inputStream = resource.inputStream
val deliveryNote = JasperCompileManager.compileReport(inputStream)
if (deliveryNoteInfo.isEmpty()) {
throw NoSuchElementException("Delivery orders not found for IDs: $deliveryOrderIds")
}

val fields = mutableListOf<MutableMap<String, Any>>()
val params = mutableMapOf<String, Any>()
val pickOrderId = pickOrderIds.first()
val truckNo = doPickOrder.truckLanceCode ?: ""
val selectedPickOrder = pickOrderRepository.findById(pickOrderId).orElse(null)

val truckNo = doPickOrder.truckLanceCode ?: ""
val selectedPickOrder = pickOrderRepository.findById(pickOrderId).orElse(null)
val allLines = deliveryNoteInfo.flatMap { info ->
info.deliveryOrderLines.map { line -> line }
}

val allLines = deliveryNoteInfo.flatMap { info ->
info.deliveryOrderLines.map { line -> line }
}
val sortedLines = allLines.sortedBy { line ->
line.itemId?.let { itemId ->
getWarehouseOrderByItemId(itemId)
} ?: Int.MAX_VALUE
}

val sortedLines = allLines.sortedBy { line ->
line.itemId?.let { itemId ->
getWarehouseOrderByItemId(itemId)
} ?: Int.MAX_VALUE
}
sortedLines.forEach { line ->
val field = mutableMapOf<String, Any>()

field["sequenceNumber"] = (fields.size + 1).toString()
field["itemNo"] = line.itemNo
field["itemName"] = line.itemName ?: ""
field["uom"] = line.uom ?: ""
field["qty"] = line.qty.toString()
field["shortName"] = line.uomShortDesc ?: ""

val route = line.itemId?.let { itemId ->
getWarehouseCodeByItemId(itemId)
} ?: "-"
field["route"] = route

//USE SUGGESTED PICK LOTS
val lotNo = line.itemId?.let { itemId ->
pickOrderIds.mapNotNull { pickOrderId ->
val lots = getLotNumbersForPickOrderByItemId(itemId, pickOrderId)
lots.ifBlank { null }
}.distinct().joinToString(", ")
}?.ifBlank { "沒有庫存" } ?: "沒有庫存"
field["lotNo"] = lotNo
fields.add(field)
}

sortedLines.forEach { line ->
val field = mutableMapOf<String, Any>()
params["dnTitle"] = "送貨單(初稿)"
params["colQty"] = "所需數量"
params["totalCartonTitle"] = ""
params["deliveryNoteCodeTitle"] = ""
params["deliveryNoteCode"] = ""

field["sequenceNumber"] = (fields.size + 1).toString()
field["itemNo"] = line.itemNo
field["itemName"] = line.itemName ?: ""
field["uom"] = line.uom ?: ""
field["qty"] = line.qty.toString()
field["shortName"] = line.uomShortDesc ?: ""

val route = line.itemId?.let { itemId ->
getWarehouseCodeByItemId(itemId)
} ?: "-"
field["route"] = route

val lotNo = line.itemId?.let { itemId ->
pickOrderIds.mapNotNull { pickOrderId ->
val lots = getLotNumbersForPickOrderByItemId(itemId, pickOrderId)
lots.ifBlank { null }
}.distinct().joinToString(", ")
}?.ifBlank { "沒有庫存" } ?: "沒有庫存"
field["lotNo"] = lotNo
fields.add(field)
params["numOfCarton"] = request.numOfCarton.toString()
if (params["numOfCarton"] == "0") {
params["numOfCarton"] = ""
}

params["shopName"] = doPickOrder.shopName ?: deliveryNoteInfo[0].shopName ?: ""
params["shopAddress"] = deliveryNoteInfo[0].shopAddress ?: ""
params["deliveryDate"] = deliveryNoteInfo[0].estimatedArrivalDate?.format(DateTimeFormatter.ISO_LOCAL_DATE) ?: ""
params["truckNo"] = truckNo
params["ShopPurchaseOrderNo"] = doPickOrder.deliveryOrderCode ?: deliveryNoteInfo.joinToString(", ") { it.code }
params["FGPickOrderNo"] = doPickOrder.pickOrderCode ?: selectedPickOrder?.code ?: ""

return mapOf(
"report" to PdfUtils.fillReport(deliveryNote, fields, params),
"filename" to deliveryNoteInfo.joinToString("_") { it.code }
)
}

private fun exportDeliveryNoteFromRecord(
request: ExportDeliveryNoteRequest,
deliveryNote: net.sf.jasperreports.engine.JasperReport,
fields: MutableList<MutableMap<String, Any>>,
params: MutableMap<String, Any>
) : Map<String, Any> {

val doPickOrderRecord = doPickOrderRecordRepository.findById(request.doPickOrderId).orElseThrow {
NoSuchElementException("DoPickOrderRecord not found with ID: ${request.doPickOrderId}")
}

val doPickOrderLineRecords = doPickOrderLineRecordRepository.findByDoPickOrderIdAndDeletedFalse(request.doPickOrderId)

val pickOrderIds = doPickOrderLineRecords.mapNotNull { it.pickOrderId }.distinct()
if(pickOrderIds.isEmpty()){
throw IllegalStateException("DoPickOrderRecord ${request.doPickOrderId} has no associated pick orders")
}

val deliveryOrderIds = doPickOrderLineRecords.mapNotNull { it.doOrderId }.distinct()
if(deliveryOrderIds.isEmpty()){
throw IllegalStateException("DoPickOrderRecord ${request.doPickOrderId} has no associated delivery orders")
}

val deliveryNoteInfo = deliveryOrderIds.flatMap { deliveryOrderId ->
deliveryOrderRepository.findDeliveryOrderInfoById(deliveryOrderId)
}.toMutableList()

val pickOrderId = pickOrderIds.first()
val truckNo = doPickOrderRecord.truckLanceCode ?: ""
val selectedPickOrder = pickOrderRepository.findById(pickOrderId).orElse(null)

val allLines = deliveryNoteInfo.flatMap { info ->
info.deliveryOrderLines.map { line -> line }
}

val pickOrderLines = pickOrderIds.flatMap { pickOrderId ->
pickOrderLineRepository.findAllByPickOrderId(pickOrderId)
}

val pickOrderLineIdsByItemId = pickOrderLines
.groupBy { it.item?.id }
.mapValues { (_, lines) -> lines.mapNotNull { it.id } }

val allPickOrderLineIds = pickOrderLines.mapNotNull { it.id }
val stockOutLinesByPickOrderLineId = if (allPickOrderLineIds.isNotEmpty()) {
allPickOrderLineIds.associateWith { pickOrderLineId ->
stockOutLineRepository.findAllByPickOrderLineIdAndDeletedFalse(pickOrderLineId)
}
} else {
emptyMap()
}

val sortedLines = allLines.sortedBy { line ->
line.itemId?.let { itemId ->
getWarehouseOrderByItemId(itemId)
} ?: Int.MAX_VALUE
}

sortedLines.forEach { line ->
val field = mutableMapOf<String, Any>()

if (request.isDraft) {
params["dnTitle"] = "送貨單(初稿)"
params["colQty"] = "所需數量"
params["totalCartonTitle"] = ""
params["deliveryOrderCodeTitle"] = ""
params["deliveryOrderCode"] = ""
field["sequenceNumber"] = (fields.size + 1).toString()
field["itemNo"] = line.itemNo
field["itemName"] = line.itemName ?: ""
field["uom"] = line.uom ?: ""

val actualPickQty = if (line.itemId != null) {
val pickOrderLineIdsForItem = pickOrderLineIdsByItemId[line.itemId] ?: emptyList()
val totalQty = pickOrderLineIdsForItem.sumOf { pickOrderLineId ->
val stockOutLines = stockOutLinesByPickOrderLineId[pickOrderLineId] ?: emptyList()
stockOutLines.sumOf { it.qty }
}
totalQty.toString()
} else {
params["dnTitle"] = "送貨單"
params["colQty"] = "已提數量"
params["totalCartonTitle"] = "總箱數:"
params["deliveryOrderCodeTitle"] = "送貨單編號:"
params["deliveryOrderCode"] = "GEN FROM CODE GENERATOR (NEED FIND TIMING)"
line.qty.toString()
}
field["qty"] = actualPickQty

params["numOfCarton"] = request.numOfCarton.toString()
if (params["numOfCarton"] == "0") {
params["numOfCarton"] = ""
}
field["shortName"] = line.uomShortDesc ?: ""

params["shopName"] = doPickOrder.shopName ?: deliveryNoteInfo[0].shopName ?:""
params["shopAddress"] = deliveryNoteInfo[0].shopAddress ?: ""
params["deliveryDate"] = deliveryNoteInfo[0].estimatedArrivalDate?.format(DateTimeFormatter.ISO_LOCAL_DATE) ?: ""
params["truckNo"] = truckNo
params["ShopPurchaseOrderNo"] = doPickOrder.deliveryOrderCode ?: deliveryNoteInfo.joinToString(", ") { it.code }
params["FGPickOrderNo"] = doPickOrder.pickOrderCode ?: selectedPickOrder?.code ?: ""
val route = line.itemId?.let { itemId ->
getWarehouseCodeByItemId(itemId)
} ?: "-"
field["route"] = route

//USE STOCK OUT LINE
val lotNo = line.itemId?.let { itemId ->
val pickOrderLineIdsForItem = pickOrderLineIdsByItemId[itemId] ?: emptyList()
val lotNumbers = pickOrderLineIdsForItem.flatMap { pickOrderLineId ->
val stockOutLines = stockOutLinesByPickOrderLineId[pickOrderLineId] ?: emptyList()
stockOutLines.mapNotNull { it.lotNo }
}.distinct().joinToString(", ")

return mapOf(
"report" to PdfUtils.fillReport(deliveryNote, fields, params),
"filename" to deliveryNoteInfo.joinToString("_") { it.code }
)
lotNumbers.ifBlank {
"沒有庫存"
}
} ?: "沒有庫存"

field["lotNo"] = lotNo
fields.add(field)
}

params["dnTitle"] = "送貨單"
params["colQty"] = "已提數量"
params["totalCartonTitle"] = "總箱數:"
params["deliveryNoteCodeTitle"] = "送貨單編號:"
params["deliveryNoteCode"] = doPickOrderRecord.deliveryNoteCode ?: ""

params["numOfCarton"] = request.numOfCarton.toString()
if (params["numOfCarton"] == "0") {
params["numOfCarton"] = ""
}

params["shopName"] = doPickOrderRecord.shopName ?: deliveryNoteInfo[0].shopName ?: ""
params["shopAddress"] = deliveryNoteInfo[0].shopAddress ?: ""
params["deliveryDate"] = deliveryNoteInfo[0].estimatedArrivalDate?.format(DateTimeFormatter.ISO_LOCAL_DATE) ?: ""
params["truckNo"] = truckNo
params["ShopPurchaseOrderNo"] = doPickOrderRecord.deliveryOrderCode ?: deliveryNoteInfo.joinToString(", ") { it.code }
params["FGPickOrderNo"] = doPickOrderRecord.pickOrderCode ?: selectedPickOrder?.code ?: ""

return mapOf(
"report" to PdfUtils.fillReport(deliveryNote, fields, params),
"filename" to deliveryNoteInfo.joinToString("_") { it.code }
)
}

//Print Delivery Note
@Transactional
open fun printDeliveryNote(request: PrintDeliveryNoteRequest) {
@@ -857,7 +993,7 @@ open class DeliveryOrderService(

}
params["shopPurchaseOrderNo"] = doPickOrder.deliveryOrderCode ?: cartonLabelInfo[0].code
params["deliveryOrderCode"] = "GEN FROM CODE GENERATOR (NEED FIND TIMING)"
params["deliveryNoteCode"] = "GEN FROM CODE GENERATOR (NEED FIND TIMING)"
params["shopAddress"] = cartonLabelInfo[0].shopAddress ?: ""
params["shopName"] = doPickOrder.shopName ?: cartonLabelInfo[0].shopName ?: ""



+ 2
- 0
src/main/java/com/ffii/fpsms/modules/pickOrder/service/PickOrderService.kt View File

@@ -4546,6 +4546,7 @@ println("DEBUG sol polIds in linesResults: " + linesResults.mapNotNull { it["sto
val sql = """
SELECT DISTINCT
dpor.id as doPickOrderRecordId,
dpor.record_id as recordId,
dpor.ticket_no as ticketNo,
dpor.store_id as storeId,
dpor.ticketCompleteDateTime as completedDate,
@@ -4648,6 +4649,7 @@ println("DEBUG sol polIds in linesResults: " + linesResults.mapNotNull { it["sto
mapOf(
"id" to (row["doPickOrderRecordId"] ?: 0L),
"doPickOrderRecordId" to (row["doPickOrderRecordId"] ?: 0L),
"recordId" to (row["recordId"] ?: ""),
"ticketNo" to (row["ticketNo"] ?: ""),
"storeId" to (row["storeId"] ?: ""),
"completedDate" to (row["completedDate"]?.toString() ?: ""),


+ 9
- 1
src/main/java/com/ffii/fpsms/modules/stock/service/StockOutLineService.kt View File

@@ -31,6 +31,8 @@ import com.ffii.fpsms.modules.deliveryOrder.entity.DoPickOrderRecord
import com.ffii.fpsms.modules.deliveryOrder.entity.DoPickOrderLineRecord
import com.ffii.fpsms.modules.deliveryOrder.enums.DeliveryOrderStatus
import com.ffii.fpsms.modules.deliveryOrder.entity.DoPickOrderLineRecordRepository
import com.ffii.fpsms.modules.common.CodeGenerator

@Service
open class StockOutLineService(
private val jdbcDao: JdbcDao,
@@ -372,7 +374,12 @@ private fun getStockOutIdFromPickOrderLine(pickOrderLineId: Long): Long {
dpo.ticketStatus = DoPickOrderStatus.completed
dpo.ticketCompleteDateTime = LocalDateTime.now()
doPickOrderRepository.save(dpo)

val prefix = "DN"
val midfix = CodeGenerator.DEFAULT_MIDFIX
val latestCode = doPickOrderRecordRepository.findLatestDeliveryNoteCodeByPrefix("${prefix}-${midfix}")
val deliveryNoteCode = CodeGenerator.generateNo(prefix = prefix, midfix = midfix, latestCode = latestCode)

// 4) 可选:复制 header 到 record 表,复制 lines 到 line_record,再删除原有行/头(与你在 PickOrderService.completeStockOut 的做法保持一致)
val dpoRecord = DoPickOrderRecord(
recordId =dpoId,
@@ -388,6 +395,7 @@ private fun getStockOutIdFromPickOrderLine(pickOrderLineId: Long): Long {
doOrderId = dpo.doOrderId,
pickOrderCode = dpo.pickOrderCode,
deliveryOrderCode = dpo.deliveryOrderCode,
deliveryNoteCode = deliveryNoteCode,
loadingSequence = dpo.loadingSequence,
ticketReleaseTime = dpo.ticketReleaseTime,
ticketCompleteDateTime = LocalDateTime.now(),


Loading…
Cancel
Save