package models import ( "context" "fmt" "time" "quyun/app/requests" "quyun/database/fields" "quyun/database/schemas/public/model" "quyun/database/schemas/public/table" . "github.com/go-jet/jet/v2/postgres" "github.com/pkg/errors" "github.com/sirupsen/logrus" ) // @provider type ordersModel struct { log *logrus.Entry `inject:"false"` } func (m *ordersModel) Prepare() error { m.log = logrus.WithField("model", "ordersModel") return nil } // GetByID returns an order by ID func (m *ordersModel) GetByID(ctx context.Context, id int64) (*model.Orders, error) { tbl := table.Orders stmt := tbl. SELECT(tbl.AllColumns). WHERE( tbl.ID.EQ(Int64(id)), ) m.log.Infof("sql: %s", stmt.DebugSql()) var order model.Orders err := stmt.QueryContext(ctx, db, &order) if err != nil { m.log.Errorf("error querying order by ID: %v", err) return nil, err } return &order, nil } // BuildConditionWithKey builds the WHERE clause for order queries func (m *ordersModel) BuildConditionWithKey(orderNumber *string, userID *int64) BoolExpression { tbl := table.Orders cond := Bool(true) if orderNumber != nil && *orderNumber != "" { cond = cond.AND( tbl.OrderNo.LIKE(String("%" + *orderNumber + "%")), ) } if userID != nil { cond = cond.AND( tbl.UserID.EQ(Int(*userID)), ) } return cond } // countByCondition counts orders matching the given condition func (m *ordersModel) countByCondition(ctx context.Context, expr BoolExpression) (int64, error) { var cnt struct { Cnt int64 } tbl := table.Orders stmt := SELECT(COUNT(tbl.ID).AS("cnt")).FROM(tbl).WHERE(expr) m.log.Infof("sql: %s", stmt.DebugSql()) err := stmt.QueryContext(ctx, db, &cnt) if err != nil { m.log.Errorf("error counting orders: %v", err) return 0, err } return cnt.Cnt, nil } // List returns a paginated list of orders func (m *ordersModel) List(ctx context.Context, pagination *requests.Pagination, cond BoolExpression) (*requests.Pager, error) { pagination.Format() tbl := table.Orders stmt := tbl. SELECT(tbl.AllColumns). WHERE(cond). ORDER_BY(tbl.ID.DESC()). LIMIT(pagination.Limit). OFFSET(pagination.Offset) m.log.Infof("sql: %s", stmt.DebugSql()) var orders []model.Orders = make([]model.Orders, 0) err := stmt.QueryContext(ctx, db, &orders) if err != nil { m.log.Errorf("error querying orders: %v", err) return nil, err } count, err := m.countByCondition(ctx, cond) if err != nil { m.log.Errorf("error getting order count: %v", err) return nil, err } return &requests.Pager{ Items: orders, Total: count, Pagination: *pagination, }, nil } // Create creates a new order func (m *ordersModel) Create(ctx context.Context, userId, postId int64) (*model.Orders, error) { post, err := Posts.GetByID(ctx, postId) if err != nil { return nil, errors.Wrap(err, "failed to get post") } model := &model.Orders{} model.CreatedAt = time.Now() model.UpdatedAt = time.Now() model.Status = fields.OrderStatusPending model.OrderNo = fmt.Sprintf("%s", time.Now().Format("20060102150405")) model.SubOrderNo = model.OrderNo model.UserID = userId model.PostID = postId model.Meta = fields.ToJson(fields.OrderMeta{}) model.Price = post.Price model.Discount = post.Discount tbl := table.Orders stmt := tbl.INSERT(tbl.MutableColumns).MODEL(model) m.log.Infof("sql: %s", stmt.DebugSql()) if _, err := stmt.ExecContext(ctx, db); err != nil { m.log.Errorf("error creating order: %v", err) return nil, err } return model, nil } // DeleteByID soft deletes an order by ID func (m *ordersModel) SetStatus(ctx context.Context, orderNo string, status fields.OrderStatus) error { tbl := table.Orders stmt := tbl. UPDATE(tbl.Status). SET(status). WHERE( tbl.OrderNo.EQ(String(orderNo)), ) m.log.Infof("sql: %s", stmt.DebugSql()) if _, err := stmt.ExecContext(ctx, db); err != nil { m.log.Errorf("error set order status: %v", err) return err } return nil }