forked from ebhomengo/niki
1
0
Fork 0

feat(niki): agent deliver kindboxreq (transactional)

This commit is contained in:
Iman Mirazimi 2024-07-13 00:55:20 +03:30 committed by hossein
parent 0eb8f89848
commit b6eca45519
19 changed files with 358 additions and 118 deletions

View File

@ -1,13 +1,13 @@
package adminkindboxreqhandler package adminkindboxreqhandler
import ( import (
"net/http" "context"
"strconv"
param "git.gocasts.ir/ebhomengo/niki/param/admin/kind_box_req" param "git.gocasts.ir/ebhomengo/niki/param/admin/kind_box_req"
errmsg "git.gocasts.ir/ebhomengo/niki/pkg/err_msg" errmsg "git.gocasts.ir/ebhomengo/niki/pkg/err_msg"
httpmsg "git.gocasts.ir/ebhomengo/niki/pkg/http_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" echo "github.com/labstack/echo/v4"
"net/http"
) )
// Deliver godoc // Deliver godoc
@ -16,6 +16,7 @@ import (
// @Accept json // @Accept json
// @Produce json // @Produce json
// @Param id path int true "KindBoxReq ID" // @Param id path int true "KindBoxReq ID"
// @Param Request body param.DeliverKindBoxReqRequest true "KindBoxReq deliver request details"
// @Success 200 {object} param.DeliverKindBoxReqResponse // @Success 200 {object} param.DeliverKindBoxReqResponse
// @Failure 400 {string} "Bad request" // @Failure 400 {string} "Bad request"
// @Security AuthBearerAdmin // @Security AuthBearerAdmin
@ -23,14 +24,10 @@ import (
func (h Handler) Deliver(c echo.Context) error { func (h Handler) Deliver(c echo.Context) error {
var req param.DeliverKindBoxReqRequest var req param.DeliverKindBoxReqRequest
id, cErr := strconv.ParseUint(c.Param("id"), 10, 64) if bErr := c.Bind(&req); bErr != nil {
return echo.NewHTTPError(http.StatusBadRequest)
if cErr != nil {
return c.JSON(http.StatusBadRequest, errmsg.ErrorMsgInvalidInput)
} }
req.KindBoxReqID = uint(id)
if fieldErrors, err := h.adminKindBoxReqVld.ValidateDeliver(req); err != nil { if fieldErrors, err := h.adminKindBoxReqVld.ValidateDeliver(req); err != nil {
msg, code := httpmsg.Error(err) 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 { if sErr != nil {
rErr := q.Rollback()
if rErr != nil {
return echo.NewHTTPError(http.StatusInternalServerError, errmsg.ErrorMsgSomethingWentWrong)
}
msg, code := httpmsg.Error(sErr) msg, code := httpmsg.Error(sErr)
return echo.NewHTTPError(code, msg) return echo.NewHTTPError(code, msg)
} }
cErr := q.Commit()
if cErr != nil {
return echo.NewHTTPError(http.StatusInternalServerError, errmsg.ErrorMsgSomethingWentWrong)
}
return c.JSON(http.StatusOK, resp) return c.JSON(http.StatusOK, resp)
} }

View File

@ -938,6 +938,15 @@ const docTemplate = `{
"name": "id", "name": "id",
"in": "path", "in": "path",
"required": true "required": true
},
{
"description": "KindBoxReq deliver request details",
"name": "Request",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/adminkindboxreqparam.DeliverKindBoxReqRequest"
}
} }
], ],
"responses": { "responses": {
@ -1791,6 +1800,9 @@ const docTemplate = `{
"deliverReferDate": { "deliverReferDate": {
"type": "string" "type": "string"
}, },
"deliverReferTimeID": {
"type": "integer"
},
"deliveredAt": { "deliveredAt": {
"type": "string" "type": "string"
}, },
@ -1840,6 +1852,22 @@ const docTemplate = `{
"adminkindboxreqparam.AssignSenderResponse": { "adminkindboxreqparam.AssignSenderResponse": {
"type": "object" "type": "object"
}, },
"adminkindboxreqparam.DeliverKindBoxReqRequest": {
"type": "object",
"properties": {
"serial_numbers": {
"type": "array",
"items": {
"type": "string"
},
"example": [
"1",
"2",
"3"
]
}
}
},
"adminkindboxreqparam.DeliverKindBoxReqResponse": { "adminkindboxreqparam.DeliverKindBoxReqResponse": {
"type": "object" "type": "object"
}, },
@ -2349,6 +2377,9 @@ const docTemplate = `{
"deliverReferDate": { "deliverReferDate": {
"type": "string" "type": "string"
}, },
"deliverReferTimeID": {
"type": "integer"
},
"deliveredAt": { "deliveredAt": {
"type": "string" "type": "string"
}, },
@ -2601,6 +2632,9 @@ const docTemplate = `{
"deliverReferDate": { "deliverReferDate": {
"type": "string" "type": "string"
}, },
"deliverReferTimeID": {
"type": "integer"
},
"deliveredAt": { "deliveredAt": {
"type": "string" "type": "string"
}, },

View File

@ -927,6 +927,15 @@
"name": "id", "name": "id",
"in": "path", "in": "path",
"required": true "required": true
},
{
"description": "KindBoxReq deliver request details",
"name": "Request",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/adminkindboxreqparam.DeliverKindBoxReqRequest"
}
} }
], ],
"responses": { "responses": {
@ -1780,6 +1789,9 @@
"deliverReferDate": { "deliverReferDate": {
"type": "string" "type": "string"
}, },
"deliverReferTimeID": {
"type": "integer"
},
"deliveredAt": { "deliveredAt": {
"type": "string" "type": "string"
}, },
@ -1829,6 +1841,22 @@
"adminkindboxreqparam.AssignSenderResponse": { "adminkindboxreqparam.AssignSenderResponse": {
"type": "object" "type": "object"
}, },
"adminkindboxreqparam.DeliverKindBoxReqRequest": {
"type": "object",
"properties": {
"serial_numbers": {
"type": "array",
"items": {
"type": "string"
},
"example": [
"1",
"2",
"3"
]
}
}
},
"adminkindboxreqparam.DeliverKindBoxReqResponse": { "adminkindboxreqparam.DeliverKindBoxReqResponse": {
"type": "object" "type": "object"
}, },
@ -2338,6 +2366,9 @@
"deliverReferDate": { "deliverReferDate": {
"type": "string" "type": "string"
}, },
"deliverReferTimeID": {
"type": "integer"
},
"deliveredAt": { "deliveredAt": {
"type": "string" "type": "string"
}, },
@ -2590,6 +2621,9 @@
"deliverReferDate": { "deliverReferDate": {
"type": "string" "type": "string"
}, },
"deliverReferTimeID": {
"type": "integer"
},
"deliveredAt": { "deliveredAt": {
"type": "string" "type": "string"
}, },

View File

@ -96,6 +96,8 @@ definitions:
type: integer type: integer
deliverReferDate: deliverReferDate:
type: string type: string
deliverReferTimeID:
type: integer
deliveredAt: deliveredAt:
type: string type: string
id: id:
@ -128,6 +130,17 @@ definitions:
type: object type: object
adminkindboxreqparam.AssignSenderResponse: adminkindboxreqparam.AssignSenderResponse:
type: object type: object
adminkindboxreqparam.DeliverKindBoxReqRequest:
properties:
serial_numbers:
example:
- "1"
- "2"
- "3"
items:
type: string
type: array
type: object
adminkindboxreqparam.DeliverKindBoxReqResponse: adminkindboxreqparam.DeliverKindBoxReqResponse:
type: object type: object
adminkindboxreqparam.DeliveryAwaitingGetAllResponse: adminkindboxreqparam.DeliveryAwaitingGetAllResponse:
@ -461,6 +474,8 @@ definitions:
type: integer type: integer
deliverReferDate: deliverReferDate:
type: string type: string
deliverReferTimeID:
type: integer
deliveredAt: deliveredAt:
type: string type: string
id: id:
@ -630,6 +645,8 @@ definitions:
type: integer type: integer
deliverReferDate: deliverReferDate:
type: string type: string
deliverReferTimeID:
type: integer
deliveredAt: deliveredAt:
type: string type: string
id: id:
@ -1369,6 +1386,12 @@ paths:
name: id name: id
required: true required: true
type: integer type: integer
- description: KindBoxReq deliver request details
in: body
name: Request
required: true
schema:
$ref: '#/definitions/adminkindboxreqparam.DeliverKindBoxReqRequest'
produces: produces:
- application/json - application/json
responses: responses:

View File

@ -10,6 +10,7 @@ type KindBox struct {
Amount uint Amount uint
SerialNumber string SerialNumber string
Status KindBoxStatus Status KindBoxStatus
DeliverReferTimeID uint
DeliverReferDate time.Time DeliverReferDate time.Time
DeliverAddressID uint DeliverAddressID uint
SenderAgentID uint SenderAgentID uint

View File

@ -10,11 +10,13 @@ type AddKindBoxRequest struct {
KindBoxReqID uint KindBoxReqID uint
BenefactorID uint BenefactorID uint
Type entity.KindBoxType Type entity.KindBoxType
DeliverReferTimeID uint
DeliverReferDate time.Time DeliverReferDate time.Time
DeliverAddressID uint DeliverAddressID uint
SenderAgentID uint SenderAgentID uint
DeliveredAt time.Time DeliveredAt time.Time
CountAccepted uint CountAccepted uint
SerialNumbers []string
} }
type AddKindBoxResponse struct{} type AddKindBoxResponse struct{}

View File

@ -1,7 +1,8 @@
package adminkindboxreqparam package adminkindboxreqparam
type DeliverKindBoxReqRequest struct { type DeliverKindBoxReqRequest struct {
KindBoxReqID uint `json:"-"` KindBoxReqID uint `json:"-" param:"id"`
SerialNumbers []string `json:"serial_numbers" example:"1,2,3"`
} }
type DeliverKindBoxReqResponse struct{} type DeliverKindBoxReqResponse struct{}

View File

@ -34,4 +34,5 @@ const (
ErrorMsgSortDirectionShouldBeAscOrDesc = "sort direction should be asc or desc" ErrorMsgSortDirectionShouldBeAscOrDesc = "sort direction should be asc or desc"
ErrorMsgSortFieldIsNotValid = "sort field is not valid" ErrorMsgSortFieldIsNotValid = "sort field is not valid"
ErrorMsgAssignReceiverAgentKindBoxStatus = "only ready to return kindboxes can be assigned to a receiver agent" ErrorMsgAssignReceiverAgentKindBoxStatus = "only ready to return kindboxes can be assigned to a receiver agent"
ErrorMsgInvalidSerialNumberRange = "invalid serial number range"
) )

View File

@ -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
}

View File

@ -3,6 +3,7 @@ package mysql
import ( import (
"database/sql" "database/sql"
"fmt" "fmt"
querier "git.gocasts.ir/ebhomengo/niki/pkg/query_transaction/sql"
"time" "time"
) )
@ -16,11 +17,11 @@ type Config struct {
type DB struct { type DB struct {
config Config config Config
db *sql.DB db *querier.SqlDB
} }
func (m *DB) Conn() *sql.DB { func (db *DB) Conn() *querier.SqlDB {
return m.db return db.db
} }
// TODO: this temperary to ignore linter error (magic number). // TODO: this temperary to ignore linter error (magic number).
@ -45,5 +46,5 @@ func New(config Config) *DB {
db.SetMaxOpenConns(dbMaxOpenConns) db.SetMaxOpenConns(dbMaxOpenConns)
db.SetMaxIdleConns(dbMaxIdleConns) db.SetMaxIdleConns(dbMaxIdleConns)
return &DB{config: config, db: db} return &DB{config: config, db: &querier.SqlDB{db}}
} }

View File

@ -2,9 +2,10 @@ package mysqlkindbox
import ( import (
"context" "context"
"database/sql"
"git.gocasts.ir/ebhomengo/niki/entity" "git.gocasts.ir/ebhomengo/niki/entity"
errmsg "git.gocasts.ir/ebhomengo/niki/pkg/err_msg" 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" 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 { func (d DB) AddBatchKindBox(ctx context.Context, kindBoxes []entity.KindBox) error {
const op = "mysqlkindbox.AddBatchKindBoxConcurrentlyRollback" 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{} values := []any{}
for _, kb := range kindBoxes { for _, kb := range kindBoxes {
queryStr += "(?, ?, ?, ?, ?, ?, ?, ?)," queryStr += "(?, ?, ?, ?, ?, ?, ?, ?, ?, ?),"
values = append(values, kb.KindBoxReqID, kb.BenefactorID, kb.KindBoxType, kb.Status.String(), kb.DeliverReferDate, kb.DeliverAddressID, kb.SenderAgentID, kb.DeliveredAt) 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] queryStr = queryStr[0 : len(queryStr)-1]
if _, err := d.conn.Conn().ExecContext(ctx, queryStr, values...); err != nil { q, cErr := querytransaction.GetQuerierFromContextOrNew(ctx).Continue(ctx, d.conn.Conn())
return richerror.New(op).WithErr(err). 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) WithMessage(errmsg.ErrorMsgSomethingWentWrong).WithKind(richerror.KindUnexpected)
} }
return nil return nil
} }

View File

@ -2,6 +2,7 @@ package mysqlkindboxreq
import ( import (
"context" "context"
querier "git.gocasts.ir/ebhomengo/niki/pkg/query_transaction/sql"
"time" "time"
entity "git.gocasts.ir/ebhomengo/niki/entity" entity "git.gocasts.ir/ebhomengo/niki/entity"
@ -11,13 +12,16 @@ import (
func (d DB) DeliverKindBoxReq(ctx context.Context, kindBoxReqID uint) error { func (d DB) DeliverKindBoxReq(ctx context.Context, kindBoxReqID uint) error {
const op = "mysqlkindboxreq.DeliverKindBoxReq" const op = "mysqlkindboxreq.DeliverKindBoxReq"
q, cErr := querier.GetQuerierFromContextOrNew(ctx).Continue(ctx, d.conn.Conn())
_, err := d.conn.Conn().ExecContext(ctx, `update kind_box_reqs set status = ?, delivered_at = ? where id = ?`, 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) entity.KindBoxReqDeliveredStatus.String(), time.Now(), kindBoxReqID)
if err != nil { if uErr != nil {
return richerror.New(op).WithErr(err). return richerror.New(op).WithErr(uErr).
WithMessage(errmsg.ErrorMsgSomethingWentWrong).WithKind(richerror.KindUnexpected) WithMessage(errmsg.ErrorMsgSomethingWentWrong).WithKind(richerror.KindUnexpected)
} }
return nil return nil
} }

View File

@ -3,18 +3,23 @@ package mysqlkindboxreq
import ( import (
"context" "context"
"database/sql" "database/sql"
"git.gocasts.ir/ebhomengo/niki/entity" "git.gocasts.ir/ebhomengo/niki/entity"
errmsg "git.gocasts.ir/ebhomengo/niki/pkg/err_msg" 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" richerror "git.gocasts.ir/ebhomengo/niki/pkg/rich_error"
) )
func (d DB) GetByID(ctx context.Context, id uint) (entity.KindBoxReq, error) { func (d DB) GetByID(ctx context.Context, id uint) (entity.KindBoxReq, error) {
op := richerror.Op("mysqlkindboxreq.GetByID") op := richerror.Op("mysqlkindboxreq.GetByID")
row := d.conn.Conn().QueryRowContext(ctx, `select * from kind_box_reqs where id = ? and deleted_at is null`, id) q, cErr := querier.GetQuerierFromContextOrNew(ctx).Continue(ctx, d.conn.Conn())
k, err := scanKindBoxReq(row) if cErr != nil {
if err != nil { return entity.KindBoxReq{}, richerror.New(op).WithErr(cErr).
return entity.KindBoxReq{}, richerror.New(op).WithErr(err). 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) WithMessage(errmsg.ErrorMsgCantScanQueryResult).WithKind(richerror.KindUnexpected)
} }

View File

@ -5,8 +5,9 @@ CREATE TABLE `kind_boxes` (
`benefactor_id` INT NOT NULL, `benefactor_id` INT NOT NULL,
`type` ENUM('on-table','cylindrical','stand-up') NOT NULL, `type` ENUM('on-table','cylindrical','stand-up') NOT NULL,
`amount` INT UNSIGNED, `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, `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_refer_date` DATETIME NOT NULL,
`deliver_address_id` INT NOT NULL, `deliver_address_id` INT NOT NULL,
`sender_agent_id` INT NOT NULL, `sender_agent_id` INT NOT NULL,
@ -22,6 +23,7 @@ CREATE TABLE `kind_boxes` (
`deleted_at` TIMESTAMP NULL, `deleted_at` TIMESTAMP NULL,
FOREIGN KEY (`kind_box_req_id`) REFERENCES `kind_box_reqs` (`id`), FOREIGN KEY (`kind_box_req_id`) REFERENCES `kind_box_reqs` (`id`),
FOREIGN KEY (`benefactor_id`) REFERENCES `benefactors` (`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 (`deliver_address_id`) REFERENCES `addresses` (`id`),
FOREIGN KEY (`sender_agent_id`) REFERENCES `admins` (`id`), FOREIGN KEY (`sender_agent_id`) REFERENCES `admins` (`id`),
FOREIGN KEY (`return_refer_time_id`) REFERENCES `refer_times` (`id`), FOREIGN KEY (`return_refer_time_id`) REFERENCES `refer_times` (`id`),

View File

@ -1,34 +1,38 @@
-- +migrate Up -- +migrate Up
INSERT INTO `admin_access_controls` (`id`, `actor_id`, `actor_type`,`permission`) INSERT INTO `admin_access_controls` (`id`, `actor_id`, `actor_type`,`permission`)
VALUES VALUES
(1, 1 , 'role','admin-register'), (DEFAULT, 1 , 'role','admin-register'),
(2, 1 , 'role','kindboxreq-accept'), (DEFAULT, 1 , 'role','admin-getall_agent'),
(3, 1 , 'role','kindboxreq-reject'), (DEFAULT, 2 , 'role','admin-getall_agent'),
(4, 1 , 'role','kindboxreq-getall'),
(5, 1 , 'role','kindboxreq-deliver'), (DEFAULT, 1 , 'role','kindboxreq-add'),
(6, 1 , 'role','kindboxreq-assign_sender_agent'), (DEFAULT, 2 , 'role','kindboxreq-add'),
(8, 2 , 'role','kindboxreq-accept'), (DEFAULT, 1 , 'role','kindboxreq-accept'),
(9, 2 , 'role','kindboxreq-reject'), (DEFAULT, 2 , 'role','kindboxreq-accept'),
(10, 2 , 'role','kindboxreq-getall'), (DEFAULT, 1 , 'role','kindboxreq-reject'),
(11, 2 , 'role','kindboxreq-deliver'), (DEFAULT, 2 , 'role','kindboxreq-reject'),
(12, 2 , 'role','kindboxreq-assign_sender_agent'), (DEFAULT, 1 , 'role','kindboxreq-assign_sender_agent'),
(13, 1 , 'role','admin-getall_agent'), (DEFAULT, 2 , 'role','kindboxreq-assign_sender_agent'),
(14, 2 , 'role','admin-getall_agent'), (DEFAULT, 1 , 'role','kindboxreq-deliver'),
(15, 1 , 'role','kindboxreq-get_awaiting_delivery'), (DEFAULT, 2 , 'role','kindboxreq-deliver'),
(16, 3 , 'role','kindboxreq-get_awaiting_delivery'), (DEFAULT, 3 , 'role','kindboxreq-deliver'),
(17, 1 , 'role','kindbox-get'), (DEFAULT, 1 , 'role','kindboxreq-getall'),
(18, 2 , 'role','kindbox-get'), (DEFAULT, 2 , 'role','kindboxreq-getall'),
(19, 1 , 'role','kindbox-assign_receiver_agent'), (DEFAULT, 1 , 'role','kindboxreq-update'),
(20, 2 , 'role','kindbox-assign_receiver_agent'), (DEFAULT, 2 , 'role','kindboxreq-update'),
(21, 1 , 'role','kindboxreq-add'), (DEFAULT, 1 , 'role','kindboxreq-get_awaiting_delivery'),
(22, 2 , 'role','kindboxreq-add'), (DEFAULT, 2 , 'role','kindboxreq-get_awaiting_delivery'),
(23, 1 , 'role','kindbox-getall'), (DEFAULT, 3 , 'role','kindboxreq-get_awaiting_delivery'),
(24, 2 , 'role','kindbox-getall'),
(25, 1 , 'role','kindboxreq-update'), (DEFAULT, 1 , 'role','kindbox-assign_receiver_agent'),
(26, 2 , 'role','kindboxreq-update'); (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 -- +migrate Down
DELETE DELETE FROM `admin_access_controls`;
FROM `admin_access_controls`
WHERE id BETWEEN 1 AND 7;

View File

@ -2,7 +2,6 @@ package adminkindboxservice
import ( import (
"context" "context"
entity "git.gocasts.ir/ebhomengo/niki/entity" entity "git.gocasts.ir/ebhomengo/niki/entity"
param "git.gocasts.ir/ebhomengo/niki/param/admin/kind_box" param "git.gocasts.ir/ebhomengo/niki/param/admin/kind_box"
richerror "git.gocasts.ir/ebhomengo/niki/pkg/rich_error" 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) { func (s Service) AddBatchKindBox(ctx context.Context, req param.AddKindBoxRequest) (param.AddKindBoxResponse, error) {
const op = "adminkindboxservice.AddKindBox" const op = "adminkindboxservice.AddKindBox"
kindBoxes := make([]entity.KindBox, 0) kindBoxes := make([]entity.KindBox, 0)
for i := 0; i < int(req.CountAccepted); i++ {
kb := entity.KindBox{ kb := entity.KindBox{
KindBoxReqID: req.KindBoxReqID, KindBoxReqID: req.KindBoxReqID,
BenefactorID: req.BenefactorID, BenefactorID: req.BenefactorID,
KindBoxType: req.Type, KindBoxType: req.Type,
DeliverReferTimeID: req.DeliverReferTimeID,
DeliverReferDate: req.DeliverReferDate, DeliverReferDate: req.DeliverReferDate,
DeliverAddressID: req.DeliverAddressID, DeliverAddressID: req.DeliverAddressID,
DeliveredAt: req.DeliveredAt, DeliveredAt: req.DeliveredAt,
SenderAgentID: req.SenderAgentID, SenderAgentID: req.SenderAgentID,
Status: entity.KindBoxDeliveredStatus, Status: entity.KindBoxDeliveredStatus,
} }
for i := uint(0); i < req.CountAccepted; i++ { if i < len(req.SerialNumbers) {
kb.SerialNumber = req.SerialNumbers[i]
}
kindBoxes = append(kindBoxes, kb) kindBoxes = append(kindBoxes, kb)
} }
aErr := s.repo.AddBatchKindBox(ctx, kindBoxes) aErr := s.repo.AddBatchKindBox(ctx, kindBoxes)

View File

@ -20,11 +20,13 @@ func (s Service) Deliver(ctx context.Context, req param.DeliverKindBoxReqRequest
KindBoxReqID: kindBoxReq.ID, KindBoxReqID: kindBoxReq.ID,
BenefactorID: kindBoxReq.BenefactorID, BenefactorID: kindBoxReq.BenefactorID,
Type: kindBoxReq.KindBoxType, Type: kindBoxReq.KindBoxType,
DeliverReferTimeID: kindBoxReq.DeliverReferTimeID,
DeliverReferDate: kindBoxReq.DeliverReferDate, DeliverReferDate: kindBoxReq.DeliverReferDate,
DeliverAddressID: kindBoxReq.DeliverAddressID, DeliverAddressID: kindBoxReq.DeliverAddressID,
SenderAgentID: kindBoxReq.SenderAgentID, SenderAgentID: kindBoxReq.SenderAgentID,
DeliveredAt: time.Now(), DeliveredAt: time.Now(),
CountAccepted: kindBoxReq.CountAccepted, CountAccepted: kindBoxReq.CountAccepted,
SerialNumbers: req.SerialNumbers,
}) })
if aErr != nil { if aErr != nil {
return param.DeliverKindBoxReqResponse{}, richerror.New(op).WithErr(aErr).WithKind(richerror.KindUnexpected) 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 { if dErr != nil {
return param.DeliverKindBoxReqResponse{}, richerror.New(op).WithErr(dErr).WithKind(richerror.KindUnexpected) return param.DeliverKindBoxReqResponse{}, richerror.New(op).WithErr(dErr).WithKind(richerror.KindUnexpected)
} }
return param.DeliverKindBoxReqResponse{}, nil return param.DeliverKindBoxReqResponse{}, nil
} }

View File

@ -13,7 +13,8 @@ func (v Validator) ValidateDeliver(req param.DeliverKindBoxReqRequest) (map[stri
const op = "adminkindboxreqvalidator.ValidateAssignSender" const op = "adminkindboxreqvalidator.ValidateAssignSender"
if err := validation.ValidateStruct(&req, 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) fieldErrors := make(map[string]string)

View File

@ -260,3 +260,20 @@ func (v Validator) doesBenefactorAddressExist(kindBoxReqID uint) validation.Rule
return nil 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
}
}