Files
jikimo_sf/sf_sale/models/purchase_requisition.py
2025-02-19 10:42:48 +08:00

211 lines
9.1 KiB
Python

from odoo import models, fields, api, _
from odoo.exceptions import UserError, ValidationError
import logging
_logger = logging.getLogger(__name__)
class PurchaseRequisition(models.Model):
_inherit = 'purchase.requisition'
partner_ref = fields.Char(string='合同名称', required=True)
contract_number = fields.Char(string='合同编码', size=20, required=True)
payment_term_id = fields.Many2one('account.payment.term', '付款条件',
domain="['|', ('company_id', '=', False), ('company_id', '=', company_id)]",
required=True)
contract_summary = fields.Text(string='合同概况', required=True)
contract_document_id = fields.Many2one('documents.document', string='合同文件')
contract_file = fields.Binary(related='contract_document_id.datas', string='合同文件内容')
contract_file_name = fields.Char(related='contract_document_id.attachment_id.name', string='文件名')
# 是否已上传合同文件
is_upload_contract_file = fields.Boolean(string='是否已上传合同文件', default=False)
def upload_contract_file(self):
self.ensure_one()
action = {
'type': 'ir.actions.act_window',
'name': _('上传合同文件'),
'res_model': 'ir.attachment.upload', # 我们需要创建一个新的向导模型
'view_mode': 'form',
'target': 'new',
'context': {
'default_res_model': self._name,
'default_res_id': self.id,
}
}
return action
# 删除合同文件
def delete_contract_file(self):
self.ensure_one()
if self.contract_document_id:
try:
document = self.contract_document_id
# 清空关联
self.write({
'contract_document_id': False,
'contract_file': False,
'contract_file_name': False
})
# 删除文档
if document:
document.with_context(no_attachment=True).sudo().unlink()
self.is_upload_contract_file = False
# 返回视图动作来刷新当前表单
return {
'type': 'ir.actions.act_window',
'res_model': 'purchase.requisition',
'res_id': self.id,
'view_mode': 'form',
'view_type': 'form',
'target': 'current',
'flags': {'mode': 'readonly'},
}
except Exception as e:
_logger.error('删除合同文件时出错: %s', str(e))
return {
'type': 'ir.actions.client',
'tag': 'display_notification',
'params': {
'title': _('错误'),
'message': _('删除文件时出现错误'),
'type': 'danger',
'sticky': True,
}
}
return {
'type': 'ir.actions.client',
'tag': 'display_notification',
'params': {
'title': _('提示'),
'message': _('没有需要删除的合同文件'),
'type': 'warning',
'sticky': False,
}
}
def action_in_progress(self):
self.ensure_one()
# 检查合同文件
if not self.contract_document_id:
raise ValidationError('* 必须点击上传合同文件')
if self.origin:
purchase_order = self.env['purchase.order'].search([('name', '=', self.origin)], limit=1)
if purchase_order:
if not purchase_order.requisition_id:
# 绑定采购协议
self.purchase_ids += purchase_order
else:
raise ValidationError('源单据已绑定采购协议,请手动清除源单据解绑。')
res = super(PurchaseRequisition, self).action_in_progress()
# 将合同文档移动到废弃
for requisition in self:
if requisition.contract_document_id:
workspace = self.update_documents_folder('通过')
requisition.contract_document_id.write({
'folder_id': workspace.id,
})
return res
def action_cancel(self):
for requisition in self:
if requisition.purchase_ids:
raise ValidationError(_('已关联采购订单,不能取消该采购协议'))
res = super(PurchaseRequisition, self).action_cancel()
# 将合同文档移动到废弃
for requisition in self:
if requisition.contract_document_id:
workspace = self.update_documents_folder('废弃')
requisition.contract_document_id.write({
'folder_id': workspace.id,
})
return res
def action_draft(self):
res = super(PurchaseRequisition, self).action_draft()
for requisition in self:
if requisition.contract_document_id:
workspace = self.update_documents_folder('待审')
requisition.contract_document_id.write({
'folder_id': workspace.id,
})
return res
def update_documents_folder(self, documents_folder_name):
workspace_parent = self.env['documents.folder'].search([('name', '=', '采购合同')], limit=1)
workspace = self.env['documents.folder'].search(
[('name', '=', documents_folder_name), ('parent_folder_id', '=', workspace_parent.id)], limit=1)
return workspace
@api.constrains('line_ids')
def check_line_ids(self):
if self.origin:
purchase_order = self.env['purchase.order'].search([('name', '=', self.origin)], limit=1)
if purchase_order:
error_products = []
# 获取采购订单中的所有产品
purchase_order_products = purchase_order.order_line.mapped('product_id')
if self.line_ids:
for line in self.line_ids:
# 检查当前行的产品在采购订单中的数量
order_line = purchase_order.order_line.filtered(lambda ol: ol.product_id == line.product_id)
if order_line and line.product_qty < order_line.product_qty:
error_products.append(line.product_id.name) # 收集不符合条件的产品名称
else:
raise ValidationError(
_('采购协议的产品和数量应达超源单据的产品和数量,请修改产品数量或修改源单据。'))
# 检查采购订单中的产品是否都在采购协议中
for product in purchase_order_products:
if product not in self.line_ids.mapped('product_id'):
raise ValidationError(
_('采购协议的产品和数量应达超源单据的产品和数量,请修改产品数量或修改源单据。'))
if error_products:
raise ValidationError(
_('产品 %s 的数量不能小于源单据数量,当前无法保存。') % (', '.join(error_products)))
class PurchaseRequisitionLine(models.Model):
_inherit = 'purchase.requisition.line'
materials_id = fields.Many2one('sf.production.materials', string='材料', compute='_compute_product_info')
materials_type_id = fields.Many2one('sf.materials.model', string='规格型号', compute='_compute_product_info')
part_number = fields.Char(string='零件图号', compute='_compute_product_info')
delivery_date = fields.Date(string='交货时间')
@api.depends('product_id')
def _compute_product_info(self):
for line in self:
if line.product_id:
line.materials_id = line.product_id.materials_id
line.materials_type_id = line.product_id.materials_type_id
line.part_number = line.product_id.part_number
else:
line.materials_id = False
line.materials_type_id = False
line.part_number = False
@api.model_create_multi
def create(self, vals_list):
for vals in vals_list:
if 'product_qty' in vals and vals.get('product_qty') <= 0:
raise UserError('请对【产品】中的【数量】进行输入')
if 'price_unit' in vals and vals.get('price_unit') <= 0:
raise UserError('请对【产品】中的【单价】进行输入')
return super(PurchaseRequisitionLine, self).create(vals_list)
def write(self, vals):
if 'product_qty' in vals and vals.get('product_qty') <= 0:
raise UserError('请对【产品】中的【数量】进行输入')
if 'price_unit' in vals and vals.get('price_unit') <= 0:
raise UserError('请对【产品】中的【单价】进行输入')
return super(PurchaseRequisitionLine, self).write(vals)