From 409a49ba200be04f1e4ec779e4581a07703e6f1e Mon Sep 17 00:00:00 2001 From: Lance Edgar Date: Fri, 12 Aug 2022 14:27:26 -0500 Subject: [PATCH] Standardize merge logic when a handler is defined for it also adds basic merge support for products view --- tailbone/views/master.py | 33 ++++++++++++++++++++++++++++++++- tailbone/views/people.py | 32 +++++--------------------------- tailbone/views/products.py | 2 ++ 3 files changed, 39 insertions(+), 28 deletions(-) diff --git a/tailbone/views/master.py b/tailbone/views/master.py index 610c2c2e..1915ac83 100644 --- a/tailbone/views/master.py +++ b/tailbone/views/master.py @@ -108,6 +108,7 @@ class MasterView(View): supports_set_enabled_toggle = False populatable = False mergeable = False + merge_handler = None downloadable = False cloneable = False touchable = False @@ -1931,17 +1932,34 @@ class MasterView(View): def get_merge_fields(self): if hasattr(self, 'merge_fields'): return self.merge_fields + + if self.merge_handler: + fields = self.merge_handler.get_merge_preview_fields() + return [field['name'] for field in fields] + mapper = orm.class_mapper(self.get_model_class()) return mapper.columns.keys() def get_merge_coalesce_fields(self): if hasattr(self, 'merge_coalesce_fields'): return self.merge_coalesce_fields + + if self.merge_handler: + fields = self.merge_handler.get_merge_preview_fields() + return [field['name'] for field in fields + if field.get('coalesce')] + return [] def get_merge_additive_fields(self): if hasattr(self, 'merge_additive_fields'): return self.merge_additive_fields + + if self.merge_handler: + fields = self.merge_handler.get_merge_preview_fields() + return [field['name'] for field in fields + if field.get('additive')] + return [] def merge(self): @@ -1985,8 +2003,15 @@ class MasterView(View): the requested merge is valid, in your context. If it is not - for *any reason* - you should raise an exception; the type does not matter. """ + if self.merge_handler: + reason = self.merge_handler.why_not_merge(removing, keeping) + if reason: + raise Exception(reason) def get_merge_data(self, obj): + if self.merge_handler: + return self.merge_handler.get_merge_preview_data(obj) + raise NotImplementedError("please implement `{}.get_merge_data()`".format(self.__class__.__name__)) def get_merge_resulting_data(self, remove, keep): @@ -2008,7 +2033,13 @@ class MasterView(View): Merge the two given objects. You should probably override this; default behavior is merely to delete the 'removing' object. """ - self.Session.delete(removing) + if self.merge_handler: + self.merge_handler.perform_merge(removing, keeping, + user=self.request.user) + + else: + # nb. default "merge" does not update kept object! + self.Session.delete(removing) ############################## # Core Stuff diff --git a/tailbone/views/people.py b/tailbone/views/people.py index 55f35927..5dc76b73 100644 --- a/tailbone/views/people.py +++ b/tailbone/views/people.py @@ -95,10 +95,13 @@ class PersonView(MasterView): def __init__(self, request): super(PersonView, self).__init__(request) + app = self.get_rattail_app() # always get a reference to the People Handler - app = self.get_rattail_app() - self.handler = app.get_people_handler() + self.people_handler = app.get_people_handler() + self.merge_handler = self.people_handler + # TODO: deprecate / remove this + self.handler = self.people_handler def make_grid_kwargs(self, **kwargs): kwargs = super(PersonView, self).make_grid_kwargs(**kwargs) @@ -396,31 +399,6 @@ class PersonView(MasterView): (model.VendorContact, 'person_uuid'), ] - def get_merge_fields(self): - fields = self.handler.get_merge_preview_fields() - return [field['name'] for field in fields] - - def get_merge_additive_fields(self): - fields = self.handler.get_merge_preview_fields() - return [field['name'] for field in fields - if field.get('additive')] - - def get_merge_coalesce_fields(self): - fields = self.handler.get_merge_preview_fields() - return [field['name'] for field in fields - if field.get('coalesce')] - - def get_merge_data(self, person): - return self.handler.get_merge_preview_data(person) - - def validate_merge(self, removing, keeping): - reason = self.handler.why_not_merge(removing, keeping) - if reason: - raise Exception(reason) - - def merge_objects(self, removing, keeping): - self.handler.perform_merge(removing, keeping, user=self.request.user) - def view_profile(self): """ View which exposes the "full profile" for a given person, i.e. all diff --git a/tailbone/views/products.py b/tailbone/views/products.py index a9376faf..8f1ea545 100644 --- a/tailbone/views/products.py +++ b/tailbone/views/products.py @@ -83,6 +83,7 @@ class ProductView(MasterView): has_versions = True results_downloadable_xlsx = True supports_autocomplete = True + mergeable = True configurable = True labels = { @@ -180,6 +181,7 @@ class ProductView(MasterView): app = self.get_rattail_app() self.products_handler = app.get_products_handler() + self.merge_handler = self.products_handler # TODO: deprecate / remove these self.product_handler = self.products_handler self.handler = self.products_handler