diff --git a/stock_move_invoice/README.rst b/stock_move_invoice/README.rst index a71021ce2..1f2bb3712 100644 --- a/stock_move_invoice/README.rst +++ b/stock_move_invoice/README.rst @@ -1,3 +1,6 @@ +.. image:: https://img.shields.io/badge/licence-AGPL--3-blue.svg + :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html + :alt: License: AGPL-3 Invoice From Stock Picking ========================== * Enables the option for creating invoice from stock picking @@ -20,8 +23,8 @@ Credits ------- * Developer: V13 Sayooj A O - V14 Minhaj T - V15 Tintuk Tomin + V14 Minhaj T + V15 Tintuk Tomin Contacts -------- @@ -33,9 +36,12 @@ Bugs are tracked on GitHub Issues. In case of trouble, please check there if you Maintainer ========== +.. image:: https://cybrosys.com/images/logo.png + :target: https://cybrosys.com + This module is maintained by Cybrosys Technologies. -For support and more information, please visit https://www.cybrosys.com +For support and more information, please visit `Our Website `__ Further information =================== diff --git a/stock_move_invoice/__manifest__.py b/stock_move_invoice/__manifest__.py index c4d319f56..a3b6825cd 100644 --- a/stock_move_invoice/__manifest__.py +++ b/stock_move_invoice/__manifest__.py @@ -3,7 +3,7 @@ # # Cybrosys Technologies Pvt. Ltd. # -# Copyright (C) 2021-TODAY Cybrosys Technologies(). +# Copyright (C) 2020-TODAY Cybrosys Technologies(). # Author: Sayooj A O() # # You can modify it under the terms of the GNU AFFERO @@ -43,5 +43,5 @@ 'images': ['static/description/banner.png'], 'installable': True, 'application': True, - 'sequence':1 + 'sequence': 1 } diff --git a/stock_move_invoice/doc/RELEASE_NOTES.md b/stock_move_invoice/doc/RELEASE_NOTES.md index da4b00a2b..00000bfed 100644 --- a/stock_move_invoice/doc/RELEASE_NOTES.md +++ b/stock_move_invoice/doc/RELEASE_NOTES.md @@ -3,4 +3,9 @@ #### 06.11.2020 #### Version 16.0.1.0.0 ##### ADD -- Initial commit +- Initial commit for Invoice From Stock Picking + +#### 19.07.2023 +#### Version 16.0.1.0.0 +##### UPDATE +- Update for Invoice From Stock Picking \ No newline at end of file diff --git a/stock_move_invoice/models/account_move.py b/stock_move_invoice/models/account_move.py index a30b36df9..9ef738c23 100644 --- a/stock_move_invoice/models/account_move.py +++ b/stock_move_invoice/models/account_move.py @@ -19,10 +19,12 @@ # If not, see . # ############################################################################# -from odoo import api, fields, models +from odoo import fields, models class AccountMove(models.Model): + """Inheriting the model account.move""" _inherit = 'account.move' picking_id = fields.Many2one('stock.picking', string='Picking') + transfer_ids = fields.Many2many('stock.picking', string='Transfers') diff --git a/stock_move_invoice/models/res_config_settings.py b/stock_move_invoice/models/res_config_settings.py index e43712180..fc6ca4256 100644 --- a/stock_move_invoice/models/res_config_settings.py +++ b/stock_move_invoice/models/res_config_settings.py @@ -23,8 +23,17 @@ from odoo import fields, models class Settings(models.TransientModel): + """Inheriting model res.config.settings to add journal fields""" _inherit = 'res.config.settings' - customer_journal_id = fields.Many2one('account.journal', string='Customer Journal', - config_parameter='stock_move_invoice.customer_journal_id') - vendor_journal_id = fields.Many2one('account.journal', string='Vendor Journal', - config_parameter='stock_move_invoice.vendor_journal_id') + + customer_journal_id = fields.Many2one('account.journal', + string='Customer Journal', + config_parameter= + 'stock_move_invoice.' + 'customer_journal_id', + help='To add customer journal') + vendor_journal_id = fields.Many2one('account.journal', + string='Vendor Journal', + config_parameter= + 'stock_move_invoice.vendor_journal_id', + help='To add vendor journal') diff --git a/stock_move_invoice/models/stock_picking.py b/stock_move_invoice/models/stock_picking.py index d8142be78..67e4c766f 100644 --- a/stock_move_invoice/models/stock_picking.py +++ b/stock_move_invoice/models/stock_picking.py @@ -24,15 +24,20 @@ from odoo.exceptions import UserError class StockPicking(models.Model): + """Inheriting model stock.picking""" _inherit = 'stock.picking' - invoice_count = fields.Integer(string='Invoices', compute='_compute_invoice_count') + + invoice_count = fields.Integer(string='Invoices', + compute='_compute_invoice_count') operation_code = fields.Selection(related='picking_type_id.code') is_return = fields.Boolean() def _compute_invoice_count(self): - """This compute function used to count the number of invoice for the picking""" + """This compute function used to count the number of invoice for + the picking""" for picking_id in self: - move_ids = picking_id.env['account.move'].search([('invoice_origin', '=', picking_id.name)]) + move_ids = picking_id.env['account.move'].search( + [('transfer_ids', 'in', picking_id.id)]) if move_ids: self.invoice_count = len(move_ids) else: @@ -44,19 +49,31 @@ class StockPicking(models.Model): for picking_id in self: current_user = self.env.uid if picking_id.picking_type_id.code == 'outgoing': - customer_journal_id = picking_id.env['ir.config_parameter'].sudo().get_param( - 'stock_move_invoice.customer_journal_id') or False + customer_journal_id = \ + picking_id.env['ir.config_parameter'].sudo().\ + get_param('stock_move_invoice.customer_journal_id') or \ + False if not customer_journal_id: - raise UserError(_("Please configure the journal from settings")) + raise UserError( + _("Please configure the journal from settings")) invoice_line_list = [] - for move_ids_without_package in picking_id.move_ids_without_package: + for move_ids_without_package in picking_id.\ + move_ids_without_package: vals = (0, 0, { 'name': move_ids_without_package.description_picking, 'product_id': move_ids_without_package.product_id.id, - 'price_unit': move_ids_without_package.product_id.lst_price, - 'account_id': move_ids_without_package.product_id.property_account_income_id.id if move_ids_without_package.product_id.property_account_income_id - else move_ids_without_package.product_id.categ_id.property_account_income_categ_id.id, - 'tax_ids': [(6, 0, [picking_id.company_id.account_sale_tax_id.id])], + 'price_unit': + move_ids_without_package.product_id.lst_price, + 'account_id': + move_ids_without_package.product_id. + property_account_income_id.id if + move_ids_without_package. + product_id.property_account_income_id + else move_ids_without_package. + product_id.categ_id. + property_account_income_categ_id.id, + 'tax_ids': [(6, 0, [ + picking_id.company_id.account_sale_tax_id.id])], 'quantity': move_ids_without_package.quantity_done, }) invoice_line_list.append(vals) @@ -66,11 +83,13 @@ class StockPicking(models.Model): 'invoice_user_id': current_user, 'narration': picking_id.name, 'partner_id': picking_id.partner_id.id, - 'currency_id': picking_id.env.user.company_id.currency_id.id, + 'currency_id': + picking_id.env.user.company_id.currency_id.id, 'journal_id': int(customer_journal_id), 'payment_reference': picking_id.name, 'picking_id': picking_id.id, - 'invoice_line_ids': invoice_line_list + 'invoice_line_ids': invoice_line_list, + 'transfer_ids': self }) return invoice @@ -80,19 +99,29 @@ class StockPicking(models.Model): for picking_id in self: current_user = self.env.uid if picking_id.picking_type_id.code == 'incoming': - vendor_journal_id = picking_id.env['ir.config_parameter'].sudo().get_param( + vendor_journal_id = picking_id.env[ + 'ir.config_parameter'].sudo().get_param( 'stock_move_invoice.vendor_journal_id') or False if not vendor_journal_id: - raise UserError(_("Please configure the journal from the settings.")) + raise UserError( + _("Please configure the journal from the settings.")) invoice_line_list = [] - for move_ids_without_package in picking_id.move_ids_without_package: + for move_ids_without_package in picking_id.\ + move_ids_without_package: vals = (0, 0, { 'name': move_ids_without_package.description_picking, 'product_id': move_ids_without_package.product_id.id, - 'price_unit': move_ids_without_package.product_id.lst_price, - 'account_id': move_ids_without_package.product_id.property_account_income_id.id if move_ids_without_package.product_id.property_account_income_id - else move_ids_without_package.product_id.categ_id.property_account_income_categ_id.id, - 'tax_ids': [(6, 0, [picking_id.company_id.account_purchase_tax_id.id])], + 'price_unit': + move_ids_without_package.product_id.lst_price, + 'account_id': + move_ids_without_package.product_id. + property_account_income_id.id if + move_ids_without_package.product_id. + property_account_income_id + else move_ids_without_package.product_id.categ_id. + property_account_income_categ_id.id, + 'tax_ids': [(6, 0, [ + picking_id.company_id.account_purchase_tax_id.id])], 'quantity': move_ids_without_package.quantity_done, }) invoice_line_list.append(vals) @@ -102,11 +131,13 @@ class StockPicking(models.Model): 'invoice_user_id': current_user, 'narration': picking_id.name, 'partner_id': picking_id.partner_id.id, - 'currency_id': picking_id.env.user.company_id.currency_id.id, + 'currency_id': + picking_id.env.user.company_id.currency_id.id, 'journal_id': int(vendor_journal_id), 'payment_reference': picking_id.name, 'picking_id': picking_id.id, - 'invoice_line_ids': invoice_line_list + 'invoice_line_ids': invoice_line_list, + 'transfer_ids': self }) return invoice @@ -116,19 +147,29 @@ class StockPicking(models.Model): for picking_id in self: current_user = picking_id.env.uid if picking_id.picking_type_id.code == 'incoming': - customer_journal_id = picking_id.env['ir.config_parameter'].sudo().get_param( - 'stock_move_invoice.customer_journal_id') or False + customer_journal_id = \ + picking_id.env['ir.config_parameter'].sudo().\ + get_param('stock_move_invoice.customer_journal_id') or \ + False if not customer_journal_id: - raise UserError(_("Please configure the journal from settings")) + raise UserError( + _("Please configure the journal from settings")) invoice_line_list = [] - for move_ids_without_package in picking_id.move_ids_without_package: + for move_ids_without_package in picking_id.\ + move_ids_without_package: vals = (0, 0, { 'name': move_ids_without_package.description_picking, 'product_id': move_ids_without_package.product_id.id, - 'price_unit': move_ids_without_package.product_id.lst_price, - 'account_id': move_ids_without_package.product_id.property_account_income_id.id if move_ids_without_package.product_id.property_account_income_id - else move_ids_without_package.product_id.categ_id.property_account_income_categ_id.id, - 'tax_ids': [(6, 0, [picking_id.company_id.account_sale_tax_id.id])], + 'price_unit': + move_ids_without_package.product_id.lst_price, + 'account_id': move_ids_without_package.product_id. + property_account_income_id.id if + move_ids_without_package.product_id. + property_account_income_id + else move_ids_without_package.product_id.categ_id. + property_account_income_categ_id.id, + 'tax_ids': [(6, 0, [ + picking_id.company_id.account_sale_tax_id.id])], 'quantity': move_ids_without_package.quantity_done, }) invoice_line_list.append(vals) @@ -138,11 +179,13 @@ class StockPicking(models.Model): 'invoice_user_id': current_user, 'narration': picking_id.name, 'partner_id': picking_id.partner_id.id, - 'currency_id': picking_id.env.user.company_id.currency_id.id, + 'currency_id': + picking_id.env.user.company_id.currency_id.id, 'journal_id': int(customer_journal_id), 'payment_reference': picking_id.name, 'picking_id': picking_id.id, - 'invoice_line_ids': invoice_line_list + 'invoice_line_ids': invoice_line_list, + 'transfer_ids': self }) return invoice @@ -152,19 +195,28 @@ class StockPicking(models.Model): for picking_id in self: current_user = self.env.uid if picking_id.picking_type_id.code == 'outgoing': - vendor_journal_id = picking_id.env['ir.config_parameter'].sudo().get_param( + vendor_journal_id = picking_id.env[ + 'ir.config_parameter'].sudo().get_param( 'stock_move_invoice.vendor_journal_id') or False if not vendor_journal_id: - raise UserError(_("Please configure the journal from the settings.")) + raise UserError( + _("Please configure the journal from the settings.")) invoice_line_list = [] - for move_ids_without_package in picking_id.move_ids_without_package: + for move_ids_without_package in picking_id.\ + move_ids_without_package: vals = (0, 0, { 'name': move_ids_without_package.description_picking, 'product_id': move_ids_without_package.product_id.id, - 'price_unit': move_ids_without_package.product_id.lst_price, - 'account_id': move_ids_without_package.product_id.property_account_income_id.id if move_ids_without_package.product_id.property_account_income_id - else move_ids_without_package.product_id.categ_id.property_account_income_categ_id.id, - 'tax_ids': [(6, 0, [picking_id.company_id.account_purchase_tax_id.id])], + 'price_unit': + move_ids_without_package.product_id.lst_price, + 'account_id': move_ids_without_package.product_id. + property_account_income_id.id if + move_ids_without_package.product_id. + property_account_income_id + else move_ids_without_package.product_id.categ_id. + property_account_income_categ_id.id, + 'tax_ids': [(6, 0, [ + picking_id.company_id.account_purchase_tax_id.id])], 'quantity': move_ids_without_package.quantity_done, }) invoice_line_list.append(vals) @@ -174,11 +226,13 @@ class StockPicking(models.Model): 'invoice_user_id': current_user, 'narration': picking_id.name, 'partner_id': picking_id.partner_id.id, - 'currency_id': picking_id.env.user.company_id.currency_id.id, + 'currency_id': + picking_id.env.user.company_id.currency_id.id, 'journal_id': int(vendor_journal_id), 'payment_reference': picking_id.name, 'picking_id': picking_id.id, - 'invoice_line_ids': invoice_line_list + 'invoice_line_ids': invoice_line_list, + 'transfer_ids': self }) return invoice @@ -190,18 +244,134 @@ class StockPicking(models.Model): 'type': 'ir.actions.act_window', 'view_mode': 'tree,form', 'res_model': 'account.move', - 'domain': [('invoice_origin', '=', self.name)], + 'domain': [('transfer_ids', 'in', self.id)], 'context': {'create': False}, 'target': 'current' } + def action_create_multi_invoice_for_multi_transfer(self): + """This is the function for creating customer invoice + from the picking""" + picking_type = list(self.picking_type_id) + if all(first == picking_type[0] for first in picking_type): + if self.picking_type_id.code == 'outgoing': + partner = list(self.partner_id) + if all(first == partner[0] for first in partner): + partner_id = self.partner_id + invoice_line_list = [] + customer_journal_id = \ + self.env['ir.config_parameter'].sudo().\ + get_param('stock_move_invoice.customer_journal_id') \ + or False + if not customer_journal_id: + raise UserError( + _("Please configure the journal from settings")) + for picking_id in self: + for move_ids_without_package in picking_id.\ + move_ids_without_package: + vals = (0, 0, { + 'name': + move_ids_without_package.description_picking + , + 'product_id': + move_ids_without_package.product_id.id, + 'price_unit': move_ids_without_package. + product_id.lst_price, + 'account_id': move_ids_without_package. + product_id.property_account_income_id.id if + move_ids_without_package.product_id. + property_account_income_id + else move_ids_without_package. + product_id.categ_id. + property_account_income_categ_id.id, + 'tax_ids': [(6, 0, [picking_id.company_id. + account_purchase_tax_id.id])], + 'quantity': + move_ids_without_package.quantity_done, + }) + invoice_line_list.append(vals) + invoice = self.env['account.move'].create({ + 'move_type': 'out_invoice', + 'invoice_origin': picking_id.name, + 'invoice_user_id': self.env.uid, + 'narration': picking_id.name, + 'partner_id': partner_id.id, + 'currency_id': + picking_id.env.user.company_id.currency_id.id, + 'journal_id': int(customer_journal_id), + 'payment_reference': picking_id.name, + 'invoice_line_ids': invoice_line_list, + 'transfer_ids': self + }) + else: + for picking_id in self: + picking_id.create_invoice() + elif self.picking_type_id.code == 'incoming': + partner = list(self.partner_id) + if all(first == partner[0] for first in partner): + partner_id = self.partner_id + bill_line_list = [] + vendor_journal_id = \ + self.env['ir.config_parameter'].sudo().\ + get_param('stock_move_invoice.vendor_journal_id') \ + or False + if not vendor_journal_id: + raise UserError(_("Please configure the journal from " + "the settings.")) + for picking_id in self: + for move_ids_without_package in picking_id.\ + move_ids_without_package: + vals = (0, 0, { + 'name': + move_ids_without_package.description_picking + , + 'product_id': + move_ids_without_package.product_id.id, + 'price_unit': move_ids_without_package. + product_id.lst_price, + 'account_id': move_ids_without_package. + product_id.property_account_income_id.id if + move_ids_without_package.product_id. + property_account_income_id + else move_ids_without_package. + product_id.categ_id. + property_account_income_categ_id.id, + 'tax_ids': [(6, 0, [picking_id.company_id. + account_purchase_tax_id.id])], + 'quantity': + move_ids_without_package.quantity_done, + }) + bill_line_list.append(vals) + invoice = self.env['account.move'].create({ + 'move_type': 'in_invoice', + 'invoice_origin': picking_id.name, + 'invoice_user_id': self.env.uid, + 'narration': picking_id.name, + 'partner_id': partner_id.id, + 'currency_id': + picking_id.env.user.company_id.currency_id.id, + 'journal_id': int(vendor_journal_id), + 'payment_reference': picking_id.name, + 'picking_id': picking_id.id, + 'invoice_line_ids': bill_line_list, + 'transfer_ids': self + }) + else: + for picking_id in self: + picking_id.create_bill() + else: + raise UserError( + _("Please select single type transfer")) + class StockReturnInvoicePicking(models.TransientModel): _inherit = 'stock.return.picking' def _create_returns(self): """in this function the picking is marked as return""" - new_picking, pick_type_id = super(StockReturnInvoicePicking, self)._create_returns() + + new_picking, pick_type_id = \ + super(StockReturnInvoicePicking, self)._create_returns() picking = self.env['stock.picking'].browse(new_picking) picking.write({'is_return': True}) return new_picking, pick_type_id diff --git a/stock_move_invoice/static/description/assets/screenshots/demo6.png b/stock_move_invoice/static/description/assets/screenshots/demo6.png new file mode 100644 index 000000000..f82e01b43 Binary files /dev/null and b/stock_move_invoice/static/description/assets/screenshots/demo6.png differ diff --git a/stock_move_invoice/static/description/assets/screenshots/demo7.png b/stock_move_invoice/static/description/assets/screenshots/demo7.png new file mode 100644 index 000000000..d5b7d8b89 Binary files /dev/null and b/stock_move_invoice/static/description/assets/screenshots/demo7.png differ diff --git a/stock_move_invoice/static/description/assets/screenshots/demo8.png b/stock_move_invoice/static/description/assets/screenshots/demo8.png new file mode 100644 index 000000000..7955972f4 Binary files /dev/null and b/stock_move_invoice/static/description/assets/screenshots/demo8.png differ diff --git a/stock_move_invoice/static/description/index.html b/stock_move_invoice/static/description/index.html index 88b372c34..4241cd0bd 100644 --- a/stock_move_invoice/static/description/index.html +++ b/stock_move_invoice/static/description/index.html @@ -160,6 +160,27 @@

