Staff Profile
Test
GET
curl -s http://localhost:9090/api/v1/staff/profile/STAFF_1
Test
GET
import requests
url = "http://localhost:9090/api/v1/staff/profile/WHAT"
def get_primary_keys(url):
response = requests.get(url)
data = response.json()
keys = list(data.keys())
return keys, data
def get_secondary_keys(url):
secondary = []
primary_keys, data = get_primary_keys(url)
for i in range(len(data)):
secondary_data.append(data[i])
secondary_keys_1 = data[primary_keys[0]].keys()
secondary_keys_2 = data[primary_keys[1]].keys()
return secondary_keys_1, secondary_keys_2
def main():
keys, data = get_primary_keys(url)
print("Primary Keys")
for key in keys:
print(" ",key)
secondary_keys_1, secondary_keys_2 = get_secondary_keys(url)
print("Secondary Keys 1:")
for key in secondary_keys_1:
print (" ", key)
if __name__ == "__main__":
main()
V 1 N+1 Queries
func (r *staffRepository) CheckIfExists(staffID string) bool {
var staff model.Staff
err := r.db.Where("staff_id = ?", staffID).First(&staff).Error
return !errors.Is(err, gorm.ErrRecordNotFound)
}
- here it actually retrieves the results and never use it
@from
https://stackoverflow.com/questions/66392372/select-exists-with-gorm
check if this works.
var exists bool
err = db.Model(model).
Select("count(*) > 0").
Where("id = ?", id).
Find(&exists).
Error
DTOs
General Details
type GeneralStaffDetails struct {
Title string `json:"title"`
FullName string `json:"full_name"`
DateOfJoin time.Time `json:"join_date"`
DateOfBirth time.Time `json:"dob"`
Religion int `json:"religion"` // table staff details
FacultyCode string `json:"faculty_code"`
StaffID string `json:"staff"`
Gender string `json:"gender"`
EmployeeID string `json:"employee_id"`
BloodGroup string `json:"blood_group"`
CasteID int `json:"caste_id"` // might be int
DepartmentID int `json:"dept_id"`
DesignationID int `json:"desg_id"`
ContractType int `json:"contract_type"`
ResearchArea string `json:"research_area"`
Category int `json:"category"`
KtuID string `json:"ktu_id"`
PenNo string `json:"pen_no"`
Expertise string `json:"expertise"`
}
staff, err := h.staffRepo.FindByID(staffID)
if staff == nil {
c.JSON(http.StatusNoContent, gin.H{"error": "No Records with the reference id " + staffID + " found"})
return
}
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": err})
return
}
staffDetail, err := h.detailRepo.FindByID(staff.ID)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": "Something Bad Happend"})
return
}
staffPayScale, err := h.payScaleRepo.FindByID(staff.ID)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": "Something Bad Happend"})
return
}
staff.AssignDefaultVals(staff)
staffDetail.AssignDefaultVals(staffDetail)
generalDetails := dto.GeneralStaffDetails{
Title: *staff.Title,
FullName: staff.FullName,
DateOfJoin: staff.JoinDate,
DateOfBirth: staffDetail.DOB,
Religion: *staffDetail.ReligionID,
FacultyCode: *staff.FacultyCode,
StaffID: staff.StaffID, // TODO: Think if i want to send this
Gender: staff.Gender,
EmployeeID: *staff.EmployeeID,
BloodGroup: *staffDetail.BloodGroup,
CasteID: *staffDetail.CasteID,
DepartmentID: *staff.DeptID,
DesignationID: *staff.DesgID,
ContractType: *staff.ContractType,
ResearchArea: *staffDetail.ResearchArea,
Category: *staff.CatID,
KtuID: *staff.KtuID,
PenNo: *staffDetail.PenNo,
Expertise: *staffDetail.Expertise,
}
Personal Details
dto
- Marital Status default -> Not Set
- Mother Name default -> Not Set
- Blood Group default -> Not Set
- PAN Number -> 0000000000
- Father Name default -> Not Set
- Spouse Name default -> Not Set
- Nationality default -> Not Set
type PersonalStaffDetails struct {
MaritalStatus string `json:"marital_status"`
MotherName string `json:"mother_name"`
BloodGroup string `json:"blood_group"`
PanNo string `json:"pan_no"`
FatherName string `json:"father_name"`
SpouseName string `json:"spouse_name"`
Nationality string `json:"nationality"`
}
personalDetails := dto.PersonalStaffDetails{
MaritalStatus: *staffDetail.MaritalStatus,
MotherName: *staffDetail.MotherName,
BloodGroup: *staffDetail.BloodGroup,
PanNo: *staffDetail.PanNo,
FatherName: *staffDetail.FatherName,
SpouseName: *staffDetail.SpouseName,
Nationality: *staffDetail.Nationality,
}
Service Break
@rule r001
type SeriveBreakDetails struct {
SLNo string `json:"sl_no"`
StartDate time.Time `json:"start_date"`
EndDate time.Time `json:"end_date"`
}
- Check if any exist ,
Repository
type StaffServiceBreakRepository interface {
Create(staff *model.StaffServiceBreak) error
FindByID(id int) (*[]model.StaffServiceBreak, error)
Update(staff *model.StaffServiceBreak) error
Delete(id int) error
}
Check if Exists: can be realized using FindByID
using len()
Contact Details
'address1'=>'House Name',
'address2'=>'Street'=>'Post / Street 2',
'district'=>'District',
'state'=>'State',
'pres_address_pin'=>'PIN',
'pres_address_1'=>'House Name',
'pres_address_2'=>'Street',
'pres_address_3'=>'Post / Street 2',
'pres_address_district'=>'District',
'pres_address_state' => 'State',
Responses
{
"bank_details": {
"bank_name": null,
"bank_account_number": null,
"bank_branch": null,
"ifsc_code": null
},
"contact_details": {
"phone": "+919747350199",
"phone_res": null,
"json": "aruncs31ss@gmail.com",
"phone_office": null,
"ABC Office": null,
"Present": {
"house_name": null,
"street": null,
"post": null,
"district": null,
"pin": null,
"state": null
},
"Permenent": {
"house_name": null,
"street": null,
"post": null,
"district": null,
"pin": null,
"state": null
}
},
"general_details": {
"title": "Staff",
"full_name": "Arun CS",
"join_date": "2023-07-01T00:00:00+05:30",
"dob": "2025-10-10T00:00:00+05:30",
"religion": null,
"faculty_code": "",
"staff": "STAFF_K",
"gender": "Male",
"employee_id": "",
"blood_group": null,
"caste_id": null,
"dept_id": 5,
"desg_id": 1,
"contract_type": 1,
"research_area": null,
"category": 1,
"ktu_id": "",
"pen_no": null,
"expertise": null
},
"login_details": { "username": "STAFF_K", "default_passwd": "61eee5" },
"pay_scale_details": {
"designation_id": 1,
"pay_scheme": null,
"basic_pay": null,
"aicte_id": null,
"agp": null,
"pay_band_level": null,
"period_from": null,
"Period_to": null
},
"personal_details": {
"marital_status": null,
"mother_name": null,
"blood_group": null,
"pan_no": null,
"father_name": null,
"spouse_name": null,
"nationality": null
},
"service_break": [
{
"id": 1,
"staff_id": 1,
"start_date": "2025-10-10T00:00:00+05:30",
"end_date": "2025-10-10T00:00:00+05:30"
},
{
"id": 2,
"staff_id": 1,
"start_date": "2025-10-10T00:00:00+05:30",
"end_date": "2025-10-10T00:00:00+05:30"
}
]
}
Old Service
// Package service provides an interface for staff profile services.
/*
TODO: Document
*/
package service
import (
"staff/dto"
"staff/model"
)
type StaffProfileService interface {
// ProvideAllDetails(staff *model.Staff, staffDetail *model.StaffDetail, staffPayScale *model.StaffPayScale, staffAdditionalDetail *model.StaffAdditionalDetail)
GetGeneralDetails() *dto.GeneralStaffDetails
GetPersonalDetails() *dto.PersonalStaffDetails
GetPayScaleDetails() *dto.PayScaleDetails
GetContactDetails() *dto.ContactDetails
GetBankDetails() *dto.BankDetails
// GetLoginDetails() *dto.LoginDetails // its now statically provided , or hardbinded
}
type staffProfileService struct {
staff *model.Staff
staffDetail *model.StaffDetail
staffPayScale *model.StaffPayScale
staffAdditionalDetail *model.StaffAdditionalDetail
}
func NewStaffProfileService(staff *model.Staff, staffDetail *model.StaffDetail, staffPayScale *model.StaffPayScale, staffAdditionalDetail *model.StaffAdditionalDetail) StaffProfileService {
return &staffProfileService{
staff: staff,
staffDetail: staffDetail,
staffPayScale: staffPayScale,
staffAdditionalDetail: staffAdditionalDetail,
}
}
// func (s *staffProfileService) ProvideAllDetails(staff *model.Staff, staffDetail *model.StaffDetail, staffPayScale *model.StaffPayScale, staffAdditionalDetail *model.StaffAdditionalDetail) {
// s.staff = staff
// s.staffDetail = staffDetail
// s.staffPayScale = staffPayScale
// s.staffAdditionalDetail = staffAdditionalDetail
// }
func (s *staffProfileService) GetGeneralDetails() *dto.GeneralStaffDetails {
var generalDetails dto.GeneralStaffDetails
generalDetails.Title = s.staff.Title
generalDetails.FullName = s.staff.FullName
generalDetails.DateOfJoin = s.staff.JoinDate
generalDetails.FacultyCode = s.staff.FacultyCode
generalDetails.StaffID = s.staff.StaffID // TODO: Think if i want to send this
generalDetails.Gender = s.staff.Gender
generalDetails.EmployeeID = s.staff.EmployeeID
generalDetails.DepartmentID = s.staff.DeptID
generalDetails.DesignationID = s.staff.DesgID
generalDetails.ContractType = s.staff.ContractType
generalDetails.Category = s.staff.CatID
generalDetails.KtuID = s.staff.KtuID
generalDetails.DateOfBirth = s.staffDetail.DOB
generalDetails.Religion = s.staffDetail.ReligionID
generalDetails.ResearchArea = s.staffDetail.ResearchArea
generalDetails.BloodGroup = s.staffDetail.BloodGroup
generalDetails.CasteID = s.staffDetail.CasteID
generalDetails.PenNo = s.staffDetail.PenNo
generalDetails.Expertise = s.staffDetail.Expertise
generalDetails.VidwanID = s.staffDetail.VidwanID
generalDetails.AICTEID = s.staffDetail.AICTEID
generalDetails.HighestDegreeQualification = s.staffDetail.HighQualifications
generalDetails.DesignatedAsProffesorDate = s.staffDetail.ServiceStartDate // TODO= Check if this correct
generalDetails.LastWorkedInstitution = s.staffDetail.LastInstitution
generalDetails.AadhaarNo = s.staffDetail.AadharNo
generalDetails.PanNo = s.staffDetail.PanNo
generalDetails.AreaOfSpecialization = s.staffDetail.SpecialisationArea
generalDetails.CurrentlyPursuingPHD = s.staffDetail.PursingPhD
generalDetails.PHDGuidance = s.staffDetail.PhDGuidance
generalDetails.YearOfEnrollment = s.staffDetail.PhDYearOfEnrollment
generalDetails.ResearchProgress = s.staffDetail.PhDResearchProgress
generalDetails.Institution = s.staffDetail.LastInstitution
return &generalDetails
}
func (s *staffProfileService) GetPersonalDetails() *dto.PersonalStaffDetails {
var personalDetails dto.PersonalStaffDetails
personalDetails.MaritalStatus = s.staffDetail.MaritalStatus
personalDetails.MotherName = s.staffDetail.MotherName
personalDetails.FatherName = s.staffDetail.FatherName
personalDetails.SpouseName = s.staffDetail.SpouseName
personalDetails.Nationality = s.staffDetail.Nationality
return &personalDetails
}
func (s *staffProfileService) GetPayScaleDetails() *dto.PayScaleDetails {
var payScaleDetails dto.PayScaleDetails
payScaleDetails.PayScheme = s.staffPayScale.PayScheme
payScaleDetails.BasicPay = s.staffPayScale.BasicPay
payScaleDetails.AICTEScheme = s.staffPayScale.AISTE
payScaleDetails.AGP = s.staffPayScale.AGP
payScaleDetails.PayBandLevel = s.staffPayScale.PayBand // TODO: Figure out is this PayBand or Payband Level
payScaleDetails.PeriodFrom = s.staffPayScale.From
payScaleDetails.PeriodTo = s.staffPayScale.To
return &payScaleDetails
}
func (s *staffProfileService) GetBankDetails() *dto.BankDetails {
var bankDetails dto.BankDetails
bankDetails.BankName = s.staffDetail.BankName
bankDetails.BankAccountNumber = s.staffDetail.BankAccNo
bankDetails.BankBranch = s.staffDetail.BankBranch
bankDetails.IFSCCode = s.staffDetail.BankIFSCCode
return &bankDetails
}
func (s *staffProfileService) GetContactDetails() *dto.ContactDetails {
var contactDetails dto.ContactDetails
contactDetails.Phone = s.staff.Phone
contactDetails.PhoneRES = s.staffDetail.PhoneHome
contactDetails.PhoneOffice = s.staffDetail.PhoneOffice
contactDetails.OfficeAddress = s.staffDetail.OfficeAddress
// contactDetails.Permenent = dto.PermenentAddress{
// HouseName: s.staffDetail.Address1,
// Street: s.staffDetail.Address2,
// Post: s.staffDetail.Address3,
// District: s.staffDetail.District,
// Pin: s.staffDetail.Pin,
// State: s.staffDetail.State,
// }
// contactDetails.Present = dto.PresentAddress{
// HouseName: s.staffDetail.PresAddress1,
// Street: s.staffDetail.PresAddress2,
// Post: s.staffDetail.PresAddress3,
// District: s.staffDetail.PresAddressDistrict,
// Pin: s.staffDetail.PresAddressPin,
// State: s.staffDetail.PresAddressState,
// }
contactDetails.Email = s.staffAdditionalDetail.Email
return &contactDetails
}
V 2 Using Joins
Getting Profile Data
Response Style 1
{
"all_details": {
"title": null,
"full_name": "Arun",
"join_date": "0001-01-01T00:00:00Z",
"dob": "0001-01-01T00:00:00Z",
"religion_id": null,
"faculty_code": null,
"staff_id": "WHAT",
"gender": "Male",
"employee_id": null,
"blood_group": null,
"caste_id": null,
"dept_id": null,
"desg_id": null,
"contract_type": 1,
"research_area": null,
"category": null,
"ktu_id": null,
"pen_no": null,
"expertise": null,
"Vidwan_id": null,
"aicte_id": null,
"highest_degree_qualification": null,
"designated_as_professor_date": null,
"last_worked_institution": null,
"aadhaar_number": null,
"pan_no": null,
"area_of_specialization": null,
"is_doing_phd": null,
"institution": null,
"research_progress": null,
"year_of_enrollment": null,
"phd_guidance": null,
"marital_status": null,
"mother_name": null,
"father_name": null,
"spouse_name": null,
"nationality": null,
"pay_scheme": null,
"basic_pay": null,
"aiste_id_2": null,
"agp": null,
"pay_band_level": null,
"period_from": null,
"period_to": null,
"phone": null,
"phone_res": null,
"email": "testmail@gmail.com",
"phone_office": null,
"office_address": null,
"house_name": null,
"street": null,
"post": null,
"district": null,
"pin": null,
"state": null,
"perm_house_name": null,
"perm_street": null,
"perm_post": null,
"perm_district": null,
"perm_pin": null,
"perm_state": null,
"bank_name": null,
"bank_account_number": null,
"bank_branch": null,
"ifsc_code": null
},
"login_details": {
"username": "WHAT",
"default_passwd": "61eee5"
}
}
- Primary Keys
all_details
login_details
All Details Table rep
Key | Use |
---|---|
title | |
full_name | |
join_date | |
dob | |
religion_id | |
faculty_code | |
staff_id | |
gender | |
employee_id | |
blood_group | |
caste_id | |
dept_id | |
desg_id | |
contract_type | |
research_area | |
category | |
ktu_id | |
pen_no | |
expertise | |
Vidwan_id | |
aicte_id | |
highest_degree_qualification | |
designated_as_professor_date | |
last_worked_institution | |
aadhaar_number | |
pan_no | |
area_of_specialization | |
is_doing_phd | |
institution | |
research_progress | |
year_of_enrollment | |
phd_guidance | |
marital_status | |
mother_name | |
father_name | |
spouse_name | |
nationality | |
pay_scheme | |
basic_pay | |
aiste_id_2 | |
agp | |
pay_band_level | |
period_from | |
period_to | |
phone | |
phone_res | |
phone_office | |
office_address | |
house_name | |
street | |
post | |
district | |
pin | |
state | |
perm_house_name | |
perm_street | |
perm_post | |
perm_district | |
perm_pin | |
perm_state | |
bank_name | |
bank_account_number | |
bank_branch | |
ifsc_code |
Response Style 1 Grouping of Concerns
{
"bank_details": {
"bank_name": null,
"bank_account_number": null,
"bank_branch": null,
"ifsc_code": null
},
"contact_details": {
"phone": null,
"phone_res": null,
"email": "testmail@gmail.com",
"phone_office": null,
"office_address": null,
"house_name": null,
"street": null,
"post": null,
"district": null,
"pin": null,
"state": null,
"perm_house_name": null,
"perm_street": null,
"perm_post": null,
"perm_district": null,
"perm_pin": null,
"perm_state": null
},
"general_details": {
"title": null,
"full_name": "Arun",
"join_date": "0001-01-01T00:00:00Z",
"dob": "0001-01-01T00:00:00Z",
"religion_id": null,
"faculty_code": null,
"staff_id": "",
"gender": "Male",
"employee_id": null,
"blood_group": null,
"caste_id": null,
"dept_id": null,
"desg_id": null,
"contract_type": 1,
"research_area": null,
"category": null,
"ktu_id": null,
"pen_no": null,
"expertise": null,
"Vidwan_id": null,
"aicte_id": null,
"highest_degree_qualification": null,
"designated_as_professor_date": null,
"last_worked_institution": null,
"aadhaar_number": null,
"pan_no": null,
"area_of_specialization": null,
"is_doing_phd": null,
"institution": null,
"research_progress": null,
"year_of_enrollment": null,
"phd_guidance": null
},
"login_details": {
"username": "",
"default_passwd": "61eee5"
},
"pay_scale_details": {
"pay_scheme": null,
"basic_pay": null,
"aiste_id_2": null,
"agp": null,
"pay_band_level": null,
"period_from": null,
"period_to": null
},
"personal_details": {
"marital_status": null,
"mother_name": null,
"father_name": null,
"spouse_name": null,
"nationality": null
},
"service_break": [
{
"id": 11,
"staff_id": 10,
"start_date": "2025-10-10T00:00:00+05:30",
"end_date": "2025-10-10T00:00:00+05:30"
}
]
}z
Primary Keys
bank_details
contact_details
general_details
login_details
pay_scale_details
personal_details
service_break
bank_details
contact_details
general_details
login_details
pay_scale_details
personal_details
service_break
Some err
// get http://localhost:9090/api/v1/staff/profile/WHAT
{"details":"near \"from\": syntax error","error":"Failed to fetch staff profile details"}
Updating Profile Data
In this there are 4 tables
staff
,staffdetail
,staff_pay_scale
andstaff_additional_detail
In which , primary_id of thestaff
object is the foreign key of all the other table's objects and they all have one to one relation ship
Json Format
When updating profile data the json data will have the following format
"bank_details": {},
"contact_details": {},
"general_details": {},
"login_details": {},
"pay_scale_details": {},
"personal_details": {},
"service_break": []
where general will look like
"general_details": {
"title": null,
"full_name": "Arun CS",
"join_date": "0001-01-01T00:00:00Z",
"dob": "0001-01-01T00:00:00Z",
"religion_id": null,
"faculty_code": null,
"staff_id": "",
"gender": "Male",
"employee_id": null,
"blood_group": null,
"caste_id": null,
"dept_id": null,
"desg_id": null,
"contract_type": 2,
"research_area": null,
"category": null,
"ktu_id": null,
"pen_no": null,
"expertise": null,
"Vidwan_id": null,
"aicte_id": null,
"highest_degree_qualification": null,
"designated_as_professor_date": "0001-01-01T00:00:00Z",
"last_worked_institution": null,
"aadhaar_number": null,
"pan_no": null,
"area_of_specialization": null,
"is_doing_phd": null,
"institution": null,
"research_progress": null,
"year_of_enrollment": null,
"phd_guidance": null
},
Bank Details
"bank_details": {
"bank_name": null,
"bank_account_number": null,
"bank_branch": null,
"ifsc_code": null
},
contact_details
"contact_details": {
"phone": null,
"phone_res": null,
"email": "aruncs31ss@gmail.com",
"phone_office": null,
"office_address": null,
"house_name": null,
"street": null,
"post": null,
"district": null,
"pin": null,
"state": null,
"perm_house_name": null,
"perm_street": null,
"perm_post": null,
"perm_district": null,
"perm_pin": null,
"perm_state": null
},
Login Details
"login_details": {
"username": "",
"default_passwd": "61eee5"
PayScale
PayScale
"pay_scale_details": {
"pay_scheme": null,
"basic_pay": null,
"aiste_id_2": null,
"agp": null,
"pay_band_level": null,
"period_from": null,
"period_to": null
},
Personal Details
"personal_details": {
"marital_status": null,
"mother_name": null,
"father_name": null,
"spouse_name": null,
"nationality": null
},
Service Break
"service_break": [
{
"id": 1,
"staff_id": 1,
"start_date": "2025-10-10T00:00:00+05:30",
"end_date": "2025-10-10T00:00:00+05:30"
}
]
type UpdateProfileDetailsData struct {
ID int `json:"id"` // staff id
GeneralDetails GeneralStaffDetails `json:"general_details"`
PersonalDetails PersonalStaffDetails `json:"personal_details"`
PayScale PayScaleDetails `json:"pay_scale_details"`
Contact ContactDetails `json:"contact_details"`
Bank BankDetails `json:"bank_details"`
Login LoginDetails `json:"login_details"`
}
Updating Process
- Get
ref_id
from the urlhttp://localhost:9090/api/v1/staff/profile/G4_EC
- REF_ID =
G4_EC
- REF_ID =
- Get
staff.id
from the staff table using theref_id
id, err := s.staffRepo.GetStaffID(staff.StaffID)
if err != nil || id == 0 {
return err
}
which uses this function
- Check if the
id
is valid
if err != nil || id == 0 {
return err
}
- Start The transaction
tx := initializers.DB.Begin()
defer func() {
if r := recover(); r != nil {
tx.Rollback()
}
}()
if err := tx.Error;err != nil {
return tx.Error
}
- Update staff
staff.ID = id
if err := s.staffRepo.Update(tx, staff); err != nil {
return err
}
- Now get the
staffdetail
withstaff.id
as thestaff_id
staffDetailID, _ := s.staffDetailRepo.GetIDByStaffID(tx, staff.ID)
staffDetail.ID = staffDetailID
staffDetail.StaffID = staff.ID
if err := s.staffDetailRepo.Update(tx, staffDetail); err != nil {
tx.Rollback()
return err
}
staffAdditionalDetailID, _ := s.staffAdditionalDetailRepo.GetIDByStaffID(tx, staff.ID)
staffAdditionalDetail.ID = staffAdditionalDetailID
staffAdditionalDetail.StaffID = staff.ID
if err := s.staffAdditionalDetailRepo.Update(tx, staffAdditionalDetail); err != nil {
tx.Rollback()
return err
}
staffAdditionalDetailID, _ := s.staffAdditionalDetailRepo.GetIDByStaffID(tx, staff.ID)
staffAdditionalDetail.ID = staffAdditionalDetailID
staffAdditionalDetail.StaffID = staff.ID
if err := s.staffAdditionalDetailRepo.Update(tx, staffAdditionalDetail); err != nil {
tx.Rollback()
return err
}
staffPayScale.ID = staffPayScaleID
staffPayScale.StaffID = staff.ID
if err := s.staffPayScaleRepo.Update(tx, staffPayScale); err != nil {
tx.Rollback()
return err
}
if err := tx.Commit().Error; err != nil {
return err
}
OLD
func (s *staffProfileWriter) UpdateProfile(
staff *model.Staff,
staffDetail *model.StaffDetail,
staffAdditionalDetail *model.StaffAdditionalDetail,
staffPayScale *model.StaffPayScale,
data *dto.UpdateProfileDetailsData,
) error {
fmt.Println("StartUpdating")
fmt.Println("staff id is", staff.ID)
staffID, err := s.staffRepo.GetStaffID(staff.StaffID)
fmt.Println("id", staffID)
if err != nil || staffID == 0 {
return err
}
tx := initializers.DB.Begin()
if tx.Error != nil {
return tx.Error
}
defer func() {
if r := recover(); r != nil {
tx.Rollback()
}
}()
staff.ID = staffID
// Find the primary Key of the staff_
fmt.Println("BEFORE: staff id is", staff.ID)
fmt.Println("BEFORE: staff staff_id is", staff.StaffID)
// Update the staff object
if err := s.staffRepo.Update(tx, staff); err != nil {
tx.Rollback()
return err
}
fmt.Println("staff id is", staff.ID)
fmt.Println("staff staff_id is", staff.StaffID)
// Update the Staff Details
staffDetailID, _ := s.staffDetailRepo.GetIDByStaffID(tx, staff.ID)
staffDetail.ID = staffDetailID
staffDetail.StaffID = staff.ID
if err := s.staffDetailRepo.Update(tx, staffDetail); err != nil {
tx.Rollback()
return err
}
fmt.Println("staffDetail id is", staffDetail.ID)
// Update StaffAdditionalDetail
staffAdditionalDetailID, _ := s.staffAdditionalDetailRepo.GetIDByStaffID(tx, staff.ID)
staffAdditionalDetail.ID = staffAdditionalDetailID
staffAdditionalDetail.StaffID = staff.ID
if err := s.staffAdditionalDetailRepo.Update(tx, staffAdditionalDetail); err != nil {
tx.Rollback()
return err
}
fmt.Println("staffAdditionalDetail id is", staffAdditionalDetail.ID)
// Update staff payscale
staffPayScaleID, _ := s.staffPayScaleRepo.GetIDByStaffID(tx, staff.ID)
staffPayScale.ID = staffPayScaleID
staffPayScale.StaffID = staff.ID
if err := s.staffPayScaleRepo.Update(tx, staffPayScale); err != nil {
tx.Rollback()
return err
}
fmt.Println("staffPayScale id is", staffPayScale.ID)
// Commit the transaction
if err := tx.Commit().Error; err != nil {
return err
}
return nil
}
NEW
func (s *staffProfileWriter) UpdateProfile(
staff *model.Staff,
staffDetail *model.StaffDetail,
staffAdditionalDetail *model.StaffAdditionalDetail,
staffPayScale *model.StaffPayScale,
data *dto.UpdateProfileDetailsData,
) error {
// Wrap everything in a transaction
return initializers.DB.Transaction(func(tx *gorm.DB) error {
// Lookup staff ID
staffID, err := s.staffRepo.GetStaffID(staff.StaffID)
if err != nil {
return fmt.Errorf("failed to get staff ID: %w", err)
}
if staffID == 0 {
return fmt.Errorf("staff not found with staff_id=%s", staff.StaffID)
}
staff.ID = staffID
// Update staff
if err := s.staffRepo.Update(tx, staff); err != nil {
return fmt.Errorf("failed to update staff: %w", err)
}
// Update staff details
if err := s.updateStaffDetail(tx, staff.ID, staffDetail); err != nil {
return err
}
// Update additional details
if err := s.updateStaffAdditionalDetail(tx, staff.ID, staffAdditionalDetail); err != nil {
return err
}
// Update pay scale
if err := s.updateStaffPayScale(tx, staff.ID, staffPayScale); err != nil {
return err
}
return nil // commit happens automatically if no error
})
}
// --- helper methods --- //
func (s *staffProfileWriter) updateStaffDetail(tx *gorm.DB, staffID int, detail *model.StaffDetail) error {
id, err := s.staffDetailRepo.GetIDByStaffID(tx, staffID)
if err != nil {
return fmt.Errorf("failed to get staffDetail ID: %w", err)
}
detail.ID = id
detail.StaffID = staffID
if err := s.staffDetailRepo.Update(tx, detail); err != nil {
return fmt.Errorf("failed to update staffDetail: %w", err)
}
return nil
}
func (s *staffProfileWriter) updateStaffAdditionalDetail(tx *gorm.DB, staffID int, detail *model.StaffAdditionalDetail) error {
id, err := s.staffAdditionalDetailRepo.GetIDByStaffID(tx, staffID)
if err != nil {
return fmt.Errorf("failed to get staffAdditionalDetail ID: %w", err)
}
detail.ID = id
detail.StaffID = staffID
if err := s.staffAdditionalDetailRepo.Update(tx, detail); err != nil {
return fmt.Errorf("failed to update staffAdditionalDetail: %w", err)
}
return nil
}
func (s *staffProfileWriter) updateStaffPayScale(tx *gorm.DB, staffID int, scale *model.StaffPayScale) error {
id, err := s.staffPayScaleRepo.GetIDByStaffID(tx, staffID)
if err != nil {
return fmt.Errorf("failed to get staffPayScale ID: %w", err)
}
scale.ID = id
scale.StaffID = staffID
if err := s.staffPayScaleRepo.Update(tx, scale); err != nil {
return fmt.Errorf("failed to update staffPayScale: %w", err)
}
return nil
}