コード例 #1
0
ファイル: customer_api.py プロジェクト: sungitly/isr
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
コード例 #2
0
ファイル: customer_api.py プロジェクト: sungitly/isr
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))
コード例 #3
0
ファイル: customer_api.py プロジェクト: sungitly/isr
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
コード例 #4
0
ファイル: order_api.py プロジェクト: sungitly/isr
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))
コード例 #5
0
ファイル: customer_api.py プロジェクト: sungitly/isr
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
コード例 #6
0
ファイル: customer_api.py プロジェクト: sungitly/isr
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)
コード例 #7
0
ファイル: customer_api.py プロジェクト: sungitly/isr
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'))
コード例 #8
0
ファイル: customer_api.py プロジェクト: sungitly/isr
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
コード例 #9
0
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
コード例 #10
0
ファイル: customer.py プロジェクト: sungitly/isr
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))
コード例 #11
0
ファイル: customer_api.py プロジェクト: sungitly/isr
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
コード例 #12
0
ファイル: customer.py プロジェクト: sungitly/isr
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')))
コード例 #13
0
ファイル: customer_api.py プロジェクト: sungitly/isr
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
コード例 #14
0
ファイル: customer_api.py プロジェクト: sungitly/isr
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'))
コード例 #15
0
ファイル: sales_api.py プロジェクト: sungitly/isr
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}
コード例 #16
0
ファイル: sales_api.py プロジェクト: sungitly/isr
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
コード例 #17
0
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
コード例 #18
0
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
コード例 #19
0
ファイル: customer_api.py プロジェクト: sungitly/isr
def get_customers_of_sales(sales_id):
    return Customer.find_all_by_sales(sales_id, **get_page_info(request))
コード例 #20
0
ファイル: customer_api.py プロジェクト: sungitly/isr
def get_tbu_customers_of_sales(sales_id):
    return Customer.find_all_in_tbu_by_sales(sales_id)
コード例 #21
0
ファイル: customer_api.py プロジェクト: sungitly/isr
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))