Mhamdans17 commited on
Commit ·
c91764d
1
Parent(s): ab2ac06
feat: implement automated member points calculation
Browse files- controllers/company_controller.go +41 -0
- controllers/order_controller.go +20 -1
- main.go +1 -0
- models/models.go +2 -0
controllers/company_controller.go
CHANGED
|
@@ -48,6 +48,11 @@ type CompanyCreateRequest struct {
|
|
| 48 |
TripayProxyURL string `json:"tripay_proxy_url"`
|
| 49 |
}
|
| 50 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 51 |
type BranchCreateRequest struct {
|
| 52 |
Name string `json:"name" binding:"required"`
|
| 53 |
Address string `json:"address"`
|
|
@@ -206,6 +211,42 @@ func GetMyCompany(c *gin.Context) {
|
|
| 206 |
c.JSON(http.StatusOK, company)
|
| 207 |
}
|
| 208 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 209 |
func GetCompany(c *gin.Context) {
|
| 210 |
companyIDStr := c.Param("company_id")
|
| 211 |
companyID, err := strconv.Atoi(companyIDStr)
|
|
|
|
| 48 |
TripayProxyURL string `json:"tripay_proxy_url"`
|
| 49 |
}
|
| 50 |
|
| 51 |
+
type UpdateCompanyPointsRequest struct {
|
| 52 |
+
PointEarnAmount int `json:"point_earn_amount"`
|
| 53 |
+
PointEarnRate int `json:"point_earn_rate"`
|
| 54 |
+
}
|
| 55 |
+
|
| 56 |
type BranchCreateRequest struct {
|
| 57 |
Name string `json:"name" binding:"required"`
|
| 58 |
Address string `json:"address"`
|
|
|
|
| 211 |
c.JSON(http.StatusOK, company)
|
| 212 |
}
|
| 213 |
|
| 214 |
+
func UpdateMyCompanyPoints(c *gin.Context) {
|
| 215 |
+
userVal, exists := c.Get("user")
|
| 216 |
+
if !exists {
|
| 217 |
+
c.JSON(http.StatusUnauthorized, gin.H{"detail": "Unauthorized"})
|
| 218 |
+
return
|
| 219 |
+
}
|
| 220 |
+
user := userVal.(*models.User)
|
| 221 |
+
|
| 222 |
+
if user.CompanyID == nil || user.Role != "owner" {
|
| 223 |
+
c.JSON(http.StatusForbidden, gin.H{"detail": "Hanya owner yang bisa mengatur poin"})
|
| 224 |
+
return
|
| 225 |
+
}
|
| 226 |
+
|
| 227 |
+
var req UpdateCompanyPointsRequest
|
| 228 |
+
if err := c.ShouldBindJSON(&req); err != nil {
|
| 229 |
+
c.JSON(http.StatusBadRequest, gin.H{"detail": "Data tidak valid"})
|
| 230 |
+
return
|
| 231 |
+
}
|
| 232 |
+
|
| 233 |
+
var company models.Company
|
| 234 |
+
if err := config.DB.First(&company, *user.CompanyID).Error; err != nil {
|
| 235 |
+
c.JSON(http.StatusNotFound, gin.H{"detail": "Perusahaan tidak ditemukan"})
|
| 236 |
+
return
|
| 237 |
+
}
|
| 238 |
+
|
| 239 |
+
company.PointEarnAmount = req.PointEarnAmount
|
| 240 |
+
company.PointEarnRate = req.PointEarnRate
|
| 241 |
+
|
| 242 |
+
if err := config.DB.Save(&company).Error; err != nil {
|
| 243 |
+
c.JSON(http.StatusInternalServerError, gin.H{"detail": "Gagal menyimpan pengaturan poin"})
|
| 244 |
+
return
|
| 245 |
+
}
|
| 246 |
+
|
| 247 |
+
c.JSON(http.StatusOK, gin.H{"message": "Pengaturan poin berhasil disimpan", "company": company})
|
| 248 |
+
}
|
| 249 |
+
|
| 250 |
func GetCompany(c *gin.Context) {
|
| 251 |
companyIDStr := c.Param("company_id")
|
| 252 |
companyID, err := strconv.Atoi(companyIDStr)
|
controllers/order_controller.go
CHANGED
|
@@ -390,6 +390,8 @@ func PayCash(c *gin.Context) {
|
|
| 390 |
return
|
| 391 |
}
|
| 392 |
|
|
|
|
|
|
|
| 393 |
if err := tx.Commit().Error; err != nil {
|
| 394 |
tx.Rollback()
|
| 395 |
c.JSON(http.StatusInternalServerError, gin.H{"detail": "Gagal memproses pembayaran"})
|
|
@@ -613,11 +615,11 @@ func TripayWebhook(c *gin.Context) {
|
|
| 613 |
}
|
| 614 |
}
|
| 615 |
|
| 616 |
-
// Jika sukses terbayar, hitung platform fee
|
| 617 |
if order.PaymentStatus == "paid" && oldStatus != "paid" {
|
| 618 |
var company models.Company
|
| 619 |
if err := tx.First(&company, order.CompanyID).Error; err == nil {
|
| 620 |
order.PlatformFee = int(float64(order.TotalAmount) * company.FeePercentage / 100)
|
|
|
|
| 621 |
}
|
| 622 |
}
|
| 623 |
|
|
@@ -811,3 +813,20 @@ func restoreStock(tx *gorm.DB, order *models.Order) {
|
|
| 811 |
}
|
| 812 |
}
|
| 813 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 390 |
return
|
| 391 |
}
|
| 392 |
|
| 393 |
+
awardPoints(tx, &order, &company)
|
| 394 |
+
|
| 395 |
if err := tx.Commit().Error; err != nil {
|
| 396 |
tx.Rollback()
|
| 397 |
c.JSON(http.StatusInternalServerError, gin.H{"detail": "Gagal memproses pembayaran"})
|
|
|
|
| 615 |
}
|
| 616 |
}
|
| 617 |
|
|
|
|
| 618 |
if order.PaymentStatus == "paid" && oldStatus != "paid" {
|
| 619 |
var company models.Company
|
| 620 |
if err := tx.First(&company, order.CompanyID).Error; err == nil {
|
| 621 |
order.PlatformFee = int(float64(order.TotalAmount) * company.FeePercentage / 100)
|
| 622 |
+
awardPoints(tx, &order, &company)
|
| 623 |
}
|
| 624 |
}
|
| 625 |
|
|
|
|
| 813 |
}
|
| 814 |
}
|
| 815 |
}
|
| 816 |
+
|
| 817 |
+
func awardPoints(tx *gorm.DB, order *models.Order, company *models.Company) {
|
| 818 |
+
if order.MemberID == nil {
|
| 819 |
+
return
|
| 820 |
+
}
|
| 821 |
+
if company.PointEarnAmount > 0 && company.PointEarnRate > 0 {
|
| 822 |
+
pointsToAdd := (order.TotalAmount / company.PointEarnAmount) * company.PointEarnRate
|
| 823 |
+
if pointsToAdd > 0 {
|
| 824 |
+
var member models.Member
|
| 825 |
+
if err := tx.First(&member, *order.MemberID).Error; err == nil {
|
| 826 |
+
member.Points += pointsToAdd
|
| 827 |
+
tx.Save(&member)
|
| 828 |
+
log.Printf("[POINTS] Member %s (+%d poin dari transaksi %d)", member.Name, pointsToAdd, order.TotalAmount)
|
| 829 |
+
}
|
| 830 |
+
}
|
| 831 |
+
}
|
| 832 |
+
}
|
main.go
CHANGED
|
@@ -122,6 +122,7 @@ func main() {
|
|
| 122 |
companies.Use(middleware.GetCurrentUser())
|
| 123 |
{
|
| 124 |
companies.GET("/me", controllers.GetMyCompany)
|
|
|
|
| 125 |
companies.GET("/", middleware.RequireSuperAdmin(), controllers.ListCompanies)
|
| 126 |
companies.GET("/:company_id", middleware.RequireSuperAdmin(), controllers.GetCompany)
|
| 127 |
companies.POST("/", middleware.RequireSuperAdmin(), controllers.CreateCompany)
|
|
|
|
| 122 |
companies.Use(middleware.GetCurrentUser())
|
| 123 |
{
|
| 124 |
companies.GET("/me", controllers.GetMyCompany)
|
| 125 |
+
companies.PUT("/me/points", controllers.UpdateMyCompanyPoints)
|
| 126 |
companies.GET("/", middleware.RequireSuperAdmin(), controllers.ListCompanies)
|
| 127 |
companies.GET("/:company_id", middleware.RequireSuperAdmin(), controllers.GetCompany)
|
| 128 |
companies.POST("/", middleware.RequireSuperAdmin(), controllers.CreateCompany)
|
models/models.go
CHANGED
|
@@ -20,6 +20,8 @@ type Company struct {
|
|
| 20 |
TripayAPIKey string `gorm:"type:text" json:"tripay_api_key"`
|
| 21 |
TripayPrivateKey string `gorm:"type:text" json:"tripay_private_key"`
|
| 22 |
TripayProxyURL string `gorm:"type:text" json:"tripay_proxy_url"`
|
|
|
|
|
|
|
| 23 |
CreatedAt time.Time `gorm:"autoCreateTime" json:"created_at"`
|
| 24 |
Branches []Branch `gorm:"foreignKey:CompanyID;constraint:OnDelete:CASCADE" json:"-"`
|
| 25 |
Users []User `gorm:"foreignKey:CompanyID;constraint:OnDelete:CASCADE" json:"-"`
|
|
|
|
| 20 |
TripayAPIKey string `gorm:"type:text" json:"tripay_api_key"`
|
| 21 |
TripayPrivateKey string `gorm:"type:text" json:"tripay_private_key"`
|
| 22 |
TripayProxyURL string `gorm:"type:text" json:"tripay_proxy_url"`
|
| 23 |
+
PointEarnAmount int `gorm:"default:0" json:"point_earn_amount"`
|
| 24 |
+
PointEarnRate int `gorm:"default:0" json:"point_earn_rate"`
|
| 25 |
CreatedAt time.Time `gorm:"autoCreateTime" json:"created_at"`
|
| 26 |
Branches []Branch `gorm:"foreignKey:CompanyID;constraint:OnDelete:CASCADE" json:"-"`
|
| 27 |
Users []User `gorm:"foreignKey:CompanyID;constraint:OnDelete:CASCADE" json:"-"`
|