|  | # -*- coding: utf-8 -*-
from __future__ import division
import json
from django.conf import settings
from django.db.models.query_utils import Q
from django_logit import logit
from django_response import response
from paginator import pagination
from TimeConvert import TimeConvert as tc
from account.models import UserInfo
from maintenance.models import ExpressCompanyInfo, MaintenaceInfo
from mch.models import ModelInfo
from pre.custom_message import sendtemplatemessage
from utils.admin_utils import is_admin, is_maintenanceman
from utils.error.errno_utils import MaintenanceStatusCode
from utils.kuaidi.subscribe import KuaiDi100 as KuaiDi100Subscribe
from utils.kuaidi.synquery import KuaiDi100
WECHAT = settings.WECHAT
@logit
def maintenance_add(request):
    user_id = request.POST.get('user_id', '')
    name = request.POST.get('name', '')
    phone = request.POST.get('phone', '')
    address = request.POST.get('address', '')
    model_id = request.POST.get('model_id', '')
    log_id = request.POST.get('log_id', '')
    sn = request.POST.get('sn', '')
    desc = request.POST.get('desc', '')
    point_id = request.POST.get('point_id', '')
    point_name = request.POST.get('point_name', '')
    express_name = request.POST.get('express_name', '')
    tracking_number = request.POST.get('tracking_number', '')
    maintenance_status = request.POST.get('maintenance_status', MaintenaceInfo.TRACKING_TO_DESPATCH)
    try:
        company = ExpressCompanyInfo.objects.get(name=express_name, status=True)
    except ExpressCompanyInfo.DoesNotExist:
        company = None
    maintenance = MaintenaceInfo.objects.create(
        user_id=user_id,
        name=name,
        phone=phone,
        address=address,
        model_id=model_id,
        log_id=log_id,
        sn=sn,
        desc=desc,
        point_id=point_id,
        point_name=point_name,
        express_name=express_name,
        express_com=company.com if company else '',
        tracking_number=tracking_number,
        maintenance_status=maintenance_status,
        maintenance_status_at={maintenance_status: tc.utc_datetime()}
    )
    maintenance_tracking_info_subscribe(maintenance, 'tracking')
    return response(data={
        'maintenance_id': maintenance.id,
    })
@logit
def maintenance_delete(request):
    brand_id = request.POST.get('brand_id', settings.KODO_DEFAULT_BRAND_ID)
    maintenance_id = request.POST.get('maintenance_id', '')
    user_id = request.POST.get('user_id', '')
    try:
        maintenance = MaintenaceInfo.objects.get(id=maintenance_id, status=True)
    except MaintenaceInfo.DoesNotExist:
        return response(MaintenanceStatusCode.MAINTENACE_NOT_FOUND)
    if user_id != maintenance.user_id and not is_maintenanceman(brand_id, user_id):
        return response(MaintenanceStatusCode.MAINTENACE_PERMISSION_DENIED)
    maintenance.status = False
    maintenance.save()
    return response()
@logit
def maintenance_update(request):
    brand_id = request.POST.get('brand_id', settings.KODO_DEFAULT_BRAND_ID)
    maintenance_id = request.POST.get('maintenance_id', '')
    admin_id = request.POST.get('admin_id', '')
    user_id = request.POST.get('user_id', '')
    name = request.POST.get('name', '')
    phone = request.POST.get('phone', '')
    address = request.POST.get('address', '')
    model_id = request.POST.get('model_id', '')
    log_id = request.POST.get('log_id', '')
    sn = request.POST.get('sn', '')
    desc = request.POST.get('desc', '')
    point_id = request.POST.get('point_id', '')
    point_name = request.POST.get('point_name', '')
    express_name = request.POST.get('express_name', '')
    tracking_number = request.POST.get('tracking_number', '')
    back_express_name = request.POST.get('back_express_name', '')
    back_tracking_number = request.POST.get('back_tracking_number', '')
    try:
        maintenance = MaintenaceInfo.objects.get(id=maintenance_id, status=True)
    except MaintenaceInfo.DoesNotExist:
        return response(MaintenanceStatusCode.MAINTENACE_NOT_FOUND)
    if user_id != maintenance.user_id and not is_admin(brand_id, admin_id):
        return response(MaintenanceStatusCode.MAINTENACE_PERMISSION_DENIED)
    old_tracking_number = maintenance.tracking_number
    old_back_tracking_number = maintenance.back_tracking_number
    # 新增 `back_tracking_number` 之后,更新维修状态
    if not old_back_tracking_number and back_tracking_number:
        maintenance.maintenance_status = MaintenaceInfo.TRACKING_FIXED_BACK
        maintenance_status_at = maintenance.maintenance_status_at
        maintenance_status_at[MaintenaceInfo.TRACKING_FIXED_BACK] = tc.utc_datetime()
        maintenance.maintenance_status_at = maintenance.maintenance_status_at
        maintenance_status_update_sendtemplatemessage(maintenance)
    if name:
        maintenance.name = name
    if phone:
        maintenance.phone = phone
    if address:
        maintenance.address = address
    if log_id:
        maintenance.log_id = log_id
    if model_id:
        maintenance.model_id = model_id
    if sn:
        maintenance.sn = sn
    if desc:
        maintenance.desc = desc
    if point_id:
        maintenance.point_id = point_id
    if point_name:
        maintenance.point_name = point_name
    if express_name:
        try:
            company = ExpressCompanyInfo.objects.get(name=express_name, status=True)
        except ExpressCompanyInfo.DoesNotExist:
            company = None
        maintenance.express_name = express_name
        maintenance.express_com = company.com if company else ''
    if tracking_number:
        maintenance.tracking_number = tracking_number
    if back_express_name:
        try:
            company = ExpressCompanyInfo.objects.get(name=back_express_name, status=True)
        except ExpressCompanyInfo.DoesNotExist:
            company = None
        maintenance.back_express_name = back_express_name
        maintenance.back_express_com = company.com if company else ''
    if back_tracking_number:
        maintenance.back_tracking_number = back_tracking_number
    maintenance.save()
    if tracking_number and tracking_number != old_tracking_number:
        maintenance_tracking_info_subscribe(maintenance, 'tracking')
    if back_tracking_number and back_tracking_number != old_back_tracking_number:
        maintenance_tracking_info_subscribe(maintenance, 'back_tracking')
    return response()
