Skip to content

Commit 27515da

Browse files
committed
Merge commit 'refs/pull/370/head' of https://github.com/OCA/account-fiscal-rule into 16.0-mig-account_avatax_repair_oca
2 parents 641d471 + ae670a0 commit 27515da

20 files changed

+1199
-0
lines changed

account_avatax_repair_oca/README.rst

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
=====================================================
2+
Avalara Avatax Certified Connector for Repairs Orders
3+
=====================================================
4+
5+
.. |badge2| image:: https://img.shields.io/badge/licence-AGPL--3-blue.png
6+
:target: http://www.gnu.org/licenses/agpl-3.0-standalone.html
7+
:alt: License: AGPL-3
8+
9+
10+
|badge2|
11+
12+
This module is a component of the Avatax Integration with odoo app.
13+
Please refer to the corresponding documentation.
14+
15+
**Table of contents**
16+
17+
.. contents::
18+
:local:
19+
20+
Usage
21+
=====
22+
23+
The AvaTax module is integrated into Repair Orders and allows computation of taxes.
24+
Repairs order transactions do not appear in the in the AvaTax interface.
25+
26+
The information placed in the repair order will automatically pass to the invoice
27+
on the Avalara server and can be viewed in the AvaTax control panel.
28+
29+
Create New Repair Order
30+
31+
- Navigate to: Repairs
32+
33+
- Click Create button
34+
35+
Compute Taxes with AvaTax
36+
37+
- The module will calculate tax when the repair order is confirmed,
38+
when the changes made to a repair order are saved, by navigating to Compute Taxes
39+
or by navigating to Action >> Update taxes with Avatax.
40+
At this step, the repair order will retrieve the tax amount from Avalara
41+
but will not report the transaction to the AvaTax dashboard.
42+
Only invoice, refund, and payment activity are reported to the dashboard.
43+
44+
- The module will check if there is a selected warehouse
45+
and will automatically determine the address of the warehouse
46+
and the origin location. If no address is assigned to the warehouse
47+
the module will automatically use the address of the company as its origin.
48+
Location code will automatically populate with the warehouse code
49+
but can be modified if needed.
50+
51+
- Hide Exemption & Tax Based on shipping address -- this will provide this
52+
feature support at repair order level.
53+
54+
55+
Tax Exemption Status
56+
57+
- Tax exemption status can be defined on Contacts.
58+
59+
- In a multi-company environment, the exemption status is defined per
60+
Company, since each individual company is required to secure the
61+
exemption certificates to claim for exemption application,
62+
and this may not be the case for all Companies.
63+
64+
- If the customer is tax exempt, in the "Avatax" tab, check the "Is Tax Exempt" checkbox.
65+
When checked, the exemption details can be provided.
66+
The Exemption Code is the type of exemption,
67+
and the Exemption Number is an identification number to use on the customer's State.
68+
69+
- This exemption status will only be applied for delivery addresses
70+
in the State matching the State of the exemption address.
71+
The same customer can have exemptions on several states.
72+
For this use additional Contact/Addresses for those states,
73+
and enter the exempention details there.
74+
75+
- To make this data management simpler, is it possible to set the customer as exempt
76+
country wide, using the corresponding checkbox. In this case the exemption status will
77+
be used for delivery addresses in any state. Using this option has compliance risks, so
78+
plase use it with care.
79+
80+
Credits
81+
=======
82+
83+
Authors
84+
~~~~~~~
85+
86+
* ForgeFlow
87+
88+
Contributors
89+
~~~~~~~~~~~~
90+
91+
92+
* ForgeFlow (https://www.forgeflow.com)
93+
94+
* Alex Paris

account_avatax_repair_oca/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
from . import models
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
{
2+
"name": "Avalara Avatax Certified Connector for Repair Orders",
3+
"version": "16.0.1.0.0",
4+
"author": "ForgeFlow, Odoo Community Association (OCA)",
5+
"summary": "Repair Orders with automatic Tax application using Avatax",
6+
"license": "AGPL-3",
7+
"category": "Inventory",
8+
"website": "https://github.com/OCA/account-fiscal-rule",
9+
"depends": ["account_avatax_oca", "repair"],
10+
"data": [
11+
"views/repair_order_view.xml",
12+
"views/avalara_salestax_view.xml",
13+
"views/partner_view.xml",
14+
],
15+
"auto_install": True,
16+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
from . import account_move
2+
from . import partner
3+
from . import repair_order
4+
from . import repair_fee
5+
from . import repair_line
6+
from . import avalara_salestax
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
from odoo import api, models
2+
3+
4+
class AccountMove(models.Model):
5+
_inherit = "account.move"
6+
7+
@api.onchange("partner_id")
8+
def _onchange_partner_id(self):
9+
res = super(AccountMove, self)._onchange_partner_id()
10+
self._onchange_partner_shipping_id()
11+
return res
12+
13+
@api.onchange("partner_shipping_id")
14+
def _onchange_partner_shipping_id(self):
15+
res = super(AccountMove, self)._onchange_partner_shipping_id()
16+
self.tax_on_shipping_address = bool(self.partner_shipping_id)
17+
return res
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
from odoo import fields, models
2+
3+
4+
class AvalaraSalestax(models.Model):
5+
_inherit = "avalara.salestax"
6+
7+
use_partner_invoice_id = fields.Boolean(
8+
"Use Invoice partner's customer code in SO",
9+
default=True,
10+
help="Use Sales Order's Invoice Address field to determine Taxable" "Status",
11+
)
12+
repair_calculate_tax = fields.Boolean(
13+
"Auto Calculate Tax on Repair Save",
14+
help="Automatically triggers API to calculate tax If changes made on"
15+
"SO's warehouse_id, tax_on_shipping_address, "
16+
"SO line's price_unit, discount, product_uom_qty",
17+
)
18+
override_line_taxes = fields.Boolean(
19+
help="When checked, the Avatax computed tax will replace any other taxes"
20+
" that may exist in the document line.",
21+
)
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
from odoo import _, api, fields, models
2+
3+
4+
class ResPartner(models.Model):
5+
_inherit = "res.partner"
6+
7+
@api.onchange("property_exemption_country_wide")
8+
def _onchange_property_exemption_contry_wide(self):
9+
if self.property_exemption_country_wide:
10+
message = (
11+
_(
12+
"Enabling the exemption status for all states"
13+
" may have tax compliance risks,"
14+
" and should be carefully considered.\n\n"
15+
" Please ensure that your tax advisor was consulted and the"
16+
" necessary tax exemption documentation was obtained"
17+
" for every state this Partner may have transactions."
18+
),
19+
)
20+
return {"warning": {"title": _("Tax Compliance Risk"), "message": message}}
21+
22+
property_exemption_country_wide = fields.Boolean(
23+
"Exemption Applies Country Wide",
24+
help="When enabled, the delivery address State is irrelevant"
25+
" when looking up the exemption status, meaning that the exemption"
26+
" is considered applicable for all states",
27+
)
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
from odoo import api, fields, models
2+
3+
4+
class RepairFee(models.Model):
5+
_inherit = "repair.fee"
6+
7+
tax_amt_avatax = fields.Monetary(string="AvaTax")
8+
9+
@api.depends("tax_amt_avatax")
10+
def _compute_price_total(self):
11+
res = super()._compute_price_total()
12+
for fee in self:
13+
fee.price_total = fee.price_subtotal + fee.tax_amt_avatax
14+
return res
15+
16+
def _avatax_prepare_line(self, sign=1, doc_type=None):
17+
"""
18+
Prepare a line to use for Avatax computation.
19+
Returns a dict
20+
"""
21+
line = self
22+
res = {}
23+
# Add UPC to product item code
24+
avatax_config = line.company_id.get_avatax_config_company()
25+
product = line.product_id
26+
if product.barcode and avatax_config.upc_enable:
27+
item_code = "UPC:%d" % product.barcode
28+
else:
29+
item_code = product.default_code or ("ID:%d" % product.id)
30+
tax_code = line.product_id.applicable_tax_code_id.name
31+
amount = sign * line.price_unit * line.product_uom_qty
32+
# Calculate discount amount
33+
discount_amount = 0.0
34+
is_discounted = False
35+
res = {
36+
"qty": line.product_uom_qty,
37+
"itemcode": item_code,
38+
"description": line.name,
39+
"discounted": is_discounted,
40+
"discount": discount_amount,
41+
"amount": amount,
42+
"tax_code": tax_code,
43+
"id": line,
44+
"tax_id": line.tax_id,
45+
}
46+
return res
47+
48+
@api.onchange("product_uom_qty", "price_unit", "tax_id")
49+
def onchange_reset_avatax_amount(self):
50+
"""
51+
When changing quantities or prices, reset the Avatax computed amount.
52+
The Odoo computed tax amount will then be shown, as a reference.
53+
The Avatax amount will be recomputed upon document validation.
54+
"""
55+
for line in self:
56+
line.tax_amt_avatax = 0
57+
line.repair_id.amount_tax_avatax = 0
58+
59+
@api.depends("product_uom_qty", "price_unit", "tax_id", "tax_amt_avatax")
60+
def _compute_amount(self):
61+
"""
62+
If we have a Avatax computed amount, use it instead of the Odoo computed one
63+
"""
64+
super()._compute_amount()
65+
for line in self:
66+
if line.tax_amt_avatax: # Has Avatax computed amount
67+
vals = {
68+
"price_tax": line.tax_amt_avatax,
69+
"price_total": line.price_subtotal + line.tax_amt_avatax,
70+
}
71+
line.update(vals)
72+
return
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
from odoo import api, fields, models
2+
3+
4+
class RepairLine(models.Model):
5+
_inherit = "repair.line"
6+
7+
tax_amt_avatax = fields.Monetary(string="AvaTax")
8+
9+
@api.depends("tax_amt_avatax")
10+
def _compute_price_total(self):
11+
res = super()._compute_price_total()
12+
for line in self:
13+
line.price_total = line.price_subtotal + line.tax_amt_avatax
14+
return res
15+
16+
def _avatax_prepare_line(self, sign=1, doc_type=None):
17+
"""
18+
Prepare a line to use for Avatax computation.
19+
Returns a dict
20+
"""
21+
line = self
22+
res = {}
23+
# Add UPC to product item code
24+
avatax_config = line.company_id.get_avatax_config_company()
25+
product = line.product_id
26+
if product.barcode and avatax_config.upc_enable:
27+
item_code = "UPC:%d" % product.barcode
28+
else:
29+
item_code = product.default_code or ("ID:%d" % product.id)
30+
tax_code = line.product_id.applicable_tax_code_id.name
31+
amount = sign * line.price_unit * line.product_uom_qty
32+
# Calculate discount amount
33+
discount_amount = 0.0
34+
is_discounted = False
35+
res = {
36+
"qty": line.product_uom_qty,
37+
"itemcode": item_code,
38+
"description": line.name,
39+
"discounted": is_discounted,
40+
"discount": discount_amount,
41+
"amount": amount,
42+
"tax_code": tax_code,
43+
"id": line,
44+
"tax_id": line.tax_id,
45+
}
46+
return res
47+
48+
@api.onchange("product_uom_qty", "price_unit", "tax_id")
49+
def onchange_reset_avatax_amount(self):
50+
"""
51+
When changing quantities or prices, reset the Avatax computed amount.
52+
The Odoo computed tax amount will then be shown, as a reference.
53+
The Avatax amount will be recomputed upon document validation.
54+
"""
55+
for line in self:
56+
line.tax_amt_avatax = 0
57+
line.repair_id.amount_tax_avatax = 0
58+
59+
@api.depends("product_uom_qty", "price_unit", "tax_id", "tax_amt_avatax")
60+
def _compute_amount(self):
61+
"""
62+
If we have a Avatax computed amount, use it instead of the Odoo computed one
63+
"""
64+
super()._compute_amount()
65+
for line in self:
66+
if line.tax_amt_avatax: # Has Avatax computed amount
67+
vals = {
68+
"price_tax": line.tax_amt_avatax,
69+
"price_total": line.price_subtotal + line.tax_amt_avatax,
70+
}
71+
line.update(vals)
72+
return

0 commit comments

Comments
 (0)