示例#1
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))
示例#2
0
    def defeated(self, reason=''):
        self.status = 'defeated'
        self.intent_level = '-100'
        self.defeated_reason = reason

        # cancel all active appointments and receptions
        from application.models.appointment import Appointment
        from application.models.reception import Reception
        Appointment.cancel_all_for_sales_customer(self.sales_id, self.id, self.status + ': ' + reason)
        Reception.complete_all_for_sales_customer(self.sales_id, self.id, self.status + ': ' + reason)
示例#3
0
def cancel_customer(cid):
    replaced_by_customer_id = request.json.get('by_customer_id')

    customer = get_customer(cid)
    customer.status = 'cancelled'
    customer.save_and_flush()

    replaced_by_customer = get_customer(replaced_by_customer_id)

    Appointment.reset_customer_id(customer, replaced_by_customer)
    Reception.reset_customer_id(customer, replaced_by_customer)
    Order.reset_customer_id(customer, replaced_by_customer)

    return replaced_by_customer
示例#4
0
文件: stats.py 项目: sungitly/isr
def count_rr_rx(start, end, store_id):
    result = []
    refered_customers_rx_ids = Reception.count_all_refered_between_dates_in_store(
        start, end, store_id)

    if len(refered_customers_rx_ids) > 0:
        result.extend(refered_customers_rx_ids)

    reorder_customers_rx_ids = Reception.count_all_reorder_between_dates_in_store(
        start, end, store_id)

    if len(reorder_customers_rx_ids) > 0:
        result.extend(reorder_customers_rx_ids)

    return len(set(result))
示例#5
0
    def validate(self, appt_data):
        now_time = datetime.now()
        appt_type = appt_data.get('type', None)
        appt_time = parse(appt_data.get('appt_datetime'))
        store_id = appt_data.get('store_id')
        if appt_type and appt_type == 'followup':
            customer = appt_data.get('customer', None)
            if customer and customer.is_active():
                # 1. 未成交客户, 预约回访时间不得晚于当前时间+7天
                general_time_limit = now_time + timedelta(days=7)
                if appt_time > general_time_limit:
                    abort(
                        400,
                        description=gettext(
                            'appt_datetime can not be later than %(days)s days',
                            days=7))

                # 2. 如果客户是首次客户, 首次预约回访时间不得晚于到店第二天晚上24时
                receptions = Reception.find_all_by_customer_sales(customer.id)
                if receptions and len(receptions) == 1:
                    last_rx_date = receptions[0].rx_date
                    rx_limit = last_rx_date + timedelta(days=1)
                    if not Appointment.exist_followup_between_dates_by_customer(parse_date(now_time), parse_date(
                            rx_limit), customer.id, store_id) and parse_date(now_time) <= parse_date(rx_limit) \
                            < parse_date(appt_time):
                        abort(
                            400,
                            description=gettext(
                                'appt_datetime can not be later than 1 days for new customer'
                            ))
