init project

This commit is contained in:
aditya.siregar
2024-05-28 14:14:55 +07:00
commit 67f1dbc850
141 changed files with 16879 additions and 0 deletions
+143
View File
@@ -0,0 +1,143 @@
package entity
import (
"furtuna-be/internal/constants/role"
"furtuna-be/internal/constants/userstatus"
"time"
)
type AuthData struct {
Token string `json:"token"`
UserID int64 `gorm:"column:user_id"`
RoleID int `gorm:"column:role_id"`
OrganizationID int64 `gorm:"column:organization_id"`
}
type UserDB struct {
ID int64 `gorm:"primary_key;column:id" json:"id"`
Name string `gorm:"column:name" json:"name"`
Email string `gorm:"column:email" json:"email"`
Password string `gorm:"column:password" json:"-"`
Status userstatus.UserStatus `gorm:"column:status" json:"status"`
UserType string `gorm:"column:user_type" json:"user_type"`
PhoneNumber string `gorm:"column:phone_number" json:"phone_number"`
NIK string `gorm:"column:nik" json:"nik"`
RoleID int64 `gorm:"column:role_id" json:"role_id"`
RoleName string `gorm:"column:role_name" json:"role_name"`
BranchID *int64 `gorm:"column:partner_id" json:"partner_id"`
BranchName string `gorm:"column:partner_name" json:"partner_name"`
CreatedAt time.Time `gorm:"column:created_at" json:"created_at"`
UpdatedAt time.Time `gorm:"column:updated_at" json:"updated_at"`
DeletedAt *time.Time `gorm:"column:deleted_at" json:"deleted_at"`
CreatedBy int64 `gorm:"column:created_by" json:"created_by"`
UpdatedBy int64 `gorm:"column:updated_by" json:"updated_by"`
}
func (u *UserDB) ToUser() *User {
if u == nil {
return &User{}
}
userEntity := &User{
ID: u.ID,
Name: u.Name,
Email: u.Email,
Status: u.Status,
CreatedAt: u.CreatedAt,
UpdatedAt: u.UpdatedAt,
RoleID: role.Role(u.RoleID),
RoleName: u.RoleName,
PartnerID: u.BranchID,
BranchName: u.BranchName,
}
return userEntity
}
func (u *UserDB) ToUserRoleDB() *UserRoleDB {
if u == nil {
return &UserRoleDB{}
}
userRole := &UserRoleDB{
ID: 0,
UserID: u.ID,
RoleID: u.RoleID,
PartnerID: u.BranchID,
CreatedAt: u.CreatedAt,
UpdatedAt: u.UpdatedAt,
}
return userRole
}
func (UserDB) TableName() string {
return "users"
}
func (u *UserDB) ToUserAuthenticate(signedToken string) *AuthenticateUser {
return &AuthenticateUser{
Token: signedToken,
Name: u.Name,
RoleID: role.Role(u.RoleID),
RoleName: u.RoleName,
BranchID: u.BranchID,
BranchName: u.BranchName,
}
}
type UserSearch struct {
Search string
Name string
RoleID int64
PartnerID int64
Limit int
Offset int
}
type UserList []*UserDB
func (b *UserList) ToUserList() []*User {
var users []*User
for _, user := range *b {
users = append(users, user.ToUser())
}
return users
}
func (u *UserDB) ToUpdatedUser(req User) error {
if req.Name != "" {
u.Name = req.Name
}
if req.Email != "" {
u.Email = req.Email
}
if *req.PartnerID > 0 {
u.BranchID = req.PartnerID
}
if req.RoleID > 0 {
u.RoleID = int64(req.RoleID)
}
if req.Password != "" {
hashedPassword, err := req.HashedPassword(req.Password)
if err != nil {
return err
}
u.Password = hashedPassword
}
return nil
}
func (o *UserDB) SetDeleted(updatedby int64) {
currentTime := time.Now()
o.DeletedAt = &currentTime
o.UpdatedBy = updatedby
o.Status = userstatus.Inactive
}
+83
View File
@@ -0,0 +1,83 @@
package entity
import (
"furtuna-be/internal/constants/branch"
"time"
)
type Branch struct {
ID int64
Name string
Status branch.BranchStatus
Location string
CreatedAt time.Time
UpdatedAt time.Time
DeletedAt *time.Time
CreatedBy int64
UpdatedBy int64
}
type BranchSearch struct {
Search string
Name string
Limit int
Offset int
}
type BranchList []*BranchDB
type BranchDB struct {
Branch
}
func (b *Branch) ToBranchDB() *BranchDB {
return &BranchDB{
Branch: *b,
}
}
func (BranchDB) TableName() string {
return "branches"
}
func (e *BranchDB) ToBranch() *Branch {
return &Branch{
ID: e.ID,
Name: e.Name,
Status: e.Status,
Location: e.Location,
CreatedAt: e.CreatedAt,
UpdatedAt: e.UpdatedAt,
CreatedBy: e.CreatedBy,
}
}
func (b *BranchList) ToBranchList() []*Branch {
var branches []*Branch
for _, branch := range *b {
branches = append(branches, branch.ToBranch())
}
return branches
}
func (o *BranchDB) ToUpdatedBranch(updatedby int64, req Branch) {
o.UpdatedBy = updatedby
if req.Name != "" {
o.Name = req.Name
}
if req.Status != "" {
o.Status = req.Status
}
if req.Location != "" {
o.Location = req.Location
}
}
func (o *BranchDB) SetDeleted(updatedby int64) {
currentTime := time.Now()
o.DeletedAt = &currentTime
o.UpdatedBy = updatedby
}
+158
View File
@@ -0,0 +1,158 @@
package entity
import (
"database/sql/driver"
"errors"
"strings"
"time"
)
type Status string
type Event struct {
ID int64
Name string
Description string
StartDate time.Time
EndDate time.Time
Location string
Level string
Included StringArray `gorm:"type:text[]"`
Price float64
Paid bool
LocationID *int64
Status Status
CreatedAt time.Time
UpdatedAt time.Time
DeletedAt *time.Time
}
type StringArray []string
func (a StringArray) Value() (driver.Value, error) {
if a == nil {
return nil, nil
}
joined := "{" + strings.Join(a, ",") + "}"
return []byte(joined), nil
}
func (a *StringArray) Scan(src interface{}) error {
if src == nil {
*a = nil
return nil
}
srcStr, ok := src.(string)
if !ok {
return errors.New("failed to scan StringArray")
}
// Remove the curly braces and split the string into elements
if len(srcStr) < 2 || srcStr[0] != '{' || srcStr[len(srcStr)-1] != '}' {
return errors.New("invalid format for StringArray")
}
srcStr = srcStr[1 : len(srcStr)-1]
*a = strings.Split(srcStr, ",")
return nil
}
type EventSearch struct {
Name string
Limit int
Offset int
}
type EventList []*EventDB
type EventDB struct {
Event
}
func (e *Event) ToEventDB() *EventDB {
return &EventDB{
Event: *e,
}
}
func (e *EventDB) ToEvent() *Event {
return &Event{
ID: e.ID,
Name: e.Name,
Description: e.Description,
StartDate: e.StartDate,
EndDate: e.EndDate,
Location: e.Location,
Level: e.Level,
Included: e.Included,
Price: e.Price,
Paid: e.Paid,
LocationID: e.LocationID,
CreatedAt: e.CreatedAt,
UpdatedAt: e.UpdatedAt,
Status: e.Status,
}
}
func (e *EventList) ToEventList() []*Event {
var events []*Event
for _, event := range *e {
events = append(events, event.ToEvent())
}
return events
}
func (EventDB) TableName() string {
return "events"
}
func (o *EventDB) ToUpdatedEvent(req Event) {
if req.Name != "" {
o.Name = req.Name
}
if req.Description != "" {
o.Description = req.Description
}
if !req.StartDate.IsZero() {
o.StartDate = req.StartDate
}
if !req.EndDate.IsZero() {
o.EndDate = req.EndDate
}
if req.Location != "" {
o.Location = req.Location
}
if req.Level != "" {
o.Level = req.Level
}
if req.Included != nil && len(req.Included) > 0 {
o.Included = req.Included
}
if req.Price != 0 {
o.Price = req.Price
}
if req.LocationID != nil {
o.LocationID = req.LocationID
}
if req.Status != "" {
o.Status = req.Status
}
}
func (o *EventDB) SetDeleted() {
currentTime := time.Now()
o.DeletedAt = &currentTime
}
+12
View File
@@ -0,0 +1,12 @@
package entity
import "github.com/golang-jwt/jwt"
type JWTAuthClaims struct {
UserID int64 `json:"id"`
Name string `json:"name"`
Email string `json:"email"`
Role int `json:"role"`
BranchID int64 `json:"branch_id"`
jwt.StandardClaims
}
+166
View File
@@ -0,0 +1,166 @@
package entity
import (
"furtuna-be/internal/constants/order"
"time"
)
type Order struct {
ID int64
BranchID int64
BranchName string
Status order.OrderStatus
Amount float64
CustomerName string `gorm:"column:customer_name" json:"customer_name"`
CustomerPhone string `gorm:"column:customer_phone" json:"customer_phone"`
Pax int `gorm:"column:pax" json:"pax"`
CreatedAt time.Time
UpdatedAt time.Time
CreatedBy int64
UpdatedBy int64
Transaction Transaction
OrderItem []OrderItem
}
type OrderSearch struct {
Search string
StatusActive order.OrderSearchStatus
Status order.OrderStatus
BranchID int64
Limit int
Offset int
}
type OrderTotalRevenueSearch struct {
Year int
Month int
BranchID int64
DateStart *time.Time
DateEnd *time.Time
}
type OrderYearlyRevenueList []OrderYearlyRevenue
type OrderYearlyRevenue struct {
ItemType string `gorm:"column:item_type"`
Month int `gorm:"column:month_number"`
Amount float64 `gorm:"column:total_amount"`
}
type OrderBranchRevenueSearch struct {
DateStart *time.Time
DateEnd *time.Time
}
type OrderBranchRevenueList []OrderBranchRevenue
type OrderBranchRevenue struct {
BranchID string `gorm:"column:branch_id"`
BranchName string `gorm:"column:name"`
BranchLocation string `gorm:"column:location"`
TotalTransaction int `gorm:"column:total_trans"`
TotalAmount float64 `gorm:"column:total_amount"`
}
type OrderList []*OrderDB
type OrderDB struct {
Order
}
func (b *Order) ToOrderDB() *OrderDB {
var amount float64
for _, i := range b.OrderItem {
amount = amount + (i.Price * float64(i.Qty))
}
b.Amount = amount
b.Transaction.Amount = amount
return &OrderDB{
Order: *b,
}
}
func (OrderDB) TableName() string {
return "orders"
}
func (e *OrderDB) ToOrder() *Order {
return &Order{
ID: e.ID,
Status: e.Status,
BranchID: e.BranchID,
BranchName: e.BranchName,
Amount: e.Amount,
CustomerName: e.CustomerName,
CustomerPhone: e.CustomerPhone,
Pax: e.Pax,
Transaction: e.Transaction,
OrderItem: e.OrderItem,
CreatedAt: e.CreatedAt,
UpdatedAt: e.UpdatedAt,
CreatedBy: e.CreatedBy,
UpdatedBy: e.UpdatedBy,
}
}
func (b *OrderList) ToOrderList() []*Order {
var Orders []*Order
for _, order := range *b {
Orders = append(Orders, order.ToOrder())
}
return Orders
}
func (o *OrderDB) ToUpdatedOrder(updatedby int64, req Order) {
o.UpdatedBy = updatedby
if req.Amount > 0 {
o.Amount = req.Amount
}
if req.Status != "" {
o.Status = req.Status
}
}
type OrderItem struct {
OrderItemID int64
OrderID int64
ItemID int64
ItemType order.ItemType
ItemName string
Price float64
Qty int64
CreatedAt time.Time
UpdatedAt time.Time
CreatedBy int64
UpdatedBy int64
}
type OrderItemDB struct {
OrderItem
}
func (b *OrderItem) ToOrderItemDB() *OrderItemDB {
return &OrderItemDB{
OrderItem: *b,
}
}
func (OrderItemDB) TableName() string {
return "order_items"
}
func (e *OrderItemDB) ToOrderItem() *OrderItem {
return &OrderItem{
OrderItemID: e.OrderItemID,
OrderID: e.OrderID,
ItemID: e.ItemID,
ItemType: e.ItemType,
Price: e.Price,
Qty: e.Qty,
CreatedAt: e.CreatedAt,
UpdatedAt: e.UpdatedAt,
CreatedBy: e.CreatedBy,
UpdatedBy: e.UpdatedBy,
}
}
+24
View File
@@ -0,0 +1,24 @@
package entity
import "mime/multipart"
type UploadFileRequest struct {
FileHeader *multipart.FileHeader
FolderName string
FileSize int64 `validate:"max=10000000"` // 10Mb = 10000000 byte
Ext string `validate:"oneof=.png .jpeg .jpg .pdf .xlsx .csv"`
}
type DownloadFileRequest struct {
FileName string `query:"file_name" validate:"required"`
FolderName string `query:"folder_name" validate:"required"`
}
type UploadFileResponse struct {
FilePath string `json:"file_path"`
FileUrl string `json:"file_url"`
}
type DownloadFileResponse struct {
FileUrl string `json:"file_url"`
}
+82
View File
@@ -0,0 +1,82 @@
package entity
import (
"time"
)
type Partner struct {
ID int64
Name string
Status string
Address string
CreatedAt time.Time
UpdatedAt time.Time
DeletedAt *time.Time
CreatedBy int64
UpdatedBy int64
}
type PartnerSearch struct {
Search string
Name string
Limit int
Offset int
}
type PartnerList []*PartnerDB
type PartnerDB struct {
Partner
}
func (p *Partner) ToPartnerDB() *PartnerDB {
return &PartnerDB{
Partner: *p,
}
}
func (PartnerDB) TableName() string {
return "partners"
}
func (e *PartnerDB) ToPartner() *Partner {
return &Partner{
ID: e.ID,
Name: e.Name,
Status: e.Status,
Address: e.Address,
CreatedAt: e.CreatedAt,
UpdatedAt: e.UpdatedAt,
CreatedBy: e.CreatedBy,
}
}
func (p *PartnerList) ToPartnerList() []*Partner {
var partners []*Partner
for _, partner := range *p {
partners = append(partners, partner.ToPartner())
}
return partners
}
func (o *PartnerDB) ToUpdatedPartner(updatedBy int64, req Partner) {
o.UpdatedBy = updatedBy
if req.Name != "" {
o.Name = req.Name
}
if req.Status != "" {
o.Status = req.Status
}
if req.Address != "" {
o.Address = req.Address
}
}
func (o *PartnerDB) SetDeleted(updatedBy int64) {
currentTime := time.Now()
o.DeletedAt = &currentTime
o.UpdatedBy = updatedBy
}
+114
View File
@@ -0,0 +1,114 @@
package entity
import (
"furtuna-be/internal/constants/product"
"time"
)
type Product struct {
ID int64
Name string
Type product.ProductType
Price float64
Status product.ProductStatus
Description string
Image string
BranchID int64
StockQty int64
CreatedAt time.Time
UpdatedAt time.Time
DeletedAt *time.Time
CreatedBy int64
UpdatedBy int64
}
type ProductSearch struct {
Search string
Name string
Type product.ProductType
BranchID int64
Available product.ProductStock
Limit int
Offset int
}
type ProductList []*ProductDB
type ProductDB struct {
Product
}
func (b *Product) ToProductDB() *ProductDB {
return &ProductDB{
Product: *b,
}
}
func (ProductDB) TableName() string {
return "products"
}
func (e *ProductDB) ToProduct() *Product {
return &Product{
ID: e.ID,
Name: e.Name,
Type: e.Type,
Price: e.Price,
Status: e.Status,
Description: e.Description,
Image: e.Image,
BranchID: e.BranchID,
StockQty: e.StockQty,
CreatedAt: e.CreatedAt,
UpdatedAt: e.UpdatedAt,
DeletedAt: e.DeletedAt,
CreatedBy: e.CreatedBy,
UpdatedBy: e.UpdatedBy,
}
}
func (b *ProductList) ToProductList() []*Product {
var Products []*Product
for _, product := range *b {
Products = append(Products, product.ToProduct())
}
return Products
}
func (o *ProductDB) ToUpdatedProduct(updatedby int64, req Product) {
o.UpdatedBy = updatedby
if req.Name != "" {
o.Name = req.Name
}
if req.Type != "" {
o.Type = req.Type
}
if req.Price > 0 {
o.Price = req.Price
}
if req.Status != "" {
o.Status = req.Status
}
if req.Description != "" {
o.Description = req.Description
}
if req.Image != "" {
o.Image = req.Image
}
if req.StockQty > 0 {
o.StockQty = req.StockQty
}
}
func (o *ProductDB) SetDeleted(updatedby int64) {
currentTime := time.Now()
o.DeletedAt = &currentTime
o.UpdatedBy = updatedby
}
+95
View File
@@ -0,0 +1,95 @@
package entity
import (
"furtuna-be/internal/constants/studio"
"time"
)
type Studio struct {
ID int64
BranchId int64
Name string
Status studio.StudioStatus
Price float64
Metadata []byte `gorm:"type:jsonb"` // Use jsonb data type for JSON data
CreatedAt time.Time
UpdatedAt time.Time
CreatedBy int64
UpdatedBy int64
}
func (s *Studio) TableName() string {
return "studios"
}
func (s *Studio) NewStudiosDB() *StudioDB {
return &StudioDB{
Studio: *s,
}
}
type StudioList []*StudioDB
type StudioDB struct {
Studio
}
func (s *StudioDB) ToStudio() *Studio {
return &Studio{
ID: s.ID,
BranchId: s.BranchId,
Name: s.Name,
Status: s.Status,
Price: s.Price,
Metadata: s.Metadata,
CreatedAt: s.CreatedAt,
UpdatedAt: s.UpdatedAt,
CreatedBy: s.CreatedBy,
UpdatedBy: s.UpdatedBy,
}
}
func (s *StudioList) ToStudioList() []*Studio {
var studios []*Studio
for _, studio := range *s {
studios = append(studios, studio.ToStudio())
}
return studios
}
func (s *StudioDB) ToUpdatedStudio(updatedBy int64, req Studio) {
s.UpdatedBy = updatedBy
if req.BranchId != 0 {
s.BranchId = req.BranchId
}
if req.Name != "" {
s.Name = req.Name
}
if req.Status != "" {
s.Status = req.Status
}
if req.Price != 0 {
s.Price = req.Price
}
if req.Metadata != nil {
s.Metadata = req.Metadata
}
}
func (s *StudioDB) ToStudioDB() *StudioDB {
return s
}
type StudioSearch struct {
Id int64
Name string
Status studio.StudioStatus
BranchId int64
Limit int
Offset int
}
+35
View File
@@ -0,0 +1,35 @@
package entity
import (
"furtuna-be/internal/constants/transaction"
"time"
)
type Transaction struct {
ID int64
BranchID int64
Status transaction.PaymentStatus
Amount float64
OrderID int64
PaymentMethod transaction.PaymentMethod
CustomerName string
CustomerPhone string
CreatedAt time.Time
UpdatedAt time.Time
CreatedBy int64
UpdatedBy int64
}
type TransactionDB struct {
Transaction
}
func (b *Transaction) ToTransactionDB() *TransactionDB {
return &TransactionDB{
Transaction: *b,
}
}
func (TransactionDB) TableName() string {
return "transactions"
}
+78
View File
@@ -0,0 +1,78 @@
package entity
import (
"errors"
"furtuna-be/internal/constants/role"
"furtuna-be/internal/constants/userstatus"
"time"
"golang.org/x/crypto/bcrypt"
)
type User struct {
ID int64
Name string
Email string
Password string
Status userstatus.UserStatus
NIK string
CreatedAt time.Time
UpdatedAt time.Time
RoleID role.Role
RoleName string
PartnerID *int64
BranchName string
}
type AuthenticateUser struct {
Token string
Name string
RoleID role.Role
RoleName string
BranchID *int64
BranchName string
}
type UserRoleDB struct {
ID int64 `gorm:"primary_key;column:user_role_id" `
UserID int64 `gorm:"column:user_id"`
RoleID int64 `gorm:"column:role_id"`
PartnerID *int64 `gorm:"column:partner_id"`
CreatedAt time.Time `gorm:"column:created_at"`
UpdatedAt time.Time `gorm:"column:updated_at"`
}
func (UserRoleDB) TableName() string {
return "user_roles"
}
func (u *User) ToUserDB(createdBy int64) (*UserDB, error) {
hashedPassword, err := u.HashedPassword(u.Password)
if err != nil {
return nil, err
}
if u.RoleID == role.BranchAdmin && u.PartnerID == nil {
return nil, errors.New("invalid request")
}
return &UserDB{
Name: u.Name,
Email: u.Email,
Password: hashedPassword,
RoleID: int64(u.RoleID),
BranchID: u.PartnerID,
Status: userstatus.Active,
CreatedBy: createdBy,
}, nil
}
func (u User) HashedPassword(password string) (string, error) {
hashedPassword, err := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost)
if err != nil {
return "", err
}
return string(hashedPassword), nil
}