| @@ -30,6 +30,11 @@ public class SalaryEffective extends IdEntity<Long> { | |||||
| @NotNull | @NotNull | ||||
| private Salary salary; | private Salary salary; | ||||
| @ManyToOne | |||||
| @JoinColumn(name = "staffId") | |||||
| @NotNull | |||||
| private Staff staff; | |||||
| public Salary getSalary() { | public Salary getSalary() { | ||||
| return salary; | return salary; | ||||
| } | } | ||||
| @@ -37,4 +42,8 @@ public class SalaryEffective extends IdEntity<Long> { | |||||
| public void setSalary(Salary salary) { | public void setSalary(Salary salary) { | ||||
| this.salary = salary; | this.salary = salary; | ||||
| } | } | ||||
| public Staff getStaff() { return staff; } | |||||
| public void setStaff(Staff staff) { this.staff = staff; } | |||||
| } | } | ||||
| @@ -1,7 +1,11 @@ | |||||
| package com.ffii.tsms.modules.data.entity; | package com.ffii.tsms.modules.data.entity; | ||||
| import com.ffii.core.support.AbstractRepository; | import com.ffii.core.support.AbstractRepository; | ||||
| import org.springframework.data.repository.query.Param; | |||||
| import java.util.Optional; | |||||
| public interface SalaryEffectiveRepository extends AbstractRepository<SalaryEffective, Long> { | public interface SalaryEffectiveRepository extends AbstractRepository<SalaryEffective, Long> { | ||||
| Optional<SalaryEffective> findByStaffIdAndSalaryId(@Param("staffId") Long staffId, @Param("salaryId") Long salaryId); | |||||
| } | } | ||||
| @@ -51,10 +51,15 @@ public class Staff extends BaseEntity<Long> { | |||||
| @JoinColumn(name = "skillSetId") | @JoinColumn(name = "skillSetId") | ||||
| private Skill skill; | private Skill skill; | ||||
| // @NotNull | |||||
| // @ManyToOne | |||||
| // @JoinColumn(name = "salaryEffId") | |||||
| // private SalaryEffective salaryEffective; | |||||
| @NotNull | @NotNull | ||||
| @ManyToOne | @ManyToOne | ||||
| @JoinColumn(name = "salaryEffId") | |||||
| private SalaryEffective salaryEffective; | |||||
| @JoinColumn(name = "salaryId") | |||||
| private Salary salary; | |||||
| @ManyToOne | @ManyToOne | ||||
| @JoinColumn(name = "departmentId") | @JoinColumn(name = "departmentId") | ||||
| @@ -159,12 +164,12 @@ public class Staff extends BaseEntity<Long> { | |||||
| this.email = email; | this.email = email; | ||||
| } | } | ||||
| public SalaryEffective getSalaryEffective() { | |||||
| return salaryEffective; | |||||
| public Salary getSalary() { | |||||
| return salary; | |||||
| } | } | ||||
| public void setSalaryEffective(SalaryEffective salaryEffective) { | |||||
| this.salaryEffective = salaryEffective; | |||||
| public void setSalary(Salary salary) { | |||||
| this.salary = salary; | |||||
| } | } | ||||
| public Skill getSkill() { | public Skill getSkill() { | ||||
| @@ -30,7 +30,7 @@ open class CustomerService( | |||||
| } | } | ||||
| open fun findCustomer(id: Long): Customer { | open fun findCustomer(id: Long): Customer { | ||||
| return customerRepository.findById(id).orElseThrow() | |||||
| return customerRepository.findById(id).orElse(Customer()) | |||||
| } | } | ||||
| open fun findCustomerByCode(code: String): Optional<Customer> { | open fun findCustomerByCode(code: String): Optional<Customer> { | ||||
| @@ -4,12 +4,16 @@ import com.ffii.core.support.AbstractIdEntityService | |||||
| import com.ffii.core.support.JdbcDao | import com.ffii.core.support.JdbcDao | ||||
| import com.ffii.tsms.modules.data.entity.SalaryEffective | import com.ffii.tsms.modules.data.entity.SalaryEffective | ||||
| import com.ffii.tsms.modules.data.entity.SalaryEffectiveRepository | import com.ffii.tsms.modules.data.entity.SalaryEffectiveRepository | ||||
| import com.ffii.tsms.modules.data.entity.SalaryRepository | |||||
| import com.ffii.tsms.modules.data.entity.StaffRepository | |||||
| import org.springframework.stereotype.Service | import org.springframework.stereotype.Service | ||||
| import java.time.LocalDate | |||||
| @Service | @Service | ||||
| open class SalaryEffectiveService( | open class SalaryEffectiveService( | ||||
| private val salaryEffectiveRepository: SalaryEffectiveRepository, | private val salaryEffectiveRepository: SalaryEffectiveRepository, | ||||
| private val staffRepository: StaffRepository, | |||||
| private val salaryRepository: SalaryRepository, | |||||
| private val jdbcDao: JdbcDao, | private val jdbcDao: JdbcDao, | ||||
| ) : AbstractIdEntityService<SalaryEffective, Long, SalaryEffectiveRepository>(jdbcDao, salaryEffectiveRepository) { | ) : AbstractIdEntityService<SalaryEffective, Long, SalaryEffectiveRepository>(jdbcDao, salaryEffectiveRepository) { | ||||
| @@ -22,4 +26,41 @@ open class SalaryEffectiveService( | |||||
| // ) | // ) | ||||
| // return jdbcDao.queryForList(sql.toString(), args) | // return jdbcDao.queryForList(sql.toString(), args) | ||||
| // } | // } | ||||
| open fun findByStaffIdAndSalaryId(staffId: Long, salaryId: Long): SalaryEffective? { | |||||
| return salaryEffectiveRepository.findByStaffIdAndSalaryId(staffId, salaryId).orElse(null) | |||||
| } | |||||
| open fun findLatestSalaryIdByStaffId(staffId: Long): Long { | |||||
| val sql = StringBuilder("select salaryId from salary_effective where staffId = :staffId order by id desc limit 1") | |||||
| val result = jdbcDao.queryForInt(sql.toString(), mapOf("staffId" to staffId)) | |||||
| return if(result > 0) result.toLong() else -1 | |||||
| } | |||||
| open fun saveSalaryEffective (staffId: Long, salaryId: Long): SalaryEffective { | |||||
| val existSalaryEffective = findByStaffIdAndSalaryId(staffId, salaryId) | |||||
| if (existSalaryEffective != null) { | |||||
| val latestSalaryId = findLatestSalaryIdByStaffId(staffId) | |||||
| // If latest salary id is same as current salary id, then skip | |||||
| if (latestSalaryId == existSalaryEffective.salary.id) { | |||||
| return existSalaryEffective | |||||
| } | |||||
| } | |||||
| val staff = staffRepository.findById(staffId).orElseThrow() | |||||
| val salary = salaryRepository.findById(salaryId).orElseThrow() | |||||
| val salaryEffective = SalaryEffective().apply { | |||||
| date = LocalDate.now() | |||||
| this.staff = staff | |||||
| this.salary = salary | |||||
| } | |||||
| salaryEffectiveRepository.save(salaryEffective) | |||||
| return salaryEffective | |||||
| } | |||||
| } | } | ||||
| @@ -22,7 +22,9 @@ open class StaffsService( | |||||
| private val gradeRepository: GradeRepository, | private val gradeRepository: GradeRepository, | ||||
| private val teamRepository: TeamRepository, | private val teamRepository: TeamRepository, | ||||
| private val skillRepository: SkillRepository, | private val skillRepository: SkillRepository, | ||||
| private val salaryRepository: SalaryRepository, | |||||
| private val salaryEffectiveRepository: SalaryEffectiveRepository, | private val salaryEffectiveRepository: SalaryEffectiveRepository, | ||||
| private val salaryEffectiveService: SalaryEffectiveService, | |||||
| private val departmentRepository: DepartmentRepository, | private val departmentRepository: DepartmentRepository, | ||||
| private val jdbcDao: JdbcDao, | private val jdbcDao: JdbcDao, | ||||
| private val passwordEncoder: PasswordEncoder | private val passwordEncoder: PasswordEncoder | ||||
| @@ -73,10 +75,11 @@ open class StaffsService( | |||||
| val currentPosition = positionRepository.findById(req.currentPositionId).orElseThrow() | val currentPosition = positionRepository.findById(req.currentPositionId).orElseThrow() | ||||
| val joinPosition = positionRepository.findById(req.joinPositionId).orElseThrow() | val joinPosition = positionRepository.findById(req.joinPositionId).orElseThrow() | ||||
| val company = companyRepository.findById(req.companyId).orElseThrow() | val company = companyRepository.findById(req.companyId).orElseThrow() | ||||
| val grade = gradeRepository.findById(req.gradeId).orElseThrow() | |||||
| val team = teamRepository.findById(req.teamId).orElseThrow() | |||||
| val skill = skillRepository.findById(req.skillSetId).orElseThrow() | |||||
| val salaryEffective = salaryEffectiveRepository.findById(req.salaryEffId).orElseThrow() | |||||
| val grade = if (req.gradeId != null && req.gradeId > 0L) gradeRepository.findById(req.gradeId).orElseThrow() else null | |||||
| val team = if (req.teamId != null && req.teamId > 0L) teamRepository.findById(req.teamId).orElseThrow() else null | |||||
| val skill = if (req.skillSetId != null && req.skillSetId > 0L) skillRepository.findById(req.skillSetId).orElseThrow() else null | |||||
| val salary = salaryRepository.findById(req.salaryId).orElseThrow() | |||||
| // val salaryEffective = salaryEffectiveRepository.findById(req.salaryEffId).orElseThrow() | |||||
| val department = departmentRepository.findById(req.departmentId).orElseThrow() | val department = departmentRepository.findById(req.departmentId).orElseThrow() | ||||
| // // TODO: Add tasks, milestones, allocated | // // TODO: Add tasks, milestones, allocated | ||||
| @@ -100,10 +103,15 @@ open class StaffsService( | |||||
| this.grade = grade | this.grade = grade | ||||
| this.team = team | this.team = team | ||||
| this.skill = skill | this.skill = skill | ||||
| this.salaryEffective = salaryEffective | |||||
| this.salary = salary | |||||
| this.department = department | this.department = department | ||||
| } | } | ||||
| return staffRepository.save(staff) | |||||
| staffRepository.save(staff) | |||||
| salaryEffectiveService.saveSalaryEffective(staff.id!!, salary.id!!) | |||||
| logger.info(staff.id) | |||||
| return staff | |||||
| } | } | ||||
| @Transactional(rollbackFor = [Exception::class]) | @Transactional(rollbackFor = [Exception::class]) | ||||
| @@ -111,10 +119,11 @@ open class StaffsService( | |||||
| val currentPosition = positionRepository.findById(req.currentPositionId).orElseThrow() | val currentPosition = positionRepository.findById(req.currentPositionId).orElseThrow() | ||||
| val joinPosition = positionRepository.findById(req.joinPositionId).orElseThrow() | val joinPosition = positionRepository.findById(req.joinPositionId).orElseThrow() | ||||
| val company = companyRepository.findById(req.companyId).orElseThrow() | val company = companyRepository.findById(req.companyId).orElseThrow() | ||||
| val grade = gradeRepository.findById(req.gradeId).orElseThrow() | |||||
| val team = teamRepository.findById(req.teamId).orElseThrow() | |||||
| val skill = skillRepository.findById(req.skillSetId).orElseThrow() | |||||
| val salaryEffective = salaryEffectiveRepository.findById(req.salaryEffId).orElseThrow() | |||||
| val grade = if (req.gradeId != null && req.gradeId > 0L) gradeRepository.findById(req.gradeId).orElseThrow() else null | |||||
| val team = if (req.teamId != null && req.teamId > 0L) teamRepository.findById(req.teamId).orElseThrow() else null | |||||
| val skill = if (req.skillSetId != null && req.skillSetId > 0L) skillRepository.findById(req.skillSetId).orElseThrow() else null | |||||
| val salary = salaryRepository.findById(req.salaryId).orElseThrow() | |||||
| // val salaryEffective = salaryEffectiveRepository.findById(req.salaryEffId).orElseThrow() | |||||
| val department = departmentRepository.findById(req.departmentId).orElseThrow() | val department = departmentRepository.findById(req.departmentId).orElseThrow() | ||||
| staff.apply { | staff.apply { | ||||
| @@ -136,17 +145,19 @@ open class StaffsService( | |||||
| this.grade = grade | this.grade = grade | ||||
| this.team = team | this.team = team | ||||
| this.skill = skill | this.skill = skill | ||||
| this.salaryEffective = salaryEffective | |||||
| this.salary = salary | |||||
| this.department = department | this.department = department | ||||
| } | } | ||||
| salaryEffectiveService.saveSalaryEffective(staff.id!!, salary.id!!) | |||||
| return staffRepository.save(staff) | return staffRepository.save(staff) | ||||
| } | } | ||||
| @Transactional(rollbackFor = [Exception::class]) | @Transactional(rollbackFor = [Exception::class]) | ||||
| open fun saveOrUpdate(req: NewStaffRequest): Staff { | open fun saveOrUpdate(req: NewStaffRequest): Staff { | ||||
| val staff = find(req.id).get() | |||||
| if (req.id != 0L) { | |||||
| val staff = if(req.id > 0L) find(req.id).get() else Staff() | |||||
| if (req.id > 0L) { | |||||
| updateStaff(req, staff) | updateStaff(req, staff) | ||||
| } else { | } else { | ||||
| saveStaff(req) | saveStaff(req) | ||||
| @@ -31,7 +31,7 @@ open class SubsidiaryService( | |||||
| } | } | ||||
| open fun findSubsidiary(id: Long): Subsidiary { | open fun findSubsidiary(id: Long): Subsidiary { | ||||
| return subsidiaryRepository.findById(id).orElseThrow() | |||||
| return subsidiaryRepository.findById(id).orElse(Subsidiary()) | |||||
| } | } | ||||
| open fun findSubsidiaryByCode(code: String): Optional<Subsidiary> { | open fun findSubsidiaryByCode(code: String): Optional<Subsidiary> { | ||||
| @@ -15,24 +15,24 @@ data class NewStaffRequest( | |||||
| val staffId: String, | val staffId: String, | ||||
| @field:NotNull(message = "Staff companyId cannot be empty") | @field:NotNull(message = "Staff companyId cannot be empty") | ||||
| val companyId: Long, | val companyId: Long, | ||||
| @field:NotNull(message = "Staff salaryEffId cannot be empty") | |||||
| val salaryEffId: Long, | |||||
| @field:NotNull(message = "Staff skillSetId cannot be empty") | |||||
| val skillSetId: Long, | |||||
| @field:NotNull(message = "Staff salaryId cannot be empty") | |||||
| val salaryId: Long, | |||||
| // @field:NotNull(message = "Staff skillSetId cannot be empty") | |||||
| val skillSetId: Long?, | |||||
| val joinDate: LocalDate, | val joinDate: LocalDate, | ||||
| val currentPositionId: Long, | val currentPositionId: Long, | ||||
| val joinPositionId: Long, | val joinPositionId: Long, | ||||
| val gradeId: Long, | |||||
| val teamId: Long, | |||||
| val gradeId: Long?, | |||||
| val teamId: Long?, | |||||
| val departmentId: Long, | val departmentId: Long, | ||||
| val phone1: String, | val phone1: String, | ||||
| val phone2: String, | |||||
| val phone2: String?, | |||||
| val email: String, | val email: String, | ||||
| val emergContactName: String, | val emergContactName: String, | ||||
| val emergContactPhone: String, | val emergContactPhone: String, | ||||
| val employType: String, | val employType: String, | ||||
| val departDate: LocalDate, | |||||
| val departReason: String, | |||||
| val remark: String, | |||||
| val departDate: LocalDate?, | |||||
| val departReason: String?, | |||||
| val remark: String?, | |||||
| ) | ) | ||||