示例#6
0
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
示例#7
0
文件: user.py 项目: sungitly/isr
def morning_call():
    current_user = g.user
    store_id = get_or_set_store_id()

    today = datetime.date.today()
    yesterday = today - datetime.timedelta(days=1)
    orders_stats = dict()
    orders_stats['yesterday_orders_count'] = Order.count_orders_by_date_and_store(yesterday, store_id)
    orders_stats['current_month_orders_count'] = Order.count_orders_from_date_and_store(
        datetime.date.today().replace(day=1),
        store_id)
    current_month_ta = TaSetting.find_active_monthly_ta(today.year, today.month, store_id)
    orders_stats['current_month_target'] = current_month_ta.value if current_month_ta else 'N/A'

    sales_stats = User.get_all_sales_by_store_from_cache(long(store_id))
    yesterday_receptions = Reception.find_all_by_date_in_store(yesterday, store_id)
    today_appointments = Appointment.find_all_by_date_in_store(datetime.date.today(), store_id)

    rx_stats = dict()
    rx_stats['yesterday_incomplete_count'] = len(
        [x for x in yesterday_receptions if x._last_status_changer == 'system'])

    total_counts, sales_counts = calc_reception_counts(yesterday_receptions, sales_stats)

    for sale in sales_stats:
        sale.rx_count = sales_counts.get(sale.id, {'total': 0, 'new': 0, 'appt_new': 0, 'appt': 0, 'other': 0})

        populate_appt_count_agg_by_sale_and_type(today_appointments, sale)

    sales_stats.sort(key=lambda sale: sale.rx_count, reverse=True)

    appts_count = generate_appt_count_agg_by_type(today_appointments)
    recent_campaigns = Campaign.find_all_by_store_in_recent_days(store_id, 15)

    current_endpoint = 'user.morning_call'
    now = datetime.datetime.now()
    yesterday_datetime = now - datetime.timedelta(days=1)
    rx_base_url, rx_url_params = get_filter_link('receptions.receptions', yesterday_datetime, yesterday_datetime,
                                                 current_endpoint)
    rx_incomplete_params = rx_url_params.copy()
    rx_incomplete_params['incomplete'] = 'y'

    appt_base_url, appt_url_params = get_filter_link('appointments.appts', now, now, current_endpoint)

    order_base_url, order_url_params = get_filter_link('orders.orders', yesterday_datetime, yesterday_datetime,
                                                       current_endpoint)
    monthly_order_url_params = order_url_params.copy()
    monthly_order_url_params['start_date'] = datetime.date.today().replace(day=1).strftime(DATE_FORMAT)
    monthly_order_url_params['end_date'] = now.strftime(DATE_FORMAT)

    return render_template('user/salesmanager/morningcall.html', selected_menu=USER_MORNING_CALL,
                           orders_stats=orders_stats, sales_stats=sales_stats, appts_count=appts_count,
                           total_rx_count=total_counts, recent_campaigns=recent_campaigns,
                           recent_campaigns_count=len(recent_campaigns), current_month_ta=current_month_ta,
                           rx_base_url=rx_base_url, rx_url_params=rx_url_params, appt_base_url=appt_base_url,
                           appt_url_params=appt_url_params, rx_incomplete_params=rx_incomplete_params,
                           order_base_url=order_base_url, order_url_params=order_url_params,
                           monthly_order_url_params=monthly_order_url_params, rx_stats=rx_stats,
                           back_endpoint=request.args.get('back_endpoint', None))
示例#8
0
def get_reception(uid):
    result = Reception.find(uid)

    if result is None:
        abort(404,
              description=gettext(u'reception with id %(id)s is not found',
                                  id=uid))
    return result
示例#9
0
    def update_sales_status(store_id, sales_id, status=None):
        old_status = SalesStatus.get_sales_status(store_id, sales_id)

        if status is None and old_status == 'leave':
            return

        if status is None:
            if Reception.exist_sales_incomplete_receptions_of_today(sales_id):
                status = 'busy'
            else:
                status = 'free'

        SalesStatus.set_sales_status(store_id, sales_id, status)
示例#10
0
文件: sales_api.py 项目: sungitly/isr
def update_sales_status(sales_id):
    status = request.json.get('name')
    sales = User.find(sales_id)

    if not sales:
        abort(400, description=gettext(u'sales with id (%id)s is not found', id=sales_id))

    if status == 'free' and Reception.exist_sales_incomplete_receptions_of_today(sales_id):
        raise InvalidSalesStatusTransitionException(
            gettext(u'sales %(name)s can not be free because there is incomplete receptions', name=sales.username))
    else:
        SalesStatus.set_sales_status(sales.store_id, sales.id, status)
        return {sales_id: status}
