Accept Merge Request #1942: (feature/采购申请代码搬迁 -> develop)
Merge Request: Merge branch 'feature/采购单优化' into feature/采购申请代码搬迁 Created By: @禹翔辉 Reviewed By: @胡尧 Approved By: @胡尧 Accepted By: @禹翔辉 URL: https://jikimo-hn.coding.net/p/jikimo_sfs/d/jikimo_sf/git/merge/1942
This commit is contained in:
@@ -1,2 +1,3 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
from . import models
|
from . import models
|
||||||
|
from . import wizard
|
||||||
|
|||||||
@@ -9,6 +9,8 @@
|
|||||||
'depends': ['sf_manufacturing', 'purchase_request'],
|
'depends': ['sf_manufacturing', 'purchase_request'],
|
||||||
'data': [
|
'data': [
|
||||||
'views/sale_order_view.xml',
|
'views/sale_order_view.xml',
|
||||||
|
'views/purchase_request_view.xml',
|
||||||
|
'wizard/purchase_request_line_make_purchase_order_view.xml',
|
||||||
],
|
],
|
||||||
# 'assets': {
|
# 'assets': {
|
||||||
# 'web.assets_backend': [
|
# 'web.assets_backend': [
|
||||||
|
|||||||
@@ -2,3 +2,4 @@
|
|||||||
from . import product_template
|
from . import product_template
|
||||||
from . import purchase_request
|
from . import purchase_request
|
||||||
from . import sale_order
|
from . import sale_order
|
||||||
|
from . import stock_rule
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
from odoo import models, fields
|
from odoo import models, fields, api
|
||||||
|
|
||||||
|
|
||||||
class PurchaseRequest(models.Model):
|
class PurchaseRequest(models.Model):
|
||||||
@@ -11,7 +11,48 @@ class PurchaseRequest(models.Model):
|
|||||||
ondelete={'cancel': 'set default'} # 添加 ondelete 策略
|
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):
|
class PurchaseRequestLine(models.Model):
|
||||||
_inherit = 'purchase.request.line'
|
_inherit = 'purchase.request.line'
|
||||||
_description = '采购申请明细'
|
_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
|
||||||
|
|||||||
44
jikimo_purchase_request/models/stock_rule.py
Normal file
44
jikimo_purchase_request/models/stock_rule.py
Normal file
@@ -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)
|
||||||
15
jikimo_purchase_request/views/purchase_request_view.xml
Normal file
15
jikimo_purchase_request/views/purchase_request_view.xml
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
<odoo>
|
||||||
|
<record id="view_purchase_request_form_sf" model="ir.ui.view">
|
||||||
|
<field name="name">purchase.request.sf.form</field>
|
||||||
|
<field name="model">purchase.request</field>
|
||||||
|
<field name="inherit_id" ref="purchase_request.view_purchase_request_form" />
|
||||||
|
<field name="arch" type="xml">
|
||||||
|
<xpath expr="//button[@name='button_draft']" position="attributes">
|
||||||
|
<attribute name="string">重置草稿</attribute>
|
||||||
|
</xpath>
|
||||||
|
<xpath expr="//field[@name='line_ids']//field[@name='purchased_qty']" position="after">
|
||||||
|
<field name="supply_method"/>
|
||||||
|
</xpath>
|
||||||
|
</field>
|
||||||
|
</record>
|
||||||
|
</odoo>
|
||||||
3
jikimo_purchase_request/wizard/__init__.py
Normal file
3
jikimo_purchase_request/wizard/__init__.py
Normal file
@@ -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
|
||||||
@@ -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='供货方式')
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8" ?>
|
||||||
|
<odoo>
|
||||||
|
<record id="view_purchase_request_line_make_purchase_order_sf" model="ir.ui.view">
|
||||||
|
<field name="name">Purchase Request Line Make Purchase Order sf</field>
|
||||||
|
<field name="model">purchase.request.line.make.purchase.order</field>
|
||||||
|
<field name="inherit_id" ref="purchase_request.view_purchase_request_line_make_purchase_order"/>
|
||||||
|
<field name="arch" type="xml">
|
||||||
|
<xpath expr="//field[@name='item_ids']//field[@name='keep_description']" position="before">
|
||||||
|
<field name="supply_method"/>
|
||||||
|
</xpath>
|
||||||
|
</field>
|
||||||
|
</record>
|
||||||
|
</odoo>
|
||||||
Reference in New Issue
Block a user