コード例 #1
0
class CalendarSync:
    STATUS_MAP = {
        'approved': 'confirmed',
        'denied': 'tentative',
        'declined': 'tentative',
        'requested': 'tentative',
        'canceled': 'cancelled',  # This is what their API is
        'cancelled': 'cancelled'  # Just in case they fix it
    }

    def __init__(self):
        outer_config = Config()
        config = outer_config.get_config()

        try:
            token = config[Config.BAMBOO_SECTION]['token']
        except KeyError:
            # No token - try getting it from username/password
            password = getpass()
            token = CalendarSync.get_api_key(
                config[Config.BAMBOO_SECTION]['company'],
                config[Config.BAMBOO_SECTION]['user'], password)
            outer_config.save_token(token)

        self.bamboohr_client = PyBambooHR(
            config[Config.BAMBOO_SECTION]['company'], token)
        self.gcal_client = GoogleCalendar(
            config[Config.GCAL_SECTION]['calendar_id'])
        self.employee_id = config[Config.BAMBOO_SECTION]['employee_id']

    @staticmethod
    def get_api_key(company, user, password):

        logging.info('Obtaining API Key')
        payload = {
            'user': user,
            'password': password,
            'applicationKey': '3fdb46cdade6088a442be908141eaaada89ff6c9'
        }
        url = 'https://api.bamboohr.com/api/gateway.php/%s/v1/login' % company
        r = requests.post(url,
                          data=payload,
                          headers={'Accept': "application/json"})
        # I have no idea how long this key is valid for. Let's see when it fails
        if r.ok:
            return json.loads(r.text).get('key')
        else:
            raise Exception(
                'Failed to get Access Token. Invalid username/password?')

    def get_time_off_requests(self):
        # Get events up to one year in the past
        start = (date.today() - timedelta(days=365)).isoformat()
        return self.bamboohr_client.get_time_off_requests(
            start_date=start, employee_id=self.employee_id)

    def update_calendar(self, time_off_requests):
        print('Updating/Creating %s items' % len(time_off_requests))
        for booking in time_off_requests:
            event_id = 'emp' + booking['employeeId'] + 'id' + booking['id']
            start = booking['start']
            # Add an extra day, otherwise google will treat it as ending at the start of the last day
            end = (datetime.strptime(booking['end'], '%Y-%m-%d') +
                   timedelta(days=1)).date().isoformat()

            status = booking['status']['status']
            notes = 'Type: ' + booking['type']['name'] + '\n'
            try:
                notes += 'Notes:\n' + '\n'.join([
                    '  ' + str(k) + ': ' + str(v)
                    for k, v in booking['notes'].items()
                ])
            except AttributeError as e:
                pass
            summary = 'Time Booked off: ' + status.title()
            # Set the status to be what google calendars expents
            status = self.STATUS_MAP.get(status, 'tentative')
            logging.debug(
                'Updating Booking: id: %s, start: %s, end: %s, status: %s, summary: %s, notes: %s',
                event_id, start, end, status, summary, notes)
            self.gcal_client.update_event(event_id, start, end, status,
                                          summary, notes)
