Overhaul new custorder so contact may be either Person or Customer
also make the handler responsible for (un)assigning contact
This commit is contained in:
parent
12310da09e
commit
a52b5ec380
|
@ -101,50 +101,63 @@
|
|||
|
||||
<br />
|
||||
<div class="field">
|
||||
<b-radio v-model="customerIsKnown"
|
||||
<b-radio v-model="contactIsKnown"
|
||||
:native-value="true">
|
||||
Customer is already in the system.
|
||||
</b-radio>
|
||||
</div>
|
||||
|
||||
<div v-show="customerIsKnown">
|
||||
<div v-show="contactIsKnown">
|
||||
<b-field label="Customer" horizontal>
|
||||
<tailbone-autocomplete ref="customerAutocomplete"
|
||||
v-model="customerUUID"
|
||||
<tailbone-autocomplete ref="contactAutocomplete"
|
||||
v-model="contactUUID"
|
||||
placeholder="Enter name or phone number"
|
||||
:initial-label="customerDisplay"
|
||||
:initial-label="contactDisplay"
|
||||
% if new_order_requires_customer:
|
||||
serviceUrl="${url('{}.customer_autocomplete'.format(route_prefix))}"
|
||||
@input="customerChanged">
|
||||
% else:
|
||||
serviceUrl="${url('{}.person_autocomplete'.format(route_prefix))}"
|
||||
% endif
|
||||
@input="contactChanged">
|
||||
</tailbone-autocomplete>
|
||||
<b-button v-if="contactUUID && contactProfileURL"
|
||||
type="is-primary"
|
||||
tag="a" target="_blank"
|
||||
:href="contactProfileURL"
|
||||
icon-pack="fas"
|
||||
icon-left="external-link-alt">
|
||||
View Profile
|
||||
</b-button>
|
||||
</b-field>
|
||||
<b-field label="Phone Number" horizontal
|
||||
v-show="customerUUID">
|
||||
<b-input v-model="phoneNumberEntry"
|
||||
@input="phoneNumberChanged"
|
||||
@keydown.native="phoneNumberKeyDown">
|
||||
</b-input>
|
||||
<b-button v-if="!phoneNumberSaved"
|
||||
type="is-primary"
|
||||
icon-pack="fas"
|
||||
icon-left="fas fa-save"
|
||||
@click="setCustomerData()">
|
||||
Please save when finished editing
|
||||
</b-button>
|
||||
<!-- <tailbone-autocomplete -->
|
||||
<!-- serviceUrl="${url('customers.autocomplete.phone')}"> -->
|
||||
<!-- </tailbone-autocomplete> -->
|
||||
v-show="contactUUID">
|
||||
{{ phoneNumberEntry }}
|
||||
## <b-input v-model="phoneNumberEntry"
|
||||
## @input="phoneNumberChanged"
|
||||
## @keydown.native="phoneNumberKeyDown">
|
||||
## </b-input>
|
||||
## <b-button v-if="!phoneNumberSaved"
|
||||
## type="is-primary"
|
||||
## icon-pack="fas"
|
||||
## icon-left="fas fa-save"
|
||||
## @click="setContactData()">
|
||||
## Please save when finished editing
|
||||
## </b-button>
|
||||
## <!-- <tailbone-autocomplete -->
|
||||
## <!-- serviceUrl="${url('customers.autocomplete.phone')}"> -->
|
||||
## <!-- </tailbone-autocomplete> -->
|
||||
</b-field>
|
||||
</div>
|
||||
|
||||
<br />
|
||||
<div class="field">
|
||||
<b-radio v-model="customerIsKnown" disabled
|
||||
<b-radio v-model="contactIsKnown" disabled
|
||||
:native-value="false">
|
||||
Customer is not yet in the system.
|
||||
</b-radio>
|
||||
</div>
|
||||
|
||||
<div v-if="!customerIsKnown">
|
||||
<div v-if="!contactIsKnown">
|
||||
<b-field label="Customer Name" horizontal>
|
||||
<b-input v-model="customerName"></b-input>
|
||||
</b-field>
|
||||
|
@ -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
|
||||
|
|
|
@ -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),
|
||||
|
|
Loading…
Reference in a new issue