From dc8246eb03b37d2be7bff497f656cd183ba8a5c9 Mon Sep 17 00:00:00 2001 From: Simon Lejeune Date: Fri, 4 Apr 2014 13:23:08 +0200 Subject: [PATCH] [ADD] sale_layout module allowing to set categories and subtotals on invoice and sale order bzr revid: sle@openerp.com-20140404112308-aopihnefnf55b4er --- addons/account/views/report_invoice.xml | 2 +- addons/sale/views/report_saleorder.xml | 2 +- addons/sale_layout/__init__.py | 1 + addons/sale_layout/__openerp__.py | 44 ++++++ .../data/sale_layout_category_data.xml | 20 +++ addons/sale_layout/models/__init__.py | 1 + addons/sale_layout/models/sale_layout.py | 137 ++++++++++++++++++ .../sale_layout/security/ir.model.access.csv | 5 + .../views/report_invoice_layouted.xml | 65 +++++++++ .../views/report_quotation_layouted.xml | 70 +++++++++ .../views/sale_layout_category_view.xml | 120 +++++++++++++++ .../views/sale_layout_template.xml | 42 ++++++ 12 files changed, 507 insertions(+), 2 deletions(-) create mode 100644 addons/sale_layout/__init__.py create mode 100644 addons/sale_layout/__openerp__.py create mode 100644 addons/sale_layout/data/sale_layout_category_data.xml create mode 100644 addons/sale_layout/models/__init__.py create mode 100644 addons/sale_layout/models/sale_layout.py create mode 100644 addons/sale_layout/security/ir.model.access.csv create mode 100644 addons/sale_layout/views/report_invoice_layouted.xml create mode 100644 addons/sale_layout/views/report_quotation_layouted.xml create mode 100644 addons/sale_layout/views/sale_layout_category_view.xml create mode 100644 addons/sale_layout/views/sale_layout_template.xml diff --git a/addons/account/views/report_invoice.xml b/addons/account/views/report_invoice.xml index bc0dc5e92a2..437c9726bf3 100644 --- a/addons/account/views/report_invoice.xml +++ b/addons/account/views/report_invoice.xml @@ -54,7 +54,7 @@ Amount - + diff --git a/addons/sale/views/report_saleorder.xml b/addons/sale/views/report_saleorder.xml index c6f237e3ac3..40c8afa045d 100644 --- a/addons/sale/views/report_saleorder.xml +++ b/addons/sale/views/report_saleorder.xml @@ -64,7 +64,7 @@ Price - + diff --git a/addons/sale_layout/__init__.py b/addons/sale_layout/__init__.py new file mode 100644 index 00000000000..bff786c0885 --- /dev/null +++ b/addons/sale_layout/__init__.py @@ -0,0 +1 @@ +import models diff --git a/addons/sale_layout/__openerp__.py b/addons/sale_layout/__openerp__.py new file mode 100644 index 00000000000..b8fcefc6adc --- /dev/null +++ b/addons/sale_layout/__openerp__.py @@ -0,0 +1,44 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# OpenERP, Open Source Management Solution +# Copyright (C) 2014-Today OpenERP SA (). +# +# 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 . +# +############################################################################## + +{ + 'name': 'Sale Layout', + 'version': '1.0', + 'sequence': 14, + 'summary': 'Sale Layout, page-break, subtotals, separators, report', + 'description': """ +Manage your sales reports +========================= +With this module you can personnalize the sale order and invoice report with +separators, page-breaks or subtotals. + """, + 'author': 'OpenERP SA', + 'website': 'http://www.openerp.com', + 'depends': ['sale', 'report'], + 'category': 'Sale', + 'data': ['views/sale_layout_category_view.xml', + 'views/report_invoice_layouted.xml', + 'views/report_quotation_layouted.xml', + 'views/sale_layout_template.xml', + 'security/ir.model.access.csv'], + 'demo': ['data/sale_layout_category_data.xml'], + 'installable': True, +} diff --git a/addons/sale_layout/data/sale_layout_category_data.xml b/addons/sale_layout/data/sale_layout_category_data.xml new file mode 100644 index 00000000000..858654e427f --- /dev/null +++ b/addons/sale_layout/data/sale_layout_category_data.xml @@ -0,0 +1,20 @@ + + + + + Services + + + + 1 + + + + Material + + + + 10 + + + diff --git a/addons/sale_layout/models/__init__.py b/addons/sale_layout/models/__init__.py new file mode 100644 index 00000000000..9e9b002e402 --- /dev/null +++ b/addons/sale_layout/models/__init__.py @@ -0,0 +1 @@ +import sale_layout diff --git a/addons/sale_layout/models/sale_layout.py b/addons/sale_layout/models/sale_layout.py new file mode 100644 index 00000000000..d6e7e435b99 --- /dev/null +++ b/addons/sale_layout/models/sale_layout.py @@ -0,0 +1,137 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# OpenERP, Open Source Management Solution +# Copyright (C) 2014-Today OpenERP SA (). +# +# 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 . +# +############################################################################## + +from openerp.osv import osv, fields +from itertools import groupby + + +def grouplines(self, ordered_lines, sortkey): + """Return lines from a specified invoice or sale order grouped by category""" + grouped_lines = [] + for key, valuesiter in groupby(ordered_lines, sortkey): + group = {} + group['category'] = key + group['lines'] = list(v for v in valuesiter) + + if 'subtotal' in key and key.subtotal is True: + group['subtotal'] = sum(line.price_subtotal for line in group['lines']) + grouped_lines.append(group) + + return grouped_lines + + +class SaleLayoutCategory(osv.Model): + _name = 'sale_layout.category' + _order = 'sequence' + _columns = { + 'name': fields.char('Name', required=True), + 'sequence': fields.integer('Sequence', required=True), + 'subtotal': fields.boolean('Add subtotal'), + 'separator': fields.boolean('Add separator'), + 'pagebreak': fields.boolean('Add pagebreak') + } + + _defaults = { + 'subtotal': True, + 'separator': True, + 'pagebreak': False, + 'sequence': 10 + } + + # We want to forbid edit of a category if it is already linked to a report. + def _check(self, cr, uid, ids): + for cat in self.browse(cr, uid, ids): + invoice_obj = self.pool.get('account.invoice.line') + sale_obj = self.pool.get('sale.order.line') + ids = invoice_obj.search(cr, uid, [('sale_layout_cat_id', '=', cat.id)]) + ids += sale_obj.search(cr, uid, [('sale_layout_cat_id', '=', cat.id)]) + + if len(ids) > 0: + return False + + return True + + _constraints = [( + _check, + 'This category could not be modified nor deleted because it is still used in an invoice or' + ' a sale report.', ['name'] + )] + + +class AccountInvoice(osv.Model): + _inherit = 'account.invoice' + + def sale_layout_lines(self, cr, uid, ids, context, invoice_id, *args, **kwargs): + """ + Returns invoice lines from a specified invoice ordered by + sale_layout_category sequence. Used in sale_layout module. + + :Parameters: + -'invoice_id' (int): specify the concerned invoice. + """ + ordered_lines = self.browse(cr, uid, invoice_id, context=context).invoice_line + # We chose to group first by category model and, if not present, by invoice name + sortkey = lambda x: x.sale_layout_cat_id if x.sale_layout_cat_id else '' + + return grouplines(self, ordered_lines, sortkey) + + +class AccountInvoiceLine(osv.Model): + _inherit = 'account.invoice.line' + _columns = { + 'sale_layout_cat_id': fields.many2one('sale_layout.category', + 'Layout Category'), + 'categ_sequence': fields.related('sale_layout_cat_id', + 'sequence', type='integer', + string='Layout Sequence', store=True) + # Store is intentionally set in order to keep the "historic" order. + } + _order = 'invoice_id, categ_sequence, sequence, id' + + +class SaleOrder(osv.Model): + _inherit = 'sale.order' + + def sale_layout_lines(self, cr, uid, ids, context, order_id, *args, **kwargs): + """ + Returns order lines from a specified sale ordered by + sale_layout_category sequence. Used in sale_layout module. + + :Parameters: + -'order_id' (int): specify the concerned sale order. + """ + ordered_lines = self.browse(cr, uid, order_id, context=context).order_line + sortkey = lambda x: x.sale_layout_cat_id if x.sale_layout_cat_id else '' + + return grouplines(self, ordered_lines, sortkey) + + +class SaleOrderLine(osv.Model): + _inherit = 'sale.order.line' + _columns = { + 'sale_layout_cat_id': fields.many2one('sale_layout.category', + 'Layout Category'), + 'categ_sequence': fields.related('sale_layout_cat_id', + 'sequence', type='integer', + string='Layout Sequence', store=True) + # Store is intentionally set in order to keep the "historic" order. + } + _order = 'order_id, categ_sequence, sequence, id' diff --git a/addons/sale_layout/security/ir.model.access.csv b/addons/sale_layout/security/ir.model.access.csv new file mode 100644 index 00000000000..119fce977d1 --- /dev/null +++ b/addons/sale_layout/security/ir.model.access.csv @@ -0,0 +1,5 @@ +id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink +report_layout_category_1,report_layout_category_1,model_sale_layout_category,base.group_sale_manager,1,1,1,1 +report_layout_category_2,report_layout_category_2,model_sale_layout_category,account.group_account_manager,1,1,1,1 +report_layout_category_3,report_layout_category_3,model_sale_layout_category,base.group_sale_salesman,1,1,1,O +report_layout_category_4,report_layout_category_4,model_sale_layout_category,base.group_sale_salesman_all_leads,1,1,1,0 diff --git a/addons/sale_layout/views/report_invoice_layouted.xml b/addons/sale_layout/views/report_invoice_layouted.xml new file mode 100644 index 00000000000..4c0b1929484 --- /dev/null +++ b/addons/sale_layout/views/report_invoice_layouted.xml @@ -0,0 +1,65 @@ + + + + + + diff --git a/addons/sale_layout/views/report_quotation_layouted.xml b/addons/sale_layout/views/report_quotation_layouted.xml new file mode 100644 index 00000000000..ad04e271e7d --- /dev/null +++ b/addons/sale_layout/views/report_quotation_layouted.xml @@ -0,0 +1,70 @@ + + + + + + diff --git a/addons/sale_layout/views/sale_layout_category_view.xml b/addons/sale_layout/views/sale_layout_category_view.xml new file mode 100644 index 00000000000..08f892c127e --- /dev/null +++ b/addons/sale_layout/views/sale_layout_category_view.xml @@ -0,0 +1,120 @@ + + + + + + sale.order.form.inherit_1 + sale.order + + + + + + + + + + + + sale.order.line.form.inherit_2 + sale.order + + + + + + + + + + + + + account.invoice.form.inherit_1 + account.invoice + + + + + + + + + + + + account.invoice.line.form.inherit_2 + account.invoice.line + + + + + + + + + + + + + report.configuration.form.view + sale_layout.category + +
+ + + + + + + +
+
+
+ + + report.configuration.form.view + sale_layout.category + + + + + + + + + + + + + report.configuration.search.view + sale_layout.category + + + + + + + + + + + + + + Report Configuration + sale_layout.category + form + tree,form + + + +
+
diff --git a/addons/sale_layout/views/sale_layout_template.xml b/addons/sale_layout/views/sale_layout_template.xml new file mode 100644 index 00000000000..7b39ea4c632 --- /dev/null +++ b/addons/sale_layout/views/sale_layout_template.xml @@ -0,0 +1,42 @@ + + + + + + + + +