采购协议
This commit is contained in:
@@ -4,4 +4,3 @@ from . import quick_easy_order_old
|
||||
from . import auto_quatotion_common
|
||||
from . import parser_and_calculate_work_time
|
||||
from . import preload_datas_functions
|
||||
from . import purchase_requisition
|
||||
|
||||
@@ -1,210 +0,0 @@
|
||||
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)
|
||||
@@ -303,39 +303,13 @@ class RePurchaseOrder(models.Model):
|
||||
string='采购类型', default='standard', store=True, compute='_compute_purchase_type')
|
||||
|
||||
# 合同编号
|
||||
contract_number = fields.Char(related='requisition_id.contract_number', string='合同编号', size=20)
|
||||
contract_number = fields.Char(string='合同编号', size=20)
|
||||
# 合同概况
|
||||
contract_summary = fields.Text(string='合同概况')
|
||||
|
||||
# 选择是否为紧急采购
|
||||
urgent_purchase = fields.Selection([('no', '否'), ('yes', '是')], string='紧急采购', default='no')
|
||||
|
||||
purchase_requisition_count = fields.Integer('采购协议数量', compute='_compute_purchase_requisition_count')
|
||||
|
||||
partner_ref = fields.Char(related='requisition_id.partner_ref')
|
||||
payment_term_id = fields.Many2one(related='requisition_id.payment_term_id')
|
||||
|
||||
requisition_id = fields.Many2one('purchase.requisition', string='采购协议', copy=False, readonly=True)
|
||||
show_create_requisition_button = fields.Boolean(string='显示创建采购协议按钮',
|
||||
compute='_compute_show_create_requisition_button'
|
||||
)
|
||||
show_requisition_fields = fields.Boolean(string='显示协议按钮', compute='_compute_show_requisition_fields')
|
||||
|
||||
@api.depends('requisition_id')
|
||||
def _compute_show_requisition_fields(self):
|
||||
for order in self:
|
||||
order.show_requisition_fields = bool(order.requisition_id and order.requisition_id.state == 'ongoing')
|
||||
|
||||
@api.depends('requisition_id')
|
||||
def _compute_show_create_requisition_button(self):
|
||||
for order in self:
|
||||
purchase_requisition = self.env['purchase.requisition'].search_count([('origin', '=', order.name)])
|
||||
order.show_create_requisition_button = purchase_requisition > 0
|
||||
|
||||
def _compute_purchase_requisition_count(self):
|
||||
for record in self:
|
||||
record.purchase_requisition_count = len(record.requisition_id)
|
||||
|
||||
@api.depends('origin')
|
||||
def _compute_purchase_type(self):
|
||||
for purchase in self:
|
||||
@@ -370,26 +344,6 @@ class RePurchaseOrder(models.Model):
|
||||
for item in self:
|
||||
if not item.order_line:
|
||||
raise UserError('该询价单未添加【产品】,请进行添加')
|
||||
missing_products = []
|
||||
over_ordered_products = []
|
||||
if item.requisition_id:
|
||||
requisition_product_ids = item.requisition_id.line_ids.mapped('product_id.id')
|
||||
for line in item.order_line:
|
||||
if line.product_id.id not in requisition_product_ids:
|
||||
missing_products.append(line.product_id.name)
|
||||
else:
|
||||
requisition_line = item.requisition_id.line_ids.filtered(
|
||||
lambda r: r.product_id.id == line.product_id.id)
|
||||
remaining_qty = requisition_line.product_qty - requisition_line.qty_ordered
|
||||
if requisition_line and line.product_qty > remaining_qty:
|
||||
over_ordered_products.append(
|
||||
f'{line.product_id.name}:{remaining_qty}{requisition_line.product_uom_id.name}')
|
||||
|
||||
if missing_products:
|
||||
raise UserError('关联协议不存在产品 %s ,无法保存。' % '、'.join(missing_products))
|
||||
if over_ordered_products:
|
||||
raise UserError('当前订购数量超过了关联协议的剩余数量,无法保存。\n涉及产品及剩余数量有:\n%s' % '\n'.join(
|
||||
over_ordered_products))
|
||||
for line in item.order_line:
|
||||
if not line.product_id:
|
||||
raise UserError('【产品】未添加,请进行添加')
|
||||
@@ -445,21 +399,6 @@ class RePurchaseOrder(models.Model):
|
||||
# raise ValidationError('【%s】已存在,请勿重复添加' % product[-1].name)
|
||||
|
||||
def button_confirm(self):
|
||||
over_ordered_products = []
|
||||
for item in self:
|
||||
if item.requisition_id:
|
||||
requisition_product_ids = item.requisition_id.line_ids.mapped('product_id.id')
|
||||
for line in item.order_line:
|
||||
if line.product_id.id in requisition_product_ids:
|
||||
requisition_line = item.requisition_id.line_ids.filtered(
|
||||
lambda r: r.product_id.id == line.product_id.id)
|
||||
remaining_qty = requisition_line.product_qty - requisition_line.qty_ordered
|
||||
if requisition_line and line.product_qty > remaining_qty:
|
||||
over_ordered_products.append(
|
||||
f'{line.product_id.name}:{remaining_qty} {requisition_line.product_uom_id.name}')
|
||||
if over_ordered_products:
|
||||
raise UserError('当前订购数量超过了关联协议的剩余数量,无法保存。\n涉及产品及剩余数量有:\n%s' % '\n'.join(
|
||||
over_ordered_products))
|
||||
result = super(RePurchaseOrder, self).button_confirm()
|
||||
for item in self:
|
||||
# 确认订单时,自动分配序列号
|
||||
@@ -500,90 +439,6 @@ class RePurchaseOrder(models.Model):
|
||||
purchase_order_overdue.write({'delivery_warning': 'normal'})
|
||||
return last_overdue_order, last_warning_order
|
||||
|
||||
def button_create_requisition(self):
|
||||
self.ensure_one()
|
||||
line_ids = []
|
||||
for order_line in self.order_line:
|
||||
line_values = {
|
||||
'product_id': order_line.product_id.id,
|
||||
'product_uom_id': order_line.product_uom.id,
|
||||
'product_qty': order_line.product_qty,
|
||||
'price_unit': order_line.price_unit,
|
||||
}
|
||||
line_ids.append((0, 0, line_values))
|
||||
initial_data = {
|
||||
'vendor_id': self.partner_id.id,
|
||||
'origin': self.name,
|
||||
'line_ids': line_ids,
|
||||
}
|
||||
return {
|
||||
'type': 'ir.actions.act_window',
|
||||
'res_model': 'purchase.requisition',
|
||||
'view_mode': 'form',
|
||||
'target': 'current',
|
||||
'context': {
|
||||
'default_origin': initial_data['origin'],
|
||||
'default_line_ids': initial_data['line_ids'],
|
||||
'default_vendor_id': initial_data['vendor_id'],
|
||||
}
|
||||
}
|
||||
|
||||
def button_link_requisition(self):
|
||||
requisition_ids = self.env['purchase.requisition'].sudo().search(
|
||||
[('state', '=', 'ongoing'), ('vendor_id', '=', self.partner_id.id),
|
||||
('line_ids.product_id', 'in', self.order_line.mapped('product_id.id'))])
|
||||
|
||||
# 新增的逻辑:过滤出符合条件的requisition_ids
|
||||
valid_requisition_ids = []
|
||||
for requisition in requisition_ids:
|
||||
for line in requisition.line_ids:
|
||||
if line.product_id in self.order_line.mapped(
|
||||
'product_id') and line.product_qty - line.qty_ordered >= self.order_line.filtered(
|
||||
lambda ol: ol.product_id == line.product_id).product_qty:
|
||||
valid_requisition_ids.append(requisition.id)
|
||||
break
|
||||
|
||||
action = {
|
||||
'res_model': 'purchase.requisition',
|
||||
'type': 'ir.actions.act_window',
|
||||
'name': _("选择采购申请"),
|
||||
'domain': [('id', 'in', valid_requisition_ids)],
|
||||
'views': [[self.env.ref('sf_sale.purchase_requisition_wizard_tree_view').id, 'list']],
|
||||
'target': 'new',
|
||||
'context': {'purchase_order_id': self.id},
|
||||
}
|
||||
return action
|
||||
|
||||
def button_unlink_requisition(self):
|
||||
self.ensure_one()
|
||||
for line in self.order_line:
|
||||
if self.requisition_id:
|
||||
requisition_line = self.requisition_id.line_ids.filtered(lambda r: r.product_id.id == line.product_id.id)
|
||||
if requisition_line:
|
||||
self.requisition_id.origin = False
|
||||
self.requisition_id.purchase_ids = [(3, self.id)]
|
||||
|
||||
|
||||
def action_view_requisition(self):
|
||||
self.ensure_one()
|
||||
requisition_ids = self.requisition_id.ids
|
||||
action = {
|
||||
'res_model': 'purchase.requisition',
|
||||
'type': 'ir.actions.act_window',
|
||||
}
|
||||
if len(requisition_ids) == 1:
|
||||
action.update({
|
||||
'view_mode': 'form',
|
||||
'res_id': requisition_ids[0],
|
||||
})
|
||||
else:
|
||||
action.update({
|
||||
'name': _("采购协议来源%s", self.name),
|
||||
'domain': [('id', 'in', requisition_ids)],
|
||||
'view_mode': 'tree,form',
|
||||
})
|
||||
return action
|
||||
|
||||
|
||||
class PurchaseOrderLine(models.Model):
|
||||
_inherit = 'purchase.order.line'
|
||||
|
||||
Reference in New Issue
Block a user