osbzr/gooderp_addons

View on GitHub
warehouse_wave/models/express_menu.py

Summary

Maintainability
A
1 hr
Test Coverage
# -*- coding: utf-8 -*-

from odoo import models, fields, api
import hashlib
import base64
import json
import urllib
import urllib2
from odoo.tools.safe_eval import safe_eval
from odoo.exceptions import UserError


class ExpressMenuConfig(models.Model):
    """
    快递面单设置 目前只支持 下面这几个快递
    EMS 顺丰 圆通 百世 中通 韵达 申通 德邦 宅急送 京东 信丰 全峰 跨越速运 安能 快捷 天天 国通 优速
    """
    _name = 'express.menu.config'
    name = fields.Char(u'快递公司名称', required=True)
    abbreviation = fields.Char(u'简称', required=True)
    customername = fields.Char(u'客户名称')
    customerpwd = fields.Char(u'客户密码')
    monthcode = fields.Char(u'月结号')
    sendsite = fields.Char(u'发送站点')
    logisticcode = fields.Char(u'快递单号')


class Warehouse(models.Model):
    _name = 'warehouse'
    _inherit = ['warehouse', 'state.city.county']
    detail_address = fields.Char(u'详细地址')
    principal_id = fields.Many2one('staff', u'负责人')


