diff --git a/picking_create_invoice/__init__.py b/picking_create_invoice/__init__.py new file mode 100644 index 000000000..544391c02 --- /dev/null +++ b/picking_create_invoice/__init__.py @@ -0,0 +1,23 @@ +# -*- coding: utf-8 -*- +################################################################################### +# +# Cybrosys Technologies Pvt. Ltd. +# Copyright (C) 2017-TODAY Cybrosys Technologies(). +# Author: Treesa Maria() +# +# This program is free software: you can modify +# it under the terms of the GNU Affero General Public License (AGPL) 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 . +# +################################################################################### + +import models diff --git a/picking_create_invoice/__manifest__.py b/picking_create_invoice/__manifest__.py new file mode 100644 index 000000000..eeb722ecd --- /dev/null +++ b/picking_create_invoice/__manifest__.py @@ -0,0 +1,43 @@ +# -*- coding: utf-8 -*- +################################################################################### +# +# Cybrosys Technologies Pvt. Ltd. +# Copyright (C) 2017-TODAY Cybrosys Technologies(). +# Author: Treesa Maria() +# +# This program is free software: you can modify +# it under the terms of the GNU Affero General Public License (AGPL) 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': 'Extended Scope For Invoicing Policy', + 'version': '10.0.1.0.0', + 'summary': 'Set Your Invoicing Policy at Different Levels', + 'description': 'Invoicing policy is implemented in sale orders as well as customer side', + 'category': 'Sales', + 'author': 'Cybrosys Techno Solutions', + 'website': "https://www.cybrosys.com", + 'company': 'Cybrosys Techno Solutions', + 'depends': ['base', 'sale', 'stock', 'account'], + 'data': [ + 'views/invoice_option_view.xml', + 'views/customer_picking.xml', + ], + + 'images': ['static/description/banner.jpg'], + 'license': 'AGPL-3', + 'installable': True, + 'auto_install': False, + 'application': False, +} diff --git a/picking_create_invoice/models/__init__.py b/picking_create_invoice/models/__init__.py new file mode 100644 index 000000000..0e58a57a8 --- /dev/null +++ b/picking_create_invoice/models/__init__.py @@ -0,0 +1,23 @@ +# -*- coding: utf-8 -*- +################################################################################### +# +# Cybrosys Technologies Pvt. Ltd. +# Copyright (C) 2017-TODAY Cybrosys Technologies(). +# Author: Treesa Maria() +# +# This program is free software: you can modify +# it under the terms of the GNU Affero General Public License (AGPL) 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 . +# +################################################################################### + +import delivery_invoice diff --git a/picking_create_invoice/models/delivery_invoice.py b/picking_create_invoice/models/delivery_invoice.py new file mode 100644 index 000000000..a4b898da9 --- /dev/null +++ b/picking_create_invoice/models/delivery_invoice.py @@ -0,0 +1,157 @@ +# -*- coding: utf-8 -*- +################################################################################### +# +# Cybrosys Technologies Pvt. Ltd. +# Copyright (C) 2017-TODAY Cybrosys Technologies(). +# Author: Treesa Maria() +# +# This program is free software: you can modify +# it under the terms of the GNU Affero General Public License (AGPL) 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 odoo.exceptions import UserError +from odoo import fields, models, api, _ +from odoo.tools import float_is_zero + + +class CustomerInvoice(models.Model): + _inherit = 'res.partner' + + invoice_option = fields.Selection([('on_delivery', 'Delivered quantities'), + ('before_delivery', 'Ordered quantities'), ], + "Invoicing Policy") + + +class DeliveryInvoice(models.Model): + + _inherit = 'sale.order' + + invoice_option = fields.Selection([('on_delivery', 'Delivered quantities'), + ('before_delivery', 'Ordered quantities'), ], + string="Invoicing Policy") + + @api.onchange('partner_id') + def onchange_customer(self): + if self.partner_id.invoice_option: + self.invoice_option = self.partner_id.invoice_option + else: + self.invoice_option = False + + @api.multi + def action_invoice_create(self, grouped=False, final=False): + """ + Create the invoice associated to the SO. + :param grouped: if True, invoices are grouped by SO id. If False, invoices are grouped by + (partner_invoice_id, currency) + :param final: if True, refunds will be generated if necessary + :returns: list of created invoices + """ + if self.invoice_option == 'before_delivery': + inv_obj = self.env['account.invoice'] + for order in self: + inv_data = order._prepare_invoice() + invoice = inv_obj.create(inv_data) + for inv_line in order.order_line: + + inv_line.invoice_line_create(invoice.id, inv_line.product_uom_qty) + + else: + inv_obj = self.env['account.invoice'] + precision = self.env['decimal.precision'].precision_get('Product Unit of Measure') + invoices = {} + references = {} + for order in self: + group_key = order.id if grouped else (order.partner_invoice_id.id, order.currency_id.id) + for line in order.order_line.sorted(key=lambda l: l.qty_to_invoice < 0): + if float_is_zero(line.qty_to_invoice, precision_digits=precision): + continue + if group_key not in invoices: + + inv_data = order._prepare_invoice() + invoice = inv_obj.create(inv_data) + + references[invoice] = order + invoices[group_key] = invoice + elif group_key in invoices: + vals = {} + if order.name not in invoices[group_key].origin.split(', '): + + vals['origin'] = invoices[group_key].origin + ', ' + order.name + if order.client_order_ref and order.client_order_ref \ + not in invoices[group_key].name.split(', '): + + vals['name'] = invoices[group_key].name + ', ' + order.client_order_ref + invoices[group_key].write(vals) + if line.qty_to_invoice > 0: + line.invoice_line_create(invoices[group_key].id, line.qty_to_invoice) + elif line.qty_to_invoice < 0 and final: + line.invoice_line_create(invoices[group_key].id, line.qty_to_invoice) + + if references.get(invoices.get(group_key)): + + if order not in references[invoices[group_key]]: + + references[invoice] = references[invoice] | order + if not invoices: + + raise UserError(_('There is no invoicable line.')) + + for invoice in invoices.values(): + + if not invoice.invoice_line_ids: + + raise UserError(_('There is no invoicable line.')) + # If invoice is negative, do a refund invoice instead + if invoice.amount_untaxed < 0: + + invoice.type = 'out_refund' + for line in invoice.invoice_line_ids: + + line.quantity = -line.quantity + for line in invoice.invoice_line_ids: + + line._set_additional_fields(invoice) + invoice.compute_taxes() + invoice.message_post_with_view('mail.message_origin_link', + values={'self': invoice, 'origin': references[invoice]}, + subtype_id=self.env.ref('mail.mt_note').id) + return [inv.id for inv in invoices.values()] + + +class InvoiceControl(models.Model): + + _inherit = 'stock.picking' + + invoice_control = fields.Selection([('to_invoice', 'To be Invoiced'), + ('invoice_na', 'Not applicable'), ], + string="Invoicing Policy", compute='get_invoice_control') + + @api.depends('group_id') + def get_invoice_control(self): + for group in self: + + obj = self.env['sale.order'].search([('name', '=', group.group_id.name)]) + + if obj.invoice_option == 'on_delivery': + group.invoice_control = 'to_invoice' + elif obj.invoice_option == 'before_delivery': + group.invoice_control = 'invoice_na' + else: + group.invoice_control = False + + @api.depends('group_id') + def pick_create_invoices(self): + + sale_orders = self.env['sale.order'].search([('name', '=', self.group_id.name)]) + sale_orders.action_invoice_create() + return sale_orders.action_view_invoice() diff --git a/picking_create_invoice/static/description/banner.jpg b/picking_create_invoice/static/description/banner.jpg new file mode 100644 index 000000000..bab6fbfcd Binary files /dev/null and b/picking_create_invoice/static/description/banner.jpg differ diff --git a/picking_create_invoice/static/description/cus.png b/picking_create_invoice/static/description/cus.png new file mode 100644 index 000000000..af24fc61f Binary files /dev/null and b/picking_create_invoice/static/description/cus.png differ diff --git a/picking_create_invoice/static/description/cybro_logo.png b/picking_create_invoice/static/description/cybro_logo.png new file mode 100644 index 000000000..bb309114c Binary files /dev/null and b/picking_create_invoice/static/description/cybro_logo.png differ diff --git a/picking_create_invoice/static/description/icon.png b/picking_create_invoice/static/description/icon.png new file mode 100644 index 000000000..fe3ffdc22 Binary files /dev/null and b/picking_create_invoice/static/description/icon.png differ diff --git a/picking_create_invoice/static/description/index.html b/picking_create_invoice/static/description/index.html new file mode 100644 index 000000000..3024459f8 --- /dev/null +++ b/picking_create_invoice/static/description/index.html @@ -0,0 +1,145 @@ +
+
+

