From 86d2fb1ac213d8d1ef4e9b5cd4560480ab4a25da Mon Sep 17 00:00:00 2001
From: yuxianghui <3437689193@qq.com>
Date: Fri, 21 Mar 2025 11:20:24 +0800
Subject: [PATCH] =?UTF-8?q?efms-purchase=5Frequest=E6=A8=A1=E5=9D=97?=
=?UTF-8?q?=E6=96=B0=E5=A2=9E=E4=BF=AE=E6=94=B9=E4=BB=A3=E7=A0=81=E6=90=AC?=
=?UTF-8?q?=E8=BF=81=E5=88=B0sf-jikimo=5Fpurchase=5Frequest=E6=A8=A1?=
=?UTF-8?q?=E5=9D=97?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
jikimo_purchase_request/__init__.py | 1 +
jikimo_purchase_request/__manifest__.py | 2 +
jikimo_purchase_request/models/__init__.py | 1 +
.../models/purchase_request.py | 43 ++++++++-
jikimo_purchase_request/models/stock_rule.py | 44 +++++++++
.../views/purchase_request_view.xml | 15 +++
jikimo_purchase_request/wizard/__init__.py | 3 +
...rchase_request_line_make_purchase_order.py | 94 +++++++++++++++++++
..._request_line_make_purchase_order_view.xml | 13 +++
9 files changed, 215 insertions(+), 1 deletion(-)
create mode 100644 jikimo_purchase_request/models/stock_rule.py
create mode 100644 jikimo_purchase_request/views/purchase_request_view.xml
create mode 100644 jikimo_purchase_request/wizard/__init__.py
create mode 100644 jikimo_purchase_request/wizard/purchase_request_line_make_purchase_order.py
create mode 100644 jikimo_purchase_request/wizard/purchase_request_line_make_purchase_order_view.xml
diff --git a/jikimo_purchase_request/__init__.py b/jikimo_purchase_request/__init__.py
index a0fdc10f..408a6001 100644
--- a/jikimo_purchase_request/__init__.py
+++ b/jikimo_purchase_request/__init__.py
@@ -1,2 +1,3 @@
# -*- coding: utf-8 -*-
from . import models
+from . import wizard
diff --git a/jikimo_purchase_request/__manifest__.py b/jikimo_purchase_request/__manifest__.py
index 683c4311..d919b25d 100644
--- a/jikimo_purchase_request/__manifest__.py
+++ b/jikimo_purchase_request/__manifest__.py
@@ -9,6 +9,8 @@
'depends': ['sf_manufacturing', 'purchase_request'],
'data': [
'views/sale_order_view.xml',
+ 'views/purchase_request_view.xml',
+ 'wizard/purchase_request_line_make_purchase_order_view.xml',
],
# 'assets': {
# 'web.assets_backend': [
diff --git a/jikimo_purchase_request/models/__init__.py b/jikimo_purchase_request/models/__init__.py
index 284002d0..6942c727 100644
--- a/jikimo_purchase_request/models/__init__.py
+++ b/jikimo_purchase_request/models/__init__.py
@@ -2,3 +2,4 @@
from . import product_template
from . import purchase_request
from . import sale_order
+from . import stock_rule
diff --git a/jikimo_purchase_request/models/purchase_request.py b/jikimo_purchase_request/models/purchase_request.py
index 1ddedda7..f2a78bda 100644
--- a/jikimo_purchase_request/models/purchase_request.py
+++ b/jikimo_purchase_request/models/purchase_request.py
@@ -1,4 +1,4 @@
-from odoo import models, fields
+from odoo import models, fields, api
class PurchaseRequest(models.Model):
@@ -11,7 +11,48 @@ class PurchaseRequest(models.Model):
ondelete={'cancel': 'set default'} # 添加 ondelete 策略
)
+ rule_new_add = fields.Boolean('采购请求为规则创建', default=False, compute='_compute_state', store=True)
+
+ @api.depends('state')
+ def _compute_state(self):
+ for pr in self:
+ if pr.state != 'draft' and pr.rule_new_add:
+ pr.rule_new_add = False
+
class PurchaseRequestLine(models.Model):
_inherit = 'purchase.request.line'
_description = '采购申请明细'
+
+ origin = fields.Char(string="Source Document")
+ supply_method = fields.Selection([
+ ('automation', "自动化产线加工"),
+ ('manual', "人工线下加工"),
+ ('purchase', "外购"),
+ ('outsourcing', "委外加工"),
+ ], string='供货方式', compute='_compute_supply_method', store=True)
+
+ @api.depends('origin')
+ def _compute_supply_method(self):
+ for prl in self:
+ order_ids = []
+ if not prl.origin:
+ continue
+ origin = [origin.replace(' ', '') for origin in prl.origin.split(',')]
+ if 'S' in prl.origin:
+ # 原单据是销售订单
+ order_ids = self.env['sale.order'].sudo().search([('name', 'in', origin)]).ids
+ elif 'MO' in prl.origin:
+ # 原单据是制造订单
+ mp_ids = self.env['mrp.production'].sudo().search([('name', 'in', origin)])
+ order_ids = [mp_id.sale_order_id.id for mp_id in mp_ids] if mp_ids else []
+ elif 'WH' in prl.origin:
+ # 原单据是调拨单
+ sp_ids = self.env['stock.picking'].sudo().search([('name', 'in', origin)])
+ order_ids = [sp_id.sale_order_id.id for sp_id in sp_ids] if sp_ids else []
+ order_line = self.env['sale.order.line'].sudo().search(
+ [('product_id', '=', prl.product_id.id), ('order_id', 'in', order_ids)])
+ if order_line:
+ prl.supply_method = order_line[0].supply_method
+ else:
+ prl.supply_method = None
diff --git a/jikimo_purchase_request/models/stock_rule.py b/jikimo_purchase_request/models/stock_rule.py
new file mode 100644
index 00000000..7920433f
--- /dev/null
+++ b/jikimo_purchase_request/models/stock_rule.py
@@ -0,0 +1,44 @@
+from odoo import api, fields, models
+
+
+class StockRule(models.Model):
+ _inherit = "stock.rule"
+
+ def create_purchase_request(self, procurement_group):
+ """
+ Create a purchase request containing procurement order product.
+ """
+ procurement = procurement_group[0]
+ rule = procurement_group[1]
+ purchase_request_model = self.env["purchase.request"]
+ purchase_request_line_model = self.env["purchase.request.line"]
+ cache = {}
+ pr = self.env["purchase.request"]
+ domain = rule._make_pr_get_domain(procurement.values)
+ if domain in cache:
+ pr = cache[domain]
+ elif domain:
+ pr = self.env["purchase.request"].search([dom for dom in domain])
+ pr = pr[0] if pr else False
+ cache[domain] = pr
+ if not pr:
+ request_data = rule._prepare_purchase_request(
+ procurement.origin, procurement.values
+ )
+ request_data.update({'rule_new_add': True})
+ pr = purchase_request_model.create(request_data)
+ cache[domain] = pr
+ elif (
+ not pr.origin
+ or procurement.origin not in pr.origin.split(", ")
+ and procurement.origin != "/"
+ ):
+ if pr.origin:
+ if procurement.origin:
+ pr.write({"origin": pr.origin + ", " + procurement.origin})
+ else:
+ pr.write({"origin": procurement.origin})
+ # Create Line
+ request_line_data = rule._prepare_purchase_request_line(pr, procurement)
+ request_line_data.update({'origin': procurement.origin})
+ purchase_request_line_model.create(request_line_data)
diff --git a/jikimo_purchase_request/views/purchase_request_view.xml b/jikimo_purchase_request/views/purchase_request_view.xml
new file mode 100644
index 00000000..66a62bbf
--- /dev/null
+++ b/jikimo_purchase_request/views/purchase_request_view.xml
@@ -0,0 +1,15 @@
+
+
+ purchase.request.sf.form
+ purchase.request
+
+
+
+ 重置草稿
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/jikimo_purchase_request/wizard/__init__.py b/jikimo_purchase_request/wizard/__init__.py
new file mode 100644
index 00000000..0a2ad149
--- /dev/null
+++ b/jikimo_purchase_request/wizard/__init__.py
@@ -0,0 +1,3 @@
+# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl-3.0)
+
+from . import purchase_request_line_make_purchase_order
diff --git a/jikimo_purchase_request/wizard/purchase_request_line_make_purchase_order.py b/jikimo_purchase_request/wizard/purchase_request_line_make_purchase_order.py
new file mode 100644
index 00000000..dd246a5d
--- /dev/null
+++ b/jikimo_purchase_request/wizard/purchase_request_line_make_purchase_order.py
@@ -0,0 +1,94 @@
+# Copyright 2018-2019 ForgeFlow, S.L.
+# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl-3.0).
+from datetime import datetime
+
+from odoo import _, api, fields, models
+from odoo.exceptions import UserError, ValidationError
+from odoo.tools import get_lang
+
+
+class PurchaseRequestLineMakePurchaseOrder(models.TransientModel):
+ _inherit = "purchase.request.line.make.purchase.order"
+
+ def make_purchase_order(self):
+ res = []
+ purchase_obj = self.env["purchase.order"]
+ po_line_obj = self.env["purchase.order.line"]
+ purchase = False
+
+ if len(set([item_id.line_id.supply_method for item_id in self.item_ids])) > 1:
+ raise ValidationError('不同供货方式不可合并创建询价单!')
+
+ for item in self.item_ids:
+ line = item.line_id
+ if item.product_qty <= 0.0:
+ raise UserError(_("Enter a positive quantity."))
+ if self.purchase_order_id:
+ purchase = self.purchase_order_id
+ if not purchase:
+ po_data = self._prepare_purchase_order(
+ line.request_id.picking_type_id,
+ line.request_id.group_id,
+ line.company_id,
+ line.request_id.origin,
+ )
+ purchase = purchase_obj.create(po_data)
+
+ # Look for any other PO line in the selected PO with same
+ # product and UoM to sum quantities instead of creating a new
+ # po line
+ domain = self._get_order_line_search_domain(purchase, item)
+ available_po_lines = po_line_obj.search(domain)
+ new_pr_line = True
+ # If Unit of Measure is not set, update from wizard.
+ if not line.product_uom_id:
+ line.product_uom_id = item.product_uom_id
+ # Allocation UoM has to be the same as PR line UoM
+ alloc_uom = line.product_uom_id
+ wizard_uom = item.product_uom_id
+ if available_po_lines and not item.keep_description:
+ new_pr_line = False
+ po_line = available_po_lines[0]
+ po_line.purchase_request_lines = [(4, line.id)]
+ po_line.move_dest_ids |= line.move_dest_ids
+ po_line_product_uom_qty = po_line.product_uom._compute_quantity(
+ po_line.product_uom_qty, alloc_uom
+ )
+ wizard_product_uom_qty = wizard_uom._compute_quantity(
+ item.product_qty, alloc_uom
+ )
+ all_qty = min(po_line_product_uom_qty, wizard_product_uom_qty)
+ self.create_allocation(po_line, line, all_qty, alloc_uom)
+ else:
+ po_line_data = self._prepare_purchase_order_line(purchase, item)
+ if item.keep_description:
+ po_line_data["name"] = item.name
+ po_line = po_line_obj.create(po_line_data)
+ po_line_product_uom_qty = po_line.product_uom._compute_quantity(
+ po_line.product_uom_qty, alloc_uom
+ )
+ wizard_product_uom_qty = wizard_uom._compute_quantity(
+ item.product_qty, alloc_uom
+ )
+ all_qty = min(po_line_product_uom_qty, wizard_product_uom_qty)
+ self.create_allocation(po_line, line, all_qty, alloc_uom)
+ self._post_process_po_line(item, po_line, new_pr_line)
+ res.append(purchase.id)
+
+ purchase_requests = self.item_ids.mapped("request_id")
+ purchase_requests.button_in_progress()
+ return {
+ "domain": [("id", "in", res)],
+ "name": _("RFQ"),
+ "view_mode": "tree,form",
+ "res_model": "purchase.order",
+ "view_id": False,
+ "context": False,
+ "type": "ir.actions.act_window",
+ }
+
+
+class PurchaseRequestLineMakePurchaseOrderItem(models.TransientModel):
+ _inherit = "purchase.request.line.make.purchase.order.item"
+
+ supply_method = fields.Selection(related='line_id.supply_method', string='供货方式')
diff --git a/jikimo_purchase_request/wizard/purchase_request_line_make_purchase_order_view.xml b/jikimo_purchase_request/wizard/purchase_request_line_make_purchase_order_view.xml
new file mode 100644
index 00000000..4d519a2e
--- /dev/null
+++ b/jikimo_purchase_request/wizard/purchase_request_line_make_purchase_order_view.xml
@@ -0,0 +1,13 @@
+
+
+
+ Purchase Request Line Make Purchase Order sf
+ purchase.request.line.make.purchase.order
+
+
+
+
+
+
+
+