/src/gitlab.com/mahina/platform/models/standing_order_item.go

https://gitlab.com/mahina/platform · Go · 316 lines · 281 code · 19 blank · 16 comment · 101 complexity · 0d41d0ee8e91500aff796e52773eafc7 MD5 · raw file

  1. package models
  2. import (
  3. "bytes"
  4. "encoding/json"
  5. "errors"
  6. "github.com/jmoiron/sqlx"
  7. "github.com/jmoiron/sqlx/types"
  8. pq "github.com/lib/pq"
  9. "fmt"
  10. "github.com/guregu/null"
  11. "github.com/guregu/null/zero"
  12. )
  13. // StandingOrderItem defines an line item in an order.
  14. type StandingOrderItem struct {
  15. StandingOrderItemID int64 `db:"order_item_id" json:"-"`
  16. StandingOrderItemUUID null.String `db:"order_item_uuid" json:"orderItemUUID"`
  17. OrderID int64 `db:"order_id" json:"-"`
  18. OrderUUID null.String `db:"order_uuid" json:"orderUUID"`
  19. SupplierID int64 `db:"supplier_id" json:"-"`
  20. SupplierUUID null.String `db:"supplier_uuid" json:"supplierUUID"`
  21. ItemID int64 `db:"item_id" json:"-"`
  22. ItemUUID null.String `db:"item_uuid" json:"itemUUID"`
  23. OfferID null.Int `db:"offer_id" json:"-"`
  24. OfferUUID zero.String `db:"offer_uuid" json:"offerUUID"`
  25. LineItem int64 `db:"line_item" json:"lineItem"`
  26. QuantityByDOW pq.Float64Array `db:"quantity_by_dow" json:"quantityByDOW"`
  27. Frequency null.String `db:"frequency" json:"frequency"`
  28. Price float64 `db:"price" json:"price"`
  29. Notes zero.String `db:"notes" json:"notes"`
  30. Created zero.Time `db:"created" json:"created"`
  31. Extended types.JSONText `db:"extended" json:"extended,omitempty"`
  32. Schema string `db:"-" json:"-"`
  33. }
  34. // NewStandingOrderItem creates a StandingOrderItem struct from a passed JSON string. No database
  35. // update events occur from this call.
  36. func NewStandingOrderItem(tx *sqlx.Tx, jsonStr []byte, schema string) (*StandingOrderItem, error) {
  37. entity := StandingOrderItem{}
  38. entity.Schema = schema
  39. err := json.Unmarshal(jsonStr, &entity)
  40. if err != nil {
  41. return nil, err
  42. }
  43. if entity.OrderID == 0 {
  44. order, err := GetOrderByUUID(tx, entity.OrderUUID.String, schema)
  45. if err != nil {
  46. return nil, err
  47. }
  48. entity.OrderID = order.OrderID
  49. }
  50. if entity.SupplierID == 0 {
  51. org, err := GetOrganizationByUUID(tx, entity.SupplierUUID.String)
  52. if err != nil {
  53. return nil, err
  54. }
  55. entity.SupplierID = org.OrgID
  56. }
  57. if entity.ItemID == 0 {
  58. item, err := GetItemByUUID(tx, entity.ItemUUID.String, schema)
  59. if err != nil {
  60. return nil, err
  61. }
  62. entity.ItemID = item.ItemID
  63. }
  64. if entity.OfferID.Int64 == 0 && entity.OfferUUID.String != "" {
  65. offer, err := GetOfferByUUID(tx, entity.OfferUUID.String, schema)
  66. if err != nil {
  67. return nil, err
  68. }
  69. entity.OfferID = null.IntFrom(offer.OfferID)
  70. }
  71. return &entity, nil
  72. }
  73. // Get performs a SELECT, using StandingOrderItemID as the lookup key. The StandingOrderItem object
  74. // is updated with the attributes of the found StandingOrderItem.
  75. func (entity *StandingOrderItem) Get(tx *sqlx.Tx) (err error) {
  76. if entity.Schema == "" {
  77. err = errors.New("schema not specified")
  78. return
  79. }
  80. statement := fmt.Sprintf("SELECT * FROM %s.standing_order_item WHERE order_item_id = $1", entity.Schema)
  81. var db *sqlx.DB
  82. if tx == nil {
  83. db, err = GetDB()
  84. if err != nil {
  85. return
  86. }
  87. err = db.Get(entity, statement, entity.StandingOrderItemID)
  88. } else {
  89. err = tx.Get(entity, statement, entity.StandingOrderItemID)
  90. }
  91. if err == nil {
  92. if entity.OfferID.IsZero() {
  93. entity.OfferUUID = zero.StringFrom("")
  94. }
  95. }
  96. return
  97. }
  98. // Valid returns the validity of the StandingOrderItem object
  99. func (entity *StandingOrderItem) Valid() bool {
  100. return len(entity.StandingOrderItemUUID.String) > 0
  101. }
  102. // Exists tests for the existence of a StandingOrderItem record corresponding to the StandingOrderItemID value
  103. func (entity *StandingOrderItem) Exists(tx *sqlx.Tx) bool {
  104. if entity.StandingOrderItemID <= 0 {
  105. return false
  106. }
  107. err := entity.Get(tx)
  108. if err != nil {
  109. return false
  110. }
  111. return entity.StandingOrderItemID > 0
  112. }
  113. const standingOrderItemInsertStatement = `INSERT INTO %s.standing_order_item (` +
  114. `order_id, order_uuid, supplier_id, supplier_uuid, item_id, item_uuid, offer_id, offer_uuid, line_item, quantity_by_dow, frequency, price, notes, extended` +
  115. `) VALUES (` +
  116. `$1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14` +
  117. `) RETURNING order_item_id`
  118. // Insert performs an SQL INSERT statement using the StandingOrderItem struct fields as attributes. The struct
  119. // will contain all DB-generated defaults, IDs, etc.
  120. func (entity *StandingOrderItem) Insert(tx *sqlx.Tx) (err error) {
  121. if entity.Schema == "" {
  122. err = errors.New("schema not specified")
  123. return
  124. }
  125. statement := fmt.Sprintf(standingOrderItemInsertStatement, entity.Schema)
  126. isolated := tx == nil
  127. if isolated {
  128. tx, err = BeginTX()
  129. if err != nil {
  130. return
  131. }
  132. }
  133. row := tx.QueryRowx(statement, entity.OrderID, entity.OrderUUID, entity.SupplierID, entity.SupplierUUID,
  134. entity.ItemID, entity.ItemUUID, entity.OfferID, entity.OfferUUID, entity.LineItem, entity.QuantityByDOW, entity.Frequency, entity.Price, entity.Notes, entity.Extended)
  135. err = row.Err()
  136. if err != nil {
  137. goto end
  138. }
  139. err = row.Scan(&entity.StandingOrderItemID)
  140. if err != nil {
  141. goto end
  142. }
  143. if entity.StandingOrderItemID == 0 {
  144. err = errors.New("Primary key unexpectedly nil")
  145. }
  146. end:
  147. if err != nil {
  148. if isolated {
  149. tx.Rollback()
  150. }
  151. } else {
  152. err = entity.Get(tx)
  153. if isolated {
  154. err = tx.Commit()
  155. }
  156. }
  157. return
  158. }
  159. const standingOrderItemUpdateStatement = `UPDATE %s.standing_order_item SET (` +
  160. `order_id, order_uuid, supplier_id, supplier_uuid, item_id, item_uuid, offer_id, offer_uuid, line_item, quantity_by_dow, frequency, price, notes, extended` +
  161. `) = ( ` +
  162. `$1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14` +
  163. `) WHERE order_item_id = $15`
  164. // Update performs an SQL UPDATE operation using the StandingOrderItem struct fields as attributes.
  165. func (entity *StandingOrderItem) Update(tx *sqlx.Tx) (err error) {
  166. if entity.Schema == "" {
  167. err = errors.New("schema not specified")
  168. return
  169. }
  170. statement := fmt.Sprintf(standingOrderItemUpdateStatement, entity.Schema)
  171. isolated := tx == nil
  172. if isolated {
  173. tx, err = BeginTX()
  174. if err != nil {
  175. return
  176. }
  177. }
  178. _, err = tx.Exec(statement, entity.OrderID, entity.OrderUUID, entity.SupplierID, entity.SupplierUUID,
  179. entity.ItemID, entity.ItemUUID, entity.OfferID, entity.OfferUUID, entity.LineItem, entity.QuantityByDOW,
  180. entity.Frequency, entity.Price, entity.Notes, entity.Extended,
  181. entity.StandingOrderItemID)
  182. if err != nil {
  183. if isolated {
  184. tx.Rollback()
  185. }
  186. } else {
  187. err = entity.Get(tx)
  188. if isolated {
  189. err = tx.Commit()
  190. }
  191. }
  192. return
  193. }
  194. // Delete performs an SQL DELETE operation, using StandingOrderItemID as the lookup key.
  195. func (entity *StandingOrderItem) Delete(tx *sqlx.Tx) (err error) {
  196. if entity.Schema == "" {
  197. err = errors.New("schema not specified")
  198. return
  199. }
  200. statement := fmt.Sprintf("DELETE FROM %s.standing_order_item WHERE order_item_id = $1", entity.Schema)
  201. isolated := tx == nil
  202. if isolated {
  203. tx, err = BeginTX()
  204. if err != nil {
  205. return
  206. }
  207. }
  208. _, err = tx.Exec(statement, entity.StandingOrderItemID)
  209. if err != nil {
  210. if isolated {
  211. tx.Rollback()
  212. }
  213. } else {
  214. if isolated {
  215. err = tx.Commit()
  216. }
  217. entity.StandingOrderItemID = 0
  218. }
  219. return
  220. }
  221. func (entity *StandingOrderItem) String() string {
  222. var prettyJSON bytes.Buffer
  223. b, err := json.Marshal(entity)
  224. err = json.Indent(&prettyJSON, b, "", "\t")
  225. if err != nil {
  226. return "Error encoding"
  227. }
  228. return string(prettyJSON.Bytes())
  229. }
  230. // GetStandingOrderItemByStandingOrderItemID performs a SELECT, using the passed StandingOrderItemID as the lookup key
  231. // Returns nil if the entity does not exist--err may/may not be nil in that case.
  232. func GetStandingOrderItemByStandingOrderItemID(tx *sqlx.Tx, entityID int64, schema string) (entity *StandingOrderItem, err error) {
  233. if schema == "" {
  234. err = errors.New("schema not specified")
  235. return
  236. }
  237. statement := fmt.Sprintf("SELECT * FROM %s.standing_order_item WHERE order_item_id = $1", schema)
  238. db, err := GetDB()
  239. if err != nil {
  240. return
  241. }
  242. entity = new(StandingOrderItem)
  243. if tx == nil {
  244. err = db.Get(entity, statement, entityID)
  245. } else {
  246. err = tx.Get(entity, statement, entityID)
  247. }
  248. if err != nil {
  249. entity = nil
  250. } else {
  251. entity.Schema = schema
  252. }
  253. return
  254. }
  255. // GetStandingOrderItemByUUID performs a SELECT, using the passed UUID as the lookup key.
  256. // Returns nil if the entity does not exist—-err may/may not be nil in that case.
  257. func GetStandingOrderItemByUUID(tx *sqlx.Tx, uuid string, schema string) (entity *StandingOrderItem, err error) {
  258. if schema == "" {
  259. err = errors.New("schema not specified")
  260. return
  261. }
  262. statement := fmt.Sprintf("SELECT * FROM %s.standing_order_item WHERE order_item_uuid = $1", schema)
  263. db, err := GetDB()
  264. if err != nil {
  265. return
  266. }
  267. entity = new(StandingOrderItem)
  268. if tx == nil {
  269. err = db.Get(entity, statement, uuid)
  270. } else {
  271. err = tx.Get(entity, statement, uuid)
  272. }
  273. if err != nil {
  274. entity = nil
  275. } else {
  276. entity.Schema = schema
  277. }
  278. return
  279. }
  280. // GetAllStandingOrderItemsForOrder returns all items from a standing order
  281. func GetAllStandingOrderItemsForOrder(tx *sqlx.Tx, orderUUID string, schema string) ([]StandingOrderItem, error) {
  282. if schema == "" {
  283. err := errors.New("schema not specified")
  284. return nil, err
  285. }
  286. db, err := GetDB()
  287. if err != nil {
  288. return nil, err
  289. }
  290. items := []StandingOrderItem{}
  291. if tx == nil {
  292. err = db.Select(&items, fmt.Sprintf("SELECT * FROM %s.standing_order_item WHERE order_uuid = $1 ORDER BY line_item", schema), orderUUID)
  293. } else {
  294. err = tx.Select(&items, fmt.Sprintf("SELECT * FROM %s.standing_order_item WHERE order_uuid = $1 ORDER BY line_item", schema), orderUUID)
  295. }
  296. return items, err
  297. }