From c3441f700dba9966c4a8dc1d9aef5a40690e5b19 Mon Sep 17 00:00:00 2001 From: Lance Edgar Date: Sat, 10 Aug 2024 12:00:48 -0500 Subject: [PATCH 1/9] fix: improve `core-office anonymize` command logic - prefer setting `custdata` names over `meminfo` - use custdata name for basis of `meminfo.email` - use "real" random zipcode - fix attr assignment for `meminfo.zip` --- rattail_corepos/corepos/office/anonymize.py | 80 ++++++++++++--------- rattail_corepos/corepos/office/commands.py | 7 ++ 2 files changed, 54 insertions(+), 33 deletions(-) diff --git a/rattail_corepos/corepos/office/anonymize.py b/rattail_corepos/corepos/office/anonymize.py index 276c88f..912ca69 100644 --- a/rattail_corepos/corepos/office/anonymize.py +++ b/rattail_corepos/corepos/office/anonymize.py @@ -37,8 +37,13 @@ class Anonymizer(GenericHandler): """ def anonymize_all(self, dbkey=None, dry_run=False, progress=None): + # nb. these must be installed with: + # pip install names us zipcodes import names import us + import zipcodes + + self.all_zipcodes = zipcodes.list_all() core_handler = self.app.get_corepos_handler() op_session = core_handler.make_session_office_op(dbkey=dbkey) @@ -46,45 +51,56 @@ class Anonymizer(GenericHandler): states = [state.abbr for state in us.states.STATES] - # meminfo - members = op_session.query(op_model.MemberInfo).all() - members_by_card_number = {} - - def anon_meminfo(member, i): - member.first_name = names.get_first_name() - member.last_name = names.get_last_name() - member.other_first_name = names.get_first_name() - member.other_last_name = names.get_last_name() - member.street = '123 Main St.' - member.city = 'Anytown' - member.state = random.choice(states) - member.zipcode = self.random_zipcode() - member.phone = self.random_phone() - member.email = self.random_email() - member.notes.clear() - members_by_card_number[member.card_number] = member - - self.app.progress_loop(anon_meminfo, members, progress, - message="Anonymizing meminfo") - # custdata - customers = op_session.query(op_model.CustomerClassic).all() + customers = op_session.query(op_model.CustomerClassic)\ + .order_by(op_model.CustomerClassic.card_number, + op_model.CustomerClassic.person_number)\ + .all() blueline_template = get_blueline_template(self.config) + customers_by_card_number = {} def anon_custdata(customer, i): - member = members_by_card_number.get(customer.card_number) - if member: - customer.first_name = member.first_name - customer.last_name = member.last_name - else: - customer.first_name = names.get_first_name() - customer.last_name = names.get_last_name() + customer.first_name = names.get_first_name() + customer.last_name = names.get_last_name() customer.blue_line = make_blueline(self.config, customer, template=blueline_template) + customers_by_card_number.setdefault(customer.card_number, []).append(customer) self.app.progress_loop(anon_custdata, customers, progress, message="Anonymizing custdata") + # meminfo + members = op_session.query(op_model.MemberInfo).all() + + def anon_meminfo(member, i): + if member.first_name: + member.first_name = names.get_first_name() + if member.last_name: + member.last_name = names.get_last_name() + if member.other_first_name: + member.other_first_name = names.get_first_name() + if member.other_last_name: + member.other_last_name = names.get_last_name() + + member.street = '123 Main St.' + member.city = 'Anytown' + member.state = random.choice(states) + member.zip = self.random_zipcode() + member.phone = self.random_phone() + + customers = customers_by_card_number.get(member.card_number) + if customers: + customer = customers[0] + member.email = f'{customer.first_name}_{customer.last_name}@mailinator.com'\ + .lower() + else: + member.email = self.random_email() + + member.notes.clear() + + self.app.progress_loop(anon_meminfo, members, progress, + message="Anonymizing meminfo") + # Customers customers = op_session.query(op_model.Customer).all() @@ -133,9 +149,7 @@ class Anonymizer(GenericHandler): import names name = names.get_full_name() name = name.replace(' ', '_') - return f'{name}@mailinator.com' + return f'{name}@mailinator.com'.lower() def random_zipcode(self): - digits = [random.choice('0123456789') - for i in range(5)] - return ''.join(digits) + return random.choice(self.all_zipcodes)['zip_code'] diff --git a/rattail_corepos/corepos/office/commands.py b/rattail_corepos/corepos/office/commands.py index 51ff05f..dd10603 100644 --- a/rattail_corepos/corepos/office/commands.py +++ b/rattail_corepos/corepos/office/commands.py @@ -95,6 +95,13 @@ def anonymize( "\tpip install us\n") sys.exit(2) + try: + import zipcodes + except ImportError: + sys.stderr.write("must install the `zipcodes` package first!\n\n" + "\tpip install zipcodes\n") + sys.exit(2) + anonymizer = Anonymizer(config) anonymizer.anonymize_all(dbkey=dbkey, dry_run=dry_run, progress=progress) From b4f8bb9c93b251b36ea938e7df5f0fee71d43ad2 Mon Sep 17 00:00:00 2001 From: Lance Edgar Date: Tue, 13 Aug 2024 11:24:36 -0500 Subject: [PATCH 2/9] =?UTF-8?q?bump:=20version=200.3.6=20=E2=86=92=200.3.7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGELOG.md | 6 ++++++ pyproject.toml | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 82f5044..1d49b0b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to rattail-corepos will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html). +## v0.3.7 (2024-08-13) + +### Fix + +- improve `core-office anonymize` command logic + ## v0.3.6 (2024-08-06) ### Fix diff --git a/pyproject.toml b/pyproject.toml index 748c5fb..8a2bfde 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -6,7 +6,7 @@ build-backend = "hatchling.build" [project] name = "rattail_corepos" -version = "0.3.6" +version = "0.3.7" description = "Rattail Software Interfaces for CORE POS" readme = "README.rst" authors = [{name = "Lance Edgar", email = "lance@edbob.org"}] From 802c8ab87b79ea501e262527da1802bd7f5c2b28 Mon Sep 17 00:00:00 2001 From: Lance Edgar Date: Wed, 14 Aug 2024 09:12:32 -0500 Subject: [PATCH 3/9] fix: work around, log error when datasync can't locate member --- rattail_corepos/datasync/rattail.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/rattail_corepos/datasync/rattail.py b/rattail_corepos/datasync/rattail.py index 5b6e925..18ff5dd 100644 --- a/rattail_corepos/datasync/rattail.py +++ b/rattail_corepos/datasync/rattail.py @@ -24,11 +24,16 @@ DataSync for Rattail DB """ +import logging + from sqlalchemy import orm from rattail.datasync import DataSyncImportConsumer +log = logging.getLogger(__name__) + + class FromCOREAPIToRattail(DataSyncImportConsumer): """ Consumer for CORE POS (API) -> Rattail datasync @@ -69,6 +74,11 @@ class FromCOREAPIToRattail(DataSyncImportConsumer): else: # import member data from API, into various Rattail tables member = self.get_host_object(session, change) + if not member: + # TODO: should log.warning() instead but for now i + # need to see this in action and further troubleshoot + log.error("CORE member not found for change: %s", change) + continue self.process_change(session, self.importers['Customer'], host_object=member) shoppers = self.importers['CustomerShopper'].get_shoppers_for_member(member) From 6072a359fdef8dc7089abab7c31dd73b7d1e3ccd Mon Sep 17 00:00:00 2001 From: Lance Edgar Date: Fri, 16 Aug 2024 10:14:07 -0500 Subject: [PATCH 4/9] fix: avoid deprecated base class for config extension --- rattail_corepos/config.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/rattail_corepos/config.py b/rattail_corepos/config.py index cdb032e..376e365 100644 --- a/rattail_corepos/config.py +++ b/rattail_corepos/config.py @@ -26,12 +26,11 @@ Rattail-COREPOS Config Extension import warnings +from wuttjamaican.conf import WuttaConfigExtension from wuttjamaican.db.conf import get_engines -from rattail.config import ConfigExtension - -class RattailCOREPOSExtension(ConfigExtension): +class RattailCOREPOSExtension(WuttaConfigExtension): """ Config extension for Rattail-COREPOS """ From 666fb747bb4580da781a701b52859b4e9466dd7f Mon Sep 17 00:00:00 2001 From: Lance Edgar Date: Sun, 18 Aug 2024 20:08:25 -0500 Subject: [PATCH 5/9] =?UTF-8?q?bump:=20version=200.3.7=20=E2=86=92=200.3.8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGELOG.md | 7 +++++++ pyproject.toml | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1d49b0b..1815f59 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,13 @@ All notable changes to rattail-corepos will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html). +## v0.3.8 (2024-08-18) + +### Fix + +- avoid deprecated base class for config extension +- work around, log error when datasync can't locate member + ## v0.3.7 (2024-08-13) ### Fix diff --git a/pyproject.toml b/pyproject.toml index 8a2bfde..2cf8f29 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -6,7 +6,7 @@ build-backend = "hatchling.build" [project] name = "rattail_corepos" -version = "0.3.7" +version = "0.3.8" description = "Rattail Software Interfaces for CORE POS" readme = "README.rst" authors = [{name = "Lance Edgar", email = "lance@edbob.org"}] From 57d3a21e4394896e1f4450709ca2dcfa7202a89a Mon Sep 17 00:00:00 2001 From: Lance Edgar Date: Mon, 19 Aug 2024 11:30:44 -0500 Subject: [PATCH 6/9] fix: improve logic for matching CORE stock purchase to Rattail payment we were already "trying" to match on date only, but only as a sort of fallback. now we still try "exact" date/time match first but then also an explicit date match, before other fallback logic --- rattail_corepos/importing/corepos/db.py | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/rattail_corepos/importing/corepos/db.py b/rattail_corepos/importing/corepos/db.py index 63b6894..59d4b0e 100644 --- a/rattail_corepos/importing/corepos/db.py +++ b/rattail_corepos/importing/corepos/db.py @@ -953,7 +953,17 @@ class MemberEquityPaymentImporter(FromCOREPOS, corepos_importing.model.MemberEqu if len(match) == 1: return match[0] - # nb. avoid datetime for this one + # then try to match on date only, not time + match = [payment for payment in payments + if payment.corepos_transaction_number == stock_purchase.transaction_number + and payment.corepos_transaction_id == stock_purchase.transaction_id + and payment.amount == stock_purchase.amount + and payment.corepos_department_number == stock_purchase.department_number + and self.app.localtime(payment.corepos_datetime, from_utc=True).date() == dt.date()] + if len(match) == 1: + return match[0] + + # nb. avoid date/time for this one matches = [payment for payment in payments if payment.corepos_transaction_number == stock_purchase.transaction_number and payment.corepos_transaction_id == stock_purchase.transaction_id @@ -966,6 +976,9 @@ class MemberEquityPaymentImporter(FromCOREPOS, corepos_importing.model.MemberEqu stock_purchase.amount, stock_purchase.datetime) + # TODO: now that we try to match on date above, this logic + # may no longer be necssary/useful? + # so there is one match, but its timestamp may be way off, # so let's also make sure at least date matches payment = matches[0] From c954c4304bc0937f3fa1903271ef34be665c2427 Mon Sep 17 00:00:00 2001 From: Lance Edgar Date: Mon, 19 Aug 2024 12:02:28 -0500 Subject: [PATCH 7/9] =?UTF-8?q?bump:=20version=200.3.8=20=E2=86=92=200.3.9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGELOG.md | 6 ++++++ pyproject.toml | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1815f59..28bd885 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to rattail-corepos will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html). +## v0.3.9 (2024-08-19) + +### Fix + +- improve logic for matching CORE stock purchase to Rattail payment + ## v0.3.8 (2024-08-18) ### Fix diff --git a/pyproject.toml b/pyproject.toml index 2cf8f29..4e1763a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -6,7 +6,7 @@ build-backend = "hatchling.build" [project] name = "rattail_corepos" -version = "0.3.8" +version = "0.3.9" description = "Rattail Software Interfaces for CORE POS" readme = "README.rst" authors = [{name = "Lance Edgar", email = "lance@edbob.org"}] From 7cc5c7abad6d3a0d55bd03d1cb66922924c4bc94 Mon Sep 17 00:00:00 2001 From: Lance Edgar Date: Fri, 13 Sep 2024 18:46:06 -0500 Subject: [PATCH 8/9] docs: use markdown for readme file --- README.md | 11 +++++++++++ README.rst | 14 -------------- pyproject.toml | 2 +- 3 files changed, 12 insertions(+), 15 deletions(-) create mode 100644 README.md delete mode 100644 README.rst diff --git a/README.md b/README.md new file mode 100644 index 0000000..cb82d29 --- /dev/null +++ b/README.md @@ -0,0 +1,11 @@ + +# rattail-corepos + +Rattail is a retail software framework, released under the GNU General Public +License. + +This package contains software interfaces for the [CORE +POS](https://github.com/CORE-POS/IS4C) system. + +Please see Rattail's [home page](https://rattailproject.org/) for more +information. diff --git a/README.rst b/README.rst deleted file mode 100644 index 5f5141b..0000000 --- a/README.rst +++ /dev/null @@ -1,14 +0,0 @@ - -rattail_corepos -=============== - -Rattail is a retail software framework, released under the GNU General Public -License. - -This package contains software interfaces for the `CORE POS`_ system. - -.. _`CORE POS`: https://github.com/CORE-POS/IS4C - -Please see Rattail's `home page`_ for more information. - -.. _`home page`: https://rattailproject.org/ diff --git a/pyproject.toml b/pyproject.toml index 4e1763a..e55beae 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -8,7 +8,7 @@ build-backend = "hatchling.build" name = "rattail_corepos" version = "0.3.9" description = "Rattail Software Interfaces for CORE POS" -readme = "README.rst" +readme = "README.md" authors = [{name = "Lance Edgar", email = "lance@edbob.org"}] license = {text = "GNU GPL v3+"} classifiers = [ From 49d897ab86b37c4c67d4d6a51c3d53be7a147452 Mon Sep 17 00:00:00 2001 From: Lance Edgar Date: Sat, 14 Sep 2024 12:11:06 -0500 Subject: [PATCH 9/9] docs: update project links, kallithea -> forgejo --- pyproject.toml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index e55beae..11e679d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -33,10 +33,10 @@ dependencies = [ [project.urls] -Homepage = "https://redmine.rattailproject.org/projects/corepos-integration" -Repository = "https://kallithea.rattailproject.org/rattail-project/rattail-corepos" -Issues = "https://redmine.rattailproject.org/projects/corepos-integration/issues" -Changelog = "https://kallithea.rattailproject.org/rattail-project/rattail-corepos/files/master/CHANGELOG.md" +Homepage = "https://rattailproject.org" +Repository = "https://forgejo.wuttaproject.org/rattail/rattail-corepos" +Issues = "https://forgejo.wuttaproject.org/rattail/rattail-corepos/issues" +Changelog = "https://forgejo.wuttaproject.org/rattail/rattail-corepos/src/branch/master/CHANGELOG.md" [project.scripts]