def logs(self, ltype, lid): """ :param ltype: :param lid: :return: """ if ltype == 'express': logistics = Logistic.objects(id=lid).first().express_tracking return self.render('admin/logistic/express.html', logistics=logistics) elif ltype == 'logistic': logistics = LogisticLog.objects(logistic_id=lid, log_type__ne='API') user = lambda i: getattr(User.objects(id=i).first(), 'name', '' ) if i and i != 'system' else i return self.render('admin/logistic/logs.html', logistics=logistics, user=user) elif ltype == 'print': logistic = Logistic.objects(id=lid).first() if logistic.is_closed: return Response('this logistics id has been closed.') return self.render('admin/logistic/print_page.html', logistic=logistic)
def logistics_delay(self, status=None, delay_type=None): """ 物流延迟 :param status: :param delay_type: :return: """ utcnow = datetime.datetime.utcnow() if status: items_range = request.headers.get('Range', '0-9') start, end = items_range.split('-') per_page = int(end) - int(start) + 1 query = restruct_query(request.args) tracking_no = query.pop('tracking_no', '') date_field = LogisticDetail.attr_by_log_status[status] delay_days = datetime.timedelta(days=delay_status_by_date[status]) query.update({ 'detail__%s__lt' % date_field: utcnow - delay_days, 'detail__status': status, }) logistic = Logistic.objects(is_closed=False, **query).order_by( 'detail__%s' % date_field) if tracking_no: logistic = logistic.filter( Q(detail__us_tracking_no=tracking_no) | Q(detail__cn_tracking_no=tracking_no)) if delay_type: logistic = logistic.filter( detail__delay_details__reason__contains=delay_type) data = logistic[int(start):int(end)] data = [to_json(l) for l in data] resp = make_response(json_util.dumps(data), 200) resp.headers['Accept_Range'] = 'items' resp.headers['Content_Range'] = '%s-%s/%s' % (start, end, logistic.count()) resp.headers['Content_Type'] = 'application/json' return resp data = {} for status in [ 'PAYMENT_RECEIVED', 'PROCESSING', 'SHIPPING', 'PORT_ARRIVED' ]: logistic = Logistic.objects(is_closed=False) date_field = LogisticDetail.attr_by_log_status[status] delay_days = datetime.timedelta(days=delay_status_by_date[status]) query = { 'detail__%s__lt' % date_field: utcnow - delay_days, 'detail__status': status, } count = logistic.filter(**query).count() data.update({status: count}) return jsonify(results=data)
def logistics(self): """ 物流 :return: """ items_range = request.headers.get('Range', '0-9') start, end = items_range.split('-') per_page = int(end) - int(start) + 1 query = restruct_query(request.args) tracking_no = query.pop('tracking_no', '') include_closed = query.get('include_closed') and query.pop( 'include_closed') try: if include_closed: logistic = Logistic.objects(**query) else: logistic = Logistic.objects(is_closed=False, **query) if tracking_no: logistic = logistic.filter( Q(detail__us_tracking_no=tracking_no) | Q(detail__cn_tracking_no=tracking_no)) if request.args.get('status'): logistic = logistic.order_by('detail__%s' % LogisticDetail.attr_by_log_status[ request.args.get('status')]) except: pass if query.get('receiver'): address = Address.objects( receiver=query.get('receiver')).distinct('id') orders = Order.commodities(address__in=address) logistic = list( chain.from_iterable(order.logistics for order in orders)) if query.get('order_id'): orders = Order.commodities(short_id=int(query.get('order_id'))) logistic = list( chain.from_iterable(order.logistics for order in orders)) try: logistic_size = logistic.count() except: logistic_size = len(logistic) data = logistic[int(start):int(end)] data = [to_json(l) for l in data] resp = make_response(json_util.dumps(data), 200) resp.headers['Accept_Range'] = 'items' resp.headers['Content_Range'] = '%s-%s/%s' % (start, end, logistic_size) resp.headers['Content_Type'] = 'application/json' return resp
def split_entries(self): """ :return: """ entries = request.json.get('selected') if not entries: return jsonify(message='Failed', desc='please select entries.') lids = [] entry_ids = [] for e in entries: l = e.split(':') lids.append(l[1]) entry_ids.append(l[0]) logistic = [Logistic.objects(id=lid).first() for lid in set(lids)] entry_lst = [] for i in entry_ids: e = OrderEntry.objects(id=str(i)).first() entry_lst.append(e) entries_groups = map( lambda lo: filter(lambda e: e in lo.entries, entry_lst), logistic) for logistic, lst in zip(logistic, entries_groups): logistic.fork_by_entries([e.id for e in lst]) return jsonify(message='OK', oid=logistic.order.short_id)
def close(self, lid): """ :param lid: :return: """ logistic = Logistic.objects(id=lid).first() logistic.close('closed by %s' % current_user.name) return jsonify(message='OK')
def logistics_irregular(self, process_status=None, irr_type=None): """ :param process_status: :param irr_type: :return: """ utcnow = datetime.datetime.utcnow() if process_status: items_range = request.headers.get('Range', '0-9') start, end = items_range.split('-') query = restruct_query(request.args) tracking_no = query.pop('tracking_no', '') logistic = Logistic.objects( detail__irregular_details__process_status=process_status, **query).order_by('-detail.irregular_details.created_at') if irr_type: logistic = logistic.filter( detail__irregular_details__irr_type=irr_type).order_by( '-detail.irregular_details.created_at') if tracking_no: logistic = logistic.filter( Q(detail__us_tracking_no=tracking_no) | Q(detail__cn_tracking_no=tracking_no)) data = logistic[int(start):int(end)] data = [to_json(l) for l in data] resp = make_response(json_util.dumps(data), 200) resp.headers['Accept-Range'] = 'items' resp.headers['Content-Range'] = '%s-%s/%s' % (start, end, logistic.count()) resp.headers['Content_Type'] = 'application/json' return resp data = {} for status in ['WAITTING_PROCESS', 'PROCESSING', 'PROCESSED']: logistic = Logistic.objects( detail__irregular_details_process_status=status) data.udpate({status: logistic.count()}) return jsonify(results=data)
def logistic_provider_dispatcher(order): """ :param order: :return: """ Logistic.create(order) for logistic in order.logistics: if len(logistic.entries) > 1: logs = LogisticSpliter(log=logistic).do() if len(logs) > 1: logistic.close(reason='close by auto spliter') order.reload() for logistic in order.logistics: if order.order_type == ORDER_TYPE.TRANSFER: logistic.detail.route = order.order_type logistic.save() return order
def back_status(self): lid = request.args.get('lid') status = request.args.get('status') logistic = Logistic.objects(id=lid).first() logistic.detail.status = status setattr(logistic.detail, LogisticDetail.attr_by_log_status[status], datetime.datetime.utcnow()) logistic.save() order = logistic.order order.update_logistic_status() return jsonify(message='OK')
def create(self): try: log = Logistic(detail=self.log.detail) except: log = Logistic(detail=LogisticDetail()) log.order = self.order log.entries = list(self.entries) self.order.logistics.append(log) if not self.debug: log.detail.partner = Partner.objects().first() log.detail.partner_tracking_no = generate_uid() log.save() self.order.save() return log
def get_logistic(logistic_id): """ :param logistic_id: :return: """ logistic = Logistic.objects(id=logistic_id).first_or_404() express = logistic.express_tracking logistic_obj = {'id': str(logistic.id)} logistic_obj['entries'] = [ json_templ.entry_json(entry) for entry in logistic.entries ] logistic_obj['status'] = logistic.detail.status logistic_obj['data'] = logistic.to_json() logistic_obj['history'] = logistic.shipping_history logistic_obj['tracking'] = express.history if express else '' logistic_obj['address'] = logistic.order.address.to_json() logistic_obj['payment_status'] = logistic.order.goods_payment.status return jsonify(message='OK', logistic=logistic_obj)
def update_logistic_received_status(state, com, num, data): """ 更新物流状态 :param state: :param com: :param num: :param data: :return: """ latest_time = datetime.strptime(data[0]['time'], '%Y-%m-%d %H:%M:%S') first_time = datetime.strptime(data[-1]['time'], '%Y-%m-%d %H:%M:%S') check = (state == '3') for logistic in Logistic.objects(detail__cn_tracking_no=num): if not check and logistic.status != LOG_STATUS.SHIPPING: logistic.update_logistic({ 'status': LOG_STATUS.SHIPPING, 'shipping_date': to_utc(first_time).replace(tzinfo=None), 'modified_by': 'kuaidi100' }) elif not check and 'ISC' in data[0][ 'ISC'] and logistic.detail.status != LOG_STATUS.PORT_ARRIVED: logistic.update_logistic({ 'status': LOG_STATUS.PORT_ARRIVED, 'received_date': to_utc(latest_time).replace(tzinfo=None), 'modified_by': 'kuaidi100', }) elif check and logistic.detail.status != LOG_STATUS.RECEIVED: logistic.update_logistic({ 'status': LOG_STATUS.RECEIVED, 'received_date': to_utc(latest_time).replace(tzinfo=None), 'modified_by': 'kuaidi100', })
def merge(self): """ :return: """ lids = request.json.get('lids') if not lids: return jsonify(message='Failed', desc='error') logistic = [Logistic.objects(id=lid).first() for lid in lids] if not type(logistic) is list: return jsonify(message='Failed', desc='please select more than 2 logistics') start = 0 for index in range(len(logistic) - 1): if logistic[index + 1].detail.cn_tracking_no != logistic[ start].detail.cn_tracking_no or logistic[ index + 1].order != logistic[0].order: return jsonify(message='Failed', desc='CTN and OrderID should be the same') for index in range(len(logistic) - 1): map(lambda e: logistic[index + 1].entries.append(e), logistic[index].entries) logistic[index].entries = [] logistic[index].save() logistic[index].close('merged with %s' % logistic[index + 1].id, datetime.datetime.utcnow()) logistic[index].save() if index + 1 == len(logistic) - 1: comment = LogisticRemark(content='合并单', creator=current_user.name) logistic[index + 1].detail.remarks.append(comment) logistic[index + 1].save() return jsonify(message='OK', lid=str(logistic[index + 1].id))
def split_quantity(self): """ :return: """ lid = request.json.get('lid') eid = request.json.get('eid') quantity = request.json.get('quantity') logistic = Logistic.objects(id=lid).first() entry = OrderEntry.objects(id=eid).first() if entry.quantity > 1 and entry.quantity - int( quantity) >= 1 and entry and logistic: entry.quantity -= int(quantity) entry.update_snapshot() entry.update_amount() new_entry = deepcopy(entry) new_entry.__class__ = OrderEntry new_entry.id = None new_entry.quantity = int(quantity) new_entry.update_snapshot() new_entry.update_amount() new_entry.save() logistic.entries.append(new_entry) logistic.save() order = logistic.order order.entries.append(new_entry) order.save() else: return jsonify(message='Failed', desc='quantity error') return jsonify(message='OK', entries=[ json.loads(json_util.dumps(entry_to_json(entry))) for entry in logistic.entries ])
def check_kuaidi(): logistics = Logistic.objects(is_closed=False, detail__cn_tracking_no__ne='', detail__cn_logistic_name__ne='', detail__status__in=['SHIPPING', 'PORT_ARRIVED']) for logistic in logistics: jobs.express.kuai_request(logistic.detail.cn_logistic_name, logistic.detail.cn_logistic_no)
def download(self): """ :return: """ FIELDS = [ '包裹ID', 'IMG NO', 'CTN', '下单日期', '订单ID', '订单短号', '收件人', '手机号', '合作物流商', 'remark', '下单备注', '估重', '渠道' ] now = datetime.datetime.now() status = request.args.get('status') query = restruct_query(request.args) delay_export = query.get('delay_export') and query.pop('delay_export') delay_type = query.get('delay_type') and query.pop('delay_type') try: logistics = Logistic.objects(is_closed=False, **query) if status: logistics = logistics.order_by( 'detail__%s' % LogisticDetail.attr_by_log_status[status]) except: pass if delay_export: date_field = LogisticDetail.attr_by_log_status[status] delay_days = datetime.timedelta(days=delay_status_by_date[status]) query = { 'detail__%s__lt' % date_field: datetime.datetime.utcnow() - delay_days, 'detail__status': status, } logistics = logistics.filter(**query).order_by('detail__%s' % date_field) if delay_type: logistics = logistics.filter( detail__delay_details__reason__contains=delay_type) if query.get('receiver'): addresses = Address.objects( receiver=query.get('receiver')).distince('id') orders = Order.commodities(address__in=addresses) logistics = list( chain.from_iterable(order.logistics for order in orders)) if query.get('order_id'): orders = Order.commodities(short_id=int(query.get('order_id'))) logistics = list( chain.from_iterable(order.logistics for order in orders)) def generate(): yield ','.join(st for st in FIELDS) + '\n' for logistic in logistics: yield ','.join([ str(logistic.id), logistic.detail.partner_tracking_no, logistic.detail.carrier_tracking_no, logistic.detail.cn_tracking_no, logistic.detail.cn_logistic_name, format_date(logistic.detail_payment_received_date), str(logistic.order.id), str(logistic.order.short_id), logistic.order.address.receiver, logistic.order.address.mobile_number, format_date(logistic.detail.processing_date), format_date(logistic.detail.shipping_date), format_date(logistic.detail.port_arrived_date), format_date(logistic.detail.received_date), format_date(logistic.detail.modified), logistic.detail.partner.name if logistic.detail.partner else '', ';'.join([r.content for r in logistic.detail.remarks]), logistic.detail.extra or '', str(logistic.estimated_weight), logistic.detail.channel, ]) + '\n' return Response(generate(), minetype='text/csv', headers={ 'Content_Disposition': 'attachment;filename=%s %s.csv' % (format_date(now, '%Y-%m-%d'), 'dumps_file') })