From efdde5aef0e37205b1515650ea00c8737eff634d Mon Sep 17 00:00:00 2001 From: mgw <1392924357@qq.com> Date: Tue, 20 Feb 2024 13:09:25 +0800 Subject: [PATCH] =?UTF-8?q?=E5=88=86=E9=85=8D=E5=BA=8F=E5=88=97=E5=8F=B7?= =?UTF-8?q?=E6=97=B6=E5=A2=9E=E5=8A=A0=E4=BA=8C=E7=BB=B4=E7=A0=81=E7=94=9F?= =?UTF-8?q?=E6=88=90=E5=8F=8A=E7=BC=96=E7=A0=81=E6=89=93=E5=8D=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sf_warehouse/models/model.py | 143 +++++++++++++++++- .../views/change_stock_move_views.xml | 16 ++ 2 files changed, 158 insertions(+), 1 deletion(-) diff --git a/sf_warehouse/models/model.py b/sf_warehouse/models/model.py index 26b336d1..02c52392 100644 --- a/sf_warehouse/models/model.py +++ b/sf_warehouse/models/model.py @@ -1,6 +1,9 @@ # -*- coding: utf-8 -*- import datetime import logging +import base64 +import qrcode +import io from odoo import api, fields, models, _ from odoo.osv import expression from odoo.exceptions import UserError @@ -230,7 +233,7 @@ class ShelfLocation(models.Model): # destination_location_id = fields.Many2one('sf.shelf.location', string='目的位置') current_move_ids = fields.One2many('stock.move.line', 'current_location_id', '当前位置调拨单') destination_move_ids = fields.One2many('stock.move.line', 'destination_location_id', '目标位置调拨单') - storage_time = fields.Datetime('入库时间', compute='_compute_location_status') + storage_time = fields.Datetime('入库时间', compute='_compute_location_status') @api.depends('location_status') def _compute_location_status(self): @@ -375,6 +378,112 @@ class Sf_stock_move_line(models.Model): # location_dest_id = fields.Many2one('stock.location', string='目标库位') location_dest_id_product_type = fields.Many2many(related='location_dest_id.product_type') location_dest_id_value = fields.Integer(compute='_compute_location_dest_id_value', store=True) + # lot_qr_code = fields.Binary(string='二维码', compute='_compute_lot_qr_code', store=True) + lot_qr_code = fields.Binary(string='二维码', compute='_compute_lot_qr_code', store=True) + + @api.depends('lot_name') + def _compute_lot_qr_code(self): + for record in self: + if record.lot_id: + # record.lot_qr_code = record.lot_id.lot_qr_code + # 创建一个QRCode对象 + qr = qrcode.QRCode( + version=1, # 设置版本, 1-40,控制二维码的大小 + error_correction=qrcode.constants.ERROR_CORRECT_L, # 设置错误校正等级 + box_size=10, # 设置每个格子的像素大小 + border=4, # 设置边框的格子宽度 + ) + + # 添加数据 + qr.add_data(self.lot_id.name) + qr.make(fit=True) + + # 创建二维码图像 + img = qr.make_image(fill_color="black", back_color="white") + + # 创建一个内存文件 + buffer = io.BytesIO() + img.save(buffer, format="PNG") # 将图像保存到内存文件中 + + # 获取二进制数据 + binary_data = buffer.getvalue() + + # 使用Base64编码这些二进制数据 + data = base64.b64encode(binary_data) + self.lot_qr_code = data + else: + record.lot_qr_code = False + + def print_qr_code(self): + self.ensure_one() # 确保这个方法只为一个记录调用 + # if not self.lot_id: + # raise UserError("没有找到序列号。") + # 假设_lot_qr_code方法已经生成了二维码并保存在字段中 + qr_code_data = self.lot_qr_code + if not qr_code_data: + raise UserError("没有找到二维码数据。") + + # 生成下载链接或直接触发下载 + # 此处的实现依赖于你的具体需求,以下是触发下载的一种示例 + attachment = self.env['ir.attachment'].sudo().create({ + 'datas': self.lot_qr_code, + 'type': 'binary', + 'description': '二维码图片', + 'name': self.lot_name + '.png', + # 'res_id': invoice.id, + # 'res_model': 'stock.picking', + 'public': True, + 'mimetype': 'application/x-png', + # 'model_name': 'stock.picking', + }) + # 返回附件的下载链接 + download_url = '/web/content/%s?download=true' % attachment.id + base_url = self.env['ir.config_parameter'].sudo().get_param('web.base.url') + return { + 'type': 'ir.actions.act_url', + 'url': str(base_url) + download_url, + 'target': 'self', + } + + # # # 定义一个方法,用于根据序列号生成二维码 + # # @api.depends('lot_id') + # def generate_lot_qr_code(self): + # # 创建一个QRCode对象 + # qr = qrcode.QRCode( + # version=1, # 设置版本, 1-40,控制二维码的大小 + # error_correction=qrcode.constants.ERROR_CORRECT_L, # 设置错误校正等级 + # box_size=10, # 设置每个格子的像素大小 + # border=4, # 设置边框的格子宽度 + # ) + # + # # 添加数据 + # qr.add_data(self.lot_id.name) + # qr.make(fit=True) + # + # # 创建二维码图像 + # img = qr.make_image(fill_color="black", back_color="white") + # + # # 创建一个内存文件 + # buffer = io.BytesIO() + # img.save(buffer, format="PNG") # 将图像保存到内存文件中 + # + # # 获取二进制数据 + # binary_data = buffer.getvalue() + # + # # 使用Base64编码这些二进制数据 + # data = base64.b64encode(binary_data) + # self.lot_qr_code = data + # attachment = self.env['ir.attachment'].sudo().create({ + # 'datas': data, + # 'type': 'binary', + # 'description': '二维码图片', + # 'name': self.lot_id.name + '.png', + # # 'res_id': invoice.id, + # # 'res_model': 'stock.picking', + # 'public': True, + # 'mimetype': 'application/pdf', + # # 'model_name': 'stock.picking', + # }) # def button_test(self): # print(self.picking_id.name) @@ -652,3 +761,35 @@ class SfStockScrap(models.Model): def action_check(self): self.check_state = 'enable' + + +class CustomStockMove(models.Model): + _inherit = 'stock.move' + + def action_assign_serial_show_details(self): + # 首先执行原有逻辑 + result = super(CustomStockMove, self).action_assign_serial_show_details() + # 接着为每个 lot_name 生成二维码 + move_lines = self.move_line_ids # 获取当前 stock.move 对应的所有 stock.move.line 记录 + for line in move_lines: + if line.lot_name: # 确保 lot_name 存在 + qr_data = self.compute_lot_qr_code(line.lot_name) + # 假设 stock.move.line 模型中有一个字段叫做 lot_qr_code 用于存储二维码数据 + line.lot_qr_code = qr_data + return result + + def compute_lot_qr_code(self, lot_name): + qr = qrcode.QRCode( + version=1, + error_correction=qrcode.constants.ERROR_CORRECT_L, + box_size=10, + border=4, + ) + qr.add_data(lot_name) + qr.make(fit=True) + img = qr.make_image(fill_color="black", back_color="white") + buffer = io.BytesIO() + img.save(buffer, format="PNG") + binary_data = buffer.getvalue() + data = base64.b64encode(binary_data).decode() # 确保返回的是字符串形式的数据 + return data diff --git a/sf_warehouse/views/change_stock_move_views.xml b/sf_warehouse/views/change_stock_move_views.xml index b10eaaa9..40294a20 100644 --- a/sf_warehouse/views/change_stock_move_views.xml +++ b/sf_warehouse/views/change_stock_move_views.xml @@ -51,6 +51,22 @@ + + + + + + + + + + sf.stock.move.line.operation.tree + stock.move.line + + + + +