-
-
Notifications
You must be signed in to change notification settings - Fork 695
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Correctly segregates templates and variants. Rewritten in new API. Uses the ORM instead of SQL calls. Conforms better to OCA standards 'Quoted qty' is now positive. Explain UoM feature drop. Added directions to block quotations using sale_exceptions Rewrote the tests in python and added new tests regarding warehouses, locations, variants and templates ; and now test the quantity available for sale.
- Loading branch information
Lionel Sausin
committed
Nov 6, 2015
1 parent
1fe140c
commit e4daf3d
Showing
13 changed files
with
478 additions
and
318 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
# -*- coding: utf-8 -*- | ||
############################################################################## | ||
# | ||
# This module is copyright (C) 2014 Numérigraphe SARL. All Rights Reserved. | ||
# | ||
# This program is free software: you can redistribute it and/or modify | ||
# it under the terms of the GNU Affero General Public License as | ||
# published by the Free Software Foundation, either version 3 of the | ||
# License, or (at your option) any later version. | ||
# | ||
# This program is distributed in the hope that it will be useful, | ||
# but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
# GNU Affero General Public License for more details. | ||
# | ||
# You should have received a copy of the GNU Affero General Public License | ||
# along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
# | ||
############################################################################## | ||
|
||
from . import product_template | ||
from . import product_product |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,133 @@ | ||
# -*- coding: utf-8 -*- | ||
############################################################################## | ||
# | ||
# This module is copyright (C) 2014 Numérigraphe SARL. All Rights Reserved. | ||
# | ||
# This program is free software: you can redistribute it and/or modify | ||
# it under the terms of the GNU Affero General Public License as | ||
# published by the Free Software Foundation, either version 3 of the | ||
# License, or (at your option) any later version. | ||
# | ||
# This program is distributed in the hope that it will be useful, | ||
# but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
# GNU Affero General Public License for more details. | ||
# | ||
# You should have received a copy of the GNU Affero General Public License | ||
# along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
# | ||
############################################################################## | ||
|
||
from openerp import models, api, fields | ||
import openerp.addons.decimal_precision as dp | ||
|
||
|
||
class ProductProduct(models.Model): | ||
"""Add the computation for the stock available to promise""" | ||
_inherit = 'product.product' | ||
|
||
quoted_qty = fields.Float( | ||
compute='_get_quoted_qty', | ||
type='float', | ||
digits_compute=dp.get_precision('Product Unit of Measure'), | ||
string='Quoted', | ||
help="Total quantity of this Product that have been included in " | ||
"Quotations (Draft Sale Orders).\n" | ||
"In a context with a single Warehouse, this includes " | ||
"Quotation processed in this Warehouse.\n" | ||
"In a context with a single Stock Location, this includes " | ||
"Quotation processed at any Warehouse using " | ||
"this Location, or any of its children, as it's Stock " | ||
"Location.\n" | ||
"Otherwise, this includes every Quotation.") | ||
|
||
@api.multi | ||
@api.depends('quoted_qty') | ||
def _immediately_usable_qty(self): | ||
"""Subtract quoted quantity from qty available to promise""" | ||
super(ProductProduct, self)._immediately_usable_qty() | ||
for product in self: | ||
product.immediately_usable_qty -= product.quoted_qty | ||
|
||
@api.multi | ||
def _get_quoted_qty(self): | ||
"""Compute the quantities in Quotations.""" | ||
|
||
domain = [ | ||
('state', '=', 'draft'), | ||
('product_id', 'in', [p.id for p in self])] | ||
|
||
# Limit to a specific company | ||
if self.env.context.get('force_company', False): | ||
domain.append(('company_id', '=', | ||
self.env.context['force_company'])) | ||
# when we search locations, should children be searched too? | ||
if self.env.context.get('compute_child', True): | ||
loc_op = 'child_of' | ||
else: | ||
loc_op = 'in' | ||
# Limit to some locations | ||
# Take warehouses that have these locations as stock locations | ||
if self.env.context.get('location', False): | ||
# Search by ID | ||
if isinstance(self.env.context['location'], (int, long)): | ||
domain.append( | ||
('order_id.warehouse_id.lot_stock_id', loc_op, | ||
[self.env.context['location']])) | ||
# Search by name | ||
elif isinstance(self.env.context['location'], basestring): | ||
location_ids = [ | ||
l.id | ||
for l in self.env['stock.location'].search([ | ||
('complete_name', 'ilike', | ||
self.env.context['location'])])] | ||
domain.append( | ||
('order_id.warehouse_id.lot_stock_id', loc_op, | ||
location_ids)) | ||
# Search by whatever the context has - probably a list of IDs | ||
else: | ||
domain.append( | ||
('order_id.warehouse_id.lot_stock_id', loc_op, | ||
self.env.context['location'])) | ||
# Limit to a warehouse | ||
if self.env.context.get('warehouse', False): | ||
domain.append( | ||
('order_id.warehouse_id', '=', self.env.context['warehouse'])) | ||
# Limit to a period | ||
from_date = self.env.context.get('from_date', False) | ||
to_date = self.env.context.get('to_date', False) | ||
if from_date: | ||
domain.extend([ | ||
('order_id.requested_date', '>=', from_date), | ||
'&', # only consider 'date' when 'equested_date' is empty | ||
('order_id.requested_date', '=', False), | ||
('order_id.date', '>=', from_date), | ||
]) | ||
if to_date: | ||
domain.extend([ | ||
('order_id.requested_date', '<=', to_date), | ||
'&', # only consider 'date' when 'equested_date' is empty | ||
('order_id.requested_date', '=', False), | ||
('order_id.date', '<=', to_date), | ||
]) | ||
|
||
# Compute the quoted quantity for each product | ||
results = {} | ||
for group in self.env['sale.order.line'].read_group( | ||
domain, ['product_uom_qty', 'product_id', 'product_uom'], | ||
['product_id', 'product_uom'], | ||
lazy=False): | ||
product_id = group['product_id'][0] | ||
uom_id = group['product_uom'][0] | ||
# Compute the quoted quantity | ||
# Convert to the product's UoM | ||
# Rounding is OK since small values have not been squashed before | ||
results[product_id] = ( | ||
results.get(product_id, 0.0) + | ||
self.env['product.uom'].sudo()._compute_qty( | ||
uom_id, | ||
group['product_uom_qty'], | ||
self.browse(product_id).uom_id.id)) | ||
|
||
for product in self: | ||
product.quoted_qty = results.get(product.id, 0.0) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
# -*- coding: utf-8 -*- | ||
############################################################################## | ||
# | ||
# This module is copyright (C) 2014 Numérigraphe SARL. All Rights Reserved. | ||
# | ||
# This program is free software: you can redistribute it and/or modify | ||
# it under the terms of the GNU Affero General Public License as | ||
# published by the Free Software Foundation, either version 3 of the | ||
# License, or (at your option) any later version. | ||
# | ||
# This program is distributed in the hope that it will be useful, | ||
# but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
# GNU Affero General Public License for more details. | ||
# | ||
# You should have received a copy of the GNU Affero General Public License | ||
# along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
# | ||
############################################################################## | ||
|
||
from openerp import models, fields, api | ||
from openerp.addons import decimal_precision as dp | ||
|
||
|
||
class ProductTemplate(models.Model): | ||
_inherit = 'product.template' | ||
|
||
quoted_qty = fields.Float( | ||
compute='_get_quoted_qty', | ||
type='float', | ||
digits_compute=dp.get_precision('Product Unit of Measure'), | ||
string='Quoted', | ||
help="Total quantity of this Product that have been included in " | ||
"Quotations (Draft Sale Orders).\n" | ||
"In a context with a single Warehouse, this includes " | ||
"Quotation processed in this Warehouse.\n" | ||
"In a context with a single Stock Location, this includes " | ||
"Quotation processed at any Warehouse using " | ||
"this Location, or any of its children, as it's Stock " | ||
"Location.\n" | ||
"Otherwise, this includes every Quotation.") | ||
|
||
@api.multi | ||
@api.depends('product_variant_ids.quoted_qty') | ||
def _get_quoted_qty(self): | ||
"""Compute the quantity using all the variants""" | ||
for tmpl in self: | ||
tmpl.quoted_qty = sum( | ||
[v.quoted_qty for v in tmpl.product_variant_ids]) |
Oops, something went wrong.