示例#11
0
def cleanup_today_receptions():
    """
    Could be scheduled every morning 7:00 AM.
    Complete un-completed receptions today.
    :return:
    """
    store_id = request.args.get('store_id', None)
    process_date = parse_date(request.args.get('process_date', None),
                              default=datetime.date.today())
    reason = 'Daily Cleanup'
    receptions_cleanup = {}

    if store_id:
        receptions = Reception.complete_all_of_date_for_store(
            store_id, process_date, reason, 'system')
    else:
        receptions = Reception.complete_all_of_today(process_date, reason,
                                                     'system')

    receptions_cleanup['store_id'] = store_id
    receptions_cleanup['process_date'] = process_date
    receptions_cleanup['processed_count'] = len(receptions)

    return receptions_cleanup
示例#12
0
    def reset_all_sales_status(store_id):
        existing_sales_status = SalesStatus.get_all_sales_status(store_id)
        incomplete_rx_count_by_sales = Reception.count_all_incomplete_of_today_by_sales(
            store_id)
        new_sales_status = {
            str(r[0]): 'busy' if r[1] > 0 else 'free'
            for r in incomplete_rx_count_by_sales
        }

        for sales_id, sales_status in existing_sales_status.iteritems():
            if sales_status != 'leave':
                existing_sales_status[sales_id] = new_sales_status.get(
                    sales_id, 'free')
        SalesStatus.set_sales_status_from_mapping(store_id,
                                                  existing_sales_status)
示例#13
0
文件: stats.py 项目: sungitly/isr
def get_unordered_customers_count_by_intent_level(start, end, store_id):
    uoc_stats = Reception.get_unordered_customers_count_by_intent_level_between_dates_in_store(
        start, end, store_id)

    uoc_stats = {s[1]: s[0] for s in uoc_stats}

    intent_levels_dict = LookupValue.find_all_in_dict_by_lookup_name_of_store_from_cache(
        long(store_id), 'intent-level')

    result = []
    for code, value in intent_levels_dict.iteritems():
        stats = uoc_stats.get(code, 0)
        if stats != 0:
            result.append((value.value, stats))

    return result
示例#14
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')))
示例#15
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
示例#16
0
文件: stats.py 项目: sungitly/isr
def get_rx_customers_count_by_car_models(start, end, store_id):
    rx_customers_by_car = Reception.get_rx_customers_count_by_car_models_bwteeen_dates_in_stores(
        start, end, store_id)

    intent_cars_dict = LookupValue.find_all_in_dict_by_lookup_name_of_store_from_cache(
        long(store_id), 'intent-car')

    result = dict()
    for code, value in intent_cars_dict.iteritems():
        count = 0
        for stats in rx_customers_by_car:
            # need to calc count again since there would be multiple intent cars seperated by comma.
            if code in stats[1]:
                count += stats[0]

        if count > 0:
            result[code] = count
    return result
示例#17
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
示例#18
0
文件: lead.py 项目: sungitly/isr
def leads():
    current_user = g.user
    store_id = current_user.store_id

    from application.forms.lead import LeadSearchForm
    search_form = LeadSearchForm(request.args)

    query = dict()
    if search_form.start_date.data and search_form.start_date.data != '':
        query['start_date'] = search_form.start_date.data
    if search_form.end_date.data and search_form.end_date.data != '':
        query['end_date'] = search_form.end_date.data
    if search_form.on_file.data:
        query['on_file'] = search_form.on_file.data

    query.update(get_page_info(request))

    rx = Reception.find_all_leads_by_query_params_in_store(store_id, **query)

    return render_template('leads/leads.html', selected_menu=LEADS_VIEW, form=search_form,
                           leads=rx, back_endpoint=request.args.get('back_endpoint', None),
                           today=datetime.date.today())
