diff --git a/addons/purchase/__manifest__.py b/addons/purchase/__manifest__.py index 655a1fa7fde..01cb6908404 100644 --- a/addons/purchase/__manifest__.py +++ b/addons/purchase/__manifest__.py @@ -36,6 +36,7 @@ Dashboard / Reports for Purchase Management will include: 'views/purchase_views.xml', 'views/procurement_views.xml', 'views/stock_views.xml', + 'views/stock_config_settings_views.xml', 'views/res_partner_views.xml', 'report/purchase_report_views.xml', 'data/mail_template_data.xml', diff --git a/addons/purchase/models/__init__.py b/addons/purchase/models/__init__.py index dead81bb8fb..6402c67a0cd 100644 --- a/addons/purchase/models/__init__.py +++ b/addons/purchase/models/__init__.py @@ -3,6 +3,7 @@ import account_invoice import purchase +import stock_config_settings import res_company import res_config import res_partner diff --git a/addons/purchase/models/res_config.py b/addons/purchase/models/res_config.py index 68137a57b20..036e7d0f2b6 100644 --- a/addons/purchase/models/res_config.py +++ b/addons/purchase/models/res_config.py @@ -10,7 +10,6 @@ class PurchaseConfigSettings(models.TransientModel): company_id = fields.Many2one('res.company', string='Company', required=True, default=lambda self: self.env.user.company_id) - po_lead = fields.Float(related='company_id.po_lead', string="Purchase Lead Time") lock_confirmed_po = fields.Boolean("Lock Confirmed Orders", default=lambda self: self.env.user.company_id.po_lock == 'lock') po_lock = fields.Selection(related='company_id.po_lock', string="Purchase Order Modification *") po_order_approval = fields.Boolean("Order Approval", default=lambda self: self.env.user.company_id.po_double_validation == 'two_step') diff --git a/addons/purchase/models/stock_config_settings.py b/addons/purchase/models/stock_config_settings.py new file mode 100644 index 00000000000..d69b07bc8bb --- /dev/null +++ b/addons/purchase/models/stock_config_settings.py @@ -0,0 +1,11 @@ +# -*- coding: utf-8 -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +from odoo import api, fields, models + + +class StockConfigSettings(models.TransientModel): + _inherit = 'stock.config.settings' + + po_lead = fields.Float(related='company_id.po_lead', default=lambda self: self.env.user.company_id.po_lead) + default_new_po_lead = fields.Boolean(string="Security Lead Time for Purchase", default_model="stock.config.settings", help="Margin of error for vendor lead times. When the system generates Purchase Orders for reordering products,they will be scheduled that many days earlier to cope with unexpected vendor delays.") diff --git a/addons/purchase/views/res_config_views.xml b/addons/purchase/views/res_config_views.xml index 2f55188a4d2..80875a3c6d1 100644 --- a/addons/purchase/views/res_config_views.xml +++ b/addons/purchase/views/res_config_views.xml @@ -140,17 +140,6 @@ -
-
-
-
-
-

Logistics

