diff --git a/addons/purchase/models/product.py b/addons/purchase/models/product.py index b6459638716..9c53328324a 100644 --- a/addons/purchase/models/product.py +++ b/addons/purchase/models/product.py @@ -5,6 +5,7 @@ from datetime import timedelta from odoo import api, fields, models, _ from odoo.addons.base.models.res_partner import WARNING_MESSAGE, WARNING_HELP from odoo.tools.float_utils import float_round +from dateutil.relativedelta import relativedelta class ProductTemplate(models.Model): @@ -43,8 +44,7 @@ class ProductTemplate(models.Model): action['domain'] = ['&', ('state', 'in', ['purchase', 'done']), ('product_tmpl_id', 'in', self.ids)] action['context'] = { 'graph_measure': 'qty_ordered', - 'search_default_orders': 1, - 'time_ranges': {'field': 'date_approve', 'range': 'last_365_days'} + 'search_default_later_than_a_year_ago': True } return action @@ -56,13 +56,12 @@ class ProductProduct(models.Model): purchased_product_qty = fields.Float(compute='_compute_purchased_product_qty', string='Purchased') def _compute_purchased_product_qty(self): - date_from = fields.Datetime.to_string(fields.datetime.now() - timedelta(days=365)) + date_from = fields.Datetime.to_string(fields.Date.context_today(self) - relativedelta(years=1)) domain = [ - ('state', 'in', ['purchase', 'done']), + ('order_id.state', 'in', ['purchase', 'done']), ('product_id', 'in', self.ids), - ('date_order', '>', date_from) + ('order_id.date_approve', '>=', date_from) ] - PurchaseOrderLines = self.env['purchase.order.line'].search(domain) order_lines = self.env['purchase.order.line'].read_group(domain, ['product_id', 'product_uom_qty'], ['product_id']) purchased_data = dict([(data['product_id'][0], data['product_uom_qty']) for data in order_lines]) for product in self: @@ -75,9 +74,8 @@ class ProductProduct(models.Model): action = self.env.ref('purchase.action_purchase_order_report_all').read()[0] action['domain'] = ['&', ('state', 'in', ['purchase', 'done']), ('product_id', 'in', self.ids)] action['context'] = { - 'search_default_last_year_purchase': 1, - 'search_default_status': 1, 'search_default_order_month': 1, - 'graph_measure': 'qty_ordered' + 'graph_measure': 'qty_ordered', + 'search_default_later_than_a_year_ago': True } return action diff --git a/addons/purchase/models/purchase.py b/addons/purchase/models/purchase.py index 868dfe37b26..dc52d85cae7 100644 --- a/addons/purchase/models/purchase.py +++ b/addons/purchase/models/purchase.py @@ -98,7 +98,9 @@ class PurchaseOrder(models.Model): ], string='Billing Status', compute='_get_invoiced', store=True, readonly=True, copy=False, default='no') # There is no inverse function on purpose since the date may be different on each line - date_planned = fields.Datetime(string='Receipt Date', index=True) + date_planned = fields.Datetime(string='Receipt Date', index=True, + help='This is the Receipt Date promised by the supplier. If set, the receipt will be scheduled at this date.') + date_calendar_start = fields.Datetime(compute='_compute_date_calendar_start', readonly=True, store=True) amount_untaxed = fields.Monetary(string='Untaxed Amount', store=True, readonly=True, compute='_amount_all', tracking=True) amount_tax = fields.Monetary(string='Taxes', store=True, readonly=True, compute='_amount_all') @@ -128,6 +130,11 @@ class PurchaseOrder(models.Model): for order in self: order.access_url = '/my/purchase/%s' % (order.id) + @api.depends('state', 'date_order', 'date_approve') + def _compute_date_calendar_start(self): + for order in self: + order.date_calendar_start = order.date_approve if (order.state in ['purchase', 'done']) else order.date_order + @api.model def _name_search(self, name, args=None, operator='ilike', limit=100, name_get_uid=None): args = args or [] diff --git a/addons/purchase/report/purchase_report_views.xml b/addons/purchase/report/purchase_report_views.xml index 250443025ff..a9fff659f69 100644 --- a/addons/purchase/report/purchase_report_views.xml +++ b/addons/purchase/report/purchase_report_views.xml @@ -23,29 +23,6 @@ - - - Monthly Purchases - purchase.report - [('state','!=','cancel')] - - - - Price Per Vendor - purchase.report - [('state','!=','draft'),('state','!=','cancel')] - - {'group_by': ['partner_id'], 'col_group_by': ['product_id'], 'measures': ['price_average']} - - - Average Delivery Time - purchase.report - [('state','!=','draft'),('state','!=','cancel')] - - {'group_by': ['partner_id'], 'measures': ['delay_pass']} - - - report.purchase.order.search purchase.report @@ -53,6 +30,7 @@ + @@ -87,8 +65,6 @@ current - - - + diff --git a/addons/purchase/views/purchase_views.xml b/addons/purchase/views/purchase_views.xml index de63c1550c4..da5d47989b4 100644 --- a/addons/purchase/views/purchase_views.xml +++ b/addons/purchase/views/purchase_views.xml @@ -24,19 +24,31 @@ + parent="menu_purchase_config" sequence="30"/> + + + + + + + parent="purchase.menu_product_in_config_purchase" sequence="3" /> - + + parent="purchase.menu_unit_of_measure_in_config_purchase" sequence="5" groups="uom.group_uom"/> + + @@ -87,9 +99,8 @@ purchase.order - + - @@ -548,8 +559,8 @@