@logit
def maintenance_list(request):
    brand_id = request.POST.get('brand_id', settings.KODO_DEFAULT_BRAND_ID)
    admin_id = request.POST.get('admin_id', '')
    user_id = request.POST.get('user_id', '')
    page = request.POST.get('page', 1)
    num = request.POST.get('num', 20)
    maintenance_status = request.POST.get('maintenance_status', 'all')
    query = request.POST.get('query', '')
    start_time = request.POST.get('start_time', '')
    end_time = request.POST.get('end_time', '')
    point_id = request.POST.get('point_id', '')
    maintenances = MaintenaceInfo.objects.filter(status=True)
    if not is_admin(brand_id, admin_id):
        maintenances = maintenances.filter(user_id=user_id)
    if maintenance_status and maintenance_status != 'all':
        maintenances = maintenances.filter(maintenance_status=maintenance_status)
    if query:
        maintenances = maintenances.filter(Q(phone=query) | Q(name__icontains=query) | Q(sn=query))
    if start_time and end_time:
        start_time = tc.string_to_utc_datetime(start_time, format='%Y%m%d')
        end_time = tc.string_to_utc_datetime(end_time + ' 23:59:59', format='%Y%m%d %H:%M:%S')
        maintenances = maintenances.filter(created_at__range=(start_time, end_time))
    if point_id:
        maintenances = maintenances.filter(point_id=point_id)
    count = maintenances.count()
    maintenances = maintenances.order_by('-pk')
    maintenances = [maintenance.data for maintenance in maintenances]
    maintenances, left = pagination(maintenances, page, num)
    return response(data={
        'maintenaces': maintenances,
        'count': count,
        'left': left,
    })
@logit
def maintenance_detail(request):
    maintenance_id = request.POST.get('maintenance_id', '')
    try:
        maintenance = MaintenaceInfo.objects.get(id=maintenance_id, status=True)
    except MaintenaceInfo.DoesNotExist:
        return response(MaintenanceStatusCode.MAINTENACE_NOT_FOUND)
    return response(data={
        'maintenace': maintenance.data,
    })
def maintenance_status_update_sendtemplatemessage(maintenance):
    try:
        user = UserInfo.objects.get(user_id=maintenance.user_id, status=True)
    except UserInfo.DoesNotExist:
        return
    model = ModelInfo.objects.get(model_id=maintenance.model_id)
    user = UserInfo.objects.get(user_id=maintenance.user_id)
    # Send template_message
    data = {
        "first": {
            "value": u'您的维修状态已更新',
            "color": "#173177"
        },
        "keyword1": {
            "value": model.model_name,
            "color": "#173177"
        },
        "keyword2": {
            "value": maintenance.sn,
            "color": "#173177"
        },
        "keyword3": {
            "value": maintenance.maintenance_status,
            "color": "#173177"
        },
        "remark": {
            "value": u'如您有任何其他疑问,可在腾龙公众号进行留言',
            "color": "#173177"
        }
    }
    wxcfg = WECHAT.get('MINIAPP', {})
    appid = wxcfg.get('appID')
    sendtemplatemessage(openid=user.openid, template_id=settings.TEMPLATE_ID_MAINTENANCE, data=data, miniappid=appid, minipagepath='/pages/index/index')
def is_maintenance_tracking_signed(tracking_info):
    if not tracking_info:
        return False
    items = tracking_info.get('data', [])
    if not items:
        return False
    return items[0].get('status') == u'签收'
