def sign_in(): sign_in = client['profile']['sign_in'] start, end = TimeZone.day_range(value=TimeZone.local_now()) pprint( "姓名", "电话", "时间", "地址", "POI", "经度", "维度", ) for doc in sign_in.find({"create_time": {"$gte": start, "$lte": end}}): pprint(doc['name'], doc['tel'], TimeZone.utc_to_local(doc['create_time']), doc['loc']['addr'], doc['loc']['name'], doc['loc']['lng'], doc['loc']['lat'])
def api_deliveryman_sign_in(): """ 派件系人员签到 :param man_id: 根据 id 查出 name, tel, avatar :param loc: {name, addr, lng, lat} :param device: {mac_id, ...} :return: 失败返回400和message """ params = ctx.request.input() # ==> 根据id拿基本信息 man = Man.objects(id=params.man_id).first() # ==> 检查今日签到次数 now = TimeZone.local_now() start_time, _end_time = TimeZone.day_range(value=now) start_time = TimeZone.datetime_to_str(start_time) sign_in_count = SignIn.objects(**{ 'man_id': params.man_id, 'create_time__gte': start_time }).count() if sign_in_count >= 50: logging.warn("Man[%s][%s] try to sign in over 10 times." % (params.man_id, man.name)) raise ValueError("一天最多签到10次") # ==> 记录这次签到 name = man.name if man.name else '' avatar = man.avatar if man.avatar else '' SignIn(man_id=params.man_id, name=name, tel=man.tel, avatar=avatar, loc=params.loc, device=params.device, create_time=now).save(force_insert=True) return { 'create_time': TimeZone.datetime_to_str(now, pattern='%Y-%m-%dT%H:%M:%S') }
def api_retrieve_man_info(what): what = str(what).upper().strip() request = ctx.request.input() # 如果传入what,by不是允许的值,直接报错 if what not in WHATS: raise ValueError("WHAT[%s] should be in WHATS%s." % (what, list(WHATS.keys()))) params = set([str(k).lower().strip() for k in request]) bys = set(BYS.keys()) by = params.intersection(bys) if not by: raise ValueError("BY%s should be in BYS%s." % (list(params), list(bys))) by_key = next(iter(by)) by_val = request[by_key] if by_key == 'id' and by_val and len(by_val) != 24: raise ValueError('find man with id=%s, id should be of length 24.' % by_val) # 判断是要什么类型的返回 if what == WHATS.BASIC: excludes = ('accounts', 'create_time', 'my_man') man = Man.objects(**{by_key: by_val}).exclude(*excludes).first() if not man: raise ValueError("Can't find man with[%s]=[%s]." % (by_key, by_val)) packed = ManLogic.pack_man(man, excludes=excludes) ret_cnt = ('familiars', 'pick_up_locations') for k in ret_cnt: if k in packed: packed[k] = len(packed[k]) if packed[k] else 0 return packed elif what == WHATS.ACCOUNT_LIST: man = Man.objects(**{by_key: by_val}).only('accounts').first() return man.accounts elif what == WHATS.FAMILIAR_LIST: man = Man.objects(**{by_key: by_val}).only('familiars').first() return man.familiars elif what == WHATS.STATUS: man = Man.objects(**{by_key: by_val}).only('status').first() return man.status elif what == WHATS.MAN_LIST: man = Man.objects(**{by_key: by_val}).only('my_man').first() if man and man.my_man: only = ('status', 'id', 'name', 'tel', 'avatar') my_man = {m['id']: m['bind_time'] for m in man.my_man} mans = Man.objects(id__in=list(my_man.keys())).only(*only) ret = [] for m in mans: packed_man = ManLogic.pack_man(m, only=only) packed_man['bind_time'] = my_man[str(m.pk)] ret.append(packed_man) return ret else: return [] elif what == WHATS.CODE: # 取header里面的app-name, 没给的话就给man app_name = ctx.request.header('app-name', 'man') man_id = by_val code = shortuuid.ShortUUID().random(length=8) # role是区域经理app端header里面的app-name key = key_man_code.format(role=app_name, content=code) # 存放: 二维码(360秒): get <app-name>:code:fe11ad907e2fa779ed2f363ef589d3f9 => 56f1028b2d50c07c80914393 redis_client.setex(key, man_id, 360) logging.info('Setting Code [%s] => [%s].' % (key, man_id)) return key elif what == WHATS.PICKUP_LIST: man = Man.objects(**{by_key: by_val}).only('pick_up_locations').first() return man.pick_up_locations elif what == WHATS.SIGN_IN_COUNT: # 获取人员名字 man = Man.objects(id=by_val).only('name').first() name = man.name if man.name else '' # 获取今天凌晨以后的签到记录次数 now = TimeZone.local_now() start_time, _end_time = TimeZone.day_range(value=now) start_time = TimeZone.datetime_to_str(start_time) sign_in_count = SignIn.objects(**{ by_key: by_val, 'create_time__gte': start_time }).count() return dict(name=name, sign_in_count=sign_in_count, server_time=TimeZone.datetime_to_str( now, pattern='%Y-%m-%dT%H:%M:%S'))
def op_data(): logging.info("op_data start...") man_conn = mongodb_client['profile']['man'] shop_conn = mongodb_client['profile']['shop'] express = mongodb_client['aeolus']['express'] opdata = OpData.objects.order_by("-create_time").first() start_date = date(2016, 5, 20) if opdata: start_date = TimeZone.increment_days( TimeZone.utc_to_local(opdata.create_time), 1).date() end_date = TimeZone.local_now().date() for day in TimeZone.date_xrange(start_date, end_date): start_time, end_time = TimeZone.day_range(value=day) logging.info("op data %s", day) data = {} # ============= 资金 ============== data['zj_top_up'], data['zj_pay'] = get_zj_statistics( day, TimeZone.increment_days(day)) # ============= 订单 ============== data['dd_count'] = express.find({ "create_time": { "$gte": start_time, "$lte": end_time } }).count() data['dd_sj_count'] = express.find({ "times.zj_time": { "$gte": start_time, "$lte": end_time } }).count() data['dd_tt_count'] = express.find({ "times.parttime_tt_time": { "$gte": start_time, "$lte": end_time } }).count() data['dd_error_count'] = express.find({ "times.yc_time": { "$gte": start_time, "$lte": end_time } }).count() # ============= 客户 ============== data['sh_register'] = shop_conn.find({ "create_time": { "$gte": start_time, "$lte": end_time } }).count() data['sh_order'] = 0 result = express.aggregate([{ "$match": { "create_time": { "$gte": start_time, "$lte": end_time } } }, { "$group": { "_id": "$creator.id", } }, { "$group": { "_id": "sum", "count": { "$sum": 1 } } }]) for doc in result: data['sh_order'] += doc['count'] # ============== 人力 =============== data['hr_on_job'] = man_conn.find({ "job_description": "parttime", "status": "STATUS_WORKING" }).count() data['hr_active'] = 0 # 在规定时间内收件的人 result = express.aggregate([{ "$match": { "times.sj_time": { "$gte": start_time, "$lte": end_time } } }, { "$project": { "man": { "$arrayElemAt": ["$watchers", 0] } } }, { "$group": { "_id": "$man.id" } }]) active_list = [_['_id'] for _ in result] result = express.aggregate([{ "$match": { "times.parttime_tt_time": { "$gte": start_time, "$lte": end_time } } }, { "$group": { "_id": "$assignee.id", } }]) # 在规定时间内妥投的人 active_list2 = [_['_id'] for _ in result] temp = set(active_list + active_list2) data['hr_active'] = len(temp) # 司机出勤 man_list = man_conn.find({"tel": {"$in": driver_list}}) node_conn = psycopg2.connect(cursor_factory=psycopg2.extras.DictCursor, database="tlbs", **CONFIG_POSTGRESQL) cursor = node_conn.cursor() data['cl_depart'] = 0 man_id_list = [str(_['_id']) for _ in man_list] for man_id in man_id_list: local = arrow.get(day, "local") cursor.execute( """SELECT count(*) from trans.bs_trans_deliver_sign_record where deliver_id = %s and create_time >= %s and create_time <= %s """, (man_id, local.floor("day").strftime(TIME_PATTERN), local.ceil("day").strftime(TIME_PATTERN))) doc = cursor.fetchone() if doc and int(doc[0]) > 0: data['cl_depart'] += 1 cursor.execute( """ SELECT count(*) FROM trans.bs_trans_bind_node_info WHERE deliver_id = ANY(%s) """, (man_id_list, )) doc = cursor.fetchone() if not doc: data['cl_shift'] = 0 else: data['cl_shift'] = int(doc[0]) # ======================================= create_time = TimeZone.datetime_to_utc( TimeZone.naive_to_aware(datetime(day.year, day.month, day.day, 1))) data["create_time"] = create_time OpData(**data).save() logging.info("op_data end...")
def shop_reward(): logging.info("invitation shop reward start...") man_conn = mongodb_client['profile']['man'] shop_conn = mongodb_client['profile']['shop'] express = mongodb_client['aeolus']['express'] now = TimeZone.utc_now() local = TimeZone.local_now() cursor = shop_conn.find({ "recommended_by.tel": { "$exists": True }, "recommended_by.time": { "$gt": TimeZone.decrement_months(now, 2) } }) m_type = "shop_invitation" for doc in cursor: man = man_conn.find_one({"tel": doc['recommended_by']['tel']}) if not man: logging.warning("no man tel:%s", doc['recommended_by']['tel']) continue shop_id = str(doc['_id']) shop_name = utf8(doc.get("name", "新客户")) man = format_man(man, 'parttime') invite_time = TimeZone.naive_to_aware(doc['recommended_by']['time'], pytz.utc) # 拿出这个人对应商户所有的奖励, 用来计算已经奖励了多少钱 reward_list = Rewards.objects(man__id=man['id'], source__shop_id=shop_id, m_type=m_type) # 计算还剩多少可以奖励 count = 0 for r in reward_list: count += r.money count = int(count) left = 100 - count # 如果没剩了, 不能再奖励了 if left <= 0: continue # 计算最近一次需要计算的日期, try: reward = reward_list[0] start_date = TimeZone.utc_to_local( TimeZone.increment_days(reward.create_time, 1)).date() except IndexError: start_date = TimeZone.utc_to_local(invite_time).date() # 最多计算到昨天 end_date = local.date() # 从开始日期开始到昨天都需要计算 for day in TimeZone.date_xrange(start_date, end_date): start_time, end_time = TimeZone.day_range(value=day) # 限制一下start_time start_time = start_time if start_time > invite_time else invite_time _count = express.find({ "creator.id": shop_id, "times.sj_time": { "$gte": start_time, "$lte": end_time }, }).count() if _count == 0: continue c = _count if _count < left else left money = c * 1.0 # 先将时间加上本地tzinfo, 然后再转换时区, 直接指定tzinfo会出错, 差6分钟, 故意躲加1小时 create_time = TimeZone.datetime_to_utc( TimeZone.naive_to_aware( datetime(day.year, day.month, day.day, 1))) Rewards(m_type=m_type, title="邀请客户", desc="%s当日下单%s单" % (shop_name, c), man=man, money=money, source={ "shop_id": shop_id, "shop_name": shop_name }, create_time=create_time).save() logging.info( "reward: m_type[%s], date[%s], man[%s], shop_id[%s], money[%s]", m_type, day, man['id'], shop_id, money) left -= c if left <= 0: break
def get(self): # 商户名,商户注册电话,余额,当日消费,当日10:00前下单,当日10:00~14:00下单,当日14:00之后下单,当日待取件,总计待妥投 try: data = Schema({ "date": schema_date, }).validate(self.get_query_args()) date = data['date'] except SchemaError: self.resp_error('参数[date]解析失败') return middle = {} # 1. 商户名,商户注册电话,当日消费,当日10:00前下单,当日10:00~14:00下单,当日14:00之后下单 start_time, end_time = TimeZone.day_range(value=date) pipeline = [ # 取今天的所有有效运单 { "$match": { "create_time": { "$gt": start_time, "$lt": end_time }, "status.sub_status": {"$ne": ExprState.SUB_STATUS_CANCEL} } }, # 按照[商户,小时]分组 { "$group": { "_id": { "creator_id": "$creator.id", "hour": {"$hour": {"$add": ['$create_time', 28800000]}}, }, "tel": {"$first": "$creator.tel"}, "name": {"$first": "$creator.name"}, "expr_count": {"$sum": 1}, # 暂时除了pre_created的运单才算是消费了 "expense": {"$sum": {"$cond": [{"$ne": ["$status.status", "PRE_CREATED"]}, "$fee.fh", 0]}} } }, # 根据[商户,小时]分组计算10:00前,10:00~14:00,14:00后下单数量 { "$group": { "_id": { "creator_id": "$_id.creator_id", }, "tel": {"$first": "$tel"}, "name": {"$first": "$name"}, "expense": {"$sum": "$expense"}, "count_before_10am": {"$sum": {"$cond": [{"$lt": ["$_id.hour", 10]}, "$expr_count", 0]}}, "count_10am_to_2pm": {"$sum": { "$cond": [{"$and": [{"$gte": ["$_id.hour", 10]}, {"$lt": ["$_id.hour", 14]}]}, "$expr_count", 0]}}, "count_after_2pm": {"$sum": {"$cond": [{"$gte": ["$_id.hour", 14]}, "$expr_count", 0]}}, "count_all": {"$sum": "$expr_count"} } }, { "$sort": { "count_all": -1, } } ] result = yield self.async_fetch(redirect_aggregation(pipeline=pipeline)) content = result.content # 从这里拿到所有的商户id creator_ids = [] for c in content: creator_id = c['_id']['creator_id'] tel = c['tel'] name = c['name'] expense = c['expense'] # 10点之前下单数量 count0 = c['count_before_10am'] # 10-14点下单数量 count1 = c['count_10am_to_2pm'] # 14点之后下单数量 count2 = c['count_after_2pm'] # 当日总计下单量 _count_all = c['count_all'] # print("[%s] %s+%s+%s=%s 消費:%s" % (name, count0, count1, count2, _count_all, expense)) creator_ids.append(creator_id) middle[creator_id] = dict(name=name, tel=tel, expense=expense, count_before_10am=count0, count_10am_to_2pm=count1, count_after_2pm=count2, count_all=_count_all) # 2. 当日待取件, 当日待妥投 pipeline = [ # 取今天在<creator_ids>里面的所有运单 { "$match": { "create_time": { "$gt": start_time, "$lt": end_time }, "creator.id": { "$in": creator_ids } } }, # 按照[商户,状态条件]分组 { "$group": { "_id": { "creator_id": "$creator.id", }, "count_created": {"$sum": {"$cond": [{"$eq": ["$status.status", "PRE_CREATED"]}, 1, 0]}}, "count_sending": {"$sum": {"$cond": [{"$eq": ["$status.status", "SENDING"]}, 1, 0]}}, "count_all": {"$sum": 1} } }, { "$sort": { "count_all": -1, } } ] result = yield self.async_fetch(redirect_aggregation(pipeline=pipeline)) for c in result.content: creator_id = c['_id']['creator_id'] # 待取貨 count0 = c['count_created'] # 派件中 count1 = c['count_sending'] # 当日总计下单量 _count_all = c['count_all'] # print("[%s] 待取貨:%s 派件中:%s 總計:%s" % (name, count0, count1, _count_all)) middle[creator_id]['count_created'] = count0 middle[creator_id]['count_sending'] = count1 # 3. 拿余额 balances = yield multi_shop_balance(creator_ids) # 4. 拼结果 fin = [] for cid in creator_ids: middle[cid]['id'] = cid middle[cid]['balance'] = balances[cid] fin.append(middle[cid]) self.resp(fin)