mirror of
https://github.com/guohuadeng/app-odoo.git
synced 2025-02-23 04:11:36 +02:00
add ztree trans
This commit is contained in:
83
app_sale_for_subcontract_service/README.rst
Normal file
83
app_sale_for_subcontract_service/README.rst
Normal file
@@ -0,0 +1,83 @@
|
|||||||
|
.. image:: https://img.shields.io/badge/licence-AGPL--3-blue.png
|
||||||
|
:target: http://www.gnu.org/licenses/agpl-3.0-standalone.html
|
||||||
|
:alt: License: AGPL-3
|
||||||
|
|
||||||
|
======================
|
||||||
|
Subcontracted services
|
||||||
|
======================
|
||||||
|
|
||||||
|
This module allows a user to indicate that a service is subcontracted.
|
||||||
|
It provides the ability to create purchases from procurement processes.
|
||||||
|
|
||||||
|
This is a base module, upon specific modules for sale / manufacuturing, modules
|
||||||
|
will need to rely on. By itself it does not provide any function to the end user.
|
||||||
|
|
||||||
|
Possible uses of this module can be:
|
||||||
|
|
||||||
|
* Add subcontracted services to BOMs. When a manufacturing order is created a
|
||||||
|
PO is triggered for the service to be subcontracted. See
|
||||||
|
|
||||||
|
* Add subcontracted services to sales order. When the SO is confirmed, it
|
||||||
|
creates a PO for the service.
|
||||||
|
|
||||||
|
|
||||||
|
Configuration
|
||||||
|
=============
|
||||||
|
|
||||||
|
To configure this module, you need to:
|
||||||
|
|
||||||
|
#. Configure your service product with the flag
|
||||||
|
``property_subcontracted_service`` in product form if this product should
|
||||||
|
trigger a procurement.
|
||||||
|
#. Add supplier in your product form.
|
||||||
|
#. Additionally and despite a predefined rule is created in each warehouse,
|
||||||
|
you can configure the 'Subcontracting_service procurement rule' for each
|
||||||
|
warehouse through 'Inventory / Configuration / Warehouse Management /
|
||||||
|
Warehouse'.
|
||||||
|
|
||||||
|
Usage
|
||||||
|
=====
|
||||||
|
|
||||||
|
.. image:: https://odoo-community.org/website/image/ir.attachment/5784_f2813bd/datas
|
||||||
|
:alt: Try me on Runbot
|
||||||
|
:target: https://runbot.odoo-community.org/runbot/142/11.0
|
||||||
|
|
||||||
|
|
||||||
|
Bug Tracker
|
||||||
|
===========
|
||||||
|
|
||||||
|
Bugs are tracked on `GitHub Issues
|
||||||
|
<https://github.com/OCA/purchase-workflow/issues>`_. In case of trouble, please
|
||||||
|
check there if your issue has already been reported. If you spotted it first,
|
||||||
|
help us smash it by providing detailed and welcomed feedback.
|
||||||
|
|
||||||
|
Credits
|
||||||
|
=======
|
||||||
|
|
||||||
|
Images
|
||||||
|
------
|
||||||
|
|
||||||
|
* Odoo Community Association: `Icon <https://github.com/OCA/maintainer-tools/blob/master/template/module/static/description/icon.png>`_.
|
||||||
|
|
||||||
|
Contributors
|
||||||
|
------------
|
||||||
|
|
||||||
|
* Damien Crier <damien.crier@camptocamp.com>
|
||||||
|
* Jordi Ballester Alomar <jordi.ballester@eficent.com>
|
||||||
|
* Lois Rilo <lois.rilo@eficent.com>
|
||||||
|
|
||||||
|
|
||||||
|
Maintainer
|
||||||
|
----------
|
||||||
|
|
||||||
|
.. image:: https://odoo-community.org/logo.png
|
||||||
|
:alt: Odoo Community Association
|
||||||
|
:target: https://odoo-community.org
|
||||||
|
|
||||||
|
This module is maintained by the OCA.
|
||||||
|
|
||||||
|
OCA, or the Odoo Community Association, is a nonprofit organization whose
|
||||||
|
mission is to support the collaborative development of Odoo features and
|
||||||
|
promote its widespread use.
|
||||||
|
|
||||||
|
To contribute to this module, please visit https://odoo-community.org.
|
||||||
2
app_sale_for_subcontract_service/__init__.py
Normal file
2
app_sale_for_subcontract_service/__init__.py
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
|
||||||
|
from . import models
|
||||||
28
app_sale_for_subcontract_service/__manifest__.py
Normal file
28
app_sale_for_subcontract_service/__manifest__.py
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
# Author: Damien Crier
|
||||||
|
# Copyright 2017 Camptocamp SA
|
||||||
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
|
||||||
|
# base on Camptocamp, Odoo Community Association (OCA)
|
||||||
|
|
||||||
|
{
|
||||||
|
"name": 'App Sale for Subcontracted service',
|
||||||
|
"version": "11.0.1.0.0",
|
||||||
|
"category": "Sale",
|
||||||
|
"website": "http://www.sunpop.cn/",
|
||||||
|
"author": "Sunpop.cn",
|
||||||
|
"license": "AGPL-3",
|
||||||
|
'sequence': 3,
|
||||||
|
"summary": 'Sale for Subcontracted service(委外采购的销售整合)',
|
||||||
|
'description': """
|
||||||
|
""",
|
||||||
|
'price': 68.00,
|
||||||
|
'currency': 'EUR',
|
||||||
|
'installable': True,
|
||||||
|
'application': True,
|
||||||
|
'auto_install': False,
|
||||||
|
"depends": [
|
||||||
|
"app_procurement_for_subcontract_service",
|
||||||
|
"sale_stock",
|
||||||
|
],
|
||||||
|
"data": [
|
||||||
|
],
|
||||||
|
}
|
||||||
54
app_sale_for_subcontract_service/i18n/zh_CN.po
Normal file
54
app_sale_for_subcontract_service/i18n/zh_CN.po
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
# Translation of Odoo Server.
|
||||||
|
# This file contains the translation of the following modules:
|
||||||
|
# * app_procurement_for_subcontract_service
|
||||||
|
#
|
||||||
|
msgid ""
|
||||||
|
msgstr ""
|
||||||
|
"Project-Id-Version: Odoo Server 11.0+e-20180617\n"
|
||||||
|
"Report-Msgid-Bugs-To: \n"
|
||||||
|
"POT-Creation-Date: 2018-07-20 11:07+0000\n"
|
||||||
|
"PO-Revision-Date: 2018-07-20 11:07+0000\n"
|
||||||
|
"Last-Translator: <>\n"
|
||||||
|
"Language-Team: \n"
|
||||||
|
"MIME-Version: 1.0\n"
|
||||||
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
|
"Content-Transfer-Encoding: \n"
|
||||||
|
"Plural-Forms: \n"
|
||||||
|
|
||||||
|
#. module: app_procurement_for_subcontract_service
|
||||||
|
#: code:addons/app_procurement_for_subcontract_service/models/warehouse.py:29
|
||||||
|
#, python-format
|
||||||
|
msgid "%s: Subcontracting service rule"
|
||||||
|
msgstr "%s: 委外服务路线"
|
||||||
|
|
||||||
|
#. module: app_procurement_for_subcontract_service
|
||||||
|
#: model:ir.model,name:app_procurement_for_subcontract_service.model_procurement_group
|
||||||
|
msgid "Procurement Requisition"
|
||||||
|
msgstr "补货申请"
|
||||||
|
|
||||||
|
#. module: app_procurement_for_subcontract_service
|
||||||
|
#: model:ir.model,name:app_procurement_for_subcontract_service.model_product_template
|
||||||
|
msgid "Product Template"
|
||||||
|
msgstr "产品模板"
|
||||||
|
|
||||||
|
#. module: app_procurement_for_subcontract_service
|
||||||
|
#: model:ir.model.fields,field_description:app_procurement_for_subcontract_service.field_product_product_property_subcontracted_service
|
||||||
|
#: model:ir.model.fields,field_description:app_procurement_for_subcontract_service.field_product_template_property_subcontracted_service
|
||||||
|
msgid "Subcontracted Service"
|
||||||
|
msgstr "Subcontracted Service"
|
||||||
|
|
||||||
|
#. module: app_procurement_for_subcontract_service
|
||||||
|
#: model:ir.ui.view,arch_db:app_procurement_for_subcontract_service.view_warehouse
|
||||||
|
msgid "Subcontracting"
|
||||||
|
msgstr "委外服务"
|
||||||
|
|
||||||
|
#. module: app_procurement_for_subcontract_service
|
||||||
|
#: model:ir.model.fields,field_description:app_procurement_for_subcontract_service.field_stock_warehouse_subcontracting_service_proc_rule_id
|
||||||
|
msgid "Subcontracting Service Procurement Rule"
|
||||||
|
msgstr "委外服务补货规则"
|
||||||
|
|
||||||
|
#. module: app_procurement_for_subcontract_service
|
||||||
|
#: model:ir.model,name:app_procurement_for_subcontract_service.model_stock_warehouse
|
||||||
|
msgid "Warehouse"
|
||||||
|
msgstr "仓库"
|
||||||
|
|
||||||
2
app_sale_for_subcontract_service/models/__init__.py
Normal file
2
app_sale_for_subcontract_service/models/__init__.py
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
|
||||||
|
from . import sale_order_line
|
||||||
92
app_sale_for_subcontract_service/models/sale_order_line.py
Normal file
92
app_sale_for_subcontract_service/models/sale_order_line.py
Normal file
@@ -0,0 +1,92 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||||
|
|
||||||
|
from datetime import datetime, timedelta
|
||||||
|
|
||||||
|
from odoo import api, fields, models, _
|
||||||
|
from odoo.tools import DEFAULT_SERVER_DATETIME_FORMAT, float_compare
|
||||||
|
from odoo.exceptions import UserError
|
||||||
|
|
||||||
|
|
||||||
|
class SaleOrderLine(models.Model):
|
||||||
|
_inherit = 'sale.order.line'
|
||||||
|
|
||||||
|
route_id = fields.Many2one('stock.location.route', string='Route', domain=[('sale_selectable', '=', True)], ondelete='restrict')
|
||||||
|
|
||||||
|
@api.multi
|
||||||
|
def _prepare_procurement_values(self, group_id=False):
|
||||||
|
""" Prepare specific key for moves or other components that will be created from a procurement rule
|
||||||
|
comming from a sale order line. This method could be override in order to add other custom key that could
|
||||||
|
be used in move/po creation.
|
||||||
|
"""
|
||||||
|
values = super(SaleOrderLine, self)._prepare_procurement_values(group_id)
|
||||||
|
self.ensure_one()
|
||||||
|
date_planned = datetime.strptime(self.order_id.confirmation_date, DEFAULT_SERVER_DATETIME_FORMAT) \
|
||||||
|
+ timedelta(days=self.customer_lead or 0.0) - timedelta(days=self.order_id.company_id.security_lead)
|
||||||
|
values.update({
|
||||||
|
'company_id': self.order_id.company_id,
|
||||||
|
'group_id': group_id,
|
||||||
|
'sale_line_id': self.id,
|
||||||
|
'date_planned': date_planned.strftime(DEFAULT_SERVER_DATETIME_FORMAT),
|
||||||
|
'route_ids': self.route_id,
|
||||||
|
'warehouse_id': self.order_id.warehouse_id or False,
|
||||||
|
'partner_dest_id': self.order_id.partner_shipping_id
|
||||||
|
})
|
||||||
|
return values
|
||||||
|
|
||||||
|
@api.multi
|
||||||
|
def _action_launch_procurement_rule(self):
|
||||||
|
res = super(SaleOrderLine, self)._action_launch_procurement_rule
|
||||||
|
"""
|
||||||
|
Launch procurement group run method with required/custom fields genrated by a
|
||||||
|
sale order line. procurement group will launch '_run_move', '_run_buy' or '_run_manufacture'
|
||||||
|
depending on the sale order line product rule.
|
||||||
|
"""
|
||||||
|
precision = self.env['decimal.precision'].precision_get('Product Unit of Measure')
|
||||||
|
errors = []
|
||||||
|
for line in self:
|
||||||
|
if line.state != 'sale' or line.product_id.type in ('consu', 'product'):
|
||||||
|
continue
|
||||||
|
qty = 0.0
|
||||||
|
for move in line.move_ids.filtered(lambda r: r.state != 'cancel'):
|
||||||
|
qty += move.product_uom._compute_quantity(move.product_uom_qty, line.product_uom, rounding_method='HALF-UP')
|
||||||
|
if float_compare(qty, line.product_uom_qty, precision_digits=precision) >= 0:
|
||||||
|
continue
|
||||||
|
|
||||||
|
group_id = line.order_id.procurement_group_id
|
||||||
|
if not group_id:
|
||||||
|
group_id = self.env['procurement.group'].create({
|
||||||
|
'name': line.order_id.name, 'move_type': line.order_id.picking_policy,
|
||||||
|
'sale_id': line.order_id.id,
|
||||||
|
'partner_id': line.order_id.partner_shipping_id.id,
|
||||||
|
})
|
||||||
|
line.order_id.procurement_group_id = group_id
|
||||||
|
else:
|
||||||
|
# In case the procurement group is already created and the order was
|
||||||
|
# cancelled, we need to update certain values of the group.
|
||||||
|
updated_vals = {}
|
||||||
|
if group_id.partner_id != line.order_id.partner_shipping_id:
|
||||||
|
updated_vals.update({'partner_id': line.order_id.partner_shipping_id.id})
|
||||||
|
if group_id.move_type != line.order_id.picking_policy:
|
||||||
|
updated_vals.update({'move_type': line.order_id.picking_policy})
|
||||||
|
if updated_vals:
|
||||||
|
group_id.write(updated_vals)
|
||||||
|
|
||||||
|
values = line._prepare_procurement_values(group_id=group_id)
|
||||||
|
product_qty = line.product_uom_qty - qty
|
||||||
|
|
||||||
|
procurement_uom = line.product_uom
|
||||||
|
quant_uom = line.product_id.uom_id
|
||||||
|
get_param = self.env['ir.config_parameter'].sudo().get_param
|
||||||
|
if procurement_uom.id != quant_uom.id and get_param('stock.propagate_uom') != '1':
|
||||||
|
product_qty = line.product_uom._compute_quantity(product_qty, quant_uom, rounding_method='HALF-UP')
|
||||||
|
procurement_uom = quant_uom
|
||||||
|
|
||||||
|
try:
|
||||||
|
self.env['procurement.group'].run(line.product_id, product_qty, procurement_uom, line.order_id.partner_shipping_id.property_stock_customer,
|
||||||
|
line.name, line.order_id.name, values)
|
||||||
|
except UserError as error:
|
||||||
|
errors.append(error.name)
|
||||||
|
if errors:
|
||||||
|
raise UserError('\n'.join(errors))
|
||||||
|
return True
|
||||||
BIN
app_sale_for_subcontract_service/static/description/icon.png
Normal file
BIN
app_sale_for_subcontract_service/static/description/icon.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 78 KiB |
Reference in New Issue
Block a user