public void UpdateAppointmentStatus(Guid rowGuid, string statusCode)
        {
            AG_B_APPOINTMENT appointment = DBContext.AG_B_APPOINTMENT.FirstOrDefault(E => E.ROWGUID == rowGuid);

            if (appointment == null)
            {
                throw new NotFoundException($"Cannot find appointment with RowGuid={rowGuid}");
            }

            appointmentStatus.CheckNewStatusAllowed(appointment, statusCode);

            appointment.STATUS_CODE = statusCode;
            EntityMapper.UpdateEntityStandardFields(appointment);

            AG_B_APPOINTMENT_STATUS_HISTORY history = DBContext.AG_B_APPOINTMENT_STATUS_HISTORY.FirstOrDefault(E => E.ROWGUID == rowGuid);

            if (history != null)
            {
                if (statusCode == appointmentStatus.Confirmed)
                {
                    history.CONFIRMATION_STATUS = statusCode;
                    history.CONFIRMED_DATE      = DateTime.Now;
                    history.CONFIRMED_USER      = appointment.USERUPDATE;
                    EntityMapper.UpdateEntityStandardFields(history);
                }
                else if (statusCode == appointmentStatus.Deleted || statusCode == appointmentStatus.Rescheduled)
                {
                    history.CONFIRMATION_STATUS = statusCode;
                    history.CANCEL_DATE         = DateTime.Now;
                    history.CANCEL_USER         = appointment.USERUPDATE;
                    EntityMapper.UpdateEntityStandardFields(history);
                }
            }
            DBContext.SaveChanges();
        }
