using DocumentFormat.OpenXml.EMMA; using Model; using Org.BouncyCastle.Asn1.Ocsp; using PagedList; using System; using System.Collections.Generic; using System.Data.Entity; using System.Linq; using System.Threading.Tasks; using System.Web; using System.Web.Http; using static Model.admin_log; /// /// guadanOderController 的摘要描述 /// [ezAuthorize] public class guadanOrderController : ApiController { private Model.ezEntities _db = new Model.ezEntities(); [HttpPost] [Route("api/guadan/list")] public async Task getGuadanList([FromBody] guadan_order_search_dto search) { var lastCheckoutTime = _db.GuadanTimeSetting.FirstOrDefault(); string lastCheckoutTimeStr = null; if (lastCheckoutTime != null) { lastCheckoutTimeStr = lastCheckoutTime.LatestCheckOut; } var query = _db.GuaDanOrder .Where(a => a.IsCancel == false) .Where(a => a.IsDeleted == false); if(!string.IsNullOrEmpty(search.guaDanOrderNo)) { query = query.Where(order => order.GuaDanOrderNo == search.guaDanOrderNo); } if (search.guadanUser != null) { query = query.Where(order => order.BookerName == search.guadanUser); } if (search.startDate != null && search.endDate != null) { query = query.Where(order => order.StartDate >= search.startDate) .Where(order => order.EndDate <= search.endDate); } else { if (search.startDate != null) { query = query.Where(order => order.StartDate == search.startDate); } else if (search.endDate != null) { query = query.Where(order => order.EndDate == search.endDate); } } var total = query.Count(); var data1 = await query.ToListAsync(); var data = data1 .OrderByDescending(b => b.CreatedAt) .Select(a => new { uuid = a.Uuid, guaDanOrderNo = a.GuaDanOrderNo, start_date = a.StartDate, end_date = a.EndDate, created_at = a.CreatedAt, updated_at = a.UpdatedAt, notes = a.Notes, is_timeout = !string.IsNullOrEmpty(lastCheckoutTimeStr) && _db.GuaDanOrderGuest .Where(g => g.GuaDanOrderNo == a.GuaDanOrderNo && !g.IsDeleted && g.StatusCode == GuaDanOrderGuest.STATUS_CHECKED_IN) .ToList() .Any(g => g.CheckOutAt.HasValue && DateTime.Parse(g.CheckOutAt.Value.ToString("yyyy-MM-dd") + " " + lastCheckoutTimeStr) < DateTime.Now ), activity = _db.activities .Where(act => act.num == a.ActivityNum) .Select(act => new { subject = act.subject }) .FirstOrDefault(), bookerName = a.BookerName, guest_count = _db.GuaDanOrderGuest .Where(c => c.GuaDanOrderNo == a.GuaDanOrderNo && c.IsDeleted == false) .Where(c => c.RegionRoomBedStatus.Code != GuaDanOrderGuest.STATUS_CANCELLED) .Count(), guadan_status = _db.GuaDanOrderGuest .Where(g => g.GuaDanOrderNo == a.GuaDanOrderNo && a.IsDeleted == false) .Where(g => g.StatusCode != GuaDanOrderGuest.STATUS_CANCELLED) .All(g => g.StatusCode == "401") ? new { code=501, name="預約" }: _db.GuaDanOrderGuest .Where(g => g.GuaDanOrderNo == a.GuaDanOrderNo && a.IsDeleted == false) .Where(g => g.StatusCode != GuaDanOrderGuest.STATUS_CANCELLED) .All(g => g.StatusCode == "403") ? new { code = 502, name = "全部退房" } : _db.GuaDanOrderGuest .Where(g => g.GuaDanOrderNo == a.GuaDanOrderNo && a.IsDeleted == false) .Where(g => g.StatusCode != GuaDanOrderGuest.STATUS_CANCELLED) .Any(g => g.StatusCode == "402" && a.IsCancel == false) ? new { code = 503, name = "正在入住" } : new { code = 504, name = "部分退房" } }) .Skip((search.page - 1) * search.pageSize) .Take(search.pageSize) .ToList(); return Ok(new { total, data }); } [HttpGet] [Route("api/guadan/getorderbyid")] public async Task getGuadanOrderById(string orderId) { var order = await _db.GuaDanOrder .Where(a => a.GuaDanOrderNo == orderId) .Where(a => a.IsCancel == false && a.IsDeleted == false) .FirstOrDefaultAsync(); if (order == null) { return BadRequest("未找到對應訂單"); } var result = new { order.admin, order.followers, StartDate = order.StartDate?.ToString("yyyy-MM-dd"), EndDate = order.EndDate?.ToString("yyyy-MM-dd"), order.CreateUser, order.CreatedAt, order.UpdatedAt, order.Notes, order.GuaDanOrderNo, order.BookerFollowerNum, order.BookerName, order.BookerPhone, order.IsDeleted, order.Uuid, order.ActivityNum, }; return Ok(result); } [HttpPost] [Route("api/guadan/create")] public async Task createGuadanOrder(GuaDanOrderView model) { if (model == null) { return BadRequest("掛單資料不可為空"); } if (model.Uuid.HasValue) { return BadRequest("已存在對應掛單資料"); } try { if (model.startdate > model.enddate) { return BadRequest("掛單結束時間不能再開始時間之前"); } } catch { } var guadanorder = new GuaDanOrder { StartDate = model.startdate, EndDate = model.enddate, CreateUser = model.createuser, CreatedAt = DateTime.Now, UpdatedAt = DateTime.Now, Notes = model.note, GuaDanOrderNo = GuaDanOrder.GenerateStatusCode(), BookerName = model.bookerName, BookerPhone = model.bookerPhone, Uuid = Guid.NewGuid(), ActivityNum = model.activityNum, }; _db.GuaDanOrder.Add(guadanorder); await _db.SaveChangesAsync(); return Ok(guadanorder); } [HttpPost] [Route("api/guadan/saveGandan")] public async Task SaveGandan([FromBody] dynamic req) { var json = req; if (json != null&&json.order!=null) { var order = json.order; if (string.IsNullOrEmpty(order.GuaDanOrderNo)) {//表示新增掛單 // 生成新的掛單編號跟uuid var guadanorder = new GuaDanOrder { StartDate = order.startdate, EndDate = order.enddate, CreateUser = order.createuser, CreatedAt = DateTime.Now, UpdatedAt = DateTime.Now, Notes = order.note, GuaDanOrderNo = GuaDanOrder.GenerateStatusCode(), BookerName = order.bookerName, BookerPhone = order.bookerPhone, Uuid = Guid.NewGuid(), ActivityNum = order.activityNum, }; //掛單明細 var list = new List(); var guest = new GuaDanOrderGuest(); var bedList = new List(); if (json.detail!=null) { var details = json.detail; foreach (var detail in details) { guest=new GuaDanOrderGuest { GuaDanOrderNo = guadanorder.GuaDanOrderNo, Uuid = Guid.NewGuid(), StatusCode = GuaDanOrderGuest.STATUS_BOOKED, // 預約狀態 RoomUuid = detail.roomUuid, BedUuid = detail.bedUuid, CheckInAt = detail.checkInAt, CheckOutAt = detail.checkOutAt, Sex = detail.gender, Handi = detail.handi, IsDeleted = false, Name = detail.name, }; list.Add(guest); if (!Guid.TryParse((string)detail.bedUuid, out Guid targetGuid)) { return BadRequest("無效的 GUID 格式"); } if (detail.bedUuid!=null&&!string.IsNullOrEmpty((string)detail.bedUuid)) { var bed = _db.RegionRoomBed.Where(r => r.Uuid == targetGuid); if (bed == null) return BadRequest("床位不存在"); // 檢查床位可用性 var bedIsCanUse = await RegionAndRoomAndBedSchedule.IsBedAvailableAsync( _db, targetGuid, guest.CheckInAt.Value, guest.CheckOutAt.Value ); if (!bedIsCanUse) return BadRequest("床位在該時間段內已被占用"); } else { return BadRequest("未設定床位"); } int totalDays = (guest.CheckOutAt.Value - guest.CheckInAt.Value).Days; for (int i = 0; i < totalDays; i++) { var scheduleDate = guest.CheckOutAt.Value.AddDays(i); var schedul = new RegionAndRoomAndBedSchedule { Title = "掛單", Description = "床位掛單", ScheduleDate = scheduleDate, IsDeleted = false, IsCancel = false, TargetUuid = guest.BedUuid, UseType = (int)RegionAndRoomAndBedSchedule.SchedulePurpose.Bed_Reservation, CreatedAt = DateTime.Now, GuaDanOrderNo = guest.GuaDanOrderNo, Uuid = Guid.NewGuid(), GuaDanOrderGuestUuid = guest.Uuid, }; //_db.RegionAndRoomAndBedSchedule.Add(schedul); bedList.Add(schedul); } } } _db.GuaDanOrder.Add(guadanorder); _db.GuaDanOrderGuest.AddRange(list); _db.RegionAndRoomAndBedSchedule.AddRange(bedList); _db.SaveChanges(); } else {//表示更新掛單 var model =await _db.GuaDanOrder.FindAsync((string)order.Uuid); if (model == null) { return BadRequest("未找到對應掛單資料"); } model.StartDate = order.startdate; model.EndDate = order.enddate; model.Notes = order.note; model.BookerName = order.bookerName; model.BookerPhone = order.bookerPhone; model.ActivityNum = order.activityNum; //更新掛單明細...還要處理RegionAndRoomAndBedSchedule } //if (json.detail != null) //{ // var details = json.detail; // foreach (var detail in details) // { // var guadanDetail = new GuaDanOrderGuest // { // GuaDanOrderNo = order.GuaDanOrderNo, // //FollowerNum = detail.guestName, // Uuid = detail.uuid, // StatusCode = "401", // 預約狀態 // RoomUuid = detail.roomUuid, // BedUuid = detail.bedUuid, // CheckInAt = detail.checkInAt, // CheckOutAt = detail.checkOutAt, // Sex = detail.gender, // Handi = detail.handi, // IsDeleted = false, // Name = detail.name, // }; // _db.GuaDanOrderGuest.Add(guadanDetail); // } // //return BadRequest("掛單資料不可為空"); //} } return Ok(); } [HttpPost] [Route("api/guadan/update")] public async Task updateGuadanOrder(GuaDanOrderView model) { if (model == null) { return BadRequest("掛單資料不可為空"); } if (!model.Uuid.HasValue) { return BadRequest(""); } try { if (model.startdate > model.enddate) { return BadRequest("掛單結束時間不能再開始時間之前"); } } catch { } var order = await _db.GuaDanOrder.FindAsync(model.Uuid.Value); if (order == null) { return BadRequest("未找到對應掛單資料"); } order.StartDate = model.startdate; order.EndDate = model.enddate; order.Notes = model.note; order.BookerName = model.bookerName; order.BookerPhone = model.bookerPhone; order.ActivityNum = model.activityNum; await _db.SaveChangesAsync(); return Ok(model); } [HttpPost] [Route("api/guadan/cancel")] public async Task CancelGuadanOrder([FromUri] Guid uuid) { var guadan = await _db.GuaDanOrder.FindAsync(uuid); if (guadan == null) { return NotFound(); } if (_db.GuaDanOrderGuest.Any(a => (a.GuaDanOrderNo == guadan.GuaDanOrderNo) && a.StatusCode != "404")) { return BadRequest($"該掛單已經存在掛單蓮友,不能取消!"); } using (var transaction = _db.Database.BeginTransaction()) { try { var guadanGuests = await _db.GuaDanOrderGuest .Where(a => a.GuaDanOrderNo == guadan.GuaDanOrderNo) .ToListAsync(); if (guadanGuests.Any()) { foreach (var guest in guadanGuests) { guest.StatusCode = "404"; // 取消所有相關的排程 if (guest.RegionAndRoomAndBedSchedule != null && guest.RegionAndRoomAndBedSchedule.Any()) { foreach (var schedule in guest.RegionAndRoomAndBedSchedule) { schedule.IsCancel = true; } } } await _db.SaveChangesAsync(); } guadan.IsCancel = true; await _db.SaveChangesAsync(); transaction.Commit(); return Ok(new { message = "取消成功" }); } catch (Exception ex) { transaction.Rollback(); return InternalServerError(ex); } } } public class guadan_order_dto { public int id { get; set; } public int room_id { get; set; } public int bed_id { get; set; } public int guest_id { get; set; } public DateTime start_date { get; set; } public DateTime? end_date { get; set; } public int? create_user { get; set; } public DateTime created_at { get; set; } public DateTime updated_at { get; set; } public string notes { get; set; } public int? follower_num { get; set; } public Room room { get; set; } = null; public RegionRoomBed bed { get; set; } = null; } public class guadan_order_search_dto { public DateTime? startDate { get; set; } public DateTime? endDate { get; set; } public string guadanUser { get; set; } public int page { get; set; } = 1; public int pageSize { get; set; } = 10; public string guaDanOrderNo { get; set; } = null; } }