def update_customer(uid): data = request.json if data is None: abort(400, description=gettext('invalid json request')) # do not allow to update customer id and status directly Customer.filter_not_updatable_fields(data) customer = get_customer(uid) # validate mobile. The logic is duplicated with validate method of Customer. Merge the logic later. if data.get('mobile', None) and '000' != data['mobile'] and validate_mobile( data['mobile']): existing_cust_with_same_mobile = Customer.find_by_mobile_exclude( customer.store_id, data['mobile'], customer.id) existing_cust_with_same_mobile = handle_no_rx_customer( existing_cust_with_same_mobile) if existing_cust_with_same_mobile: if customer.sales_id == existing_cust_with_same_mobile.sales_id: raise DuplicatedCustomerException( gettext(u'The mobile is the same as customer %(name)s', name=existing_cust_with_same_mobile.respect_name), existing_customer_id=existing_cust_with_same_mobile.id) else: raise NoPermissionOnCustomerException( existing_cust_with_same_mobile, gettext(u'The mobile belongs to other sales\' customer')) is_defeated = Customer.is_defeated(data) if not is_defeated: # validate required fields if client ask for it. if customer.status != 'draft': data['required_validation'] = True if not validate_required_fields(data): raise EmptyRequiredFields( gettext(u'Please fill all required fields')) create_or_update_addl_info(customer, data) for key, value in data.iteritems(): if hasattr(customer, key): try: setattr(customer, key, value) except: # ignore the errors here pass if not is_defeated: customer.formal() from application.models.hwaccount import HwjdAccount if customer.store_id in HwjdAccount.find_active_hwjd_store_ids(): last_rx = Reception.find_last_rx_by_customer_id(customer.id) if last_rx: from application.queue import async_call async_call("sync_hwjd_customer_rx", [last_rx.id]) else: customer.defeated('NA') return customer
def create_customer(sales_id): sales = User.get_user_by_id_from_cache(sales_id) if sales is None: abort(400, description=gettext( u'Incorrect sales, cannot find sales with id %(id)'), id=sales_id) data = request.json customer = None if data.get('mobile', None): customer = Customer.find_by_mobile(sales.store_id, data['mobile']) from application.api.viewhelper import handle_no_rx_customer customer = handle_no_rx_customer(customer) if customer: if customer.sales_id != sales.id: raise NoPermissionOnCustomerException( customer, gettext(u'The mobile belongs to other sales\' customer')) else: raise DuplicatedCustomerException(gettext( u'The mobile is the same as customer %(name)s', name=customer.respect_name), existing_customer_id=customer.id) else: customer = Customer(**data) customer.store_id = sales.store_id customer.sales_id = sales.id customer.reset_status() customer.save_and_flush() return customer, 201, add_location_header( dict(), url_for('api.get_customer', uid=customer.id))
def create_calllog(customer_id): customer = Customer.find(customer_id) if customer is None: abort(400, description=gettext(u'Customer with id %(id) not found', id=customer)) data = request.json data.pop('id', None) data.pop('created_on', None) data.pop('updated_on', None) sequence_id = data.get('sequence_id', None) call_log = None if sequence_id: call_log = Calllog.find_by_sequence_id(sequence_id) if not call_log: call_log = Calllog(**data) call_log.customer_id = customer_id call_log.store_id = customer.store_id call_log.save_and_flush() return call_log
def create_order(): data = request.json if data is None: abort(400, description=gettext('invalid json request')) validate_amounts_fields_in_orders(data) order = Order(**data) order.generate_order_no() order.save_and_flush() customer = Customer.find(order.customer_id) customer.status = 'ordered' Appointment.cancel_all_for_sales_customer( order.sales_id, order.customer_id, 'Order: ' + str(order.id) + ' is created') Reception.complete_all_for_sales_customer( order.sales_id, order.customer_id, 'Order: ' + str(order.id) + ' is created') return Order.find(order.id), 201, add_location_header( dict(), url_for('api.get_order', uid=order.id))
def get_customer(uid): result = Customer.find_with_addl(uid) if result is None: abort(404, description=gettext(u'customer with id %(id)s is not found', id=uid)) return result
def sync_customers_of_sales(sales_id): last_sync_date = request.args.get('last_sync_date', None) try: last_sync_date = datetime.datetime.fromtimestamp(int(last_sync_date)) except: last_sync_date = None bulk_size = parse_int(request.args.get('bulk_size', None), 100) return Customer.find_all_by_sales_before_sync_in_bulk( sales_id, last_sync_date, bulk_size)
def search_customer(cid): mobile = request.json.get('mobile', None) if mobile: customer = Customer.find_by_mobile_with_sales_in_store(mobile, cid) return customer else: abort(400, description=gettext(u'Customer with mobile %(mobile)s not found', mobile=mobile)) abort(400, description=gettext(u'Mobile is empty'))
def accept_reassign_customer(sid, cid): customer = Customer.find(cid) if customer is None or customer.sales_id != sid: abort( 400, description=gettext( u'customer with id %(id)s is not found or not belongs to sales %(sid)s', id=cid, sid=sid)) customer.reassigned = 0 return customer
def update_reception(uid): original_reception = get_reception(uid) data = request.json # only support update sales assignment for now if data is None or data.get('sales_id', None) is None: abort(400, description=gettext('invalid json request')) new_assigned_sales = User.find(data['sales_id']) if new_assigned_sales is None: abort(400, description=gettext('salespeople with id %(id)s is not found', id=data['sales_id'])) # cancel original reception original_reception.status = 'cancelled' # update customer associate sales if the reception is not created from an appointment and customer is created today. new_customer = None if (not original_reception.appointment_id) \ and original_reception.customer.created_on.date() == datetime.today().date(): # create new customer from old one new_customer_dict = obj_to_dict(original_reception.customer) new_customer_dict.pop('id') new_customer_dict.pop('last_reception_date') new_customer_dict.pop('next_appointment_date') new_customer_dict['sales_id'] = data['sales_id'] new_customer = Customer(**new_customer_dict) # cancel original customer original_reception.customer.status = 'cancelled' original_reception.save_and_flush() reception_cancelled.send(reception=original_reception) # create new reception new_reception_dict = obj_to_dict(original_reception) new_reception_dict.pop('id') new_reception_dict.pop('status') if new_customer: new_reception_dict.pop('customer_id') new_reception_dict['customer'] = new_customer new_reception_dict.pop('sales') new_reception_dict['sales_id'] = new_assigned_sales.id new_reception = Reception(**new_reception_dict) new_reception.prev_rx_id = original_reception.id new_reception.created_on = datetime.now() new_reception.customer.last_reception_date = new_reception.created_on new_reception.save_and_flush() new_reception_created.send(new_reception=new_reception) return new_reception
def customers(): current_user = g.user store_id = get_or_set_store_id() from application.forms.customer import CustomerSearchForm search_form = CustomerSearchForm(request.args) search_form.intent_level_filter.choices = get_intent_level_selection( store_id) search_form.intent_car_ids_filter.choices = get_intent_car_ids_selection( store_id) search_form.last_instore_filter.choices = get_last_instore_selection( store_id) search_form.status_filter.choices = get_status_selection() search_form.sales_filter.choices = get_sales_selection(store_id) # build query query = dict() if search_form.intent_level_filter.data not in ('None', 'all'): query['intent_level'] = search_form.intent_level_filter.data if search_form.intent_car_ids_filter.data not in ('None', 'all'): query['intent_car_ids'] = search_form.intent_car_ids_filter.data if search_form.last_instore_filter.data not in ('None', 'all'): query['last_instore'] = search_form.last_instore_filter.data if search_form.status_filter.data not in ('None', 'all'): query['status'] = search_form.status_filter.data if search_form.keywords.data: query['keywords'] = search_form.keywords.data if search_form.sales_filter.data not in ('None', 'all'): query['sales_id'] = search_form.sales_filter.data if not current_user.has_role_in_current_store(USER_ROLE_STORE_MANAGER): query.pop('sales_id', None) # TODO: scope = current_user.getDataScope('customer', store_id) if scope: scope.pop('store_id', None) query.update(scope) sort_params = SortMixin.get_order_query(search_form) if sort_params: query.update(sort_params) query.update(get_page_info(request)) customers_list = Customer.find_all_with_last_appt_by_query_params_in_store( store_id, **query) return render_template('customers/customers.html', selected_menu=CUSTOMER_MGMT, form=search_form, customers=customers_list, back_endpoint=request.args.get( 'back_endpoint', None))
def assign_customer(cid): customer = Customer.find(cid) if customer is None: abort(400, description=gettext(u'customer with id %(id)s is not found', id=cid)) new_sales_id = request.json.get('sales_id') if new_sales_id is None: abort(400, description=gettext(u'new sales id is empty')) customer.reassign(new_sales_id) return customer
def view_details(cid): current_user = g.user store_id = get_or_set_store_id() customer = Customer.find_by_id_and_store(cid, store_id) if not customer: abort(404) orders = Order.find_all_by_customer_sales(customer.id) appts = Appointment.find_all_by_customer_sales(customer.id) receptions = Reception.find_all_by_customer_sales(customer.id) calllogs = Calllog.find_all_by_customer_id(customer.id) form = CustomerReassignForm() form.saleses_list.choices = get_sales_selection(store_id) if current_user.is_receptionist() or ( current_user.is_sales() and current_user.is_role_in_store_id(store_id, 'manager') == False and customer.sales_id != current_user.id): abort(401) if request.method == 'GET': form.saleses_list.data = customer.sales_id if request.method == 'POST' and ( form.saleses_list.data not in ('None', customer.sales_id) and current_user.is_role_in_store_id(store_id, 'manager')): customer.reassign(int(form.saleses_list.data)) customer.save_and_flush() flash_success(u'重新分配成功') return redirect(url_for('customers.view_details', cid=cid, back_url=back_url( url_for('customers.customers'))), code=303) return render_template('customers/detail.html', selected_menu=CUSTOMER_MGMT, customer=customer, orders=orders, appts=appts, receptions=receptions, calllogs=calllogs, form=form, back_url=back_url(url_for('customers.customers')))
def bulk_assign_store_customers(store_id): # currently only support bulk reassign defeated customers by last reception date new_sales_id = request.json.get('sales_id') if new_sales_id is None: abort(400, description=gettext(u'new sales id is empty')) rx_date_from = request.json.get('rx_date_from') rx_date_to = request.json.get('rx_date_to') if not rx_date_from or not rx_date_to: abort(400, description=u"rx_date_from or rx_date_to can't be empty") customers = Customer.find_all_defeated_in_store_by_last_reception_date( store_id, rx_date_from, rx_date_to) for customer in customers: customer.reassign(new_sales_id) return customers
def search_sales_customer(sales_id): sales = User.get_user_by_id_from_cache(sales_id) data = request.json mobile = data.get('mobile', None) if mobile: customer = Customer.find_by_mobile(sales.store_id, mobile) if customer: if customer.sales_id == sales.id: return customer else: raise NoPermissionOnCustomerException( customer, gettext(u'The mobile belongs to other sales\' customer')) else: abort(400, description=gettext( u'Customer with mobile %(mobile)s not found', mobile=mobile)) else: abort(400, description=gettext(u'Mobile is empty'))
def transfer_sales_customers(from_sales_id, to_sales_id): passcode = request.args.get('passcode', None) status = request.args.getlist('status') if not passcode or not valid_passcode(passcode): abort(401) from_sales = User.find(from_sales_id) if not from_sales or from_sales.is_active(): abort(400, description=gettext(u'sales with id (%id)s is not found', id=from_sales_id)) to_sales = User.find(to_sales_id) if not to_sales: abort(400, description=gettext(u'sales with id (%id)s is not found', id=to_sales_id)) Appointment.cancel_all_for_sales(from_sales_id, u'重新分配客户') processed_count = Customer.reassign_all_of_sales_to_sales(from_sales_id, to_sales_id, status) return {'from_sales_id': from_sales_id, 'to_sales_id': to_sales_id, 'processed_count': processed_count}
def merge_stores(from_store_id, to_store_id): passcode = request.args.get('passcode', None) if not passcode or not valid_passcode(passcode): abort(401) result = dict() result['receptions'] = Reception.migrate_store(from_store_id, to_store_id) result['customers'] = Customer.migrate_store(from_store_id, to_store_id) result['appointments'] = Appointment.migrate_store(from_store_id, to_store_id) from application.models.order import Order result['orders'] = Order.migrate_store(from_store_id, to_store_id) from application.models.calllog import Calllog result['calllogs'] = Calllog.migrate_store(from_store_id, to_store_id) from application.models.campaign import Campaign result['campaigns'] = Campaign.migrate_store(from_store_id, to_store_id) from application.models.driverecord import DriveRecord result['driverecords'] = DriveRecord.migrate_store(from_store_id, to_store_id) return result
def populate_customer_from_request(data, store_id, user_id): from application.models.customer import Customer customer_id = extract_customer_id(data) customer_data = data.get('customer') customer = None if not customer_id and not customer_data: abort(400, description=gettext( 'either customer_id or customer has to be provided')) elif customer_id: customer = Customer.find(customer_id) if not customer: abort(400, description=gettext('customer with id %(id)s is not found', id=data['customer_id'])) elif unicode(customer.sales_id) != unicode(user_id) and data.get( 'force', None) != 'force': raise NoPermissionOnCustomerException( customer, gettext( u'the customer %(name)s you are operating does not belong to you. Please contact your sales manager', name=customer.name)) else: if customer_data.get('mobile', None): customer = Customer.find_by_mobile(store_id, customer_data['mobile']) customer = handle_no_rx_customer(customer) if customer and unicode( customer.sales_id) != unicode(user_id) and data.get( 'force', None) != 'force': raise NoPermissionOnCustomerException( customer, gettext( u'the customer %(name)s you are operating does not belong to you. Please contact your sales manager', name=customer.name)) if not customer: customer = Customer(**customer_data) customer.store_id = store_id customer.sales_id = user_id data['customer'] = customer return data
def cleanup_today_invalid_receptions(): """ Find id in user which username is invalid reception Set status is cancelled which in reception and customer """ users = User.find_all_by_sales_name(INSTORE_NO_RX_LEAD) cancelled_rx_count = 0 cancelled_cus_count = 0 invalid_cancelled = {} if len(users) != 0: for invalid_user in users: sales_id = invalid_user.id cancelled_rx_count += Reception.cancel_receptions_by_sales_id( sales_id) cancelled_cus_count += Customer.cancel_not_filed_customers_by_sales_id( sales_id) invalid_cancelled['cancelled_rx_count'] = cancelled_rx_count invalid_cancelled['cancelled_cus_count'] = cancelled_cus_count return invalid_cancelled
def get_customers_of_sales(sales_id): return Customer.find_all_by_sales(sales_id, **get_page_info(request))
def get_tbu_customers_of_sales(sales_id): return Customer.find_all_in_tbu_by_sales(sales_id)
def get_all_store_customers(sid): status = request.args.get('status', None) return Customer.find_all_by_store_in_status(sid, status, **get_page_info(request))