public async static Task <DateTime> CheckTheLastUpdatedAttendance(string empid)
        {
            Log.Info($"Checking LastUpdatedAttendanceDate of employee:{empid}");
            DateTime        LastUpdatedAttendanceDt = DateTime.MinValue;
            FetchListOption listOption = new FetchListOption();

            listOption.Filters.Add(new ERPFilter(DocType.Employee, "name", OperatorFilter.Equals, empid));
            listOption.IncludedFields.AddRange(new string[] { "name", "employee_name", "date_of_joining", "last_attendance_date" });
            var employees = Client.ListObjects(DocType.Employee, listOption);

            if (employees != null && employees.Count > 0)
            {
                //For the first time ReadOnly field  last_attendance_date will be null
                if (employees[0].Data.last_attendance_date == null)
                {
                    LastUpdatedAttendanceDt = DateTime.Now.AddDays(-2);
                }
                else
                {
                    LastUpdatedAttendanceDt = DateTime.Parse(employees[0].Data.last_attendance_date);
                }
            }
            Log.Info($"LastUpdatedAttendanceDate of employee:{empid} is {LastUpdatedAttendanceDt}");
            return(LastUpdatedAttendanceDt);
        }
예제 #2
0
        public List <ERPWarehouse> GetRootWarehouses()
        {
            FetchListOption listOption = new FetchListOption();

            listOption.Filters.Add(new ERPFilter(DocType.Warehouse, "parent_warehouse", OperatorFilter.Equals, ""));
            List <ERPObject> warehouses_list = client.ListObjects(DocType.Warehouse, listOption);

            return(warehouses_list.Select(x => new ERPWarehouse(x)).ToList());
        }
예제 #3
0
        public List <string> ListNames(List <ERPFilter> filters = null, int pageSize = 0, int pageStartIndex = 0)
        {
            FetchListOption listOption = new FetchListOption();

            listOption.Filters        = filters;
            listOption.PageSize       = 0;
            listOption.PageStartIndex = 0;

            List <ERPObject> object_list = this.client.ListObjects(ObjectType, listOption);

            return(object_list.Select(x => x.Name).ToList());
        }
예제 #4
0
        public List <ERPObject> ListObjects(DocType docType, FetchListOption listOption = null)
        {
            loginIfNeeded();

            listOption = listOption ?? new FetchListOption();
            RestRequest request = new RestRequest($"/api/resource/{docType}", Method.GET);

            var filters = listOption.Filters ?? new List <ERPFilter>();

            if (filters.Any())
            {
                var filter_val = ToString(filters.Select(toFilterObject).ToList());
                request.AddParameter("filters", filter_val);
            }

            var included_fields = listOption.IncludedFields ?? new List <string>();

            if (included_fields.Any())
            {
                var filter_val = ToString(included_fields.ToList());
                request.AddParameter("fields", filter_val);
            }

            if (listOption.PageSize > 0)
            {
                request.AddParameter("limit_page_length", listOption.PageSize);
            }

            if (listOption.PageStartIndex > 0)
            {
                request.AddParameter("limit_start", listOption.PageStartIndex);
            }

            var response             = this.client.Execute(request);
            List <ERPObject> objects = new List <ERPObject>();

            if (assertResponseIsOK(response))
            {
                objects = parseManyObjects(docType, response);
            }

            return(objects);
        }
예제 #5
0
 public List <ERPObject> ListObjects(FetchListOption listOption)
 {
     return(this.client.ListObjects(ObjectType, listOption));
 }