diff --git a/addons/purchase/views/stock_config_settings_views.xml b/addons/purchase/views/stock_config_settings_views.xml new file mode 100644 index 00000000000..1c29d7f314c --- /dev/null +++ b/addons/purchase/views/stock_config_settings_views.xml @@ -0,0 +1,42 @@ + + + + + stock.config.settings.view.form.inherit.purchase + stock.config.settings + + +
+
+
+ +
+
+
+
+
+
+ +
+
+
+
+
+
+
+
+
diff --git a/addons/sale_stock/__manifest__.py b/addons/sale_stock/__manifest__.py index d3c371fbc01..e6ed99c5fee 100644 --- a/addons/sale_stock/__manifest__.py +++ b/addons/sale_stock/__manifest__.py @@ -32,6 +32,7 @@ You can choose flexible invoicing methods: 'views/sale_order_views.xml', 'views/stock_views.xml', 'views/sale_config_settings_views.xml', + 'views/stock_config_settings_views.xml', 'views/account_invoice_views.xml', 'report/sale_order_report_templates.xml', 'report/stock_report_deliveryslip.xml', diff --git a/addons/sale_stock/models/__init__.py b/addons/sale_stock/models/__init__.py index 961eddcf23b..71d84fbca4f 100644 --- a/addons/sale_stock/models/__init__.py +++ b/addons/sale_stock/models/__init__.py @@ -7,4 +7,5 @@ from . import product from . import res_company from . import sale_order from . import sale_config_settings +from . import stock_config_settings from . import stock diff --git a/addons/sale_stock/models/stock_config_settings.py b/addons/sale_stock/models/stock_config_settings.py new file mode 100644 index 00000000000..5d558712a81 --- /dev/null +++ b/addons/sale_stock/models/stock_config_settings.py @@ -0,0 +1,15 @@ +# -*- coding: utf-8 -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +from odoo import fields, models + + +class StockConfigSettings(models.TransientModel): + _inherit = 'stock.config.settings' + + security_lead = fields.Float(related='company_id.security_lead') + default_new_security_lead = fields.Boolean(string="Security Lead Time for Sales", default_model="stock.config.settings", help="Margin of error for dates promised to customers. Products will be scheduled for procurement and delivery that many days earlier than the actual promised date, to cope with unexpected delays in the supply chain.") + default_picking_policy = fields.Selection([ + ('direct', 'Ship products as soon as available, with back orders'), + ('one', 'Ship all products at once') + ], "Shipping Management", default='direct', default_model="sale.order") diff --git a/addons/sale_stock/views/stock_config_settings_views.xml b/addons/sale_stock/views/stock_config_settings_views.xml new file mode 100644 index 00000000000..bc019ab07a4 --- /dev/null +++ b/addons/sale_stock/views/stock_config_settings_views.xml @@ -0,0 +1,59 @@ + + + + + stock.config.settings.inherit.sale.stock + stock.config.settings + + +
+
+
+
+
+
+
+
+
+
+
+
+
+ +
+
+
+
+
+
+
+ +
diff --git a/addons/stock/models/stock_config_settings.py b/addons/stock/models/stock_config_settings.py index 10a62afcc97..d4ae47461f3 100644 --- a/addons/stock/models/stock_config_settings.py +++ b/addons/stock/models/stock_config_settings.py @@ -4,126 +4,68 @@ from odoo import api, fields, models -class StockSettings(models.TransientModel): +class StockConfigSettings(models.TransientModel): _name = 'stock.config.settings' _inherit = 'res.config.settings' - @api.model - def default_get(self, fields): - res = super(StockSettings, self).default_get(fields) - if 'warehouse_and_location_usage_level' in fields or not fields: - res['warehouse_and_location_usage_level'] = int(res.get('group_stock_multi_locations', False)) + int(res.get('group_stock_multi_warehouses', False)) - return res - - group_product_variant = fields.Selection([ - (0, "No variants on products"), - (1, 'Products can have several attributes, defining variants (Example: size, color,...)') - ], "Product Variants", - implied_group='product.group_product_variant', - help='Work with product variant allows you to define some variant of the same products, an ease the product management in the ecommerce for example') company_id = fields.Many2one( 'res.company', 'Company', default=lambda self: self.env.user.company_id, required=True) module_procurement_jit = fields.Selection([ - (1, 'Reserve products immediately after the sales order confirmation'), - (0, 'Reserve products manually or based on automatic scheduler') - ], "Procurements", - help="""Allows you to automatically reserve the available - products when confirming a sales order. - This installs the module procurement_jit.""") - module_product_expiry = fields.Selection([ - (0, 'Do not use Expiration Date on serial numbers'), - (1, 'Define Expiration Date on serial numbers') - ], "Expiration Dates", - help="""Track different dates on products and serial numbers. - The following dates can be tracked: - - end of life - - best before date - - removal date - - alert date. - This installs the module product_expiry.""") - group_uom = fields.Selection([ - (0, 'Products have only one unit of measure (easier)'), - (1, 'Some products may be sold/purchased in different units of measure (advanced)') - ], "Units of Measure", - implied_group='product.group_uom', - help="""Allows you to select and maintain different units of measure for products.""") - group_stock_packaging = fields.Selection([ - (0, 'Do not manage packaging'), - (1, 'Manage available packaging options per products') - ], "Packaging Methods", + (1, 'Immediately after sales order confirmation'), + (0, 'Manually or based on automatic scheduler') + ], "Reservation", + help="Reserving products manually in delivery orders or by running the scheduler is advised to better manage priorities in case of long customer lead times or/and frequent stock-outs.") + module_product_expiry = fields.Boolean("Expiration Dates", + help="Track following dates on lots & serial numbers: best before, removal, end of life, alert. \n Such dates are set automatically at lot/serial number creation based on values set on the product (in days).") + group_stock_packaging = fields.Boolean('Packaging', implied_group='product.group_stock_packaging', - help="""Allows you to create and manage your packaging dimensions and types you want to be maintained in your system.""") - group_stock_production_lot = fields.Selection([ - (0, 'Do not track individual product items'), - (1, 'Track lots or serial numbers') - ], "Lots and Serial Numbers", - implied_group='stock.group_production_lot', - help="""This allows you to assign a lot (or serial number) to the pickings and moves. This can make it possible to know which production lot was sent to a certain client, ...""") - group_stock_tracking_lot = fields.Selection([ - (0, 'Do not manage packaging'), - (1, 'Record packages used on packing: pallets, boxes, ...') - ], "Packages", + help="Select or scan the packaging used to transfer products in operations. This allows to update or check the unit # transferred (which must be a multiple of the unit # per package). Packaging types are set on product detail form.") + group_stock_production_lot = fields.Boolean("Lots & Serial Numbers", + implied_group='stock.group_production_lot') + group_stock_tracking_lot = fields.Boolean("Packages", implied_group='stock.group_tracking_lot', - help="""This allows to manipulate packages. You can put something in, take something from a package, but also move entire packages and put them even in another package. """) - group_stock_tracking_owner = fields.Selection([ - (0, 'All products in your warehouse belong to your company'), - (1, 'Manage consignee stocks (advanced)') - ], "Product Owners", - implied_group='stock.group_tracking_owner', - help="""This way you can receive products attributed to a certain owner. """) - group_stock_adv_location = fields.Selection([ - (0, 'No automatic routing of products'), - (1, 'Advanced routing of products using rules') - ], "Routes", + help="Put products in packages and get shipping labels per package unit thanks to shipping connectors.") + group_stock_tracking_owner = fields.Boolean("Consignment", + implied_group='stock.group_tracking_owner') + group_stock_adv_location = fields.Boolean("Multi-Step Routes", implied_group='stock.group_adv_location', - help="""This option supplements the warehouse application by effectively implementing Push and Pull inventory flows through Routes.""") - group_warning_stock = fields.Selection([ - (0, 'All the partners can be used in pickings'), - (1, 'An informative or blocking warning can be set on a partner') - ], "Warning", implied_group='stock.group_warning_stock') - decimal_precision = fields.Integer('Decimal precision on weight', help="As an example, a decimal precision of 2 will allow weights like: 9.99 kg, whereas a decimal precision of 4 will allow weights like: 0.0231 kg.") - propagation_minimum_delta = fields.Integer("Minimum days to trigger a propagation of date change in pushed/pull flows.", related='company_id.propagation_minimum_delta') - module_stock_dropshipping = fields.Selection([ - (0, 'Suppliers always deliver to your warehouse(s)'), - (1, "Allow suppliers to deliver directly to your customers") - ], "Dropshipping", - help='\nCreates the dropship route and add more complex tests\n' - '-This installs the module stock_dropshipping.') - module_stock_picking_wave = fields.Selection([ - (0, 'Manage pickings one at a time'), - (1, 'Manage picking in batch per worker') - ], "Picking Waves", - help='Install the picking wave module which will help you grouping your pickings and processing them in batch') - module_stock_calendar = fields.Selection([ - (0, 'Set lead times in calendar days (easy)'), - (1, "Adapt lead times using the suppliers' open days calendars (advanced)") - ], "Minimum Stock Rules", - help='This allows you to handle minimum stock rules differently by the possibility to take into account the purchase and delivery calendars \n-This installs the module stock_calendar.') - module_stock_barcode = fields.Boolean("Barcode scanner support") - module_delivery_dhl = fields.Boolean("DHL integration") - module_delivery_fedex = fields.Boolean("Fedex integration") - module_delivery_ups = fields.Boolean("UPS integration") - module_delivery_usps = fields.Boolean("USPS integration") - # Warehouse and location usage_level - warehouse_and_location_usage_level = fields.Selection([ - (0, 'Manage only 1 Warehouse with only 1 stock location'), - (1, 'Manage only 1 Warehouse, composed by several stock locations'), - (2, 'Manage several Warehouses, each one composed by several stock locations') - ], "Warehouses and Locations usage level") - group_stock_multi_locations = fields.Boolean('Manage several stock locations', implied_group='stock.group_stock_multi_locations') - group_stock_multi_warehouses = fields.Boolean('Manage several warehouses', implied_group='stock.group_stock_multi_warehouses') - module_quality = fields.Boolean(string="Quality", help="This module allows you to generate quality alerts and quality check") + help="Add and customize route operations to process product moves in your warehouse(s): e.g. unload > quality control > stock for incoming products, pick > pack > ship for outgoing products. \n You can also set putaway strategies on warehouse locations in order to send incoming products into specific child locations straight away (e.g. specific bins, racks).") + group_warning_stock = fields.Boolean("Warnings", implied_group='stock.group_warning_stock') + propagation_minimum_delta = fields.Integer(related='company_id.propagation_minimum_delta', string="No Rescheduling Propagation") + default_new_propagation_minimum_delta = fields.Boolean(string="No Rescheduling Propagation", default_model="stock.config.settings", help="Rescheduling applies to any chain of operations (e.g. Make To Order, Pick Pack Ship). In the case of MTO sales, a vendor delay (updated incoming date) impacts the expected delivery date to the customer. \n This option allows to not propagate the rescheduling if the change is not critical.") + module_stock_picking_wave = fields.Boolean("Picking Waves") + module_stock_calendar = fields.Boolean("Vendor Calendar for Reordering", + help='Scheduled dates of requests for quotation generated from reordering rules are based on vendor lead times (defined on products).\nBy default, such a scheduling is made on calendar days. This option allow to adapt the scheduling with vendor calendars to set on reordering rules.') + module_stock_barcode = fields.Boolean("Barcode Scanner") + module_delivery_dhl = fields.Boolean("DHL") + module_delivery_fedex = fields.Boolean("FedEx") + module_delivery_ups = fields.Boolean("UPS") + module_delivery_usps = fields.Boolean("USPS") + group_uom = fields.Boolean("Units of Measure", implied_group='product.group_uom') + group_product_variant = fields.Boolean("Attributes & Variants", implied_group='product.group_product_variant') + group_stock_multi_locations = fields.Boolean('Storage Locations', implied_group='stock.group_stock_multi_locations', + help="Store products in specific locations of your warehouse (e.g. bins, racks) and to track inventory accordingly.") + group_stock_multi_warehouses = fields.Boolean('Multi-Warehouses', implied_group='stock.group_stock_multi_warehouses') + module_quality = fields.Boolean(string="Quality Control") + module_mrp = fields.Boolean(string="Manufacturing") + module_sale = fields.Boolean(string="Sales") + module_purchase = fields.Boolean(string="Purchase") - @api.onchange('warehouse_and_location_usage_level') - def onchange_warehouse_and_location_usage_level(self): - self.group_stock_multi_locations = self.warehouse_and_location_usage_level > 0 - self.group_stock_multi_warehouses = self.warehouse_and_location_usage_level > 1 + @api.onchange('group_stock_multi_locations') + def _onchange_group_stock_multi_locations(self): + if not self.group_stock_multi_locations: + self.group_stock_multi_warehouses = False + + @api.onchange('group_stock_multi_warehouses') + def _onchange_group_stock_multi_warehouses(self): + if self.group_stock_multi_warehouses: + self.group_stock_multi_locations = True @api.onchange('group_stock_adv_location') def onchange_adv_location(self): - if self.group_stock_adv_location and self.warehouse_and_location_usage_level == 0: - self.warehouse_and_location_usage_level = 1 + if self.group_stock_adv_location and not self.group_stock_multi_locations: + self.group_stock_multi_locations = True @api.multi def set_group_stock_multi_locations(self): diff --git a/addons/stock/views/stock_config_settings_views.xml b/addons/stock/views/stock_config_settings_views.xml index 1e596c20269..8a714c446df 100644 --- a/addons/stock/views/stock_config_settings_views.xml +++ b/addons/stock/views/stock_config_settings_views.xml @@ -7,84 +7,338 @@
-
- - - - - -