def __init__(
        self,
        cust_id,
        cust_name,
        alt_cust_id,
        vendor_login,
        vendor_password,
        destination_site_id,
        source_site_id,
        prime_suite_site_id,
        prime_suite_user_alias,
        prime_suite_user_name,
        prime_suite_user_password,
        prime_suite_user_id,
        appointment_url,
        patient_url,
        days_before_today=2,
        days_after_today=7,
    ):
        # Constructor
        self.customer_id = cust_id
        # self.alt_customer_id = alt_cust_id
        self.customer_name = cust_name
        self.page_size = 500
        self.max_results = 1000
        self.days_before_today = days_before_today
        self.days_after_today = days_after_today

        self.api_client = GWAPIWrapper(
            alt_cust_id,
            source_site_id,
            destination_site_id,
            prime_suite_site_id,
            prime_suite_user_name,
            prime_suite_user_id,
            prime_suite_user_alias,
            prime_suite_user_password,
            vendor_login,
            vendor_password,
            appointment_url,
            patient_url,
            self.page_size,
            self.max_results,
        )
        self.appointments_data = []
        self.serialized_appointments = []
class GWCustomer(object):
    # Common shared data
    def __init__(
        self,
        cust_id,
        cust_name,
        alt_cust_id,
        vendor_login,
        vendor_password,
        destination_site_id,
        source_site_id,
        prime_suite_site_id,
        prime_suite_user_alias,
        prime_suite_user_name,
        prime_suite_user_password,
        prime_suite_user_id,
        appointment_url,
        patient_url,
        days_before_today=2,
        days_after_today=7,
    ):
        # Constructor
        self.customer_id = cust_id
        # self.alt_customer_id = alt_cust_id
        self.customer_name = cust_name
        self.page_size = 500
        self.max_results = 1000
        self.days_before_today = days_before_today
        self.days_after_today = days_after_today

        self.api_client = GWAPIWrapper(
            alt_cust_id,
            source_site_id,
            destination_site_id,
            prime_suite_site_id,
            prime_suite_user_name,
            prime_suite_user_id,
            prime_suite_user_alias,
            prime_suite_user_password,
            vendor_login,
            vendor_password,
            appointment_url,
            patient_url,
            self.page_size,
            self.max_results,
        )
        self.appointments_data = []
        self.serialized_appointments = []

    def fetch_data(self):
        """
            Make request for 2 API and fetch the data of appointments and patients.
            
        """
        LOGGER.info("------------------------------")
        LOGGER.info("|        Fetch Data          |")
        LOGGER.info("------------------------------")
        # Start date and end date
        start_date = (datetime.today() - timedelta(days=self.days_before_today)).strftime("%m-%d-%Y")
        end_date = (datetime.today() + timedelta(days=self.days_after_today)).strftime("%m-%d-%Y")
        # start_date = datetime.now().strftime("%m-%d-%Y")
        self.appointments_data = []
        LOGGER.info("Fetching appointment data from: %s to %s." % (start_date, end_date))
        LOGGER.info("Sending GreenWay request.")
        self.appointments_data = self.api_client.get_site_scheduled_appointments(start_date, end_date)

        """
            All required data not gained from this SitesScheduledAppointments API, for completing 
            Patient data make another request for PatientDemographics API.
        
        """

        # if self.appointments_data:
        for appt in self.appointments_data["SitesScheduledAppointmentsGetResult"]["ScheduledAppointments"]:
            patient_id = appt["Patient"]["PatientID"]
            LOGGER.info("API request send for Patient Id: %s" % (patient_id))
            patient_response = self.api_client.get_patient_demographics(patient_id)
            if patient_response:
                patient_data = patient_response["PatientDemographicsGetResult"]["Patient"]

                # Setting only required field in appointment_data's object
                # appt['Patient']['FullName'] = patient_data['FullName']
                appt["Patient"]["Firstname"] = patient_data["Firstname"]
                appt["Patient"]["LastName"] = patient_data["LastName"]

                appt["Patient"]["EmailAddress1"] = patient_data["EmailAddress1"]
                appt["Patient"]["EmailAddress2"] = patient_data["EmailAddress2"]

                appt["Patient"]["PrimaryPhoneNumber"] = patient_data["PrimaryPhoneNumber"]
                appt["Patient"]["CellPhoneNumber1"] = patient_data["CellPhoneNumber1"]
                appt["Patient"]["CellPhoneNumber2"] = patient_data["CellPhoneNumber2"]

                appt["Patient"]["PhoneNumber1"] = patient_data["PhoneNumber1"]
                appt["Patient"]["PhoneNumber2"] = patient_data["PhoneNumber2"]

                appt["Patient"]["PrimaryWorkPhone"] = patient_data["PrimaryWorkPhone"]

                appt["Patient"]["PagerNumber"] = patient_data["PagerNumber"]
                appt["Patient"]["ResidentialAddress"] = patient_data["ResidentialAddress"]
                appt["Patient"]["PrimaryLanguage"] = patient_data["PrimaryLanguage"]
                ##remove below if condition.
                if patient_data["DateOfBirth"] is not "None":
                    appt["Patient"]["DateOfBirth"] = patient_data["DateOfBirth"]
                appt["Patient"]["GuarantorID"] = patient_data["GuarantorID"]

        # print 'Response appointments_patient_data: {0}'.format(self.appointments_data)

    #        try:
    #            with open(start_date +'.json', 'wb') as fp:
    #                json.dump(self.appointments_data, fp)
    #        except:
    #            from sys import exc_info
    #            print 'ERROR: File I/O error. Detail: {}'.format(exc_info()[0])

    def serialize_data(self):
        """
            Mapping data from row data to appointment class
            
        """
        LOGGER.info("------------------------------")
        LOGGER.info("|      Serialize Data        |")
        LOGGER.info("------------------------------")
        self.serialized_appointments = []
        if self.appointments_data:
            number = 1
            total_count = len(self.appointments_data["SitesScheduledAppointmentsGetResult"]["ScheduledAppointments"])
            LOGGER.info("Serializing appointments data. Total count: %s" % (total_count))
            for appt in self.appointments_data["SitesScheduledAppointmentsGetResult"]["ScheduledAppointments"]:
                LOGGER.debug("Serializing appointment (%s of %s)" % (number, total_count))
                number += 1
                LOGGER.debug("Appointment Id: %s - Raw Data: \n%s" % (appt["AppointmentID"], appt))
                appointment = AppointmentData()

                # Customer ID
                appointment.customer_id = self.customer_id

                # Appointment data
                appointment.altAppointmentId = appt["AppointmentID"]
                if appt["ScheduleDate"]:
                    appt_date = time.strptime(appt["ScheduleDate"], "%m/%d/%Y")
                    appointment.apptDate = time.strftime("%Y-%m-%d", appt_date)
                if appt["StartTime"]:
                    appt_time = time.strptime(appt["ScheduleDate"] + appt["StartTime"], "%m/%d/%Y%I:%M:%S %p")
                    appointment.apptTime = time.strftime("%Y-%m-%d %H:%M:%S", appt_time)
                appointment.apptTypeName = appt["Type"]["Name"]
                appointment.altApptTypeId = appt["Type"]["AppointmentTypeID"]

                # Patient data
                appointment.altPatientId = appt["Patient"]["PatientID"]
                if appt["Patient"]["FullName"] not in NULLS:
                    name = appt["Patient"]["FullName"].split(",")
                    appointment.fname = name[1]
                    appointment.lname = name[0]
                elif appt["Patient"]["Firstname"] not in NULLS:
                    appointment.fname = appt["Patient"]["Firstname"]
                elif appt["Patient"]["LastName"] not in NULLS:
                    appointment.lname = appt["Patient"]["LastName"]
                if appt["Patient"]["EmailAddress1"] not in NULLS:
                    appointment.email = appt["Patient"]["EmailAddress1"]
                elif appt["Patient"]["EmailAddress2"] not in NULLS:
                    appointment.email = appt["Patient"]["EmailAddress2"]
                # Patient's email validating
                if not is_email_valid(appointment.email):
                    appointment.email = ""
                # Patient's cell phone is added
                if appt["Patient"]["PrimaryPhoneNumber"] not in NULLS:
                    appointment.cellPhone = appt["Patient"]["PrimaryPhoneNumber"]
                elif appt["Patient"]["CellPhoneNumber1"] not in NULLS:
                    appointment.cellPhone = appt["Patient"]["CellPhoneNumber1"]
                elif appt["Patient"]["CellPhoneNumber2"] not in NULLS:
                    appointment.cellPhone = appt["Patient"]["CellPhoneNumber2"]
                # Patient's home phone is added
                if appt["Patient"]["PhoneNumber1"] not in NULLS:
                    appointment.homePhone = appt["Patient"]["PhoneNumber1"]
                elif appt["Patient"]["PhoneNumber2"] not in NULLS:
                    appointment.homePhone = appt["Patient"]["PhoneNumber2"]
                # Patient's work phone is added
                if appt["Patient"]["PrimaryWorkPhone"] not in NULLS:
                    appointment.workPhone = appt["Patient"]["PrimaryWorkPhone"]
                appointment.pagerNo = appt["Patient"]["PagerNumber"]
                # Patient's Address mapping.
                if appt["Patient"]["ResidentialAddress"] not in NULLS:
                    if appt["Patient"]["ResidentialAddress"]["AddressLine1"] not in NULLS:
                        appointment.address = appt["Patient"]["ResidentialAddress"]["AddressLine1"]
                    elif appt["Patient"]["ResidentialAddress"]["AddressLine2"] not in NULLS:
                        appointment.address += " " + appt["Patient"]["ResidentialAddress"]["AddressLine2"]
                    if appt["Patient"]["ResidentialAddress"]["City"] not in NULLS:
                        appointment.city = appt["Patient"]["ResidentialAddress"]["City"]
                    if appt["Patient"]["ResidentialAddress"]["State"] not in NULLS:
                        appointment.state = appt["Patient"]["ResidentialAddress"]["State"]
                    if appt["Patient"]["ResidentialAddress"]["PostalCode"] not in NULLS:
                        appointment.zip = appt["Patient"]["ResidentialAddress"]["PostalCode"]
                if appt["Patient"]["PrimaryLanguage"] not in NULLS:
                    appointment.language = appt["Patient"]["PrimaryLanguage"]
                if appt["Patient"]["DateOfBirth"] not in NULLS:
                    dob = re.findall(r"\/\w+\S(\-?\d+)", appt["Patient"]["DateOfBirth"])[
                        0
                    ]  # trying to parse '/Date(223432432432-4400)/ and /Date(-223432432432-4400)/'
                    if dob[0] == "-":
                        dob = dob[1:]
                    dob = time.gmtime(long(dob) / 1000)
                    appointment.dateOfBirth = time.strftime("%Y-%m-%d", dob)
                appointment.guarantorID = appt["Patient"]["GuarantorID"]

                # Doctor data
                appointment.altDoctorId = appt["Resource"]["OwnerCareProviderID"]
                if appt["Resource"]["Name"]:
                    appointment.doctorName = appt["Resource"]["Name"]
                    if appointment.doctorName.find("Dr") == -1:
                        appointment.doctorName = "Dr. " + appointment.doctorName
                else:
                    appointment.doctorName = "the staff"

                # Facility data
                appointment.altFacilityId = appt["ScheduleLocation"]["ScheduleLocationID"]
                appointment.facilityName = appt["ScheduleLocation"]["Name"]
                appointment.facilityAddr = appt["ScheduleLocation"]["CareProviderLocation"]["Address"]

                appointment.normalize()
                LOGGER.debug(
                    "Appointment ID: %s, serialized result: \n%s" % (appointment.altAppointmentId, appointment.__dict__)
                )
                self.serialized_appointments.append(appointment)

        return self.serialized_appointments

    def save_data(self):
        """
            Save serialized data in database, make changes in table : Patient, Appointment, Doctor, Facility
            
        """
        LOGGER.info("-------------------------------")
        LOGGER.info("|         Save Data           |")
        LOGGER.info("-------------------------------")
        LOGGER.info("Saving appointments to database. Count: %s" % (len(self.serialized_appointments)))
        number = 1
        for appt in self.serialized_appointments:
            LOGGER.info(
                "Saving appointment (%s of %s). Alt appointment id: %s"
                % (number, len(self.serialized_appointments), appt.altAppointmentId)
            )
            appt.altFacilityId = 1
            number += 1
            save_appointment(appt.__dict__)