固定资产导出,入库借用领用仓库限制
This commit is contained in:
@@ -100,19 +100,49 @@ class InheritMaintenanceEquipment(models.Model):
|
||||
workbook = load_workbook(template_path)
|
||||
sheet = workbook.active
|
||||
|
||||
# 统计导出数据中最常见的年月(用于标题)
|
||||
year_month_list = []
|
||||
for record in equipment_records:
|
||||
if record.purchase_date:
|
||||
year_month_list.append((record.purchase_date.year, record.purchase_date.month))
|
||||
|
||||
if year_month_list:
|
||||
# 取出现次数最多的年月
|
||||
from collections import Counter
|
||||
most_common_ym = Counter(year_month_list).most_common(1)[0][0]
|
||||
title_year, title_month = most_common_ym
|
||||
else:
|
||||
# 如果没有购入日期,使用当前年月
|
||||
now = datetime.datetime.now()
|
||||
title_year, title_month = now.year, now.month
|
||||
|
||||
# 修改A1单元格:生成动态标题
|
||||
title_text = f'{title_year}年{title_month}月固定资产盘点表'
|
||||
sheet['A1'] = title_text
|
||||
sheet['A1'].alignment = Alignment(horizontal='left', vertical='center')
|
||||
|
||||
# 修改K1单元格:生成制表人信息(直接替换,不追加)
|
||||
current_date = datetime.datetime.now().strftime('%Y-%m-%d')
|
||||
k1_text = f'制表人:叶华锋 {current_date}'
|
||||
sheet['K1'] = k1_text
|
||||
sheet['K1'].alignment = Alignment(horizontal='left', vertical='center')
|
||||
|
||||
# 从第3行开始写入数据(第1-2行是表头)
|
||||
row = 3
|
||||
|
||||
# 设置列宽(A列序号列设置为较窄,C列型号列也设置较窄)
|
||||
sheet.column_dimensions['A'].width = 6 # 序号列宽度
|
||||
sheet.column_dimensions['C'].width = 12 # 型号列宽度
|
||||
# 设置列宽
|
||||
sheet.column_dimensions['A'].width = 6 # 序号列
|
||||
sheet.column_dimensions['B'].width = 20 # 资产编号列(加宽)
|
||||
sheet.column_dimensions['C'].width = 30 # 设备名称列(加宽)
|
||||
sheet.column_dimensions['D'].width = 12 # 型号列
|
||||
sheet.column_dimensions['K'].width = 25 # 制表人列(确保内容完整显示)
|
||||
|
||||
# 获取模板样式行(使用第3行作为参考)
|
||||
template_row_idx = 3
|
||||
if sheet.max_row >= template_row_idx:
|
||||
# 先保存第3行的样式
|
||||
template_styles = {}
|
||||
for col in range(1, 11): # A到J列(10列)
|
||||
for col in range(1, 12): # A到K列(11列)
|
||||
cell = sheet.cell(row=template_row_idx, column=col)
|
||||
template_styles[col] = {
|
||||
'font': copy(cell.font),
|
||||
@@ -132,8 +162,8 @@ class InheritMaintenanceEquipment(models.Model):
|
||||
for merged_range_str in merged_cells_to_unmerge:
|
||||
sheet.unmerge_cells(merged_range_str)
|
||||
|
||||
# 先为所有列应用模板样式
|
||||
for col in range(1, 11): # A到J列
|
||||
# 先为所有列应用模板样式并统一居中对齐
|
||||
for col in range(1, 12): # A到K列
|
||||
cell = sheet.cell(row=row, column=col)
|
||||
if col in template_styles:
|
||||
cell.font = copy(template_styles[col]['font'])
|
||||
@@ -145,41 +175,44 @@ class InheritMaintenanceEquipment(models.Model):
|
||||
# A列:序号(从1开始)
|
||||
sheet.cell(row=row, column=1, value=index)
|
||||
|
||||
# B列:设备名称
|
||||
sheet.cell(row=row, column=2, value=record.name or '')
|
||||
# B列:资产编号
|
||||
sheet.cell(row=row, column=2, value=record.serial_no or '')
|
||||
|
||||
# C列:型号
|
||||
sheet.cell(row=row, column=3, value=record.model or '')
|
||||
# C列:设备名称
|
||||
sheet.cell(row=row, column=3, value=record.name or '')
|
||||
|
||||
# D列:原值
|
||||
sheet.cell(row=row, column=4, value=record.cost or 0)
|
||||
# D列:型号
|
||||
sheet.cell(row=row, column=4, value=record.model or '')
|
||||
|
||||
# E列:寿命
|
||||
# E列:原值
|
||||
sheet.cell(row=row, column=5, value=record.cost or 0)
|
||||
|
||||
# F列:寿命
|
||||
warranty_date = ''
|
||||
if record.warranty_date:
|
||||
warranty_date = record.warranty_date.strftime('%Y-%m-%d')
|
||||
sheet.cell(row=row, column=5, value=warranty_date)
|
||||
sheet.cell(row=row, column=6, value=warranty_date)
|
||||
|
||||
# F列:设备状态
|
||||
# G列:设备状态
|
||||
mainten_state = ''
|
||||
if record.mainten_state:
|
||||
mainten_state = dict(record._fields['mainten_state'].selection).get(record.mainten_state, '')
|
||||
sheet.cell(row=row, column=6, value=mainten_state)
|
||||
sheet.cell(row=row, column=7, value=mainten_state)
|
||||
|
||||
# G列:员工
|
||||
sheet.cell(row=row, column=7, value=record.employee_id.name if record.employee_id else '')
|
||||
# H列:员工
|
||||
sheet.cell(row=row, column=8, value=record.employee_id.name if record.employee_id else '')
|
||||
|
||||
# H列:部门
|
||||
sheet.cell(row=row, column=8, value=record.department_id1.name if record.department_id1 else '')
|
||||
# I列:部门
|
||||
sheet.cell(row=row, column=9, value=record.department_id1.name if record.department_id1 else '')
|
||||
|
||||
# I列:设备类别
|
||||
sheet.cell(row=row, column=9, value=record.category_id.name if record.category_id else '')
|
||||
# J列:设备类别
|
||||
sheet.cell(row=row, column=10, value=record.category_id.name if record.category_id else '')
|
||||
|
||||
# J列:公司(company 字段)
|
||||
# K列:公司(company 字段)
|
||||
company = ''
|
||||
if record.company:
|
||||
company = dict(record._fields['company'].selection).get(record.company, '')
|
||||
sheet.cell(row=row, column=10, value=company)
|
||||
sheet.cell(row=row, column=11, value=company)
|
||||
|
||||
# 设置最小行高,确保内容显示完整
|
||||
if not sheet.row_dimensions[row].height or sheet.row_dimensions[row].height < 30:
|
||||
@@ -193,8 +226,8 @@ class InheritMaintenanceEquipment(models.Model):
|
||||
output.seek(0)
|
||||
excel_data = base64.b64encode(output.read())
|
||||
|
||||
# 创建附件
|
||||
filename = f'固定资产盘点表_{datetime.datetime.now().strftime("%Y%m%d%H%M%S")}.xlsx'
|
||||
# 创建附件(文件名只包含日期,不含时分秒)
|
||||
filename = f'固定资产盘点表_{datetime.datetime.now().strftime("%Y%m%d")}.xlsx'
|
||||
attachment = self.env['ir.attachment'].create({
|
||||
'name': filename,
|
||||
'type': 'binary',
|
||||
|
||||
Binary file not shown.
@@ -26,3 +26,5 @@ class ProductProduct(models.Model):
|
||||
|
||||
class StockMove(models.Model):
|
||||
_inherit = 'stock.move'
|
||||
|
||||
|
||||
|
||||
@@ -38,9 +38,20 @@ class StockPicking(models.Model):
|
||||
)
|
||||
available_product_ids = fields.Many2many(
|
||||
'product.product',
|
||||
'stock_picking_product_available_rel',
|
||||
'picking_id',
|
||||
'product_id',
|
||||
compute='_compute_available_product_ids',
|
||||
string="可用产品"
|
||||
)
|
||||
available_location_ids = fields.Many2many(
|
||||
'stock.location',
|
||||
'stock_picking_location_available_rel',
|
||||
'picking_id',
|
||||
'location_id',
|
||||
compute='_compute_available_location_ids',
|
||||
string="可用仓库"
|
||||
)
|
||||
can_certify = fields.Boolean(
|
||||
string="可以证明",
|
||||
compute='_compute_can_certify',
|
||||
@@ -81,19 +92,39 @@ class StockPicking(models.Model):
|
||||
})
|
||||
return result
|
||||
|
||||
@api.depends('location_id')
|
||||
@api.depends('location_id', 'picking_type_code')
|
||||
def _compute_available_product_ids(self):
|
||||
"""根据仓库计算可用产品列表"""
|
||||
"""根据仓库和作业类型计算可用产品列表"""
|
||||
for record in self:
|
||||
if record.location_id:
|
||||
# 查询该仓库中有库存的产品
|
||||
# 如果是入库单,返回所有产品(不限制)
|
||||
if record.picking_type_code == 'incoming':
|
||||
record.available_product_ids = self.env['product.product'].search([])
|
||||
# 如果是借用/领用等,只返回该仓库中有库存的产品
|
||||
elif record.location_id:
|
||||
quants = self.env['stock.quant'].search([
|
||||
('location_id', '=', record.location_id.id)
|
||||
('location_id', '=', record.location_id.id),
|
||||
('quantity', '>', 0) # 只查询有库存的
|
||||
])
|
||||
record.available_product_ids = quants.mapped('product_id')
|
||||
else:
|
||||
record.available_product_ids = False
|
||||
|
||||
|
||||
@api.depends('picking_type_code')
|
||||
def _compute_available_location_ids(self):
|
||||
"""根据作业类型计算可用仓库列表"""
|
||||
for record in self:
|
||||
# 如果是入库单,不限制仓库选择
|
||||
if record.picking_type_code == 'incoming':
|
||||
record.available_location_ids = self.env['stock.location'].search([])
|
||||
# 如果是借用/领用等,只显示有库存的仓库
|
||||
else:
|
||||
quants = self.env['stock.quant'].search([
|
||||
('quantity', '>', 0)
|
||||
])
|
||||
record.available_location_ids = quants.mapped('location_id')
|
||||
|
||||
|
||||
@api.onchange('user_id')
|
||||
def _onchange_user_id(self):
|
||||
if self.user_id:
|
||||
|
||||
@@ -8,6 +8,9 @@
|
||||
<xpath expr="//field[@name='picking_type_id']" position="after">
|
||||
<field name="department_id" options="{'no_create': True}" invisible="1"/>
|
||||
</xpath>
|
||||
<xpath expr="//field[@name='location_id'][@groups='stock.group_stock_multi_locations']" position="attributes">
|
||||
<attribute name="domain">[('id', 'in', available_location_ids)]</attribute>
|
||||
</xpath>
|
||||
<xpath expr="//field[@name='picking_type_id']" position="attributes">
|
||||
<attribute name="readonly">state != 'draft' and receipt_status in ['acceptance', 'certification']</attribute>
|
||||
</xpath>
|
||||
@@ -18,6 +21,7 @@
|
||||
<field name="purchase_id" string="源单据" readonly="1" options="{'no_create': True, 'no_open': False}"/>
|
||||
<field name="user_id" string="采购人员"/>
|
||||
<field name="available_product_ids" invisible="1"/>
|
||||
<field name="available_location_ids" invisible="1"/>
|
||||
<field name="state" invisible="1"/>
|
||||
<field name="can_certify" invisible="1"/>
|
||||
</xpath>
|
||||
|
||||
Reference in New Issue
Block a user