2023-04-17 11:58:21 +00:00
import { LineItemModel } from "avatax/lib/models/LineItemModel" ;
import { TransactionModel } from "avatax/lib/models/TransactionModel" ;
import { TaxBaseFragment } from "../../../../generated/graphql" ;
import { DocumentType } from "avatax/lib/enums/DocumentType" ;
import { ChannelConfig } from "../../channels-configuration/channels-config" ;
2023-04-26 11:40:51 +00:00
import { numbers } from "../../taxes/numbers" ;
2023-04-17 11:58:21 +00:00
import { CalculateTaxesResponse } from "../../taxes/tax-provider-webhook" ;
import { CreateTransactionArgs } from "../avatax-client" ;
import { AvataxConfig } from "../avatax-config" ;
import { avataxAddressFactory } from "./address-factory" ;
/ * *
* * Shipping is a regular line item in Avatax
* https : //developer.avalara.com/avatax/dev-guide/shipping-and-handling/taxability-of-shipping-charges/
* /
const SHIPPING_ITEM_CODE = "Shipping" ;
function mapLines ( taxBase : TaxBaseFragment ) : LineItemModel [ ] {
const productLines = taxBase . lines . map ( ( line ) = > ( {
amount : line.unitPrice.amount ,
taxIncluded : line.chargeTaxes ,
// todo: get from tax code matcher
2023-04-26 11:40:51 +00:00
taxCode : "" ,
2023-04-17 11:58:21 +00:00
quantity : line.quantity ,
} ) ) ;
if ( taxBase . shippingPrice . amount !== 0 ) {
// * In Avatax, shipping is a regular line
const shippingLine : LineItemModel = {
amount : taxBase.shippingPrice.amount ,
itemCode : SHIPPING_ITEM_CODE ,
/ * *
* todo : add taxCode
* * Different shipping methods can have different tax codes
* https : //developer.avalara.com/ecommerce-integration-guide/sales-tax-badge/designing/non-standard-items/\
* /
quantity : 1 ,
} ;
return [ . . . productLines , shippingLine ] ;
}
return productLines ;
}
export type AvataxCalculateTaxesMapPayloadArgs = {
taxBase : TaxBaseFragment ;
channel : ChannelConfig ;
config : AvataxConfig ;
} ;
const mapPayload = ( props : AvataxCalculateTaxesMapPayloadArgs ) : CreateTransactionArgs = > {
const { taxBase , channel , config } = props ;
return {
model : {
type : DocumentType . SalesOrder ,
customerCode : taxBase.sourceObject.user?.id ? ? "" ,
companyCode : config.companyCode ,
// * commit: If true, the transaction will be committed immediately after it is created. See: https://developer.avalara.com/communications/dev-guide_rest_v2/commit-uncommit
commit : config.isAutocommit ,
addresses : {
shipFrom : avataxAddressFactory.fromChannelAddress ( channel . address ) ,
shipTo : avataxAddressFactory.fromSaleorAddress ( taxBase . address ! ) ,
} ,
currencyCode : taxBase.currency ,
lines : mapLines ( taxBase ) ,
date : new Date ( ) ,
} ,
} ;
} ;
const mapResponse = ( transaction : TransactionModel ) : CalculateTaxesResponse = > {
const shippingLine = transaction . lines ? . find ( ( line ) = > line . itemCode === SHIPPING_ITEM_CODE ) ;
const productLines = transaction . lines ? . filter ( ( line ) = > line . itemCode !== SHIPPING_ITEM_CODE ) ;
const shippingGrossAmount = shippingLine ? . taxableAmount ? ? 0 ;
const shippingTaxCalculated = shippingLine ? . taxCalculated ? ? 0 ;
const shippingNetAmount = numbers . roundFloatToTwoDecimals (
shippingGrossAmount - shippingTaxCalculated
) ;
return {
shipping_price_gross_amount : shippingGrossAmount ,
shipping_price_net_amount : shippingNetAmount ,
// todo: add shipping tax rate
shipping_tax_rate : 0 ,
lines :
productLines ? . map ( ( line ) = > {
const lineTaxCalculated = line . taxCalculated ? ? 0 ;
const lineTotalNetAmount = line . taxableAmount ? ? 0 ;
const lineTotalGrossAmount = numbers . roundFloatToTwoDecimals (
lineTotalNetAmount + lineTaxCalculated
) ;
return {
total_gross_amount : lineTotalGrossAmount ,
total_net_amount : lineTotalNetAmount ,
// todo: add tax rate
tax_rate : 0 ,
} ;
} ) ? ? [ ] ,
} ;
} ;
export const avataxCalculateTaxesMaps = {
mapPayload ,
mapResponse ,
mapLines ,
shippingItemCode : SHIPPING_ITEM_CODE ,
} ;