예제 #2
0
 public AppointmentBase(AG_B_APPOINTMENT Entity) : base(Entity.ROWGUID)
 {
     AppointmentID       = Entity.APPOINTMENT_ID;
     StatusCode          = Entity.STATUS_CODE;
     AppointmentDate     = Entity.DT_APPOINTMENT;
     Duration            = Entity.DURATION.GetValueOrDefault();
     EmployeeCode        = Entity.EMPLOYEE_CODE;
     CustomerCode        = Entity.CUSTOMER_CODE;
     AppointmentShopCode = Entity.APPOINTMENT_SHOP_CODE;
     ServiceCode         = Entity.SERVICE_CODE;
     Note = Entity.NOTE;
 }
        public ActionResult <AppointmentListItem> Get(Guid rowGuid)
        {
            AppointmentListItem Result = null;
            AG_B_APPOINTMENT    Item   = DBContext.AG_B_APPOINTMENT.FirstOrDefault(E => E.ROWGUID == rowGuid);

            if (Item == null)
            {
                throw new NotFoundException($"No appointment found with rowGuid: {rowGuid}");
            }

            Result = EntityMapper.Map <AppointmentListItem, AG_B_APPOINTMENT>(DBContext, Item, Item.AG_B_APPOINTMENT_EXT_AUS);

            return(Result);
        }
        public ActionResult <AppointmentListItem> Reschedule(Guid rescheduledAppointmentRowGuid, [FromBody] AppointmentBase value)
        {
            if (value == null)
            {
                throw new ArgumentNullException(nameof(value), $"Argument value cannot be null");
            }

            AG_B_APPOINTMENT oldAppointment = DBContext.AG_B_APPOINTMENT.SingleOrDefault(E => E.ROWGUID == rescheduledAppointmentRowGuid);

            if (oldAppointment == null)
            {
                throw new NotFoundException($"No appointment found with RowGuid:{rescheduledAppointmentRowGuid}");
            }

            if (oldAppointment.AG_B_APPOINTMENT_EXT_AUS.RESCHEDULED_NUMBER.GetValueOrDefault(0) >= 3)
            {
                throw new InvalidOperationException("Appointment reschedule max number exceeded");
            }

            oldAppointment.AG_B_APPOINTMENT_EXT_AUS.RESCHEDULED_NUMBER = oldAppointment.AG_B_APPOINTMENT_EXT_AUS.RESCHEDULED_NUMBER.GetValueOrDefault(0) + 1;

            using (IDbContextTransaction scope = DBContext.Database.BeginTransaction())
            {
                UpdateAppointmentStatus(oldAppointment.ROWGUID, appointmentStatus.Rescheduled);
                AppointmentListItem Result = DoPost(value, rescheduledAppointmentRowGuid: rescheduledAppointmentRowGuid);

                CU_B_ACTIVITY         activity    = EntityMapper.CreateEntity <CU_B_ACTIVITY>();
                CU_B_ACTIVITY_EXT_AUS activityExt = EntityMapper.CreateEntity <CU_B_ACTIVITY_EXT_AUS>();
                activity.ACTIVITY_TYPE_CODE      = "DY";
                activity.ACTIVITY_DATE           = DateTime.Today;
                activity.CUSTOMER_CODE           = activityExt.CUSTOMER_CODE = Result.CustomerCode;
                activity.EMPLOYEE_CODE           = Result.EmployeeCode;
                activity.REFERENCE_DATE          = oldAppointment.DT_APPOINTMENT;
                activity.REFERENCE_NUMBER        = oldAppointment.APPOINTMENT_ID;
                activity.APPOINTMENT_ID          = Result.AppointmentID;
                activityExt.DT_APPOINTEMENT_FROM = oldAppointment.DT_APPOINTMENT;
                activityExt.DT_APPOINTEMENT_TO   = Result.AppointmentDate;
                activity.ACTIVITY_ID             = activityExt.ACTIVITY_ID = FoxDataService.GetNewCounter("CU_B_ACTIVITY", "ACTIVITY_ID", Result.StatusCode, activity.USERINSERT).VALUE.GetValueOrDefault();
                activity.SHOP_CODE = activity.LAPTOP_CODE = activityExt.SHOP_CODE = activityExt.LAPTOP_CODE = Result.ShopCode;
                DBContext.CU_B_ACTIVITY.Add(activity);
                DBContext.CU_B_ACTIVITY_EXT_AUS.Add(activityExt);

                DBContext.SaveChanges();
                scope.Commit();

                return(Result);
            }
        }
        public void Put(Guid rowGuid, [FromBody] AppointmentBase value)
        {
            if (value == null)
            {
                throw new ArgumentNullException(nameof(value), $"Argument value cannot be null");
            }

            AG_B_APPOINTMENT Item = DBContext.AG_B_APPOINTMENT.SingleOrDefault(E => E.ROWGUID == rowGuid);

            if (Item == null)
            {
                throw new NotFoundException($"No appointment found with RowGuid:{rowGuid}");
            }

            OperationResult <bool> check = CheckCanBookAppointment(value.CustomerCode, value.AppointmentShopCode, value.ServiceCode, value.AppointmentDate, rowGuid);

            if (!check.Result)
            {
                throw new InvalidOperationException(check.Message);
            }

            EntityMapper.UpdateEntity(value, Item, Item.AG_B_APPOINTMENT_EXT_AUS);

            value.SaveData <AG_B_APPOINTMENT>(DBContext, Item);

            if (string.IsNullOrEmpty(Item.SHOP_CODE))
            {
                Item.SHOP_CODE = Item.AG_B_APPOINTMENT_EXT_AUS.SHOP_CODE = Item.LAPTOP_CODE = Item.AG_B_APPOINTMENT_EXT_AUS.LAPTOP_CODE = Item.APPOINTMENT_SHOP_CODE;
            }


            CM_B_SHOP shop = DBContext.CM_B_SHOP.FirstOrDefault(E => E.SHOP_CODE == Item.SHOP_CODE);


            value.SaveData <AG_B_APPOINTMENT>(DBContext, Item);

            using (IDbContextTransaction scope = DBContext.Database.BeginTransaction())
            {
                CheckAppointmentOverlap(Item);
                //Complete the scope here to commit, otherwise it will rollback
                //The table lock will be released after we exit the TransactionScope block
                DBContext.SaveChanges();
                scope.Commit();
            }
        }
        public ActionResult <AppointmentListItem> CustomerNextAppointment(string id)
        {
            AppointmentListItem Result = null;
            //Take next appointment
            AG_B_APPOINTMENT Appointment = DBContext.AG_B_APPOINTMENT.OrderBy(E => E.DT_APPOINTMENT).FirstOrDefault(E => E.CUSTOMER_CODE == id && E.DT_APPOINTMENT >= DateTime.Today && AllowedAppointmentStatus.Contains(E.STATUS_CODE));

            if (Appointment == null)             //Take last appointment
            {
                Appointment = DBContext.AG_B_APPOINTMENT.OrderByDescending(E => E.DT_APPOINTMENT).FirstOrDefault(E => E.CUSTOMER_CODE == id && E.DT_APPOINTMENT < DateTime.Today);
            }

            if (Appointment != null)
            {
                Result = EntityMapper.Map <AppointmentListItem, AG_B_APPOINTMENT>(DBContext, Appointment, Appointment.AG_B_APPOINTMENT_EXT_AUS);
            }

            return(Result);
        }
