From a52b5ec3808d4b462e78daf56c6ac3306db46616 Mon Sep 17 00:00:00 2001 From: Lance Edgar Date: Mon, 27 Sep 2021 09:22:06 -0400 Subject: [PATCH] Overhaul new custorder so contact may be either Person or Customer also make the handler responsible for (un)assigning contact --- tailbone/templates/custorders/create.mako | 156 ++++++++++++---------- tailbone/views/custorders/orders.py | 137 +++++++++++++++---- 2 files changed, 202 insertions(+), 91 deletions(-) diff --git a/tailbone/templates/custorders/create.mako b/tailbone/templates/custorders/create.mako index 61df8552..f1ecfb9f 100644 --- a/tailbone/templates/custorders/create.mako +++ b/tailbone/templates/custorders/create.mako @@ -101,50 +101,63 @@
- Customer is already in the system.
-
+
- + % else: + serviceUrl="${url('{}.person_autocomplete'.format(route_prefix))}" + % endif + @input="contactChanged"> + + View Profile + - - - - Please save when finished editing - - - - + v-show="contactUUID"> + {{ phoneNumberEntry }} +## +## +## +## Please save when finished editing +## +## +## +##

- Customer is not yet in the system.
-
+
@@ -382,10 +395,11 @@ batchTotalPriceDisplay: ${json.dumps(normalized_batch['total_price_display'])|n}, customerPanelOpen: false, - customerIsKnown: true, - customerUUID: ${json.dumps(batch.customer_uuid)|n}, - customerDisplay: ${json.dumps(six.text_type(batch.customer or ''))|n}, + contactIsKnown: true, + contactUUID: ${json.dumps(batch.customer_uuid)|n}, + contactDisplay: ${json.dumps(six.text_type(batch.customer or ''))|n}, customerEntry: null, + contactProfileURL: ${json.dumps(contact_profile_url)|n}, phoneNumberEntry: ${json.dumps(batch.phone_number)|n}, phoneNumberSaved: true, customerName: null, @@ -415,12 +429,12 @@ customerPanelHeader() { let text = "Customer" - if (this.customerIsKnown) { - if (this.customerUUID) { - if (this.$refs.customerAutocomplete) { - text = "Customer: " + this.$refs.customerAutocomplete.getDisplayText() + if (this.contactIsKnown) { + if (this.contactUUID) { + if (this.$refs.contactAutocomplete) { + text = "Customer: " + this.$refs.contactAutocomplete.getDisplayText() } else { - text = "Customer: " + this.customerDisplay + text = "Customer: " + this.contactDisplay } } } else { @@ -457,8 +471,8 @@ }, customerStatusTypeAndText() { let phoneNumber = null - if (this.customerIsKnown) { - if (!this.customerUUID) { + if (this.contactIsKnown) { + if (!this.contactUUID) { return { type: 'is-danger', text: "Please identify the customer.", @@ -495,7 +509,7 @@ } } - if (!this.customerIsKnown) { + if (!this.contactIsKnown) { return { type: 'is-warning', text: "Will create a new customer record.", @@ -555,8 +569,8 @@ // return // } // } - // this.customerIsKnown = true - // this.customerUUID = null + // this.contactIsKnown = true + // this.contactUUID = null // // this.customerEntry = null // this.phoneNumberEntry = null // this.customerName = null @@ -607,17 +621,17 @@ }) }, - setCustomerData() { - let params = { - action: 'set_customer_data', - customer_uuid: this.customerUUID, - phone_number: this.phoneNumberEntry, - } - let that = this - this.submitBatchData(params, function(response) { - that.phoneNumberSaved = true - }) - }, + // setContactData() { + // let params = { + // action: 'set_customer_data', + // customer_uuid: this.contactUUID, + // phone_number: this.phoneNumberEntry, + // } + // let that = this + // this.submitBatchData(params, function(response) { + // that.phoneNumberSaved = true + // }) + // }, submitOrder() { this.submittingOrder = true @@ -644,32 +658,40 @@ }) }, - customerChanged(uuid) { + contactChanged(uuid) { + let params if (!uuid) { - this.phoneNumberEntry = null - this.setCustomerData() - } else { - let params = { - action: 'get_customer_info', - uuid: this.customerUUID, + params = { + action: 'unassign_contact', + } + } else { + params = { + action: 'assign_contact', + uuid: this.contactUUID, } - let that = this - this.submitBatchData(params, function(response) { - that.phoneNumberEntry = response.data.phone_number - that.setCustomerData() - }) } + let that = this + this.submitBatchData(params, function(response) { + console.log(response.data) + % if new_order_requires_customer: + that.contactUUID = response.data.customer_uuid + % else: + that.contactUUID = response.data.person_uuid + % endif + that.phoneNumberEntry = response.data.phone_number + that.contactProfileURL = response.data.contact_profile_url + }) }, - phoneNumberChanged(value) { - this.phoneNumberSaved = false - }, + // phoneNumberChanged(value) { + // this.phoneNumberSaved = false + // }, - phoneNumberKeyDown(event) { - if (event.which == 13) { // Enter - this.setCustomerData() - } - }, + // phoneNumberKeyDown(event) { + // if (event.which == 13) { // Enter + // this.setContactData() + // } + // }, showAddItemDialog() { this.editingItem = null diff --git a/tailbone/views/custorders/orders.py b/tailbone/views/custorders/orders.py index 36414a89..4bab7740 100644 --- a/tailbone/views/custorders/orders.py +++ b/tailbone/views/custorders/orders.py @@ -227,8 +227,10 @@ class CustomerOrderView(MasterView): data = dict(self.request.json_body) action = data.get('action') json_actions = [ + 'assign_contact', + 'unassign_contact', 'get_customer_info', - 'set_customer_data', + # 'set_customer_data', 'find_product_by_upc', 'get_product_info', 'add_item', @@ -251,8 +253,17 @@ class CustomerOrderView(MasterView): context = {'batch': batch, 'normalized_batch': self.normalize_batch(batch), + 'new_order_requires_customer': self.handler.new_order_requires_customer(), + 'contact_profile_url': None, 'order_items': items, 'product_autocomplete_url': self.request.route_url(product_autocomplete)} + + # maybe add profile URL + if batch.person_uuid: + if self.request.has_perm('people.view_profile'): + context['contact_profile_url'] = self.request.route_url( + 'people.view_profile', uuid=batch.person_uuid) + return self.render_to_response(template, context) def get_current_batch(self): @@ -307,13 +318,22 @@ class CustomerOrderView(MasterView): def customer_autocomplete(self): """ - Custom customer autocomplete logic, which invokes the handler. + Customer autocomplete logic, which invokes the handler. """ self.handler = self.get_batch_handler() term = self.request.GET['term'] return self.handler.customer_autocomplete(self.Session(), term, user=self.request.user) + def person_autocomplete(self): + """ + Person autocomplete logic, which invokes the handler. + """ + self.handler = self.get_batch_handler() + term = self.request.GET['term'] + return self.handler.person_autocomplete(self.Session(), term, + user=self.request.user) + def get_customer_info(self, batch, data): uuid = data.get('uuid') if not uuid: @@ -326,30 +346,90 @@ class CustomerOrderView(MasterView): return self.info_for_customer(batch, data, customer) def info_for_customer(self, batch, data, customer): - phone = customer.first_phone() - email = customer.first_email() - return { - 'uuid': customer.uuid, - 'phone_number': phone.number if phone else None, - 'email_address': email.address if email else None, + + # most info comes from handler + info = self.handler.get_customer_info(batch) + + # maybe add profile URL + if info['person_uuid']: + if self.request.has_perm('people.view_profile'): + info['contact_profile_url'] = self.request.route_url( + 'people.view_profile', uuid=info['person_uuid']), + + return info + + def assign_contact(self, batch, data): + kwargs = {} + + # this will either be a Person or Customer UUID + uuid = data['uuid'] + + if self.handler.new_order_requires_customer(): + + customer = self.Session.query(model.Customer).get(uuid) + if not customer: + return {'error': "Customer not found"} + kwargs['customer'] = customer + + else: + + person = self.Session.query(model.Person).get(uuid) + if not person: + return {'error': "Person not found"} + kwargs['person'] = person + + # invoke handler to assign contact + try: + self.handler.assign_contact(batch, **kwargs) + except ValueError as error: + return {'error': six.text_type(error)} + + context = { + 'success': True, + 'customer_uuid': batch.customer_uuid, + 'person_uuid': batch.person_uuid, + 'phone_number': batch.phone_number, + 'email_address': batch.email_address, } - def set_customer_data(self, batch, data): - if 'customer_uuid' in data: - batch.customer_uuid = data['customer_uuid'] - if 'person_uuid' in data: - batch.person_uuid = data['person_uuid'] - elif batch.customer_uuid: - self.Session.flush() - batch.person = batch.customer.first_person() - else: # no customer set - batch.person_uuid = None - if 'phone_number' in data: - batch.phone_number = data['phone_number'] - if 'email_address' in data: - batch.email_address = data['email_address'] - self.Session.flush() - return {'success': True} + # maybe add profile URL + if batch.person_uuid: + if self.request.has_perm('people.view_profile'): + context['contact_profile_url'] = self.request.route_url( + 'people.view_profile', uuid=batch.person_uuid) + + return context + + def unassign_contact(self, batch, data): + self.handler.unassign_contact(batch) + + context = { + 'success': True, + 'customer_uuid': batch.customer_uuid, + 'person_uuid': batch.person_uuid, + 'phone_number': batch.phone_number, + 'email_address': batch.email_address, + 'contact_profile_url': None, + } + + return context + + # def set_customer_data(self, batch, data): + # if 'customer_uuid' in data: + # batch.customer_uuid = data['customer_uuid'] + # if 'person_uuid' in data: + # batch.person_uuid = data['person_uuid'] + # elif batch.customer_uuid: + # self.Session.flush() + # batch.person = batch.customer.first_person() + # else: # no customer set + # batch.person_uuid = None + # if 'phone_number' in data: + # batch.phone_number = data['phone_number'] + # if 'email_address' in data: + # batch.email_address = data['email_address'] + # self.Session.flush() + # return {'success': True} def product_autocomplete(self): """ @@ -601,6 +681,15 @@ class CustomerOrderView(MasterView): route_prefix = cls.get_route_prefix() url_prefix = cls.get_url_prefix() + # person autocomplete + config.add_route('{}.person_autocomplete'.format(route_prefix), + '{}/person-autocomplete'.format(url_prefix), + request_method='GET') + config.add_view(cls, attr='person_autocomplete', + route_name='{}.person_autocomplete'.format(route_prefix), + renderer='json', + permission='people.list') + # customer autocomplete config.add_route('{}.customer_autocomplete'.format(route_prefix), '{}/customer-autocomplete'.format(url_prefix),