Extended Scope For Invoicing Policy

+

Set Your Invoicing Policy at Different Levels

+

Cybrosys Technologies

+ +
+
+

Features:

+
+ Invoicing policy in sale order.
+ Invoicing policy in customers.
+ Prioritized level.
+ +
+
+
+ +
+
+
+

Overview

+

+ Generally, we can choose the invoice creation process in two ways: +

    +
  •  Ordered quantities : Before processing the delivery
  • +
  • Delivered quantities : After finishing the delivery process
  • +
+ + Currently, in Odoo, we can set this feature only on the product side. This module extends the +scope of this feature to Sale Orders as well as Customers. Then, the priority of Invoicing +Policy will be as follows. +

Sale Order > Customer side > Product side > Default Settings

+

That is, Invoicing Policy set in Sale Order will get the high priority and + Default settings will be considered only if the rest of the levels doesn't + contain any Invoicing Policies.

+
+
+
+ +
+
+

Invoicing Policy in Sale Order: Delivered quantities

+ +
+
+

First, you have to download and Install the application form + Odoo App Store. Then follow the below steps to enable the feature.

+

    +
  • Create a Sale Order.
  • +
  • Go to Other Information ->Create Invoice -> Set 'Delivered quantities'
  • +
  • You can create invoice only after the delivery of the product. + 'Create Invoice' will not be visible on sale order
  • + + +
