| @@ -0,0 +1,94 @@ | |||
| package com.ffii.fpsms.modules.deliveryOrder.entity | |||
| import jakarta.persistence.* | |||
| import java.time.LocalDateTime | |||
| import java.time.LocalTime | |||
| import com.ffii.fpsms.modules.deliveryOrder.enums.DoPickOrderStatus | |||
| import org.hibernate.annotations.CreationTimestamp | |||
| import org.hibernate.annotations.UpdateTimestamp | |||
| @Entity | |||
| @Table(name = "do_pick_order") | |||
| class DoPickOrder { | |||
| @Id | |||
| @GeneratedValue(strategy = GenerationType.IDENTITY) | |||
| var id: Long? = null | |||
| @Column(name = "store_id", length = 10) | |||
| var storeId: String? = null | |||
| @Column(name = "ticket_no", length = 50) | |||
| var ticketNo: String? = null | |||
| @Enumerated(EnumType.STRING) | |||
| @Column(name = "ticket_status") | |||
| var ticketStatus: DoPickOrderStatus? = null | |||
| @Column(name = "truck_id") | |||
| var truckId: Long? = null | |||
| @Column(name = "truck_departure_time") | |||
| var truckDepartureTime: LocalTime? = null | |||
| @Column(name = "item_id") | |||
| var itemId: Long? = null | |||
| @Column(name = "shop_id") | |||
| var shopId: Long? = null | |||
| @Column(name = "shop_po_supplier_id") | |||
| var shopPoSupplierId: Long? = null | |||
| @Column(name = "handled_by") | |||
| var handledBy: Long? = null | |||
| @CreationTimestamp | |||
| @Column(name = "created") | |||
| var created: LocalDateTime? = null | |||
| @Column(name = "createdBy", length = 30) | |||
| var createdBy: String? = null | |||
| @Version | |||
| var version: Int = 0 | |||
| @UpdateTimestamp | |||
| @Column(name = "modified") | |||
| var modified: LocalDateTime? = null | |||
| @Column(name = "modifiedBy", length = 30) | |||
| var modifiedBy: String? = null | |||
| @Column(name = "deleted") | |||
| var deleted: Boolean = false | |||
| // Default constructor for Hibernate | |||
| constructor() | |||
| // Constructor for creating new instances | |||
| constructor( | |||
| storeId: String, | |||
| ticketNo: String, | |||
| ticketStatus: DoPickOrderStatus, | |||
| truckId: Long? = null, | |||
| truckDepartureTime: LocalTime? = null, | |||
| itemId: Long? = null, | |||
| shopId: Long? = null, | |||
| shopPoSupplierId: Long? = null, | |||
| handledBy: Long? = null, | |||
| createdBy: String? = null, | |||
| modifiedBy: String? = null | |||
| ) { | |||
| this.storeId = storeId | |||
| this.ticketNo = ticketNo | |||
| this.ticketStatus = ticketStatus | |||
| this.truckId = truckId | |||
| this.truckDepartureTime = truckDepartureTime | |||
| this.itemId = itemId | |||
| this.shopId = shopId | |||
| this.shopPoSupplierId = shopPoSupplierId | |||
| this.handledBy = handledBy | |||
| this.createdBy = createdBy | |||
| this.modifiedBy = modifiedBy | |||
| } | |||
| } | |||
| @@ -0,0 +1,21 @@ | |||
| package com.ffii.fpsms.modules.deliveryOrder.entity | |||
| import com.ffii.core.support.AbstractRepository | |||
| import com.ffii.fpsms.modules.deliveryOrder.entity.models.DeliveryOrderInfo | |||
| import com.ffii.fpsms.modules.deliveryOrder.enums.DeliveryOrderStatus | |||
| import com.ffii.fpsms.modules.deliveryOrder.enums.DoPickOrderStatus | |||
| import com.ffii.fpsms.modules.master.entity.projections.SearchId | |||
| import org.springframework.data.jpa.repository.JpaRepository | |||
| import org.springframework.data.jpa.repository.Query | |||
| import org.springframework.stereotype.Repository | |||
| import java.io.Serializable | |||
| import java.time.LocalDateTime | |||
| @Repository | |||
| interface DoPickOrderRepository : JpaRepository<DoPickOrder, Long> { | |||
| fun findByTicketNoStartingWith(prefix: String): List<DoPickOrder> | |||
| fun findByStoreIdAndTicketStatusOrderByTruckDepartureTimeAsc( | |||
| storeId: String, | |||
| status: DoPickOrderStatus | |||
| ): List<DoPickOrder> | |||
| } | |||
| @@ -0,0 +1,6 @@ | |||
| package com.ffii.fpsms.modules.deliveryOrder.enums | |||
| enum class DoPickOrderStatus(val value: String) { | |||
| pending("pending"), | |||
| completed("completed") | |||
| } | |||
| @@ -29,7 +29,12 @@ import java.time.LocalDate | |||
| import java.math.BigDecimal | |||
| import com.ffii.fpsms.modules.master.web.models.MessageResponse | |||
| import java.time.LocalDateTime | |||
| import com.ffii.fpsms.modules.deliveryOrder.service.DoPickOrderService | |||
| import com.ffii.fpsms.modules.deliveryOrder.entity.DoPickOrder | |||
| import com.ffii.fpsms.modules.deliveryOrder.enums.DoPickOrderStatus | |||
| import java.time.format.DateTimeFormatter | |||
| import com.ffii.fpsms.modules.pickOrder.entity.TruckRepository | |||
| import java.time.LocalTime | |||
| @Service | |||
| open class DeliveryOrderService( | |||
| private val deliveryOrderRepository: DeliveryOrderRepository, | |||
| @@ -39,24 +44,27 @@ open class DeliveryOrderService( | |||
| private val m18DataLogRepository: M18DataLogRepository, | |||
| private val userService: UserService, | |||
| private val userRepository: UserRepository, | |||
| private val pickOrderService: PickOrderService | |||
| private val pickOrderService: PickOrderService, | |||
| private val doPickOrderService: DoPickOrderService, | |||
| private val truckRepository: TruckRepository | |||
| ) { | |||
| open fun findByM18DataLogId(m18DataLogId: Long): DeliveryOrder? { | |||
| return deliveryOrderRepository.findTopByM18DataLogIdAndDeletedIsFalseOrderByModifiedDesc(m18DataLogId) | |||
| } | |||
| open fun getDoList() : List<DeliveryOrderInfo> { | |||
| open fun getDoList(): List<DeliveryOrderInfo> { | |||
| return deliveryOrderRepository.findDeliveryOrderInfoByDeletedIsFalse(); | |||
| } | |||
| /* | |||
| /* | |||
| open fun getDetailedDo(id: Long) : DeliveryOrder? { | |||
| return deliveryOrderRepository.findByIdAndDeletedIsFalse(id); | |||
| } | |||
| */ | |||
| open fun getDetailedDo(id: Long): DoDetailResponse? { | |||
| val deliveryOrder = deliveryOrderRepository.findByIdAndDeletedIsFalse(id) ?: return null | |||
| return DoDetailResponse( | |||
| id = deliveryOrder.id!!, | |||
| code = deliveryOrder.code ?: "", | |||
| @@ -80,11 +88,12 @@ open class DeliveryOrderService( | |||
| } | |||
| ) | |||
| } | |||
| open fun searchByCode(code: String?) : List<DeliveryOrderInfo> { | |||
| open fun searchByCode(code: String?): List<DeliveryOrderInfo> { | |||
| return deliveryOrderRepository.findAllByCodeContainsAndDeletedIsFalse(code); | |||
| } | |||
| open fun searchByShopName(shopName: String) : List<DeliveryOrderInfo> { | |||
| open fun searchByShopName(shopName: String): List<DeliveryOrderInfo> { | |||
| return deliveryOrderRepository.findAllByShopNameContainsAndDeletedIsFalse(shopName); | |||
| } | |||
| @@ -97,41 +106,125 @@ open class DeliveryOrderService( | |||
| } | |||
| open fun getFullList(): List<DeliveryOrderInfo>{ | |||
| open fun getFullList(): List<DeliveryOrderInfo> { | |||
| return deliveryOrderRepository.findAllBy(); | |||
| } | |||
| open fun searchAll(code: String?, shopName: String?, status: DeliveryOrderStatus?, orderStartDate: LocalDateTime?, orderEndDate: LocalDateTime?, estArrStartDate: LocalDateTime?, estArrEndDate: LocalDateTime?):List<DeliveryOrderInfo> { | |||
| return deliveryOrderRepository.findAllByCodeContainsAndShopNameContainsAndStatusAndOrderDateBetweenAndEstimatedArrivalDateBetweenAndDeletedIsFalse(code, shopName, status, orderStartDate, orderEndDate, estArrStartDate, estArrEndDate); | |||
| open fun searchAll( | |||
| code: String?, | |||
| shopName: String?, | |||
| status: DeliveryOrderStatus?, | |||
| orderStartDate: LocalDateTime?, | |||
| orderEndDate: LocalDateTime?, | |||
| estArrStartDate: LocalDateTime?, | |||
| estArrEndDate: LocalDateTime? | |||
| ): List<DeliveryOrderInfo> { | |||
| return deliveryOrderRepository.findAllByCodeContainsAndShopNameContainsAndStatusAndOrderDateBetweenAndEstimatedArrivalDateBetweenAndDeletedIsFalse( | |||
| code, | |||
| shopName, | |||
| status, | |||
| orderStartDate, | |||
| orderEndDate, | |||
| estArrStartDate, | |||
| estArrEndDate | |||
| ); | |||
| } | |||
| open fun searchWithoutStatus(code: String?, shopName: String?, orderStartDate: LocalDateTime?, orderEndDate: LocalDateTime?, estArrStartDate: LocalDateTime?, estArrEndDate: LocalDateTime?) : List<DeliveryOrderInfo> { | |||
| return deliveryOrderRepository.findAllByCodeContainsAndShopNameContainsAndOrderDateBetweenAndEstimatedArrivalDateBetweenAndDeletedIsFalse(code, shopName, orderStartDate, orderEndDate, estArrStartDate, estArrEndDate); | |||
| open fun searchWithoutStatus( | |||
| code: String?, | |||
| shopName: String?, | |||
| orderStartDate: LocalDateTime?, | |||
| orderEndDate: LocalDateTime?, | |||
| estArrStartDate: LocalDateTime?, | |||
| estArrEndDate: LocalDateTime? | |||
| ): List<DeliveryOrderInfo> { | |||
| return deliveryOrderRepository.findAllByCodeContainsAndShopNameContainsAndOrderDateBetweenAndEstimatedArrivalDateBetweenAndDeletedIsFalse( | |||
| code, | |||
| shopName, | |||
| orderStartDate, | |||
| orderEndDate, | |||
| estArrStartDate, | |||
| estArrEndDate | |||
| ); | |||
| } | |||
| open fun searchWithoutEstArrDate(code: String?, shopName: String?, status: DeliveryOrderStatus?, orderStartDate: LocalDateTime?, orderEndDate: LocalDateTime?): List<DeliveryOrderInfo>{ | |||
| return deliveryOrderRepository.findAllByCodeContainsAndShopNameContainsAndStatusAndOrderDateBetweenAndDeletedIsFalse(code, shopName, status, orderStartDate, orderEndDate); | |||
| open fun searchWithoutEstArrDate( | |||
| code: String?, | |||
| shopName: String?, | |||
| status: DeliveryOrderStatus?, | |||
| orderStartDate: LocalDateTime?, | |||
| orderEndDate: LocalDateTime? | |||
| ): List<DeliveryOrderInfo> { | |||
| return deliveryOrderRepository.findAllByCodeContainsAndShopNameContainsAndStatusAndOrderDateBetweenAndDeletedIsFalse( | |||
| code, | |||
| shopName, | |||
| status, | |||
| orderStartDate, | |||
| orderEndDate | |||
| ); | |||
| } | |||
| open fun searchWithoutEstArrDateAndStatus(code: String?, shopName: String?, orderStartDate: LocalDateTime?, orderEndDate: LocalDateTime?): List<DeliveryOrderInfo>{ | |||
| return deliveryOrderRepository.findAllByCodeContainsAndShopNameContainsAndOrderDateBetweenAndDeletedIsFalse(code, shopName, orderStartDate, orderEndDate); | |||
| open fun searchWithoutEstArrDateAndStatus( | |||
| code: String?, | |||
| shopName: String?, | |||
| orderStartDate: LocalDateTime?, | |||
| orderEndDate: LocalDateTime? | |||
| ): List<DeliveryOrderInfo> { | |||
| return deliveryOrderRepository.findAllByCodeContainsAndShopNameContainsAndOrderDateBetweenAndDeletedIsFalse( | |||
| code, | |||
| shopName, | |||
| orderStartDate, | |||
| orderEndDate | |||
| ); | |||
| } | |||
| open fun searchWithoutOrderDate(code: String?, shopName: String?, status: DeliveryOrderStatus?, estArrStartDate: LocalDateTime?, estArrEndDate: LocalDateTime?) : List<DeliveryOrderInfo>{ | |||
| return deliveryOrderRepository.findAllByCodeContainsAndShopNameContainsAndStatusAndEstimatedArrivalDateBetweenAndDeletedIsFalse(code, shopName, status, estArrStartDate, estArrEndDate); | |||
| open fun searchWithoutOrderDate( | |||
| code: String?, | |||
| shopName: String?, | |||
| status: DeliveryOrderStatus?, | |||
| estArrStartDate: LocalDateTime?, | |||
| estArrEndDate: LocalDateTime? | |||
| ): List<DeliveryOrderInfo> { | |||
| return deliveryOrderRepository.findAllByCodeContainsAndShopNameContainsAndStatusAndEstimatedArrivalDateBetweenAndDeletedIsFalse( | |||
| code, | |||
| shopName, | |||
| status, | |||
| estArrStartDate, | |||
| estArrEndDate | |||
| ); | |||
| } | |||
| open fun searchWithoutOrderDateAndStatus(code: String?, shopName: String?, estArrStartDate: LocalDateTime?, estArrEndDate: LocalDateTime?) : List<DeliveryOrderInfo>{ | |||
| return deliveryOrderRepository.findAllByCodeContainsAndShopNameContainsAndEstimatedArrivalDateBetweenAndDeletedIsFalse(code, shopName, estArrStartDate, estArrEndDate); | |||
| open fun searchWithoutOrderDateAndStatus( | |||
| code: String?, | |||
| shopName: String?, | |||
| estArrStartDate: LocalDateTime?, | |||
| estArrEndDate: LocalDateTime? | |||
| ): List<DeliveryOrderInfo> { | |||
| return deliveryOrderRepository.findAllByCodeContainsAndShopNameContainsAndEstimatedArrivalDateBetweenAndDeletedIsFalse( | |||
| code, | |||
| shopName, | |||
| estArrStartDate, | |||
| estArrEndDate | |||
| ); | |||
| } | |||
| open fun searchWithoutDate(code: String?, shopName: String?, status: DeliveryOrderStatus?) : List<DeliveryOrderInfo> { | |||
| return deliveryOrderRepository.findAllByCodeContainsAndShopNameContainsAndStatusAndDeletedIsFalse(code, shopName, status); | |||
| open fun searchWithoutDate( | |||
| code: String?, | |||
| shopName: String?, | |||
| status: DeliveryOrderStatus? | |||
| ): List<DeliveryOrderInfo> { | |||
| return deliveryOrderRepository.findAllByCodeContainsAndShopNameContainsAndStatusAndDeletedIsFalse( | |||
| code, | |||
| shopName, | |||
| status | |||
| ); | |||
| } | |||
| open fun searchCodeAndShopName(code: String?, shopName: String?) : List<DeliveryOrderInfo> { | |||
| open fun searchCodeAndShopName(code: String?, shopName: String?): List<DeliveryOrderInfo> { | |||
| return deliveryOrderRepository.findAllByCodeContainsAndShopNameContainsAndDeletedIsFalse(code, shopName); | |||
| } | |||
| open fun updateDeliveryOrderStatus(request: SaveDeliveryOrderStatusRequest): SaveDeliveryOrderResponse { | |||
| val deliveryOrder = checkNotNull( | |||
| request.id?.let { deliveryOrderRepository.findById(it).getOrNull() } | |||
| @@ -212,9 +305,13 @@ open class DeliveryOrderService( | |||
| @Transactional(rollbackFor = [Exception::class]) | |||
| open fun releaseDeliveryOrder(request: ReleaseDoRequest): MessageResponse { | |||
| println("�� DEBUG: Starting releaseDeliveryOrder for DO ID: ${request.id}, User ID: ${request.userId}") | |||
| val deliveryOrder = deliveryOrderRepository.findByIdAndDeletedIsFalse(request.id) | |||
| ?: throw NoSuchElementException("Delivery Order not found") | |||
| println("�� DEBUG: Found delivery order - ID: ${deliveryOrder.id}, Shop: ${deliveryOrder.shop?.code}, Status: ${deliveryOrder.status}") | |||
| deliveryOrder.apply { | |||
| status = DeliveryOrderStatus.PENDING | |||
| } | |||
| @@ -228,13 +325,61 @@ open fun releaseDeliveryOrder(request: ReleaseDoRequest): MessageResponse { | |||
| ) | |||
| } | |||
| val po = SavePickOrderRequest( | |||
| doId = deliveryOrder.id, // Set doId instead of joId | |||
| type = PickOrderType.DELIVERY_ORDER, // You might need to add this enum value | |||
| doId = deliveryOrder.id, | |||
| type = PickOrderType.DELIVERY_ORDER, | |||
| targetDate = deliveryOrder.estimatedArrivalDate?.toLocalDate() ?: LocalDate.now(), | |||
| pickOrderLine = pols | |||
| ) | |||
| pickOrderService.create(po) | |||
| val createdPickOrder = pickOrderService.create(po) | |||
| println("🔍 DEBUG: Created pick order - ID: ${createdPickOrder.id}") | |||
| // ✅ CREATE do_pick_order_record entries | |||
| val targetDate = deliveryOrder.estimatedArrivalDate?.toLocalDate() ?: LocalDate.now() | |||
| val datePrefix = targetDate.format(DateTimeFormatter.ofPattern("ddMMyy")) | |||
| println("�� DEBUG: Target date: $targetDate, Date prefix: $datePrefix") | |||
| // Get next ticket number for this date | |||
| val nextTicketNumber = doPickOrderService.getNextTicketNumber(datePrefix) | |||
| println("�� DEBUG: Next ticket number: $nextTicketNumber") | |||
| // ✅ Find truck by shop ID with earliest departure time | |||
| val truck = deliveryOrder.shop?.id?.let { shopId -> | |||
| println("�� DEBUG: Looking for truck with shop ID: $shopId") | |||
| val trucks = truckRepository.findByShopIdAndDeletedFalse(shopId) | |||
| println("🔍 DEBUG: Found ${trucks.size} trucks for shop $shopId") | |||
| trucks.forEach { t -> | |||
| println("🔍 DEBUG: Truck ID: ${t.id}, DepartureTime: ${t.departureTime}") | |||
| } | |||
| val selectedTruck = trucks.minByOrNull { it.departureTime ?: LocalTime.MAX } | |||
| println("🔍 DEBUG: Selected truck: ID=${selectedTruck?.id}, DepartureTime=${selectedTruck?.departureTime}") | |||
| selectedTruck | |||
| } | |||
| println("🔍 DEBUG: Processing ${deliveryOrder.deliveryOrderLines.size} delivery order lines") | |||
| deliveryOrder.deliveryOrderLines.forEach { line -> | |||
| val storeId = if (deliveryOrder.shop?.code == "P06B") "2/F" else "4/F" | |||
| println("�� DEBUG: Processing line - Item ID: ${line.item?.id}, Store ID: $storeId") | |||
| val doPickOrder = DoPickOrder( | |||
| storeId = storeId, | |||
| ticketNo = nextTicketNumber, | |||
| ticketStatus = DoPickOrderStatus.pending, | |||
| truckId = truck?.id, | |||
| truckDepartureTime = truck?.departureTime, | |||
| itemId = line.item?.id, | |||
| shopId = deliveryOrder.shop?.id, | |||
| shopPoSupplierId = deliveryOrder.shop?.id, | |||
| handledBy = request.userId | |||
| ) | |||
| println("�� DEBUG: Creating DoPickOrder - Store: $storeId, Ticket: $nextTicketNumber, Truck: ${truck?.id}") | |||
| val savedDoPickOrder = doPickOrderService.save(doPickOrder) | |||
| println("🔍 DEBUG: Saved DoPickOrder - ID: ${savedDoPickOrder.id}") | |||
| } | |||
| return MessageResponse( | |||
| id = deliveryOrder.id, | |||
| @@ -0,0 +1,95 @@ | |||
| package com.ffii.fpsms.modules.deliveryOrder.service | |||
| import com.ffii.fpsms.m18.entity.M18DataLogRepository | |||
| import com.ffii.fpsms.m18.service.M18DataLogService | |||
| import com.ffii.fpsms.modules.deliveryOrder.entity.DeliveryOrder | |||
| import com.ffii.fpsms.modules.deliveryOrder.entity.DeliveryOrderRepository | |||
| import com.ffii.fpsms.modules.deliveryOrder.entity.models.DeliveryOrderInfo | |||
| import com.ffii.fpsms.modules.deliveryOrder.enums.DeliveryOrderStatus | |||
| import com.ffii.fpsms.modules.deliveryOrder.web.models.SaveDeliveryOrderRequest | |||
| import com.ffii.fpsms.modules.deliveryOrder.web.models.SaveDeliveryOrderResponse | |||
| import com.ffii.fpsms.modules.deliveryOrder.web.models.SaveDeliveryOrderStatusRequest | |||
| import com.ffii.fpsms.modules.master.service.CurrencyService | |||
| import com.ffii.fpsms.modules.master.service.ShopService | |||
| import com.ffii.fpsms.modules.user.entity.UserRepository | |||
| import com.ffii.fpsms.modules.user.service.UserService | |||
| import org.springframework.stereotype.Service | |||
| import org.springframework.transaction.annotation.Transactional | |||
| import java.io.IOException | |||
| import kotlin.jvm.optionals.getOrDefault | |||
| import kotlin.jvm.optionals.getOrNull | |||
| import com.ffii.fpsms.modules.deliveryOrder.web.models.DoDetailResponse | |||
| import com.ffii.fpsms.modules.deliveryOrder.web.models.DoDetailLineResponse | |||
| import com.ffii.fpsms.modules.deliveryOrder.web.models.ReleaseDoRequest | |||
| import com.ffii.fpsms.modules.pickOrder.web.models.SavePickOrderRequest | |||
| import com.ffii.fpsms.modules.pickOrder.web.models.SavePickOrderLineRequest | |||
| import com.ffii.fpsms.modules.pickOrder.enums.PickOrderType | |||
| import com.ffii.fpsms.modules.pickOrder.service.PickOrderService | |||
| import com.ffii.fpsms.modules.deliveryOrder.entity.DoPickOrder | |||
| import com.ffii.fpsms.modules.deliveryOrder.entity.DoPickOrderRepository | |||
| import com.ffii.fpsms.modules.deliveryOrder.enums.DoPickOrderStatus | |||
| import java.time.LocalDate | |||
| import java.math.BigDecimal | |||
| import com.ffii.fpsms.modules.master.web.models.MessageResponse | |||
| import java.time.LocalDateTime | |||
| import com.ffii.fpsms.modules.deliveryOrder.web.models.AssignByStoreRequest | |||
| @Service | |||
| class DoPickOrderService( | |||
| private val doPickOrderRepository: DoPickOrderRepository | |||
| ) { | |||
| fun getNextTicketNumber(datePrefix: String): String { | |||
| println("🔍 DEBUG: Getting next ticket number for date prefix: $datePrefix") | |||
| try { | |||
| val todayTickets = doPickOrderRepository.findByTicketNoStartingWith("${datePrefix}_") | |||
| println("🔍 DEBUG: Found ${todayTickets.size} existing tickets with prefix ${datePrefix}_") | |||
| todayTickets.forEach { ticket -> | |||
| println("�� DEBUG: Existing ticket: ${ticket.ticketNo}, Status: ${ticket.ticketStatus}") | |||
| } | |||
| val nextNumber = (todayTickets.size + 1).toString().padStart(3, '0') | |||
| val ticketNumber = "${datePrefix}_${nextNumber}" | |||
| println("🔍 DEBUG: Generated ticket number: $ticketNumber") | |||
| return ticketNumber | |||
| } catch (e: Exception) { | |||
| println("❌ ERROR in getNextTicketNumber: ${e.message}") | |||
| e.printStackTrace() | |||
| throw e | |||
| } | |||
| } | |||
| fun save(record: DoPickOrder): DoPickOrder { | |||
| return doPickOrderRepository.save(record) | |||
| } | |||
| fun findByStoreIdOrderByTruckDepartureTime(storeId: String): List<DoPickOrder> { | |||
| return doPickOrderRepository.findByStoreIdAndTicketStatusOrderByTruckDepartureTimeAsc( | |||
| storeId, DoPickOrderStatus.pending | |||
| ) | |||
| } | |||
| // Add these missing methods | |||
| fun assignByStore(request: AssignByStoreRequest): MessageResponse { | |||
| // TODO: Implement store-based assignment logic | |||
| return MessageResponse( | |||
| id = null, | |||
| code = null, | |||
| name = null, | |||
| type = null, | |||
| message = "Store-based assignment not implemented yet", | |||
| errorPosition = null, | |||
| entity = null | |||
| ) | |||
| } | |||
| fun releaseAssignedByStore(request: AssignByStoreRequest): MessageResponse { | |||
| // TODO: Implement store-based release logic | |||
| return MessageResponse( | |||
| id = null, | |||
| code = null, | |||
| name = null, | |||
| type = null, | |||
| message = "Store-based release not implemented yet", | |||
| errorPosition = null, | |||
| entity = null | |||
| ) | |||
| } | |||
| } | |||
| @@ -51,50 +51,93 @@ class DeliveryOrderController( | |||
| } | |||
| @GetMapping("/search-orderdate/{start}&{end}") | |||
| fun searchBetweenOrderDate(@PathVariable start: LocalDateTime?,@PathVariable end: LocalDateTime?): List<DeliveryOrderInfo> { | |||
| fun searchBetweenOrderDate( | |||
| @PathVariable start: LocalDateTime?, | |||
| @PathVariable end: LocalDateTime? | |||
| ): List<DeliveryOrderInfo> { | |||
| return deliveryOrderService.searchBetweenOrderDate(start, end); | |||
| } | |||
| @GetMapping("/search-DO/{code}&{shopName}&{status}&{orderStartDate}&{orderEndDate}&{estArrStartDate}&{estArrEndDate}") | |||
| fun searchDO(@PathVariable code: String?, @PathVariable shopName: String?, @PathVariable status: DeliveryOrderStatus?, @PathVariable orderStartDate: LocalDateTime? , @PathVariable orderEndDate: LocalDateTime?, @PathVariable estArrStartDate: LocalDateTime?, @PathVariable estArrEndDate: LocalDateTime?): List<DeliveryOrderInfo>{ | |||
| fun searchDO( | |||
| @PathVariable code: String?, | |||
| @PathVariable shopName: String?, | |||
| @PathVariable status: DeliveryOrderStatus?, | |||
| @PathVariable orderStartDate: LocalDateTime?, | |||
| @PathVariable orderEndDate: LocalDateTime?, | |||
| @PathVariable estArrStartDate: LocalDateTime?, | |||
| @PathVariable estArrEndDate: LocalDateTime? | |||
| ): List<DeliveryOrderInfo> { | |||
| println("test"); | |||
| if(code != null || shopName != null){ | |||
| if(orderStartDate != null && orderEndDate != null && estArrStartDate != null && estArrEndDate != null){ | |||
| if (status != null){ | |||
| return deliveryOrderService.searchAll(code, shopName, status, orderStartDate, orderEndDate, estArrStartDate, estArrEndDate); | |||
| if (code != null || shopName != null) { | |||
| if (orderStartDate != null && orderEndDate != null && estArrStartDate != null && estArrEndDate != null) { | |||
| if (status != null) { | |||
| return deliveryOrderService.searchAll( | |||
| code, | |||
| shopName, | |||
| status, | |||
| orderStartDate, | |||
| orderEndDate, | |||
| estArrStartDate, | |||
| estArrEndDate | |||
| ); | |||
| } else { | |||
| return deliveryOrderService.searchWithoutStatus( | |||
| code, | |||
| shopName, | |||
| orderStartDate, | |||
| orderEndDate, | |||
| estArrStartDate, | |||
| estArrEndDate | |||
| ); | |||
| } | |||
| else{ | |||
| return deliveryOrderService.searchWithoutStatus(code, shopName, orderStartDate, orderEndDate, estArrStartDate, estArrEndDate); | |||
| } | |||
| } | |||
| else{ | |||
| if(orderStartDate == null && orderEndDate == null && estArrStartDate == null && estArrEndDate == null){ | |||
| if(status != null){ | |||
| } else { | |||
| if (orderStartDate == null && orderEndDate == null && estArrStartDate == null && estArrEndDate == null) { | |||
| if (status != null) { | |||
| return deliveryOrderService.searchWithoutDate(code, shopName, status); | |||
| } | |||
| else{ | |||
| } else { | |||
| return deliveryOrderService.searchCodeAndShopName(code, shopName); | |||
| } | |||
| } | |||
| else{ | |||
| if(estArrStartDate != null && estArrEndDate != null && (orderStartDate == null && orderEndDate == null)){ | |||
| if (status != null){ | |||
| return deliveryOrderService.searchWithoutOrderDate(code, shopName, status, estArrStartDate, estArrEndDate); | |||
| } | |||
| else{ | |||
| return deliveryOrderService.searchWithoutOrderDateAndStatus(code, shopName, estArrStartDate, estArrEndDate); | |||
| } | |||
| } | |||
| else if(orderStartDate != null && orderEndDate != null && (estArrStartDate == null && estArrEndDate == null)){ | |||
| if (status != null){ | |||
| return deliveryOrderService.searchAll(code, shopName, status, orderStartDate, orderEndDate, estArrStartDate, estArrEndDate); | |||
| } else { | |||
| if (estArrStartDate != null && estArrEndDate != null && (orderStartDate == null && orderEndDate == null)) { | |||
| if (status != null) { | |||
| return deliveryOrderService.searchWithoutOrderDate( | |||
| code, | |||
| shopName, | |||
| status, | |||
| estArrStartDate, | |||
| estArrEndDate | |||
| ); | |||
| } else { | |||
| return deliveryOrderService.searchWithoutOrderDateAndStatus( | |||
| code, | |||
| shopName, | |||
| estArrStartDate, | |||
| estArrEndDate | |||
| ); | |||
| } | |||
| else{ | |||
| return deliveryOrderService.searchWithoutStatus(code, shopName, orderStartDate, orderEndDate, estArrStartDate, estArrEndDate); | |||
| } else if (orderStartDate != null && orderEndDate != null && (estArrStartDate == null && estArrEndDate == null)) { | |||
| if (status != null) { | |||
| return deliveryOrderService.searchAll( | |||
| code, | |||
| shopName, | |||
| status, | |||
| orderStartDate, | |||
| orderEndDate, | |||
| estArrStartDate, | |||
| estArrEndDate | |||
| ); | |||
| } else { | |||
| return deliveryOrderService.searchWithoutStatus( | |||
| code, | |||
| shopName, | |||
| orderStartDate, | |||
| orderEndDate, | |||
| estArrStartDate, | |||
| estArrEndDate | |||
| ); | |||
| } | |||
| } | |||
| else{ | |||
| } else { | |||
| return emptyList(); | |||
| } | |||
| } | |||
| @@ -104,14 +147,9 @@ class DeliveryOrderController( | |||
| return deliveryOrderService.getFullList(); | |||
| } | |||
| @PostMapping("/update-status") | |||
| fun updateDoStatus(@RequestBody request: SaveDeliveryOrderStatusRequest): SaveDeliveryOrderResponse { | |||
| return deliveryOrderService.updateDeliveryOrderStatus(request); | |||
| @@ -125,8 +163,10 @@ class DeliveryOrderController( | |||
| ) | |||
| return deliveryOrderService.updateDeliveryOrderStatus(request); | |||
| } | |||
| @PostMapping("/release") | |||
| fun releaseDeliveryOrder(@Valid @RequestBody request: ReleaseDoRequest): MessageResponse { | |||
| fun releaseDeliveryOrder(@RequestBody request: ReleaseDoRequest): MessageResponse { | |||
| // ✅ Simply pass the request directly - userId comes from frontend session | |||
| return deliveryOrderService.releaseDeliveryOrder(request) | |||
| } | |||
| } | |||
| @@ -0,0 +1,53 @@ | |||
| package com.ffii.fpsms.modules.deliveryOrder.web | |||
| import com.ffii.core.response.RecordsRes | |||
| import com.ffii.core.utils.CriteriaArgsBuilder | |||
| import com.ffii.core.utils.PagingUtils | |||
| import com.ffii.fpsms.modules.master.web.models.MessageResponse | |||
| import com.ffii.fpsms.modules.pickOrder.entity.PickOrderRepository | |||
| import com.ffii.fpsms.modules.pickOrder.entity.projection.PickOrderInfo | |||
| import com.ffii.fpsms.modules.pickOrder.service.PickOrderService | |||
| import com.ffii.fpsms.modules.pickOrder.web.models.* | |||
| import com.ffii.fpsms.modules.pickOrder.web.models.ConsoPickOrderRequest | |||
| import com.ffii.fpsms.modules.pickOrder.web.models.ConsoPickOrderResponse | |||
| import com.ffii.fpsms.modules.pickOrder.web.models.ReleaseConsoPickOrderRequest | |||
| import com.ffii.fpsms.modules.pickOrder.web.models.SearchPickOrderRequest | |||
| import com.ffii.fpsms.modules.pickOrder.web.models.SavePickOrderGroupRequest | |||
| import jakarta.servlet.http.HttpServletRequest | |||
| import jakarta.validation.Valid | |||
| import org.springframework.data.domain.Page | |||
| import org.springframework.data.domain.PageRequest | |||
| import org.springframework.data.domain.Pageable | |||
| import org.springframework.http.ResponseEntity | |||
| import org.springframework.web.bind.annotation.GetMapping | |||
| import org.springframework.web.bind.annotation.ModelAttribute | |||
| import org.springframework.web.bind.annotation.PathVariable | |||
| import org.springframework.web.bind.annotation.PostMapping | |||
| import org.springframework.web.bind.annotation.RequestBody | |||
| import org.springframework.web.bind.annotation.RequestMapping | |||
| import org.springframework.web.bind.annotation.RequestParam | |||
| import org.springframework.web.bind.annotation.RestController | |||
| import java.time.DateTimeException | |||
| import java.time.LocalDateTime | |||
| import java.time.format.DateTimeFormatter | |||
| import java.time.LocalDate | |||
| import com.ffii.fpsms.modules.deliveryOrder.service.DoPickOrderService | |||
| import com.ffii.fpsms.modules.deliveryOrder.entity.DoPickOrderRepository | |||
| import com.ffii.fpsms.modules.deliveryOrder.web.models.AssignByStoreRequest | |||
| @RestController | |||
| @RequestMapping("/doPickOrder") | |||
| class DoPickOrderController( | |||
| private val doPickOrderService: DoPickOrderService, | |||
| private val doPickOrderRepository: DoPickOrderRepository, | |||
| ) { | |||
| @PostMapping("/assign-by-store") | |||
| fun assignPickOrderByStore(@RequestBody request: AssignByStoreRequest): MessageResponse { | |||
| return doPickOrderService.assignByStore(request) | |||
| } | |||
| @PostMapping("/release-assigned-by-store") | |||
| fun releaseAssignedPickOrderByStore(@RequestBody request: AssignByStoreRequest): MessageResponse { | |||
| return doPickOrderService.releaseAssignedByStore(request) | |||
| } | |||
| } | |||
| @@ -0,0 +1,6 @@ | |||
| package com.ffii.fpsms.modules.deliveryOrder.web.models | |||
| data class AssignByStoreRequest( | |||
| val storeId: String, // "2/F" or "4/F" | |||
| val assignTo: Long | |||
| ) | |||
| @@ -1,5 +1,6 @@ | |||
| package com.ffii.fpsms.modules.deliveryOrder.web.models | |||
| data class ReleaseDoRequest( | |||
| val id: Long | |||
| val id: Long, | |||
| val userId: Long | |||
| ) | |||
| @@ -0,0 +1,63 @@ | |||
| --liquibase formatted sql | |||
| --changeset enson:update | |||
| CREATE TABLE `do_pick_order` ( | |||
| `id` int NOT NULL AUTO_INCREMENT, | |||
| `store_id` varchar(10) NOT NULL, | |||
| `ticket_no` varchar(50) NOT NULL, | |||
| `ticket_status` enum('pending','completed') DEFAULT 'pending', | |||
| `truck_id` int NOT NULL, | |||
| `truck_departure_time` TIME NOT NULL, | |||
| `item_id` int NOT NULL, | |||
| `shop_id` int DEFAULT NULL, | |||
| `shop_po_supplier_id` int NOT NULL, | |||
| `handled_by` int NOT NULL, | |||
| `created` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, | |||
| `createdBy` varchar(30) DEFAULT NULL, | |||
| `version` int NOT NULL DEFAULT '0', | |||
| `modified` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, | |||
| `modifiedBy` varchar(30) DEFAULT NULL, | |||
| `deleted` tinyint(1) NOT NULL DEFAULT '0', | |||
| PRIMARY KEY (`id`), | |||
| KEY `IDX_DO_PICK_ORDER_TRUCK` (`truck_id`), | |||
| KEY `IDX_DO_PICK_ORDER_ITEM` (`item_id`), | |||
| KEY `IDX_DO_PICK_ORDER_SHOP` (`shop_id`), | |||
| KEY `IDX_DO_PICK_ORDER_SHOP_SUPP` (`shop_po_supplier_id`), | |||
| KEY `IDX_DO_PICK_ORDER_HANDLED_BY` (`handled_by`), | |||
| CONSTRAINT `FK_DO_PICK_ORDER_ON_HANDLED_BY` FOREIGN KEY (`handled_by`) REFERENCES `user` (`id`), | |||
| CONSTRAINT `FK_DO_PICK_ORDER_ON_ITEM` FOREIGN KEY (`item_id`) REFERENCES `items` (`id`), | |||
| CONSTRAINT `FK_DO_PICK_ORDER_ON_SHOP` FOREIGN KEY (`shop_id`) REFERENCES `shop` (`id`), | |||
| CONSTRAINT `FK_DO_PICK_ORDER_ON_SHOP_PO_SUPPLIER` FOREIGN KEY (`shop_po_supplier_id`) REFERENCES `shop` (`id`), | |||
| CONSTRAINT `FK_DO_PICK_ORDER_ON_TRUCK` FOREIGN KEY (`truck_id`) REFERENCES `Truck` (`id`) | |||
| ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; | |||
| CREATE TABLE `do_pick_order_record` ( | |||
| `id` int NOT NULL AUTO_INCREMENT, | |||
| `store_id` varchar(10) NOT NULL, | |||
| `ticket_no` varchar(50) NOT NULL, | |||
| `ticket_status` enum('pending','completed') DEFAULT 'pending', | |||
| `truck_id` int NOT NULL, | |||
| `truck_departure_time` TIME NOT NULL, | |||
| `item_id` int NOT NULL, | |||
| `shop_id` int DEFAULT NULL, | |||
| `shop_po_supplier_id` int NOT NULL, | |||
| `handled_by` int NOT NULL, | |||
| `created` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, | |||
| `createdBy` varchar(30) DEFAULT NULL, | |||
| `version` int NOT NULL DEFAULT '0', | |||
| `modified` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, | |||
| `modifiedBy` varchar(30) DEFAULT NULL, | |||
| `deleted` tinyint(1) NOT NULL DEFAULT '0', | |||
| PRIMARY KEY (`id`), | |||
| KEY `IDX_DO_PICK_ORDER_REC_TRUCK` (`truck_id`), | |||
| KEY `IDX_DO_PICK_ORDER_REC_ITEM` (`item_id`), | |||
| KEY `IDX_DO_PICK_ORDER_REC_SHOP` (`shop_id`), | |||
| KEY `IDX_DO_PICK_ORDER_REC_SHOP_SUPP` (`shop_po_supplier_id`), | |||
| KEY `IDX_DO_PICK_ORDER_REC_HANDLED_BY` (`handled_by`), | |||
| CONSTRAINT `FK_DO_PICK_ORDER_REC_ON_HANDLED_BY` FOREIGN KEY (`handled_by`) REFERENCES `user` (`id`), | |||
| CONSTRAINT `FK_DO_PICK_ORDER_REC_ON_ITEM` FOREIGN KEY (`item_id`) REFERENCES `items` (`id`), | |||
| CONSTRAINT `FK_DO_PICK_ORDER_REC_ON_SHOP` FOREIGN KEY (`shop_id`) REFERENCES `shop` (`id`), | |||
| CONSTRAINT `FK_DO_PICK_ORDER_REC_ON_SHOP_PO_SUPPLIER` FOREIGN KEY (`shop_po_supplier_id`) REFERENCES `shop` (`id`), | |||
| CONSTRAINT `FK_DO_PICK_ORDER_REC_ON_TRUCK` FOREIGN KEY (`truck_id`) REFERENCES `Truck` (`id`) | |||
| ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; | |||