odoo13中的个性化导入

目录

1.建立个性化导入的临时模型

2.个性化导入的临时模型的xml视图

 3.下载导入模板的逻辑

4. 导入的功能


1.建立个性化导入的临时模型

from odoo import models, fields, api


class NameImport(models.TransientModel):
    _name = 'name.import'    # 临时模型名名称,一般 项目简称.功能.import
    _description = '临时模型的导入功能的具体描述'

    # 导入的文件
    inventory_file = fields.Binary(string="选择模板", help="File Import")
    # 导入文件的名称
    inventory_file_name = fields.Char(string="导入文件的名称")

2.个性化导入的临时模型的xml视图

<?xml version="1.0" encoding="utf-8" ?>
<odoo>
    <data>
        <record id="name_import_form" model="ir.ui.view">
            <field name="name">个性化导入form视图</field>
            <field name="model">个性化导入的临时模型的名称</field>
            <field name="arch" type="xml">
                <form>
                    <button name="download_import_temp" string="下载导入模板" type="object" class="oe_link"/>
                    <group>
                        <field name="inventory_file" filename="inventory_file_name"/>
                        <field name="inventory_file_name" invisible="1"/>
                    </group>
                    <footer>
                        <button name="import_confirm" string="确定" type="object" class="oe_highlight"/>
                        <button string="取消" class="oe_link" special="cancel"/>
                    </footer>
                </form>
            </field>
        </record>

        <act_window id="name_import_action"
            name="导入"
            res_model="个性化导入的临时模型的名称"
            binding_model="导入按钮绑定到那个模型上,即给那个模型创建个性化导入功能"
            view_mode="form"
            view_id="name_import_form"
            target="new"
            context="{'on_tree': '2', 'btn_class': 'btn-secondary'}"/>

        <report id="name_import_temp_xlsx"
                model="个性化导入的临时模型的名称"
                string="个性化的导入的下载模板时的名称"
                report_type="xlsx"
                name="个性化导入的下载模板时,对应的xlxs模型逻辑的模型名,取report.后面的所有值"
                file="个性化的导入的下载模板时的名称"
                attachment_use="False"
        />
    </data>
</odoo>

效果:

 3.下载导入模板的逻辑

在个性化导入的临时模型中添加该方法,

注意:  函数名是对应的xml中下载导入模板按钮的name的值

report_name的取值是下方的,xlsx的模型的report.后面的值

# 下载导入模板
def download_import_temp(self):
    return {
        'type': 'ir.actions.report',
        'report_name': 'report.后面的值',
        'report_type': 'xlsx'
}

 对应的下载导入模板的模型类

下方的逻辑为示例

需注意的:

        row1一般是示例标题,就是表头

        row2一般是示例的第一行数据

设置好格式和样式直接写入即可

class InsuranceImportTempXlsx(models.AbstractModel):
    _name = 'report.模块名.功能_import_temp_xlsx'
    _inherit = 'report.report_xlsx.abstract'
    _description = '下载xx导入模板'    # 描述

    def dict_union(self, dict1, dict2):
        """
        :return:
        """
        return {**dict1, **dict2}

    def generate_xlsx_report(self, wb, data, objs):
        # 要写入excel模板的数据
        row1 = ['*公司', '*员工', '*员工编号', '*养老单位缴纳基数', '*养老单位缴纳金额', '*失业单位缴纳基数', '*失业单位缴纳金额',
                '*医疗单位缴纳基数', '*医疗单位缴纳金额', '*工伤单位缴纳基数', '*工伤单位缴纳金额', '*生育单位缴纳基数',
                '*生育单位缴纳金额', '*单位补充医保缴费基数', '*单位补充医保缴费金额', '*单位职业年金缴费基数', '*单位职业年金缴费金额',
                '*个人所有保险缴费金额', '*住房公积金单位缴纳基数', '*住房公积金单位缴纳金额', '*住房公积金个人缴纳金额']
        row2 = ['山东省肿瘤医院', '[H0001]1', 'H0001', '0', '0.00', '0', '0.00', '0', '0.00', '0', '0.00', '0', '0.00', '0',
                '0.00', '0', '0.00', '0.00', '0', '0.00', '0.00', '导入时请勿删除示例!!!']
        # format
        ten_font_style = {
            'font_name': u'微软雅黑',
            'font_size': 10,
            'valign': 'vcenter',
            'align': 'center',
            'text_wrap': True
        }
        bold_style = wb.add_format(self.dict_union(ten_font_style, {'bold': True}))
        green_bold_style = wb.add_format(self.dict_union(ten_font_style, {'bold': True, 'font_color': 'green'}))
        red_style = wb.add_format(self.dict_union(ten_font_style, {'font_color': 'red'}))
        # blue_style = wb.add_format(self.dict_union(ten_font_style, {'font_color': 'blue'}))
        ws = wb.add_worksheet('五险一金导入模板')
        ws.set_column(0, 0, 19.5)
        ws.set_column(1, 2, 8.5)
        ws.set_column(3, 21, 30)
        row_pos = 0
        ws.set_row(row_pos, 23)
        for index, value in enumerate(row1):
            if index < 3:
                ws.write(row_pos, index, value, bold_style)
            elif index < 21:
                ws.write(row_pos, index, value, green_bold_style)
            else:
                ws.write(row_pos, index, value, red_style)
        row_pos += 1
        ws.set_row(row_pos, 15)
        for index, value in enumerate(row2):
            ws.write(row_pos, index, value, red_style)

