package com.ffii.fpsms.modules.stock.entity.projection

import com.ffii.fpsms.modules.master.entity.UomConversion
import com.ffii.fpsms.modules.stock.entity.InventoryLot
import org.springframework.beans.factory.annotation.Value
import java.math.BigDecimal
import java.time.LocalDate
import java.time.LocalDateTime

interface StockInLineInfo {
    val id: Long
    @get:Value("#{target.item?.id}")
    val itemId: Long
    @get:Value("#{target.item?.name}")
    val itemName: String?
    @get:Value("#{target.item?.LocationCode}")
    val locationCode: String?
    val itemNo: String
    @get:Value("#{target.stockIn?.id}")
    val stockInId: Long
    @get:Value("#{target.purchaseOrderLine?.id}")
    val purchaseOrderLineId: Long?
    @get:Value("#{target.purchaseOrder?.id}")
    val purchaseOrderId: Long?
    @get:Value("#{target.jobOrder?.id}")
    val jobOrderId: Long?
    @get:Value("#{target.receivedQtyM18ForPol}")
    val receivedQty: BigDecimal?
    val demandQty: BigDecimal?
    val acceptedQty: BigDecimal
    @get:Value("#{target.acceptedQtyM18}")
    val purchaseAcceptedQty: BigDecimal?
    @get:Value("#{target.purchaseOrderLine?.qtyM18}")
    val qty: BigDecimal?
    val price: BigDecimal?
    val priceUnit: BigDecimal?
    @get:Value("#{target.item?.shelfLife}")
    val shelfLife: Double?
    val receiptDate: LocalDateTime?
    val productionDate: LocalDateTime?
    val expiryDate: LocalDate?
    val status: String
    var lotNo: String?
    var productLotNo: String?
    @get:Value("#{target.stockIn?.supplier?.name}")
    val supplier: String?
    @get:Value("#{target.item?.itemUoms.^[salesUnit == true && deleted == false]?.uom}") //TODO review
    val uom: UomConversion?
    @get:Value("#{target.purchaseOrderLine?.uomM18?.udfudesc}")
    val purchaseUomDesc: String?
    @get:Value("#{target.item?.itemUoms.^[stockUnit == true && deleted == false]?.uom?.udfudesc}")
    val stockUomDesc: String?
    @get:Value("#{target.stockIn?.purchaseOrder?.code}")
    val poCode: String?
    @get:Value("#{target.jobOrder?.code}")
    val joCode: String?
    @get:Value("#{target.item?.type}")
    val itemType: String?
    val dnNo: String?
    @get:Value("#{target.jobOrder?.bom?.description}")
    val bomDescription: String?
    @get:Value("#{target.escalationLog.^[status.value == 'pending']?.handler?.id}")
    val handlerId: Long?
    @get:Value("#{target.inventoryLot?.inventoryLotLines ?: new java.util.ArrayList()}")
    val putAwayLines: List<PutAwayLineForSil>?
}

interface PutAwayLineForSil {
    val id: Long?;
    /** Stock qty (inventory lot line inQty) */
    @get:Value("#{target.inQty}")
    val stockQty: BigDecimal?;
    @get:Value("#{target.inQty " +
            "* ((target.inventoryLot.item.itemUoms.^[stockUnit == true && deleted == false]?.ratioN / target.inventoryLot.item.itemUoms.^[stockUnit == true && deleted == false]?.ratioD))" +
            "/ ((target.inventoryLot.item.itemUoms.^[purchaseUnit == true && deleted == false]?.ratioN / target.inventoryLot.item.itemUoms.^[purchaseUnit == true && deleted == false]?.ratioD))}")
    val qty: BigDecimal?;
    @get:Value("#{target.warehouse?.code} - #{target.warehouse?.name}")
    val warehouse: String?;
    @get:Value("#{target.warehouse?.id}")
    val warehouseId: Long?;
    @get:Value("#{target.warehouse?.code}")
    val warehouseCode: String?;
    @get:Value("#{target.warehouse?.name}")
    val warehouseName: String?;
    @get:Value("#{target.created}")
    val putawayDate: LocalDateTime?;
    @get:Value("#{target.createdBy}")
    val putawayUser: String?;

}