Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
20 changed files
with
1,215 additions
and
0 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
=========== | ||
Debit Notes | ||
=========== | ||
|
||
.. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | ||
!! This file is generated by oca-gen-addon-readme !! | ||
!! changes will be overwritten. !! | ||
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | ||
.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png | ||
:target: https://odoo-community.org/page/development-status | ||
:alt: Beta | ||
.. |badge2| image:: https://img.shields.io/badge/licence-AGPL--3-blue.png | ||
:target: http://www.gnu.org/licenses/agpl-3.0-standalone.html | ||
:alt: License: AGPL-3 | ||
.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Faccount--invoicing-lightgray.png?logo=github | ||
:target: https://github.com/OCA/account-invoicing/tree/12.0/account_debitnote | ||
:alt: OCA/account-invoicing | ||
.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png | ||
:target: https://translation.odoo-community.org/projects/account-invoicing-12-0/account-invoicing-12-0-account_debitnote | ||
:alt: Translate me on Weblate | ||
.. |badge5| image:: https://img.shields.io/badge/runbot-Try%20me-875A7B.png | ||
:target: https://runbot.odoo-community.org/runbot/95/12.0 | ||
:alt: Try me on Runbot | ||
|
||
|badge1| |badge2| |badge3| |badge4| |badge5| | ||
|
||
In some situations, You need to add some service charge or add some fees | ||
you need to create debit note but in Invoicing don't have this module, | ||
so I am interested to add this module. | ||
|
||
**Table of contents** | ||
|
||
.. contents:: | ||
:local: | ||
|
||
Usage | ||
===== | ||
|
||
To use this module, you need to: | ||
|
||
- Go to Invoicing -> Customers -> Invoices. | ||
- Create a new invoice and the Validate. | ||
- Click on Add Debit Note. | ||
- Get Reason. (You can add Account Date, If not Default is the same as the invoice.) | ||
- Click Add Debit Note, You will have a new one Invoice(Debit Note). | ||
|
||
* You can also do the same thing in Vendors -> Bills | ||
|
||
Bug Tracker | ||
=========== | ||
|
||
Bugs are tracked on `GitHub Issues <https://github.com/OCA/account-invoicing/issues>`_. | ||
In case of trouble, please check there if your issue has already been reported. | ||
If you spotted it first, help us smashing it by providing a detailed and welcomed | ||
`feedback <https://github.com/OCA/account-invoicing/issues/new?body=module:%20account_debitnote%0Aversion:%2012.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_. | ||
|
||
Do not contact contributors directly about support or help with technical issues. | ||
|
||
Credits | ||
======= | ||
|
||
Authors | ||
~~~~~~~ | ||
|
||
* Eocosft | ||
|
||
Contributors | ||
~~~~~~~~~~~~ | ||
|
||
* Rattapong Chokmasermkul <rattapongc@ecosoft.co.th> | ||
|
||
Maintainers | ||
~~~~~~~~~~~ | ||
|
||
This module is maintained by the OCA. | ||
|
||
.. image:: https://odoo-community.org/logo.png | ||
:alt: Odoo Community Association | ||
:target: https://odoo-community.org | ||
|
||
OCA, or the Odoo Community Association, is a nonprofit organization whose | ||
mission is to support the collaborative development of Odoo features and | ||
promote its widespread use. | ||
|
||
This module is part of the `OCA/account-invoicing <https://github.com/OCA/account-invoicing/tree/12.0/account_debitnote>`_ project on GitHub. | ||
|
||
You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. |
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,5 @@ | ||
# Copyright 2019 Ecosoft Co., Ltd (http://ecosoft.co.th/) | ||
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html) | ||
|
||
from . import models | ||
from . import wizard |
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,21 @@ | ||
# Copyright 2019 Ecosoft Co., Ltd. | ||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). | ||
|
||
{ | ||
'name': 'Debit Notes', | ||
'summary': """ | ||
Create debit note from invoice and vendor bill""", | ||
'version': '12.0.1.0.0', | ||
'website': 'https://github.com/OCA/account-invoicing', | ||
'author': 'Eocosft,Odoo Community Association (OCA)', | ||
'license': 'AGPL-3', | ||
'depends': [ | ||
'account', | ||
], | ||
'data': [ | ||
'wizard/account_invoice_debitnote_view.xml', | ||
'views/account_invoice_view.xml', | ||
'views/account_view.xml', | ||
], | ||
'installable': True, | ||
} |
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,7 @@ | ||
# Copyright 2019 Ecosoft (http://ecosoft.co.th) | ||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). | ||
|
||
from . import account_invoice | ||
from . import account | ||
from . import ir_sequence | ||
from . import account_move |
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,120 @@ | ||
# Copyright 2019 Ecosoft (http://ecosoft.co.th) | ||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). | ||
|
||
from odoo import models, fields, api, _ | ||
|
||
|
||
class AccountJournal(models.Model): | ||
_inherit = "account.journal" | ||
|
||
debitnote_sequence_id = fields.Many2one( | ||
comodel_name='ir.sequence', | ||
string='Debit Note Entry Sequence', | ||
help="""This field contains the information related to the numbering of | ||
the debit note entries of this journal.""", | ||
copy=False | ||
) | ||
debitnote_sequence_number_next = fields.Integer( | ||
string='Debit Notes: Next Number', | ||
help='The next sequence number will be used for the next debit note.', | ||
compute='_compute_debitnote_seq_number_next', | ||
inverse='_inverse_debitnote_seq_number_next' | ||
) | ||
debitnote_sequence = fields.Boolean( | ||
string='Dedicated Debit Note Sequence', | ||
help="""Check this box if you don't want to share the same sequence | ||
for invoices and debit notes made from this journal""", | ||
default=False | ||
) | ||
|
||
@api.depends('debitnote_sequence_id.use_date_range', | ||
'debitnote_sequence_id.number_next_actual') | ||
def _compute_debitnote_seq_number_next(self): | ||
""" | ||
Compute 'sequence_number_next' according to the current sequence | ||
in use, an ir.sequence or an ir.sequence.date_range. | ||
""" | ||
for journal in self: | ||
if journal.debitnote_sequence_id and journal.debitnote_sequence: | ||
sequence = journal.debitnote_sequence_id.\ | ||
_get_current_sequence() | ||
journal.debitnote_sequence_number_next = sequence.\ | ||
number_next_actual | ||
else: | ||
journal.debitnote_sequence_number_next = 1 | ||
|
||
@api.multi | ||
def _inverse_debitnote_seq_number_next(self): | ||
""" | ||
Inverse 'debitnote_sequence_number_next' to edit | ||
the current sequence next number. | ||
""" | ||
for journal in self: | ||
if journal.debitnote_sequence_id and \ | ||
journal.debitnote_sequence and \ | ||
journal.debitnote_sequence_number_next: | ||
sequence = journal.debitnote_sequence_id.\ | ||
_get_current_sequence() | ||
sequence.number_next = journal.debitnote_sequence_number_next | ||
|
||
@api.multi | ||
def write(self, vals): | ||
# create the relevant debitnote sequence | ||
res = super().write(vals) | ||
if vals.get('debitnote_sequence'): | ||
for journal in self.filtered((( | ||
lambda j: j.type in ('sale', 'purchase') and not | ||
j.debitnote_sequence_id))): | ||
journal_vals = { | ||
'name': journal.name, | ||
'company_id': journal.company_id.id, | ||
'code': journal.code, | ||
'debitnote_sequence_number_next': | ||
vals.get('debitnote_sequence_number_next', | ||
journal.debitnote_sequence_number_next), | ||
} | ||
journal.debitnote_sequence_id = self.sudo().\ | ||
_create_debitnote_sequence(journal_vals, debitnote=True).id | ||
return res | ||
|
||
@api.model | ||
def _get_debitnote_sequence_prefix(self, code, debitnote=False): | ||
prefix = code.upper() | ||
if debitnote: | ||
prefix = 'D' + prefix | ||
return prefix + '/%(range_year)s/' | ||
|
||
@api.model | ||
def _create_debitnote_sequence(self, vals, debitnote=False): | ||
""" Create new no_gap entry sequence for every new Journal""" | ||
prefix = self._get_debitnote_sequence_prefix(vals['code'], debitnote) | ||
seq_name = debitnote and vals['code'] + \ | ||
_(': Debitnote') or vals['code'] | ||
seq = { | ||
'name': _('%s Sequence') % seq_name, | ||
'implementation': 'no_gap', | ||
'prefix': prefix, | ||
'padding': 4, | ||
'number_increment': 1, | ||
'use_date_range': True, | ||
} | ||
if 'company_id' in vals: | ||
seq['company_id'] = vals['company_id'] | ||
seq = self.env['ir.sequence'].create(seq) | ||
seq_date_range = seq._get_current_sequence() | ||
seq_date_range.number_next = debitnote and \ | ||
vals.get('debitnote_sequence_number_next', 1) or \ | ||
vals.get('sequence_number_next', 1) | ||
return seq | ||
|
||
@api.model | ||
def create(self, vals): | ||
if vals.get('type') in ('sale', 'purchase') and \ | ||
vals.get('debitnote_sequence') and not \ | ||
vals.get('debitnote_sequence_id'): | ||
vals.update({'debitnote_sequence_id': | ||
self.sudo()._create_debitnote_sequence | ||
(vals, debitnote=True).id}) | ||
res = super().create(vals) | ||
|
||
return res |
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,128 @@ | ||
# Copyright 2019 Ecosoft (http://ecosoft.co.th) | ||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). | ||
|
||
from odoo import models, fields, api, _ | ||
from odoo.exceptions import ValidationError | ||
|
||
|
||
class AccountInvoice(models.Model): | ||
_inherit = 'account.invoice' | ||
|
||
debit_invoice_id = fields.Many2one( | ||
comodel_name='account.invoice', | ||
string='Debit Note', | ||
help="Reference to the origin invoice that create this debit note", | ||
) | ||
debit_invoice_ids = fields.One2many( | ||
comodel_name='account.invoice', | ||
inverse_name='debit_invoice_id', | ||
string='Debit Notes', | ||
readonly=True, | ||
help="List all debit notes being created by this invoice", | ||
) | ||
|
||
@api.model | ||
def _debitnote_cleanup_lines(self, lines): | ||
""" | ||
Convert records to dict of values suitable | ||
for one2many line creation | ||
:param list(browse_record) lines: records to convert | ||
:return: list of command tuple for one2many line creation | ||
[(0, 0, dict of valueis)] | ||
""" | ||
result = [] | ||
for line in lines: | ||
values = {} | ||
for name, field in line._fields.items(): | ||
if name in ['id', 'create_uid', 'create_date', | ||
'write_uid', 'write_date']: | ||
continue | ||
elif field.type == 'many2one': | ||
values[name] = line[name].id | ||
elif field.type not in ['many2many', 'one2many']: | ||
values[name] = line[name] | ||
elif name == 'invoice_line_tax_ids': | ||
values[name] = [(6, 0, line[name].ids)] | ||
elif name == 'analytic_tag_ids': | ||
values[name] = [(6, 0, line[name].ids)] | ||
result.append((0, 0, values)) | ||
return result | ||
|
||
@api.model | ||
def _prepare_debitnote(self, invoice, date_invoice=None, | ||
date=None, description=None, journal_id=None): | ||
""" | ||
Prepare the dict of values to create the new debit note | ||
from the invoice. | ||
This method may be overridden to implement custom debit note | ||
generation (making sure to call super() to establish a clean | ||
extension chain). | ||
:param dict invoice: read of the invoice to create debit note | ||
:param string invoice_date: debit note create date from the wizard | ||
:param integer date: force account.period from the wizard | ||
:param string description: description of | ||
the debit note from the wizard | ||
:param integer journal_id: account.journal from the wizard | ||
:return: dict of value to create() the debit note | ||
""" | ||
values = {} | ||
type_list = ['out_invoice', 'in_invoice'] | ||
|
||
if invoice.type not in type_list: | ||
raise ValidationError(_('Can not create Debit Note')) | ||
|
||
for field in ['name', 'reference', 'comment', 'date_due', 'partner_id', | ||
'company_id', 'account_id', 'currency_id', | ||
'payment_term_id', 'user_id', 'fiscal_position_id']: | ||
if invoice._fields[field].type == 'many2one': | ||
values[field] = invoice[field].id | ||
else: | ||
values[field] = invoice[field] or False | ||
|
||
values['invoice_line_ids'] = \ | ||
self._debitnote_cleanup_lines((invoice.invoice_line_ids)) | ||
tax_lines = filter(lambda l: l['manual'], invoice.tax_line_ids) | ||
tax_lines = self._debitnote_cleanup_lines(tax_lines) | ||
|
||
if journal_id: | ||
debitnote_journal = self.env['account.journal'].browse( | ||
(journal_id)) | ||
elif invoice['type'] == 'in_invoice': | ||
debitnote_journal = self.env['account.journal'].search( | ||
[('type', '=', 'purchase')], limit=1) | ||
else: | ||
debitnote_journal = self.env['account.journal'].search( | ||
[('type', '=', 'sale')], limit=1) | ||
|
||
values['journal_id'] = debitnote_journal.id | ||
values['type'] = invoice['type'] | ||
values['date_invoice'] = date_invoice or \ | ||
fields.Date.context_today((invoice)) | ||
values['state'] = 'draft' | ||
values['number'] = False | ||
values['origin'] = invoice.number | ||
values['payment_term_id'] = False | ||
values['debit_invoice_id'] = invoice.id | ||
|
||
if date: | ||
values['date'] = date | ||
if description: | ||
values['name'] = description | ||
return values | ||
|
||
@api.multi | ||
@api.returns('self') | ||
def debitnote(self, date_invoice=None, date=None, | ||
description=None, journal_id=None): | ||
new_invoice = [] | ||
for invoice in self: | ||
invoice = self._prepare_debitnote( | ||
invoice, | ||
date_invoice=date_invoice, | ||
date=date, | ||
description=description, | ||
journal_id=journal_id | ||
) | ||
new_invoice = self.create(invoice) | ||
return new_invoice |
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,13 @@ | ||
# Copyright 2019 Ecosoft (http://ecosoft.co.th) | ||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). | ||
|
||
from odoo import models, api | ||
|
||
|
||
class AccountMove(models.Model): | ||
_inherit = 'account.move' | ||
|
||
@api.multi | ||
def post(self, invoice=False): | ||
self = self.with_context(ctx_invoice=invoice) | ||
return super().post(invoice=invoice) |
Oops, something went wrong.