Skip to content

Commit

Permalink
Merge PR #369 into 14.0
Browse files Browse the repository at this point in the history
Signed-off-by dreispt
  • Loading branch information
OCA-git-bot committed Oct 10, 2023
2 parents e909fd9 + 7d5eb26 commit b89ba13
Show file tree
Hide file tree
Showing 20 changed files with 1,179 additions and 0 deletions.
94 changes: 94 additions & 0 deletions account_avatax_repair_oca/README.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
=====================================================
Avalara Avatax Certified Connector for Repairs Orders
=====================================================

.. |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


|badge2|

This module is a component of the Avatax Integration with odoo app.
Please refer to the corresponding documentation.

**Table of contents**

.. contents::
:local:

Usage
=====

The AvaTax module is integrated into Repair Orders and allows computation of taxes.
Repairs order transactions do not appear in the in the AvaTax interface.

The information placed in the repair order will automatically pass to the invoice
on the Avalara server and can be viewed in the AvaTax control panel.

Create New Repair Order

- Navigate to: Repairs

- Click Create button

Compute Taxes with AvaTax

- The module will calculate tax when the repair order is confirmed,
when the changes made to a repair order are saved, by navigating to Compute Taxes
or by navigating to Action >> Update taxes with Avatax.
At this step, the repair order will retrieve the tax amount from Avalara
but will not report the transaction to the AvaTax dashboard.
Only invoice, refund, and payment activity are reported to the dashboard.

- The module will check if there is a selected warehouse
and will automatically determine the address of the warehouse
and the origin location. If no address is assigned to the warehouse
the module will automatically use the address of the company as its origin.
Location code will automatically populate with the warehouse code
but can be modified if needed.

- Hide Exemption & Tax Based on shipping address -- this will provide this
feature support at repair order level.


Tax Exemption Status

- Tax exemption status can be defined on Contacts.

- In a multi-company environment, the exemption status is defined per
Company, since each individual company is required to secure the
exemption certificates to claim for exemption application,
and this may not be the case for all Companies.

- If the customer is tax exempt, in the "Avatax" tab, check the "Is Tax Exempt" checkbox.
When checked, the exemption details can be provided.
The Exemption Code is the type of exemption,
and the Exemption Number is an identification number to use on the customer's State.

- This exemption status will only be applied for delivery addresses
in the State matching the State of the exemption address.
The same customer can have exemptions on several states.
For this use additional Contact/Addresses for those states,
and enter the exempention details there.

- To make this data management simpler, is it possible to set the customer as exempt
country wide, using the corresponding checkbox. In this case the exemption status will
be used for delivery addresses in any state. Using this option has compliance risks, so
plase use it with care.

Credits
=======

Authors
~~~~~~~

* ForgeFlow

Contributors
~~~~~~~~~~~~


* ForgeFlow (https://www.forgeflow.com)

* Alex Paris
1 change: 1 addition & 0 deletions account_avatax_repair_oca/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from . import models
16 changes: 16 additions & 0 deletions account_avatax_repair_oca/__manifest__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"name": "Avalara Avatax Certified Connector for Repair Orders",
"version": "14.0.1.0.0",
"author": "ForgeFlow, Odoo Community Association (OCA)",
"summary": "Repair Orders with automatic Tax application using Avatax",
"license": "AGPL-3",
"category": "Inventory",
"website": "https://github.com/OCA/account-fiscal-rule",
"depends": ["account_avatax_oca", "repair"],
"data": [
"views/repair_order_view.xml",
"views/avalara_salestax_view.xml",
"views/partner_view.xml",
],
"auto_install": True,
}
6 changes: 6 additions & 0 deletions account_avatax_repair_oca/models/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
from . import account_move
from . import partner
from . import repair_order
from . import repair_fee
from . import repair_line
from . import avalara_salestax
17 changes: 17 additions & 0 deletions account_avatax_repair_oca/models/account_move.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
from odoo import api, models


class AccountMove(models.Model):
_inherit = "account.move"

@api.onchange("partner_id")
def _onchange_partner_id(self):
res = super(AccountMove, self)._onchange_partner_id()
self._onchange_partner_shipping_id()
return res

@api.onchange("partner_shipping_id")
def _onchange_partner_shipping_id(self):
res = super(AccountMove, self)._onchange_partner_shipping_id()
self.tax_on_shipping_address = bool(self.partner_shipping_id)
return res
21 changes: 21 additions & 0 deletions account_avatax_repair_oca/models/avalara_salestax.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
from odoo import fields, models


class AvalaraSalestax(models.Model):
_inherit = "avalara.salestax"

use_partner_invoice_id = fields.Boolean(
"Use Invoice partner's customer code in SO",
default=True,
help="Use Sales Order's Invoice Address field to determine Taxable" "Status",
)
repair_calculate_tax = fields.Boolean(
"Auto Calculate Tax on Repair Save",
help="Automatically triggers API to calculate tax If changes made on"
"SO's warehouse_id, tax_on_shipping_address, "
"SO line's price_unit, discount, product_uom_qty",
)
override_line_taxes = fields.Boolean(
help="When checked, the Avatax computed tax will replace any other taxes"
" that may exist in the document line.",
)
27 changes: 27 additions & 0 deletions account_avatax_repair_oca/models/partner.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
from odoo import _, api, fields, models


