// Path: tcc-transaction-tutorial-sample/tcc-transaction-sample/tcc-transaction-order/src/main/java/org/pankai/tcctransaction/sample/order/service/PlaceOrderService.java
// @Service
// public class PlaceOrderService {
// 
//     @Autowired
//     private ShopRepository shopRepository;
// 
//     @Autowired
//     private PaymentService paymentService;
// 
//     @Autowired
//     private OrderService orderService;
// 
//     public String placeOrder(long payerUserId, long shopId, List<Pair<Long, Integer>> productQuantities, BigDecimal redPacketPayAmount) {
//         Shop shop = shopRepository.findById(shopId);
//         Order order = orderService.createOrder(payerUserId, shop.getOwnerUserId(), productQuantities);
//         try {
//             paymentService.makePayment(order, redPacketPayAmount, order.getTotalAmount().subtract(redPacketPayAmount));
//         } catch (ConfirmingException e) {
//             //exception throws with the tcc transaction status is CONFIRMING,
//             //when tcc transaction is confirming status,
//             // the tcc transaction recovery will try to confirm the whole transaction to ensure eventually consistent.
//         } catch (CancellingException e) {
//             //exception throws with the tcc transaction status is CANCELLING,
//             //when tcc transaction is under CANCELLING status,
//             // the tcc transaction recovery will try to cancel the whole transaction to ensure eventually consistent.
//         } catch (Throwable e) {
//             //other exceptions throws at TRYING stage.
//             //you can retry or cancel the operation.
//             throw new RuntimeException(e);
//         }
//         return order.getMerchantOrderNo();
//     }
// 
// 
// }
// 
// Path: tcc-transaction-tutorial-sample/tcc-transaction-sample/tcc-transaction-order/src/main/java/org/pankai/tcctransaction/sample/order/web/request/PlaceOrderRequest.java
// public class PlaceOrderRequest {
// 
//     private long payerUserId;
// 
//     private long shopId;
// 
//     private BigDecimal redPacketPayAmount;
// 
//     private List<Pair<Long, Integer>> productQuantities = new ArrayList<Pair<Long, Integer>>();
// 
//     public long getPayerUserId() {
//         return payerUserId;
//     }
// 
//     public void setPayerUserId(long payerUserId) {
//         this.payerUserId = payerUserId;
//     }
// 
//     public long getShopId() {
//         return shopId;
//     }
// 
//     public void setShopId(long shopId) {
//         this.shopId = shopId;
//     }
// 
//     public BigDecimal getRedPacketPayAmount() {
//         return redPacketPayAmount;
//     }
// 
//     public void setRedPacketPayAmount(BigDecimal redPacketPayAmount) {
//         this.redPacketPayAmount = redPacketPayAmount;
//     }
// 
//     public List<Pair<Long, Integer>> getProductQuantities() {
//         return productQuantities;
//     }
// 
//     public void setProductQuantities(List<Pair<Long, Integer>> productQuantities) {
//         this.productQuantities = productQuantities;
//     }
// }


import org.apache.commons.lang3.tuple.ImmutablePair;
import org.pankai.tcctransaction.sample.order.service.PlaceOrderService;
import org.pankai.tcctransaction.sample.order.web.request.PlaceOrderRequest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import java.math.BigDecimal;
import java.security.InvalidParameterException;
package org.pankai.tcctransaction.sample.order.web;



/**
 * Created by pktczwd on 2016/12/16.
 */
@Controller
public class OrderController {

    @Autowired
    private PlaceOrderService placeOrderService;

