| @@ -357,7 +357,7 @@ def maintenance_tracking_info_subscribe(maintenance, type_): | ||
| 357 | 357 | express_com = maintenance.back_express_com | 
| 358 | 358 | tracking_number = maintenance.back_tracking_number | 
| 359 | 359 | phone = maintenance.phone | 
| 360 | - res = KuaiDi100Subscribe().submit(express_com, tracking_number, phone=phone, callbackurl=callbackurl) | |
| 360 | + return KuaiDi100Subscribe().submit(express_com, tracking_number, phone=phone, callbackurl=callbackurl) | |
| 361 | 361 |  | 
| 362 | 362 |  | 
| 363 | 363 | @logit(body=True) | 
| @@ -8,6 +8,7 @@ from django_response import response | ||
| 8 | 8 | from paginator import pagination | 
| 9 | 9 | from TimeConvert import TimeConvert as tc | 
| 10 | 10 |  | 
| 11 | +from api.tenancy_views import tenancy_tracking_info_subscribe | |
| 11 | 12 | from kodo.decorators import check_admin | 
| 12 | 13 | from tenancy.models import TenancyShotInfo, TenancyShotRequestInfo | 
| 13 | 14 | from utils.error.errno_utils import TenancyStatusCode | 
| @@ -137,6 +138,9 @@ def shot_request_update(request, administrator): | ||
| 137 | 138 | except TenancyShotRequestInfo.DoesNotExist: | 
| 138 | 139 | return response(TenancyStatusCode.TENANCY_SHOT_REQUEST_NOT_FOUND) | 
| 139 | 140 |  | 
| 141 | + old_tracking_number = req.tracking_number | |
| 142 | + old_back_tracking_number = req.back_tracking_number | |
| 143 | + | |
| 140 | 144 | if shot_id: | 
| 141 | 145 | req.shot_id = shot_id | 
| 142 | 146 | if name: | 
| @@ -159,6 +163,11 @@ def shot_request_update(request, administrator): | ||
| 159 | 163 | req.back_tracking_number = back_tracking_number | 
| 160 | 164 | req.save() | 
| 161 | 165 |  | 
| 166 | + if tracking_number and tracking_number != old_tracking_number: | |
| 167 | + tenancy_tracking_info_subscribe(req, 'tracking') | |
| 168 | + if back_tracking_number and back_tracking_number != old_back_tracking_number: | |
| 169 | + tenancy_tracking_info_subscribe(req, 'back_tracking') | |
| 170 | + | |
| 162 | 171 |      return response(data={ | 
| 163 | 172 | 'req': req.data, | 
| 164 | 173 | }) | 
| @@ -2,16 +2,20 @@ | ||
| 2 | 2 |  | 
| 3 | 3 | from __future__ import division | 
| 4 | 4 |  | 
| 5 | +import json | |
| 6 | + | |
| 5 | 7 | from django.conf import settings | 
| 6 | 8 | from django.db import transaction | 
| 7 | 9 | from django_logit import logit | 
| 8 | 10 | from django_query import get_query_value | 
| 9 | 11 | from django_response import response | 
| 12 | +from json_response import JsonResponse | |
| 10 | 13 | from paginator import pagination | 
| 11 | 14 | from TimeConvert import TimeConvert as tc | 
| 12 | 15 |  | 
| 13 | 16 | from tenancy.models import TenancyShotInfo, TenancyShotRequestInfo | 
| 14 | 17 | from utils.error.errno_utils import TenancyStatusCode | 
| 18 | +from utils.kuaidi.subscribe import KuaiDi100 as KuaiDi100Subscribe | |
| 15 | 19 |  | 
| 16 | 20 |  | 
| 17 | 21 | @logit | 
| @@ -134,10 +138,84 @@ def shot_request_sendback(request): | ||
| 134 | 138 | except TenancyShotRequestInfo.DoesNotExist: | 
| 135 | 139 | return response(TenancyStatusCode.TENANCY_SHOT_REQUEST_NOT_FOUND) | 
| 136 | 140 |  | 
| 141 | + old_back_tracking_number = req.back_tracking_number | |
| 142 | + | |
| 137 | 143 | req.back_tracking_number = back_tracking_number | 
| 138 | - req.request_status = '寄出已签收' | |
| 144 | + req.request_status = '寄回' | |
| 139 | 145 | req.save() | 
| 140 | 146 |  | 
| 147 | + if back_tracking_number and back_tracking_number != old_back_tracking_number: | |
| 148 | + tenancy_tracking_info_subscribe(req, 'back_tracking') | |
| 149 | + | |
| 141 | 150 |      return response(data={ | 
| 142 | 151 | 'req': req.data, | 
| 143 | 152 | }) | 
| 153 | + | |
| 154 | + | |
| 155 | +def is_tenancy_tracking_signed(tracking_info): | |
| 156 | + if not tracking_info: | |
| 157 | + return False | |
| 158 | +    items = tracking_info.get('data', []) | |
| 159 | + if not items: | |
| 160 | + return False | |
| 161 | +    return items[0].get('status') == u'签收' | |
| 162 | + | |
| 163 | + | |
| 164 | +@transaction.atomic | |
| 165 | +def tenancy_tracking_info_update(req, type_, tracking_info): | |
| 166 | + is_tracking_signed = is_tenancy_tracking_signed(tracking_info) | |
| 167 | + if type_ == 'tracking': | |
| 168 | + req.tracking_info = tracking_info | |
| 169 | + req.tracking_signed = is_tracking_signed | |
| 170 | + else: | |
| 171 | + req.back_tracking_info = tracking_info | |
| 172 | + req.back_tracking_signed = is_tracking_signed | |
| 173 | + req.save() | |
| 174 | + | |
| 175 | + | |
| 176 | +def tenancy_tracking_info_subscribe(req, type_): | |
| 177 | +    callbackurl = '{}/api/tenancy/tracking/info/callback?reqpk={}&type={}'.format(settings.DOMAIN, req.pk, type_) | |
| 178 | + if type_ == 'tracking': | |
| 179 | + express_com = req.express_com | |
| 180 | + tracking_number = req.tracking_number | |
| 181 | + phone = req.phone | |
| 182 | + else: | |
| 183 | + express_com = req.back_express_com | |
| 184 | + tracking_number = req.back_tracking_number | |
| 185 | + phone = req.phone | |
| 186 | + return KuaiDi100Subscribe().submit(express_com, tracking_number, phone=phone, callbackurl=callbackurl) | |
| 187 | + | |
| 188 | + | |
| 189 | +@logit(body=True) | |
| 190 | +@transaction.atomic | |
| 191 | +def tenancy_tracking_info_callback(request): | |
| 192 | +    reqpk = request.GET.get('reqpk', '') | |
| 193 | +    type_ = request.GET.get('type', 'tracking')  # tracking / back_tracking | |
| 194 | + | |
| 195 | +    param = request.POST.get('param', '') | |
| 196 | + | |
| 197 | + if not param: | |
| 198 | + return response(message='Not Param') | |
| 199 | + | |
| 200 | + try: | |
| 201 | + callback_json = json.loads(param) | |
| 202 | + except Exception: | |
| 203 | + return response(message='JSON Loads Error') | |
| 204 | + | |
| 205 | +    tracking_info = callback_json.get('lastResult', {}) | |
| 206 | + | |
| 207 | + if not tracking_info: | |
| 208 | + return response(message='Not Tracking Info') | |
| 209 | + | |
| 210 | + try: | |
| 211 | + req = TenancyShotRequestInfo.objects.select_for_update().get(pk=reqpk, status=True) | |
| 212 | + except TenancyShotRequestInfo.DoesNotExist: | |
| 213 | + return response(TenancyStatusCode.TENANCY_SHOT_REQUEST_NOT_FOUND) | |
| 214 | + | |
| 215 | + tenancy_tracking_info_update(req, type_, tracking_info) | |
| 216 | + | |
| 217 | +    return JsonResponse({ | |
| 218 | + 'result': True, | |
| 219 | + 'returnCode': '200', | |
| 220 | + 'message': '成功' | |
| 221 | + }, safe=False) | 
| @@ -356,6 +356,7 @@ urlpatterns += [ | ||
| 356 | 356 | url(r'^admin/tenancy/shot/request/signed$', tenancy_admin_views.shot_request_signed, name='admin_tenancy_shot_request_signed'), | 
| 357 | 357 |  | 
| 358 | 358 | # 快递信息回调接口 | 
| 359 | + url(r'^tenancy/tracking/info/callback$', tenancy_views.tenancy_tracking_info_callback, name='tenancy_tracking_info_callback'), | |
| 359 | 360 | ] | 
| 360 | 361 |  | 
| 361 | 362 | # 腾讯云 | 
| @@ -52,6 +52,11 @@ class TenancyShotInfo(BaseModelMixin): | ||
| 52 | 52 |  | 
| 53 | 53 |  | 
| 54 | 54 | class TenancyShotRequestInfo(BaseModelMixin): | 
| 55 | + TRACKING_TO_DESPATCH = u'寄出' | |
| 56 | + TRACKING_SIGNED_FIXING = u'寄出已签收' | |
| 57 | + TRACKING_FIXED_BACK = u'寄回' | |
| 58 | + TRACKING_BACK_SIGNED = u'寄回已签收并检查无损坏' | |
| 59 | + | |
| 55 | 60 | AUDIT_PASS = 1 | 
| 56 | 61 | AUDIT_STATUS = ( | 
| 57 | 62 | (0, u'未审批'), | 
| @@ -21,6 +21,7 @@ class KuaiDi100: | ||
| 21 | 21 | :param ship_to: 目的地城市,省-市-区,非必填,填了有助于提升签收状态的判断的准确率,且到达目的地后会加大监控频率,请尽量提供 | 
| 22 | 22 | :return: requests.Response.text | 
| 23 | 23 | """ | 
| 24 | + autoCom = '0' if com else '1' | |
| 24 | 25 |          param = { | 
| 25 | 26 | 'company': com, | 
| 26 | 27 | 'number': num, | 
| @@ -32,7 +33,7 @@ class KuaiDi100: | ||
| 32 | 33 | # 'callbackurl': 'https://www.baidu.com/kd100/callback', # 回调接口的地址。如果需要在推送信息回传自己业务参数,可以在回调地址URL后面拼接上去,例如:https://www.baidu.com/kd100/callback?orderId=123 | 
| 33 | 34 | 'salt': None, # 签名用随机字符串。32位自定义字符串。添加该参数,则推送的时候会增加sign给贵司校验消息的可靠性 | 
| 34 | 35 | 'resultv2': '1', # 添加此字段表示开通行政区域解析功能。0:关闭(默认),1:开通行政区域解析功能 | 
| 35 | - 'autoCom': '0', # 添加此字段且将此值设为1,则表示开始智能判断单号所属公司的功能,开启后,company字段可为空,即只传运单号(number字段),我方收到后会根据单号判断出其所属的快递公司(即company字段)。建议只有在无法知道单号对应的快递公司(即company的值)的情况下才开启此功能 | |
| 36 | + 'autoCom': autoCom, # 添加此字段且将此值设为1,则表示开始智能判断单号所属公司的功能,开启后,company字段可为空,即只传运单号(number字段),我方收到后会根据单号判断出其所属的快递公司(即company字段)。建议只有在无法知道单号对应的快递公司(即company的值)的情况下才开启此功能 | |
| 36 | 37 | 'interCom': '0', # 添加此字段且将此值设为1,则表示开启国际版,开启后,若订阅的单号(即number字段)属于国际单号,会返回出发国与目的国两个国家的跟踪信息,本功能暂时只支持邮政体系(国际类的邮政小包、EMS)内的快递公司,若单号我方识别为非国际单,即使添加本字段,也不会返回destResult元素组 | 
| 37 | 38 | 'departureCountry': '', # 出发国家编码,interCom=1的国际单号最好提供该值 | 
| 38 | 39 | 'departureCom': '', # 出发国家快递公司的编码,interCom=1的国际单号最好提供该值 |