예제 #6
0
        public void CustomerFull()
        {
            var client = TestUtils.CreateClient();

            string test_customer_name    = Guid.NewGuid().ToString();
            string test_customer_website = Guid.NewGuid().ToString();

            ERPCustomer initial_data = new ERPCustomer();

            initial_data.customer_type  = Customertype.Individual;
            initial_data.customer_name  = test_customer_name;
            initial_data.customer_group = "All Customer Groups";
            initial_data.website        = test_customer_website;
            initial_data.territory      = "All Territories";
            initial_data.mobile_no      = "216-346-2739";
            initial_data.tax_category   = "Ohio Tax";

            #region Test - Insert

            client.InsertObject(initial_data.Object);

            #endregion

            #region Test - List

            FetchListOption listOption = new FetchListOption();
            listOption.Filters.Add(new ERPFilter(DocType.Customer, "name", OperatorFilter.Equals, test_customer_name));
            listOption.IncludedFields.AddRange(new string[] { "name", "website" });
            var documents = client.ListObjects(DocType.Customer, listOption);

            Assert.IsTrue(documents.Count == 1, "Customer result is not one");
            Assert.IsTrue(documents[0].Data.name == test_customer_name, "Customer name is invalid");
            Assert.IsTrue(documents[0].Data.website == test_customer_website, "Customer website is invalid");

            #endregion

            #region Test - Get

            var full_customer_object = client.GetObject(DocType.Customer, test_customer_name);
            Assert.IsTrue(full_customer_object.Data.name == test_customer_name, "Customer name is invalid");
            Assert.IsTrue(full_customer_object.Data.website == test_customer_website, "Customer website is invalid");

            #endregion

            #region Test - Wrapper

            ERPCustomer customer = new ERPCustomer(full_customer_object);
            Assert.IsTrue(customer.customer_name == test_customer_name, "Customer name is invalid");
            Assert.IsTrue(customer.website == test_customer_website, "Customer website is invalid");
//            Assert.IsTrue(customer.status == CustomerStatus.Active, "Customer website is invalid");

            #endregion

            #region Test - Update

            ERPObject updated_obj = new ERPObject(DocType.Customer);
            updated_obj.Data.website = Guid.NewGuid().ToString();

            // update first
            client.UpdateObject(DocType.Customer, test_customer_name, updated_obj);

            // get a new instance - after update
            var remote_updated_customer = client.GetObject(DocType.Customer, test_customer_name);

            // test
            Assert.IsTrue(remote_updated_customer.Data.website == updated_obj.Data.website, "Customer website is invalid - after update");
            Assert.IsTrue(remote_updated_customer.Data.territory == initial_data.territory, "Customer territory is invalid - after update");

            #endregion


            #region Test - Delete

            client.DeleteObject(DocType.Customer, test_customer_name);

            FetchListOption option = new FetchListOption();
            option.Filters.Add(new ERPFilter(DocType.Customer, nameof(ERPCustomer.customer_name), OperatorFilter.Equals,
                                             test_customer_name));
            var after_delete_result = client.ListObjects(DocType.Customer, option);
            Assert.IsTrue(after_delete_result.Count == 0, "Failed to delete customer");

            #endregion
        }
        public async static Task UpdateAttendance(DateTime ProcessingDate, DateTime ProcessingDayCheckIn, DateTime ProcessingDayCheckOut, string empid)
        {
            try
            {
                var employee = Client.GetObject(DocType.Employee, empid);
                if (employee != null)
                {
                    Log.Info($"updating attendance of employee:{empid} for the day {ProcessingDate} with chekin {ProcessingDayCheckIn} and checkout{ProcessingDayCheckOut}");
                    int                 HalfDayThreshold = Convert.ToInt32(ConfigurationManager.AppSettings["HalfDayThresholdHour"]);
                    int                 FullDayThreshold = Convert.ToInt32(ConfigurationManager.AppSettings["FullDayThresholdHour"]);
                    float               workinghours     = 0;
                    float               othours          = 0;
                    ERPAttendance       attendance       = new ERPAttendance();
                    List <TimeSheetLog> TimeSheetLogs    = new List <TimeSheetLog>();
                    TimeSheetLog        timeSheetLog     = new TimeSheetLog();
                    //If there is no records in AMS for the day
                    if (ProcessingDayCheckOut == DateTime.MinValue)
                    {
                        //Check the employee is on leave or not
                        Log.Info($"Checking employee {empid} is leave or not");
                        FetchListOption listOption = new FetchListOption();
                        listOption.Filters.Add(new ERPFilter(DocType.Attendance, "employee_id", OperatorFilter.Equals, empid));
                        listOption.Filters.Add(new ERPFilter(DocType.Attendance, "attendance_date", OperatorFilter.Equals, ProcessingDate.ToString("yyyy-MM-dd")));
                        listOption.IncludedFields.AddRange(new string[] { "name", "status", "attendance_date" });
                        var documents = Client.ListObjects(DocType.Attendance, listOption);


                        if (documents.Count > 0 && documents != null)
                        {
                            attendance.status          = (AttendanceStatusEnum)Enum.Parse(typeof(AttendanceStatusEnum), documents[0].Data.status.Replace(" ", ""));
                            attendance.attendance_date = documents[0].Data.attendance_date.ToString();
                            //timeSheetLog.from_time = documents[0].Data.attendance_date.ToString();
                            //timeSheetLog.hours = 0;
                            //timeSheetLog.activity_type = "Execution";
                            //TimeSheetLogs.Add(timeSheetLog);
                            Log.Info($"Employee {empid} is on leave with status {attendance.status}");
                        }
                        else
                        {
                            //Not on Leave and also there is no swipe
                            attendance.status          = AttendanceStatusEnum.Absent;
                            attendance.attendance_date = ProcessingDate.ToString("yyyy-MM-dd");
                            //timeSheetLog.from_time = ProcessingDate.ToString("yyyy-MM-dd");
                            //timeSheetLog.hours = 0;
                            //timeSheetLog.activity_type = "Execution";
                            //TimeSheetLogs.Add(timeSheetLog);
                            Log.Info($"Employee {empid} is Not on leave and there is no swipe so status :{attendance.status}");
                        }
                    }

                    //if checkout is before 1 pm
                    else if (ProcessingDayCheckOut < ProcessingDate.Date.AddHours(HalfDayThreshold))
                    {
                        attendance.status          = AttendanceStatusEnum.Absent;
                        attendance.attendance_date = ProcessingDayCheckOut.ToString("yyyy-MM-dd");
                        //workinghours=(float)(ProcessingDayCheckOut - ProcessingDayCheckIn).TotalHours;
                        //timeSheetLog.from_time = ProcessingDayCheckIn.ToString("yyyy-MM-dd");
                        //timeSheetLog.to_time = ProcessingDayCheckOut.ToString("yyyy-MM-dd");
                        //var ts = (ProcessingDayCheckOut - ProcessingDayCheckIn);
                        //var h = Math.Floor(ts.TotalHours);
                        //var m = (ts.TotalHours - h) * 60;
                        //workinghours = (float)(h + m/60);
                        //timeSheetLog.hours = workinghours;
                        //timeSheetLog.activity_type = "Execution";
                        //TimeSheetLogs.Add(timeSheetLog);
                        Log.Info($"Employee {empid} checkout {ProcessingDayCheckOut} before 1pm so marking as leave with status {attendance.status}");
                    }
                    //if checkout is before 5 pm
                    else if (ProcessingDayCheckOut < ProcessingDate.Date.AddHours(FullDayThreshold))
                    {
                        attendance.status          = AttendanceStatusEnum.HalfDay;
                        attendance.attendance_date = ProcessingDayCheckOut.ToString("yyyy-MM-dd");
                        //var ts = (ProcessingDayCheckOut - ProcessingDayCheckIn);
                        //var h = Math.Floor(ts.TotalHours);
                        //var m = (ts.TotalHours - h) * 60;
                        //workinghours = (float)(h + m/60);
                        //timeSheetLog.from_time = ProcessingDayCheckIn.ToString("yyyy-MM-dd");
                        //timeSheetLog.to_time = ProcessingDayCheckOut.ToString("yyyy-MM-dd");
                        //timeSheetLog.hours = workinghours;
                        //timeSheetLog.activity_type = "Execution";
                        //TimeSheetLogs.Add(timeSheetLog);
                        Log.Info($"Employee {empid}  chekout {ProcessingDayCheckOut} before 5pm so marking attendance status as {attendance.status}");
                    }
                    else
                    {
                        attendance.status          = AttendanceStatusEnum.Present;
                        attendance.attendance_date = ProcessingDayCheckOut.ToString("yyyy-MM-dd");
                        // workinghours = (float)(ProcessingDayCheckOut - ProcessingDayCheckIn).TotalHours;
                        var ts = (ProcessingDayCheckOut - ProcessingDayCheckIn);
                        var h  = Math.Floor(ts.TotalHours);
                        var m  = (ts.TotalHours - h) * 60;
                        workinghours           = (float)(h + m / 60);
                        timeSheetLog.from_time = ProcessingDayCheckIn.ToString("yyyy-MM-dd");
                        timeSheetLog.to_time   = ProcessingDayCheckOut.ToString("yyyy-MM-dd");
                        if (workinghours > 8)
                        {
                            othours = workinghours - 8;
                        }
                        else
                        {
                            othours = 0;
                        }

                        timeSheetLog.hours         = othours;
                        timeSheetLog.activity_type = "Execution";
                        TimeSheetLogs.Add(timeSheetLog);
                        Log.Info($"Employee {empid} checkout {ProcessingDayCheckOut} properly and marking attendance status {attendance.status} and workinghours {timeSheetLog.hours}");
                    }
                    attendance.employee_name = employee.Data.employee_name;
                    attendance.employee      = employee.Data.employee;
                    attendance.company       = employee.Data.company;
                    attendance.department    = employee.Data.department;
                    attendance.docstatus     = 1;

                    //mark the attendance
                    Client.InsertObject(attendance.Object);
                    Log.Info($"Marked the attendance for the eemployee {empid} successfully");

                    //create the time sheet for the employee
                    if (TimeSheetLogs.Count > 0)
                    {
                        ERPTimesheet timesheet = new ERPTimesheet();
                        timesheet.employee_name = employee.Data.employee_name;
                        timesheet.employee      = employee.Data.employee;
                        timesheet.company       = employee.Data.company;
                        timesheet.department    = employee.Data.department;
                        timesheet.time_logs     = TimeSheetLogs;
                        timesheet.docstatus     = 1;
                        //timesheet.total_hours = workinghours;
                        Client.InsertObject(timesheet.Object);
                        Log.Info($"created time sheet for the employee {empid} successfully");
                    }

                    //finally update Employee with lastattendance date
                    ERPObject updated_obj = new ERPObject(DocType.Employee);
                    updated_obj.Data.last_attendance_date = ProcessingDate.ToString("yyyy-MM-dd");
                    Client.UpdateObject(DocType.Employee, empid, updated_obj);
                    Log.Info($"updated the processed date for the employee {empid} successfully");
                }
            }

            catch (Exception ex)
            {
                Log.Error(ex);
            }
        }
        public void AddressFull()
        {
            var client = TestUtils.CreateClient();

            string test_address_title  = "Test_" + Guid.NewGuid().ToString();
            string test_address_line_1 = "Somewhere Road";
            string test_city           = "Somewhere Town";
            string test_country        = "United States";
            string test_taxcat         = "Ohio Tax";

            ERPAddress initial_data = new ERPAddress();

            initial_data.address_title = test_address_title;
            initial_data.address_line1 = test_address_line_1;
            initial_data.city          = test_city;
            initial_data.country       = test_country;
            initial_data.tax_category  = test_taxcat;

            #region Test - Insert

            client.InsertObject(initial_data.Object);

            #endregion

            #region Test - List

            FetchListOption listOption = new FetchListOption();
            listOption.Filters.Add(new ERPFilter(DocType.Address, "address_title", OperatorFilter.Equals, test_address_title));
            listOption.IncludedFields.AddRange(new string[] { "address_title", "address_line1", "city", "country" });
            var documents = client.ListObjects(DocType.Address, listOption);

            Assert.IsTrue(documents.Count == 1, "Address result is not one");
            Assert.IsTrue(documents[0].Data.address_title == test_address_title, "Address title is invalid");
            Assert.IsTrue(documents[0].Data.address_line1 == test_address_line_1, "Address Line 1 is invalid");
            Assert.IsTrue(documents[0].Data.city == test_city, "City is invalid");
            Assert.IsTrue(documents[0].Data.country == test_country, "Country is invalid");

            #endregion

            #region Test - Get

            //Address will be created by concatenating address type to address title - quick hack here to test
            string test_address_name = test_address_title + "-Billing";

            var full_address_object = client.GetObject(DocType.Address, test_address_name);
            Assert.IsTrue(full_address_object.Data.address_title == test_address_title, "Address title is invalid");
            Assert.IsTrue(full_address_object.Data.address_line1 == test_address_line_1, "Address Line 1 is invalid");
            Assert.IsTrue(full_address_object.Data.city == test_city, "City is invalid");
            Assert.IsTrue(full_address_object.Data.country == test_country, "Country is invalid");

            #endregion

            #region Test - Wrapper

            ERPAddress address = new ERPAddress(full_address_object);
            Assert.IsTrue(address.address_title == test_address_title, "address title is invalid");
            Assert.IsTrue(address.address_line1 == test_address_line_1, "Address Line 1 is invalid");
            Assert.IsTrue(address.city == test_city, "City is invalid");
            Assert.IsTrue(address.country == test_country, "Country is invalid");

            #endregion

            #region Test - Update

            ERPObject updated_obj = new ERPObject(DocType.Address);
            updated_obj.Data.address_line1 = "New Address Detail Line";

            // update first
            client.UpdateObject(DocType.Address, test_address_name, updated_obj);

            // get a new instance - after update
            var remote_updated_address = client.GetObject(DocType.Address, test_address_name);

            // test
            Assert.IsTrue(remote_updated_address.Data.address_line1 == updated_obj.Data.address_line1, "Address Line 1 is invalid - after update");
            Assert.IsTrue(remote_updated_address.Data.city == initial_data.city, "Address city is invalid - after update");
            Assert.IsTrue(remote_updated_address.Data.country == initial_data.country, "Address country is invalid - after update");

            #endregion

            #region Test - Delete

            client.DeleteObject(DocType.Address, test_address_name);

            FetchListOption option = new FetchListOption();
            option.Filters.Add(new ERPFilter(DocType.Address, nameof(ERPAddress.address_title), OperatorFilter.Equals,
                                             test_address_title));
            var after_delete_result = client.ListObjects(DocType.Address, option);
            Assert.IsTrue(after_delete_result.Count == 0, "Failed to delete Address");

            #endregion
        }
