Skip to content

Commit

Permalink
Merge branch 'release/v0.0.98'
Browse files Browse the repository at this point in the history
  • Loading branch information
lmquang committed May 15, 2023
2 parents 0721553 + 159b921 commit 83904f8
Show file tree
Hide file tree
Showing 15 changed files with 150 additions and 37 deletions.
1 change: 1 addition & 0 deletions .env.sample
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ NOTION_HIRING_DB_ID="NOTION_HIRING_DB_ID"
NOTION_ISSUE_DB_ID="NOTION_ISSUE_DB_ID"
NOTION_MEMO_DB_ID="NOTION_MEMO_DB_ID"
NOTION_PROJECT_DB_ID="NOTION_PROJECT_DB_ID"
NOTION_DELIVERY_DB_ID="NOTION_DELIVERY_DB_ID"
NOTION_STAFFING_DEMAND_DB_ID="NOTION_STAFFING_DEMAND_DB_ID"
NOTION_TECH_RADAR_DB_ID="NOTION_TECH_RADAR_DB_ID"
NOTION_UPDATES_DB_ID="NOTION_UPDATES_DB_ID"
6 changes: 4 additions & 2 deletions docs/docs.go
Original file line number Diff line number Diff line change
Expand Up @@ -7687,8 +7687,7 @@ const docTemplate = `{
"roles",
"salary",
"seniorityID",
"status",
"teamEmail"
"status"
],
"properties": {
"displayName": {
Expand All @@ -7698,6 +7697,9 @@ const docTemplate = `{
"type": "string",
"maxLength": 100
},
"joinDate": {
"type": "string"
},
"personalEmail": {
"type": "string"
},
Expand Down
6 changes: 4 additions & 2 deletions docs/swagger.json
Original file line number Diff line number Diff line change
Expand Up @@ -7679,8 +7679,7 @@
"roles",
"salary",
"seniorityID",
"status",
"teamEmail"
"status"
],
"properties": {
"displayName": {
Expand All @@ -7690,6 +7689,9 @@
"type": "string",
"maxLength": 100
},
"joinDate": {
"type": "string"
},
"personalEmail": {
"type": "string"
},
Expand Down
3 changes: 2 additions & 1 deletion docs/swagger.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -1275,6 +1275,8 @@ definitions:
fullName:
maxLength: 100
type: string
joinDate:
type: string
personalEmail:
type: string
positions:
Expand Down Expand Up @@ -1303,7 +1305,6 @@ definitions:
- salary
- seniorityID
- status
- teamEmail
type: object
request.CreatePositionInput:
properties:
Expand Down
2 changes: 2 additions & 0 deletions pkg/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ type NotionDatabase struct {
Hiring string
StaffingDemand string
Project string
Delivery string
Digest string
Updates string
Memo string
Expand Down Expand Up @@ -194,6 +195,7 @@ func Generate(v ENV) *Config {
Hiring: v.GetString("NOTION_HIRING_DB_ID"),
StaffingDemand: v.GetString("NOTION_STAFFING_DEMAND_DB_ID"),
Project: v.GetString("NOTION_PROJECT_DB_ID"),
Delivery: v.GetString("NOTION_DELIVERY_DB_ID"),
Digest: v.GetString("NOTION_DIGEST_DB_ID"),
Updates: v.GetString("NOTION_UPDATES_DB_ID"),
Memo: v.GetString("NOTION_MEMO_DB_ID"),
Expand Down
4 changes: 4 additions & 0 deletions pkg/controller/auth/auth.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,10 @@ func (r *controller) Auth(in AuthenticationInput) (*model.Employee, string, erro
return nil, "", err
}

if employee.WorkingStatus == model.WorkingStatusLeft || employee.WorkingStatus == model.WorkingStatusOnBoarding {
return nil, "", ErrUserInactivated
}

// 2.5 generate jwt bearer token
authenticationInfo := model.AuthenticationInfo{
UserID: employee.ID.String(),
Expand Down
77 changes: 61 additions & 16 deletions pkg/controller/employee/create.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,11 @@ import (
"strings"
"time"

"gorm.io/gorm"

"github.com/dwarvesf/fortress-api/pkg/logger"
"github.com/dwarvesf/fortress-api/pkg/model"
"gorm.io/gorm"
"github.com/dwarvesf/fortress-api/pkg/service/currency"
)

type CreateEmployeeInput struct {
Expand All @@ -16,26 +18,27 @@ type CreateEmployeeInput struct {
TeamEmail string
PersonalEmail string
Positions []model.UUID
Salary int
Salary int64
SeniorityID model.UUID
Roles []model.UUID
Status string
ReferredBy model.UUID
JoinDate *time.Time
}

func (r *controller) Create(userID string, input CreateEmployeeInput) (*model.Employee, error) {
l := r.logger.Fields(logger.Fields{
"controller": "employee",
"method": "Create",
})
loggedInUser, err := r.store.Employee.One(r.repo.DB(), userID, false)
if errors.Is(err, gorm.ErrRecordNotFound) {
return nil, ErrEmployeeNotFound
}

if err != nil {
return nil, err
}

// 1.2 prepare employee data
now := time.Now()

// Check position existence
positions, err := r.store.Position.All(r.repo.DB())
if err != nil {
Expand All @@ -47,7 +50,7 @@ func (r *controller) Create(userID string, input CreateEmployeeInput) (*model.Em
for _, pID := range input.Positions {
_, ok := positionMap[pID]
if !ok {
r.logger.Errorf(ErrPositionNotFound, "position not found with id ", pID.String())
l.Errorf(ErrPositionNotFound, "position not found with id ", pID.String())
return nil, ErrPositionNotFound
}

Expand All @@ -64,7 +67,7 @@ func (r *controller) Create(userID string, input CreateEmployeeInput) (*model.Em

roles, err := r.store.Role.GetByIDs(r.repo.DB(), input.Roles)
if err != nil {
r.logger.Error(err, "failed to get roles by ids")
l.Error(err, "failed to get roles by ids")
return nil, err
}

Expand All @@ -85,7 +88,7 @@ func (r *controller) Create(userID string, input CreateEmployeeInput) (*model.Em
TeamEmail: input.TeamEmail,
PersonalEmail: input.PersonalEmail,
WorkingStatus: model.WorkingStatus(input.Status),
JoinedDate: &now,
JoinedDate: input.JoinDate,
SeniorityID: sen.ID,
Username: strings.Split(input.TeamEmail, "@")[0],
}
Expand Down Expand Up @@ -132,35 +135,72 @@ func (r *controller) Create(userID string, input CreateEmployeeInput) (*model.Em
// 2.2 store employee
eml, err = r.store.Employee.Create(tx.DB(), eml)
if err != nil {
l.Errorf(err, "failed to create employee", "employee", eml)
return nil, done(err)
}

// 2.3 create employee position
for _, p := range positionsReq {
_, err = r.store.EmployeePosition.Create(tx.DB(), &model.EmployeePosition{
ep := &model.EmployeePosition{
EmployeeID: eml.ID,
PositionID: p.ID,
})
}
_, err = r.store.EmployeePosition.Create(tx.DB(), ep)
if err != nil {
l.Errorf(err, "failed to create employee position", "employee_position", ep)
return nil, done(err)
}
}

// 2.4 create employee roles
for _, role := range roles {
er := &model.EmployeeRole{
EmployeeID: eml.ID,
RoleID: role.ID,
}
_, err = r.store.EmployeeRole.Create(tx.DB(), &model.EmployeeRole{
EmployeeID: eml.ID,
RoleID: role.ID,
})
if err != nil {
r.logger.Fields(logger.Fields{
"emlID": eml.ID,
"roleID": role.ID,
}).Error(err, "failed to create employee role")
l.Errorf(err, "failed to create employee role", "employee_role", er)
return nil, done(err)
}
}

baseCurrency, err := r.store.Currency.GetByName(tx.DB(), currency.VNDCurrency)
if err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
return nil, done(ErrCurrencyNotFound)
}

return nil, done(err)
}

salaryBatch := 1
if input.JoinDate.Day() > 1 && input.JoinDate.Day() < 16 {
salaryBatch = 15
}

// 2.4 create employee salary
ebs := &model.BaseSalary{
EmployeeID: eml.ID,
ContractAmount: 0,
CompanyAccountAmount: 0,
PersonalAccountAmount: input.Salary,
InsuranceAmount: 0,
Type: "",
Category: "",
CurrencyID: baseCurrency.ID,
Batch: salaryBatch,
EffectiveDate: nil,
}
err = r.store.BaseSalary.Save(tx.DB(), ebs)
if err != nil {
l.Errorf(err, "failed to create employee base salary", "employee_base_salary", ebs)
return nil, done(err)
}

// Create employee organization
org, err := r.store.Organization.OneByCode(tx.DB(), model.OrganizationCodeDwarves)
if err != nil {
Expand All @@ -170,7 +210,12 @@ func (r *controller) Create(userID string, input CreateEmployeeInput) (*model.Em
return nil, done(err)
}

if _, err := r.store.EmployeeOrganization.Create(tx.DB(), &model.EmployeeOrganization{EmployeeID: eml.ID, OrganizationID: org.ID}); err != nil {
eo := &model.EmployeeOrganization{
EmployeeID: eml.ID,
OrganizationID: org.ID,
}
if _, err := r.store.EmployeeOrganization.Create(tx.DB(), eo); err != nil {
l.Errorf(err, "failed to create employee organization", "employee_organization", eo)
return nil, done(err)
}

Expand Down
1 change: 1 addition & 0 deletions pkg/controller/employee/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ var (
ErrCouldNotAssignRoleForSameLevelEmployee = errors.New("could not assign role for the same level employee")
ErrCouldNotMentorTheirMentor = errors.New("employee could not be mentor of their mentor")
ErrCouldNotMentorThemselves = errors.New("employee could not be their own mentor")
ErrCurrencyNotFound = errors.New("currency not found")
ErrEmailExisted = errors.New("email already exists")
ErrEmployeeExisted = errors.New("can't create existed employee")
ErrEmployeeLeft = errors.New("employee is left")
Expand Down
1 change: 1 addition & 0 deletions pkg/handler/employee/employee.go
Original file line number Diff line number Diff line change
Expand Up @@ -380,6 +380,7 @@ func (h *handler) Create(c *gin.Context) {
Roles: input.Roles,
Status: input.Status,
ReferredBy: input.ReferredBy,
JoinDate: input.JoinDate,
}

eml, err := h.controller.Employee.Create(userID, requestBody)
Expand Down
7 changes: 4 additions & 3 deletions pkg/handler/employee/request/request.go
Original file line number Diff line number Diff line change
Expand Up @@ -82,14 +82,15 @@ func (e *DeleteMenteeInput) Validate() error {
type CreateEmployeeInput struct {
FullName string `json:"fullName" binding:"required,max=100"`
DisplayName string `json:"displayName"`
TeamEmail string `json:"teamEmail" binding:"required,email"`
TeamEmail string `json:"teamEmail"`
PersonalEmail string `json:"personalEmail" binding:"required,email"`
Positions []model.UUID `form:"positions" json:"positions" binding:"required"`
Salary int `json:"salary" binding:"required"`
Salary int64 `json:"salary" binding:"required"`
SeniorityID model.UUID `json:"seniorityID" binding:"required"`
Roles []model.UUID `json:"roles" binding:"required"`
Status string `json:"status" binding:"required"`
ReferredBy model.UUID `json:"referredBy"`
JoinDate *time.Time `json:"joinDate"`
}

type UpdateSkillsInput struct {
Expand Down Expand Up @@ -170,7 +171,7 @@ func (input *GetListEmployeeInput) Validate() error {
}

func (input CreateEmployeeInput) Validate() error {
teamEmailRegex := ".+@((dwarvesv\\.com)|(d\\.foundation)|(gmail\\.com))"
teamEmailRegex := ".+@((dwarvesv\\.com)|(d\\.foundation))"
regex, _ := regexp.Compile(teamEmailRegex)
if !regex.MatchString(input.TeamEmail) {
return errs.ErrInvalidEmailDomain
Expand Down
4 changes: 2 additions & 2 deletions pkg/handler/notion/project_milestone.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,9 @@ func (h *handler) ListProjectMilestones(c *gin.Context) {
},
}...)

resp, err := h.service.Notion.GetDatabase(h.config.Notion.Databases.Project, filter, nil, 0)
resp, err := h.service.Notion.GetDatabase(h.config.Notion.Databases.Delivery, filter, nil, 0)
if err != nil {
c.JSON(http.StatusBadRequest, view.CreateResponse[any](nil, nil, err, nil, "failed to get projects from notion"))
c.JSON(http.StatusBadRequest, view.CreateResponse[any](nil, nil, err, nil, "failed to get milestones from notion"))
return
}

Expand Down
20 changes: 17 additions & 3 deletions pkg/handler/project/project.go
Original file line number Diff line number Diff line change
Expand Up @@ -2995,12 +2995,26 @@ func (h *handler) UploadAvatar(c *gin.Context) {
func (h *handler) SyncProjectMemberStatus(c *gin.Context) {
l := h.logger.Fields(logger.Fields{
"handler": "project",
"method": "UpdateSendingSurveyState",
"method": "SyncProjectMemberStatus",
})

err := h.store.ProjectMember.UpdateExpMemberToInActive(h.repo.DB())
err := h.store.ProjectMember.UpdateEndDateOverdueMemberToInActive(h.repo.DB())
if err != nil {
l.Error(err, "failed to update end date overdue member status to inactive")
c.JSON(http.StatusInternalServerError, view.CreateResponse[any](nil, nil, err, nil, ""))
return
}

err = h.store.ProjectMember.UpdateMemberInClosedProjectToInActive(h.repo.DB())
if err != nil {
l.Error(err, "failed to update member in closed/paused project status to inactive")
c.JSON(http.StatusInternalServerError, view.CreateResponse[any](nil, nil, err, nil, ""))
return
}

err = h.store.ProjectMember.UpdateLeftMemberToInActive(h.repo.DB())
if err != nil {
l.Error(err, "failed to update project member status to inactive")
l.Error(err, "failed to update left member project status to inactive")
c.JSON(http.StatusInternalServerError, view.CreateResponse[any](nil, nil, err, nil, ""))
return
}
Expand Down
2 changes: 1 addition & 1 deletion pkg/store/currency/pg.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,6 @@ func (c currencyService) GetByName(db *gorm.DB, name string) (*model.Currency, e
}

func (c currencyService) GetList(db *gorm.DB) ([]model.Currency, error) {
currencies := []model.Currency{}
var currencies []model.Currency
return currencies, db.Find(&currencies).Error
}
4 changes: 3 additions & 1 deletion pkg/store/projectmember/interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,9 @@ type IStore interface {
OneByID(db *gorm.DB, id string) (*model.ProjectMember, error)
OneBySlotID(db *gorm.DB, slotID string) (*model.ProjectMember, error)
UpdateEndDateByProjectID(db *gorm.DB, projectID string) error
UpdateExpMemberToInActive(db *gorm.DB) error
UpdateEndDateOverdueMemberToInActive(db *gorm.DB) error
UpdateLeftMemberToInActive(db *gorm.DB) error
UpdateMemberInClosedProjectToInActive(db *gorm.DB) error
UpdateSelectedFieldByProjectID(db *gorm.DB, projectID string, updateModel model.ProjectMember, updatedField string) error
UpdateSelectedFieldsByID(db *gorm.DB, id string, updateModel model.ProjectMember, updatedFields ...string) (*model.ProjectMember, error)
}
Loading

0 comments on commit 83904f8

Please sign in to comment.