Files
gzth/yuthon_stock/wizard/yuthon_inventory_line_wizard.py
T
2026-07-03 19:05:50 +08:00

161 lines
6.5 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# -*- coding: utf-8 -*-
"""盘点明细编辑向导:弹出窗口编辑 single line,填写后提交"""
import logging
from odoo import api, fields, models
from odoo.exceptions import UserError
_logger = logging.getLogger(__name__)
class YuthonInventoryLineWizard(models.TransientModel):
"""盘点明细行编辑弹窗"""
_name = 'yuthon.inventory.line.wizard'
_description = '盘点明细编辑向导'
# ========== 关联明细行 ==========
line_id = fields.Many2one(
'yuthon.inventory.sheet.line',
string='明细行',
readonly=True,
)
# ========== 只读展示字段 ==========
product_name = fields.Char(string='产品/设备名称', readonly=True)
specification = fields.Char(string='规格型号', readonly=True)
# 是否为办公用品(用于控制库存位置字段的显示/隐藏)
is_office = fields.Boolean(
string='是否办公用品',
compute='_compute_is_office',
)
# 库存位置:办公用品可编辑,固定资产不显示
stock_location_id = fields.Many2one(
'stock.location',
string='库存位置',
domain="[('usage', '=', 'internal')]",
)
on_hand_qty = fields.Float(string='在手数量(系统数)', readonly=True)
# ========== 可编辑字段 ==========
actual_qty = fields.Float(string='实际盘点数量', digits='Product Unit of Measure')
# 固定资产:员工下拉(办公用品隐藏)
employee_id = fields.Many2one(
'hr.employee',
string='使用人',
)
# 使用部门(只读,根据选中的员工自动带出)
department_name = fields.Char(
string='使用部门',
compute='_compute_department_name',
readonly=True,
)
difference_reason = fields.Char(string='差额原因',
help='实际数量与在手数量有差额时必须填写')
# ========== 计算字段 ==========
difference_qty = fields.Float(
string='差额',
compute='_compute_difference',
digits='Product Unit of Measure',
)
@api.depends('line_id')
def _compute_is_office(self):
"""根据关联明细行的类型判断是否为办公用品"""
for wiz in self:
wiz.is_office = bool(wiz.line_id and wiz.line_id.sheet_type == 'office')
@api.depends('employee_id', 'employee_id.department_id')
def _compute_department_name(self):
"""根据选中的员工自动带出所属部门名称"""
for wiz in self:
if wiz.employee_id and wiz.employee_id.department_id:
wiz.department_name = wiz.employee_id.department_id.name
else:
wiz.department_name = ''
@api.depends('actual_qty', 'on_hand_qty')
def _compute_difference(self):
"""动态计算差额"""
for wiz in self:
wiz.difference_qty = (wiz.actual_qty or 0.0) - (wiz.on_hand_qty or 0.0)
@api.model
def default_get(self, fields_list):
"""打开弹窗时从明细行预填数据"""
res = super().default_get(fields_list)
line_id = self.env.context.get('default_line_id')
if line_id:
line = self.env['yuthon.inventory.sheet.line'].browse(line_id)
if line.exists():
# 预填固定资产的员工(按名称匹配 hr.employee)
employee_id = False
if line.sheet_type == 'fixed_asset' and line.user_name:
employee = self.env['hr.employee'].sudo().search([
('name', '=', line.user_name),
], limit=1)
if employee:
employee_id = employee.id
res.update({
'line_id': line.id,
'product_name': line.product_name or '',
'specification': line.specification or '',
'is_office': (line.sheet_type == 'office'),
'stock_location_id': line.stock_location_id.id if (line.sheet_type == 'office' and line.stock_location_id) else False,
'on_hand_qty': line.on_hand_qty or 0.0,
'actual_qty': line.actual_qty if line.actual_qty else 0.0,
'employee_id': employee_id, # 固定资产预填员工,办公用品留空
'difference_reason': line.difference_reason or '',
})
return res
def action_save(self):
"""保存数据到明细行(仅写回编辑字段,不执行提交/库存调整逻辑)
固定资产:员工下拉选择后同步写回 maintenance.equipment
"""
self.ensure_one()
line = self.line_id
if not line:
raise UserError('未找到关联的盘点明细行!')
# 写回用户编辑过的字段(库存位置改动会触发 inverse 移动库存)
write_vals = {
'actual_qty': self.actual_qty,
'difference_reason': self.difference_reason,
}
# 办公用品:使用人/部门保持 Char 写法
if line.sheet_type == 'office':
write_vals['user_name'] = ''
write_vals['department_name'] = ''
else:
# 固定资产:将 employee_id 的名称写回 line 的 user_name
# department_name 由 compute 自动取,无需手动写入
write_vals['user_name'] = self.employee_id.name if self.employee_id else ''
write_vals['department_name'] = self.department_name or ''
# 办公用品才写回库存位置
if line.sheet_type == 'office' and self.stock_location_id:
write_vals['stock_location_id'] = self.stock_location_id.id
line.write(write_vals)
# 固定资产:直接将 employee_id 和 department_id1 同步到 maintenance.equipment
if line.sheet_type == 'fixed_asset' and line.equipment_id:
eq = line.equipment_id
eq_vals = {}
eq_vals['employee_id'] = self.employee_id.id if self.employee_id else False
# 部门从员工的 department_id 取出 → 写入设备的 department_id1
if self.employee_id and self.employee_id.department_id:
eq_vals['department_id1'] = self.employee_id.department_id.id
else:
eq_vals['department_id1'] = False
eq.sudo().write(eq_vals)
# 关闭弹窗(不执行提交,用户回到列表后点「提交」按钮)
return {'type': 'ir.actions.act_window_close'}