예제 #9
0
        public async static Task UpdateAttendance(DateTime ProcessingDate, DateTime ProcessingDayCheckIn, DateTime ProcessingDayCheckOut, string empid)
        {
            try
            {
                var employee = Client.GetObject(DocType.Employee, empid);
                if (employee != null)
                {
                    Log.Info($"updating attendance of employee:{empid} for the day {ProcessingDate} with chekin {ProcessingDayCheckIn} and checkout{ProcessingDayCheckOut}");


                    int                 ShiftOneHalfDayThresholdHour   = 0;
                    int                 ShiftTwoHalfDayThresholdHour   = 0;
                    int                 ShiftThreeHalfDayThresholdHour = 0;
                    float               workinghours  = 0;
                    float               othours       = 0;
                    float               otThreshold   = 0;
                    float               BufferHour    = 0;
                    ERPAttendance       attendance    = new ERPAttendance();
                    List <TimeSheetLog> TimeSheetLogs = new List <TimeSheetLog>();
                    TimeSheetLog        timeSheetLog  = new TimeSheetLog();

                    ShiftOneHalfDayThresholdHour   = Convert.ToInt32(ConfigurationManager.AppSettings["ShiftOneHalfDayThresholdHour"]);
                    ShiftTwoHalfDayThresholdHour   = Convert.ToInt32(ConfigurationManager.AppSettings["ShiftTwoHalfDayThresholdHour"]);
                    ShiftThreeHalfDayThresholdHour = Convert.ToInt32(ConfigurationManager.AppSettings["ShiftThreeHalfDayThresholdHour"]);
                    otThreshold = Convert.ToInt32(ConfigurationManager.AppSettings["OtHoursThreshold"]);
                    BufferHour  = Convert.ToInt32(ConfigurationManager.AppSettings["BufferHours"]);
                    //fetching shift timings from webconfig
                    IList <string> ShiftOneStartList = ConfigurationManager.AppSettings["ShiftOneStartTime"].Split(':');
                    TimeSpan       ShiftOneStartTs   = new TimeSpan(Convert.ToInt32(ShiftOneStartList[0]), Convert.ToInt32(ShiftOneStartList[1]), 0);
                    var            ShiftOneStartdate = ProcessingDate.Date.Add(ShiftOneStartTs);

                    IList <string> ShiftOneEndList = ConfigurationManager.AppSettings["ShiftOneEndTime"].Split(':');
                    TimeSpan       ShiftOneEndTs   = new TimeSpan(Convert.ToInt32(ShiftOneEndList[0]), Convert.ToInt32(ShiftOneEndList[1]), 0);
                    var            ShiftOneEnddate = ProcessingDate.Date.Add(ShiftOneEndTs);

                    IList <string> ShiftTwoStartList = ConfigurationManager.AppSettings["ShiftTwoStartTime"].Split(':');
                    TimeSpan       ShiftTwoStartTs   = new TimeSpan(Convert.ToInt32(ShiftTwoStartList[0]), Convert.ToInt32(ShiftTwoStartList[1]), 0);
                    var            ShiftTwoStartdate = ProcessingDate.Date.Add(ShiftTwoStartTs);

                    IList <string> ShiftTwoEndList = ConfigurationManager.AppSettings["ShiftTwoEndTime"].Split(':');
                    TimeSpan       ShiftTwoEndTs   = new TimeSpan(Convert.ToInt32(ShiftTwoEndList[0]), Convert.ToInt32(ShiftTwoEndList[1]), 0);
                    var            ShiftTwoEnddate = ProcessingDate.Date.Add(ShiftTwoEndTs).AddDays(1);

                    IList <string> ShiftThreeStartList = ConfigurationManager.AppSettings["ShiftThreeStartTime"].Split(':');
                    TimeSpan       ShiftThreeStartTs   = new TimeSpan(Convert.ToInt32(ShiftThreeStartList[0]), Convert.ToInt32(ShiftThreeStartList[1]), 0);
                    var            ShiftThreeStartdate = ProcessingDate.Date.Add(ShiftThreeStartTs);

                    IList <string> ShiftThreeEndList = ConfigurationManager.AppSettings["ShiftThreeEndTime"].Split(':');
                    TimeSpan       ShiftThreeEndTs   = new TimeSpan(Convert.ToInt32(ShiftThreeEndList[0]), Convert.ToInt32(ShiftThreeEndList[1]), 0);
                    var            ShiftThreeEnddate = ProcessingDate.Date.Add(ShiftThreeEndTs);


                    //If there is no checkin records in AMS for the day
                    if (ProcessingDayCheckIn == DateTime.MinValue || ProcessingDayCheckOut == DateTime.MinValue)
                    {
                        //Check the employee is on leave or not
                        Log.Info($"Checking employee {empid} is leave or not");
                        FetchListOption listOption = new FetchListOption();
                        listOption.Filters.Add(new ERPFilter(DocType.Attendance, "employee_id", OperatorFilter.Equals, empid));
                        listOption.Filters.Add(new ERPFilter(DocType.Attendance, "attendance_date", OperatorFilter.Equals, ProcessingDate.ToString("yyyy-MM-dd")));
                        listOption.IncludedFields.AddRange(new string[] { "name", "status", "attendance_date" });
                        var documents = Client.ListObjects(DocType.Attendance, listOption);

                        if (documents.Count > 0 && documents != null)
                        {
                            attendance.status          = (AttendanceStatusEnum)Enum.Parse(typeof(AttendanceStatusEnum), documents[0].Data.status.Replace(" ", ""));
                            attendance.attendance_date = documents[0].Data.attendance_date.ToString();
                            Log.Info($"Employee {empid} is on leave with status {attendance.status}");
                        }
                        else
                        {
                            //Not on Leave and also there is no swipe
                            attendance.status          = AttendanceStatusEnum.Absent;
                            attendance.attendance_date = ProcessingDate.ToString("yyyy-MM-dd");
                            Log.Info($"Employee {empid} is Not on leave and there is no swipe so status :{attendance.status}");
                        }
                    }

                    if (ProcessingDayCheckIn >= ShiftOneStartdate.AddHours(BufferHour) && ProcessingDayCheckOut >= ShiftOneEnddate.AddHours(BufferHour) || ProcessingDayCheckIn >= ShiftOneStartdate.AddHours(-BufferHour) && ProcessingDayCheckOut >= ShiftOneEnddate.AddHours(-BufferHour))
                    {
                        Log.Info($"Employee {empid} is found in shift1 so processing attendance");
                        //if checkout is before HalfDayThreshold
                        if (ProcessingDayCheckOut < ProcessingDate.Date.AddHours(ShiftOneHalfDayThresholdHour))
                        {
                            attendance.status          = AttendanceStatusEnum.Absent;
                            attendance.attendance_date = ProcessingDayCheckOut.ToString("yyyy-MM-dd");
                            Log.Info($"Employee {empid} checkout {ProcessingDayCheckOut} before HalfDayThreshold so marking as leave with status {attendance.status}");
                        }
                        //if checkout is before FullDayThreshold
                        else if (ProcessingDayCheckOut < ShiftOneEnddate)
                        {
                            attendance.status          = AttendanceStatusEnum.HalfDay;
                            attendance.attendance_date = ProcessingDayCheckOut.ToString("yyyy-MM-dd");
                            Log.Info($"Employee {empid}  chekout {ProcessingDayCheckOut} before Full Day Threshold so marking attendance status as {attendance.status}");
                        }
                        else
                        {
                            attendance.status          = AttendanceStatusEnum.Present;
                            attendance.attendance_date = ProcessingDayCheckOut.ToString("yyyy-MM-dd");
                            var ts = (ProcessingDayCheckOut - ProcessingDayCheckIn);
                            var h  = Math.Floor(ts.TotalHours);
                            var m  = (ts.TotalHours - h) * 60;
                            workinghours           = (float)(h + m / 60);
                            timeSheetLog.from_time = ProcessingDayCheckIn.ToString("yyyy-MM-dd");
                            timeSheetLog.to_time   = ProcessingDayCheckOut.ToString("yyyy-MM-dd");
                            if (workinghours > otThreshold && ProcessingDayCheckIn <= ShiftOneStartdate.AddHours(BufferHour))
                            {
                                othours                    = workinghours - (float)otThreshold;
                                timeSheetLog.hours         = (float)Math.Round(othours);
                                timeSheetLog.activity_type = "Execution";
                                TimeSheetLogs.Add(timeSheetLog);
                            }


                            Log.Info($"Employee {empid} checkout {ProcessingDayCheckOut} properly and marking attendance status {attendance.status} and workinghours {timeSheetLog.hours}");
                        }
                    }
                    else if (ProcessingDayCheckIn >= ShiftTwoStartdate.AddHours(BufferHour) && ProcessingDayCheckOut >= ShiftTwoEnddate.AddHours(BufferHour) || ProcessingDayCheckIn >= ShiftTwoStartdate.AddHours(-BufferHour) && ProcessingDayCheckOut >= ShiftTwoEnddate.AddHours(-BufferHour))
                    {
                        Log.Info($"Employee {empid} is found in shift2 so processing attendance");
                        //this shift is ending in next day so feteching chekouttime again
                        if (ProcessingDayCheckOut == ProcessingDayCheckIn)
                        {
                            ProcessingDayCheckOut = await AMSConnector.GetChekOutTime(empid, ProcessingDate.AddDays(1));
                        }
                        //if checkout is before HalfDayThreshold
                        if (ProcessingDayCheckOut < ProcessingDate.Date.AddHours(ShiftTwoHalfDayThresholdHour))
                        {
                            attendance.status          = AttendanceStatusEnum.Absent;
                            attendance.attendance_date = ProcessingDayCheckOut.ToString("yyyy-MM-dd");
                            Log.Info($"Employee {empid} checkout {ProcessingDayCheckOut} before HalfDayThreshold so marking as leave with status {attendance.status}");
                        }
                        //if checkout is before FullDayThreshold
                        else if (ProcessingDayCheckOut < ShiftTwoEnddate)
                        {
                            attendance.status          = AttendanceStatusEnum.HalfDay;
                            attendance.attendance_date = ProcessingDayCheckOut.ToString("yyyy-MM-dd");
                            Log.Info($"Employee {empid}  chekout {ProcessingDayCheckOut} before Full Day Threshold so marking attendance status as {attendance.status}");
                        }
                        else
                        {
                            attendance.status          = AttendanceStatusEnum.Present;
                            attendance.attendance_date = ProcessingDayCheckOut.ToString("yyyy-MM-dd");
                            var ts = (ProcessingDayCheckOut - ProcessingDayCheckIn);
                            var h  = Math.Floor(ts.TotalHours);
                            var m  = (ts.TotalHours - h) * 60;
                            workinghours           = (float)(h + m / 60);
                            timeSheetLog.from_time = ProcessingDayCheckIn.ToString("yyyy-MM-dd");
                            timeSheetLog.to_time   = ProcessingDayCheckOut.ToString("yyyy-MM-dd");
                            if (workinghours > otThreshold && ProcessingDayCheckIn <= ShiftTwoStartdate.AddHours(BufferHour))
                            {
                                othours                    = workinghours - (float)otThreshold;
                                timeSheetLog.hours         = (float)Math.Round(othours);
                                timeSheetLog.activity_type = "Execution";
                                TimeSheetLogs.Add(timeSheetLog);
                            }


                            Log.Info($"Employee {empid} checkout {ProcessingDayCheckOut} properly and marking attendance status {attendance.status} and workinghours {timeSheetLog.hours}");
                        }
                    }
                    else if (ProcessingDayCheckIn >= ShiftThreeStartdate.AddHours(BufferHour) && ProcessingDayCheckOut >= ShiftThreeEnddate.AddHours(BufferHour) || ProcessingDayCheckIn >= ShiftThreeStartdate.AddHours(-BufferHour) && ProcessingDayCheckOut >= ShiftThreeEnddate.AddHours(-BufferHour))
                    {
                        Log.Info($"Employee {empid} is found in shift3 so processing attendance");
                        //if checkout is before HalfDayThreshold
                        if (ProcessingDayCheckOut < ProcessingDate.Date.AddHours(ShiftThreeHalfDayThresholdHour))
                        {
                            attendance.status          = AttendanceStatusEnum.Absent;
                            attendance.attendance_date = ProcessingDayCheckOut.ToString("yyyy-MM-dd");
                            Log.Info($"Employee {empid} checkout {ProcessingDayCheckOut} before HalfDayThreshold so marking as leave with status {attendance.status}");
                        }
                        //if checkout is before FullDayThreshold
                        else if (ProcessingDayCheckOut < ShiftThreeEnddate)
                        {
                            attendance.status          = AttendanceStatusEnum.HalfDay;
                            attendance.attendance_date = ProcessingDayCheckOut.ToString("yyyy-MM-dd");
                            Log.Info($"Employee {empid}  chekout {ProcessingDayCheckOut} before Full Day Threshold so marking attendance status as {attendance.status}");
                        }
                        else
                        {
                            attendance.status          = AttendanceStatusEnum.Present;
                            attendance.attendance_date = ProcessingDayCheckOut.ToString("yyyy-MM-dd");
                            var ts = (ProcessingDayCheckOut - ProcessingDayCheckIn);
                            var h  = Math.Floor(ts.TotalHours);
                            var m  = (ts.TotalHours - h) * 60;
                            workinghours           = (float)(h + m / 60);
                            timeSheetLog.from_time = ProcessingDayCheckIn.ToString("yyyy-MM-dd");
                            timeSheetLog.to_time   = ProcessingDayCheckOut.ToString("yyyy-MM-dd");
                            if (workinghours > otThreshold && ProcessingDayCheckIn <= ShiftTwoStartdate.AddHours(BufferHour))
                            {
                                othours                    = workinghours - (float)otThreshold;
                                timeSheetLog.hours         = (float)Math.Round(othours);
                                timeSheetLog.activity_type = "Execution";
                                TimeSheetLogs.Add(timeSheetLog);
                            }


                            Log.Info($"Employee {empid} checkout {ProcessingDayCheckOut} properly and marking attendance status {attendance.status} and workinghours {timeSheetLog.hours}");
                        }
                    }
                    //if employee is not there in any shift
                    else
                    {
                        var Datediff          = (ProcessingDayCheckOut - ProcessingDayCheckIn);
                        var Diffh             = Math.Floor(Datediff.TotalHours);
                        var Diffm             = (Datediff.TotalHours - Diffh) * 60;
                        var Totalworkinghours = (float)(Diffh + Diffm / 60);
                        if (Totalworkinghours <= 4)
                        {
                            attendance.status          = AttendanceStatusEnum.Absent;
                            attendance.attendance_date = ProcessingDayCheckOut.ToString("yyyy-MM-dd");
                            Log.Info($"Employee {empid} is not there in any shift and his checkout {ProcessingDayCheckOut} and checkin {ProcessingDayCheckIn} the total working hours {Totalworkinghours} so marking attendance status {attendance.status} and workinghours {timeSheetLog.hours}");
                        }
                        else if (Totalworkinghours <= 8)
                        {
                            attendance.status          = AttendanceStatusEnum.HalfDay;
                            attendance.attendance_date = ProcessingDayCheckOut.ToString("yyyy-MM-dd");
                            Log.Info($"Employee {empid} checkout {ProcessingDayCheckOut} properly and marking attendance status {attendance.status} and workinghours {timeSheetLog.hours}");
                        }
                        else
                        {
                            attendance.status          = AttendanceStatusEnum.Present;
                            attendance.attendance_date = ProcessingDayCheckOut.ToString("yyyy-MM-dd");
                            Log.Info($"Employee {empid} checkout {ProcessingDayCheckOut} properly and marking attendance status {attendance.status} and workinghours {timeSheetLog.hours}");
                        }
                    }



                    attendance.employee_name = employee.Data.employee_name;
                    attendance.employee      = employee.Data.employee;
                    attendance.company       = employee.Data.company;
                    attendance.department    = employee.Data.department;
                    attendance.docstatus     = 1;

                    //mark the attendance
                    Client.InsertObject(attendance.Object);
                    Log.Info($"Marked the attendance for the eemployee {empid} successfully");

                    //create the time sheet for the employee
                    if (TimeSheetLogs.Count > 0)
                    {
                        ERPTimesheet timesheet = new ERPTimesheet();
                        timesheet.employee_name = employee.Data.employee_name;
                        timesheet.employee      = employee.Data.employee;
                        timesheet.company       = employee.Data.company;
                        timesheet.department    = employee.Data.department;
                        timesheet.time_logs     = TimeSheetLogs;
                        timesheet.docstatus     = 0;
                        Client.InsertObject(timesheet.Object);
                        Log.Info($"created OT for the employee {empid}  successfully");
                    }

                    //finally update Employee with lastattendance date
                    ERPObject updated_obj = new ERPObject(DocType.Employee);
                    updated_obj.Data.last_attendance_date = ProcessingDate.ToString("yyyy-MM-dd");
                    Client.UpdateObject(DocType.Employee, empid, updated_obj);
                    Log.Info($"updated the processed date for the employee {empid} successfully");
                }
            }

            catch (Exception ex)
            {
                Log.Error(ex);
            }
        }
        public void ItemGroupFull()
        {
            var client = TestUtils.CreateClient();

            string test_group_name  = "Test_" + Guid.NewGuid().ToString();
            int    test_is_group    = 0;
            string test_description = "Group Description Test";

            ERPItem_group initial_data = new ERPItem_group();

            initial_data.item_group_name = test_group_name;
            initial_data.is_group        = test_is_group;
            initial_data.description     = test_description;

            #region Test - Insert

            client.InsertObject(initial_data.Object);

            #endregion

            #region Test - List

            FetchListOption listOption = new FetchListOption();
            listOption.Filters.Add(new ERPFilter(DocType.Item_group, "item_group_name", OperatorFilter.Equals, test_group_name));
            listOption.IncludedFields.AddRange(new string[] { "item_group_name", "is_group", "description" });
            var documents = client.ListObjects(DocType.Item_group, listOption);

            Console.WriteLine(documents[0]);

            Assert.IsTrue(documents.Count == 1, "Item Group result is not one");
            Assert.IsTrue(documents[0].Data.item_group_name == test_group_name, "Group Name is invalid");
            Assert.IsTrue(documents[0].Data.is_group == test_is_group, "Is a Group is invalid");
            Assert.IsTrue(documents[0].Data.description == test_description, "Description is invalid");

            #endregion

            #region Test - Get

            var full_itemgroup_object = client.GetObject(DocType.Item_group, test_group_name);
            Assert.IsTrue(full_itemgroup_object.Data.item_group_name == test_group_name, "Group Name is invalid");
            Assert.IsTrue(full_itemgroup_object.Data.is_group == test_is_group, "Is Group is invalid");
            Assert.IsTrue(full_itemgroup_object.Data.description == test_description, "Description is invalid");

            #endregion

            #region Test - Wrapper

            ERPItem_group item_group = new ERPItem_group(full_itemgroup_object);
            Assert.IsTrue(item_group.item_group_name == test_group_name, "address title is invalid");
            Assert.IsTrue(item_group.is_group == test_is_group, "Address Line 1 is invalid");
            Assert.IsTrue(item_group.description == test_description, "City is invalid");

            #endregion

            #region Test - Update

            ERPObject updated_obj = new ERPObject(DocType.Item_group);
            test_description = "Test 2 - Update the description";

            updated_obj.Data.description = test_description;
            // update first
            client.UpdateObject(DocType.Item_group, test_group_name, updated_obj);

            // get a new instance - after update
            var remote_updated_group = client.GetObject(DocType.Item_group, test_group_name);

            // test
            Assert.IsTrue(remote_updated_group.Data.description == updated_obj.Data.description, "Invalid Description - after update");
            Assert.IsTrue(remote_updated_group.Data.is_group == initial_data.is_group, "Invalid Is A Group - after update");
            Assert.IsTrue(remote_updated_group.Data.item_group_name == initial_data.item_group_name, "Invalid name - after update");

            #endregion

            #region Test - Delete

            client.DeleteObject(DocType.Item_group, test_group_name);

            FetchListOption option = new FetchListOption();
            option.Filters.Add(new ERPFilter(DocType.Item_group, nameof(ERPItem_group.item_group_name), OperatorFilter.Equals,
                                             test_group_name));
            var after_delete_result = client.ListObjects(DocType.Item_group, option);
            Assert.IsTrue(after_delete_result.Count == 0, "Failed to delete Address");

            #endregion
        }