diff --git a/.github/workflows/publish-to-test-pypi.yml b/.github/workflows/publish-to-test-pypi.yml index c6922d4..2fa7516 100644 --- a/.github/workflows/publish-to-test-pypi.yml +++ b/.github/workflows/publish-to-test-pypi.yml @@ -7,10 +7,10 @@ jobs: runs-on: ubuntu-22.04 steps: - uses: actions/checkout@master - - name: Set up Python 3.9 + - name: Set up Python 3.13 uses: actions/setup-python@v1 with: - python-version: 3.9 + python-version: 3.13 - name: Install pypa/build run: >- python -m diff --git a/connectpyse/CHANGES.md b/connectpyse/CHANGES.md index 3a7187e..91d8903 100644 --- a/connectpyse/CHANGES.md +++ b/connectpyse/CHANGES.md @@ -71,4 +71,12 @@ 0.7.6 --- -- Added support for Document Download \ No newline at end of file +- Added support for Document Download + +0.8.0 +--- +- Moved to pyproject.toml + +0.8.1 +--- +- Added ProjectTicket and ProjectTicketsAPI endpoints \ No newline at end of file diff --git a/connectpyse/project/project_ticket.py b/connectpyse/project/project_ticket.py new file mode 100644 index 0000000..68213ce --- /dev/null +++ b/connectpyse/project/project_ticket.py @@ -0,0 +1,133 @@ +from ..cw_model import CWModel + + +class ProjectTicket(CWModel): + + def __init__(self, json_dict=None): + + # Core fields + self.id = None # (int) + self.summary = None # (String) Max length: 100, required + self.isIssueFlag = None # (boolean) + + # Reference objects + self.board = None # (BoardReference) + self.status = None # (ServiceStatusReference) + self.workRole = None # (WorkRoleReference) + self.workType = None # (WorkTypeReference) + self.project = None # (ProjectReference) + self.phase = None # (ProjectPhaseReference) required + + # WBS and Location + self.wbsCode = None # (String) Max length: 50 + self.company = None # (CompanyReference) + self.site = None # (SiteReference) + self.siteName = None # (String) Max length: 156 + + # Address fields + self.addressLine1 = None # (String) Max length: 50 + self.addressLine2 = None # (String) Max length: 50 + self.city = None # (String) Max length: 50 + self.stateIdentifier = None # (String) Max length: 50 + self.zip = None # (String) Max length: 12 + self.country = None # (CountryReference) + + # Contact information + self.contact = None # (ContactReference) + self.contactName = None # (String) Max length: 62 + self.contactPhoneNumber = None # (String) Max length: 20 + self.contactPhoneExtension = None # (String) Max length: 15 + self.contactEmailAddress = None # (String) Max length: 250 + + # Service classification + self.type = None # (ServiceTypeReference) + self.subType = None # (ServiceSubTypeReference) + self.item = None # (ServiceItemReference) + + # Assignment and priority + self.owner = None # (MemberReference) + self.priority = None # (PriorityReference) + self.serviceLocation = None # (ServiceLocationReference) + self.source = None # (ServiceSourceReference) + + # Dates and hours + self.requiredDate = None # (String) ISO 8601 datetime + self.budgetHours = None # (double) + + # Related records + self.opportunity = None # (OpportunityReference) + self.agreement = None # (AgreementReference) + self.agreementType = None # (String) + + # Knowledge base + self.knowledgeBaseCategoryId = None # (int) + self.knowledgeBaseSubCategoryId = None # (int) + self.knowledgeBaseLinkId = None # (int) + self.knowledgeBaseLinkType = None # (String) Enum: ["ServiceFaq", "ServiceTicket", "ServiceBoard", "Article", "Unknown", "SalesFaq"] + + # Portal and notification flags + self.allowAllClientsPortalView = None # (boolean) + self.customerUpdatedFlag = None # (boolean) + self.automaticEmailContactFlag = None # (boolean) + self.automaticEmailResourceFlag = None # (boolean) + self.automaticEmailCcFlag = None # (boolean) + self.automaticEmailCc = None # (String) Max length: 1000 + + # Closure information + self.closedDate = None # (String) + self.closedBy = None # (String) + self.closedFlag = None # (boolean) + + # Time tracking + self.actualHours = None # (double) + self.approved = None # (boolean) + + # Billing + self.subBillingMethod = None # (String) Enum: ["ActualRates", "FixedFee", "NotToExceed", "OverrideRate"] + self.subBillingAmount = None # (double) + self.subDateAccepted = None # (String) + self.resources = None # (String) + + # Billing flags + self.billTime = None # (String) Enum: ["Billable", "DoNotBill", "NoCharge", "NoDefault"] + self.billExpenses = None # (String) Enum: ["Billable", "DoNotBill", "NoCharge", "NoDefault"] + self.billProducts = None # (String) Enum: ["Billable", "DoNotBill", "NoCharge", "NoDefault"] + + # Predecessor/dependency information + self.predecessorType = None # (String) Enum: ["Ticket", "Phase"] + self.predecessorId = None # (int) + self.predecessorClosedFlag = None # (boolean) + self.lagDays = None # (int) + self.lagNonworkingDaysFlag = None # (boolean) + + # Scheduling + self.estimatedStartDate = None # (String) ISO 8601 datetime + self.location = None # (SystemLocationReference) + self.department = None # (SystemDepartmentReference) + self.duration = None # (int) + self.scheduleStartDate = None # (String) ISO 8601 datetime + self.scheduleEndDate = None # (String) ISO 8601 datetime + + # Additional fields + self.mobileGuid = None # (String) UUID format + self.currency = None # (CurrencyReference) + self._info = None # (dict) + + # Related objects + self.tasks = None # (List) List of TicketTask + + # POST-only fields (not returned in response) + self.initialDescription = None # (String) + self.initialInternalAnalysis = None # (String) + self.initialResolution = None # (String) + + # Processing flags + self.contactEmailLookup = None # (String) + self.processNotifications = None # (boolean) Can be set to false to skip notification processing (defaults to True) + self.skipCallback = None # (boolean) + + # Custom fields + self.customFields = None # (List) List of CustomFieldValue + + # initialize object with json dict + super().__init__(json_dict) diff --git a/connectpyse/project/project_tickets_api.py b/connectpyse/project/project_tickets_api.py new file mode 100644 index 0000000..0bf373c --- /dev/null +++ b/connectpyse/project/project_tickets_api.py @@ -0,0 +1,39 @@ +from ..cw_controller import CWController +# Class for /project/tickets +from . import project_ticket + + +class ProjectTicketsAPI(CWController): + def __init__(self, **kwargs): + self.module_url = 'project' + self.module = 'tickets' + self._class = project_ticket.ProjectTicket + super().__init__(**kwargs) # instance gets passed to parent object + + def get_tickets(self): + return super()._get() + + def create_ticket(self, a_ticket): + return super()._create(a_ticket) + + def get_tickets_count(self): + return super()._get_count() + + def get_ticket_by_id(self, ticket_id): + return super()._get_by_id(ticket_id) + + def delete_ticket_by_id(self, ticket_id): + super()._delete_by_id(ticket_id) + + def replace_ticket(self, ticket_id): + pass + + def update_ticket(self, ticket_id, key, value): + return super()._update(ticket_id, key, value) + + def update_ticket_multiple_keys(self, ticket_id, changes_dict): + return super()._update_multiple_keys(ticket_id, changes_dict) + + def merge_ticket(self, a_ticket, target_ticket_id): + # return super()._merge(a_ticket, target_ticket_id) + pass diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..4189255 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,36 @@ +[build-system] +requires = ["setuptools>=61.0", "wheel"] +build-backend = "setuptools.build_meta" + +[project] +name = "connectpyse" +version = "0.8.1" +description = "A ConnectWise API tool for the rest of us." +readme = "README.md" +license = {text = "MIT"} +authors = [ + {name = "Joshua M Smith (original)", email = "saether@gmail.com"}, + {name = "Mark Ciecior (forked)", email = "mark@markciecior.com"}, + {name = "@wesgann"} +] +keywords = ["connectwise", "rest", "api"] +classifiers = [ + "Development Status :: 3 - Alpha", + "License :: OSI Approved :: MIT License", + "Programming Language :: Python :: 3.5", +] +requires-python = ">=3.5" +dependencies = [ + "requests", +] + +[project.urls] +Homepage = "https://github.com/markciecior/ConnectPyse" + +[tool.setuptools] +include-package-data = true +zip-safe = false + +[tool.setuptools.packages.find] +where = ["."] +include = ["connectpyse*"] diff --git a/setup.py b/setup.py deleted file mode 100644 index 7f20052..0000000 --- a/setup.py +++ /dev/null @@ -1,42 +0,0 @@ -from setuptools import setup - - -with open('README.md', 'r') as f: - long_description = f.read() - -setup(name='connectpyse', - version='0.7.6', - description='A ConnectWise API tool for the rest of us.', - long_description=long_description, - long_description_content_type="text/markdown", - classifiers=[ - 'Development Status :: 3 - Alpha', - 'License :: OSI Approved :: MIT License', - 'Programming Language :: Python :: 3.5' - ], - keywords='connectwise rest api', - url='https://github.com/markciecior/ConnectPyse', - author='Joshua M Smith (original), Mark Ciecior (forked), @wesgann', - author_email='saether@gmail.com (original), mark@markciecior.com (forked)', - license='MIT', - packages=['.', - 'connectpyse.company', - 'connectpyse.expense', - 'connectpyse.finance', - 'connectpyse.marketing', - 'connectpyse.procurement', - 'connectpyse.project', - 'connectpyse.sales', - 'connectpyse.schedule', - 'connectpyse.service', - 'connectpyse.system', - 'connectpyse.time'], - py_modules = ['connectpyse.cw_controller', - 'connectpyse.config', - 'connectpyse.cw_model', - 'connectpyse.restapi'], - install_requires=[ - 'requests' - ], - include_package_data=True, - zip_safe=False)