示例#19
0
文件: reception.py 项目: sungitly/isr
def receptions():
    current_user = g.user
    store_id = get_or_set_store_id()

    from application.forms.reception import RxSearchForm
    search_form = RxSearchForm(request.args)
    search_form.type_filter.choices = get_type_selection()
    search_form.sales_filter.choices = get_sales_selection(store_id)
    search_form.status_filter.choices = get_status_selection()

    query = dict()
    if search_form.start_date.data and search_form.start_date.data != '':
        query['start_date'] = search_form.start_date.data
    if search_form.end_date.data and search_form.end_date.data != '':
        query['end_date'] = search_form.end_date.data
    if search_form.type_filter.data and search_form.type_filter.data not in (
            'None', 'all'):
        query['type_filter'] = search_form.type_filter.data
    if search_form.sales_filter.data not in ('None', 'all'):
        query['sales_filter'] = search_form.sales_filter.data
    if search_form.incomplete.data:
        query['incomplete'] = search_form.incomplete.data
    if search_form.status_filter.data not in ('None', 'all'):
        query['status'] = search_form.status_filter.data

    sort_params = SortMixin.get_order_query(search_form)
    if sort_params:
        query.update(sort_params)
    query.update(get_page_info(request))

    receptions = Reception.find_all_by_query_params_in_store(store_id, **query)
    return render_template('receptions/receptions.html',
                           selected_menu=RX_VIEW,
                           form=search_form,
                           receptions=receptions,
                           back_endpoint=request.args.get(
                               'back_endpoint', None),
                           today=datetime.date.today())
示例#20
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
示例#21
0
文件: hwjd.py 项目: sungitly/isr
def sync_hwjd_customer_rx_by_date(store_id, date_str):
    receptions = Reception.find_all_by_date_in_store(date_str, store_id)

    for rx in receptions:
        sync_rx_with_hwjd_oa(rx)
示例#22
0
文件: mmgmt.py 项目: sungitly/isr
def stats_summary():
    now = datetime.datetime.now()
    today = datetime.date.today()
    first_day_of_currrent_month = datetime.date.today().replace(day=1)
    store_id = get_or_set_store_id()
    current_endpoint = 'mmgmt.stats_summary'

    orders_stats = dict()
    orders_stats['today_orders_count'] = Order.count_orders_by_date_and_store(
        today, store_id)
    orders_stats[
        'today_delivered_count'] = Order.count_delivered_orders_between_date_and_store(
            store_id, today, today)
    orders_stats[
        'current_month_delivered_count'] = Order.count_delivered_orders_between_date_and_store(
            store_id, first_day_of_currrent_month, today)
    orders_stats['undelivered_count'] = Order.count_all_new_orders_by_store(
        store_id)

    # inv_status = dict()
    # inv_status['total_inv'] = ?

    rx_stats = dict()
    from application.models.reception import Reception
    today_receptions = Reception.find_all_of_today_in_store(store_id)
    rx_stats['rx_new'] = len(
        [rx for rx in today_receptions if rx.rx_type == 'new'])
    rx_stats['rx_appt_new'] = len(
        [rx for rx in today_receptions if rx.rx_type == 'appt_new'])
    rx_stats['rx_appt'] = len(
        [rx for rx in today_receptions if rx.rx_type == 'appt'])
    rx_stats['rx_other'] = len(
        [rx for rx in today_receptions if rx.rx_type == 'other'])

    rx_stats['rx_total'] = len(today_receptions)
    rx_stats['rx_instore'] = len(
        [rx for rx in today_receptions if rx.status != 'completed'])

    rx_base_url, rx_url_params = get_filter_link('receptions.receptions', now,
                                                 now, current_endpoint)
    order_base_url, order_url_params = get_filter_link('orders.orders', now,
                                                       now, current_endpoint)

    monthly_delivered_order_url_params = order_url_params.copy()
    monthly_delivered_order_url_params.update({
        'start_date':
        datetime.date.today().replace(day=1).strftime(DATE_FORMAT)
    })
    monthly_delivered_order_url_params['status_filter'] = 'delivered'
    monthly_delivered_order_url_params['history'] = 'y'

    all_new_order_url_params = order_url_params.copy()
    all_new_order_url_params['start_date'] = ''
    all_new_order_url_params['end_date'] = ''
    all_new_order_url_params['status_filter'] = 'new'

    return render_template(
        'mmgmt/summary.html',
        today_str=format_date_zh(datetime.date.today()),
        orders_stats=orders_stats,
        rx_stats=rx_stats,
        rx_base_url=rx_base_url,
        rx_url_params=rx_url_params,
        order_base_url=order_base_url,
        order_url_params=order_url_params,
        monthly_delivered_order_url_params=monthly_delivered_order_url_params,
        all_new_order_url_params=all_new_order_url_params)
