diff --git a/delivery/http_server/admin/kind_box_req/deliver.go b/delivery/http_server/admin/kind_box_req/deliver.go index ca222a9..d8460ae 100644 --- a/delivery/http_server/admin/kind_box_req/deliver.go +++ b/delivery/http_server/admin/kind_box_req/deliver.go @@ -1,13 +1,13 @@ package adminkindboxreqhandler import ( - "net/http" - "strconv" - + "context" param "git.gocasts.ir/ebhomengo/niki/param/admin/kind_box_req" errmsg "git.gocasts.ir/ebhomengo/niki/pkg/err_msg" httpmsg "git.gocasts.ir/ebhomengo/niki/pkg/http_msg" + querier "git.gocasts.ir/ebhomengo/niki/pkg/query_transaction/sql" echo "github.com/labstack/echo/v4" + "net/http" ) // Deliver godoc @@ -16,6 +16,7 @@ import ( // @Accept json // @Produce json // @Param id path int true "KindBoxReq ID" +// @Param Request body param.DeliverKindBoxReqRequest true "KindBoxReq deliver request details" // @Success 200 {object} param.DeliverKindBoxReqResponse // @Failure 400 {string} "Bad request" // @Security AuthBearerAdmin @@ -23,14 +24,10 @@ import ( func (h Handler) Deliver(c echo.Context) error { var req param.DeliverKindBoxReqRequest - id, cErr := strconv.ParseUint(c.Param("id"), 10, 64) - - if cErr != nil { - return c.JSON(http.StatusBadRequest, errmsg.ErrorMsgInvalidInput) + if bErr := c.Bind(&req); bErr != nil { + return echo.NewHTTPError(http.StatusBadRequest) } - req.KindBoxReqID = uint(id) - if fieldErrors, err := h.adminKindBoxReqVld.ValidateDeliver(req); err != nil { msg, code := httpmsg.Error(err) @@ -40,13 +37,21 @@ func (h Handler) Deliver(c echo.Context) error { }) } - resp, sErr := h.adminKindBoxReqSvc.Deliver(c.Request().Context(), req) - + q := querier.GetQuerierFromContextOrNew(c.Request().Context()).Begin() + ctx := context.WithValue(c.Request().Context(), querier.QuerierContextKey, q) + resp, sErr := h.adminKindBoxReqSvc.Deliver(ctx, req) if sErr != nil { + rErr := q.Rollback() + if rErr != nil { + return echo.NewHTTPError(http.StatusInternalServerError, errmsg.ErrorMsgSomethingWentWrong) + } msg, code := httpmsg.Error(sErr) return echo.NewHTTPError(code, msg) } - + cErr := q.Commit() + if cErr != nil { + return echo.NewHTTPError(http.StatusInternalServerError, errmsg.ErrorMsgSomethingWentWrong) + } return c.JSON(http.StatusOK, resp) } diff --git a/docs/docs.go b/docs/docs.go index 9dbb080..1108ead 100644 --- a/docs/docs.go +++ b/docs/docs.go @@ -938,6 +938,15 @@ const docTemplate = `{ "name": "id", "in": "path", "required": true + }, + { + "description": "KindBoxReq deliver request details", + "name": "Request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/adminkindboxreqparam.DeliverKindBoxReqRequest" + } } ], "responses": { @@ -1791,6 +1800,9 @@ const docTemplate = `{ "deliverReferDate": { "type": "string" }, + "deliverReferTimeID": { + "type": "integer" + }, "deliveredAt": { "type": "string" }, @@ -1840,6 +1852,22 @@ const docTemplate = `{ "adminkindboxreqparam.AssignSenderResponse": { "type": "object" }, + "adminkindboxreqparam.DeliverKindBoxReqRequest": { + "type": "object", + "properties": { + "serial_numbers": { + "type": "array", + "items": { + "type": "string" + }, + "example": [ + "1", + "2", + "3" + ] + } + } + }, "adminkindboxreqparam.DeliverKindBoxReqResponse": { "type": "object" }, @@ -2349,6 +2377,9 @@ const docTemplate = `{ "deliverReferDate": { "type": "string" }, + "deliverReferTimeID": { + "type": "integer" + }, "deliveredAt": { "type": "string" }, @@ -2601,6 +2632,9 @@ const docTemplate = `{ "deliverReferDate": { "type": "string" }, + "deliverReferTimeID": { + "type": "integer" + }, "deliveredAt": { "type": "string" }, diff --git a/docs/swagger.json b/docs/swagger.json index 32d90b1..e0570d3 100644 --- a/docs/swagger.json +++ b/docs/swagger.json @@ -927,6 +927,15 @@ "name": "id", "in": "path", "required": true + }, + { + "description": "KindBoxReq deliver request details", + "name": "Request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/adminkindboxreqparam.DeliverKindBoxReqRequest" + } } ], "responses": { @@ -1780,6 +1789,9 @@ "deliverReferDate": { "type": "string" }, + "deliverReferTimeID": { + "type": "integer" + }, "deliveredAt": { "type": "string" }, @@ -1829,6 +1841,22 @@ "adminkindboxreqparam.AssignSenderResponse": { "type": "object" }, + "adminkindboxreqparam.DeliverKindBoxReqRequest": { + "type": "object", + "properties": { + "serial_numbers": { + "type": "array", + "items": { + "type": "string" + }, + "example": [ + "1", + "2", + "3" + ] + } + } + }, "adminkindboxreqparam.DeliverKindBoxReqResponse": { "type": "object" }, @@ -2338,6 +2366,9 @@ "deliverReferDate": { "type": "string" }, + "deliverReferTimeID": { + "type": "integer" + }, "deliveredAt": { "type": "string" }, @@ -2590,6 +2621,9 @@ "deliverReferDate": { "type": "string" }, + "deliverReferTimeID": { + "type": "integer" + }, "deliveredAt": { "type": "string" }, diff --git a/docs/swagger.yaml b/docs/swagger.yaml index b98638b..2503b7c 100644 --- a/docs/swagger.yaml +++ b/docs/swagger.yaml @@ -96,6 +96,8 @@ definitions: type: integer deliverReferDate: type: string + deliverReferTimeID: + type: integer deliveredAt: type: string id: @@ -128,6 +130,17 @@ definitions: type: object adminkindboxreqparam.AssignSenderResponse: type: object + adminkindboxreqparam.DeliverKindBoxReqRequest: + properties: + serial_numbers: + example: + - "1" + - "2" + - "3" + items: + type: string + type: array + type: object adminkindboxreqparam.DeliverKindBoxReqResponse: type: object adminkindboxreqparam.DeliveryAwaitingGetAllResponse: @@ -461,6 +474,8 @@ definitions: type: integer deliverReferDate: type: string + deliverReferTimeID: + type: integer deliveredAt: type: string id: @@ -630,6 +645,8 @@ definitions: type: integer deliverReferDate: type: string + deliverReferTimeID: + type: integer deliveredAt: type: string id: @@ -1369,6 +1386,12 @@ paths: name: id required: true type: integer + - description: KindBoxReq deliver request details + in: body + name: Request + required: true + schema: + $ref: '#/definitions/adminkindboxreqparam.DeliverKindBoxReqRequest' produces: - application/json responses: diff --git a/entity/kind_box.go b/entity/kind_box.go index 717d9b1..021da0a 100644 --- a/entity/kind_box.go +++ b/entity/kind_box.go @@ -3,20 +3,21 @@ package entity import "time" type KindBox struct { - ID uint - KindBoxReqID uint - BenefactorID uint - KindBoxType KindBoxType - Amount uint - SerialNumber string - Status KindBoxStatus - DeliverReferDate time.Time - DeliverAddressID uint - SenderAgentID uint - DeliveredAt time.Time - ReturnReferTimeID uint - ReturnReferDate time.Time - ReturnAddressID uint - ReceiverAgentID uint - ReturnedAt time.Time + ID uint + KindBoxReqID uint + BenefactorID uint + KindBoxType KindBoxType + Amount uint + SerialNumber string + Status KindBoxStatus + DeliverReferTimeID uint + DeliverReferDate time.Time + DeliverAddressID uint + SenderAgentID uint + DeliveredAt time.Time + ReturnReferTimeID uint + ReturnReferDate time.Time + ReturnAddressID uint + ReceiverAgentID uint + ReturnedAt time.Time } diff --git a/param/admin/kind_box/add.go b/param/admin/kind_box/add.go index 358b56d..14cb8e4 100644 --- a/param/admin/kind_box/add.go +++ b/param/admin/kind_box/add.go @@ -7,14 +7,16 @@ import ( ) type AddKindBoxRequest struct { - KindBoxReqID uint - BenefactorID uint - Type entity.KindBoxType - DeliverReferDate time.Time - DeliverAddressID uint - SenderAgentID uint - DeliveredAt time.Time - CountAccepted uint + KindBoxReqID uint + BenefactorID uint + Type entity.KindBoxType + DeliverReferTimeID uint + DeliverReferDate time.Time + DeliverAddressID uint + SenderAgentID uint + DeliveredAt time.Time + CountAccepted uint + SerialNumbers []string } type AddKindBoxResponse struct{} diff --git a/param/admin/kind_box_req/deliver.go b/param/admin/kind_box_req/deliver.go index 8bd660f..e3573c0 100644 --- a/param/admin/kind_box_req/deliver.go +++ b/param/admin/kind_box_req/deliver.go @@ -1,7 +1,8 @@ package adminkindboxreqparam type DeliverKindBoxReqRequest struct { - KindBoxReqID uint `json:"-"` + KindBoxReqID uint `json:"-" param:"id"` + SerialNumbers []string `json:"serial_numbers" example:"1,2,3"` } type DeliverKindBoxReqResponse struct{} diff --git a/pkg/err_msg/message.go b/pkg/err_msg/message.go index 4c5ef34..eda2b5f 100644 --- a/pkg/err_msg/message.go +++ b/pkg/err_msg/message.go @@ -34,4 +34,5 @@ const ( ErrorMsgSortDirectionShouldBeAscOrDesc = "sort direction should be asc or desc" ErrorMsgSortFieldIsNotValid = "sort field is not valid" ErrorMsgAssignReceiverAgentKindBoxStatus = "only ready to return kindboxes can be assigned to a receiver agent" + ErrorMsgInvalidSerialNumberRange = "invalid serial number range" ) diff --git a/pkg/query_transaction/sql/querier.go b/pkg/query_transaction/sql/querier.go new file mode 100644 index 0000000..a795e86 --- /dev/null +++ b/pkg/query_transaction/sql/querier.go @@ -0,0 +1,93 @@ +package querier + +import ( + "context" + "database/sql" + "sync" + "sync/atomic" +) + +const ( + QuerierContextKey = "querier" +) + +type conn interface { + Commit() error + Rollback() error + Begin() (*sql.Tx, error) + BeginTx(ctx context.Context, opts *sql.TxOptions) (*sql.Tx, error) + QueryRow(query string, args ...any) *sql.Row + QueryRowContext(ctx context.Context, query string, args ...any) *sql.Row + Exec(query string, args ...any) (sql.Result, error) + ExecContext(ctx context.Context, query string, args ...any) (sql.Result, error) +} + +type querier struct { + txRequested atomic.Bool + initOnce sync.Once + conn conn +} + +func GetQuerierFromContextOrNew(ctx context.Context) *querier { + q, ok := ctx.Value(QuerierContextKey).(*querier) + if !ok { + q = &querier{ + txRequested: atomic.Bool{}, + initOnce: sync.Once{}, + conn: nil, + } + } + return q +} +func (q *querier) Begin() *querier { + q.txRequested.Store(true) + return q +} +func (q *querier) Continue(ctx context.Context, conn conn) (*querier, error) { + var iErr error + q.initOnce.Do(func() { + if q.txRequested.Load() { + tx, bErr := conn.BeginTx(ctx, nil) + if bErr != nil { + iErr = bErr + return + } + q.conn = &SqlTx{tx} + } else { + q.conn = conn.(*SqlDB) + } + }) + return q, iErr +} +func (q *querier) Commit() error { + return q.conn.Commit() +} +func (q *querier) Rollback() error { + return q.conn.Rollback() +} +func (q *querier) Conn() conn { + return q.conn +} + +type SqlTx struct { + *sql.Tx +} + +func (tx *SqlTx) Begin() (*sql.Tx, error) { + return &sql.Tx{}, nil +} +func (tx *SqlTx) BeginTx(ctx context.Context, opts *sql.TxOptions) (*sql.Tx, error) { + return &sql.Tx{}, nil +} + +type SqlDB struct { + *sql.DB +} + +func (db *SqlDB) Commit() error { + return nil +} + +func (db *SqlDB) Rollback() error { + return nil +} diff --git a/repository/mysql/db.go b/repository/mysql/db.go index db43a88..e2ad514 100644 --- a/repository/mysql/db.go +++ b/repository/mysql/db.go @@ -3,6 +3,7 @@ package mysql import ( "database/sql" "fmt" + querier "git.gocasts.ir/ebhomengo/niki/pkg/query_transaction/sql" "time" ) @@ -16,11 +17,11 @@ type Config struct { type DB struct { config Config - db *sql.DB + db *querier.SqlDB } -func (m *DB) Conn() *sql.DB { - return m.db +func (db *DB) Conn() *querier.SqlDB { + return db.db } // TODO: this temperary to ignore linter error (magic number). @@ -45,5 +46,5 @@ func New(config Config) *DB { db.SetMaxOpenConns(dbMaxOpenConns) db.SetMaxIdleConns(dbMaxIdleConns) - return &DB{config: config, db: db} + return &DB{config: config, db: &querier.SqlDB{db}} } diff --git a/repository/mysql/kind_box/add.go b/repository/mysql/kind_box/add.go index 5e2f384..ced975d 100644 --- a/repository/mysql/kind_box/add.go +++ b/repository/mysql/kind_box/add.go @@ -2,9 +2,10 @@ package mysqlkindbox import ( "context" - + "database/sql" "git.gocasts.ir/ebhomengo/niki/entity" errmsg "git.gocasts.ir/ebhomengo/niki/pkg/err_msg" + querytransaction "git.gocasts.ir/ebhomengo/niki/pkg/query_transaction/sql" richerror "git.gocasts.ir/ebhomengo/niki/pkg/rich_error" ) @@ -24,21 +25,28 @@ func (d DB) AddKindBox(ctx context.Context, kindBox entity.KindBox) error { func (d DB) AddBatchKindBox(ctx context.Context, kindBoxes []entity.KindBox) error { const op = "mysqlkindbox.AddBatchKindBoxConcurrentlyRollback" - queryStr := "INSERT INTO kind_boxes (kind_box_req_id, benefactor_id, type, status ,deliver_refer_date,deliver_address_id,sender_agent_id,delivered_at) VALUES " + queryStr := "INSERT INTO kind_boxes (kind_box_req_id, benefactor_id, type, serial_number, status ,deliver_refer_time_id,deliver_refer_date,deliver_address_id,sender_agent_id,delivered_at) VALUES " values := []any{} for _, kb := range kindBoxes { - queryStr += "(?, ?, ?, ?, ?, ?, ?, ?)," - values = append(values, kb.KindBoxReqID, kb.BenefactorID, kb.KindBoxType, kb.Status.String(), kb.DeliverReferDate, kb.DeliverAddressID, kb.SenderAgentID, kb.DeliveredAt) + queryStr += "(?, ?, ?, ?, ?, ?, ?, ?, ?, ?)," + if kb.SerialNumber == "" { + values = append(values, kb.KindBoxReqID, kb.BenefactorID, kb.KindBoxType, sql.NullString{}, kb.Status.String(), kb.DeliverReferTimeID, kb.DeliverReferDate, kb.DeliverAddressID, kb.SenderAgentID, kb.DeliveredAt) + } else { + values = append(values, kb.KindBoxReqID, kb.BenefactorID, kb.KindBoxType, kb.SerialNumber, kb.Status.String(), kb.DeliverReferTimeID, kb.DeliverReferDate, kb.DeliverAddressID, kb.SenderAgentID, kb.DeliveredAt) + } } - - // trim the last , + // trim the last ',' queryStr = queryStr[0 : len(queryStr)-1] - if _, err := d.conn.Conn().ExecContext(ctx, queryStr, values...); err != nil { - return richerror.New(op).WithErr(err). + q, cErr := querytransaction.GetQuerierFromContextOrNew(ctx).Continue(ctx, d.conn.Conn()) + if cErr != nil { + return richerror.New(op).WithErr(cErr). + WithMessage(errmsg.ErrorMsgCantScanQueryResult).WithKind(richerror.KindUnexpected) + } + if _, aErr := q.Conn().ExecContext(ctx, queryStr, values...); aErr != nil { + return richerror.New(op).WithErr(aErr). WithMessage(errmsg.ErrorMsgSomethingWentWrong).WithKind(richerror.KindUnexpected) } - return nil } diff --git a/repository/mysql/kind_box_req/deliver.go b/repository/mysql/kind_box_req/deliver.go index 8f0b381..d9bc568 100644 --- a/repository/mysql/kind_box_req/deliver.go +++ b/repository/mysql/kind_box_req/deliver.go @@ -2,6 +2,7 @@ package mysqlkindboxreq import ( "context" + querier "git.gocasts.ir/ebhomengo/niki/pkg/query_transaction/sql" "time" entity "git.gocasts.ir/ebhomengo/niki/entity" @@ -11,13 +12,16 @@ import ( func (d DB) DeliverKindBoxReq(ctx context.Context, kindBoxReqID uint) error { const op = "mysqlkindboxreq.DeliverKindBoxReq" - - _, err := d.conn.Conn().ExecContext(ctx, `update kind_box_reqs set status = ?, delivered_at = ? where id = ?`, + q, cErr := querier.GetQuerierFromContextOrNew(ctx).Continue(ctx, d.conn.Conn()) + if cErr != nil { + return richerror.New(op).WithErr(cErr). + WithMessage(errmsg.ErrorMsgCantScanQueryResult).WithKind(richerror.KindUnexpected) + } + _, uErr := q.Conn().ExecContext(ctx, `update kind_box_reqs set status = ?, delivered_at = ? where id = ?`, entity.KindBoxReqDeliveredStatus.String(), time.Now(), kindBoxReqID) - if err != nil { - return richerror.New(op).WithErr(err). + if uErr != nil { + return richerror.New(op).WithErr(uErr). WithMessage(errmsg.ErrorMsgSomethingWentWrong).WithKind(richerror.KindUnexpected) } - return nil } diff --git a/repository/mysql/kind_box_req/get.go b/repository/mysql/kind_box_req/get.go index cf595ea..caaf088 100644 --- a/repository/mysql/kind_box_req/get.go +++ b/repository/mysql/kind_box_req/get.go @@ -3,18 +3,23 @@ package mysqlkindboxreq import ( "context" "database/sql" - "git.gocasts.ir/ebhomengo/niki/entity" errmsg "git.gocasts.ir/ebhomengo/niki/pkg/err_msg" + querier "git.gocasts.ir/ebhomengo/niki/pkg/query_transaction/sql" richerror "git.gocasts.ir/ebhomengo/niki/pkg/rich_error" ) func (d DB) GetByID(ctx context.Context, id uint) (entity.KindBoxReq, error) { op := richerror.Op("mysqlkindboxreq.GetByID") - row := d.conn.Conn().QueryRowContext(ctx, `select * from kind_box_reqs where id = ? and deleted_at is null`, id) - k, err := scanKindBoxReq(row) - if err != nil { - return entity.KindBoxReq{}, richerror.New(op).WithErr(err). + q, cErr := querier.GetQuerierFromContextOrNew(ctx).Continue(ctx, d.conn.Conn()) + if cErr != nil { + return entity.KindBoxReq{}, richerror.New(op).WithErr(cErr). + WithMessage(errmsg.ErrorMsgCantScanQueryResult).WithKind(richerror.KindUnexpected) + } + row := q.Conn().QueryRowContext(ctx, `select * from kind_box_reqs where id = ? and deleted_at is null`, id) + k, sErr := scanKindBoxReq(row) + if sErr != nil { + return entity.KindBoxReq{}, richerror.New(op).WithErr(sErr). WithMessage(errmsg.ErrorMsgCantScanQueryResult).WithKind(richerror.KindUnexpected) } diff --git a/repository/mysql/migration/1705992494_create_kind_boxes_table.sql b/repository/mysql/migration/1705992494_create_kind_boxes_table.sql index 3dae14c..643ce69 100644 --- a/repository/mysql/migration/1705992494_create_kind_boxes_table.sql +++ b/repository/mysql/migration/1705992494_create_kind_boxes_table.sql @@ -5,8 +5,9 @@ CREATE TABLE `kind_boxes` ( `benefactor_id` INT NOT NULL, `type` ENUM('on-table','cylindrical','stand-up') NOT NULL, `amount` INT UNSIGNED, - `serial_number` varchar(191), + `serial_number` VARCHAR(191) UNIQUE, `status` ENUM('delivered','ready-to-return','assigned-receiver-agent','returned','enumerated') NOT NULL, + `deliver_refer_time_id` INT NOT NULL, `deliver_refer_date` DATETIME NOT NULL, `deliver_address_id` INT NOT NULL, `sender_agent_id` INT NOT NULL, @@ -20,13 +21,14 @@ CREATE TABLE `kind_boxes` ( `created_at` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, `updated_at` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, `deleted_at` TIMESTAMP NULL, - FOREIGN KEY (`kind_box_req_id`) REFERENCES `kind_box_reqs` (`id`), - FOREIGN KEY (`benefactor_id`) REFERENCES `benefactors` (`id`), - FOREIGN KEY (`deliver_address_id`) REFERENCES `addresses` (`id`), - FOREIGN KEY (`sender_agent_id`) REFERENCES `admins` (`id`), - FOREIGN KEY (`return_refer_time_id`)REFERENCES `refer_times` (`id`), - FOREIGN KEY (`return_address_id`) REFERENCES `addresses` (`id`), - FOREIGN KEY (`receiver_agent_id`) REFERENCES `admins` (`id`), + FOREIGN KEY (`kind_box_req_id`) REFERENCES `kind_box_reqs` (`id`), + FOREIGN KEY (`benefactor_id`) REFERENCES `benefactors` (`id`), + FOREIGN KEY (`deliver_refer_time_id`) REFERENCES `refer_times` (`id`), + FOREIGN KEY (`deliver_address_id`) REFERENCES `addresses` (`id`), + FOREIGN KEY (`sender_agent_id`) REFERENCES `admins` (`id`), + FOREIGN KEY (`return_refer_time_id`) REFERENCES `refer_times` (`id`), + FOREIGN KEY (`return_address_id`) REFERENCES `addresses` (`id`), + FOREIGN KEY (`receiver_agent_id`) REFERENCES `admins` (`id`), INDEX `index_serial_number` (`serial_number`) ); diff --git a/repository/mysql/migration/1708712565_insert_admin_access_controls_table.sql b/repository/mysql/migration/1708712565_insert_admin_access_controls_table.sql index 30aaa21..7e97529 100644 --- a/repository/mysql/migration/1708712565_insert_admin_access_controls_table.sql +++ b/repository/mysql/migration/1708712565_insert_admin_access_controls_table.sql @@ -1,34 +1,38 @@ -- +migrate Up INSERT INTO `admin_access_controls` (`id`, `actor_id`, `actor_type`,`permission`) VALUES - (1, 1 , 'role','admin-register'), - (2, 1 , 'role','kindboxreq-accept'), - (3, 1 , 'role','kindboxreq-reject'), - (4, 1 , 'role','kindboxreq-getall'), - (5, 1 , 'role','kindboxreq-deliver'), - (6, 1 , 'role','kindboxreq-assign_sender_agent'), - (8, 2 , 'role','kindboxreq-accept'), - (9, 2 , 'role','kindboxreq-reject'), - (10, 2 , 'role','kindboxreq-getall'), - (11, 2 , 'role','kindboxreq-deliver'), - (12, 2 , 'role','kindboxreq-assign_sender_agent'), - (13, 1 , 'role','admin-getall_agent'), - (14, 2 , 'role','admin-getall_agent'), - (15, 1 , 'role','kindboxreq-get_awaiting_delivery'), - (16, 3 , 'role','kindboxreq-get_awaiting_delivery'), - (17, 1 , 'role','kindbox-get'), - (18, 2 , 'role','kindbox-get'), - (19, 1 , 'role','kindbox-assign_receiver_agent'), - (20, 2 , 'role','kindbox-assign_receiver_agent'), - (21, 1 , 'role','kindboxreq-add'), - (22, 2 , 'role','kindboxreq-add'), - (23, 1 , 'role','kindbox-getall'), - (24, 2 , 'role','kindbox-getall'), - (25, 1 , 'role','kindboxreq-update'), - (26, 2 , 'role','kindboxreq-update'); + (DEFAULT, 1 , 'role','admin-register'), + (DEFAULT, 1 , 'role','admin-getall_agent'), + (DEFAULT, 2 , 'role','admin-getall_agent'), + + (DEFAULT, 1 , 'role','kindboxreq-add'), + (DEFAULT, 2 , 'role','kindboxreq-add'), + (DEFAULT, 1 , 'role','kindboxreq-accept'), + (DEFAULT, 2 , 'role','kindboxreq-accept'), + (DEFAULT, 1 , 'role','kindboxreq-reject'), + (DEFAULT, 2 , 'role','kindboxreq-reject'), + (DEFAULT, 1 , 'role','kindboxreq-assign_sender_agent'), + (DEFAULT, 2 , 'role','kindboxreq-assign_sender_agent'), + (DEFAULT, 1 , 'role','kindboxreq-deliver'), + (DEFAULT, 2 , 'role','kindboxreq-deliver'), + (DEFAULT, 3 , 'role','kindboxreq-deliver'), + (DEFAULT, 1 , 'role','kindboxreq-getall'), + (DEFAULT, 2 , 'role','kindboxreq-getall'), + (DEFAULT, 1 , 'role','kindboxreq-update'), + (DEFAULT, 2 , 'role','kindboxreq-update'), + (DEFAULT, 1 , 'role','kindboxreq-get_awaiting_delivery'), + (DEFAULT, 2 , 'role','kindboxreq-get_awaiting_delivery'), + (DEFAULT, 3 , 'role','kindboxreq-get_awaiting_delivery'), + + (DEFAULT, 1 , 'role','kindbox-assign_receiver_agent'), + (DEFAULT, 2 , 'role','kindbox-assign_receiver_agent'), + (DEFAULT, 1 , 'role','kindbox-get'), + (DEFAULT, 2 , 'role','kindbox-get'), + (DEFAULT, 1 , 'role','kindbox-getall'), + (DEFAULT, 2 , 'role','kindbox-getall'); + + -- +migrate Down -DELETE - FROM `admin_access_controls` - WHERE id BETWEEN 1 AND 7; \ No newline at end of file +DELETE FROM `admin_access_controls`; \ No newline at end of file diff --git a/service/admin/kind_box/add.go b/service/admin/kind_box/add.go index 7416d11..ba0aae6 100644 --- a/service/admin/kind_box/add.go +++ b/service/admin/kind_box/add.go @@ -2,7 +2,6 @@ package adminkindboxservice import ( "context" - entity "git.gocasts.ir/ebhomengo/niki/entity" param "git.gocasts.ir/ebhomengo/niki/param/admin/kind_box" richerror "git.gocasts.ir/ebhomengo/niki/pkg/rich_error" @@ -11,17 +10,21 @@ import ( func (s Service) AddBatchKindBox(ctx context.Context, req param.AddKindBoxRequest) (param.AddKindBoxResponse, error) { const op = "adminkindboxservice.AddKindBox" kindBoxes := make([]entity.KindBox, 0) - kb := entity.KindBox{ - KindBoxReqID: req.KindBoxReqID, - BenefactorID: req.BenefactorID, - KindBoxType: req.Type, - DeliverReferDate: req.DeliverReferDate, - DeliverAddressID: req.DeliverAddressID, - DeliveredAt: req.DeliveredAt, - SenderAgentID: req.SenderAgentID, - Status: entity.KindBoxDeliveredStatus, - } - for i := uint(0); i < req.CountAccepted; i++ { + for i := 0; i < int(req.CountAccepted); i++ { + kb := entity.KindBox{ + KindBoxReqID: req.KindBoxReqID, + BenefactorID: req.BenefactorID, + KindBoxType: req.Type, + DeliverReferTimeID: req.DeliverReferTimeID, + DeliverReferDate: req.DeliverReferDate, + DeliverAddressID: req.DeliverAddressID, + DeliveredAt: req.DeliveredAt, + SenderAgentID: req.SenderAgentID, + Status: entity.KindBoxDeliveredStatus, + } + if i < len(req.SerialNumbers) { + kb.SerialNumber = req.SerialNumbers[i] + } kindBoxes = append(kindBoxes, kb) } aErr := s.repo.AddBatchKindBox(ctx, kindBoxes) diff --git a/service/admin/kind_box_req/deliver.go b/service/admin/kind_box_req/deliver.go index 7102df3..8779ff3 100644 --- a/service/admin/kind_box_req/deliver.go +++ b/service/admin/kind_box_req/deliver.go @@ -17,14 +17,16 @@ func (s Service) Deliver(ctx context.Context, req param.DeliverKindBoxReqRequest return param.DeliverKindBoxReqResponse{}, richerror.New(op).WithErr(gErr).WithKind(richerror.KindUnexpected) } _, aErr := s.kindBoxSvc.AddBatchKindBox(ctx, kindboxParam.AddKindBoxRequest{ - KindBoxReqID: kindBoxReq.ID, - BenefactorID: kindBoxReq.BenefactorID, - Type: kindBoxReq.KindBoxType, - DeliverReferDate: kindBoxReq.DeliverReferDate, - DeliverAddressID: kindBoxReq.DeliverAddressID, - SenderAgentID: kindBoxReq.SenderAgentID, - DeliveredAt: time.Now(), - CountAccepted: kindBoxReq.CountAccepted, + KindBoxReqID: kindBoxReq.ID, + BenefactorID: kindBoxReq.BenefactorID, + Type: kindBoxReq.KindBoxType, + DeliverReferTimeID: kindBoxReq.DeliverReferTimeID, + DeliverReferDate: kindBoxReq.DeliverReferDate, + DeliverAddressID: kindBoxReq.DeliverAddressID, + SenderAgentID: kindBoxReq.SenderAgentID, + DeliveredAt: time.Now(), + CountAccepted: kindBoxReq.CountAccepted, + SerialNumbers: req.SerialNumbers, }) if aErr != nil { return param.DeliverKindBoxReqResponse{}, richerror.New(op).WithErr(aErr).WithKind(richerror.KindUnexpected) @@ -33,6 +35,5 @@ func (s Service) Deliver(ctx context.Context, req param.DeliverKindBoxReqRequest if dErr != nil { return param.DeliverKindBoxReqResponse{}, richerror.New(op).WithErr(dErr).WithKind(richerror.KindUnexpected) } - return param.DeliverKindBoxReqResponse{}, nil } diff --git a/validator/admin/kind_box_req/deliver.go b/validator/admin/kind_box_req/deliver.go index 0a20a10..5137e77 100644 --- a/validator/admin/kind_box_req/deliver.go +++ b/validator/admin/kind_box_req/deliver.go @@ -13,7 +13,8 @@ func (v Validator) ValidateDeliver(req param.DeliverKindBoxReqRequest) (map[stri const op = "adminkindboxreqvalidator.ValidateAssignSender" if err := validation.ValidateStruct(&req, - validation.Field(&req.KindBoxReqID, validation.Required, validation.By(v.doesKindBoxRequestExist), validation.By(v.checkKindBoxReqStatusForDelivering))); err != nil { + validation.Field(&req.KindBoxReqID, validation.Required, validation.By(v.doesKindBoxRequestExist), validation.By(v.checkKindBoxReqStatusForDelivering)), + validation.Field(&req.SerialNumbers, validation.By(v.IsSerialNumbersCountValid(req.KindBoxReqID)))); err != nil { fieldErrors := make(map[string]string) diff --git a/validator/admin/kind_box_req/validator.go b/validator/admin/kind_box_req/validator.go index 28d532e..a331d36 100644 --- a/validator/admin/kind_box_req/validator.go +++ b/validator/admin/kind_box_req/validator.go @@ -260,3 +260,20 @@ func (v Validator) doesBenefactorAddressExist(kindBoxReqID uint) validation.Rule return nil } } + +func (v Validator) IsSerialNumbersCountValid(kindBoxReqID uint) validation.RuleFunc { + return func(value interface{}) error { + serialNumbers, ok := value.([]string) + if !ok { + return fmt.Errorf(errmsg.ErrorMsgSomethingWentWrong) + } + kindBoxReq, gErr := v.repo.GetByID(context.Background(), kindBoxReqID) + if gErr != nil { + return fmt.Errorf(errmsg.ErrorMsgSomethingWentWrong) + } + if len(serialNumbers) != 0 && len(serialNumbers) > int(kindBoxReq.CountAccepted) { + return fmt.Errorf(errmsg.ErrorMsgInvalidSerialNumberRange) + } + return nil + } +}