protected Boolean _Add_Or_Update(int ctsp_id=0, int soluong=0, Boolean update_from_cart=false)
        {
            List<string> validate = new List<string>();
            ChiTietSPController ctr = new ChiTietSPController();
            DonHangController ctr_donhang = new DonHangController();

            //validate id
            if (!ctr.is_exist(ctsp_id))
            {
                return false;
            }

            //get obj
            ChiTiet_DonHang obj = this._giohang.ds_chitiet_donhang.Where(x => x.chitietsp.id == ctsp_id).FirstOrDefault();
            //add or update
            if (obj == null)
            {
                //chưa có trong cart => thêm vào
                ChiTiet_DonHang tmp = new ChiTiet_DonHang();
                tmp.chitietsp = new ChiTietSPController().get_by_id(ctsp_id);
                tmp.dongia = tmp.chitietsp.sanpham.gia;
                tmp.soluong = soluong;
                //just add
                this._giohang.ds_chitiet_donhang.Add(tmp);
            }
            else
            {
                //đã có trong cart
                if (update_from_cart)
                {
                    //cập nhật từ giỏ hàng
                    obj.soluong = soluong;
                }
                else
                {
                    //thêm từ nơi khác
                    obj.soluong += soluong;
                }
            }
            //validate giohang
            validate.AddRange(ctr_donhang.validate(this._giohang, out this._giohang));
            //finally call save
            this._save_cart_to_session();

            TempData["state"] = validate;
            return true;
        }
 /* Sử dụng khi lưu đon hàng, do có quá nhiều DBContext tracking nên bắt buộc phải Clone ra obj mới theo
  * this._db thì mới lưu được không sẽ bị báo lỗi
  *
  */
 private DonHang _Clone(DonHang obj)
 {
     DonHang tmp = new DonHang();
     tmp.active = obj.active;
     tmp.ds_chitiet_donhang = new List<ChiTiet_DonHang>();
     foreach (var item in obj.ds_chitiet_donhang)
     {
         ChiTiet_DonHang ct = new ChiTiet_DonHang();
         ct.chitietsp = this._db.ds_chitietsp.Where(x => x.id == item.chitietsp.id).FirstOrDefault();
         ct.dongia = item.dongia;
         ct.soluong = item.soluong;
         tmp.ds_chitiet_donhang.Add(ct);
     }
     if (obj.khachhang != null)
     {
         tmp.khachhang = this._db.ds_khachhang.Where(x => x.id == obj.khachhang.id).FirstOrDefault();
     }
     if (obj.khachhang_nhanvien != null)
     {
         tmp.khachhang_nhanvien = this._db.ds_nhanvien.Where(x => x.id == obj.khachhang_nhanvien.id).FirstOrDefault();
     }
     tmp.ngay = obj.ngay;
     tmp.nguoinhan_diachi = obj.nguoinhan_diachi;
     tmp.nguoinhan_diachi_tinhtp = this._db.ds_tinhtp.Where(x => x.id == obj.nguoinhan_diachi_tinhtp.id).FirstOrDefault();
     tmp.nguoinhan_sdt = obj.nguoinhan_sdt;
     tmp.nguoinhan_ten = obj.nguoinhan_ten;
     if (obj.nhanvien != null)
     {
         tmp.nhanvien = this._db.ds_nhanvien.Where(x => x.id == obj.nhanvien.id).FirstOrDefault();
     }
     tmp.phivanchuyen = obj.phivanchuyen;
     tmp.thanhtoan_tructuyen = obj.thanhtoan_tructuyen;
     tmp.tongtien = obj.tongtien;
     tmp.trangthai = obj.trangthai;
     return tmp;
 }