    @RequestMapping(value = "/placeorder", method = RequestMethod.POST)
    @ResponseBody
    public String placeOrder(@RequestParam String redPacketPayAmount,
                             @RequestParam long shopId,
                             @RequestParam long payerUserId,
                             @RequestParam long productId) {

// Path: tcc-transaction-tutorial-sample/tcc-transaction-sample/tcc-transaction-order/src/main/java/org/pankai/tcctransaction/sample/order/service/PlaceOrderService.java
// @Service
// public class PlaceOrderService {
// 
//     @Autowired
//     private ShopRepository shopRepository;
// 
//     @Autowired
//     private PaymentService paymentService;
// 
//     @Autowired
//     private OrderService orderService;
// 
//     public String placeOrder(long payerUserId, long shopId, List<Pair<Long, Integer>> productQuantities, BigDecimal redPacketPayAmount) {
//         Shop shop = shopRepository.findById(shopId);
//         Order order = orderService.createOrder(payerUserId, shop.getOwnerUserId(), productQuantities);
//         try {
//             paymentService.makePayment(order, redPacketPayAmount, order.getTotalAmount().subtract(redPacketPayAmount));
//         } catch (ConfirmingException e) {
//             //exception throws with the tcc transaction status is CONFIRMING,
//             //when tcc transaction is confirming status,
//             // the tcc transaction recovery will try to confirm the whole transaction to ensure eventually consistent.
//         } catch (CancellingException e) {
//             //exception throws with the tcc transaction status is CANCELLING,
//             //when tcc transaction is under CANCELLING status,
//             // the tcc transaction recovery will try to cancel the whole transaction to ensure eventually consistent.
//         } catch (Throwable e) {
//             //other exceptions throws at TRYING stage.
//             //you can retry or cancel the operation.
//             throw new RuntimeException(e);
//         }
//         return order.getMerchantOrderNo();
//     }
// 
// 
// }
// 
// Path: tcc-transaction-tutorial-sample/tcc-transaction-sample/tcc-transaction-order/src/main/java/org/pankai/tcctransaction/sample/order/web/request/PlaceOrderRequest.java
// public class PlaceOrderRequest {
// 
//     private long payerUserId;
// 
//     private long shopId;
// 
//     private BigDecimal redPacketPayAmount;
// 
//     private List<Pair<Long, Integer>> productQuantities = new ArrayList<Pair<Long, Integer>>();
// 
//     public long getPayerUserId() {
//         return payerUserId;
//     }
// 
//     public void setPayerUserId(long payerUserId) {
//         this.payerUserId = payerUserId;
//     }
// 
//     public long getShopId() {
//         return shopId;
//     }
// 
//     public void setShopId(long shopId) {
//         this.shopId = shopId;
//     }
// 
//     public BigDecimal getRedPacketPayAmount() {
//         return redPacketPayAmount;
//     }
// 
//     public void setRedPacketPayAmount(BigDecimal redPacketPayAmount) {
//         this.redPacketPayAmount = redPacketPayAmount;
//     }
// 
//     public List<Pair<Long, Integer>> getProductQuantities() {
//         return productQuantities;
//     }
// 
//     public void setProductQuantities(List<Pair<Long, Integer>> productQuantities) {
//         this.productQuantities = productQuantities;
//     }
// }


// Path: tcc-transaction-tutorial-sample/tcc-transaction-sample/tcc-transaction-order/src/main/java/org/pankai/tcctransaction/sample/order/web/OrderController.java
import org.apache.commons.lang3.tuple.ImmutablePair;
import org.pankai.tcctransaction.sample.order.service.PlaceOrderService;
import org.pankai.tcctransaction.sample.order.web.request.PlaceOrderRequest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import java.math.BigDecimal;
import java.security.InvalidParameterException;

package org.pankai.tcctransaction.sample.order.web;



/**
 * Created by pktczwd on 2016/12/16.
 */
@Controller
public class OrderController {

    @Autowired
    private PlaceOrderService placeOrderService;

    @RequestMapping(value = "/placeorder", method = RequestMethod.POST)
    @ResponseBody
    public String placeOrder(@RequestParam String redPacketPayAmount,
                             @RequestParam long shopId,
                             @RequestParam long payerUserId,
                             @RequestParam long productId) {

        PlaceOrderRequest request = buildRequest(redPacketPayAmount, shopId, payerUserId, productId);