def maintenance_tracking_info_update(maintenance, type_, tracking_info):
    old_maintenance_status = maintenance.maintenance_status
    is_tracking_signed = is_maintenance_tracking_signed(tracking_info)
    # 状态流转,TRACKING_TO_DESPATCH -> TRACKING_SIGNED_FIXING -> TRACKING_FIXED_BACK -> TRACKING_BACK_SIGNED
    # 需判断快递签收再更新维修状态
    maintenance_status = ''
    if type_ == 'tracking':
        maintenance.tracking_info = tracking_info
        maintenance.tracking_signed = is_tracking_signed
        if is_tracking_signed and old_maintenance_status == MaintenaceInfo.TRACKING_TO_DESPATCH:
            maintenance_status = MaintenaceInfo.TRACKING_SIGNED_FIXING
    else:
        maintenance.back_tracking_info = tracking_info
        maintenance.back_tracking_signed = is_tracking_signed
        if is_tracking_signed and old_maintenance_status == MaintenaceInfo.TRACKING_FIXED_BACK:
            maintenance_status = MaintenaceInfo.TRACKING_BACK_SIGNED
    if maintenance_status:
        maintenance.maintenance_status = maintenance_status
        maintenance_status_at = maintenance.maintenance_status_at
        if maintenance_status not in maintenance_status_at:
            maintenance_status_at[maintenance_status] = tc.utc_datetime()
        maintenance.maintenance_status_at = maintenance_status_at
    maintenance.save()
    if maintenance_status and maintenance_status != old_maintenance_status:
        maintenance_status_update_sendtemplatemessage(maintenance)
@logit
def maintenance_tracking_info(request):
    maintenance_id = request.POST.get('maintenance_id', '')
    type_ = request.POST.get('type', 'tracking')  # tracking / back_tracking
    try:
        maintenance = MaintenaceInfo.objects.get(id=maintenance_id, status=True)
    except MaintenaceInfo.DoesNotExist:
        return response(MaintenanceStatusCode.MAINTENACE_NOT_FOUND)
    tracking_info = {}
    if type_ == 'tracking':
        if maintenance.express_com and maintenance.tracking_number:
            tracking_info = KuaiDi100().track(maintenance.express_com, maintenance.tracking_number)
    else:
        if maintenance.back_express_com and maintenance.back_tracking_number:
            tracking_info = KuaiDi100().track(maintenance.back_express_com, maintenance.back_tracking_number)
    if tracking_info:
        try:
            tracking_info = json.loads(tracking_info)
        except Exception:
            tracking_info = {}
    if tracking_info:
        maintenance_tracking_info_update(maintenance, type_, tracking_info)
    return response(data={
        'type': type_,
        'tracking_info': tracking_info,
    })
def maintenance_tracking_info_subscribe(maintenance, type_):
    callbackurl = '{}/api/maintenance/tracking/info/callback?maintenance_id={}&type={}'.format(settings.DOMAIN, maintenance.pk, type_)
    if type_ == 'tracking':
        express_com = maintenance.express_com
        tracking_number = maintenance.tracking_number
        phone = maintenance.phone
    else:
        express_com = maintenance.back_express_com
        tracking_number = maintenance.back_tracking_number
        phone = maintenance.phone
    res = KuaiDi100Subscribe().submit(express_com, tracking_number, phone=phone, callbackurl=callbackurl)
@logit(body=True)
def maintenance_tracking_info_callback(request):
    maintenance_id = request.GET.get('maintenance_id', '')
    type_ = request.GET.get('type', 'tracking')  # tracking / back_tracking
    param = request.POST.get('param', '')
    if not param:
        return response(message='Not Param')
    try:
        callback_json = json.loads(param)
    except Exception:
        return response(message='JSON Loads Error')
    tracking_info = callback_json.get('lastResult', {})
    if not tracking_info:
        return response(message='Not Tracking Info')
    try:
        maintenance = MaintenaceInfo.objects.get(id=maintenance_id, status=True)
    except MaintenaceInfo.DoesNotExist:
        return response(MaintenanceStatusCode.MAINTENACE_NOT_FOUND)
    maintenance_tracking_info_update(maintenance, type_, tracking_info)
    return response()
@logit
def maintenance_close(request):
    brand_id = request.POST.get('brand_id', settings.KODO_DEFAULT_BRAND_ID)
    maintenance_id = request.POST.get('maintenance_id', '')
    admin_id = request.POST.get('admin_id', '')
    try:
        maintenance = MaintenaceInfo.objects.get(id=maintenance_id, status=True)
    except MaintenaceInfo.DoesNotExist:
        return response(MaintenanceStatusCode.MAINTENACE_NOT_FOUND)
    if not is_admin(brand_id, admin_id):
        return response(MaintenanceStatusCode.MAINTENACE_NOT_FOUND)
    maintenance.maintenance_status = MaintenaceInfo.TRACKING_BACK_SIGNED
    maintenance_status_at = maintenance.maintenance_status_at
    maintenance_status_at[MaintenaceInfo.TRACKING_BACK_SIGNED] = tc.utc_datetime()
    maintenance.maintenance_status_at = maintenance_status_at
    maintenance.save()
    return response()
 |