+

+
+ +
+

    +
  • At the Delivery side, create invoice will be 'To be Invoiced, which + indicates the invoice can be created from the picking side. When the + delivery is done, you can create the invoice from the delivery order itself.
  • +
+

+
+ +
+
+
+
+
+ +
+
+

Invoicing Policy in Sale Order : Ordered quantities

+ +
+
+ + +

    +
  • Create a Sale Order.
  • +
  • Go to Other Information ->Create Invoice -> Set 'Ordered quantities'
  • +
  • After confirming the sale orders, you can directly create the invoice + from sale order itself.
  • +
+

+
+ +
+

    +
  • At Delivery side, create invoice will be 'Not Applicable', which + indicates invoice cannot be created from the picking side.
  • +
+

+
+ +
+
+
+
+
+ +
+
+

Invoicing policy in Customer Side

+
+
+

+
+ +
+
+
+
+
+ + +
+

Need Any Help?

+ +
diff --git a/picking_create_invoice/static/description/so1.png b/picking_create_invoice/static/description/so1.png new file mode 100644 index 000000000..b6c4b60b8 Binary files /dev/null and b/picking_create_invoice/static/description/so1.png differ diff --git a/picking_create_invoice/static/description/so2.png b/picking_create_invoice/static/description/so2.png new file mode 100644 index 000000000..7a22c559c Binary files /dev/null and b/picking_create_invoice/static/description/so2.png differ diff --git a/picking_create_invoice/static/description/wh1.png b/picking_create_invoice/static/description/wh1.png new file mode 100644 index 000000000..df99d2604 Binary files /dev/null and b/picking_create_invoice/static/description/wh1.png differ diff --git a/picking_create_invoice/static/description/wh2.png b/picking_create_invoice/static/description/wh2.png new file mode 100644 index 000000000..7aefaba5a Binary files /dev/null and b/picking_create_invoice/static/description/wh2.png differ diff --git a/picking_create_invoice/views/customer_picking.xml b/picking_create_invoice/views/customer_picking.xml new file mode 100644 index 000000000..813e98b29 --- /dev/null +++ b/picking_create_invoice/views/customer_picking.xml @@ -0,0 +1,17 @@ + + + + + customer.invoice.option.view + + res.partner + + + + + + + + + + \ No newline at end of file diff --git a/picking_create_invoice/views/invoice_option_view.xml b/picking_create_invoice/views/invoice_option_view.xml new file mode 100644 index 000000000..903f245af --- /dev/null +++ b/picking_create_invoice/views/invoice_option_view.xml @@ -0,0 +1,57 @@ + + + + + invoice.option.view + + sale.order + + + + + + +