Create a request for quotation

- The quotation contains the history of the discussion - you had with your vendor. + The requests for quotation are documents that will be sent to your suppliers to request prices for different products you consider buying. + Once an agreement has been found with the supplier, they will be confirmed and turned into purchase orders.

@@ -568,9 +579,9 @@ {}

- Create a quotation + Create a purchase order

- It will be converted into a purchase order. + Once you ordered your products to your supplier, confirm your request for quotation and it will turn into a purchase order.

diff --git a/addons/purchase/views/res_config_settings_views.xml b/addons/purchase/views/res_config_settings_views.xml index 98ba8144739..352c9cd1eb2 100644 --- a/addons/purchase/views/res_config_settings_views.xml +++ b/addons/purchase/views/res_config_settings_views.xml @@ -109,6 +109,23 @@

Products

+
+
+ +
+
+
+
diff --git a/addons/purchase_requisition/models/purchase_requisition.py b/addons/purchase_requisition/models/purchase_requisition.py index 1b863ba2f35..3438498fc41 100644 --- a/addons/purchase_requisition/models/purchase_requisition.py +++ b/addons/purchase_requisition/models/purchase_requisition.py @@ -24,10 +24,10 @@ class PurchaseRequisitionType(models.Model): name = fields.Char(string='Agreement Type', required=True, translate=True) sequence = fields.Integer(default=1) exclusive = fields.Selection([ - ('exclusive', 'Select only one RFQ (exclusive)'), ('multiple', 'Select multiple RFQ')], + ('exclusive', 'Select only one RFQ (exclusive)'), ('multiple', 'Select multiple RFQ (non-exclusive)')], string='Agreement Selection Type', required=True, default='multiple', help="""Select only one RFQ (exclusive): when a purchase order is confirmed, cancel the remaining purchase order.\n - Select multiple RFQ: allows multiple purchase orders. On confirmation of a purchase order it does not cancel the remaining orders""") + Select multiple RFQ (non-exclusive): allows multiple purchase orders. On confirmation of a purchase order it does not cancel the remaining orders""") quantity_copy = fields.Selection([ ('copy', 'Use quantities of agreement'), ('none', 'Set quantities manually')], string='Quantities', required=True, default='none') diff --git a/addons/purchase_requisition/views/purchase_requisition_views.xml b/addons/purchase_requisition/views/purchase_requisition_views.xml index afbbb59fee6..fc82df844df 100644 --- a/addons/purchase_requisition/views/purchase_requisition_views.xml +++ b/addons/purchase_requisition/views/purchase_requisition_views.xml @@ -134,7 +134,7 @@ - +