示例#23
0
文件: user.py 项目: sungitly/isr
def evening_call():
    current_user = g.user
    store_id = get_or_set_store_id()

    today = datetime.date.today()
    orders_stats = dict()
    orders_stats['today_orders_count'] = Order.count_orders_by_date_and_store(datetime.date.today(), store_id)
    orders_stats['current_month_orders_count'] = Order.count_orders_from_date_and_store(
        datetime.date.today().replace(day=1),
        store_id)
    current_month_ta = TaSetting.find_active_monthly_ta(today.year, today.month, store_id)
    orders_stats['current_month_target'] = current_month_ta.value if current_month_ta else 'N/A'

    sales_stats = User.get_all_sales_by_store_from_cache(long(store_id))
    today_receptions = Reception.find_all_of_today_in_store(store_id)
    today_appointments = Appointment.find_all_by_date_in_store(datetime.date.today(), store_id)
    tomorrow_appointments = Appointment.find_all_by_date_in_store(datetime.date.today() + datetime.timedelta(days=1),
                                                                  store_id)
    total_counts, sales_counts = calc_reception_counts(today_receptions, sales_stats)

    for sale in sales_stats:
        populate_appt_count_agg_by_sale_and_type(today_appointments, sale, include_closed=True)
        populate_appt_count_agg_by_sale_and_type(tomorrow_appointments, sale, attr_prefix='tomorrow_')
        sale.rx_count = sales_counts.get(sale.id, {'total': 0, 'new': 0, 'appt_new': 0, 'appt': 0, 'other': 0})

    appts_count = generate_appt_count_agg_by_type(today_appointments, include_closed=True)
    tomorrow_appts_count = generate_appt_count_agg_by_type(tomorrow_appointments)

    sales_stats.sort(key=lambda sale: sale.rx_count, reverse=True)

    rx_stats = {'today_incomplete_count': len([x for x in today_receptions if x.status != 'completed'])}

    appt_stats = dict()
    appt_stats['instore'] = len([x for x in today_appointments if x.status != 'cancelled' and x.type == 'instore'])
    appt_stats['open_instore'] = len([x for x in today_appointments if x.status == 'opened' and x.type == 'instore'])
    appt_stats['followup'] = len([x for x in today_appointments if x.type == 'followup'])
    appt_stats['open_followup'] = len([x for x in today_appointments if x.status == 'opened' and x.type == 'followup'])

    now = datetime.datetime.now()
    tomorrow_datetime = now + datetime.timedelta(days=1)
    current_endpoint = 'user.evening_call'

    rx_base_url, rx_url_params = get_filter_link('receptions.receptions', now, now, current_endpoint)
    rx_incomplete_params = rx_url_params.copy()
    rx_incomplete_params['status_filter'] = 'in-store'
    appt_base_url, appt_url_params = get_filter_link('appointments.appts', now, now, current_endpoint)

    tomorrow_appt_base_url, tomorrow_appt_url_params = get_filter_link('appointments.appts', tomorrow_datetime,
                                                                       tomorrow_datetime,
                                                                       current_endpoint)

    recent_campaigns = Campaign.find_all_by_store_in_recent_days(store_id, 15)

    order_base_url, order_url_params = get_filter_link('orders.orders', now, now, current_endpoint)
    monthly_order_url_params = order_url_params.copy()
    monthly_order_url_params['start_date'] = datetime.date.today().replace(day=1).strftime(DATE_FORMAT)
    monthly_order_url_params['end_date'] = now.strftime(DATE_FORMAT)

    return render_template('user/salesmanager/eveningcall.html', selected_menu=USER_EVENING_CALL, rx_stats=rx_stats,
                           orders_stats=orders_stats, today_receptions_count=len(today_receptions),
                           rx_incomplete_params=rx_incomplete_params,
                           sales_stats=sales_stats, appts_count=appts_count, total_rx_count=total_counts,
                           tomorrow_appts_count=tomorrow_appts_count, recent_campaigns=recent_campaigns,
                           recent_campaigns_count=len(recent_campaigns), rx_base_url=rx_base_url,
                           rx_url_params=rx_url_params, order_base_url=order_base_url,
                           tomorrow_appt_base_url=tomorrow_appt_base_url,
                           tomorrow_appt_url_params=tomorrow_appt_url_params,
                           order_url_params=order_url_params, appt_stats=appt_stats, appt_base_url=appt_base_url,
                           appt_url_params=appt_url_params,
                           monthly_order_url_params=monthly_order_url_params,
                           back_endpoint=request.args.get('back_endpoint', None))