4. 导入的功能

在个性化导入的临时模型中写入

  • import_confirm也是对应xml中按钮的名称,这个函数的功能是建立后台任务,让后台任务去进行导入
  • import_confirm中的method的对应的方法就是具体的读取并写入系统的逻辑,
  • 注意的是,读取的时候,第一行和第二行为标题和示例数据需要跳过,从第三行开始读取即可,
# 薪酬数据导入
    def import_confirm(self):
        now_datetime = fields.Datetime.to_string(fields.Datetime.context_timestamp(self, fields.Datetime.now()))
        # 导入对象
        objs = ['sdszl.hr.insurance']
        self.env['ir.actuator.user.list'].sudo().create({
            'name': '五险一金导入程序',
            'description': f"导入对象:{objs}-{now_datetime}",
            'model_name': 'sdszl.hr.insurance.import',
            'method': 'write_to_model',
            'method_args': [self.id, objs],
        }).run_actuator()
        return {
            'type': 'ir.actions.act_multi',
            'actions': [
                {'type': 'ir.actions.act_window_close'},
                {
                    'type': 'ir.actions.act_window.message',
                    'title': '信息',
                    'message': "已提交请求,可在用户任务中查看请求状态",
                }
            ]
        }

    def write_to_model(self, objs):
        if not self.inventory_file:
            raise ValidationError('未上传文件')
        # 对传入的文件进行base64解码,然后调用open_workbook对文件进行解析
        book = xlrd.open_workbook(file_contents=base64.b64decode(self.inventory_file))
        # 读入第一个sheet页
        sh = book.sheet_by_index(0)
        insurance_obj = self.env['sdszl.hr.insurance']
        insurance_data = []
        # 开始处理数据行,跳过标题行和示例行,从第三行开始
        error_list = []
        row_num = 2
        for rx in range(2, sh.nrows):
            row_num += 1
            row = sh.row_values(rx)
            row_error = []
            company_name = row[0]
            company = self.env['res.company'].search([('name', '=', company_name)], limit=1)
            if not company:
                row_error.append(f'第{row_num}行,找不到公司{company_name}!')
            employee_code = row[2]
            employee = self.env['eno.employee'].search([
                ('company_id.name', '=', company_name), ('code', '=', employee_code)], limit=1)
            if not employee:
                row_error.append(f'找不到公司为 {company_name},编号为 {employee_code}的员工!')
            if not row_error:
                old_data = insurance_obj.search([('company_id.name', '=', company_name), ('employee_code', '=', employee_code)], limit=1)
                if old_data:
                    old_data.update({
                        'yl_payment_base': row[3],
                        'yl_payment_proportion': row[4],
                        'sy_payment_base': row[5],
                        'sy_payment_proportion': row[6],
                        'yli_payment_base': row[7],
                        'yli_payment_proportion': row[8],
                        'gs_payment_base': row[9],
                        'gs_payment_proportion': row[10],
                        'syu_payment_base': row[11],
                        'syu_payment_proportion': row[12],
                        'bq_payment_base': row[13],
                        'bq_payment_proportion': row[14],
                        'zy_payment_base': row[15],
                        'zy_payment_proportion': row[16],
                        'gr_payment_proportion': row[17],
                        'gjj_payment_base': row[18],
                        'gjj_payment_proportion_1': row[19],
                        'gjj_payment_proportion_2': row[20],
                    })
                else:
                    insurance_data.append({
                        'company_id': company.id,
                        'employee_id': employee.id,
                        'yl_payment_base': row[3],
                        'yl_payment_proportion': row[4],
                        'sy_payment_base': row[5],
                        'sy_payment_proportion': row[6],
                        'yli_payment_base': row[7],
                        'yli_payment_proportion': row[8],
                        'gs_payment_base': row[9],
                        'gs_payment_proportion': row[10],
                        'syu_payment_base': row[11],
                        'syu_payment_proportion': row[12],
                        'bq_payment_base': row[13],
                        'bq_payment_proportion': row[14],
                        'zy_payment_base': row[15],
                        'zy_payment_proportion': row[16],
                        'gr_payment_proportion': row[17],
                        'gjj_payment_base': row[18],
                        'gjj_payment_proportion_1': row[19],
                        'gjj_payment_proportion_2': row[20],
                    })
            else:
                errors = '\n'.join(row_error)
                error_list.append(f"第{row_num}行:\n{errors}")
        if error_list:
            raise ValidationError('\n'.join(error_list))
        else:
            insurance_obj.create(insurance_data)

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

还是那个同伟伟

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值