when we creating a delivery operation there is an option for making bill in the same page

+ +
+

Create invoice/bill for multiple transfer with same customer +

+

select multiple transfer with same transfer type and with same partner from the tree view. It will create a single invoice/bill with all the products.

+ +
+ +
+

Create invoice/bill for multiple transfer with different customer +

+

select multiple transfer with same transfer type and with different partner from the tree view. It will create a single invoice/bill for each transfer.

+ +
+ +
+

User error for different type transfer +

+

It shows a user error for the selection of different type transfer.

+ +

invoice/bill smart button @@ -552,4 +573,4 @@

- \ No newline at end of file + diff --git a/stock_move_invoice/views/account_move_inherited.xml b/stock_move_invoice/views/account_move_inherited.xml index 8eb74a27a..cebfcc303 100644 --- a/stock_move_invoice/views/account_move_inherited.xml +++ b/stock_move_invoice/views/account_move_inherited.xml @@ -1,6 +1,7 @@ + account.move.form.view.inherited account.move @@ -8,6 +9,7 @@ + diff --git a/stock_move_invoice/views/res_config_settings_inherited.xml b/stock_move_invoice/views/res_config_settings_inherited.xml index cf61956f4..f0fc627d7 100644 --- a/stock_move_invoice/views/res_config_settings_inherited.xml +++ b/stock_move_invoice/views/res_config_settings_inherited.xml @@ -1,5 +1,6 @@ + res.config.settings.invoice.modification res.config.settings @@ -9,25 +10,30 @@

Invoice From Stock Picking

-
+
Journals -
- Journals which should apply for the invoice creation from stock picking + Journals which should apply for the invoice + creation from stock picking
-
-