class ResPartner(models.Model):
_inherit = "res.partner"

@api.onchange("property_exemption_country_wide")
def _onchange_property_exemption_contry_wide(self):
if self.property_exemption_country_wide:
message = (
_(
"Enabling the exemption status for all states"
" may have tax compliance risks,"
" and should be carefully considered.\n\n"
" Please ensure that your tax advisor was consulted and the"
" necessary tax exemption documentation was obtained"
" for every state this Partner may have transactions."
),
)
return {"warning": {"title": _("Tax Compliance Risk"), "message": message}}

property_exemption_country_wide = fields.Boolean(
"Exemption Applies Country Wide",
help="When enabled, the delivery address State is irrelevant"
" when looking up the exemption status, meaning that the exemption"
" is considered applicable for all states",
)
73 changes: 73 additions & 0 deletions account_avatax_repair_oca/models/repair_fee.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
from odoo import api, fields, models


class RepairFee(models.Model):
_inherit = "repair.fee"

tax_amt_avatax = fields.Monetary(string="AvaTax")

@api.depends("tax_amt_avatax")
def _compute_price_total(self):
res = super()._compute_price_total()
for fee in self:
fee.price_total = fee.price_subtotal + fee.tax_amt_avatax
return res

def _avatax_prepare_line(self, sign=1, doc_type=None):
"""
Prepare a line to use for Avatax computation.
Returns a dict
"""
line = self
res = {}
# Add UPC to product item code
avatax_config = line.company_id.get_avatax_config_company()
product = line.product_id
if product.barcode and avatax_config.upc_enable:
item_code = "UPC:%d" % product.barcode
else:
item_code = product.default_code or ("ID:%d" % product.id)
tax_code = line.product_id.applicable_tax_code_id.name
amount = sign * line.price_unit * line.product_uom_qty
# Calculate discount amount
discount_amount = 0.0
is_discounted = False
res = {
"qty": line.product_uom_qty,
"itemcode": item_code,
"description": line.name,
"discounted": is_discounted,
"discount": discount_amount,
"amount": amount,
"tax_code": tax_code,
"id": line,
"tax_id": line.tax_id,
}
return res

@api.onchange("product_uom_qty", "discount", "price_unit", "tax_id")
def onchange_reset_avatax_amount(self):
"""
When changing quantities or prices, reset the Avatax computed amount.
The Odoo computed tax amount will then be shown, as a reference.
The Avatax amount will be recomputed upon document validation.
"""
for line in self:
line.tax_amt_avatax = 0
line.repair_id.amount_tax_avatax = 0

@api.depends(
"product_uom_qty", "discount", "price_unit", "tax_id", "tax_amt_avatax"
)
def _compute_amount(self):
"""
If we have a Avatax computed amount, use it instead of the Odoo computed one
"""
super()._compute_amount()
for line in self:
if line.tax_amt_avatax: # Has Avatax computed amount
vals = {
"price_tax": line.tax_amt_avatax,
"price_total": line.price_subtotal + line.tax_amt_avatax,
}
line.update(vals)
73 changes: 73 additions & 0 deletions account_avatax_repair_oca/models/repair_line.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
from odoo import api, fields, models


class RepairLine(models.Model):
_inherit = "repair.line"

tax_amt_avatax = fields.Monetary(string="AvaTax")

@api.depends("tax_amt_avatax")
def _compute_price_total(self):
res = super()._compute_price_total()
for line in self:
line.price_total = line.price_subtotal + line.tax_amt_avatax
return res

def _avatax_prepare_line(self, sign=1, doc_type=None):
"""
Prepare a line to use for Avatax computation.
Returns a dict
"""
line = self
res = {}
# Add UPC to product item code
avatax_config = line.company_id.get_avatax_config_company()
product = line.product_id
if product.barcode and avatax_config.upc_enable:
item_code = "UPC:%d" % product.barcode
else:
item_code = product.default_code or ("ID:%d" % product.id)
tax_code = line.product_id.applicable_tax_code_id.name
amount = sign * line.price_unit * line.product_uom_qty
# Calculate discount amount
discount_amount = 0.0
is_discounted = False
res = {
"qty": line.product_uom_qty,
"itemcode": item_code,
"description": line.name,
"discounted": is_discounted,
"discount": discount_amount,
"amount": amount,
"tax_code": tax_code,
"id": line,
"tax_id": line.tax_id,
}
return res

@api.onchange("product_uom_qty", "discount", "price_unit", "tax_id")
def onchange_reset_avatax_amount(self):
"""
When changing quantities or prices, reset the Avatax computed amount.
The Odoo computed tax amount will then be shown, as a reference.
The Avatax amount will be recomputed upon document validation.
"""
for line in self:
line.tax_amt_avatax = 0
line.repair_id.amount_tax_avatax = 0

@api.depends(
"product_uom_qty", "discount", "price_unit", "tax_id", "tax_amt_avatax"
)
def _compute_amount(self):
"""
If we have a Avatax computed amount, use it instead of the Odoo computed one
"""
super()._compute_amount()
for line in self:
if line.tax_amt_avatax: # Has Avatax computed amount
vals = {
"price_tax": line.tax_amt_avatax,
"price_total": line.price_subtotal + line.tax_amt_avatax,
}
line.update(vals)
Loading

0 comments on commit b89ba13

Please sign in to comment.