示例#24
0
def sync_hwjd_customer_rx(reception_id):
    reception = Reception.find(reception_id)

    if reception:
        sync_rx_with_hwjd_oa(reception)
示例#25
0
def get_customer_receptions(customer_id):
    sales_id = request.args.get("sales_id", None)
    return Reception.find_all_by_customer_sales(customer_id, sales_id)
示例#26
0
def get_today_receptions_by_status_of_sales(sale_id, status):
    return Reception.find_all_of_today_of_sales_by_status(sale_id, status)
示例#27
0
def get_today_receptions(store_id):
    return Reception.find_all_of_today_in_store(store_id)
示例#28
0
def create_reception():
    data = request.json
    if data is None:
        abort(400, description=gettext('invalid json request'))

    try:
        populate_customer_from_request(data, data.get('store_id'),
                                       data.get('sales_id'))
    except NoPermissionOnCustomerException, npe:
        raise IncorrectSalesAssignmentException(
            gettext(
                u'the customer belongs to %(sales_name)s, force assign to %(new_sales)s',
                sales_name=npe.customer.sales.username,
                new_sales=User.find(data.get('sales_id')).username))

    reception = Reception(**data)
    # default receptionist_id if not passed from client
    if convert_int(reception.receptionist_id) <= 0:
        reception.receptionist_id = get_user_id()
    reception.customer.enlist()

    reception.created_on = datetime.now()
    reception.customer.last_reception_date = reception.created_on

    if reception.appointment_id is not None:
        appt = Appointment.find(reception.appointment_id)
        if not appt:
            reception.appointment_id = None
        else:
            if appt.type == 'deliver':
                reception.rx_type = 'other'
