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
19 changed files
with
1,256 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,98 @@ | ||
=============== | ||
Billing Process | ||
=============== | ||
|
||
.. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | ||
!! This file is generated by oca-gen-addon-readme !! | ||
!! changes will be overwritten. !! | ||
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | ||
.. |badge1| 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 | ||
.. |badge2| image:: https://img.shields.io/badge/github-OCA%2Faccount--invoicing-lightgray.png?logo=github | ||
:target: https://github.com/OCA/account-invoicing/tree/12.0-add-account_billing/account_billing | ||
:alt: OCA/account-invoicing | ||
.. |badge3| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png | ||
:target: https://translation.odoo-community.org/projects/account-invoicing-12-0-add-account_billing/account-invoicing-12-0-add-account_billing-account_billing | ||
:alt: Translate me on Weblate | ||
.. |badge4| image:: https://img.shields.io/badge/runbot-Try%20me-875A7B.png | ||
:target: https://runbot.odoo-community.org/runbot/95/12.0-add-account_billing | ||
:alt: Try me on Runbot | ||
|
||
|badge1| |badge2| |badge3| |badge4| | ||
|
||
In some countries, there is a customary practice for companies to collect money | ||
from their customers only once in a month. For example, the customer has 3 payments due in | ||
a given month, the vendor or billing company should group all the due AR Invoices in a document | ||
call Billing Document and issue it with all the invoices consolidated to the customer on the Billing Day. | ||
The customer will be paying based on the payable amount shown in Billing Document in the following month. | ||
|
||
This module use a new document called "Billing" to group these invoices together. | ||
|
||
**Table of contents** | ||
|
||
.. contents:: | ||
:local: | ||
|
||
Usage | ||
===== | ||
|
||
To use this module, you have 2 ways: | ||
|
||
1. Create new billing directly | ||
Go to *Invoicing -> Customers or Vendors -> Billing* | ||
|
||
2. Create billing from selected invoice(s) | ||
#. Go to *Invoicing -> Customers or Vendors -> Invoices or Bills* | ||
#. Create Invoice | ||
#. On tree view select invoice and go to *Action -> Create Billing* | ||
|
||
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_billing%0Aversion:%2012.0-add-account_billing%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 | ||
~~~~~~~ | ||
|
||
* Ecosoft | ||
|
||
Contributors | ||
~~~~~~~~~~~~ | ||
|
||
* Kitti U. <kittiu@ecosoft.co.th> | ||
* Saran Lim. <saranl@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. | ||
|
||
.. |maintainer-Saran440| image:: https://github.com/Saran440.png?size=40px | ||
:target: https://github.com/Saran440 | ||
:alt: Saran440 | ||
|
||
Current `maintainer <https://odoo-community.org/page/maintainer-role>`__: | ||
|
||
|maintainer-Saran440| | ||
|
||
This module is part of the `OCA/account-invoicing <https://github.com/OCA/account-invoicing/tree/12.0-add-account_billing/account_billing>`_ 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,4 @@ | ||
# 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 |
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,24 @@ | ||
# Copyright 2019 Ecosoft Co., Ltd (http://ecosoft.co.th/) | ||
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html) | ||
|
||
{ | ||
'name': 'Billing Process', | ||
'summary': 'Group invoice as billing before payment', | ||
'version': '12.0.1.0.0', | ||
'author': 'Ecosoft,Odoo Community Association (OCA)', | ||
'license': 'AGPL-3', | ||
'website': 'https://github.com/OCA/account-invoicing/', | ||
'category': 'Account', | ||
'depends': ['account'], | ||
'data': [ | ||
'data/account_billing_sequence.xml', | ||
'security/ir.model.access.csv', | ||
'views/account_billing.xml', | ||
'views/account_invoice.xml', | ||
'report/report_billing.xml', | ||
'report/report.xml', | ||
], | ||
'installable': True, | ||
'development_status': 'alpha', | ||
'maintainers': ['Saran440'], | ||
} |
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,24 @@ | ||
<?xml version="1.0" encoding="utf-8"?> | ||
<odoo noupdate="1"> | ||
<record id="seq_account_customer_billing" model="ir.sequence"> | ||
<field name="name">Billing sequence</field> | ||
<field name="code">account.customer.billing</field> | ||
<field name="prefix">CUST.BIL/%(year)s/</field> | ||
<field eval="1" name="number_next"/> | ||
<field eval="1" name="number_increment"/> | ||
<field eval="True" name="use_date_range"/> | ||
<field eval="False" name="company_id"/> | ||
<field name="padding">5</field> | ||
</record> | ||
|
||
<record id="seq_account_supplier_billing" model="ir.sequence"> | ||
<field name="name">Supplier Billing sequence</field> | ||
<field name="code">account.supplier.billing</field> | ||
<field name="prefix">SUPP.BIL/%(year)s/</field> | ||
<field eval="1" name="number_next"/> | ||
<field eval="1" name="number_increment"/> | ||
<field eval="True" name="use_date_range"/> | ||
<field eval="False" name="company_id"/> | ||
<field name="padding">5</field> | ||
</record> | ||
</odoo> |
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 account_billing | ||
from . import account_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,197 @@ | ||
# Copyright 2019 Ecosoft Co., Ltd (http://ecosoft.co.th/) | ||
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html) | ||
|
||
from odoo import models, fields, api, _ | ||
from odoo.exceptions import ValidationError | ||
|
||
MAP_INVOICE_TYPE_PARTNER_TYPE = { | ||
'out_invoice': 'customer', | ||
'in_invoice': 'supplier', | ||
} | ||
|
||
|
||
class AccountBilling(models.Model): | ||
_name = 'account.billing' | ||
_description = 'Account Billing' | ||
_inherit = ['mail.thread'] | ||
_order = 'date desc, id desc' | ||
|
||
name = fields.Char( | ||
readonly=True, | ||
copy=False, | ||
help='Number of account.billing', | ||
) | ||
partner_id = fields.Many2one( | ||
comodel_name='res.partner', | ||
required=True, | ||
default=lambda self: self._get_partner_id(), | ||
help='Partner Information', | ||
track_visibility='always', | ||
) | ||
date = fields.Date( | ||
string='Billing Date', | ||
readonly=True, | ||
states={'draft': [('readonly', False)]}, | ||
default=fields.Date.context_today, | ||
help='Effective date for accounting entries', | ||
track_visibility='always', | ||
) | ||
due_date = fields.Date( | ||
readonly=True, | ||
states={'draft': [('readonly', False)]}, | ||
default=lambda self: fields.Date.context_today(self), | ||
required=True, | ||
track_visibility='always', | ||
) | ||
invoice_ids = fields.One2many( | ||
comodel_name='account.invoice', | ||
inverse_name='billing_id', | ||
string='Invoices', | ||
readonly=True, | ||
states={'draft': [('readonly', False)]}, | ||
default=lambda self: self._context.get('active_ids', []), | ||
) | ||
invoice_related_count = fields.Integer( | ||
string='# of Invoices', | ||
compute='_compute_invoice_related_count', | ||
help='Count invoice in billing', | ||
) | ||
state = fields.Selection( | ||
[('draft', 'Draft'), | ||
('cancel', 'Cancelled'), | ||
('billed', 'Billed')], | ||
string='Status', | ||
readonly=True, | ||
default='draft', | ||
help=""" | ||
* The 'Draft' status is used when a user create a new billing\n | ||
* The 'Billed' status is used when user confirmed billing, | ||
billing number is generated\n | ||
* The 'Cancelled' status is used when user billing is cancelled | ||
""", | ||
) | ||
narration = fields.Text( | ||
string='Notes', | ||
readonly=True, | ||
states={'draft': [('readonly', False)]}, | ||
help='Notes', | ||
) | ||
bill_type = fields.Selection( | ||
[('out_invoice', 'Customer Invoice'), | ||
('in_invoice', 'Vendor Bill')], | ||
readonly=True, | ||
states={'draft': [('readonly', False)]}, | ||
default=lambda self: self._context.get('bill_type', False), | ||
help='Type of invoice', | ||
) | ||
currency_id = fields.Many2one( | ||
comodel_name='res.currency', | ||
string='Currency', | ||
required=True, | ||
default=lambda self: self._get_currency_id(), | ||
help='Currency', | ||
) | ||
|
||
@api.model | ||
def fields_view_get(self, view_id=None, view_type='form', | ||
toolbar=False, submenu=False): | ||
res = super(AccountBilling, self).fields_view_get( | ||
view_id=view_id, view_type=view_type, | ||
toolbar=toolbar, submenu=submenu) | ||
invoices = self.env['account.invoice'].browse( | ||
self._context.get('active_ids', [])) | ||
billing = invoices.mapped('billing_id') | ||
if any(inv.state != 'open' for inv in invoices): | ||
raise ValidationError(_('The billing cannot be processed ' | ||
'because the invoice is not open!')) | ||
if billing: | ||
raise ValidationError(_( | ||
'Invoice: %s, already billed!') % ', '.join( | ||
invoices.filtered(lambda l: l.billing_id).mapped('number'))) | ||
return res | ||
|
||
@api.onchange('bill_type') | ||
def _onchange_bill_type(self): | ||
# Set partner_id domain | ||
if self.bill_type: | ||
return {'domain': {'partner_id': [ | ||
(MAP_INVOICE_TYPE_PARTNER_TYPE[self.bill_type], '=', True)]}} | ||
|
||
@api.multi | ||
def _get_partner_id(self): | ||
partner_ids = self.env['account.invoice'].browse( | ||
self._context.get('active_ids', [])).mapped('partner_id') | ||
if len(partner_ids) > 1: | ||
raise ValidationError( | ||
_('Please select invoices with same partner')) | ||
return partner_ids | ||
|
||
@api.multi | ||
def _get_currency_id(self): | ||
currency_ids = self.env['account.invoice'].browse( | ||
self._context.get('active_ids', [])).mapped('currency_id') | ||
if len(currency_ids) > 1: | ||
raise ValidationError( | ||
_('Please select invoices with same currency')) | ||
return currency_ids or self.env.user.company_id.currency_id | ||
|
||
@api.multi | ||
def _compute_invoice_related_count(self): | ||
for billing in self: | ||
invoice_ids = self.env['account.invoice'].search_count([ | ||
('id', 'in', billing.invoice_ids.ids) | ||
]) | ||
billing.invoice_related_count = invoice_ids | ||
|
||
@api.multi | ||
def name_get(self): | ||
result = [] | ||
for billing in self: | ||
result.append((billing.id, (billing.name or 'Draft'))) | ||
return result | ||
|
||
@api.multi | ||
def validate_billing(self): | ||
for rec in self: | ||
if any(inv.state != 'open' for inv in rec.invoice_ids): | ||
raise ValidationError(_('Billing cannot be processed because \ | ||
some invoices are not in state Open')) | ||
# keep the number in case of a billing reset to draft | ||
if not rec.name: | ||
# Use the right sequence to set the name | ||
if rec.bill_type == 'out_invoice': | ||
sequence_code = 'account.customer.billing' | ||
if rec.bill_type == 'in_invoice': | ||
sequence_code = 'account.supplier.billing' | ||
rec.name = self.env['ir.sequence'].with_context( | ||
ir_sequence_date=rec.date).next_by_code(sequence_code) | ||
rec.write({'state': 'billed'}) | ||
rec.message_post(body=_('Billing is billed.')) | ||
return True | ||
|
||
@api.multi | ||
def action_cancel_draft(self): | ||
for rec in self: | ||
rec.write({'state': 'draft'}) | ||
rec.message_post(body=_('Billing is reset to draft')) | ||
return True | ||
|
||
@api.multi | ||
def action_cancel(self): | ||
for rec in self: | ||
invoice_paid = rec.invoice_ids.filtered( | ||
lambda l: l.state == 'paid') | ||
if invoice_paid: | ||
raise ValidationError(_("Invoice paid already.")) | ||
rec.write({'state': 'cancel'}) | ||
rec.invoice_ids.write({'billing_id': False}) | ||
self.message_post(body=_('Billing %s is cancelled') % rec.name) | ||
return True | ||
|
||
@api.multi | ||
def invoice_relate_billing_tree_view(self): | ||
self.ensure_one() | ||
action = self.env.ref('account.action_invoice_tree1') | ||
result = action.read()[0] | ||
result.update({'domain': [('id', 'in', self.invoice_ids.ids)]}) | ||
return result |
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,15 @@ | ||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). | ||
|
||
from odoo import fields, models | ||
|
||
|
||
class AccountInvoice(models.Model): | ||
_inherit = 'account.invoice' | ||
|
||
billing_id = fields.Many2one( | ||
comodel_name='account.billing', | ||
string='Billing', | ||
copy=False, | ||
index=True, | ||
help="Relationship between invoice and billing" | ||
) |
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,2 @@ | ||
* Kitti U. <kittiu@ecosoft.co.th> | ||
* Saran Lim. <saranl@ecosoft.co.th> |
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 @@ | ||
In some countries, there is a customary practice for companies to collect money | ||
from their customers only once in a month. For example, the customer has 3 payments due in | ||
a given month, the vendor or billing company should group all the due AR Invoices in a document | ||
call Billing Document and issue it with all the invoices consolidated to the customer on the Billing Day. | ||
The customer will be paying based on the payable amount shown in Billing Document in the following month. | ||
|
||
This module use a new document called "Billing" to group these invoices together. |
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,9 @@ | ||
To use this module, you have 2 ways: | ||
|
||
1. Create new billing directly | ||
Go to *Invoicing -> Customers or Vendors -> Billing* | ||
|
||
2. Create billing from selected invoice(s) | ||
#. Go to *Invoicing -> Customers or Vendors -> Invoices or Bills* | ||
#. Create Invoice | ||
#. On tree view select invoice and go to *Action -> Create Billing* |
Oops, something went wrong.