-
-
Notifications
You must be signed in to change notification settings - Fork 178
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
23 changed files
with
1,595 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,66 @@ | ||
|License LGPL-3| | |Build Status| | |Test Coverage| | ||
|
||
================== | ||
Tax Connector Base | ||
================== | ||
|
||
|
||
Installation | ||
============ | ||
|
||
|
||
Configuration | ||
============= | ||
|
||
|
||
Known Issues / Road Map | ||
======================= | ||
|
||
* In order for rates to work, the reference record must actually be saved. | ||
This is because the reference fields require explicit ``(model_name,id)`` | ||
formatting, but with an unsaved record the ID is ``NewId``. | ||
* Transaction refund method is on ``account.tax.transaction``, but it should | ||
possibly be on ``account.tax.transaction.line`` instead. This was done to | ||
simplify the addition of new adapters, but may over-complicate things. | ||
* Add a registration system for connectors, with a more centralized method for | ||
determining if the connector should be used. | ||
* Add a hook for the update of a tax transaction. TBD what would actually trigger | ||
an update, because invoices can't be edited. | ||
* Need a way to handle tax differentiation at the invoice line item level, so | ||
connectors can send individual lines instead of just whole orders. | ||
|
||
Bug Tracker | ||
=========== | ||
|
||
Bugs are tracked on `GitHub Issues | ||
<https://github.com/LasLabs/odoo-connector-taxjar/issues>`_. In case of trouble, please | ||
check there if your issue has already been reported. If you spotted it first, | ||
help us smash it by providing detailed and welcomed feedback. | ||
|
||
Credits | ||
======= | ||
|
||
Contributors | ||
------------ | ||
|
||
* Dave Lasley <dave@laslabs.com> | ||
|
||
Do not contact contributors directly about support or help with technical issues. | ||
|
||
Maintainer | ||
---------- | ||
|
||
.. image:: https://laslabs.com/logo.png | ||
:alt: LasLabs Inc. | ||
:target: https://laslabs.com | ||
|
||
This module is maintained by LasLabs Inc. | ||
|
||
|
||
.. |Build Status| image:: https://img.shields.io/travis/LasLabs/odoo-connector-taxjar/master.svg | ||
:target: https://travis-ci.org/LasLabs/odoo-connector-taxjar | ||
.. |Test Coverage| image:: https://img.shields.io/codecov/c/github/LasLabs/odoo-connector-taxjar/master.svg | ||
:target: https://codecov.io/gh/LasLabs/odoo-connector-taxjar | ||
.. |License LGPL-3| image:: https://img.shields.io/badge/license-LGPL--3-blue.svg | ||
:target: https://www.gnu.org/licenses/lgpl | ||
:alt: License: LGPL-3 |
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 @@ | ||
# -*- coding: utf-8 -*- | ||
# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl). | ||
|
||
from . import models | ||
from . import wizards |
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,27 @@ | ||
# -*- coding: utf-8 -*- | ||
# Copyright 2017 LasLabs Inc. | ||
# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl). | ||
|
||
# pylint: disable=C8101 | ||
{ | ||
"name": "Tax Connector Base", | ||
"summary": "Provides centralized logic for connection with external tax" | ||
"connectors and subsequent caching of results.", | ||
"version": "10.0.1.0.0", | ||
"category": "Connector", | ||
"website": "https://laslabs.com", | ||
"author": "LasLabs", | ||
"license": "LGPL-3", | ||
"application": False, | ||
"installable": True, | ||
"data": [ | ||
'security/ir.model.access.csv', | ||
'views/account_tax_transaction_view.xml', | ||
], | ||
"depends": [ | ||
"account", | ||
# @TODO: Figure out how to install below in a hook when testing. | ||
"purchase", | ||
"sale", | ||
], | ||
} |
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,12 @@ | ||
# -*- coding: utf-8 -*- | ||
# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl). | ||
|
||
from . import account_tax | ||
from . import account_tax_group | ||
from . import account_tax_transaction | ||
from . import account_tax_transaction_line | ||
|
||
# Line computation injections | ||
from . import account_invoice | ||
from . import account_invoice_line | ||
from . import sale_order_line |
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,28 @@ | ||
# -*- coding: utf-8 -*- | ||
# Copyright 2017 LasLabs Inc. | ||
# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl). | ||
|
||
import logging | ||
|
||
from odoo import api, models | ||
|
||
_logger = logging.getLogger(__name__) | ||
|
||
|
||
class AccountInvoice(models.Model): | ||
|
||
_inherit = 'account.invoice' | ||
|
||
@api.multi | ||
def action_move_create(self): | ||
"""Add tax purchase/refund logic into invoice validation.""" | ||
res = super(AccountInvoice, self).action_move_create() | ||
for invoice in self: | ||
if 'refund' in invoice.type: | ||
method = self.env['account.tax.group'].invoice_tax_refund | ||
else: | ||
method = self.env['account.tax.group'].invoice_tax_purchase | ||
_logger.info('Running %s on %s with type %s', | ||
method, invoice, invoice.type) | ||
method(invoice) | ||
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,30 @@ | ||
# -*- coding: utf-8 -*- | ||
# Copyright 2017 LasLabs Inc. | ||
# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl). | ||
|
||
import logging | ||
|
||
from odoo import api, fields, models | ||
|
||
|
||
_logger = logging.getLogger(__name__) | ||
|
||
|
||
class AccountInvoiceLine(models.Model): | ||
|
||
_inherit = 'account.invoice.line' | ||
|
||
@api.multi | ||
def _compute_price(self): | ||
origin = getattr(self, '_origin', None) | ||
for invoice in self.mapped('invoice_id'): | ||
self.env['account.tax.rate'].get( | ||
'account.invoice.tax.rate', | ||
invoice, | ||
origin and origin.invoice_id, | ||
) | ||
_logger.info( | ||
'Rates primed for invoice lines. In onchange? %s & %s', | ||
self.env.in_onchange, self.env.in_draft, | ||
) | ||
return super(AccountInvoiceLine, self)._compute_price() |
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,44 @@ | ||
# -*- coding: utf-8 -*- | ||
# Copyright 2017 LasLabs Inc. | ||
# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl). | ||
|
||
import logging | ||
|
||
from collections import defaultdict | ||
|
||
from odoo import api, models, fields | ||
|
||
|
||
_logger = logging.getLogger(__name__) | ||
|
||
|
||
class AccountTax(models.Model): | ||
|
||
_inherit = 'account.tax' | ||
|
||
amount_type = fields.Selection( | ||
selection_add=[('cache', 'Cached Data')], | ||
) | ||
|
||
@api.multi | ||
def _compute_amount(self, base_amount, price_unit, quantity=1.0, | ||
product=None, partner=None): | ||
"""Return the cached rate if it's a cached tax, otherwise super.""" | ||
self.ensure_one() | ||
if self.amount_type == 'cache': | ||
cached = self.env['account.tax.rate.line'].get( | ||
self, base_amount, price_unit, quantity, product, partner, | ||
) | ||
_logger.info('Got cached rate %s' % cached.price_tax) | ||
return cached and cached.price_tax or 0.0 | ||
return super(AccountTax, self)._compute_amount( | ||
base_amount, price_unit, quantity, product, partner, | ||
) | ||
|
||
@api.multi | ||
def _get_by_group(self): | ||
"""Return the taxes in a dictionary keyed by tax group.""" | ||
grouped = defaultdict(self.env['account.tax'].browse) | ||
for tax in self: | ||
grouped[tax.tax_group_id] += tax | ||
return grouped |
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,96 @@ | ||
# -*- coding: utf-8 -*- | ||
# Copyright 2017 LasLabs Inc. | ||
# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl). | ||
|
||
import logging | ||
|
||
from odoo import api, models, fields | ||
|
||
_logger = logging.getLogger(__name__) | ||
|
||
|
||
class AccountTaxGroup(models.Model): | ||
|
||
_inherit = 'account.tax.group' | ||
|
||
cache_name = fields.Char( | ||
help='This is the name of the cache store. It is an ' | ||
'arbitrary string that is primarily meant for connectors to ' | ||
'identify themselves.', | ||
) | ||
|
||
@api.multi | ||
def compute_cache_rate(self, base_amount, rate_line_values): | ||
"""Compute the cached rates for the ``account.tax.rate.line`` records. | ||
This method should be inherited by connectors in order to get rates | ||
from an external source. A singleton is guaranteed. | ||
Connector methods should call super, then edit and return the values. | ||
Args: | ||
base_amount (float): The base amount that the taxes are being | ||
applied on. This is typically the subtotal. | ||
rate_line_values (list(dict)): List of rate line values. | ||
Returns: | ||
rate_line_values (list(dict)): The same input, but with rates | ||
adjusted by any tax connectors. They will be written to the | ||
cache during ``account.tax.rate.get_rate_values``. | ||
""" | ||
self.ensure_one() | ||
_logger.debug('Computing rate for %s with base amount %s. Lines:\n%s', | ||
self, base_amount, rate_line_values) | ||
return rate_line_values | ||
|
||
@api.multi | ||
def do_tax_purchase(self, account_invoice_tax): | ||
"""Purchase a set of taxes. | ||
This method should be inherited by connectors in order to purchase | ||
taxes from an external source. A singleton is guaranteed. | ||
Connector methods should call super and perform any actual | ||
transactions. They can edit the transaction record that is returned | ||
if necessary, but that probably won't be the case. | ||
""" | ||
self.ensure_one() | ||
_logger.debug('Purchasing tax for %s', account_invoice_tax) | ||
return self.env['account.tax.transaction'].buy(account_invoice_tax) | ||
|
||
@api.multi | ||
def do_tax_refund(self, account_invoice_tax): | ||
"""Purchase a set of taxes. | ||
This method should be inherited by connectors in order to refund | ||
taxes from an external source. A singleton is guaranteed. | ||
Connector methods should call super and perform any actual | ||
transactions. They can edit the transaction record that is returned | ||
if necessary, but that probably won't be the case. | ||
""" | ||
self.ensure_one() | ||
_logger.debug('Refunding tax for %s', account_invoice_tax) | ||
return self.env['account.tax.transaction'].refund(account_invoice_tax) | ||
|
||
@api.model | ||
def invoice_tax_purchase(self, invoice): | ||
"""Perform a tax purchase for an invoice.""" | ||
taxes = invoice.mapped('invoice_line_ids.invoice_line_tax_ids') | ||
grouped_taxes = taxes._get_by_group() | ||
for group, taxes in grouped_taxes.items(): | ||
invoice_taxes = invoice.tax_line_ids.filtered( | ||
lambda r: r.tax_id in taxes | ||
) | ||
group.do_tax_purchase(invoice_taxes) | ||
|
||
@api.model | ||
def invoice_tax_refund(self, invoice): | ||
"""Perform a tax refund for an invoice.""" | ||
taxes = invoice.mapped('invoice_line_ids.invoice_line_tax_ids') | ||
grouped_taxes = taxes._get_by_group() | ||
for group, taxes in grouped_taxes.items(): | ||
invoice_taxes = invoice.tax_line_ids.filtered( | ||
lambda r: r.tax_id in taxes | ||
) | ||
group.do_tax_refund(invoice_taxes) |
Oops, something went wrong.