class WhMove(models.Model):
    """
    生成快递电子面单
    """
    _name = 'wh.move'
    _inherit = ['wh.move', 'state.city.county']
    express_menu = fields.Text(u'快递面单', copy=False)

    def get_shipping_type_config(self, menu_type):
        """
        根据传入的快递方式返回相应的参数
        """
        express_menu = self.env['express.menu.config'].search(
            [('abbreviation', '=', menu_type)])
        if not express_menu:
            raise UserError(u"单据%s,承运商暂不支持 或者承运商商户简称输入错误(%s)" %
                            (self.name, menu_type))
        shipping_type_config = dict(ShipperCode=menu_type,
                                    CustomerName=express_menu.customername or '',
                                    CustomerPwd=express_menu.customerpwd or '',
                                    MonthCode=express_menu.monthcode or '',
                                    SendSite=express_menu.sendsite or '',
                                    )
        return shipping_type_config

    def get_sender(self, ware_hosue_row, pakge_sequence):
        add_info = self.wave_id and ('(' + pakge_sequence + ')' + self.wave_id.name) or ''

        sender = dict(Company=ware_hosue_row.company_id.name,
                      Name=ware_hosue_row.principal_id.name or ware_hosue_row.company_id.name or '',
                      Mobile=ware_hosue_row.principal_id.work_phone or ware_hosue_row.company_id.phone,
                      ProvinceName=ware_hosue_row.province_id.name or u'上海',
                      CityName=ware_hosue_row.city_id.city_name or u'上海',
                      ExpAreaName=ware_hosue_row.county_id.county_name or u'浦东新区',
                      Address=((ware_hosue_row.detail_address or u'金海路2588号B-213') + add_info))
        return sender

    def get_receiver_goods_message(self):
        # TODO: 要发货的详细地址字段 (有疑问)
        ORIGIN_EXPLAIN = {
            'wh.internal': 'wh.internal',
            'wh.out.others': 'wh.out',
            'buy.receipt.return': 'buy.receipt',
            'sell.delivery.sell': 'sell.delivery',
        }
        if ORIGIN_EXPLAIN.get(self.origin):
            model_row = self.env[ORIGIN_EXPLAIN.get(self.origin)
                                 ].search([('sell_move_id', '=', self.id)])
        detail_address = model_row.address_id.detail_address
        if detail_address:
            first_index = -1
            if u'区' in detail_address:
                first_index = detail_address.find(u'区')
            if u'县' in detail_address:
                first_index = detail_address.find(u'县')
            # 处理县级市
            if u'市' in detail_address and (u'区' not in detail_address or u'县' not in detail_address):
                first_index = detail_address.find(u'市')
            # 处理 内蒙 盟
            if u'内蒙古' in detail_address and u'盟' in detail_address:
                first_index = detail_address.find(u'盟')
            detail_address = detail_address[first_index+1:]
        receiver = dict(Company=' ',
                        Name=model_row.partner_id.name,
                        Mobile=model_row.address_id.mobile,
                        ProvinceName=model_row.address_id.province_id.name or model_row.address_id.city_id.city_name or u'()',
                        CityName=model_row.address_id.city_id.city_name or u' ',
                        ExpAreaName=model_row.address_id.county_id.county_name or u' ',
                        Address=detail_address or u' ')

        goods = []
        qty = 0
        for line in self.line_out_ids:
            goods.append(dict(GoodsName=line.goods_id.code,  # 产品编号
                              Goodsquantity=int(line.goods_qty),  # 产品数量
                              GoodsWeight=1.0,  # 产品重量
                              GoodsCode=line.goods_id.code or '',  # 产品编码
                              GoodsPrice=0.0,  # 产品价格
                              ))
            qty += 1
        return receiver, goods, qty

    @api.model
    def get_express_menu(self):
        expressconfigparam = self.env['ir.config_parameter']
        appid = expressconfigparam.get_param('express_menu_app_id', default='')
        appkey = expressconfigparam.get_param(
            'express_menu_app_key', default='')
        path = expressconfigparam.get_param(
            'express_menu_oder_url', default='')
        header = safe_eval(expressconfigparam.get_param('express_menu_request_headers',
                                                        default=''))
        order_code = self.name
        sender = self.get_sender(self.warehouse_id, self.pakge_sequence)
        remark = self.note or '小心轻放'
        shipping_type = self.express_type or 'YTO'
        custom_area = self.note or '小心轻放'
        receiver, commodity, qty = self.get_receiver_goods_message()
        request_data = dict(OrderCode=order_code, PayType=3, ExpType=1, Cost=1.0, OtherCost=1.0,
                            Sender=sender, Receiver=receiver, Commodity=commodity, Weight=1.0,
                            Quantity=1, Volume=0.0, Remark=remark, IsReturnPrintTemplate=1)
        request_data.update(self.get_shipping_type_config(shipping_type))
        if shipping_type == 'YTO':
            request_data.update({'TemplateSize': 180, 'CustomArea': custom_area})
        request_data = json.dumps(request_data)
        data = {'RequestData': request_data,
                'EBusinessID': appid,
                'RequestType': '1007',
                'DataType': '2',
                'DataSign': self.encrypt_kdn(request_data, appkey)}
        req = urllib2.Request(path, urllib.urlencode(data), header)
        resp = urllib2.urlopen(req).read()
        content = json.loads(resp)
        self.express_code = (content.get(
            'Order', {})).get('LogisticCode', "")
        self.express_menu = content.get('PrintTemplate')
        if not self.express_code:
            raise UserError("获取快递面单失败!\n原因:%s %s" % (str(resp),
                                        str(request_data)))

        return self.express_menu

    def encrypt_kdn(self, data, appkey):
        """
        数据加密
        """
        key = base64.b64encode(hashlib.md5(
            "%s%s" % (data, appkey)).hexdigest(), altchars=None)
        return urllib.quote(key, safe='/')

    @api.model
    def get_package_list_data(self, move_row):
        # 装箱单明细行数据
        line_dict = []
        total_price = 0
        for line in move_row.line_out_ids:
            # code, name, goods_qty
            line_dict.append([line.goods_id.code,
                              line.goods_id.name,
                              line.goods_qty])

        # 装箱单数据
        package_list = {'0 拣货单号': [move_row.wave_id.name],
                        '1 内部订单号': [move_row.name],
                        '2 店铺名称': [move_row.company_id.name],
                        '3 外部订单号': [move_row.ref],
                        '4 收货人': [move_row.partner_id.name],
                        '5 订单日期': [move_row.date],
                        '6 格子号': [move_row.pakge_sequence],
                        '7 lines': line_dict,
                        '8 总件数': [move_row.total_qty],
                        }
        return package_list

    @api.model
    def get_moves_html(self, move_ids):
        ''' 打印快递面单+装箱单 '''
        move_rows = self.browse(move_ids)
        return_html_list = []
        for move_row in move_rows.sorted(key=lambda x: int(x.pakge_sequence)):
            if move_row.express_code:
                return_html_list.append(move_row.express_menu)
            else:
                return_html_list.append(move_row.get_express_menu())

            # 添加装箱单数据
            return_html_list.append(self.get_package_list_data(move_row))

        return return_html_list

    @api.model
    def get_moves_html_package(self, move_ids):
        ''' 打印装箱单 '''
        move_rows = self.browse(move_ids)
        return_html_list = []
        for move_row in move_rows.sorted(key=lambda x: int(x.pakge_sequence)):
            return_html_list.append(self.get_package_list_data(move_row))

        return return_html_list