コード例 #2
0
class test_time_off(unittest.TestCase):
    # Used to store the cached instance of PyBambooHR
    bamboo = None

    def setUp(self):
        if self.bamboo is None:
            self.bamboo = PyBambooHR(subdomain='test',
                                     api_key='testingnotrealapikey')

    @httpretty.activate
    def test_get_time_off_requests(self):
        body = [{
            "id": "1342",
            "employeeId": "4",
            "status": {
                "lastChanged": "2019-09-12",
                "lastChangedByUserId": "2369",
                "status": "approved"
            },
            "name": "Charlotte Abbott",
            "start": "2019-05-30",
            "end": "2019-06-01",
            "created": "2019-09-11",
            "type": {
                "id": "78",
                "name": "Vacation",
                "icon": "palm-trees"
            },
            "amount": {
                "unit": "hours",
                "amount": "24"
            },
            "actions": {
                "view": True,
                "edit": True,
                "cancel": False,
                "approve": False,
                "deny": False,
                "bypass": False
            },
            "dates": {
                "2019-05-30": "24"
            },
            "notes": {
                "manager": "Home sick with the flu."
            }
        }]
        httpretty.register_uri(
            httpretty.GET,
            "https://api.bamboohr.com/api/gateway.php/test/v1/time_off/requests",
            body=dumps(body),
            content_type="application/json")

        response = self.bamboo.get_time_off_requests()
        self.assertIsNotNone(response)
        self.assertTrue(len(response) > 0)
        self.assertEquals(response[0]['id'], '1342')
        return

    @httpretty.activate
    def test_get_time_off_policies(self):
        body = [{
            'id': '70',
            'timeOffTypeId': '77',
            'name': 'Testing Manual Policy',
            'effectiveDate': None,
            'type': 'manual'
        }]
        httpretty.register_uri(
            httpretty.GET,
            "https://api.bamboohr.com/api/gateway.php/test/v1/meta/time_off/policies",
            body=dumps(body),
            content_type="application/json")
        response = self.bamboo.get_time_off_policies()
        self.assertIsNotNone(response)
        self.assertTrue(len(response) > 0)
        self.assertEquals(response[0]['id'], '70')
        return

    @httpretty.activate
    def test_get_time_off_types(self):
        body = {
            'timeOffTypes': [{
                'id': '78',
                'name': 'Vacation',
                'units': 'hours',
                'color': None,
                'icon': 'palm-trees'
            }]
        }
        httpretty.register_uri(
            httpretty.GET,
            "https://api.bamboohr.com/api/gateway.php/test/v1/meta/time_off/types",
            body=dumps(body),
            content_type="application/json")
        response = self.bamboo.get_time_off_types()
        self.assertIsNotNone(response)
        self.assertTrue(len(response) > 0)
        self.assertEquals(response[0]['id'], '78')
        return

    @httpretty.activate
    def test_create_time_off_request(self):
        body = {
            'id':
            '1675',
            'employeeId':
            '111',
            'start':
            '2040-02-01',
            'end':
            '2040-02-02',
            'created':
            '2019-12-24',
            'status': {
                'status': 'requested',
                'lastChanged': '2019-12-24 02:29:45',
                'lastChangedByUserId': '2479'
            },
            'name':
            'xdd xdd',
            'type': {
                'id': '78',
                'name': 'Vacation'
            },
            'amount': {
                'unit': 'hours',
                'amount': '2'
            },
            'notes': {
                'employee': 'Going overseas with family',
                'manager': 'Enjoy!'
            },
            'dates': {
                '2040-02-01': '1',
                '2040-02-02': '1'
            },
            'comments': [{
                'employeeId': '111',
                'comment': 'Enjoy!',
                'commentDate': '2019-12-24',
                'commenterName': 'Test use'
            }],
            'approvers': [{
                'userId':
                '2479',
                'displayName':
                'Test user',
                'employeeId':
                '111',
                'photoUrl':
                'https://resources.bamboohr.com/employees/photos/initials.php?initials=testuser'
            }],
            'actions': {
                'view': True,
                'edit': True,
                'cancel': True,
                'approve': True,
                'deny': True,
                'bypass': True
            },
            'policyType':
            'discretionary',
            'usedYearToDate':
            0,
            'balanceOnDateOfRequest':
            0
        }
        httpretty.register_uri(
            httpretty.PUT,
            "https://api.bamboohr.com/api/gateway.php/test/v1/employees/111/time_off/request",
            body=dumps(body),
            content_type="application/json")
        data = {
            'status':
            'requested',
            'employee_id':
            '111',
            'start':
            '2040-02-01',
            'end':
            '2040-02-02',
            'timeOffTypeId':
            '78',
            'amount':
            '2',
            'dates': [{
                'ymd': '2040-02-01',
                'amount': '1'
            }, {
                'ymd': '2040-02-02',
                'amount': '1'
            }],
            'notes': [{
                'type': 'employee',
                'text': 'Going overseas with family'
            }, {
                'type': 'manager',
                'text': 'Enjoy!'
            }]
        }
        response = self.bamboo.create_time_off_request(data)
        self.assertIsNotNone(response)
        self.assertEquals(response['id'], '1675')
        return

    @httpretty.activate
    def test_update_time_off_request_status(self):
        body = {
            'id':
            '1675',
            'employeeId':
            '111',
            'start':
            '2040-02-01',
            'end':
            '2040-02-02',
            'created':
            '2019-12-24',
            'status': {
                'status': 'declined',
                'lastChanged': '2019-12-24 02:29:45',
                'lastChangedByUserId': '2479'
            },
            'name':
            'xdd xdd',
            'type': {
                'id': '78',
                'name': 'Vacation'
            },
            'amount': {
                'unit': 'hours',
                'amount': '2'
            },
            'notes': {
                'employee': 'Going overseas with family',
                'manager': 'Enjoy!'
            },
            'dates': {
                '2040-02-01': '1',
                '2040-02-02': '1'
            },
            'comments': [{
                'employeeId': '111',
                'comment': 'Enjoy!',
                'commentDate': '2019-12-24',
                'commenterName': 'Test use'
            }],
            'approvers': [{
                'userId':
                '2479',
                'displayName':
                'Test user',
                'employeeId':
                '111',
                'photoUrl':
                'https://resources.bamboohr.com/employees/photos/initials.php?initials=testuser'
            }],
            'actions': {
                'view': True,
                'edit': True,
                'cancel': True,
                'approve': True,
                'deny': True,
                'bypass': True
            },
            'policyType':
            'discretionary',
            'usedYearToDate':
            0,
            'balanceOnDateOfRequest':
            0
        }
        httpretty.register_uri(
            httpretty.PUT,
            "https://api.bamboohr.com/api/gateway.php/test/v1/time_off/requests/1675/status",
            body=dumps(body),
            content_type="application/json")
        data = {'status': 'declined', 'note': 'Have fun!'}
        response = self.bamboo.update_time_off_request_status(body['id'], data)
        self.assertIsNotNone(response)
        self.assertTrue(response)
        return