/*_______________________________________________________________________________ Get order */ func GetOrder(field string, value interface{}) (*model.Order, error) { p := new(model.Order) if err := em.Select().Where(field, value).Query( func(rows *sql.Rows) (bool, error) { return false, rows.Scan( &p.Id, &p.TrackNumber, &p.Status, &p.Type, &p.CustomerId, &p.DeliveryMethod, &p.DeliveryTrackingNumber, &p.ExpressFee, &p.ShippingAddress, &p.TotalPrice, &p.TotalCount, &p.PriceCut, &p.Accumulated, &p.Note, &p.ParentTrackNumber, &p.CreateTime, &p.UpdateTime, &p.CloseTime, ) }, ); err != nil { return nil, err } if p.Id > 0 { // cascade details, err := GetOrderDetails(p.TrackNumber) if err != nil { return nil, err } p.Details = details return p, nil } // return nil, errors.New("Order not found!") // return error if not exists.p return nil, nil // ignore when entity not exits. }
func tosimple(order *model.Order) *SimpleOrder { return &SimpleOrder{ TrackNumber: order.TrackNumber, CreateTime: order.CreateTime, OrderPrice: order.SumOrderPrice(), } }
// 创建订单的所有逻辑都在这里 func (s *OrderService) CreateOrder(order *model.Order) (*model.Order, error) { // 这个步骤很重要,判断是否订单已经存在了;如果存在了,需要换一个订单号再试; if newtn := makeSureOrderTNUnique(order.TrackNumber); newtn > 0 { order.TrackNumber = newtn } for _, detail := range order.Details { detail.OrderTrackNumber = order.TrackNumber } var needUpdateBallance = false // 需要写入Person的累计欠款 // If order delivery method is `takeaway`, chagne order status to `delivering` and // update account ballance; In other situation change status to `toprint`. if order.DeliveryMethod == "TakeAway" { order.Status = "delivering" needUpdateBallance = true } else { order.Status = "toprint" } // organize some data _processOrderCustomerPrice(order) _calculateOrder(order) // create order detail into db; if order.Details != nil && len(order.Details) > 0 { if err := orderdao.CreateOrderDetail(order.Details); err != nil { return nil, err } } // create order into db // fmt.Println("======================================") // fmt.Println("order.CreateTimeis ", order.CreateTime) // fmt.Println("======================================") if err := orderdao.CreateOrder(order); err != nil { return nil, err } _update_order_accumulated(order) // debug option // update account ballance if needUpdateBallance { Account.UpdateAccountBalance(order.CustomerId, -order.SumOrderPrice(), "Create Order", order.TrackNumber) // last step: update stocks. 修改累计欠款的时候就修改库存; _reduceProductStocks(order.Details) } return order, nil }
// calculate order, func _calculateOrder(order *model.Order) { switch model.OrderType(order.Type) { case model.SubOrder, model.Wholesale: if order.Details != nil && len(order.Details) > 0 { order.CalculateOrder() } case model.ShippingInstead: // this type of order's total price is calculated by sub // orders, which is difficult to calculate, so I calclate sum // in page, and then submit to the parent order. // So, here does nothing. } }
func _update_order_accumulated(order *model.Order) error { if debug_always_update_order_accumulated { // always update order.accumulated // 4. get person, check if customer exists. customer, err := Person.GetPersonById(order.CustomerId) if err != nil { return err } else if customer == nil { return errors.New(fmt.Sprintf("Customer not found for order! id %v", order.CustomerId)) } // 5. 设置累计欠款; order.Accumulated = -customer.AccountBallance } return nil }
// Create new Order item in db. Only OrderService call this. Not including details. // TODO: Add transaction support. func CreateOrder(order *model.Order) error { if logdebug { log.Printf("[dal] Create Order: %v", order) } // 1. create connection. res, err := em.Insert().Exec( order.TrackNumber, order.Status, order.Type, order.CustomerId, order.DeliveryMethod, order.DeliveryTrackingNumber, order.ExpressFee, order.ShippingAddress, order.TotalPrice, order.TotalCount, order.PriceCut, order.Accumulated, order.Note, order.ParentTrackNumber, time.Now(), time.Now(), time.Now(), ) fmt.Println("======================================") fmt.Println("order.CreateTimeis ", time.Now()) fmt.Println("======================================") if err != nil { return err } liid, err := res.LastInsertId() order.Id = int(liid) return nil }
// Update Order 的所有逻辑都在这里了; func (s *OrderService) UpdateOrder(order *model.Order) (*model.Order, error) { // 更新 Tracking Number 到子订单的 Tracking No for _, detail := range order.Details { // TODO: additional check if order tracking number not match; detail.OrderTrackNumber = order.TrackNumber } var needUpdateBallance = false // If status change from other to takeaway, mark as need update ballance. // Order中只包含新数据,旧的数据必须从数据库中取出了;也顺便再次验证是否存在这个订单; if oldOrder, err := s.GetOrder(order.Id); err != nil { return nil, err // panic(err) } else { // this makes mistake. // if oldOrder.DeliveryMethod == "TakeAway" { // return nil, errors.New("自提状态的订单不能再修改!") // } // 自提,非自提;状态是发货中,和其他 // 更新情况1: 修改订单时,由非自提状态改为自提状态,需要修改累计欠款; if oldOrder.DeliveryMethod != "TakeAway" && order.DeliveryMethod == "TakeAway" { order.Status = "delivering" needUpdateBallance = true } // 更新情况2: 非自提状态点发货,} if order.Status == "delivering" { // 需要修改累计欠款 if oldOrder.Status == "done" || oldOrder.Status == "canceled" { return nil, errors.New(fmt.Sprintf("%s状态的订单状态不能修改为delivering!", oldOrder.Status)) } needUpdateBallance = true } // update order _processOrderCustomerPrice(order) // update order custumize price when confirm order. _calculateOrder(order) // calculate order statistic fields. _processingUpdateOrderDetails(order) // update order detail into db; _update_order_accumulated(order) // debug option // update order if _, err := orderdao.UpdateOrder(order); err != nil { return nil, err } } // update account ballance. upate stocks left. if needUpdateBallance { // 代发的父订单不参与非累计欠款, 代发订单由其子订单负责参与累计欠款的统计; // 代发父订单的逻辑应该也到不了这里。 fmt.Println(">> update account ballance. delta: ", -order.SumOrderPrice()) switch model.OrderType(order.Type) { case model.Wholesale, model.SubOrder: Account.UpdateAccountBalance(order.CustomerId, -order.SumOrderPrice(), "Create Order", order.TrackNumber) } // update stocks _reduceProductStocks(order.Details) } return order, nil }