예제 #7
0
        public void CheckNewStatusAllowed(AG_B_APPOINTMENT appointment, string newStatus)
        {
            string oldStatus = appointment.STATUS_CODE;

            if (oldStatus == Open && (newStatus != Confirmed && newStatus != Deleted && newStatus != Rescheduled))
            {
                throw new InvalidOperationException("Invalid status for an open appointment");
            }
            else if (oldStatus == Rescheduled && newStatus != Rescheduled)
            {
                throw new InvalidOperationException("Cannot change status on a rescheduled appointment");
            }
            else if (oldStatus == Arrived && (newStatus != Completed && newStatus != Deleted))
            {
                throw new InvalidOperationException("Invalid status for an arrived appointment");
            }
            else if (newStatus == Deleted && appointment.DT_APPOINTMENT < DateTime.Today)
            {
                throw new InvalidOperationException("Cannot delete past appointments");
            }
        }
        void CheckAppointmentOverlap(AG_B_APPOINTMENT appointment)
        {
            string[] specialAvailabilityServiceCodes = FoxDataService.GetSpecialAvailabilityServiceCodes(appointment.SHOP_CODE);
            //Lock the table during this transaction
            DBContext.AG_B_APPOINTMENT.FromSql("SELECT TOP 1 * FROM AG_B_APPOINTMENT WITH (TABLOCKX, HOLDLOCK)");

            //Check for overlap
            DateTime appointmentStart = appointment.DT_APPOINTMENT;
            DateTime appointmentEnd   = appointment.DT_APPOINTMENT.AddMinutes(appointment.DURATION.GetValueOrDefault());

            int overlappedAppointmentCount = DBContext.AG_B_APPOINTMENT.Where(E => E.ROWGUID != appointment.ROWGUID && AllowedAppointmentStatus.Contains(E.STATUS_CODE) &&
                                                                              (E.ROOM_CODE == appointment.ROOM_CODE || E.EMPLOYEE_CODE == appointment.EMPLOYEE_CODE) &&
                                                                              !specialAvailabilityServiceCodes.Contains(E.AG_S_SERVICE.SERVICE_TYPE_CODE) &&
                                                                              ((E.DT_APPOINTMENT >= appointmentStart && E.DT_APPOINTMENT < appointmentEnd) ||
                                                                               (E.DT_APPOINTMENT.AddMinutes(E.DURATION.GetValueOrDefault()) > appointmentStart && E.DT_APPOINTMENT.AddMinutes(E.DURATION.GetValueOrDefault()) < appointmentEnd) ||
                                                                               (E.DT_APPOINTMENT <= appointmentStart && E.DT_APPOINTMENT.AddMinutes(E.DURATION.GetValueOrDefault()) > appointmentEnd))).Count();

            if (overlappedAppointmentCount > 0)
            {
                throw new Exception("There is already an appointment for the given time slot");
            }
        }
        public override void LoadData <T>(DbContext context, dynamic entity)
        {
            base.LoadData <T>(context, (T)entity);

            DiaryContext     DBContext   = (DiaryContext)context;
            AG_B_APPOINTMENT appointment = (AG_B_APPOINTMENT)entity;

            //EmployeeName = string.Format("{0} {1}", appointment.CM_S_EMPLOYEE?.FIRSTNAME, appointment.CM_S_EMPLOYEE?.LASTNAME);
            EmployeeName       = appointment.CM_S_EMPLOYEE?.EMPLOYEE_DESCR;
            ServiceDescription = appointment.AG_S_SERVICE?.SERVICE_DESCR;

            StatusDescription = DBContext.SY_GENERAL_STATUS.FirstOrDefault(E => E.STATUS_CODE == StatusCode)?.STATUS_DESCR;
            CU_B_ADDRESS_BOOK Customer = DBContext.CU_B_ADDRESS_BOOK.FirstOrDefault(E => E.CUSTOMER_CODE == CustomerCode);

            if (Customer != null)
            {
                CustomerName = string.Format("{0} {1}", Customer.FIRSTNAME, Customer.LASTNAME);
            }
            CM_B_SHOP Shop = DBContext.CM_B_SHOP.FirstOrDefault(E => E.SHOP_CODE == AppointmentShopCode);

            AppointmentShopDescription = Shop?.SHOP_DESCR;
            CM_S_CITY_BOOK_SHOP ShopArea = DBContext.CM_S_CITY_BOOK_SHOP.FirstOrDefault(E => E.SHOP_CODE == AppointmentShopCode);

            AreaCode = ShopArea?.AREA_CODE;
            CM_S_AREA_BOOK AreaBook = DBContext.CM_S_AREA_BOOK.FirstOrDefault(E => E.AREA_CODE == AreaCode);

            AreaDescription = AreaBook?.AREA_DESCR;
            RegionCode      = AreaBook?.REGION_CODE;
            CM_S_REGION_BOOK Region = DBContext.CM_S_REGION_BOOK.FirstOrDefault(E => E.REGION_CODE == RegionCode);

            RegionDescription = Region?.REGION_DESCR;
            CU_B_ACTIVITY activity = DBContext.CU_B_ACTIVITY.FirstOrDefault(E => E.ACTIVITY_TYPE_CODE == "PR" && E.CUSTOMER_CODE == appointment.CUSTOMER_CODE && E.APPOINTMENT_ID == appointment.APPOINTMENT_ID);

            MediaTypeDescription = activity?.CM_S_MEDIATYPE?.MEDIATYPE_DESCR;
            AG_S_ROOM room = DBContext.AG_S_ROOM.FirstOrDefault(E => E.SHOP_CODE == appointment.APPOINTMENT_SHOP_CODE && E.ROOM_CODE == appointment.ROOM_CODE);

            RoomDescription = room?.ROOM_DESCR;
        }
 public AppointmentListItem(AG_B_APPOINTMENT Entity) : base(Entity)
 {
 }
        private AppointmentListItem DoPost(AppointmentBase value, string campaignCode = null, string mediaTypeCode = null, string callID = null, Guid?rescheduledAppointmentRowGuid = null)
        {
            if (value == null)
            {
                throw new ArgumentNullException(nameof(value), "Argument 'value' cannot be null");
            }

            OperationResult <bool> check = CheckCanBookAppointment(value.CustomerCode, value.AppointmentShopCode, value.ServiceCode, value.AppointmentDate, rescheduledAppointmentRowGuid.GetValueOrDefault(Guid.Empty));

            if (!check.Result)
            {
                throw new InvalidOperationException(check.Message);
            }

            AG_B_APPOINTMENT         Item    = EntityMapper.CreateEntity <AG_B_APPOINTMENT>();
            AG_B_APPOINTMENT_EXT_AUS ItemExt = EntityMapper.CreateEntity <AG_B_APPOINTMENT_EXT_AUS>();

            CU_B_ACTIVITY         activity    = EntityMapper.CreateEntity <CU_B_ACTIVITY>();
            CU_B_ACTIVITY_EXT_AUS activityExt = EntityMapper.CreateEntity <CU_B_ACTIVITY_EXT_AUS>();

            AG_B_APPOINTMENT_STATUS_HISTORY history = EntityMapper.CreateEntity <AG_B_APPOINTMENT_STATUS_HISTORY>();

            if ((string.IsNullOrWhiteSpace(value.StatusCode) || value.StatusCode == appointmentStatus.Open) && value.AppointmentDate >= DateTime.Today && value.AppointmentDate < DateTime.Today.AddDays(2))
            {
                value.StatusCode = appointmentStatus.Confirmed;
            }

            EntityMapper.UpdateEntity(value, Item, ItemExt);

            //Add default or other values
            Item.APPOINTMENT_ID = ItemExt.APPOINTMENT_ID = string.Format("{0}00{1}", Item.APPOINTMENT_SHOP_CODE, FoxDataService.GetNewCounter("AG_B_APPOINTMENT", "APPOINTMENT_ID", "*", Item.USERINSERT).FORMATTEDVALUE);
            if (string.IsNullOrEmpty(Item.SHOP_CODE))
            {
                Item.SHOP_CODE = ItemExt.SHOP_CODE = Item.LAPTOP_CODE = ItemExt.LAPTOP_CODE = Item.APPOINTMENT_SHOP_CODE;
            }

            string[] specialAvailabilityServiceCodes = FoxDataService.GetSpecialAvailabilityServiceCodes(Item.SHOP_CODE);

            CM_B_SHOP shop = DBContext.CM_B_SHOP.FirstOrDefault(E => E.SHOP_CODE == Item.SHOP_CODE);

            activity.ACTIVITY_TYPE_CODE = "PR";
            activity.ACTIVITY_DATE      = DateTime.Today;
            activity.CUSTOMER_CODE      = activityExt.CUSTOMER_CODE = Item.CUSTOMER_CODE;
            activity.EMPLOYEE_CODE      = Item.EMPLOYEE_CODE;
            Item.LOCATION_CODE          = activity.LOCATION_CODE = shop?.OBJ_CODE;
            Item.LOCATION_TYPE_CODE     = activity.LOCATION_TYPE_CODE = Item.SHOP_CODE == "000" ? "03" : "01";
            Item.STATUS_CODE            = Item.STATUS_CODE ?? appointmentStatus.Open;
            activity.REFERENCE_DATE     = Item.DT_APPOINTMENT;
            activity.REFERENCE_NUMBER   = Item.APPOINTMENT_ID;
            history.APPOINTMENT_ID      = activity.APPOINTMENT_ID = Item.APPOINTMENT_ID;
            history.SHOP_CODE           = history.LAPTOP_CODE = activity.SHOP_CODE = activity.LAPTOP_CODE = activityExt.SHOP_CODE = activityExt.LAPTOP_CODE = Item.SHOP_CODE;
            activity.ACTIVITY_ID        = activityExt.ACTIVITY_ID = FoxDataService.GetNewCounter("CU_B_ACTIVITY", "ACTIVITY_ID", Item.SHOP_CODE, Item.USERINSERT).VALUE.GetValueOrDefault();
            history.CONFIRMATION_STATUS = Item.STATUS_CODE;
            history.REASON_CODE         = Item.REASON_CODE;
            history.ROWGUID             = Item.ROWGUID;


            /* Disabled FK check
             * //Check for valid campaign
             * if (!string.IsNullOrWhiteSpace(campaignCode))
             * {
             *      CM_S_CAMPAIGN campaign = DBContext.CM_S_CAMPAIGN.FirstOrDefault(E => E.CAMPAIGN_CODE == campaignCode);
             *      ItemExt.CAMPAIGN_CODE = activity.CAMPAIGN_CODE = campaign?.CAMPAIGN_CODE;
             * }
             * //Check for valid mediatype
             * if (!string.IsNullOrWhiteSpace(mediaTypeCode))
             * {
             *      CM_S_MEDIATYPE mediaType = DBContext.CM_S_MEDIATYPE.FirstOrDefault(E => E.MEDIATYPE_CODE == mediaTypeCode);
             *      ItemExt.MEDIATYPE_CODE = activity.MEDIATYPE_CODE = mediaType?.MEDIATYPE_CODE;
             * }
             */

            ItemExt.CAMPAIGN_CODE  = activity.CAMPAIGN_CODE = campaignCode;
            ItemExt.MEDIATYPE_CODE = activity.MEDIATYPE_CODE = mediaTypeCode;

            ItemExt.SOURCE_TRACKING_ID = callID;

            EntityMapper.CheckEntityRowId(activity, activityExt, Guid.NewGuid());

            value.SaveData <AG_B_APPOINTMENT>(DBContext, Item);
            value.SaveData <CU_B_ACTIVITY>(DBContext, activity);

            // Set proper customer shop code if needed
            CU_B_ADDRESS_BOOK customer = DBContext.CU_B_ADDRESS_BOOK.FirstOrDefault(E => E.CUSTOMER_CODE == Item.CUSTOMER_CODE && E.CU_B_ADDRESS_BOOK_EXT_AUS.SHOP_CODE == "000");

            if (customer != null)
            {
                customer.CU_B_ADDRESS_BOOK_EXT_AUS.SHOP_CODE = Item.APPOINTMENT_SHOP_CODE;
            }


            DBContext.AG_B_APPOINTMENT.Add(Item);
            DBContext.AG_B_APPOINTMENT_EXT_AUS.Add(ItemExt);
            DBContext.CU_B_ACTIVITY.Add(activity);
            DBContext.CU_B_ACTIVITY_EXT_AUS.Add(activityExt);
            DBContext.AG_B_APPOINTMENT_STATUS_HISTORY.Add(history);


            IDbContextTransaction scope = DBContext.Database.CurrentTransaction;
            bool ownTransaction         = (scope == null);

            if (scope == null)
            {
                scope = DBContext.Database.BeginTransaction();
            }

            try
            {
                //Lock the table during this transaction
                DBContext.AG_B_APPOINTMENT.FromSql("SELECT TOP 1 * FROM AG_B_APPOINTMENT WITH (TABLOCKX, HOLDLOCK)");

                //Check for overlap
                DateTime appointmentStart = Item.DT_APPOINTMENT;
                DateTime appointmentEnd   = Item.DT_APPOINTMENT.AddMinutes(Item.DURATION.GetValueOrDefault());

                int overlappedAppointmentCount = DBContext.AG_B_APPOINTMENT.Where(E => AllowedAppointmentStatus.Contains(E.STATUS_CODE) &&
                                                                                  (E.ROOM_CODE == Item.ROOM_CODE || E.EMPLOYEE_CODE == Item.EMPLOYEE_CODE) &&
                                                                                  !specialAvailabilityServiceCodes.Contains(E.AG_S_SERVICE.SERVICE_TYPE_CODE) &&
                                                                                  ((E.DT_APPOINTMENT >= appointmentStart && E.DT_APPOINTMENT < appointmentEnd) ||
                                                                                   (E.DT_APPOINTMENT.AddMinutes(E.DURATION.GetValueOrDefault()) > appointmentStart && E.DT_APPOINTMENT.AddMinutes(E.DURATION.GetValueOrDefault()) < appointmentEnd) ||
                                                                                   (E.DT_APPOINTMENT <= appointmentStart && E.DT_APPOINTMENT.AddMinutes(E.DURATION.GetValueOrDefault()) > appointmentEnd))).Count();
                if (overlappedAppointmentCount > 0)
                {
                    throw new Exception("There is already an appointment for the given time slot");
                }

                //Complete the scope here to commit, otherwise it will rollback
                //The table lock will be released after we exit the TransactionScope block
                DBContext.SaveChanges();
                if (ownTransaction)
                {
                    scope.Commit();
                }
            }
            catch (Exception E)
            {
                if (ownTransaction)
                {
                    scope.Rollback();
                }
                throw E;
            }

            return(Get(Item.ROWGUID).Value);
        }