Files
old-svijetlastrana/data/datamysql/visit.go
2018-05-25 09:12:42 +02:00

209 lines
7.0 KiB
Go

package datamysql
import (
"database/sql"
"fmt"
"bitbucket.org/nemt/nemt-portal-api/domain/entity"
"bitbucket.org/nemt/nemt-portal-api/infra/errors"
"github.com/go-sql-driver/mysql"
uuid "github.com/satori/go.uuid"
)
// visitRepo maps methods to database
type visitRepo struct {
conn executor
}
func newVisitRepo(conn executor) *visitRepo {
return &visitRepo{
conn: conn,
}
}
func (c *visitRepo) getProfileQuery(user entity.User) (query string, where string, err error) {
if len(user.Profiles) > 0 {
for _, p := range user.Profiles {
switch p.Key {
case "AD", "BCBSIAD", "BDCAD", "PLANAD":
return
case "SP", "SPT", "VIRPT":
switch p.Organization.Type.Key {
case "techsupport", "bcbsi", "bcbsa", "plan":
return
case "provider":
query = ` INNER JOIN viw_visit_provider AS o ON o.visit_id = a.visit_id `
where = fmt.Sprintf(` AND ( o.organization_uuid = '%s' OR o.parent_organization_uuid = '%s' ) `, p.Organization.UUID, p.Organization.UUID)
return
}
}
}
if query == "" && where == "" {
return "", "", fmt.Errorf("Invalid Query")
} else {
return
}
} else {
return "", "", fmt.Errorf("User has no profile to search")
}
}
func (c *visitRepo) getQuery() string {
return `SELECT
a.visit_id,
a.visit_uuid,
a.visit_status_id,
b.visit_status_key,
b.visit_status,
a.user_id,
c.user_uuid,
c.name user_name,
c.member user_member,
c.birth_date user_birth_date,
c.gender user_gender,
a.visit_datetime,
a.pickup_datetime,
IFNULL(a.notes, '') notes,
a.created_user_id,
d.user_uuid created_user_uuid,
d.name created_user_name,
a.created_date,
a.updated_date,
IFNULL(a.visit_duration, 0) visit_duration,
a.visit_external_id,
e.trip_type_id,
e.trip_type_key,
e.trip_type,
IFNULL(a.pickup_id, '') visit_pickup_id,
IFNULL(a.pickup_address_id, 0) pickup_address_id,
IFNULL(a.address_id, 0) address_id,
IFNULL(a.provider_id, 0) provider_id,
IFNULL(f.provider_uuid, '') provider_uuid,
IFNULL(f.provider_internal_id, '') provider_internal_id,
IFNULL(f.provider_muk_id, '') provider_muk_id,
IFNULL(f.provider_name, '') provider_name
FROM
tab_visit AS a
INNER JOIN tab_visit_status AS b
ON a.visit_status_id = b.visit_status_id
INNER JOIN tab_user AS c
ON c.user_id = a.user_id
INNER JOIN tab_user AS d
ON d.user_id = a.created_user_id
INNER JOIN tab_trip_type AS e
ON e.trip_type_id = a.trip_type_id
INNER JOIN tab_provider AS f
ON f.provider_id = a.provider_id `
}
func (c *visitRepo) GetAll(user entity.User) ([]entity.Visit, error) {
query, where, err := c.getProfileQuery(user)
if err != nil {
return nil, err
}
query = c.getQuery() + query + " WHERE 1 = 1 and c.active = 1 " + where
return c.parseSet(c.conn.Query(query))
}
func (c *visitRepo) GetByUUID(visitUUID string, user entity.User) (entity.Visit, error) {
query, where, err := c.getProfileQuery(user)
if err != nil {
return entity.Visit{}, err
}
query = c.getQuery() + query + " WHERE a.visit_uuid = ? " + where
return c.parseEntity(c.conn.QueryRow(query, visitUUID))
}
func (c *visitRepo) GetByID(visitID int64, user entity.User) (entity.Visit, error) {
query, where, err := c.getProfileQuery(user)
if err != nil {
return entity.Visit{}, err
}
query = c.getQuery() + query + " WHERE a.visit_id = ? " + where
return c.parseEntity(c.conn.QueryRow(query, visitID))
}
// parseSet parses a result set result to an entity array
func (c *visitRepo) parseSet(rows *sql.Rows, err error) ([]entity.Visit, error) {
if err != nil {
return nil, errors.Wrap(err)
}
result := make([]entity.Visit, 0)
for rows.Next() {
entity, err := c.parseEntity(rows)
if err != nil {
return nil, errors.Wrap(err)
}
result = append(result, entity)
}
return result, nil
}
// parseEntity parses a result to an entity
func (c *visitRepo) parseEntity(row scanner) (retVal entity.Visit, err error) {
var birthDate mysql.NullTime
var gender sql.NullString
err = row.Scan(
&retVal.ID, &retVal.UUID, &retVal.Status.ID, &retVal.Status.Key, &retVal.Status.Value, &retVal.User.ID, &retVal.User.UUID, &retVal.User.Name, &retVal.User.Member, &birthDate, &gender, &retVal.VisitDatetime, &retVal.PickupDatetime, &retVal.Notes, &retVal.CreatedUser.ID, &retVal.CreatedUser.UUID, &retVal.CreatedUser.Name, &retVal.Created, &retVal.Updated, &retVal.VisitDuration, &retVal.ExternalID, &retVal.TripType.ID, &retVal.TripType.Key, &retVal.TripType.Value, &retVal.Pickup.ID, &retVal.PickupAddressID, &retVal.DestinationAddressID, &retVal.Provider.ProviderID, &retVal.Provider.ProviderUUID, &retVal.Provider.InternalID, &retVal.Provider.MukID, &retVal.Provider.Name)
if birthDate.Valid {
retVal.User.BirthDate = birthDate.Time
}
if gender.Valid {
retVal.User.Gender = gender.String
} else {
retVal.User.Gender = "U"
}
return retVal, errors.Wrap(err)
}
func (c *visitRepo) Create(visit entity.Visit) (entity.Visit, error) {
const (
statusQuery = `SELECT a.visit_status_id, a.visit_status_key, a.visit_status, b.user_id, b.name user_name, c.user_id create_user_id, c.name create_user_name, d.trip_type_id, d.trip_type_key, d.trip_type FROM tab_visit_status a, tab_user b, tab_user c, tab_trip_type d WHERE a.visit_status_key = ? AND b.user_uuid = ? AND c.user_uuid = ? AND d.trip_type_key = ?;`
query = `INSERT INTO tab_visit(visit_uuid, visit_status_id, user_id, visit_datetime, pickup_datetime, notes, created_user_id, visit_duration, visit_external_id, return_date, trip_type_id, pickup_id, pickup_address_id, address_id, provider_id)
VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);`
)
retVal := visit
returnDate := mysql.NullTime{
Valid: (retVal.ReturnDate != nil),
}
if retVal.ReturnDate != nil {
returnDate.Time = *retVal.ReturnDate
}
UUID, _ := uuid.NewV4()
retVal.UUID = UUID.String()
if retVal.Status.Key == "" {
retVal.Status.Key = "accepted"
}
row := c.conn.QueryRow(statusQuery, retVal.Status.Key, retVal.User.UUID, retVal.CreatedUser.UUID, retVal.TripType.Key)
if err := row.Scan(&retVal.Status.ID, &retVal.Status.Key, &retVal.Status.Value, &retVal.User.ID, &retVal.User.Name, &retVal.CreatedUser.ID, &retVal.CreatedUser.Name, &retVal.TripType.ID, &retVal.TripType.Key, &retVal.TripType.Value); err != nil {
fmt.Println("Error to get base data: ", err.Error())
return retVal, err
}
results, err := c.conn.Exec(query, retVal.UUID, retVal.Status.ID, retVal.User.ID, retVal.VisitDatetime, retVal.PickupDatetime, retVal.Notes, retVal.CreatedUser.ID, toNullInt64(retVal.VisitDuration), retVal.ExternalID, returnDate, retVal.TripType.ID, retVal.Pickup.ID, retVal.PickupAddressID, retVal.DestinationAddressID, retVal.Provider.ProviderID)
if err != nil {
return retVal, err
}
retVal.ID, err = results.LastInsertId()
if err != nil {
return retVal, err
}
return retVal, nil
}