示例#29
0
文件: user.py 项目: sungitly/isr
def dashboard():
    current_user = g.user
    now = datetime.datetime.now()
    store_id = get_or_set_store_id()
    orders_stats = dict()
    orders_stats['today_orders_count'] = Order.count_orders_by_date_and_store(datetime.date.today(), store_id)
    orders_with_status = Order.find_orders_status_from_date_and_store(datetime.date.today().replace(day=1), store_id)
    orders_stats['current_month_new_count'] = len(
        [x for x in orders_with_status if x.status == 'new'])
    orders_stats['current_month_delivered_count'] = Order.count_delivered_orders_between_date_and_store(store_id,
                                                                                                        get_first_day_of_month(
                                                                                                            now).date(),
                                                                                                        now.date())

    customer_stats = dict()
    today_receptions = Reception.find_all_of_today_in_store(store_id)
    completed_reception = filter(lambda rx: rx.status == 'completed', today_receptions)
    customer_stats['total'] = len(today_receptions) if today_receptions else 0
    customer_stats['complete'] = len(completed_reception) if completed_reception else 0
    customer_stats['instore'] = customer_stats['total'] - customer_stats['complete']
    customer_stats['new'] = len([x for x in today_receptions if x.rx_type == 'new'])
    customer_stats['appt_new'] = len([x for x in today_receptions if x.rx_type == 'appt_new'])
    customer_stats['appt'] = len([x for x in today_receptions if x.rx_type == 'appt'])
    customer_stats['other'] = len([x for x in today_receptions if x.rx_type == 'other'])

    today_appointments = Appointment.find_all_by_date_in_store(datetime.date.today(), store_id)
    appt_stats = dict()
    appt_stats['instore'] = len([x for x in today_appointments if x.status != 'cancelled' and x.type == 'instore'])
    appt_stats['open_instore'] = len([x for x in today_appointments if x.status == 'opened' and x.type == 'instore'])
    appt_stats['followup'] = len([x for x in today_appointments if x.type == 'followup'])
    appt_stats['open_followup'] = len([x for x in today_appointments if x.status == 'opened' and x.type == 'followup'])

    sales = User.get_all_sales_by_store_from_cache(long(store_id))
    # make sure the status is correct
    SalesStatus.reset_all_sales_status(store_id)
    sales_status = SalesStatus.get_all_sales_status(store_id)

    total_counts, reception_counts = calc_reception_counts(today_receptions, sales)

    for sale in sales:
        sale.status = sales_status.get(str(sale.id), 'free')
        set_status_label_and_style(sale)
        sale.rx_count = reception_counts.get(sale.id, {'total': 0, 'new': 0, 'appt_new': 0, 'appt': 0, 'other': 0})
    # receptions_per_sale = filter(lambda rx: rx.sales_id == sale.id, today_receptions)
    #     sale.rx_count = len(receptions_per_sale) if receptions_per_sale else 0
    #     total_rx_count += sale.rx_count

    sales.sort(key=lambda sale: sale.status)

    today_orders = Order.find_all_created_today_by_store(store_id)
    today_orders_count = len(today_orders) if today_orders else 0

    current_endpoint = 'user.dashboard'
    rx_base_url, rx_url_params = get_filter_link('receptions.receptions', now, now, current_endpoint)
    order_base_url, order_url_params = get_filter_link('orders.orders', now, now, current_endpoint)
    monthly_order_url_params = order_url_params.copy()
    monthly_order_url_params.update({'start_date': datetime.date.today().replace(day=1).strftime(DATE_FORMAT)})
    monthly_delivered_order_url_params = monthly_order_url_params.copy()
    monthly_delivered_order_url_params['status_filter'] = 'delivered'
    monthly_delivered_order_url_params['history'] = 'y'
    appt_base_url, appt_url_params = get_filter_link('appointments.appts', now, now, current_endpoint)
    # tbc_orders = Order.find_all_in_status_by_store(store_id, confirmed=0, status='new')

    return render_template('user/salesmanager/dashboard.html', selected_menu=USER_RT_DATA, orders_stats=orders_stats,
                           appt_stats=appt_stats,
                           customer_stats=customer_stats, sales=sales, today_orders=today_orders,
                           total_count=total_counts, today_orders_count=today_orders_count,
                           sales_receptions=reception_counts, rx_base_url=rx_base_url, rx_url_params=rx_url_params,
                           order_base_url=order_base_url, order_url_params=order_url_params,
                           monthly_order_url_params=monthly_order_url_params,
                           monthly_delivered_order_url_params=monthly_delivered_order_url_params,
                           appt_base_url=appt_base_url,
                           appt_url_params=appt_url_params)