osbzr/gooderp_addons

View on GitHub
auto_exchange/models/auto_exchange.py

Summary

Maintainability
A
1 hr
Test Coverage
# -*- coding: utf-8 -*-
##############################################################################
#
#    OpenERP, Open Source Management Solution
#    Copyright (C) 2016  开阖软件(<http://www.osbzr.com>).
#
#    This program is free software: you can redistribute it and/or modify
#    it under the terms of the GNU Affero General Public License as
#    published by the Free Software Foundation, either version 3 of the
#    License, or (at your option) any later version.
#
#    This program is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU Affero General Public License for more details.
#
#    You should have received a copy of the GNU Affero General Public License
#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################

from odoo import api, fields, models, tools, _
from odoo.exceptions import UserError
import urllib
import httplib2
import re
from lxml import etree


currency_code = {'GBP': '1314',
                 'HKD': '1315',
                 'USD': '1316',
                 'DEM': '1318',
                 'CHF': '1319',
                 'SGD': '1375',
                 'SKr': '1320',
                 'DKr': '1321',
                 'NKr': '1322',
                 'JPY': '1323',
                 'CAD': '1324',
                 'AUD': '1325',
                 'EUR': '1326',
                 'PHP': '1328',
                 'NZD': '1330',
                 'KRW': '1331',
                 'RBL': '1843',
                 'MYR': '2890',
                 'NTD': '2895',
                 'ESP': '1370',
                 'ITL': '1371',
                 'NLG': '1372',
                 'BEF': '1373',
                 'FIM': '1374',
                 'IDR': '3030',
                 'BRL': '3253', }


class Currency(models.Model):
    _inherit = 'res.currency'

    month_exchange = fields.One2many(
        'auto.exchange.line', 'currency_id', u'期间汇率', copy=False)

    @api.multi
    def get_web_exchange(self, line_date):
        '''用爬虫的方法取得中国银行汇率'''
        http = httplib2.Http()
        if self.name not in currency_code:
            raise UserError(u'中国银行找不到您的(%s)币别汇率' % self.name)
        url = 'http://srh.bankofchina.com/search/whpj/search.jsp'
        body = {
            'erectDate': line_date,
            'nothing': line_date,
            'pjname': currency_code[self.name]
        }
        headers = {
            'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.6 Safari/537.36',
            'Content-type': 'application/x-www-form-urlencoded'
        }
        try:
            response, content = http.request(
                url, 'POST', headers=headers, body=urllib.urlencode(body))
            result = etree.HTML(content.decode('utf8')).xpath(
                '//table[@cellpadding="0"]/tr[4]/td/text()')
        except httplib2.HttpLib2Error:  # pragma: no cover
            raise UserError(u'网页设置有误(%s)请联系作者:(qq:2201864)' % url)
        return result[5]

    @api.multi
    def get_exchange(self):
        '''当设置自动运行时,传来的self为空值,需要补全所需自动运行的那几个ids'''
        if not self:
            currency_ids = self.env['res.currency'].search(
                [('active', '=', True)])
        else:
            currency_ids = self
        for currency in currency_ids:
            for line in currency.month_exchange:
                '''判断当前日期能不能取到汇率,如发现已有汇率则不重复取,取得的为100人民币汇率,需要/100'''
                self = currency
                if line.date <= fields.Date.context_today(self) and not line.exchange:
                    line_date = line.date
                    line.exchange = float(
                        self.get_web_exchange(line_date)) / 100
                    line.note = u'系统于(%s)从中国银行网站上取得' % fields.Date.context_today(
                        self)

    '''取汇率函数,如果要给定日期,需要在context里增加date'''
    @api.multi
    def _compute_current_rate(self):
        date = self._context.get('date') or fields.Datetime.now()
        period_id = self.env['finance.period'].get_period(date).id
        for currency in self:
            currency.rate = 1.0
            for line in currency.month_exchange:
                if period_id == line.period_id.id:
                    currency.rate = line.exchange or 1.0


class AutoExchangeLine(models.Model):
    _name = 'auto.exchange.line'
    _description = u'自动汇率明细行'

    @api.one
    @api.depends('date')
    def _compute_period_id(self):
        self.period_id = self.env['finance.period'].get_period(self.date)

    date = fields.Date(u'抓取日期',
                       index=True, copy=False, help=u"应为每个月的第一个工作日")
    period_id = fields.Many2one(
        'finance.period',
        u'会计期间',
        compute='_compute_period_id', ondelete='restrict', store=True)
    exchange = fields.Float(u'外管局中间价', digits=(12, 4),
                            help=u'取得的汇率')
    note = fields.Char(u'备注',
                       help=u'本行备注')
    currency_id = fields.Many2one('res.currency', u'币别', index=True,
                                  required=True, ondelete='cascade',
                                  help=u'关联订单的编号')
    company_id = fields.Many2one(
        'res.company',
        string=u'公司',
        change_default=True,
        default=lambda self: self.env['res.company']._company_default_get())

    _sql_constraints = [
        ('unique_start_date', 'unique (currency_id,period_id)', u'同币别期间不能重合!'),
    ]


class CurrencyMoneyOrder(models.Model):
    _inherit = 'money.order'

    @api.multi
    def get_rate_silent(self, date, currency_id):
        currency = self.env['res.currency'].search([('id', '=', currency_id)])
        period_id = self.env['finance.period'].get_period(date)
        for line in currency.month_exchange:
            if period_id == line.period_id:
                rate = line.exchange
        if not rate:
            raise UserError(u'没有设置会计期间内的外币%s汇率' % currency.name)

        return rate