initial commit 2
This commit is contained in:
133
data/datamysql/datamysql.go
Normal file
133
data/datamysql/datamysql.go
Normal file
@@ -0,0 +1,133 @@
|
||||
package datamysql
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"fmt"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"bitbucket.org/nemt/nemt-portal-api/domain/contract"
|
||||
"bitbucket.org/nemt/nemt-portal-api/infra/config"
|
||||
"bitbucket.org/nemt/nemt-portal-api/infra/errors"
|
||||
"github.com/go-sql-driver/mysql"
|
||||
)
|
||||
|
||||
var (
|
||||
instance *Conn
|
||||
once sync.Once
|
||||
connErr error
|
||||
)
|
||||
|
||||
// Conn is the MySQL connection manager
|
||||
type Conn struct {
|
||||
db *sql.DB
|
||||
users *userRepo
|
||||
rides *rideRepo
|
||||
visit *visitRepo
|
||||
provider *providerRepo
|
||||
notification *notificationRepo
|
||||
profile *profileRepo
|
||||
organization *organizationRepo
|
||||
}
|
||||
|
||||
// Begin starts a transaction
|
||||
func (c *Conn) Begin() (contract.TransactionManager, error) {
|
||||
tx, err := c.db.Begin()
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err)
|
||||
}
|
||||
|
||||
return newTransaction(tx), nil
|
||||
}
|
||||
|
||||
// Close closes the db connection
|
||||
func (c *Conn) Close() (err error) {
|
||||
return c.db.Close()
|
||||
}
|
||||
|
||||
// Users returns the users set
|
||||
func (c *Conn) Users() contract.UserRepo {
|
||||
return c.users
|
||||
}
|
||||
|
||||
// Rides returns the rides set
|
||||
func (c *Conn) Rides() contract.RideRepo {
|
||||
return c.rides
|
||||
}
|
||||
|
||||
// Visits returns the rides set
|
||||
func (c *Conn) Visits() contract.VisitRepo {
|
||||
return c.visit
|
||||
}
|
||||
|
||||
// Provider returns the rides set
|
||||
func (c *Conn) Provider() contract.ProviderRepo {
|
||||
return c.provider
|
||||
}
|
||||
|
||||
// Provider returns the rides set
|
||||
func (c *Conn) Profile() contract.ProfileRepo {
|
||||
return c.profile
|
||||
}
|
||||
|
||||
// Provider returns the rides set
|
||||
func (c *Conn) Notification() contract.NotificationRepo {
|
||||
return c.notification
|
||||
}
|
||||
|
||||
// Provider returns the rides set
|
||||
func (c *Conn) Organization() contract.OrganizationRepo {
|
||||
return c.organization
|
||||
}
|
||||
|
||||
// Instance returns an instance of a DataManager
|
||||
func Instance(cfg *config.Config) (contract.DataManager, error) {
|
||||
once.Do(func() {
|
||||
|
||||
db, err := sql.Open("mysql", getMySQLConfig(cfg).FormatDSN())
|
||||
if err != nil {
|
||||
connErr = errors.Wrap(err)
|
||||
return
|
||||
}
|
||||
|
||||
err = db.Ping()
|
||||
if err != nil {
|
||||
connErr = errors.Wrap(err)
|
||||
return
|
||||
}
|
||||
|
||||
connMaxLifetime := time.Duration(cfg.DB.MaxLifeInMinutes) * time.Minute
|
||||
db.SetConnMaxLifetime(connMaxLifetime)
|
||||
db.SetMaxIdleConns(cfg.DB.MaxIdleConns)
|
||||
db.SetMaxOpenConns(cfg.DB.MaxOpenConns)
|
||||
|
||||
instance = new(Conn)
|
||||
instance.db = db
|
||||
|
||||
instance.users = newUserRepo(db)
|
||||
instance.rides = newRideRepo(db)
|
||||
instance.visit = newVisitRepo(db)
|
||||
instance.provider = newProviderRepo(db)
|
||||
instance.notification = newNotificationRepo(db)
|
||||
instance.profile = newProfileRepo(db)
|
||||
instance.organization = newOrganizationRepo(db)
|
||||
})
|
||||
|
||||
return instance, connErr
|
||||
}
|
||||
|
||||
// getMySQLConfig returns the configuration for MySQL driver
|
||||
func getMySQLConfig(cfg *config.Config) *mysql.Config {
|
||||
loc, _ := time.LoadLocation("UTC")
|
||||
|
||||
return &mysql.Config{
|
||||
Net: "tcp",
|
||||
Addr: fmt.Sprintf("%s:%d", cfg.DB.Host, cfg.DB.Port),
|
||||
DBName: cfg.DB.Name,
|
||||
User: cfg.DB.User,
|
||||
Passwd: cfg.DB.Pass,
|
||||
ParseTime: true,
|
||||
Strict: true,
|
||||
Loc: loc,
|
||||
}
|
||||
}
|
||||
140
data/datamysql/notification.go
Normal file
140
data/datamysql/notification.go
Normal file
@@ -0,0 +1,140 @@
|
||||
package datamysql
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"fmt"
|
||||
|
||||
"bitbucket.org/nemt/nemt-portal-api/domain/entity"
|
||||
"bitbucket.org/nemt/nemt-portal-api/infra/errors"
|
||||
uuid "github.com/satori/go.uuid"
|
||||
)
|
||||
|
||||
// visitRepo maps methods to database
|
||||
type notificationRepo struct {
|
||||
conn executor
|
||||
}
|
||||
|
||||
func newNotificationRepo(conn executor) *notificationRepo {
|
||||
return ¬ificationRepo{
|
||||
conn: conn,
|
||||
}
|
||||
}
|
||||
|
||||
func (c *notificationRepo) Create(notification entity.Notification) (entity.Notification, error) {
|
||||
const (
|
||||
statusQuery = `SELECT a.contact_type_id, b.ride_id, c.user_id, d.user_id created_user_id FROM tab_contact_type a, tab_ride b, tab_user c, tab_user d WHERE a.key = ? AND b.ride_uuid = ? AND c.user_uuid = ? AND d.user_uuid = ?;`
|
||||
query = `INSERT INTO tab_notification(notification_uuid, ride_id, user_id, contact_type_id, contact, message, created_user_id, readed, notificaton_type) VALUES(?, ?, ?, ?, ?, ?, ?, 0, ?);`
|
||||
)
|
||||
|
||||
retVal := notification
|
||||
UUID, _ := uuid.NewV4()
|
||||
retVal.UUID = UUID.String()
|
||||
|
||||
row := c.conn.QueryRow(statusQuery, retVal.Type, retVal.Ride.UUID, retVal.User.UUID, retVal.CreatedUser.UUID)
|
||||
if err := row.Scan(&retVal.TypeID, &retVal.Ride.ID, &retVal.User.ID, &retVal.CreatedUser.ID); err != nil {
|
||||
fmt.Println("Error to get base data: ", err.Error())
|
||||
return retVal, err
|
||||
}
|
||||
|
||||
results, err := c.conn.Exec(query, retVal.UUID, retVal.Ride.ID, retVal.User.ID, retVal.TypeID, retVal.Subject, retVal.Message, retVal.CreatedUser.ID, retVal.MessageType)
|
||||
if err != nil {
|
||||
return retVal, err
|
||||
}
|
||||
|
||||
retVal.ID, err = results.LastInsertId()
|
||||
if err != nil {
|
||||
return retVal, err
|
||||
}
|
||||
|
||||
return c.GetByID(retVal.ID)
|
||||
}
|
||||
|
||||
func (c *notificationRepo) getQuery() string {
|
||||
return `SELECT
|
||||
a.notification_id,
|
||||
a.notification_uuid,
|
||||
a.ride_id,
|
||||
a.user_id,
|
||||
c.user_uuid,
|
||||
c.name user_name,
|
||||
CASE WHEN b.key = 'sms' THEN e.phone_number WHEN b.key = 'email' THEN e.email WHEN b.key = 'app' THEN c.user_uuid END to_address,
|
||||
CASE WHEN b.key = 'sms' THEN f.phone_number WHEN b.key = 'email' THEN f.email WHEN b.key = 'app' THEN d.user_uuid END from_address,
|
||||
a.contact_type_id,
|
||||
b.key contact_type_key,
|
||||
a.contact,
|
||||
a.message,
|
||||
a.create_at,
|
||||
a.readed,
|
||||
d.user_id created_user_id,
|
||||
d.user_uuid created_user_uuid,
|
||||
d.name created_user_name,
|
||||
a.notificaton_type
|
||||
FROM
|
||||
tab_notification a
|
||||
INNER JOIN tab_contact_type b
|
||||
ON a.contact_type_id = b.contact_type_id
|
||||
INNER JOIN tab_user c
|
||||
ON a.user_id = c.user_id
|
||||
INNER JOIN tab_user d
|
||||
ON a.created_user_id = d.user_id
|
||||
INNER JOIN tab_login e
|
||||
ON c.user_id = e.user_id
|
||||
INNER JOIN tab_login f
|
||||
ON d.user_id = f.user_id`
|
||||
}
|
||||
|
||||
func (c *notificationRepo) GetLastNotificationFromPhoneNumber(notificationType string, phoneNumber string, status string) (entity.Notification, error) {
|
||||
const (
|
||||
whereClause = ` WHERE
|
||||
a.notificaton_type = ?
|
||||
AND e.phone_number = ?
|
||||
AND b.key = ?
|
||||
ORDER BY a.notification_id DESC
|
||||
LIMIT 1;`
|
||||
)
|
||||
finalQuery := c.getQuery() + whereClause
|
||||
|
||||
return c.parseEntity(c.conn.QueryRow(finalQuery, notificationType, phoneNumber, status))
|
||||
}
|
||||
|
||||
func (c *notificationRepo) GetByUserUUIDAndReadStatus(userUUID string, status string, isRead bool) ([]entity.Notification, error) {
|
||||
return c.parseSet(c.conn.Query(c.getQuery()+" WHERE a.readed = ? AND b.key = ? AND c.user_uuid = ?; ", isRead, status, userUUID))
|
||||
}
|
||||
|
||||
func (c *notificationRepo) GetByUserUUID(userUUID string, status string) ([]entity.Notification, error) {
|
||||
return c.parseSet(c.conn.Query(c.getQuery()+" WHERE b.key = ? AND c.user_uuid = ?; ", status, userUUID))
|
||||
}
|
||||
|
||||
func (c *notificationRepo) ReadStatus(notificationUUID string, isRead bool) error {
|
||||
const query = "UPDATE tab_notification SET readed = ? WHERE notification_uuid = ?"
|
||||
_, err := c.conn.Exec(query, isRead, notificationUUID)
|
||||
return err
|
||||
}
|
||||
|
||||
func (c *notificationRepo) GetByID(ID int64) (entity.Notification, error) {
|
||||
return c.parseEntity(c.conn.QueryRow(c.getQuery()+" WHERE a.notification_id = ?; ", ID))
|
||||
}
|
||||
|
||||
// parseSet parses a result set result to an entity array
|
||||
func (c *notificationRepo) parseSet(rows *sql.Rows, err error) ([]entity.Notification, error) {
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err)
|
||||
}
|
||||
result := make([]entity.Notification, 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 *notificationRepo) parseEntity(row scanner) (retVal entity.Notification, err error) {
|
||||
err = row.Scan(
|
||||
&retVal.ID, &retVal.UUID, &retVal.Ride.ID, &retVal.User.ID, &retVal.User.UUID, &retVal.User.Name, &retVal.To, &retVal.From, &retVal.TypeID, &retVal.Type, &retVal.Subject, &retVal.Message, &retVal.Created, &retVal.Read, &retVal.CreatedUser.ID, &retVal.CreatedUser.UUID, &retVal.CreatedUser.Name, &retVal.MessageType)
|
||||
|
||||
return retVal, errors.Wrap(err)
|
||||
}
|
||||
482
data/datamysql/organization.go
Normal file
482
data/datamysql/organization.go
Normal file
@@ -0,0 +1,482 @@
|
||||
package datamysql
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"fmt"
|
||||
|
||||
"bitbucket.org/nemt/nemt-portal-api/domain/entity"
|
||||
"bitbucket.org/nemt/nemt-portal-api/infra/errors"
|
||||
uuid "github.com/satori/go.uuid"
|
||||
)
|
||||
|
||||
// rideRepo maps methods to database
|
||||
type organizationRepo struct {
|
||||
conn executor
|
||||
}
|
||||
|
||||
func newOrganizationRepo(conn executor) *organizationRepo {
|
||||
return &organizationRepo{
|
||||
conn: conn,
|
||||
}
|
||||
}
|
||||
|
||||
func (c *organizationRepo) getQuery() string {
|
||||
const (
|
||||
query = `SELECT
|
||||
a.organization_id,
|
||||
a.organization_uuid,
|
||||
b.organization_type_id,
|
||||
b.organization_type,
|
||||
b.organization_type_key,
|
||||
a.organization_name,
|
||||
a.organization_description,
|
||||
a.organization_reference_id,
|
||||
a.organization_parent_id,
|
||||
(a.main_organization = b'1') main_organization,
|
||||
a.create_at,
|
||||
a.update_at,
|
||||
(a.active = b'1') active,
|
||||
(a.suspended = b'1') suspended,
|
||||
(a.blocked = b'1') blocked,
|
||||
c.user_id created_user_id,
|
||||
c.user_uuid created_user_uuid,
|
||||
c.name created_user_name,
|
||||
d.user_id updated_user_id,
|
||||
d.user_uuid updated_user_uuid,
|
||||
d.name updated_user_name
|
||||
FROM
|
||||
tab_organization a
|
||||
INNER JOIN tab_organization_type b
|
||||
ON a.organization_type_id = b.organization_type_id
|
||||
INNER JOIN tab_user c
|
||||
ON c.user_id = a.created_user
|
||||
INNER JOIN tab_user d
|
||||
ON d.user_id = a.updated_user `
|
||||
)
|
||||
|
||||
return query
|
||||
}
|
||||
func (c *organizationRepo) getAddressQuery() string {
|
||||
const query = `SELECT
|
||||
a.organization_address_id,
|
||||
a.organization_address_uuid,
|
||||
a.internal_id,
|
||||
a.name,
|
||||
a.address,
|
||||
a.desc,
|
||||
a.lat,
|
||||
a.long,
|
||||
a.created,
|
||||
a.created_user_id,
|
||||
c.user_uuid created_user_uuid,
|
||||
c.name created_user_name,
|
||||
a.updated,
|
||||
a.updated_user_id,
|
||||
d.user_uuid updated_user_uuid,
|
||||
d.name updated_user_name,
|
||||
(a.active = b'1') active
|
||||
FROM tab_organization_address a
|
||||
INNER JOIN tab_organization b
|
||||
ON b.organization_id = a.organization_id
|
||||
INNER JOIN tab_user c
|
||||
ON c.user_id = a.created_user_id
|
||||
INNER JOIN tab_user d
|
||||
ON d.user_id = a.updated_user_id `
|
||||
|
||||
return query
|
||||
}
|
||||
|
||||
func (c *organizationRepo) getContactQuery() string {
|
||||
const (
|
||||
query = `SELECT
|
||||
a.organization_contact_id,
|
||||
a.organization_contact_uuid,
|
||||
b.contact_type_id,
|
||||
b.key contact_type_key,
|
||||
b.name contact_type_name,
|
||||
a.contact,
|
||||
a.contact_name,
|
||||
a.contact_desc,
|
||||
a.created,
|
||||
a.created_user_id,
|
||||
d.user_uuid created_user_uuid,
|
||||
d.name created_user_name,
|
||||
a.updated,
|
||||
a.updated_user_id,
|
||||
e.user_uuid updated_user_uuid,
|
||||
e.name updated_user_name,
|
||||
(a.active = b'1') active
|
||||
FROM tab_organization_contact a
|
||||
INNER JOIN tab_contact_type b
|
||||
ON a.contact_type_id = b.contact_type_id
|
||||
INNER JOIN tab_organization c
|
||||
ON c.organization_id = a.organization_id
|
||||
INNER JOIN tab_user d
|
||||
ON d.user_id = a.created_user_id
|
||||
INNER JOIN tab_user e
|
||||
ON e.user_id = a.updated_user_id `
|
||||
)
|
||||
|
||||
return query
|
||||
}
|
||||
|
||||
func (c *organizationRepo) getTypeQuery() string {
|
||||
const (
|
||||
query = `SELECT
|
||||
organization_type_id,
|
||||
organization_type,
|
||||
organization_type_key,
|
||||
description,
|
||||
create_at,
|
||||
update_at
|
||||
FROM
|
||||
tab_organization_type `
|
||||
)
|
||||
|
||||
return query
|
||||
}
|
||||
|
||||
// parseSet parses a result set result to an entity array
|
||||
func (c *organizationRepo) parseSet(rows *sql.Rows, err error) ([]entity.Organization, error) {
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err)
|
||||
}
|
||||
result := make([]entity.Organization, 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 *organizationRepo) parseEntity(row scanner) (retVal entity.Organization, err error) {
|
||||
err = row.Scan(
|
||||
&retVal.ID, &retVal.UUID, &retVal.Type.ID, &retVal.Type.Name, &retVal.Type.Key, &retVal.Name, &retVal.Description, &retVal.ReferenceID, &retVal.ParentID, &retVal.Main, &retVal.Created, &retVal.Updated, &retVal.Active, &retVal.Suspended, &retVal.Blocked, &retVal.Author.ID, &retVal.Author.UUID, &retVal.Author.Name, &retVal.LastEditor.ID, &retVal.LastEditor.UUID, &retVal.LastEditor.Name)
|
||||
|
||||
return retVal, errors.Wrap(err)
|
||||
}
|
||||
|
||||
// parseSet parses a result set result to an entity array
|
||||
func (c *organizationRepo) parseContactSet(rows *sql.Rows, err error) ([]entity.OrganizationContact, error) {
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err)
|
||||
}
|
||||
result := make([]entity.OrganizationContact, 0)
|
||||
for rows.Next() {
|
||||
entity, err := c.parseContactEntity(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 *organizationRepo) parseContactEntity(row scanner) (retVal entity.OrganizationContact, err error) {
|
||||
err = row.Scan(
|
||||
&retVal.ID, &retVal.UUID, &retVal.Type.ID, &retVal.Type.Key, &retVal.Type.Value, &retVal.Contact, &retVal.Name, &retVal.Description, &retVal.Created, &retVal.CreatedUser.ID, &retVal.CreatedUser.UUID, &retVal.CreatedUser.Name, &retVal.Updated, &retVal.UpdatedUser.ID, &retVal.UpdatedUser.UUID, &retVal.UpdatedUser.Name, &retVal.Active)
|
||||
|
||||
return retVal, errors.Wrap(err)
|
||||
}
|
||||
|
||||
// parseSet parses a result set result to an entity array
|
||||
func (c *organizationRepo) parseAddressSet(rows *sql.Rows, err error) ([]entity.OrganizationAddress, error) {
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err)
|
||||
}
|
||||
result := make([]entity.OrganizationAddress, 0)
|
||||
for rows.Next() {
|
||||
entity, err := c.parseAddressEntity(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 *organizationRepo) parseAddressEntity(row scanner) (retVal entity.OrganizationAddress, err error) {
|
||||
err = row.Scan(
|
||||
&retVal.ID, &retVal.UUID, &retVal.InternalID, &retVal.Name, &retVal.Address, &retVal.Description, &retVal.Latitude, &retVal.Longitude, &retVal.Created, &retVal.CreatedUser.ID, &retVal.CreatedUser.UUID, &retVal.CreatedUser.Name, &retVal.Updated, &retVal.UpdatedUser.ID, &retVal.UpdatedUser.UUID, &retVal.UpdatedUser.Name, &retVal.Active)
|
||||
|
||||
return retVal, errors.Wrap(err)
|
||||
}
|
||||
|
||||
// parseSet parses a result set result to an entity array
|
||||
func (c *organizationRepo) parseTypeSet(rows *sql.Rows, err error) ([]entity.OrganizationType, error) {
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err)
|
||||
}
|
||||
result := make([]entity.OrganizationType, 0)
|
||||
for rows.Next() {
|
||||
entity, err := c.parseTypeEntity(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 *organizationRepo) parseTypeEntity(row scanner) (retVal entity.OrganizationType, err error) {
|
||||
err = row.Scan(
|
||||
&retVal.ID, &retVal.Name, &retVal.Key, &retVal.Description, &retVal.Created, &retVal.Updated)
|
||||
|
||||
return retVal, errors.Wrap(err)
|
||||
}
|
||||
|
||||
func (c *organizationRepo) GetAllTypes() ([]entity.OrganizationType, error) {
|
||||
return c.parseTypeSet(c.conn.Query(c.getTypeQuery()))
|
||||
}
|
||||
|
||||
func (c *organizationRepo) GetTypeByKey(key string) (entity.OrganizationType, error) {
|
||||
return c.parseTypeEntity(c.conn.QueryRow(c.getTypeQuery()+" WHERE organization_type_key=?", key))
|
||||
}
|
||||
|
||||
func (c *organizationRepo) GetByType(organizationTypeKey string) ([]entity.Organization, error) {
|
||||
if organizationTypeKey == "" {
|
||||
return c.parseSet(c.conn.Query(c.getQuery()))
|
||||
} else {
|
||||
return c.parseSet(c.conn.Query(c.getQuery()+" WHERE b.organization_type_key = ? ", organizationTypeKey))
|
||||
}
|
||||
}
|
||||
|
||||
func (c *organizationRepo) GetByName(name string, searchType string) ([]entity.Organization, error) {
|
||||
finalQuery := c.getQuery() + " WHERE a.organization_name LIKE ?"
|
||||
switch searchType {
|
||||
case "parent":
|
||||
finalQuery += " AND a.organization_parent_id > 0; "
|
||||
case "child":
|
||||
finalQuery += " AND a.organization_parent_id = 0; "
|
||||
}
|
||||
name = "%" + name + "%"
|
||||
|
||||
fmt.Println(finalQuery)
|
||||
|
||||
return c.parseSet(c.conn.Query(finalQuery, name))
|
||||
}
|
||||
|
||||
func (c *organizationRepo) GetByUUID(organizationUUID string) (entity.Organization, error) {
|
||||
return c.parseEntity(c.conn.QueryRow(c.getQuery()+" WHERE a.organization_uuid = ? ", organizationUUID))
|
||||
}
|
||||
|
||||
func (c *organizationRepo) GetByID(organizationID int64) (entity.Organization, error) {
|
||||
return c.parseEntity(c.conn.QueryRow(c.getQuery()+" WHERE a.organization_id = ? ", organizationID))
|
||||
}
|
||||
|
||||
func (c *organizationRepo) GetChildsByID(organizationID int64) ([]entity.Organization, error) {
|
||||
return c.parseSet(c.conn.Query(c.getQuery()+" WHERE a.organization_parent_id = ? ", organizationID))
|
||||
}
|
||||
|
||||
func (c *organizationRepo) GetContactsByOrganizationUUID(organizationUUID string) ([]entity.OrganizationContact, error) {
|
||||
return c.parseContactSet(c.conn.Query(c.getContactQuery()+" WHERE a.active = 1 AND c.organization_uuid = ? ", organizationUUID))
|
||||
}
|
||||
|
||||
func (c *organizationRepo) GetContactsByOrganizationID(organizationID int64) ([]entity.OrganizationContact, error) {
|
||||
return c.parseContactSet(c.conn.Query(c.getContactQuery()+" WHERE a.active = 1 AND c.organization_id = ? ", organizationID))
|
||||
}
|
||||
|
||||
func (c *organizationRepo) GetContactsByUUID(contactUUID string) (entity.OrganizationContact, error) {
|
||||
return c.parseContactEntity(c.conn.QueryRow(c.getContactQuery()+" WHERE a.organization_contact_uuid = ? ", contactUUID))
|
||||
}
|
||||
|
||||
func (c *organizationRepo) GetAddressByOrganizationUUID(organizationUUID string) ([]entity.OrganizationAddress, error) {
|
||||
return c.parseAddressSet(c.conn.Query(c.getAddressQuery()+" WHERE a.active = 1 AND b.organization_uuid = ? ", organizationUUID))
|
||||
}
|
||||
|
||||
func (c *organizationRepo) GetAddressByOrganizationID(organizationID int64) ([]entity.OrganizationAddress, error) {
|
||||
return c.parseAddressSet(c.conn.Query(c.getAddressQuery()+" WHERE a.active = 1 AND b.organization_id = ? ", organizationID))
|
||||
}
|
||||
|
||||
func (c *organizationRepo) GetAddressByUUID(contactUUID string) (entity.OrganizationAddress, error) {
|
||||
return c.parseAddressEntity(c.conn.QueryRow(c.getAddressQuery()+" WHERE a.organization_address_uuid = ? ", contactUUID))
|
||||
}
|
||||
|
||||
func (c *organizationRepo) SetParentOrganization(organizationID int64, parentOrganizationID int64) error {
|
||||
const (
|
||||
query = `UPDATE tab_organization SET organization_parent_id = ? WHERE organization_id = ?;`
|
||||
)
|
||||
|
||||
_, err := c.conn.Exec(query, parentOrganizationID, organizationID)
|
||||
if err != nil {
|
||||
return err
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func (c *organizationRepo) InactivateOrganizationAddress(address entity.OrganizationAddress) error {
|
||||
const (
|
||||
query = "UPDATE tab_organization_address SET active = 0, updated = CURRENT_TIMESTAMP, updated_user_id = ? WHERE organization_id = ? and organization_address_uuid = ?"
|
||||
)
|
||||
|
||||
if address.Organization == nil {
|
||||
return errors.NewNotFoundError()
|
||||
}
|
||||
|
||||
organization, err := c.GetByUUID(address.Organization.UUID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
_, err = c.conn.Exec(query, address.UpdatedUser.ID, organization.ID, address.UUID)
|
||||
if err != nil {
|
||||
return err
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func (c *organizationRepo) SetOrganizationAddress(address entity.OrganizationAddress) (entity.OrganizationAddress, error) {
|
||||
const (
|
||||
query = "INSERT INTO tab_organization_address(organization_address_uuid, organization_id, internal_id, `name`, address, `desc`, lat, `long`, created_user_id, updated_user_id) VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?);"
|
||||
)
|
||||
|
||||
if address.Organization == nil {
|
||||
return entity.OrganizationAddress{}, errors.NewNotFoundError()
|
||||
}
|
||||
|
||||
organization, err := c.GetByUUID(address.Organization.UUID)
|
||||
if err != nil {
|
||||
return entity.OrganizationAddress{}, err
|
||||
}
|
||||
|
||||
UUID, _ := uuid.NewV4()
|
||||
result, err := c.conn.Exec(query, UUID.String(), organization.ID, address.InternalID, address.Name, address.Address, address.Description, address.Latitude, address.Longitude, address.CreatedUser.ID, address.UpdatedUser.ID)
|
||||
if err != nil {
|
||||
return entity.OrganizationAddress{}, err
|
||||
}
|
||||
|
||||
address.ID, err = result.LastInsertId()
|
||||
if err != nil {
|
||||
return address, err
|
||||
}
|
||||
|
||||
return address, nil
|
||||
}
|
||||
|
||||
func (c *organizationRepo) InactivateOrganizationContact(contact entity.OrganizationContact) error {
|
||||
const (
|
||||
query = "UPDATE tab_organization_contact SET active = 0, updated = CURRENT_TIMESTAMP, updated_user_id = ? WHERE organization_id = ? and organization_contact_uuid = ?"
|
||||
)
|
||||
|
||||
if contact.Organization == nil {
|
||||
return errors.NewNotFoundError()
|
||||
}
|
||||
|
||||
organization, err := c.GetByUUID(contact.Organization.UUID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
_, err = c.conn.Exec(query, contact.UpdatedUser.ID, organization.ID, contact.UUID)
|
||||
if err != nil {
|
||||
return err
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func (c *organizationRepo) SetOrganizationContact(contact entity.OrganizationContact) (entity.OrganizationContact, error) {
|
||||
const (
|
||||
selectQuery = "SELECT a.contact_type_id, a.name, a.key FROM tab_contact_type a WHERE a.key = ?"
|
||||
query = "INSERT INTO tab_organization_contact(organization_contact_uuid, organization_id, contact_type_id, contact, contact_name, contact_desc, created_user_id, updated_user_id) VALUES(?, ?, ?, ?, ?, ?, ?, ?);"
|
||||
)
|
||||
|
||||
if contact.Organization == nil {
|
||||
return entity.OrganizationContact{}, errors.NewNotFoundError()
|
||||
}
|
||||
|
||||
organization, err := c.GetByUUID(contact.Organization.UUID)
|
||||
if err != nil {
|
||||
return entity.OrganizationContact{}, err
|
||||
}
|
||||
|
||||
row := c.conn.QueryRow(selectQuery, contact.Type.Key)
|
||||
err = row.Scan(&contact.Type.ID, &contact.Type.Value, &contact.Type.Key)
|
||||
if err != nil {
|
||||
return entity.OrganizationContact{}, err
|
||||
}
|
||||
|
||||
UUID, _ := uuid.NewV4()
|
||||
result, err := c.conn.Exec(query, UUID.String(), organization.ID, contact.Type.ID, contact.Contact, contact.Name, contact.Description, contact.CreatedUser.ID, contact.UpdatedUser.ID)
|
||||
if err != nil {
|
||||
return entity.OrganizationContact{}, err
|
||||
}
|
||||
|
||||
contact.ID, err = result.LastInsertId()
|
||||
if err != nil {
|
||||
return contact, err
|
||||
}
|
||||
|
||||
return contact, nil
|
||||
}
|
||||
|
||||
func (c *organizationRepo) AddOrganization(organization entity.Organization) (entity.Organization, error) {
|
||||
const (
|
||||
queryOrgType = "SELECT a.organization_type_id FROM tab_organization_type a WHERE a.organization_type_key = ?;"
|
||||
queryParentOrg = "SELECT a.organization_id FROM tab_organization a WHERE a.organization_uuid = ?;"
|
||||
query = "INSERT INTO tab_organization(organization_uuid, organization_type_id, organization_name, organization_description, organization_reference_id, organization_parent_id, main_organization, created_user, updated_user) VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?);"
|
||||
)
|
||||
|
||||
row := c.conn.QueryRow(queryOrgType, organization.Type.Key)
|
||||
err := row.Scan(&organization.Type.ID)
|
||||
if err != nil {
|
||||
return entity.Organization{}, err
|
||||
}
|
||||
|
||||
if organization.Parent != nil && organization.Parent.UUID != "" {
|
||||
row := c.conn.QueryRow(queryParentOrg, organization.Parent.UUID)
|
||||
err := row.Scan(&organization.Parent.ID)
|
||||
if err != nil {
|
||||
return entity.Organization{}, err
|
||||
}
|
||||
organization.ParentID = organization.Parent.ID
|
||||
}
|
||||
|
||||
UUID, _ := uuid.NewV4()
|
||||
organization.UUID = UUID.String()
|
||||
result, err := c.conn.Exec(query, organization.UUID, organization.Type.ID, organization.Name, organization.Description, organization.ReferenceID, organization.ParentID, false, organization.Author.ID, organization.LastEditor.ID)
|
||||
if err != nil {
|
||||
return entity.Organization{}, err
|
||||
}
|
||||
|
||||
ID, err := result.LastInsertId()
|
||||
if err != nil {
|
||||
return entity.Organization{}, err
|
||||
}
|
||||
|
||||
organization.ID = ID
|
||||
if len(organization.Addresses) > 0 {
|
||||
for i, a := range organization.Addresses {
|
||||
a.Organization = &organization
|
||||
address, err := c.SetOrganizationAddress(a)
|
||||
if err != nil {
|
||||
fmt.Println("Error to save addresses")
|
||||
return entity.Organization{}, err
|
||||
}
|
||||
organization.Addresses[i] = address
|
||||
}
|
||||
}
|
||||
|
||||
if len(organization.Contacts) > 0 {
|
||||
for i, ct := range organization.Contacts {
|
||||
ct.Organization = &organization
|
||||
contact, err := c.SetOrganizationContact(ct)
|
||||
if err != nil {
|
||||
fmt.Println("Error to save contacts")
|
||||
return entity.Organization{}, err
|
||||
}
|
||||
organization.Contacts[i] = contact
|
||||
}
|
||||
}
|
||||
|
||||
return organization, nil
|
||||
}
|
||||
77
data/datamysql/profile.go
Normal file
77
data/datamysql/profile.go
Normal file
@@ -0,0 +1,77 @@
|
||||
package datamysql
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
|
||||
"bitbucket.org/nemt/nemt-portal-api/domain/entity"
|
||||
"bitbucket.org/nemt/nemt-portal-api/infra/errors"
|
||||
)
|
||||
|
||||
// rideRepo maps methods to database
|
||||
type profileRepo struct {
|
||||
conn executor
|
||||
}
|
||||
|
||||
func newProfileRepo(conn executor) *profileRepo {
|
||||
return &profileRepo{
|
||||
conn: conn,
|
||||
}
|
||||
}
|
||||
|
||||
func (c *profileRepo) getQuery() string {
|
||||
const (
|
||||
query = `SELECT
|
||||
a.profile_id,
|
||||
a.name,
|
||||
a.key,
|
||||
a.description,
|
||||
a.create_time,
|
||||
a.update_time,
|
||||
(a.active = b'1') active,
|
||||
(a.visible = b'1') visible
|
||||
FROM
|
||||
tab_profile a `
|
||||
)
|
||||
|
||||
return query
|
||||
}
|
||||
|
||||
// parseSet parses a result set result to an entity array
|
||||
func (c *profileRepo) parseSet(rows *sql.Rows, err error) ([]entity.Profile, error) {
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err)
|
||||
}
|
||||
result := make([]entity.Profile, 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 *profileRepo) parseEntity(row scanner) (retVal entity.Profile, err error) {
|
||||
err = row.Scan(
|
||||
&retVal.ID, &retVal.Name, &retVal.Key, &retVal.Description, &retVal.Created, &retVal.Updated, &retVal.Active, &retVal.Visible)
|
||||
|
||||
return retVal, errors.Wrap(err)
|
||||
}
|
||||
|
||||
func (c *profileRepo) GetAll() ([]entity.Profile, error) {
|
||||
return c.parseSet(c.conn.Query(c.getQuery()))
|
||||
}
|
||||
|
||||
func (c *profileRepo) GetByKey(key string) (entity.Profile, error) {
|
||||
return c.parseEntity(c.conn.QueryRow(c.getQuery()+"WHERE a.active = 1 AND a.key = ?", key))
|
||||
}
|
||||
|
||||
func (c *profileRepo) GetVisibles(visible bool) ([]entity.Profile, error) {
|
||||
return c.parseSet(c.conn.Query(c.getQuery()+"WHERE a.active = 1 AND a.visible = ?", visible))
|
||||
}
|
||||
|
||||
func (c *profileRepo) GetByOrganizationType(organizationTypeID int64) ([]entity.Profile, error) {
|
||||
return c.parseSet(c.conn.Query(c.getQuery()+" INNER JOIN tab_organization_type_profile b ON a.profile_id = b.profile_id WHERE a.active = 1 AND a.visible = 1 AND b.organization_type_id = ?", organizationTypeID))
|
||||
}
|
||||
421
data/datamysql/provider.go
Normal file
421
data/datamysql/provider.go
Normal file
@@ -0,0 +1,421 @@
|
||||
package datamysql
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"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"
|
||||
)
|
||||
|
||||
// rideRepo maps methods to database
|
||||
type providerRepo struct {
|
||||
conn executor
|
||||
}
|
||||
|
||||
func newProviderRepo(conn executor) *providerRepo {
|
||||
return &providerRepo{
|
||||
conn: conn,
|
||||
}
|
||||
}
|
||||
|
||||
func (c *providerRepo) 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":
|
||||
switch p.Organization.Type.Key {
|
||||
case "techsupport", "bcbsi", "bcbsa", "plan":
|
||||
return
|
||||
case "provider":
|
||||
query = ` INNER JOIN viw_organization_provider c
|
||||
ON a.provider_id = c.provider_id `
|
||||
where = fmt.Sprintf(` AND (c.organization_uuid = '%s' OR c.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 *providerRepo) getSelectQueryBaseKey() string {
|
||||
return `SELECT
|
||||
a.provider_key_id,
|
||||
a.provider_id,
|
||||
a.internal_id,
|
||||
a.internal_id_suffix,
|
||||
a.location_seq_num,
|
||||
a.plan_code,
|
||||
a.product_id,
|
||||
a.treatment_category_code,
|
||||
a.active,
|
||||
a.enabled,
|
||||
a.create_at,
|
||||
a.update_at,
|
||||
a.created_user
|
||||
FROM tab_provider_key a `
|
||||
}
|
||||
|
||||
func (c *providerRepo) getSelectQueryBase() string {
|
||||
return `SELECT DISTINCT
|
||||
a.provider_id,
|
||||
a.provider_uuid,
|
||||
a.provider_internal_id,
|
||||
a.provider_internal_id_suffix,
|
||||
a.provider_muk_id,
|
||||
a.organization_name,
|
||||
a.gender,
|
||||
a.accept_new_patients,
|
||||
a.provider_name,
|
||||
a.first_name,
|
||||
a.last_name,
|
||||
a.middle_name,
|
||||
a.provider_title,
|
||||
a.street_name1,
|
||||
a.street_name2,
|
||||
a.city_name,
|
||||
a.state,
|
||||
a.zipcode,
|
||||
a.country,
|
||||
a.latitude,
|
||||
a.longitude,
|
||||
a.phone_number,
|
||||
a.create_at,
|
||||
a.update_at,
|
||||
a.active,
|
||||
a.enabled,
|
||||
a.created_user,
|
||||
(3959 * acos (
|
||||
cos ( radians(?) )
|
||||
* cos( radians( a.latitude ) )
|
||||
* cos( radians( a.longitude ) - radians(?) )
|
||||
+ sin ( radians(?) )
|
||||
* sin( radians( a.latitude ) )
|
||||
)) AS distance_in_miles
|
||||
FROM
|
||||
tab_provider a
|
||||
INNER JOIN tab_provider_key b
|
||||
ON a.provider_id = b.provider_id `
|
||||
}
|
||||
|
||||
func (c *providerRepo) GetAll(user entity.User) ([]entity.Provider, error) {
|
||||
lat := 41.886406
|
||||
long := -87.624225
|
||||
|
||||
query, where, err := c.getProfileQuery(user)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
query = c.getSelectQueryBase() + query + " WHERE 1 = 1 " + where
|
||||
|
||||
providers, err := c.parseSet(c.conn.Query(query, lat, long, lat))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return c.getKeys("", "", providers)
|
||||
}
|
||||
|
||||
func (c *providerRepo) GetByMukID(mukID string, user entity.User) (entity.Provider, error) {
|
||||
lat := 41.886406
|
||||
long := -87.624225
|
||||
|
||||
query, where, err := c.getProfileQuery(user)
|
||||
if err != nil {
|
||||
return entity.Provider{}, err
|
||||
}
|
||||
|
||||
query = c.getSelectQueryBase() + query + " WHERE a.provider_muk_id = ? " + where
|
||||
|
||||
return c.parseEntity(c.conn.QueryRow(query, lat, long, lat, mukID))
|
||||
}
|
||||
|
||||
func (c *providerRepo) Get(query string, lat float64, long float64, distance int64, planCode string, productID string, mukID string, internalID string, sort string, user entity.User) ([]entity.Provider, error) {
|
||||
filter := " WHERE 1 = 1 "
|
||||
params := make([]interface{}, 0)
|
||||
|
||||
if lat == 0 && long == 0 {
|
||||
lat = 41.886406
|
||||
long = -87.624225
|
||||
}
|
||||
params = append(params, lat, long, lat)
|
||||
|
||||
if query != "" && (mukID == "" && internalID == "") {
|
||||
filter += " AND (a.provider_name LIKE ? OR a.street_name1 LIKE ? OR a.street_name2 LIKE ? OR a.zipcode LIKE ?) "
|
||||
// MATCH(a.provider_internal_id, a.provider_internal_id_suffix, a.provider_muk_id, a.provider_name, a.street_name1, a.street_name2, a.city_name, a.state, a.zipcode, a.country, a.phone_number) AGAINST (?)
|
||||
|
||||
query = "%" + query + "%"
|
||||
params = append(params, query, query, query, query)
|
||||
}
|
||||
|
||||
if planCode != "" {
|
||||
filter += " AND b.plan_code = ? "
|
||||
params = append(params, planCode)
|
||||
}
|
||||
|
||||
if productID != "" {
|
||||
filter += " AND b.product_id = ? "
|
||||
params = append(params, productID)
|
||||
}
|
||||
|
||||
if mukID != "" {
|
||||
filter += " AND a.provider_muk_id = ? "
|
||||
params = append(params, mukID)
|
||||
}
|
||||
|
||||
if internalID != "" {
|
||||
filter += " AND a.provider_internal_id = ? "
|
||||
params = append(params, internalID)
|
||||
}
|
||||
|
||||
final := " HAVING distance_in_miles < ? "
|
||||
params = append(params, distance)
|
||||
|
||||
if sort == "name" {
|
||||
final += " ORDER BY a.provider_name ASC "
|
||||
} else if sort == "distance" {
|
||||
final += " ORDER BY distance_in_miles ASC "
|
||||
}
|
||||
|
||||
query, where, err := c.getProfileQuery(user)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
query = c.getSelectQueryBase() + query + filter + where + final
|
||||
|
||||
providers, err := c.parseSet(c.conn.Query(query, params...))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(providers) > 0 {
|
||||
return c.getKeys(planCode, productID, providers)
|
||||
} else {
|
||||
return providers, nil
|
||||
}
|
||||
}
|
||||
|
||||
func (c *providerRepo) getKeys(planCode string, productID string, providers []entity.Provider) ([]entity.Provider, error) {
|
||||
var params []interface{}
|
||||
var queryParams = " WHERE a.provider_id IN ("
|
||||
for _, p := range providers {
|
||||
queryParams += "?,"
|
||||
params = append(params, p.ProviderID)
|
||||
}
|
||||
queryParams = queryParams[0 : len(queryParams)-1]
|
||||
queryParams += ") "
|
||||
|
||||
if planCode != "" {
|
||||
queryParams += " AND a.plan_code = ? "
|
||||
params = append(params, planCode)
|
||||
}
|
||||
|
||||
if productID != "" {
|
||||
queryParams += " AND a.product_id = ? "
|
||||
params = append(params, productID)
|
||||
}
|
||||
|
||||
keys, err := c.parseKeySet(c.conn.Query(c.getSelectQueryBaseKey()+queryParams, params...))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
sortedResults := make(map[string][]entity.ProviderKey)
|
||||
for _, k := range keys {
|
||||
sortedKey := fmt.Sprintf("provider%v", k.Provider.ProviderID)
|
||||
sortedResults[sortedKey] = append(sortedResults[sortedKey], k)
|
||||
}
|
||||
|
||||
for i := range providers {
|
||||
sortedKey := fmt.Sprintf("provider%v", providers[i].ProviderID)
|
||||
providers[i].Keys = sortedResults[sortedKey]
|
||||
}
|
||||
|
||||
return providers, nil
|
||||
}
|
||||
|
||||
// parseSet parses a result set result to an entity array
|
||||
func (c *providerRepo) parseKeySet(rows *sql.Rows, err error) ([]entity.ProviderKey, error) {
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err)
|
||||
}
|
||||
result := make([]entity.ProviderKey, 0)
|
||||
for rows.Next() {
|
||||
entity, err := c.parseKeyEntity(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 *providerRepo) parseKeyEntity(row scanner) (retVal entity.ProviderKey, err error) {
|
||||
err = row.Scan(
|
||||
&retVal.ProviderKeyID, &retVal.Provider.ProviderID, &retVal.InternalID, &retVal.InternalSuffixID, &retVal.LocationSeqNumber, &retVal.PlanCode, &retVal.ProductID, &retVal.TreatmentCategoryCode, &retVal.Active, &retVal.Enabled, &retVal.CreateDate, &retVal.UpdateDate, &retVal.CreatedUser.ID)
|
||||
|
||||
return retVal, errors.Wrap(err)
|
||||
}
|
||||
|
||||
// parseSet parses a result set result to an entity array
|
||||
func (c *providerRepo) parseSet(rows *sql.Rows, err error) ([]entity.Provider, error) {
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err)
|
||||
}
|
||||
result := make([]entity.Provider, 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 *providerRepo) parseEntity(row scanner) (retVal entity.Provider, err error) {
|
||||
err = row.Scan(
|
||||
&retVal.ProviderID, &retVal.ProviderUUID, &retVal.InternalID, &retVal.InternalSuffixID, &retVal.MukID, &retVal.OrganizatioName, &retVal.Gender, &retVal.AcceptNewPatients, &retVal.Name, &retVal.FirstName, &retVal.LastName, &retVal.MiddleName, &retVal.Title, &retVal.Address.StreetAddress1, &retVal.Address.StreetAddress2, &retVal.Address.CityName, &retVal.Address.State, &retVal.Address.ZipCode, &retVal.Address.Country, &retVal.Address.Latitude, &retVal.Address.Longitude, &retVal.Address.PhoneNumber, &retVal.CreateDate, &retVal.UpdateDate, &retVal.Active, &retVal.Enabled, &retVal.CreatedUser.ID, &retVal.Distance)
|
||||
|
||||
return retVal, errors.Wrap(err)
|
||||
}
|
||||
|
||||
func (c *providerRepo) Save(providers []entity.ProviderResponse, user entity.User) ([]entity.Provider, error) {
|
||||
var savedProviders = make([]entity.Provider, 0)
|
||||
for _, p := range providers {
|
||||
provider, err := c.saveProvider(p, user)
|
||||
if err != nil {
|
||||
if driverErr, ok := err.(*mysql.MySQLError); ok {
|
||||
if driverErr.Number != 1062 {
|
||||
return nil, err
|
||||
}
|
||||
} else {
|
||||
return nil, err
|
||||
}
|
||||
} else {
|
||||
savedProviders = append(savedProviders, provider)
|
||||
}
|
||||
}
|
||||
|
||||
return savedProviders, nil
|
||||
}
|
||||
|
||||
func (c *providerRepo) saveProvider(provider entity.ProviderResponse, user entity.User) (entity.Provider, error) {
|
||||
const (
|
||||
query = `INSERT INTO tab_provider(provider_uuid,provider_internal_id,provider_internal_id_suffix,provider_muk_id,organization_name,gender,accept_new_patients,provider_name,first_name,last_name,middle_name,provider_title,street_name1,street_name2,city_name,state,zipcode,country,latitude,longitude,phone_number,created_user)
|
||||
VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?);`
|
||||
)
|
||||
|
||||
UUID, _ := uuid.NewV4()
|
||||
lat, _ := strconv.ParseFloat(provider.Latitude, 64)
|
||||
long, _ := strconv.ParseFloat(provider.Longitude, 64)
|
||||
|
||||
p := entity.Provider{
|
||||
ProviderUUID: UUID.String(),
|
||||
InternalID: provider.FivePartKeyGroups[0].ProviderNum,
|
||||
InternalSuffixID: provider.FivePartKeyGroups[0].ProviderNumSuffix,
|
||||
MukID: provider.MukID,
|
||||
OrganizatioName: provider.OrgName,
|
||||
Gender: provider.Gender,
|
||||
AcceptNewPatients: provider.AcceptNewPatients,
|
||||
Name: provider.ProviderName,
|
||||
FirstName: provider.FirstName,
|
||||
MiddleName: provider.MiddleName,
|
||||
LastName: provider.LastName,
|
||||
Title: provider.ProviderTitle,
|
||||
Address: entity.ProviderAddress{
|
||||
StreetAddress1: provider.StreetName1,
|
||||
StreetAddress2: provider.StreetName2,
|
||||
CityName: provider.CityName,
|
||||
State: provider.State,
|
||||
ZipCode: provider.ZipCode,
|
||||
Country: provider.Country,
|
||||
Latitude: lat,
|
||||
Longitude: long,
|
||||
PhoneNumber: provider.PhoneNumber,
|
||||
},
|
||||
CreateDate: time.Now(),
|
||||
UpdateDate: time.Now(),
|
||||
Active: true,
|
||||
Enabled: true,
|
||||
}
|
||||
|
||||
result, err := c.conn.Exec(query, p.ProviderUUID, p.InternalID, p.InternalSuffixID, p.MukID, p.OrganizatioName, p.Gender, p.AcceptNewPatients, p.Name, p.FirstName, p.LastName, p.MiddleName, p.Title, p.Address.StreetAddress1, p.Address.StreetAddress2, p.Address.CityName, p.Address.State, p.Address.ZipCode, p.Address.Country, p.Address.Latitude, p.Address.Longitude, p.Address.PhoneNumber, 1)
|
||||
if err != nil {
|
||||
if driverErr, ok := err.(*mysql.MySQLError); ok {
|
||||
if driverErr.Number != 1062 {
|
||||
return entity.Provider{}, err
|
||||
} else {
|
||||
tempProvider, err := c.GetByMukID(p.MukID, user)
|
||||
if err != nil {
|
||||
return entity.Provider{}, err
|
||||
}
|
||||
p.ProviderID = tempProvider.ProviderID
|
||||
}
|
||||
}
|
||||
} else {
|
||||
p.ProviderID, err = result.LastInsertId()
|
||||
if err != nil {
|
||||
return entity.Provider{}, err
|
||||
}
|
||||
}
|
||||
|
||||
var providerKeys []entity.ProviderKey
|
||||
for _, fk := range provider.FivePartKeyGroups {
|
||||
key, err := c.saveKeys(p.ProviderID, fk)
|
||||
if err != nil {
|
||||
return p, err
|
||||
}
|
||||
providerKeys = append(providerKeys, key)
|
||||
}
|
||||
p.Keys = providerKeys
|
||||
|
||||
return p, nil
|
||||
}
|
||||
|
||||
func (c *providerRepo) saveKeys(ProviderID int64, fk entity.PartKeyGroup) (entity.ProviderKey, error) {
|
||||
const (
|
||||
query = `INSERT INTO tab_provider_key (provider_id, internal_id, internal_id_suffix, location_seq_num, plan_code, product_id, treatment_category_code, created_user)
|
||||
VALUES (?, ?, ?, ?, ?, ?, ?, ?) ON DUPLICATE KEY UPDATE provider_id = ?, internal_id = ?, internal_id_suffix = ?, location_seq_num = ?, plan_code = ?, product_id = ?, treatment_category_code = ?, created_user = ?;`
|
||||
)
|
||||
|
||||
key := entity.ProviderKey{
|
||||
InternalID: fk.ProviderNum,
|
||||
InternalSuffixID: fk.ProviderNumSuffix,
|
||||
TreatmentCategoryCode: fk.TreatmentCategoryCode,
|
||||
ProductID: fk.ProductID,
|
||||
PlanCode: fk.PlanCode,
|
||||
LocationSeqNumber: fk.LocationSeqNum,
|
||||
Provider: entity.Provider{
|
||||
ProviderID: ProviderID,
|
||||
},
|
||||
}
|
||||
|
||||
result, err := c.conn.Exec(query, key.Provider.ProviderID, key.InternalID, key.InternalSuffixID, key.LocationSeqNumber, key.PlanCode, key.ProductID, key.TreatmentCategoryCode, 1, key.Provider.ProviderID, key.InternalID, key.InternalSuffixID, key.LocationSeqNumber, key.PlanCode, key.ProductID, key.TreatmentCategoryCode, 1)
|
||||
if err != nil {
|
||||
return key, err
|
||||
}
|
||||
|
||||
key.ProviderKeyID, err = result.LastInsertId()
|
||||
if err != nil {
|
||||
return key, err
|
||||
}
|
||||
|
||||
return key, nil
|
||||
}
|
||||
826
data/datamysql/ride.go
Normal file
826
data/datamysql/ride.go
Normal file
@@ -0,0 +1,826 @@
|
||||
package datamysql
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"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"
|
||||
)
|
||||
|
||||
// rideRepo maps methods to database
|
||||
type rideRepo struct {
|
||||
conn executor
|
||||
}
|
||||
|
||||
func newRideRepo(conn executor) *rideRepo {
|
||||
return &rideRepo{
|
||||
conn: conn,
|
||||
}
|
||||
}
|
||||
|
||||
func (c *rideRepo) getQuery() string {
|
||||
const query = `SELECT
|
||||
a.ride_id,
|
||||
a.ride_uuid,
|
||||
b.user_id,
|
||||
b.user_uuid,
|
||||
b.name,
|
||||
b.member,
|
||||
c.ride_status_id,
|
||||
c.ride_status,
|
||||
c.key ride_status_key,
|
||||
d.ride_type_id,
|
||||
d.value ride_type,
|
||||
d.key ride_type_key,
|
||||
a.notes,
|
||||
e.first_name,
|
||||
e.last_name,
|
||||
e.image_url,
|
||||
e.phone_number,
|
||||
e.internal_user_id,
|
||||
IFNULL(f.name, '') driver_name,
|
||||
IFNULL(f.phone_number, '') driver_phone_number,
|
||||
IFNULL(f.image_url, '') driver_image_url,
|
||||
IFNULL(f.rating, '') driver_rating,
|
||||
IFNULL(g.color, '') vehicle_color,
|
||||
IFNULL(g.image_url, '') vehicle_image_url,
|
||||
IFNULL(g.license_plate, '') vehicle_license_plate,
|
||||
IFNULL(g.license_plate_state, '') vehicle_license_state,
|
||||
IFNULL(g.make, '') vehicle_make,
|
||||
IFNULL(g.model, '') vehicle_model,
|
||||
IFNULL(g.year, 0) vehicle_year,
|
||||
h.origin_name,
|
||||
h.origin_address,
|
||||
h.origin_lat,
|
||||
h.origin_lng,
|
||||
h.destination_name,
|
||||
h.destination_address,
|
||||
h.destination_lat,
|
||||
h.destination_lng,
|
||||
IFNULL(h.route_kml, '') route_kml,
|
||||
IFNULL(h.distance, 0) distance,
|
||||
IFNULL(h.duration, 0) duration,
|
||||
IFNULL(h.eta, 0) eta,
|
||||
a.pickup_time,
|
||||
a.visit_date,
|
||||
a.visit_time,
|
||||
a.ride_internal_id,
|
||||
a.visit_id,
|
||||
i.visit_uuid,
|
||||
IFNULL(i.pickup_id, '') visit_pickup_id,
|
||||
IFNULL(i.pickup_address_id, 0) pickup_address_id,
|
||||
IFNULL(i.address_id, 0) address_id,
|
||||
IFNULL(i.provider_id, 0) provider_id,
|
||||
IFNULL(o.provider_uuid, '') provider_uuid,
|
||||
IFNULL(o.provider_internal_id, '') provider_internal_id,
|
||||
IFNULL(o.provider_muk_id, '') provider_muk_id,
|
||||
IFNULL(o.provider_name, '') provider_name,
|
||||
-- i.pickup_name visit_pickup_name,
|
||||
-- i.pickup_address visit_pickup_address,
|
||||
-- i.pickup_lat visit_pickup_lat,
|
||||
-- i.pickup_lng visit_pickup_lng,
|
||||
-- IFNULL(i.destination_id, '') visit_destination_id,
|
||||
-- i.destination_name visit_destination_name,
|
||||
-- i.destination_address visit_destination_address,
|
||||
-- i.destination_lat visit_destination_lat,
|
||||
-- i.destination_lng visit_destination_lng,
|
||||
IFNULL(i.visit_external_id, '') visit_external_id,
|
||||
i.created_user_id,
|
||||
j.user_uuid created_user_uuid,
|
||||
j.name created_name,
|
||||
IFNULL(k.phone_number, '') created_user_phone_number,
|
||||
IFNULL(k.email, '') created_user_email,
|
||||
IFNULL(l.phone_number, '') user_phone_number,
|
||||
IFNULL(l.email, '') user_email,
|
||||
a.create_date,
|
||||
a.update_date,
|
||||
m.trip_type_id,
|
||||
m.trip_type_key,
|
||||
m.trip_type,
|
||||
n.trip_type_id visit_trip_type_id,
|
||||
n.trip_type_key visit_trip_type_key,
|
||||
n.trip_type visit_trip_type_key,
|
||||
i.return_date
|
||||
FROM tab_ride a
|
||||
INNER JOIN tab_user b
|
||||
ON a.user_id = b.user_id
|
||||
INNER JOIN tab_ride_status c
|
||||
ON c.ride_status_id = a.ride_status_id
|
||||
INNER JOIN tab_ride_type d
|
||||
ON d.ride_type_id = a.ride_type_id
|
||||
INNER JOIN tab_ride_passenger e
|
||||
ON e.ride_id = a.ride_id
|
||||
LEFT JOIN tab_ride_driver f
|
||||
ON f.ride_id = a.ride_id
|
||||
LEFT JOIN tab_ride_vehicle g
|
||||
ON g.ride_id = a.ride_id
|
||||
INNER JOIN tab_ride_route h
|
||||
ON h.ride_id = a.ride_id
|
||||
INNER JOIN tab_visit i
|
||||
ON i.visit_id = a.visit_id
|
||||
INNER JOIN tab_user j
|
||||
ON j.user_id = i.created_user_id
|
||||
INNER JOIN tab_login k
|
||||
ON k.user_id = j.user_id
|
||||
INNER JOIN tab_login l
|
||||
ON l.user_id = a.user_id
|
||||
INNER JOIN tab_trip_type m
|
||||
ON m.trip_type_id = a.trip_type_id
|
||||
INNER JOIN tab_trip_type n
|
||||
ON n.trip_type_id = i.trip_type_id
|
||||
INNER JOIN tab_provider o
|
||||
ON i.provider_id = o.provider_id `
|
||||
|
||||
return query
|
||||
}
|
||||
|
||||
func (c *rideRepo) 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":
|
||||
switch p.Organization.Type.Key {
|
||||
case "techsupport", "bcbsi", "bcbsa", "plan":
|
||||
return
|
||||
case "provider":
|
||||
query = `INNER JOIN viw_visit_provider o ON a.ride_id = o.ride_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 *rideRepo) Update(hook entity.WebhookResponse, user entity.User) (retVal entity.Ride, err error) {
|
||||
oldRide, err := c.GetByUUID(hook.Ride.UUID, user)
|
||||
if err != nil {
|
||||
return retVal, err
|
||||
}
|
||||
|
||||
retVal, err = c.updateHeader(hook.Ride)
|
||||
if err != nil {
|
||||
return retVal, err
|
||||
}
|
||||
|
||||
retVal, err = c.updateLocation(hook.Ride)
|
||||
if err != nil {
|
||||
return retVal, err
|
||||
}
|
||||
|
||||
// retVal, err = c.updatePassenger(hook.Ride)
|
||||
// if err != nil {
|
||||
// return retVal, err
|
||||
// }
|
||||
|
||||
if oldRide.Driver.Name != "" {
|
||||
retVal, err = c.updateDriver(hook.Ride)
|
||||
} else {
|
||||
retVal, err = c.saveDriver(hook.Ride)
|
||||
}
|
||||
if err != nil {
|
||||
return retVal, err
|
||||
}
|
||||
|
||||
if oldRide.Vehicle.LicensePlate != "" {
|
||||
retVal, err = c.updateVehicle(hook.Ride)
|
||||
} else {
|
||||
retVal, err = c.saveVehicle(hook.Ride)
|
||||
}
|
||||
if err != nil {
|
||||
return retVal, err
|
||||
}
|
||||
|
||||
go func() {
|
||||
err := c.saveHistory(hook)
|
||||
if err != nil {
|
||||
fmt.Println("Error to save history: " + err.Error())
|
||||
}
|
||||
}()
|
||||
|
||||
return retVal, nil
|
||||
}
|
||||
|
||||
func (c *rideRepo) updateVehicle(ride entity.Ride) (retVal entity.Ride, err error) {
|
||||
const (
|
||||
query = `UPDATE tab_ride_vehicle
|
||||
SET
|
||||
color = ?,
|
||||
image_url = ?,
|
||||
license_plate = ?,
|
||||
license_plate_state = ?,
|
||||
make = ?,
|
||||
model = ?,
|
||||
year = ?
|
||||
WHERE ride_id = ?;`
|
||||
)
|
||||
|
||||
retVal = ride
|
||||
_, err = c.conn.Exec(query, ride.Vehicle.Color, ride.Vehicle.ImageURL, ride.Vehicle.LicensePlate, ride.Vehicle.LicensePlateState, ride.Vehicle.Make, ride.Vehicle.Model, ride.Vehicle.Year, ride.ID)
|
||||
if err != nil {
|
||||
return retVal, err
|
||||
}
|
||||
|
||||
return retVal, nil
|
||||
}
|
||||
|
||||
func (c *rideRepo) updateDriver(ride entity.Ride) (retVal entity.Ride, err error) {
|
||||
const (
|
||||
query = `UPDATE tab_ride_driver
|
||||
SET
|
||||
name = ?,
|
||||
image_url = ?,
|
||||
phone_number = ?,
|
||||
rating = ?
|
||||
WHERE ride_id = ?;`
|
||||
)
|
||||
|
||||
retVal = ride
|
||||
_, err = c.conn.Exec(query, ride.Driver.Name, ride.Driver.ImageURL, ride.Driver.PhoneNumber, ride.Driver.Rating, ride.ID)
|
||||
if err != nil {
|
||||
return retVal, err
|
||||
}
|
||||
|
||||
return retVal, nil
|
||||
}
|
||||
|
||||
func (c *rideRepo) updatePassenger(ride entity.Ride) (retVal entity.Ride, err error) {
|
||||
const (
|
||||
query = `UPDATE tab_ride_passenger
|
||||
SET
|
||||
first_name = ?,
|
||||
last_name = ?,
|
||||
image_url = ?,
|
||||
phone_number = ?,
|
||||
internal_user_id = ?
|
||||
WHERE ride_id = ?;`
|
||||
)
|
||||
|
||||
retVal = ride
|
||||
_, err = c.conn.Exec(query, ride.Passenger.FirstName, ride.Passenger.LastName, ride.Passenger.ImageURL, ride.Passenger.PhoneNumber, ride.Passenger.InternalID, ride.ID)
|
||||
if err != nil {
|
||||
return retVal, err
|
||||
}
|
||||
|
||||
return retVal, nil
|
||||
}
|
||||
|
||||
func (c *rideRepo) updateLocation(ride entity.Ride) (retVal entity.Ride, err error) {
|
||||
query := `UPDATE tab_ride_route
|
||||
SET
|
||||
origin_address = ?,
|
||||
origin_lat = ?,
|
||||
origin_lng = ?,
|
||||
destination_address = ?,
|
||||
destination_lat = ?,
|
||||
destination_lng = ?,
|
||||
route_kml = ?,
|
||||
distance = ?,
|
||||
duration = ?,
|
||||
eta = ?`
|
||||
where := ` WHERE ride_id = ?;`
|
||||
|
||||
retVal = ride
|
||||
params := make([]interface{}, 0)
|
||||
params = append(params, ride.Route.Origin.Address, ride.Route.Origin.Latitude, ride.Route.Origin.Longitude, ride.Route.Destination.Address, ride.Route.Destination.Latitude, ride.Route.Destination.Longitude, ride.Route.RouteKML, ride.Route.Distance, ride.Route.Duration, ride.Route.ETA)
|
||||
|
||||
if retVal.Route.Origin.Name != "" {
|
||||
query += " , origin_name = ? "
|
||||
params = append(params, ride.Route.Origin.Name)
|
||||
}
|
||||
|
||||
if retVal.Route.Destination.Name != "" {
|
||||
query += " , destination_name = ? "
|
||||
params = append(params, ride.Route.Destination.Name)
|
||||
}
|
||||
params = append(params, ride.ID)
|
||||
|
||||
_, err = c.conn.Exec(query+where, params...)
|
||||
if err != nil {
|
||||
return retVal, err
|
||||
}
|
||||
|
||||
return retVal, nil
|
||||
}
|
||||
|
||||
func (c *rideRepo) updateHeader(ride entity.Ride) (retVal entity.Ride, err error) {
|
||||
const (
|
||||
statusQuery = "SELECT ride_status_id FROM tab_ride_status WHERE `key` = ?"
|
||||
query = `UPDATE tab_ride
|
||||
SET
|
||||
ride_status_id = ?,
|
||||
ride_type_id = ?,
|
||||
ride_internal_id = ?,
|
||||
request_date = ?,
|
||||
request_ms = ?,
|
||||
generate_date = ?,
|
||||
generate_ms = ?,
|
||||
route_kml = ?,
|
||||
notes = ?,
|
||||
primetime_percentage = ?,
|
||||
pickup_time = ?,
|
||||
visit_date = ?,
|
||||
visit_time = ?,
|
||||
visit_id = ?
|
||||
WHERE ride_uuid = ?;`
|
||||
)
|
||||
|
||||
row := c.conn.QueryRow(statusQuery, ride.Status.Key)
|
||||
err = row.Scan(&ride.Status.ID)
|
||||
if err != nil {
|
||||
fmt.Println("Error to get status")
|
||||
return retVal, err
|
||||
}
|
||||
|
||||
retVal = ride
|
||||
_, err = c.conn.Exec(query, ride.Status.ID, ride.Type.ID, ride.InternalID, ride.RequestDate, ride.RequestMiliseconds, ride.GenerateDate, ride.GenerateMiliseconds, ride.Route.RouteKML, ride.Note, ride.PrimetimePercentage, ride.PickupTime, ride.VisitDate, ride.VisitTime, ride.Visit.ID, ride.UUID)
|
||||
if err != nil {
|
||||
return retVal, err
|
||||
}
|
||||
|
||||
return ride, nil
|
||||
}
|
||||
|
||||
func (c *rideRepo) Save(ride entity.Ride) (retVal entity.Ride, err error) {
|
||||
retVal, err = c.saveHeader(ride)
|
||||
if err != nil {
|
||||
fmt.Println("Error to save header")
|
||||
return retVal, err
|
||||
}
|
||||
|
||||
retVal, err = c.saveLocation(retVal)
|
||||
if err != nil {
|
||||
fmt.Println("Error to save location")
|
||||
return retVal, err
|
||||
}
|
||||
|
||||
retVal, err = c.savePassenger(retVal)
|
||||
if err != nil {
|
||||
fmt.Println("Error to save passenger")
|
||||
return retVal, err
|
||||
}
|
||||
|
||||
retVal, err = c.saveDriver(retVal)
|
||||
if err != nil {
|
||||
fmt.Println("Error to save driver")
|
||||
return retVal, err
|
||||
}
|
||||
|
||||
retVal, err = c.saveVehicle(retVal)
|
||||
if err != nil {
|
||||
fmt.Println("Error to save vehicle")
|
||||
return retVal, err
|
||||
}
|
||||
|
||||
go func() {
|
||||
hook := entity.WebhookResponse{
|
||||
Ride: retVal,
|
||||
}
|
||||
err = c.saveHistory(hook)
|
||||
if err != nil {
|
||||
fmt.Println("Error to save history: ", err.Error())
|
||||
}
|
||||
}()
|
||||
|
||||
return retVal, err
|
||||
}
|
||||
|
||||
func (c *rideRepo) saveHistory(hook entity.WebhookResponse) error {
|
||||
rideHistoryID, err := c.saveHistoryHeader(hook)
|
||||
if err != nil {
|
||||
fmt.Println("Error to save header history")
|
||||
return err
|
||||
}
|
||||
|
||||
if err = c.saveLocationHistory(rideHistoryID, hook.Ride.Route); err != nil {
|
||||
fmt.Println("Error to save location history")
|
||||
return err
|
||||
}
|
||||
|
||||
if err = c.savePassengerHistory(rideHistoryID, hook.Ride.Passenger); err != nil {
|
||||
fmt.Println("Error to save passenger history")
|
||||
return err
|
||||
}
|
||||
|
||||
if err = c.saveDriverHistory(rideHistoryID, hook.Ride.Driver); err != nil {
|
||||
fmt.Println("Error to save driver history")
|
||||
return err
|
||||
}
|
||||
|
||||
if err = c.saveVehicleHistory(rideHistoryID, hook.Ride.Vehicle); err != nil {
|
||||
fmt.Println("Error to save vehicle history")
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *rideRepo) saveVehicleHistory(rideHistoryID int64, vehicle entity.RideVehicle) error {
|
||||
const (
|
||||
query = "INSERT INTO tab_ride_vehicle_history(ride_history_id,color,image_url,license_plate,license_plate_state,make,model,`year`) VALUES(?,?,?,?,?,?,?,?);"
|
||||
)
|
||||
|
||||
if vehicle.Make != "" && vehicle.Model != "" && vehicle.Color != "" && vehicle.Year > 0 {
|
||||
_, err := c.conn.Exec(query, rideHistoryID, vehicle.Color, vehicle.ImageURL, vehicle.LicensePlate, vehicle.LicensePlateState, vehicle.Make, vehicle.Model, vehicle.Year)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *rideRepo) saveDriverHistory(rideHistoryID int64, driver entity.RideDriver) error {
|
||||
const (
|
||||
query = "INSERT INTO tab_ride_driver_history(ride_history_id,name,image_url,phone_number,rating) VALUES(?,?,?,?,?);"
|
||||
)
|
||||
|
||||
if driver.Name != "" && driver.PhoneNumber != "" {
|
||||
_, err := c.conn.Exec(query, rideHistoryID, driver.Name, driver.ImageURL, driver.PhoneNumber, driver.Rating)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *rideRepo) savePassengerHistory(rideHistoryID int64, passenger entity.RidePassenger) error {
|
||||
const (
|
||||
query = "INSERT INTO tab_ride_passenger_history(ride_history_id,first_name,last_name,image_url,phone_number,internal_user_id) VALUES(?,?,?,?,?,?)"
|
||||
)
|
||||
|
||||
_, err := c.conn.Exec(query, rideHistoryID, passenger.FirstName, passenger.LastName, "", passenger.PhoneNumber, passenger.InternalID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *rideRepo) saveLocationHistory(rideHistoryID int64, route entity.RideRoute) error {
|
||||
const (
|
||||
query = `INSERT INTO tab_ride_route_history(ride_history_id,origin_name,origin_address,origin_lat,origin_lng,destination_name,destination_address,destination_lat,destination_lng,route_kml,distance,duration,eta)
|
||||
VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?);`
|
||||
)
|
||||
|
||||
if route.Origin.Latitude != 0 && route.Origin.Longitude != 0 && route.Destination.Latitude != 0 && route.Destination.Longitude != 0 {
|
||||
_, err := c.conn.Exec(query, rideHistoryID, route.Origin.Name, route.Origin.Address, route.Origin.Latitude, route.Origin.Longitude, route.Destination.Name, route.Destination.Address, route.Destination.Latitude, route.Destination.Longitude, route.RouteKML, route.Distance, route.Duration, route.ETA)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *rideRepo) saveHistoryHeader(hook entity.WebhookResponse) (int64, error) {
|
||||
const (
|
||||
query = `INSERT INTO tab_ride_history(ride_history_uuid,ride_id,event_id,href,occurred_at,event_type,ride_internal_id,ride_status_id,ride_type_id,request_date,request_ms,generate_date,generate_ms,route_kml,notes, primetime_percentage, pickup_time, visit_date, visit_time, visit_id)
|
||||
VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?);`
|
||||
)
|
||||
|
||||
UUID, _ := uuid.NewV4()
|
||||
sUUID := UUID.String()
|
||||
|
||||
if hook.OccurredAt.IsZero() {
|
||||
hook.OccurredAt = time.Now()
|
||||
}
|
||||
|
||||
results, err := c.conn.Exec(query, sUUID, hook.Ride.ID, hook.EventID, hook.HREF, hook.OccurredAt, hook.EventType, hook.Ride.InternalID, hook.Ride.Status.ID, hook.Ride.Type.ID, hook.Ride.RequestDate, hook.Ride.RequestMiliseconds, hook.Ride.GenerateDate, hook.Ride.GenerateMiliseconds, hook.Ride.Route.RouteKML, hook.Ride.Note, hook.Ride.PrimetimePercentage, hook.Ride.PickupTime, hook.Ride.VisitDate, hook.Ride.VisitTime, hook.Ride.Visit.ID)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
return results.LastInsertId()
|
||||
}
|
||||
|
||||
func (c *rideRepo) saveHeader(ride entity.Ride) (retVal entity.Ride, err error) {
|
||||
const (
|
||||
dataQuery = `SELECT
|
||||
a.user_id user_id,
|
||||
a.name,
|
||||
a.member,
|
||||
b.ride_status_id,
|
||||
b.ride_status,
|
||||
c.ride_type_id,
|
||||
c.value ride_type,
|
||||
d.user_id created_user_id,
|
||||
d.name created_name,
|
||||
IFNULL(d.member, '') created_member,
|
||||
e.trip_type_id,
|
||||
e.trip_type_key,
|
||||
e.trip_type
|
||||
FROM tab_user a,
|
||||
tab_ride_status b,
|
||||
tab_ride_type c,
|
||||
tab_user d,
|
||||
tab_trip_type e
|
||||
WHERE
|
||||
a.user_uuid = ?
|
||||
AND b.key = ?
|
||||
AND c.key = ?
|
||||
AND d.user_uuid = ?
|
||||
AND e.trip_type_key = ?;`
|
||||
|
||||
query = `INSERT INTO tab_ride(ride_uuid, user_id, ride_status_id, ride_type_id, ride_internal_id, request_date, request_ms, generate_date, generate_ms, notes, primetime_percentage, pickup_time, visit_date, visit_time, visit_id, created_user_id, trip_type_id)
|
||||
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);`
|
||||
)
|
||||
|
||||
retVal = ride
|
||||
UUID, _ := uuid.NewV4()
|
||||
retVal.UUID = UUID.String()
|
||||
|
||||
if retVal.Status.Key == "" {
|
||||
retVal.Status.Key = "accepted"
|
||||
}
|
||||
|
||||
if retVal.Type.Key == "" {
|
||||
retVal.Type.Key = "lyft"
|
||||
}
|
||||
|
||||
row := c.conn.QueryRow(dataQuery, retVal.User.UUID, retVal.Status.Key, retVal.Type.Key, retVal.CreatedUser.UUID, retVal.TripType.Key)
|
||||
if err = row.Scan(&retVal.User.ID, &retVal.User.Name, &retVal.User.Member, &retVal.Status.ID, &retVal.Status.Value, &retVal.Type.ID, &retVal.Type.Value, &retVal.CreatedUser.ID, &retVal.CreatedUser.Name, &retVal.CreatedUser.Member, &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.User.ID, retVal.Status.ID, retVal.Type.ID, retVal.InternalID, retVal.RequestDate, retVal.RequestMiliseconds, retVal.GenerateDate, retVal.GenerateMiliseconds, retVal.Note, retVal.PrimetimePercentage, retVal.PickupTime, retVal.VisitDate, retVal.VisitTime, retVal.Visit.ID, retVal.CreatedUser.ID, retVal.TripType.ID)
|
||||
if err != nil {
|
||||
fmt.Println("Error: ", err.Error())
|
||||
return retVal, err
|
||||
}
|
||||
|
||||
var ID int64
|
||||
ID, err = results.LastInsertId()
|
||||
if err != nil {
|
||||
fmt.Println("Error Getting the ID: ", err.Error())
|
||||
return retVal, err
|
||||
}
|
||||
|
||||
retVal.ID = ID
|
||||
return retVal, nil
|
||||
}
|
||||
|
||||
func (c *rideRepo) saveLocation(ride entity.Ride) (retVal entity.Ride, err error) {
|
||||
const (
|
||||
query = `INSERT INTO tab_ride_route(ride_id,origin_name,origin_address,origin_lat,origin_lng,destination_name,destination_address,destination_lat,destination_lng,route_kml,distance,duration,eta)
|
||||
VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?);`
|
||||
)
|
||||
|
||||
retVal = ride
|
||||
results, err := c.conn.Exec(query, retVal.ID, retVal.Route.Origin.Name, retVal.Route.Origin.Address, retVal.Route.Origin.Latitude, retVal.Route.Origin.Longitude, retVal.Route.Destination.Name, retVal.Route.Destination.Address, retVal.Route.Destination.Latitude, retVal.Route.Destination.Longitude, retVal.Route.RouteKML, retVal.Route.Distance, retVal.Route.Duration, retVal.Route.ETA)
|
||||
if err != nil {
|
||||
return retVal, err
|
||||
}
|
||||
|
||||
var ID int64
|
||||
ID, err = results.LastInsertId()
|
||||
if err != nil {
|
||||
fmt.Println("Error Getting the ID: ", err.Error())
|
||||
return retVal, err
|
||||
}
|
||||
|
||||
retVal.Route.ID = ID
|
||||
return retVal, nil
|
||||
}
|
||||
|
||||
func (c *rideRepo) savePassenger(ride entity.Ride) (retVal entity.Ride, err error) {
|
||||
const (
|
||||
query = `INSERT INTO tab_ride_passenger(ride_id,first_name,last_name,image_url,phone_number,internal_user_id)
|
||||
VALUES(?,?,?,?,?,?);`
|
||||
)
|
||||
|
||||
retVal = ride
|
||||
results, err := c.conn.Exec(query, retVal.ID, ride.Passenger.FirstName, ride.Passenger.LastName, ride.Passenger.ImageURL, ride.Passenger.PhoneNumber, ride.Passenger.InternalID)
|
||||
if err != nil {
|
||||
return retVal, err
|
||||
}
|
||||
|
||||
var ID int64
|
||||
ID, err = results.LastInsertId()
|
||||
if err != nil {
|
||||
fmt.Println("Error Getting the ID: ", err.Error())
|
||||
return retVal, err
|
||||
}
|
||||
|
||||
retVal.Passenger.ID = ID
|
||||
return retVal, nil
|
||||
}
|
||||
|
||||
func (c *rideRepo) saveDriver(ride entity.Ride) (retVal entity.Ride, err error) {
|
||||
const (
|
||||
query = "INSERT INTO tab_ride_driver(ride_id,`name`,image_url,phone_number,rating) VALUES(?,?,?,?,?);"
|
||||
)
|
||||
|
||||
retVal = ride
|
||||
if retVal.Driver.Name != "" && retVal.Driver.PhoneNumber != "" {
|
||||
results, err := c.conn.Exec(query, retVal.ID, ride.Driver.Name, ride.Driver.ImageURL, ride.Driver.PhoneNumber, ride.Driver.Rating)
|
||||
if err != nil {
|
||||
return retVal, err
|
||||
}
|
||||
|
||||
var ID int64
|
||||
ID, err = results.LastInsertId()
|
||||
if err != nil {
|
||||
fmt.Println("Error Getting the ID: ", err.Error())
|
||||
return retVal, err
|
||||
}
|
||||
retVal.Driver.ID = ID
|
||||
}
|
||||
return retVal, nil
|
||||
}
|
||||
|
||||
func (c *rideRepo) saveVehicle(ride entity.Ride) (retVal entity.Ride, err error) {
|
||||
const (
|
||||
query = "INSERT INTO tab_ride_vehicle(ride_id,color,image_url,license_plate,license_plate_state,make,model,`year`) VALUES(?,?,?,?,?,?,?,?);"
|
||||
)
|
||||
|
||||
retVal = ride
|
||||
if retVal.Vehicle.Color != "" && retVal.Vehicle.LicensePlate != "" && retVal.Vehicle.Make != "" && retVal.Vehicle.Model != "" && retVal.Vehicle.Year > 0 {
|
||||
results, err := c.conn.Exec(query, retVal.ID, ride.Vehicle.Color, ride.Vehicle.ImageURL, ride.Vehicle.LicensePlate, ride.Vehicle.LicensePlateState, ride.Vehicle.Make, ride.Vehicle.Model, ride.Vehicle.Year)
|
||||
if err != nil {
|
||||
return retVal, err
|
||||
}
|
||||
|
||||
var ID int64
|
||||
ID, err = results.LastInsertId()
|
||||
if err != nil {
|
||||
fmt.Println("Error Getting the ID: ", err.Error())
|
||||
return retVal, err
|
||||
}
|
||||
|
||||
retVal.Vehicle.ID = ID
|
||||
}
|
||||
return retVal, nil
|
||||
}
|
||||
|
||||
func (c *rideRepo) GetByUUID(uuid string, user entity.User) (entity.Ride, error) {
|
||||
query, where, err := c.getProfileQuery(user)
|
||||
if err != nil {
|
||||
return entity.Ride{}, err
|
||||
}
|
||||
|
||||
query = c.getQuery() + query + " WHERE a.ride_uuid = ? " + where
|
||||
return c.parseEntity(c.conn.QueryRow(query, uuid))
|
||||
}
|
||||
|
||||
func (c *rideRepo) GetByID(id int64, user entity.User) (entity.Ride, error) {
|
||||
query, where, err := c.getProfileQuery(user)
|
||||
if err != nil {
|
||||
return entity.Ride{}, err
|
||||
}
|
||||
|
||||
query = c.getQuery() + query + " WHERE a.ride_id = ? " + where
|
||||
return c.parseEntity(c.conn.QueryRow(query, id))
|
||||
}
|
||||
|
||||
func (c *rideRepo) GetByUUIDAndUserUUID(UUID string, userUUID string) (entity.Ride, error) {
|
||||
return c.parseEntity(c.conn.QueryRow(c.getQuery()+" WHERE a.ride_uuid = ? AND b.user_uuid = ?", UUID, userUUID))
|
||||
}
|
||||
|
||||
func (c *rideRepo) GetLastRideByPhoneNumber(phoneNumber string) (entity.Ride, error) {
|
||||
query := c.getQuery() + ` WHERE c.ride_status IN ('accepted', 'arrived', 'scheduled', 'pending')
|
||||
AND l.phone_number = ?
|
||||
ORDER BY a.create_date DESC
|
||||
LIMIT 1;`
|
||||
|
||||
return c.parseEntity(c.conn.QueryRow(query, phoneNumber))
|
||||
}
|
||||
|
||||
func (c *rideRepo) GetLastRideByDriversNumber(phoneNumber string) (entity.Ride, error) {
|
||||
query := c.getQuery() + ` WHERE c.ride_status IN ('accepted', 'arrived', 'scheduled', 'pending')
|
||||
AND IFNULL(f.phone_number, '') = ?
|
||||
ORDER BY a.create_date DESC
|
||||
LIMIT 1;`
|
||||
|
||||
return c.parseEntity(c.conn.QueryRow(query, phoneNumber))
|
||||
}
|
||||
|
||||
func (c *rideRepo) GetByInternalID(internalID string) (entity.Ride, error) {
|
||||
return c.parseEntity(c.conn.QueryRow(c.getQuery()+" WHERE a.ride_internal_id = ?", internalID))
|
||||
}
|
||||
|
||||
func (c *rideRepo) GetByInternalPassengerID(internalPassengerID string) (entity.Ride, error) {
|
||||
return c.parseEntity(c.conn.QueryRow(c.getQuery()+" WHERE e.internal_user_id = ?", internalPassengerID))
|
||||
}
|
||||
|
||||
func (c *rideRepo) GetByUserID(userID int64, user entity.User) ([]entity.Ride, error) {
|
||||
query, where, err := c.getProfileQuery(user)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
query = c.getQuery() + query + " WHERE b.user_id = ? " + where
|
||||
|
||||
return c.parseSet(c.conn.Query(query, userID))
|
||||
}
|
||||
|
||||
func (c *rideRepo) GetByUserUUID(userUUID string, user entity.User) ([]entity.Ride, error) {
|
||||
query, where, err := c.getProfileQuery(user)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
query = c.getQuery() + query + " WHERE b.user_uuid = ? " + where
|
||||
|
||||
return c.parseSet(c.conn.Query(query, userUUID))
|
||||
}
|
||||
|
||||
func (c *rideRepo) GetByVisitUUID(visitUUID string, user entity.User) ([]entity.Ride, error) {
|
||||
query, where, err := c.getProfileQuery(user)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
query = c.getQuery() + query + " WHERE b.user_id = ? " + where
|
||||
|
||||
return c.parseSet(c.conn.Query(query, visitUUID))
|
||||
}
|
||||
|
||||
func (c *rideRepo) GetByVisitUUIDAndTripType(visitUUID string, tripTypeKey string, user entity.User) (entity.Ride, error) {
|
||||
query, where, err := c.getProfileQuery(user)
|
||||
if err != nil {
|
||||
return entity.Ride{}, err
|
||||
}
|
||||
|
||||
query = c.getQuery() + query + " WHERE i.visit_uuid = ? AND m.trip_type_key = ? " + where
|
||||
return c.parseEntity(c.conn.QueryRow(query, visitUUID, tripTypeKey))
|
||||
}
|
||||
|
||||
func (c *rideRepo) parseSet(rows *sql.Rows, err error) ([]entity.Ride, error) {
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err)
|
||||
}
|
||||
result := make([]entity.Ride, 0)
|
||||
for rows.Next() {
|
||||
entity, err := c.parseEntity(rows)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err)
|
||||
}
|
||||
result = append(result, entity)
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func (c *rideRepo) parseEntity(row scanner) (r entity.Ride, err error) {
|
||||
var returnDate mysql.NullTime
|
||||
|
||||
err = row.Scan(&r.ID, &r.UUID, &r.User.ID, &r.User.UUID, &r.User.Name, &r.User.Member, &r.Status.ID, &r.Status.Value, &r.Status.Key, &r.Type.ID, &r.Type.Value, &r.Type.Key, &r.Note, &r.Passenger.FirstName, &r.Passenger.LastName, &r.Passenger.ImageURL, &r.Passenger.PhoneNumber, &r.Passenger.InternalID, &r.Driver.Name, &r.Driver.PhoneNumber, &r.Driver.ImageURL, &r.Driver.Rating, &r.Vehicle.Color, &r.Vehicle.ImageURL, &r.Vehicle.LicensePlate, &r.Vehicle.LicensePlateState, &r.Vehicle.Make, &r.Vehicle.Model, &r.Vehicle.Year, &r.Route.Origin.Name, &r.Route.Origin.Address, &r.Route.Origin.Latitude, &r.Route.Origin.Longitude, &r.Route.Destination.Name, &r.Route.Destination.Address, &r.Route.Destination.Latitude, &r.Route.Destination.Longitude, &r.Route.RouteKML, &r.Route.Distance, &r.Route.Duration, &r.Route.ETA, &r.PickupTime, &r.VisitDate, &r.VisitTime, &r.InternalID, &r.Visit.ID, &r.Visit.UUID, &r.Visit.Pickup.ID, &r.Visit.PickupAddressID, &r.Visit.DestinationAddressID, &r.Visit.Provider.ProviderID, &r.Visit.Provider.ProviderUUID, &r.Visit.Provider.InternalID, &r.Visit.Provider.MukID, &r.Visit.Provider.Name, &r.Visit.ExternalID, &r.Visit.CreatedUser.ID, &r.Visit.CreatedUser.UUID, &r.Visit.CreatedUser.Name, &r.Visit.CreatedUser.PhoneNumber, &r.Visit.CreatedUser.Email, &r.User.PhoneNumber, &r.User.Email, &r.Created, &r.Updated, &r.TripType.ID, &r.TripType.Key, &r.TripType.Value, &r.Visit.TripType.ID, &r.Visit.TripType.Key, &r.Visit.TripType.Value, &returnDate)
|
||||
if err != nil {
|
||||
return r, errors.Wrap(err)
|
||||
}
|
||||
|
||||
r.CreatedUser = r.Visit.CreatedUser
|
||||
if returnDate.Valid {
|
||||
r.Visit.ReturnDate = &returnDate.Time
|
||||
}
|
||||
|
||||
return r, nil
|
||||
}
|
||||
|
||||
func (c *rideRepo) UpdateStatus(rideUUID string, status string) error {
|
||||
const (
|
||||
statusQuery = "SELECT ride_status_id FROM tab_ride_status WHERE `key` = ?"
|
||||
query = "UPDATE tab_ride SET ride_status_id = ? WHERE ride_uuid = ?"
|
||||
)
|
||||
|
||||
var rideStatusID int64
|
||||
row := c.conn.QueryRow(statusQuery, status)
|
||||
err := row.Scan(&rideStatusID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
_, err = c.conn.Exec(query, rideStatusID, rideUUID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *rideRepo) GetAll(user entity.User) ([]entity.Ride, error) {
|
||||
query, where, err := c.getProfileQuery(user)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
query = c.getQuery() + query + " WHERE 1 = 1 AND b.active = 1 " + where
|
||||
|
||||
return c.parseSet(c.conn.Query(query))
|
||||
}
|
||||
87
data/datamysql/transaction.go
Normal file
87
data/datamysql/transaction.go
Normal file
@@ -0,0 +1,87 @@
|
||||
package datamysql
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
|
||||
"bitbucket.org/nemt/nemt-portal-api/domain/contract"
|
||||
"bitbucket.org/nemt/nemt-portal-api/infra/errors"
|
||||
)
|
||||
|
||||
type transaction struct {
|
||||
tx *sql.Tx
|
||||
users *userRepo
|
||||
rides *rideRepo
|
||||
visits *visitRepo
|
||||
provider *providerRepo
|
||||
notification *notificationRepo
|
||||
profile *profileRepo
|
||||
organization *organizationRepo
|
||||
}
|
||||
|
||||
func newTransaction(tx *sql.Tx) *transaction {
|
||||
|
||||
t := new(transaction)
|
||||
|
||||
t.tx = tx
|
||||
t.users = newUserRepo(tx)
|
||||
t.rides = newRideRepo(tx)
|
||||
t.visits = newVisitRepo(tx)
|
||||
t.provider = newProviderRepo(tx)
|
||||
|
||||
return t
|
||||
}
|
||||
|
||||
// Users returns the users set
|
||||
func (t transaction) Users() contract.UserRepo {
|
||||
return t.users
|
||||
}
|
||||
|
||||
// Rides returns the rides set
|
||||
func (t transaction) Rides() contract.RideRepo {
|
||||
return t.rides
|
||||
}
|
||||
|
||||
// Rides returns the rides set
|
||||
func (t transaction) Visits() contract.VisitRepo {
|
||||
return t.visits
|
||||
}
|
||||
|
||||
// Provider returns the rides set
|
||||
func (t transaction) Provider() contract.ProviderRepo {
|
||||
return t.provider
|
||||
}
|
||||
|
||||
// Provider returns the rides set
|
||||
func (t transaction) Profile() contract.ProfileRepo {
|
||||
return t.profile
|
||||
}
|
||||
|
||||
// Provider returns the rides set
|
||||
func (t transaction) Notification() contract.NotificationRepo {
|
||||
return t.notification
|
||||
}
|
||||
|
||||
// Provider returns the rides set
|
||||
func (t transaction) Organization() contract.OrganizationRepo {
|
||||
return t.organization
|
||||
}
|
||||
|
||||
func (t *transaction) Commit() error {
|
||||
|
||||
err := t.tx.Commit()
|
||||
if err != nil {
|
||||
return errors.Wrap(err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (t *transaction) Rollback() error {
|
||||
|
||||
err := t.tx.Rollback()
|
||||
if err != nil {
|
||||
return errors.Wrap(err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
825
data/datamysql/user.go
Normal file
825
data/datamysql/user.go
Normal file
@@ -0,0 +1,825 @@
|
||||
package datamysql
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"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"
|
||||
)
|
||||
|
||||
// userRepo maps methods to database
|
||||
type userRepo struct {
|
||||
conn executor
|
||||
}
|
||||
|
||||
func newUserRepo(conn executor) *userRepo {
|
||||
return &userRepo{
|
||||
conn: conn,
|
||||
}
|
||||
}
|
||||
|
||||
func (c *userRepo) GetByUUID(uuid string, profile string) (entity.User, error) {
|
||||
params := make([]interface{}, 0)
|
||||
params = append(params, uuid)
|
||||
finalQuery := c.getQuery() + " AND a.user_uuid = ? "
|
||||
if profile == "US" {
|
||||
finalQuery += " AND e.key = ? "
|
||||
params = append(params, profile)
|
||||
}
|
||||
|
||||
user, err := c.parseSet(c.conn.Query(finalQuery, params...))
|
||||
if err != nil {
|
||||
return entity.User{}, err
|
||||
}
|
||||
|
||||
if len(user) > 0 {
|
||||
retVal := user[0]
|
||||
retVal.Contacts, err = c.GetContacts(retVal.ID)
|
||||
if err != nil {
|
||||
return entity.User{}, err
|
||||
}
|
||||
|
||||
retVal.Addresses = nil
|
||||
retVal.Addresses, err = c.getAddressByUserID(retVal.ID)
|
||||
if err != nil {
|
||||
return entity.User{}, err
|
||||
}
|
||||
return retVal, nil
|
||||
} else {
|
||||
return entity.User{}, nil
|
||||
}
|
||||
}
|
||||
|
||||
func (c *userRepo) GetContacts(userID int64) ([]entity.ContactInfo, error) {
|
||||
const (
|
||||
query = `
|
||||
SELECT
|
||||
a.contact_id,
|
||||
a.contact,
|
||||
a.user_id,
|
||||
b.contact_type_id,
|
||||
b.key contact_type_key,
|
||||
b.name contact_type_name
|
||||
FROM tab_contact a
|
||||
INNER JOIN tab_contact_type b
|
||||
ON a.contact_type_id = b.contact_type_id
|
||||
WHERE a.user_id = ?;
|
||||
`
|
||||
)
|
||||
|
||||
rows, err := c.conn.Query(query, userID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
retVal := make([]entity.ContactInfo, 0)
|
||||
for rows.Next() {
|
||||
contact := entity.ContactInfo{}
|
||||
err = rows.Scan(&contact.ID, &contact.Value, &contact.UserID, &contact.Type.ID, &contact.Type.Key, &contact.Type.Value)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
retVal = append(retVal, contact)
|
||||
}
|
||||
|
||||
return retVal, nil
|
||||
}
|
||||
|
||||
func (c *userRepo) GetUsersByProfile(profile string) ([]entity.User, error) {
|
||||
query := c.getQuery()
|
||||
if profile == "" {
|
||||
query += "AND e.key <> 'US' "
|
||||
return c.parseSet(c.conn.Query(query))
|
||||
} else {
|
||||
return c.parseSet(c.conn.Query(query+"AND e.key = ? AND a.active = 1 ", profile))
|
||||
}
|
||||
}
|
||||
|
||||
func (c *userRepo) parseSet(rows *sql.Rows, err error) ([]entity.User, error) {
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err)
|
||||
}
|
||||
result := make([]entity.User, 0)
|
||||
var lastUser entity.User
|
||||
for rows.Next() {
|
||||
entity, err := c.parseEntity(rows)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err)
|
||||
}
|
||||
|
||||
if entity.UUID == lastUser.UUID {
|
||||
lastUser.Profiles = append(lastUser.Profiles, entity.Profiles...)
|
||||
} else {
|
||||
if lastUser.UUID != "" {
|
||||
result = append(result, lastUser)
|
||||
}
|
||||
lastUser = entity
|
||||
}
|
||||
}
|
||||
result = append(result, lastUser)
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func (c *userRepo) GetContactType() (retVal []entity.ContactType, err error) {
|
||||
const (
|
||||
query = `
|
||||
SELECT
|
||||
a.contact_type_id,
|
||||
a.key,
|
||||
a.name
|
||||
FROM tab_contact_type a
|
||||
WHERE a.visible = 1 `
|
||||
)
|
||||
|
||||
rows, err := c.conn.Query(query)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
retVal = make([]entity.ContactType, 0)
|
||||
for rows.Next() {
|
||||
var contactType entity.ContactType
|
||||
err = rows.Scan(&contactType.ID, &contactType.Key, &contactType.Value)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
retVal = append(retVal, contactType)
|
||||
}
|
||||
|
||||
return retVal, nil
|
||||
}
|
||||
|
||||
// parseEntity parses a result to an entity
|
||||
func (c *userRepo) parseEntity(row scanner) (retVal entity.User, err error) {
|
||||
var profile entity.Profile
|
||||
var birthDate mysql.NullTime
|
||||
|
||||
var homeAddress entity.Address
|
||||
var workAddress entity.Address
|
||||
|
||||
err = row.Scan(&retVal.ID, &retVal.UUID, &retVal.Name, &retVal.Member, &birthDate, &retVal.LoginID, &retVal.LoginUUID, &retVal.Email, &retVal.PhoneNumber, &retVal.LoginKey, &retVal.Gender, &retVal.Active, &retVal.Created, &retVal.Updated, &profile.ID, &profile.Name, &profile.Key, &profile.Active, &profile.Blocked, &profile.Suspended, &profile.Created, &profile.Updated, &profile.Organization.ID, &profile.Organization.UUID, &profile.Organization.Type.ID, &profile.Organization.Type.Name, &profile.Organization.Type.Key, &profile.Organization.Type.Description, &profile.Organization.Name, &profile.Organization.Description, &profile.Organization.ReferenceID, &profile.Organization.ParentID, &profile.Organization.Main,
|
||||
&homeAddress.ID, &homeAddress.UUID, &homeAddress.AddressType.ID, &homeAddress.AddressType.Key, &homeAddress.AddressType.Name, &homeAddress.Name, &homeAddress.Address, &homeAddress.Latitude, &homeAddress.Longitude,
|
||||
&workAddress.ID, &workAddress.UUID, &workAddress.AddressType.ID, &workAddress.AddressType.Key, &workAddress.AddressType.Name, &workAddress.Name, &workAddress.Address, &workAddress.Latitude, &workAddress.Longitude)
|
||||
if err != nil {
|
||||
if err != sql.ErrNoRows {
|
||||
return retVal, errors.Wrap(err)
|
||||
}
|
||||
}
|
||||
|
||||
if birthDate.Valid {
|
||||
retVal.BirthDate = birthDate.Time
|
||||
}
|
||||
|
||||
retVal.Profiles = append(retVal.Profiles, profile)
|
||||
if homeAddress.ID > 0 {
|
||||
retVal.Addresses = append(retVal.Addresses, homeAddress)
|
||||
}
|
||||
|
||||
if workAddress.ID > 0 {
|
||||
retVal.Addresses = append(retVal.Addresses, workAddress)
|
||||
}
|
||||
|
||||
return retVal, errors.Wrap(err)
|
||||
}
|
||||
|
||||
func (c *userRepo) FullLogin(loginType string, key string, pass string, profile string) (user entity.User, err error) {
|
||||
return c.login(loginType, key, pass, profile)
|
||||
}
|
||||
|
||||
//Login return a user based on email and password with the default `User` profile
|
||||
func (c *userRepo) Login(email string, pass string) (user entity.User, err error) {
|
||||
return c.FullLogin("email", email, pass, "US")
|
||||
}
|
||||
|
||||
func (c *userRepo) getQuery() string {
|
||||
const (
|
||||
query = `SELECT
|
||||
a.user_id,
|
||||
a.user_uuid,
|
||||
a.name,
|
||||
IFNULL(a.member, '') member,
|
||||
a.birth_date,
|
||||
b.login_id,
|
||||
b.login_uuid,
|
||||
IFNULL(b.email, '') email,
|
||||
IFNULL(b.phone_number, '') phone_number,
|
||||
b.key login_key,
|
||||
IFNULL(a.gender, 'U') gender,
|
||||
(IFNULL(a.active, b'0') = b'1') active,
|
||||
a.create_time,
|
||||
a.update_time,
|
||||
e.profile_id,
|
||||
e.name profile_name,
|
||||
e.key profile_key,
|
||||
(IFNULL(c.active, b'0') = b'1') profile_active,
|
||||
(IFNULL(c.blocked, b'0') = b'1') profile_blocked,
|
||||
(IFNULL(c.suspended, b'0') = b'1') profile_suspended,
|
||||
c.create_date profile_createat,
|
||||
c.update_date profile_updateat,
|
||||
IFNULL(f.organization_id, 0) organization_id,
|
||||
IFNULL(f.organization_uuid, '') organization_uuid,
|
||||
IFNULL(f.organization_type_id, 0) organization_type_id,
|
||||
IFNULL(g.organization_type, '') organization_type,
|
||||
IFNULL(g.organization_type_key, '') organization_type_key,
|
||||
IFNULL(g.description, '') organization_type_desc,
|
||||
IFNULL(f.organization_name, '') organization_name,
|
||||
IFNULL(f.organization_description, '') organization_desc,
|
||||
IFNULL(f.organization_reference_id, 0) organization_reference_id,
|
||||
IFNULL(f.organization_parent_id, 0) organization_parent_id,
|
||||
(IFNULL(f.main_organization, b'0') = b'1') main_organization,
|
||||
IFNULL(h.address_id, 0) home_address_id,
|
||||
IFNULL(h.address_uuid, '') home_address_uuid,
|
||||
IFNULL(h.address_type_id, 0) home_address_type_id,
|
||||
IFNULL(h.address_type_key, '') home_address_type_key,
|
||||
IFNULL(h.address_type_name, '') home_address_type_name,
|
||||
IFNULL(h.name, '') home_name,
|
||||
IFNULL(h.address, '') home_address,
|
||||
IFNULL(h.lat, 0) home_lat,
|
||||
IFNULL(h.long, 0) home_long,
|
||||
IFNULL(i.address_id, 0) work_address_id,
|
||||
IFNULL(i.address_uuid, '') work_address_uuid,
|
||||
IFNULL(i.address_type_id, 0) work_address_type_id,
|
||||
IFNULL(i.address_type_key, '') work_address_type_key,
|
||||
IFNULL(i.address_type_name, '') work_address_type_name,
|
||||
IFNULL(i.name, '') work_name,
|
||||
IFNULL(i.address, '') work_address,
|
||||
IFNULL(i.lat, 0) work_lat,
|
||||
IFNULL(i.long, 0) work_long
|
||||
FROM
|
||||
tab_user a
|
||||
INNER JOIN
|
||||
tab_login b ON a.user_id = b.user_id
|
||||
INNER JOIN
|
||||
tab_profile_login c ON c.login_id = b.login_id
|
||||
INNER JOIN
|
||||
tab_profile e ON e.profile_id = c.profile_id
|
||||
LEFT JOIN
|
||||
tab_organization f ON f.organization_id = IFNULL(c.organization_id, 0)
|
||||
LEFT JOIN
|
||||
tab_organization_type g ON IFNULL(g.organization_type_id, 0) = IFNULL(f.organization_type_id, 0)
|
||||
LEFT JOIN
|
||||
viw_address_home h ON a.user_id = h.user_id
|
||||
LEFT JOIN
|
||||
viw_address_work i ON a.user_id = i.user_id
|
||||
WHERE
|
||||
a.active = b.active
|
||||
AND b.active = c.active
|
||||
AND c.active = e.active `
|
||||
)
|
||||
|
||||
return query
|
||||
}
|
||||
|
||||
func (c *userRepo) login(loginType string, key string, pass string, profile string) (user entity.User, err error) {
|
||||
if loginType == "" {
|
||||
return user, errors.NewNullArgumentError("loginType")
|
||||
}
|
||||
|
||||
if loginType != "phone_number" && loginType != "email" {
|
||||
return user, errors.NewValidationError("loginType", "invalid")
|
||||
}
|
||||
|
||||
query := fmt.Sprintf(c.getQuery()+`
|
||||
AND a.active = 1
|
||||
AND b.%s = ?
|
||||
AND b.password = sha2(?, 512) `, loginType)
|
||||
|
||||
users, err := c.parseSet(c.conn.Query(query, key, pass))
|
||||
if err != nil {
|
||||
return user, errors.Wrap(err)
|
||||
}
|
||||
|
||||
return users[0], nil
|
||||
}
|
||||
|
||||
func (c *userRepo) Create(user entity.User) (retVal entity.User, err error) {
|
||||
retVal = user
|
||||
|
||||
if retVal.Member != "" {
|
||||
retVal, err = c.getUserByMember(retVal)
|
||||
if err != nil {
|
||||
return retVal, err
|
||||
}
|
||||
}
|
||||
|
||||
if retVal.ID == 0 || retVal.Member == "" {
|
||||
userID, guid, err := c.createUser(user)
|
||||
if err != nil {
|
||||
return retVal, err
|
||||
}
|
||||
retVal.UUID = guid
|
||||
retVal.ID = userID
|
||||
}
|
||||
|
||||
retVal, err = c.getUserLogin(retVal)
|
||||
if err != nil {
|
||||
return retVal, err
|
||||
}
|
||||
|
||||
if retVal.LoginID == 0 {
|
||||
loginID, loginGUID, err := c.createLogin(retVal)
|
||||
if err != nil {
|
||||
return retVal, err
|
||||
}
|
||||
retVal.LoginUUID = loginGUID
|
||||
retVal.LoginID = loginID
|
||||
}
|
||||
|
||||
for _, p := range user.Profiles {
|
||||
companyProfileID, err := c.getCompanyProfile(p.Key)
|
||||
if err != nil {
|
||||
return retVal, err
|
||||
}
|
||||
|
||||
if len(user.Organizations) > 0 {
|
||||
for _, o := range user.Organizations {
|
||||
err = c.addProfileToUser(retVal.LoginID, companyProfileID, o)
|
||||
if err != nil {
|
||||
return retVal, err
|
||||
}
|
||||
}
|
||||
} else {
|
||||
err = c.addProfileToUser(retVal.LoginID, companyProfileID, entity.Organization{})
|
||||
if err != nil {
|
||||
return retVal, err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if retVal.Email != "" {
|
||||
contact := entity.ContactInfo{
|
||||
Type: entity.ContactType{Key: "email"},
|
||||
Value: retVal.Email,
|
||||
UserID: retVal.ID,
|
||||
}
|
||||
|
||||
contact, err = c.addContactInfo(contact)
|
||||
if err != nil {
|
||||
return retVal, err
|
||||
}
|
||||
}
|
||||
|
||||
if retVal.PhoneNumber != "" {
|
||||
contact := entity.ContactInfo{
|
||||
Type: entity.ContactType{Key: "phone"},
|
||||
Value: retVal.PhoneNumber,
|
||||
UserID: retVal.ID,
|
||||
}
|
||||
|
||||
contact, err = c.addContactInfo(contact)
|
||||
if err != nil {
|
||||
return retVal, err
|
||||
}
|
||||
}
|
||||
|
||||
return c.GetByUUID(retVal.UUID, "")
|
||||
}
|
||||
|
||||
func (c *userRepo) SaveContact(contact entity.ContactInfo) (entity.ContactInfo, error) {
|
||||
return c.addContactInfo(contact)
|
||||
}
|
||||
|
||||
func (c *userRepo) RemoveContact(contact entity.ContactInfo) (entity.ContactInfo, error) {
|
||||
const (
|
||||
query = `INSERT INTO tab_contact(contact_type_id, user_id, contact)
|
||||
SELECT a.contact_type_id, ? user_id, ? contact
|
||||
FROM
|
||||
tab_contact_type a
|
||||
LEFT JOIN tab_contact b
|
||||
ON a.contact_type_id = b.contact_type_id
|
||||
AND b.user_id = ?
|
||||
AND b.contact = ?
|
||||
WHERE a.key = ?
|
||||
AND b.contact_id IS NULL;`
|
||||
)
|
||||
|
||||
result, err := c.conn.Exec(query, contact.UserID, contact.Value, contact.UserID, contact.Value, contact.Type.Key)
|
||||
if err != nil {
|
||||
return contact, err
|
||||
}
|
||||
|
||||
retVal := contact
|
||||
retVal.ID, err = result.LastInsertId()
|
||||
if err != nil {
|
||||
return contact, err
|
||||
}
|
||||
|
||||
return retVal, nil
|
||||
}
|
||||
|
||||
func (c *userRepo) addContactInfo(contact entity.ContactInfo) (entity.ContactInfo, error) {
|
||||
const (
|
||||
query = `INSERT INTO tab_contact(contact_type_id, user_id, contact)
|
||||
SELECT a.contact_type_id, ? user_id, ? contact
|
||||
FROM
|
||||
tab_contact_type a
|
||||
LEFT JOIN tab_contact b
|
||||
ON a.contact_type_id = b.contact_type_id
|
||||
AND b.user_id = ?
|
||||
AND b.contact = ?
|
||||
WHERE a.key = ?
|
||||
AND b.contact_id IS NULL;`
|
||||
)
|
||||
|
||||
result, err := c.conn.Exec(query, contact.UserID, contact.Value, contact.UserID, contact.Value, contact.Type.Key)
|
||||
if err != nil {
|
||||
return contact, err
|
||||
}
|
||||
|
||||
retVal := contact
|
||||
retVal.ID, err = result.LastInsertId()
|
||||
if err != nil {
|
||||
return contact, err
|
||||
}
|
||||
|
||||
return retVal, nil
|
||||
}
|
||||
|
||||
func (c *userRepo) getUserByLoginAndProfile(loginID int64) (user entity.User, err error) {
|
||||
finalQuery := c.getQuery() + " AND a.active = 1 AND b.login_Id = ? "
|
||||
|
||||
users, err := c.parseSet(c.conn.Query(finalQuery, loginID))
|
||||
if err != nil {
|
||||
return user, errors.Wrap(err)
|
||||
}
|
||||
|
||||
return users[0], nil
|
||||
}
|
||||
|
||||
func (c *userRepo) addProfileToUser(loginID int64, profileID int64, organization entity.Organization) error {
|
||||
const query = "INSERT INTO tab_profile_login(profile_id, login_id, active, blocked, suspended, organization_id) VALUES(?, ?, 1, 0, 0, ?) ON DUPLICATE KEY UPDATE profile_id = ?, login_id = ?, organization_id = ?;"
|
||||
const checkQuery = "SELECT COUNT(1) has_profile FROM tab_profile_login a WHERE a.login_id = ? AND a.profile_id = ? AND IFNULL(a.organization_id, 0) = ?;"
|
||||
|
||||
var total int64
|
||||
row := c.conn.QueryRow(checkQuery, loginID, profileID, organization.ID)
|
||||
err := row.Scan(&total)
|
||||
if err != nil && err != sql.ErrNoRows {
|
||||
return err
|
||||
}
|
||||
|
||||
if total < 1 {
|
||||
_, err := c.conn.Exec(query, profileID, loginID, organization.ID, profileID, loginID, toNullInt64(organization.ID))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *userRepo) getUserByMember(u entity.User) (user entity.User, err error) {
|
||||
user = u
|
||||
users, err := c.parseSet(c.conn.Query(c.getQuery()+" AND a.active = 1 AND e.key = 'US' AND IFNULL(a.member, '') = ?;", u.Member))
|
||||
if err != nil {
|
||||
return user, errors.Wrap(err)
|
||||
}
|
||||
|
||||
if users[0].ID != 0 {
|
||||
user = users[0]
|
||||
}
|
||||
return user, nil
|
||||
}
|
||||
|
||||
func (c *userRepo) getCompanyProfile(profile string) (int64, error) {
|
||||
const (
|
||||
query = "SELECT a.profile_id FROM tab_profile a WHERE a.key = ?;"
|
||||
)
|
||||
var companyProfileID int64
|
||||
row := c.conn.QueryRow(query, profile)
|
||||
err := row.Scan(&companyProfileID)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
return companyProfileID, nil
|
||||
}
|
||||
|
||||
func (c *userRepo) getUserLogin(u entity.User) (user entity.User, err error) {
|
||||
const (
|
||||
query = "SELECT login_id, login_uuid, user_id, IFNULL(phone_number, '') phone_number, IFNULL(email, '') email, `key`, `password` FROM tab_login WHERE user_id = ?"
|
||||
)
|
||||
|
||||
row := c.conn.QueryRow(query, user.Member)
|
||||
err = row.Scan(&user.LoginID, &user.LoginUUID, &user.ID, &user.PhoneNumber, &user.Email, &user.LoginKey, &user.Pass)
|
||||
if err != nil {
|
||||
if err == sql.ErrNoRows {
|
||||
return u, nil
|
||||
} else {
|
||||
return user, err
|
||||
}
|
||||
}
|
||||
|
||||
return user, nil
|
||||
}
|
||||
|
||||
func (c *userRepo) createLogin(user entity.User) (int64, string, error) {
|
||||
const (
|
||||
query = "INSERT INTO tab_login (login_uuid, user_id, phone_number, email, `key`, `password`) VALUES(?, ?, ?, ?, ?, sha2(?, 512)) ON DUPLICATE KEY UPDATE login_uuid = ?, user_id = ?, phone_number = ?, email = ?, `key` = ?, `password` = sha2(?, 512);"
|
||||
)
|
||||
guid, _ := uuid.NewV4()
|
||||
key, _ := uuid.NewV4()
|
||||
|
||||
result, err := c.conn.Exec(query, guid.String(), user.ID, toNullString(user.PhoneNumber), toNullString(user.Email), key.String(), user.Pass, guid.String(), user.ID, user.PhoneNumber, user.Email, key.String(), user.Pass)
|
||||
if err != nil {
|
||||
return 0, "", err
|
||||
}
|
||||
|
||||
loginID, err := result.LastInsertId()
|
||||
if err != nil {
|
||||
return 0, "", err
|
||||
}
|
||||
|
||||
return loginID, guid.String(), nil
|
||||
}
|
||||
|
||||
func (c *userRepo) createUser(user entity.User) (int64, string, error) {
|
||||
const (
|
||||
query = "INSERT INTO tab_user(user_uuid, `name`, member, birth_date, gender) VALUES(?, ?, ?, ?, ?) ON DUPLICATE KEY UPDATE user_uuid = ?, `name` = ?, member = ?, birth_date = ?, gender = ?;"
|
||||
)
|
||||
guid, _ := uuid.NewV4()
|
||||
|
||||
result, err := c.conn.Exec(query, guid.String(), user.Name, toNullString(user.Member), toNullTime(user.BirthDate), toNullString(user.Gender), guid.String(), user.Name, toNullString(user.Member), toNullTime(user.BirthDate), toNullString(user.Gender))
|
||||
if err != nil {
|
||||
return 0, "", err
|
||||
}
|
||||
|
||||
userID, err := result.LastInsertId()
|
||||
if err != nil {
|
||||
return 0, "", err
|
||||
}
|
||||
|
||||
return userID, guid.String(), nil
|
||||
}
|
||||
|
||||
func (c *userRepo) RemoveAddress(addressUUID string) error {
|
||||
const (
|
||||
query = "UPDATE tab_address SET active = 0 WHERE address_uuid = ?"
|
||||
)
|
||||
|
||||
_, err := c.conn.Exec(query, addressUUID)
|
||||
return err
|
||||
}
|
||||
|
||||
func (c *userRepo) SaveAddress(address entity.Address) (entity.Address, error) {
|
||||
const (
|
||||
query = "INSERT INTO tab_address(address_uuid,address_type_id,address_origin_id,user_id,internal_id,`name`,address,lat,`long`,created_user_id) VALUES (?,?,?,?,?,?,?,?,?,?);"
|
||||
)
|
||||
|
||||
address, err := c.getAddressSecondaryData(address)
|
||||
if err != nil {
|
||||
return address, err
|
||||
}
|
||||
|
||||
uuid, _ := uuid.NewV4()
|
||||
address.UUID = uuid.String()
|
||||
|
||||
result, err := c.conn.Exec(query, address.UUID, address.AddressType.ID, address.Origin.ID, address.User.ID, address.InternalID, address.Name, address.Address, address.Latitude, address.Longitude, address.CreatedUser.ID)
|
||||
if err != nil {
|
||||
return address, err
|
||||
}
|
||||
|
||||
addressID, err := result.LastInsertId()
|
||||
if err != nil {
|
||||
return address, err
|
||||
}
|
||||
|
||||
return c.getAddressByID(addressID)
|
||||
}
|
||||
|
||||
func (c *userRepo) getAddressByUserID(userID int64) ([]entity.Address, error) {
|
||||
const (
|
||||
query = `SELECT
|
||||
a.address_id,
|
||||
a.address_uuid,
|
||||
a.address_type_id,
|
||||
d.key address_type_key,
|
||||
d.name address_type_name,
|
||||
a.address_origin_id,
|
||||
e.key address_origin_key,
|
||||
e.name address_origin_name,
|
||||
b.user_id,
|
||||
b.user_uuid,
|
||||
b.name user_name,
|
||||
a.internal_id,
|
||||
a.name,
|
||||
a.address,
|
||||
a.lat,
|
||||
a.long,
|
||||
c.user_id created_user_id,
|
||||
c.user_uuid created_user_uuid,
|
||||
c.name created_user_name
|
||||
FROM
|
||||
tab_address a
|
||||
INNER JOIN tab_user b
|
||||
ON a.user_id = b.user_id
|
||||
INNER JOIN tab_user c
|
||||
ON a.created_user_id = c.user_id
|
||||
INNER JOIN tab_address_type d
|
||||
ON a.address_type_id = d.address_type_id
|
||||
INNER JOIN tab_address_origin e
|
||||
ON a.address_origin_id = e.address_origin_id
|
||||
WHERE
|
||||
a.user_id = ? and a.active = 1;`
|
||||
)
|
||||
|
||||
var addresses []entity.Address
|
||||
rows, err := c.conn.Query(query, userID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for rows.Next() {
|
||||
var address entity.Address
|
||||
err := rows.Scan(&address.ID, &address.UUID, &address.AddressType.ID, &address.AddressType.Key, &address.AddressType.Name,
|
||||
&address.Origin.ID, &address.Origin.Key, &address.Origin.Name, &address.User.ID, &address.User.UUID, &address.User.Name,
|
||||
&address.InternalID, &address.Name, &address.Address, &address.Latitude, &address.Longitude, &address.CreatedUser.ID,
|
||||
&address.CreatedUser.UUID, &address.CreatedUser.Name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
addresses = append(addresses, address)
|
||||
}
|
||||
return addresses, nil
|
||||
}
|
||||
|
||||
func (c *userRepo) getAddressByID(addressID int64) (entity.Address, error) {
|
||||
const (
|
||||
query = `SELECT
|
||||
a.address_id,
|
||||
a.address_uuid,
|
||||
a.address_type_id,
|
||||
d.key address_type_key,
|
||||
d.name address_type_name,
|
||||
a.address_origin_id,
|
||||
e.key address_origin_key,
|
||||
e.name address_origin_name,
|
||||
b.user_id,
|
||||
b.user_uuid,
|
||||
b.name user_name,
|
||||
a.internal_id,
|
||||
a.name,
|
||||
a.address,
|
||||
a.lat,
|
||||
a.long,
|
||||
c.user_id created_user_id,
|
||||
c.user_uuid created_user_uuid,
|
||||
c.name created_user_name
|
||||
FROM
|
||||
tab_address a
|
||||
INNER JOIN tab_user b
|
||||
ON a.user_id = b.user_id
|
||||
INNER JOIN tab_user c
|
||||
ON a.created_user_id = c.user_id
|
||||
INNER JOIN tab_address_type d
|
||||
ON a.address_type_id = d.address_type_id
|
||||
INNER JOIN tab_address_origin e
|
||||
ON a.address_origin_id = e.address_origin_id
|
||||
WHERE
|
||||
a.address_id = ?;`
|
||||
)
|
||||
|
||||
var address entity.Address
|
||||
row := c.conn.QueryRow(query, addressID)
|
||||
err := row.Scan(&address.ID, &address.UUID, &address.AddressType.ID, &address.AddressType.Key, &address.AddressType.Name,
|
||||
&address.Origin.ID, &address.Origin.Key, &address.Origin.Name, &address.User.ID, &address.User.UUID, &address.User.Name,
|
||||
&address.InternalID, &address.Name, &address.Address, &address.Latitude, &address.Longitude, &address.CreatedUser.ID,
|
||||
&address.CreatedUser.UUID, &address.CreatedUser.Name)
|
||||
if err != nil {
|
||||
return entity.Address{}, err
|
||||
}
|
||||
|
||||
return address, nil
|
||||
}
|
||||
|
||||
func (c *userRepo) GetAddressByUUID(addressUUID string) (entity.Address, error) {
|
||||
const (
|
||||
query = `SELECT
|
||||
a.address_id,
|
||||
a.address_uuid,
|
||||
a.address_type_id,
|
||||
d.key address_type_key,
|
||||
d.name address_type_name,
|
||||
a.address_origin_id,
|
||||
e.key address_origin_key,
|
||||
e.name address_origin_name,
|
||||
b.user_id,
|
||||
b.user_uuid,
|
||||
b.name user_name,
|
||||
a.internal_id,
|
||||
a.name,
|
||||
a.address,
|
||||
a.lat,
|
||||
a.long,
|
||||
c.user_id created_user_id,
|
||||
c.user_uuid created_user_uuid,
|
||||
c.name created_user_name
|
||||
FROM
|
||||
tab_address a
|
||||
INNER JOIN tab_user b
|
||||
ON a.user_id = b.user_id
|
||||
INNER JOIN tab_user c
|
||||
ON a.created_user_id = c.user_id
|
||||
INNER JOIN tab_address_type d
|
||||
ON a.address_type_id = d.address_type_id
|
||||
INNER JOIN tab_address_origin e
|
||||
ON a.address_origin_id = e.address_origin_id
|
||||
WHERE
|
||||
a.address_uuid = ?;`
|
||||
)
|
||||
|
||||
var address entity.Address
|
||||
row := c.conn.QueryRow(query, addressUUID)
|
||||
err := row.Scan(&address.ID, &address.UUID, &address.AddressType.ID, &address.AddressType.Key, &address.AddressType.Name,
|
||||
&address.Origin.ID, &address.Origin.Key, &address.Origin.Name, &address.User.ID, &address.User.UUID, &address.User.Name,
|
||||
&address.InternalID, &address.Name, &address.Address, &address.Latitude, &address.Longitude, &address.CreatedUser.ID,
|
||||
&address.CreatedUser.UUID, &address.CreatedUser.Name)
|
||||
if err != nil {
|
||||
return entity.Address{}, err
|
||||
}
|
||||
|
||||
return address, nil
|
||||
}
|
||||
|
||||
func (c *userRepo) getAddressSecondaryData(address entity.Address) (entity.Address, error) {
|
||||
const (
|
||||
query = `SELECT
|
||||
a.user_id,
|
||||
a.user_uuid,
|
||||
a.name user_name,
|
||||
b.user_id created_user_id,
|
||||
b.user_uuid created_user_uuid,
|
||||
b.name created_user_name,
|
||||
c.address_type_id,
|
||||
c.key address_type_key,
|
||||
c.name address_type_name,
|
||||
d.address_origin_id,
|
||||
d.key address_origin_key,
|
||||
d.name address_origin_name
|
||||
FROM
|
||||
tab_user a,
|
||||
tab_user b,
|
||||
tab_address_type c,
|
||||
tab_address_origin d
|
||||
WHERE
|
||||
a.user_uuid = ?
|
||||
AND b.user_uuid = ?
|
||||
AND c.key = ?
|
||||
AND d.key = ?;`
|
||||
)
|
||||
|
||||
row := c.conn.QueryRow(query, address.User.UUID, address.CreatedUser.UUID, address.AddressType.Key, address.Origin.Key)
|
||||
err := row.Scan(&address.User.ID, &address.User.UUID, &address.User.Name, &address.CreatedUser.ID, &address.CreatedUser.UUID, &address.CreatedUser.Name, &address.AddressType.ID, &address.AddressType.Key, &address.AddressType.Name, &address.Origin.ID, &address.Origin.Key, &address.Origin.Name)
|
||||
if err != nil {
|
||||
return address, err
|
||||
}
|
||||
|
||||
return address, nil
|
||||
}
|
||||
|
||||
// GetAll returns a list of all active cards
|
||||
func (c *userRepo) GetAll() (list []entity.User, err error) {
|
||||
return c.parseSet(c.conn.Query(c.getQuery() + " WHERE a.active = 1 "))
|
||||
}
|
||||
|
||||
// GetByID returns a single card data by its ID
|
||||
func (c *userRepo) GetByID(userID int64) (retVal entity.User, err error) {
|
||||
user, err := c.parseSet(c.conn.Query(c.getQuery()+" AND a.user_id = ? ", userID))
|
||||
if err != nil {
|
||||
return entity.User{}, err
|
||||
}
|
||||
|
||||
if len(user) > 0 {
|
||||
retVal := user[0]
|
||||
retVal.Contacts, err = c.GetContacts(retVal.ID)
|
||||
if err != nil {
|
||||
return entity.User{}, err
|
||||
}
|
||||
|
||||
retVal.Addresses = nil
|
||||
retVal.Addresses, err = c.getAddressByUserID(retVal.ID)
|
||||
if err != nil {
|
||||
return entity.User{}, err
|
||||
}
|
||||
return retVal, nil
|
||||
} else {
|
||||
return retVal, nil
|
||||
}
|
||||
}
|
||||
|
||||
func toNullString(s string) sql.NullString {
|
||||
return sql.NullString{String: s, Valid: s != ""}
|
||||
}
|
||||
|
||||
func toNullInt64(i int64) sql.NullInt64 {
|
||||
return sql.NullInt64{Int64: i, Valid: i > 0}
|
||||
}
|
||||
|
||||
func toNullTime(date time.Time) mysql.NullTime {
|
||||
return mysql.NullTime{Time: date, Valid: !date.IsZero()}
|
||||
}
|
||||
15
data/datamysql/utils.go
Normal file
15
data/datamysql/utils.go
Normal file
@@ -0,0 +1,15 @@
|
||||
package datamysql
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
)
|
||||
|
||||
type scanner interface {
|
||||
Scan(dest ...interface{}) error
|
||||
}
|
||||
|
||||
type executor interface {
|
||||
Exec(query string, args ...interface{}) (sql.Result, error)
|
||||
QueryRow(query string, args ...interface{}) *sql.Row
|
||||
Query(query string, args ...interface{}) (*sql.Rows, error)
|
||||
}
|
||||
210
data/datamysql/visit.go
Normal file
210
data/datamysql/visit.go
Normal file
@@ -0,0 +1,210 @@
|
||||
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":
|
||||
switch p.Organization.Type.Key {
|
||||
case "techsupport", "bcbsi", "bcbsa", "plan":
|
||||
return
|
||||
case "provider":
|
||||
query = ` INNER JOIN viw_visit_provider f
|
||||
ON f.visit_id = a.visit_id `
|
||||
where = fmt.Sprintf(` AND (f.organization_uuid = '%s' OR f.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 a
|
||||
INNER JOIN tab_visit_status b
|
||||
ON a.visit_status_id = b.visit_status_id
|
||||
INNER JOIN tab_user c
|
||||
ON c.user_id = a.user_id
|
||||
INNER JOIN tab_user d
|
||||
ON d.user_id = a.created_user_id
|
||||
INNER JOIN tab_trip_type e
|
||||
ON e.trip_type_id = a.trip_type_id
|
||||
INNER JOIN tab_provider 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
|
||||
}
|
||||
|
||||
fmt.Println("Visit ID: ", retVal.ID)
|
||||
return retVal, nil
|
||||
}
|
||||
Reference in New Issue
Block a user