| @@ -8,9 +8,9 @@ import jakarta.validation.constraints.Size | |||
| @Table(name = "equipment") | |||
| @Entity | |||
| open class Equipment : BaseEntity<Long>() { | |||
| @Size(max = 30) | |||
| @Size(max = 255) | |||
| @NotNull | |||
| @Column(name = "code", nullable = false, length = 30) | |||
| @Column(name = "code", nullable = false, length = 255) | |||
| open var code: String? = null | |||
| @Size(max = 30) | |||
| @@ -29,14 +29,14 @@ open class EquipmentDetail : BaseEntity<Long>() { | |||
| @Column(name = "repairAndMaintenanceRemarks", nullable = true, length = 255) | |||
| open var repairAndMaintenanceRemarks: String? = null | |||
| @Size(max = 30) | |||
| @Size(max = 255) | |||
| @NotNull | |||
| @Column(name = "code", nullable = false, length = 30) | |||
| @Column(name = "code", nullable = false, length = 255) | |||
| open var code: String? = null | |||
| @Size(max = 30) | |||
| @Size(max = 255) | |||
| @NotNull | |||
| @Column(name = "name", nullable = false, length = 30) | |||
| @Column(name = "name", nullable = false, length = 255) | |||
| open var name: String? = null | |||
| @Size(max = 500) | |||
| @@ -9,6 +9,7 @@ interface EquipmentDetailRepository : AbstractRepository<EquipmentDetail, Long> | |||
| fun findByCode(code: String): EquipmentDetail? | |||
| fun findByIdAndDeletedFalse(id: Long): EquipmentDetail?; | |||
| fun findByNameAndDeletedIsFalse(name: String): EquipmentDetail?; | |||
| fun findByCodeAndDeletedIsFalse(code: String): EquipmentDetail?; | |||
| fun findByDescriptionAndDeletedIsFalse(description: String): EquipmentDetail?; | |||
| fun findByEquipmentTypeIdAndDeletedFalse(equipmentTypeId: Long): List<EquipmentDetail>; | |||
| @@ -36,42 +36,94 @@ open class EquipmentDetailService( | |||
| e.lastRepairAndMaintenanceDate AS lastRepairAndMaintenanceDate, | |||
| e.repairAndMaintenanceRemarks AS repairAndMaintenanceRemarks | |||
| FROM equipment_detail e | |||
| WHERE e.deleted = FALSE | |||
| LEFT JOIN equipment eq ON e.equipmentTypeId = eq.id | |||
| """ | |||
| ) | |||
| val whereConditions = mutableListOf<String>() | |||
| // Handle combined search for code and equipmentCode (OR logic) | |||
| whereConditions.add("e.deleted = FALSE") | |||
| whereConditions.add("eq.deleted = FALSE") | |||
| val searchTerm = args["equipmentCode"] as? String | |||
| val codeTerm = args["code"] as? String | |||
| if (searchTerm != null && codeTerm != null && searchTerm == codeTerm) { | |||
| // When both are provided with the same value, search using OR | |||
| sql.append(" AND (LOWER(e.code) LIKE LOWER(:equipmentCode) OR LOWER(e.equipmentCode) LIKE LOWER(:equipmentCode)) ") | |||
| whereConditions.add("(LOWER(e.code) LIKE LOWER(:equipmentCode) OR LOWER(e.equipmentCode) LIKE LOWER(:equipmentCode))") | |||
| } else { | |||
| // Otherwise, use individual conditions | |||
| if (codeTerm != null && (searchTerm == null || searchTerm != codeTerm)) { | |||
| sql.append(" AND LOWER(e.code) LIKE LOWER(:code) ") | |||
| whereConditions.add("LOWER(e.code) LIKE LOWER(:code)") | |||
| } | |||
| if (searchTerm != null && (codeTerm == null || searchTerm != codeTerm)) { | |||
| sql.append(" AND LOWER(e.equipmentCode) LIKE LOWER(:equipmentCode) ") | |||
| whereConditions.add("LOWER(e.equipmentCode) LIKE LOWER(:equipmentCode)") | |||
| } | |||
| } | |||
| if (args.containsKey("id")) { | |||
| sql.append(" AND e.id like :id ") | |||
| whereConditions.add("e.id like :id") | |||
| } | |||
| if (args.containsKey("name")) { | |||
| sql.append(" AND LOWER(e.name) LIKE LOWER(:name) ") | |||
| whereConditions.add("LOWER(e.name) LIKE LOWER(:name)") | |||
| } | |||
| if (args.containsKey("description")) { | |||
| sql.append(" AND e.description like :description ") | |||
| whereConditions.add("e.description = :description") | |||
| } | |||
| if (args.containsKey("repairAndMaintenanceStatus")) { | |||
| sql.append(" AND e.repairAndMaintenanceStatus = :repairAndMaintenanceStatus ") | |||
| whereConditions.add("e.repairAndMaintenanceStatus = :repairAndMaintenanceStatus") | |||
| } | |||
| if (whereConditions.isNotEmpty()) { | |||
| sql.append("WHERE ${whereConditions.joinToString(" AND ")}") | |||
| } | |||
| return jdbcDao.queryForList(sql.toString(), args) | |||
| } | |||
| open fun getEquipmentDetailsByEquipmentId(equipmentId: Long): List<Map<String, Any>> { | |||
| val sql = """ | |||
| SELECT | |||
| ed.id AS id, | |||
| ed.code AS code, | |||
| ed.name AS name, | |||
| ed.description AS description, | |||
| ed.equipmentCode AS equipmentCode, | |||
| ed.repairAndMaintenanceStatus AS repairAndMaintenanceStatus, | |||
| ed.latestRepairAndMaintenanceDate AS latestRepairAndMaintenanceDate, | |||
| ed.lastRepairAndMaintenanceDate AS lastRepairAndMaintenanceDate, | |||
| ed.repairAndMaintenanceRemarks AS repairAndMaintenanceRemarks | |||
| FROM equipment_detail ed | |||
| LEFT JOIN equipment e ON ed.equipmentTypeId = e.id | |||
| WHERE ed.deleted = FALSE | |||
| AND e.id = :equipmentId | |||
| AND e.deleted = FALSE | |||
| """ | |||
| val args = mapOf("equipmentId" to equipmentId) | |||
| return jdbcDao.queryForList(sql, args) | |||
| } | |||
| open fun getEquipmentDetailsByDescriptionIncludingDeleted(description: String): List<Map<String, Any>> { | |||
| val sql = """ | |||
| SELECT | |||
| e.id AS id, | |||
| e.code AS code, | |||
| e.name AS name, | |||
| e.description AS description, | |||
| e.equipmentCode AS equipmentCode, | |||
| e.repairAndMaintenanceStatus AS repairAndMaintenanceStatus, | |||
| e.latestRepairAndMaintenanceDate AS latestRepairAndMaintenanceDate, | |||
| e.lastRepairAndMaintenanceDate AS lastRepairAndMaintenanceDate, | |||
| e.repairAndMaintenanceRemarks AS repairAndMaintenanceRemarks | |||
| FROM equipment_detail e | |||
| WHERE e.description = :description | |||
| """ | |||
| val args = mapOf("description" to description) | |||
| return jdbcDao.queryForList(sql, args) | |||
| } | |||
| open fun findById(id: Long): EquipmentDetail? { | |||
| return equipmentDetailRepository.findByIdAndDeletedFalse(id) | |||
| } | |||
| @@ -96,61 +148,52 @@ open class EquipmentDetailService( | |||
| val equipmentDetail = findById(id) | |||
| ?: throw IllegalArgumentException("Equipment detail not found with id: $id") | |||
| // Store the previous status and latest date before updating | |||
| val previousStatus = equipmentDetail.repairAndMaintenanceStatus | |||
| val previousLatestDate = equipmentDetail.latestRepairAndMaintenanceDate | |||
| // Update status and remarks | |||
| equipmentDetail.repairAndMaintenanceStatus = request.repairAndMaintenanceStatus | |||
| equipmentDetail.repairAndMaintenanceRemarks = request.repairAndMaintenanceRemarks | |||
| // Handle date updates based on status change | |||
| when { | |||
| // Changing from "是" (true) to "否" (false) | |||
| previousStatus == true && request.repairAndMaintenanceStatus == false -> { | |||
| // Save current latestRepairAndMaintenanceDate to lastRepairAndMaintenanceDate | |||
| equipmentDetail.lastRepairAndMaintenanceDate = previousLatestDate | |||
| // Update latestRepairAndMaintenanceDate to current time | |||
| equipmentDetail.latestRepairAndMaintenanceDate = LocalDateTime.now() | |||
| } | |||
| // Changing from "否" (false) to "是" (true) | |||
| // Keep dates unchanged - no action needed | |||
| previousStatus == false && request.repairAndMaintenanceStatus == true -> { | |||
| // Dates remain unchanged | |||
| } | |||
| // Other cases (null to true/false, or same status) - no date changes | |||
| } | |||
| return equipmentDetailRepository.saveAndFlush(equipmentDetail) | |||
| } | |||
| /* | |||
| @Transactional | |||
| open fun saveEquipmentDetail(request: NewEquipmentDetailRequest): EquipmentDetail { | |||
| if (request.code.isNullOrBlank()) { | |||
| throw IllegalArgumentException("Equipment detail code cannot be null or blank") | |||
| } | |||
| val duplicated = equipmentDetailRepository.findByCodeAndDeletedIsFalse(request.code!!) | |||
| if (duplicated != null && duplicated.id != request.id) { | |||
| throw IllegalArgumentException("Equipment detail code already exists") | |||
| if (request.id != null && request.id > 0) { | |||
| val duplicated = equipmentDetailRepository.findByCodeAndDeletedIsFalse(request.code!!) | |||
| if (duplicated != null && duplicated.id != request.id) { | |||
| throw IllegalArgumentException("Equipment detail code already exists") | |||
| } | |||
| } | |||
| val entity = if (request.id != null && request.id > 0) { | |||
| equipmentDetailRepository.findByIdAndDeletedFalse(request.id) ?: EquipmentDetail() | |||
| } else { | |||
| EquipmentDetail() | |||
| } | |||
| entity.code = request.code | |||
| entity.name = request.name | |||
| entity.description = request.description | |||
| entity.equipmentTypeId = request.equipmentTypeId | |||
| entity.equipmentCode = request.equipmentCode | |||
| entity.repairAndMaintenanceStatus = request.repairAndMaintenanceStatus ?: false | |||
| return equipmentDetailRepository.saveAndFlush(entity) | |||
| } | |||
| */ | |||
| @Transactional | |||
| open fun deleteEquipmentDetail(id: Long) { | |||
| val equipmentDetail = equipmentDetailRepository.findByIdAndDeletedFalse(id) | |||
| @@ -0,0 +1,86 @@ | |||
| package com.ffii.fpsms.modules.master.service | |||
| import com.ffii.core.utils.PdfUtils | |||
| import com.ffii.core.utils.QrCodeUtil | |||
| import com.ffii.fpsms.modules.master.entity.EquipmentDetailRepository | |||
| import com.ffii.fpsms.modules.master.web.ExportEquipmentQrCodeRequest | |||
| import net.sf.jasperreports.engine.JasperCompileManager | |||
| import net.sf.jasperreports.engine.JasperPrint | |||
| import org.springframework.core.io.ClassPathResource | |||
| import org.springframework.stereotype.Service | |||
| import java.io.FileNotFoundException | |||
| import java.awt.GraphicsEnvironment | |||
| import kotlinx.serialization.json.Json | |||
| import kotlinx.serialization.encodeToString | |||
| @Service | |||
| class EquipmentQrCodeService( | |||
| private val equipmentDetailRepository: EquipmentDetailRepository | |||
| ) { | |||
| fun exportEquipmentQrCode(request: ExportEquipmentQrCodeRequest): Map<String, Any> { | |||
| val QRCODE_HANDLE_PDF = "qrCodeHandle/equipment_QrHandle.jrxml" | |||
| val resource = ClassPathResource(QRCODE_HANDLE_PDF) | |||
| if (!resource.exists()) { | |||
| throw FileNotFoundException("Report file not found: $QRCODE_HANDLE_PDF") | |||
| } | |||
| val inputStream = resource.inputStream | |||
| val qrCodeHandleReport = JasperCompileManager.compileReport(inputStream) | |||
| val equipmentDetails = equipmentDetailRepository.findAllById(request.equipmentDetailIds) | |||
| if (equipmentDetails.isEmpty()) { | |||
| throw IllegalArgumentException("No equipment details found for the provided equipment detail IDs: ${request.equipmentDetailIds}") | |||
| } | |||
| val fields = mutableListOf<MutableMap<String, Any>>() | |||
| for (equipmentDetail in equipmentDetails) { | |||
| val field = mutableMapOf<String, Any>() | |||
| val code = equipmentDetail.code ?: "" | |||
| val equipmentCodeFromDetail = equipmentDetail.equipmentCode ?: "" | |||
| if (code.isBlank() && equipmentCodeFromDetail.isBlank()) { | |||
| continue | |||
| } | |||
| val qrContentMap = mapOf("equipmentCode" to equipmentCodeFromDetail) | |||
| val qrCodeContent = Json.encodeToString(qrContentMap) | |||
| val qrCodeImage = QrCodeUtil.generateQRCodeImage(qrCodeContent) | |||
| field["username"] = code | |||
| field["staffNo"] = code | |||
| field["qrCode"] = qrCodeImage | |||
| field["code"] = code | |||
| fields.add(field) | |||
| } | |||
| if (fields.isEmpty()) { | |||
| throw IllegalArgumentException("No valid equipment details found for the provided equipment detail IDs: ${request.equipmentDetailIds}") | |||
| } | |||
| val params: MutableMap<String, Any> = mutableMapOf() | |||
| val availableFonts = GraphicsEnvironment.getLocalGraphicsEnvironment().availableFontFamilyNames | |||
| val chineseFont = availableFonts.find { | |||
| it.contains("SimSun", ignoreCase = true) || | |||
| it.contains("Microsoft YaHei", ignoreCase = true) || | |||
| it.contains("STSong", ignoreCase = true) || | |||
| it.contains("SimHei", ignoreCase = true) | |||
| } ?: "Arial Unicode MS" | |||
| params["net.sf.jasperreports.default.pdf.encoding"] = "Identity-H" | |||
| params["net.sf.jasperreports.default.pdf.embedded"] = true | |||
| params["net.sf.jasperreports.default.pdf.font.name"] = chineseFont | |||
| val firstEquipmentDetail = equipmentDetails.firstOrNull() | |||
| return mapOf( | |||
| "report" to PdfUtils.fillReport(qrCodeHandleReport, fields, params), | |||
| "fileName" to (firstEquipmentDetail?.code ?: "equipment_qrcode") | |||
| ) | |||
| } | |||
| } | |||
| @@ -7,6 +7,7 @@ import com.ffii.fpsms.modules.master.entity.EquipmentRepository | |||
| import org.springframework.stereotype.Service | |||
| import org.springframework.transaction.annotation.Transactional | |||
| import com.ffii.fpsms.modules.master.web.models.NewEquipmentRequest | |||
| @Service | |||
| open class EquipmentService( | |||
| private val jdbcDao: JdbcDao, | |||
| @@ -18,40 +19,40 @@ open class EquipmentService( | |||
| } | |||
| open fun getEquipmentsByPage(args: Map<String, Any>): List<Map<String, Any>> { | |||
| val sql = StringBuilder( | |||
| """ | |||
| SELECT | |||
| e.id AS id, | |||
| e.code AS code, | |||
| e.name AS name, | |||
| e.description AS description, | |||
| e.equipmentTypeId AS equipmentTypeId, | |||
| ed.repairAndMaintenanceStatus AS repairAndMaintenanceStatus, | |||
| ed.latestRepairAndMaintenanceDate AS latestRepairAndMaintenanceDate, | |||
| ed.lastRepairAndMaintenanceDate AS lastRepairAndMaintenanceDate, | |||
| ed.repairAndMaintenanceRemarks AS repairAndMaintenanceRemarks | |||
| FROM equipment e | |||
| LEFT JOIN equipment_detail ed ON e.code = ed.equipmentCode | |||
| WHERE e.deleted = FALSE | |||
| """ | |||
| ) | |||
| if (args.containsKey("code")) { | |||
| sql.append(" AND e.code like :code ") | |||
| } | |||
| if (args.containsKey("id")) { | |||
| sql.append(" AND e.id like :id ") | |||
| } | |||
| if (args.containsKey("name")) { | |||
| sql.append(" AND e.name like :name ") | |||
| } | |||
| if (args.containsKey("description")) { | |||
| sql.append(" AND e.description like :description ") | |||
| } | |||
| if (args.containsKey("equipmentTypeId")) { | |||
| sql.append(" AND e.equipmentTypeId like :equipmentTypeId ") | |||
| val sql = StringBuilder( | |||
| """ | |||
| SELECT | |||
| e.id AS id, | |||
| e.code AS code, | |||
| e.name AS name, | |||
| e.description AS description, | |||
| e.equipmentTypeId AS equipmentTypeId, | |||
| ed.repairAndMaintenanceStatus AS repairAndMaintenanceStatus, | |||
| ed.latestRepairAndMaintenanceDate AS latestRepairAndMaintenanceDate, | |||
| ed.lastRepairAndMaintenanceDate AS lastRepairAndMaintenanceDate, | |||
| ed.repairAndMaintenanceRemarks AS repairAndMaintenanceRemarks | |||
| FROM equipment e | |||
| LEFT JOIN equipment_detail ed ON e.code = ed.equipmentCode | |||
| WHERE e.deleted = FALSE | |||
| """ | |||
| ) | |||
| if (args.containsKey("code")) { | |||
| sql.append(" AND e.code like :code ") | |||
| } | |||
| if (args.containsKey("id")) { | |||
| sql.append(" AND e.id like :id ") | |||
| } | |||
| if (args.containsKey("name")) { | |||
| sql.append(" AND e.name like :name ") | |||
| } | |||
| if (args.containsKey("description")) { | |||
| sql.append(" AND e.description like :description ") | |||
| } | |||
| if (args.containsKey("equipmentTypeId")) { | |||
| sql.append(" AND e.equipmentTypeId like :equipmentTypeId ") | |||
| } | |||
| return jdbcDao.queryForList(sql.toString(), args) | |||
| } | |||
| return jdbcDao.queryForList(sql.toString(), args) | |||
| } | |||
| open fun findById(id: Long): Equipment? { | |||
| return equipmentRepository.findByIdAndDeletedFalse(id) | |||
| @@ -69,10 +70,8 @@ open class EquipmentService( | |||
| return equipmentRepository.findByDescriptionAndDeletedIsFalse(description) | |||
| } | |||
| @Transactional | |||
| open fun saveEquipment(request: NewEquipmentRequest): Equipment { | |||
| if (request.code.isNullOrBlank()) { | |||
| throw IllegalArgumentException("Equipment type code cannot be null or blank") | |||
| } | |||
| @@ -81,26 +80,23 @@ open class EquipmentService( | |||
| throw IllegalArgumentException("Equipment type code already exists") | |||
| } | |||
| val entity = if (request.id != null && request.id > 0) { | |||
| equipmentRepository.findByIdAndDeletedFalse(request.id) ?: Equipment() | |||
| } else { | |||
| Equipment() | |||
| } | |||
| entity.code = request.code | |||
| entity.name = request.name | |||
| entity.description = request.description | |||
| entity.EquipmentDetail= request.equipmentType | |||
| entity.EquipmentDetail = request.equipmentType | |||
| return equipmentRepository.saveAndFlush(entity) | |||
| } | |||
| @Transactional | |||
| open fun deleteEquipment(id: Long) { | |||
| val Equipment = equipmentRepository.findByIdAndDeletedFalse(id) | |||
| Equipment?.let { et -> | |||
| val equipment = equipmentRepository.findByIdAndDeletedFalse(id) | |||
| equipment?.let { et -> | |||
| et.deleted = true | |||
| equipmentRepository.saveAndFlush(et) | |||
| } | |||
| @@ -5,15 +5,22 @@ import com.ffii.core.utils.CriteriaArgsBuilder | |||
| import com.ffii.core.utils.PagingUtils | |||
| import com.ffii.fpsms.modules.master.entity.Equipment | |||
| import com.ffii.fpsms.modules.master.service.EquipmentService | |||
| import com.ffii.fpsms.modules.master.service.EquipmentQrCodeService | |||
| import jakarta.servlet.http.HttpServletRequest | |||
| import jakarta.servlet.http.HttpServletResponse | |||
| import jakarta.validation.Valid | |||
| import org.springframework.web.bind.annotation.* | |||
| import java.util.Collections.emptyList | |||
| import com.ffii.fpsms.modules.master.web.models.NewEquipmentRequest | |||
| import net.sf.jasperreports.engine.JasperExportManager | |||
| import net.sf.jasperreports.engine.JasperPrint | |||
| import java.io.OutputStream | |||
| @RestController | |||
| @RequestMapping("/Equipment") | |||
| class EquipmentController( | |||
| private val equipmentService: EquipmentService | |||
| private val equipmentService: EquipmentService, | |||
| private val equipmentQrCodeService: EquipmentQrCodeService | |||
| ) { | |||
| @GetMapping | |||
| fun allEquipment(): List<Equipment> { | |||
| @@ -73,4 +80,17 @@ fun getAllEquipmentByPage( | |||
| equipmentService.deleteEquipment(id) | |||
| } | |||
| @PostMapping("/export-qrcode") | |||
| fun exportQrCode(@Valid @RequestBody request: ExportEquipmentQrCodeRequest, response: HttpServletResponse) { | |||
| response.characterEncoding = "utf-8" | |||
| response.contentType = "application/pdf" | |||
| val out: OutputStream = response.outputStream | |||
| val pdf = equipmentQrCodeService.exportEquipmentQrCode(request) | |||
| val jasperPrint = pdf["report"] as JasperPrint | |||
| val fileName = pdf["fileName"] as String | |||
| response.addHeader("Content-Disposition", "attachment; filename=\"${fileName}_qrcode.pdf\"") | |||
| out.write(JasperExportManager.exportReportToPdf(jasperPrint)) | |||
| out.flush() | |||
| } | |||
| } | |||
| @@ -63,6 +63,18 @@ fun getAllEquipmentDetailByPage( | |||
| return equipmentDetailService.findById(id) | |||
| } | |||
| @GetMapping("/byEquipmentId/{equipmentId}") | |||
| fun getEquipmentDetailsByEquipmentId(@PathVariable equipmentId: Long): RecordsRes<Map<String, Any>> { | |||
| val fullList = equipmentDetailService.getEquipmentDetailsByEquipmentId(equipmentId) ?: emptyList() | |||
| return RecordsRes(fullList as List<Map<String, Any>>, fullList.size) | |||
| } | |||
| @GetMapping("/byDescriptionIncludingDeleted/{description}") | |||
| fun getEquipmentDetailsByDescriptionIncludingDeleted(@PathVariable description: String): RecordsRes<Map<String, Any>> { | |||
| val fullList = equipmentDetailService.getEquipmentDetailsByDescriptionIncludingDeleted(description) ?: emptyList() | |||
| return RecordsRes(fullList as List<Map<String, Any>>, fullList.size) | |||
| } | |||
| @PutMapping("/update/{id}") | |||
| fun updateMaintenanceAndRepair( | |||
| @PathVariable id: Long, | |||
| @@ -70,12 +82,10 @@ fun getAllEquipmentDetailByPage( | |||
| ): EquipmentDetail { | |||
| return equipmentDetailService.updateMaintenanceAndRepair(id, request) | |||
| } | |||
| /* | |||
| @PostMapping("/save") | |||
| fun saveEquipmentDetail(@Valid @RequestBody equipmentDetail: NewEquipmentDetailRequest): EquipmentDetail { | |||
| return equipmentDetailService.saveEquipmentDetail(equipmentDetail) | |||
| } | |||
| */ | |||
| @DeleteMapping("/delete/{id}") | |||
| fun deleteEquipmentDetail(@PathVariable id: Long) { | |||
| @@ -0,0 +1,5 @@ | |||
| package com.ffii.fpsms.modules.master.web | |||
| data class ExportEquipmentQrCodeRequest( | |||
| val equipmentDetailIds: List<Long> | |||
| ) | |||
| @@ -19,6 +19,9 @@ data class NewEquipmentDetailRequest( | |||
| val id: Long?, | |||
| val description: String?, | |||
| val equipmentTypeId: Long?, | |||
| val equipmentCode: String?, | |||
| val repairAndMaintenanceStatus: Boolean?, | |||
| // val type: List<NewTypeRequest>?, | |||
| // val uom: List<NewUomRequest>?, | |||
| // val weightUnit: List<NewWeightUnitRequest>?, | |||
| @@ -0,0 +1,43 @@ | |||
| <?xml version="1.0" encoding="UTF-8"?> | |||
| <!-- Created with Jaspersoft Studio version 6.21.3.final using JasperReports Library version 6.21.3-4a3078d20785ebe464f18037d738d12fc98c13cf --> | |||
| <jasperReport xmlns="http://jasperreports.sourceforge.net/jasperreports" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://jasperreports.sourceforge.net/jasperreports http://jasperreports.sourceforge.net/xsd/jasperreport.xsd" name="qrCodeHandle" pageWidth="595" pageHeight="842" columnWidth="555" leftMargin="20" rightMargin="20" topMargin="80" bottomMargin="20" uuid="c2f7cd27-3725-47ce-ac85-d8a38dc906fa"> | |||
| <property name="com.jaspersoft.studio.data.defaultdataadapter" value="One Empty Record"/> | |||
| <property name="com.jaspersoft.studio.unit." value="pixel"/> | |||
| <property name="com.jaspersoft.studio.unit.pageHeight" value="pixel"/> | |||
| <property name="com.jaspersoft.studio.unit.pageWidth" value="pixel"/> | |||
| <property name="com.jaspersoft.studio.unit.topMargin" value="pixel"/> | |||
| <property name="com.jaspersoft.studio.unit.bottomMargin" value="pixel"/> | |||
| <property name="com.jaspersoft.studio.unit.leftMargin" value="pixel"/> | |||
| <property name="com.jaspersoft.studio.unit.rightMargin" value="pixel"/> | |||
| <property name="com.jaspersoft.studio.unit.columnWidth" value="pixel"/> | |||
| <property name="com.jaspersoft.studio.unit.columnSpacing" value="pixel"/> | |||
| <queryString> | |||
| <![CDATA[]]> | |||
| </queryString> | |||
| <field name="username" class="java.lang.String"/> | |||
| <field name="staffNo" class="java.lang.String"/> | |||
| <field name="qrCode" class="java.awt.Image"/> | |||
| <field name="code" class="java.lang.String"/> | |||
| <background> | |||
| <band splitType="Stretch"/> | |||
| </background> | |||
| <detail> | |||
| <band height="670" splitType="Stretch"> | |||
| <textField isStretchWithOverflow="true" isBlankWhenNull="false"> | |||
| <reportElement stretchType="RelativeToTallestObject" x="37" y="0" width="480" height="120" uuid="e3faf8de-84ba-423f-b6cf-84ba21598686"> | |||
| <property name="com.jaspersoft.studio.unit.x" value="px"/> | |||
| <property name="com.jaspersoft.studio.unit.width" value="px"/> | |||
| <property name="com.jaspersoft.studio.unit.height" value="px"/> | |||
| </reportElement> | |||
| <textElement textAlignment="Center" verticalAlignment="Middle"> | |||
| <font size="34" isBold="true" fontName="微軟正黑體" pdfEncoding="Identity-H" isPdfEmbedded="true"/> | |||
| </textElement> | |||
| <textFieldExpression><![CDATA[$F{code}]]></textFieldExpression> | |||
| </textField> | |||
| <image> | |||
| <reportElement x="27" y="120" width="500" height="500" uuid="b1a8ee23-9f0f-4014-9996-e0025222dcd2"/> | |||
| <imageExpression><![CDATA[$F{qrCode}]]></imageExpression> | |||
| </image> | |||
| </band> | |||
| </detail> | |||
| </jasperReport> | |||