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

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

View File

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

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,
@ -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`)
);

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

View File

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

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