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

View File

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

View File

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

View File

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

View File

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

View File

@ -10,11 +10,13 @@ type AddKindBoxRequest struct {
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{}

View File

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

View File

@ -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"
)

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 (
"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}}
}

View File

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

View File

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

View File

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

View File

@ -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,
@ -22,9 +23,10 @@ CREATE TABLE `kind_boxes` (
`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_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_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`)

View File

@ -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;
DELETE FROM `admin_access_controls`;

View File

@ -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)
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,
}
for i := uint(0); i < req.CountAccepted; i++ {
if i < len(req.SerialNumbers) {
kb.SerialNumber = req.SerialNumbers[i]
}
kindBoxes = append(kindBoxes, kb)
}
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,
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
}

View File

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

View File

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