From 12a30fcf1820d1c4a3faf492b8b4a78e73f82ede Mon Sep 17 00:00:00 2001 From: Joe Date: Wed, 6 Nov 2024 14:04:32 -0700 Subject: [PATCH] bug fix; minor updates --- .github/workflows/publish.yml | 10 +++++----- CHANGES.md | 6 ++++++ civipy/contact.py | 12 ++++++++---- civipy/financial.py | 21 +++++++++++++++------ civipy/interface/query.py | 12 ++++++++++++ pyproject.toml | 2 +- 6 files changed, 47 insertions(+), 16 deletions(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index cafb8a5..d5a555b 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -5,7 +5,7 @@ on: branches: - 'main' tags: - - '*' + - '[0-9]+.[0-9]+.[0-9]+' permissions: contents: read @@ -16,10 +16,10 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Set up latest Python - uses: actions/setup-python@v4 + uses: actions/setup-python@v5 with: python-version: "*" @@ -31,7 +31,7 @@ jobs: run: python -m build - name: Upload sdist as workflow artifact - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: path: dist/ @@ -42,7 +42,7 @@ jobs: steps: - name: Download workflow artifacts - uses: actions/download-artifact@v3 + uses: actions/download-artifact@v4 with: name: artifact path: dist diff --git a/CHANGES.md b/CHANGES.md index 9660135..56ad8cd 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -2,6 +2,12 @@ - Drop deprecated model methods +### 0.0.4 November 6, 2024 + +- Fix build bug introduced in 0.0.3 +- Update Contact find methods +- Add `get` and `save` methods to Query + ### 0.0.3 May 14, 2024 - Add CiviCRM v4 API usage and make it the default diff --git a/civipy/contact.py b/civipy/contact.py index 45f0001..1611a02 100644 --- a/civipy/contact.py +++ b/civipy/contact.py @@ -12,14 +12,18 @@ class CiviContact(CiviNotable): @classmethod def find_by_email(cls, email_address: str, select: list[str] | None = None): - email_obj = CiviEmail.find(select=["contact_id"], email=email_address) - return cls.find(select=select, id=email_obj.civi["contact_id"]) + if select is None: + select = [] + email_obj = CiviEmail.objects.filter(email=email_address).values("contact_id")[0] + return cls.objects.filter(id=email_obj.civi["contact_id"]).values(*select)[0] @classmethod def find_all_by_email(cls, email_address: str, select: list[str] | None = None): + if select is None: + select = [] return [ - cls.find(select=select, id=email_obj.civi["contact_id"]) - for email_obj in CiviEmail.find_all(select=["contact_id"], email=email_address) + cls.objects.filter(id=email_obj.civi["contact_id"]).values(*select)[0] + for email_obj in CiviEmail.objects.filter(email=email_address).values("contact_id").all() ] @classmethod diff --git a/civipy/financial.py b/civipy/financial.py index baa6ff0..bb8f905 100644 --- a/civipy/financial.py +++ b/civipy/financial.py @@ -9,10 +9,19 @@ def cancel(cls, **kwargs): @classmethod def find_by_transaction_id(cls, trxn_id: str, entity_table: str) -> "CiviEntityFinancialTrxn | None": """Find a Contribution Payment by payment transaction ID""" - kwargs = { - "select": ["*", "financial_trxn_id.*"], - "entity_table": entity_table, - "financial_trxn_id.trxn_id": trxn_id, - } - found = cls.find_all(**kwargs) + found = cls.objects.filter( + entity_table=entity_table, financial_trxn_id__trxn_id=trxn_id + ).select(["*", "financial_trxn_id.*"]).all() return next(filter(lambda c: bool(c.civi.get("entity_id")), found), None) + + +class CiviFinancialTrxn(CiviCRMBase): + ... + + +class CiviFinancialItem(CiviCRMBase): + ... + + +class CiviLineItem(CiviCRMBase): + ... diff --git a/civipy/interface/query.py b/civipy/interface/query.py index 767cde9..0e0b550 100644 --- a/civipy/interface/query.py +++ b/civipy/interface/query.py @@ -125,6 +125,9 @@ def all(self): self._fetch_all() return self._result_cache + def get(self, **kwargs): + return self.filter(**kwargs)[0] + def filter(self, **kwargs): query = self._chain() if query._filter: @@ -163,6 +166,15 @@ def create(self, **kwargs): response = self._interface().execute("create", self._entity, query) return response + def save(self, records: list[dict[str, str]], defaults: dict[str, str] | None = None, match: list[str] | None = None): + query = {"records": records} + if defaults is not None: + query["defaults"] = defaults + if match is not None: + query["match"] = match + response = self._interface().execute("save", self._entity, query) + return response + def delete(self): query = self._compose() response = self._interface().execute("delete", self._entity, query) diff --git a/pyproject.toml b/pyproject.toml index ba0b141..486217b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -35,7 +35,7 @@ optional-dependencies.dev = [ ] [tool.setuptools] -packages = ["civipy"] +packages = {find = {include = ["civipy*"]}} dynamic.version = {file = "VERSION"} [tool.cibuildwheel]