Skip to content

Commit

Permalink
fix: properly handling cubic weight on calculate and tag creation (if…
Browse files Browse the repository at this point in the history
… enabled)
  • Loading branch information
leomp12 committed Sep 14, 2024
1 parent 976c741 commit be2e1c8
Show file tree
Hide file tree
Showing 3 changed files with 132 additions and 124 deletions.
174 changes: 91 additions & 83 deletions functions/lib/kangu/create-tag.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,33 +16,48 @@ const getEcomProduct = (appSdk, storeId, productId) => {
})
}

module.exports = async (order, token, storeId, appData, appSdk) => {
// create new shipping tag with Kangu
// https://portal.kangu.com.br/docs/api/transporte/#/
module.exports = async ({
order,
shippingLine,
kanguToken,
storeId,
appData,
appSdk
}) => {
// create new shipping tag with Kangu
// https://portal.kangu.com.br/docs/api/transporte/#/
const headers = {
token,
token: kanguToken,
accept: 'application/json',
'Content-Type': 'application/json'
}
const data = {}
data.destinatario = {}
data.remetente = {}
const hasInvoice = Boolean(order.shipping_lines.find(({ invoices }) => {
return invoices && invoices[0] && invoices[0].number
}))
const { items } = order
// start parsing order body
data.produtos = []
let subtotal = 0
if (items) {
for (let i = 0; i < items.length; i++) {
const item = items[i]
const data = {
destinatario: {},
remetente: {}
}
const isUsingCubicWeight = (appData.use_kubic_weight || appData.use_cubic_weight)
if (isUsingCubicWeight && shippingLine.package?.weight) {
const { unit, value } = shippingLine.package.weight
data.volumes = [{
peso: !unit || unit === 'kg'
? value
: unit === 'g'
? value * 1000
: value * 1000000,
altura: 4,
largura: 16,
comprimento: 24,
valor: order.amount?.subtotal || 0
}]
} else if (order.items) {
data.produtos = []
for (let i = 0; i < order.items.length; i++) {
const item = order.items[i]
const produto = {
valor: item.final_price || item.price,
quantidade: item.quantity,
produto: item.name
}
subtotal += (produto.valor * produto.quantidade)
await getEcomProduct(appSdk, storeId, item.product_id)
.then(({ response }) => {
const product = response.data
Expand Down Expand Up @@ -87,86 +102,79 @@ module.exports = async (order, token, storeId, appData, appSdk) => {
.catch(logger.error)
}
}
const invoice = shippingLine.invoices?.find((invoice) => {
return invoice.number && invoice.access_key
})
data.origem = 'E-Com Plus'
data.pedido = {
numeroCli: appData.send_number ? order.number : order._id,
vlrMerc: subtotal || order.amount?.subtotal || 0,
tipo: hasInvoice ? 'N' : 'D'
vlrMerc: order.amount?.subtotal || 0,
tipo: invoice ? 'N' : 'D'
}
if (hasInvoice) {
const invoice = order.shipping_lines[0].invoices[0]
if (invoice) {
data.pedido.numero = invoice.number
data.pedido.serie = invoice.serial_number || '1'
data.pedido.chave = invoice.access_key
}
const buyer = order.buyers && order.buyers[0]
if (buyer && buyer.doc_number) {
const buyer = order.buyers?.[0]
if (buyer?.doc_number) {
data.destinatario.cnpjCpf = buyer.doc_number.replace(/\D/g, '')
data.destinatario.contato = buyer.display_name
}
if (buyer && buyer.main_email) {
if (buyer?.main_email) {
data.destinatario.email = buyer.main_email
}
if (buyer && Array.isArray(buyer.phones) && buyer.phones.length) {
if (buyer?.phones?.length) {
data.destinatario.celular = buyer.phones[0].number
}
const requests = []
if (order.shipping_lines) {
order.shipping_lines.forEach(shippingLine => {
if (shippingLine.app) {
data.servicos = [shippingLine.app.service_name]
// parse addresses and package info from shipping line object
if (shippingLine.from) {
data.remetente = {}
if (appData.seller) {
data.remetente.nome = appData.seller.name
if (shippingLine.warehouse_code) {
data.remetente.nome += ` [${shippingLine.warehouse_code}]`
}
data.remetente.cnpjCpf = appData.seller.doc_number
data.remetente.contato = appData.seller.contact
}
data.remetente.endereco = {
logradouro: shippingLine.from.street,
numero: shippingLine.from.number || 'SN',
bairro: shippingLine.from.borough,
cep: shippingLine.from.zip.replace(/\D/g, ''),
cidade: shippingLine.from.city,
uf: shippingLine.from.province_code,
complemento: shippingLine.from.complement || ''
}
}
if (shippingLine.to) {
data.destinatario.nome = shippingLine.to.name
if (shippingLine.warehouse_code) {
data.destinatario.nome += ` [${shippingLine.warehouse_code}]`
}
data.destinatario.endereco = {
logradouro: shippingLine.to.street,
numero: shippingLine.to.number || 'SN',
bairro: shippingLine.to.borough,
cep: shippingLine.to.zip.replace(/\D/g, ''),
cidade: shippingLine.to.city,
uf: shippingLine.to.province_code,
complemento: shippingLine.to.complement || ''
}
}
data.referencia = getShippingCustomField(order, 'kangu_reference')
logger.info(`> Create tag for #${order._id}`, { data })
// send POST to generate Kangu tag
requests.push(axios.post(
'https://portal.kangu.com.br/tms/transporte/solicitar',
data,
{ headers }
).then(response => {
logger.info('> Kangu tag created')
return response.data
}).catch(error => {
debugAxiosError(error)
throw error
}))
data.servicos = [shippingLine.app.service_name]
// parse addresses and package info from shipping line object
if (shippingLine.from) {
data.remetente = {}
if (appData.seller) {
data.remetente.nome = appData.seller.name
if (shippingLine.warehouse_code) {
data.remetente.nome += ` [${shippingLine.warehouse_code}]`
}
})
data.remetente.cnpjCpf = appData.seller.doc_number
data.remetente.contato = appData.seller.contact
}
data.remetente.endereco = {
logradouro: shippingLine.from.street,
numero: shippingLine.from.number || 'SN',
bairro: shippingLine.from.borough,
cep: shippingLine.from.zip.replace(/\D/g, ''),
cidade: shippingLine.from.city,
uf: shippingLine.from.province_code,
complemento: shippingLine.from.complement || ''
}
}
if (shippingLine.to) {
data.destinatario.nome = shippingLine.to.name
if (shippingLine.warehouse_code) {
data.destinatario.nome += ` [${shippingLine.warehouse_code}]`
}
data.destinatario.endereco = {
logradouro: shippingLine.to.street,
numero: shippingLine.to.number || 'SN',
bairro: shippingLine.to.borough,
cep: shippingLine.to.zip.replace(/\D/g, ''),
cidade: shippingLine.to.city,
uf: shippingLine.to.province_code,
complemento: shippingLine.to.complement || ''
}
}
return Promise.all(requests)
data.referencia = getShippingCustomField(order, 'kangu_reference')
logger.info(`> Create tag for #${order._id}`, { data })
return axios.post(
'https://portal.kangu.com.br/tms/transporte/solicitar',
data,
{ headers }
).then(response => {
logger.info('> Kangu tag created')
return response.data
}).catch(error => {
debugAxiosError(error)
throw error
})
}
70 changes: 31 additions & 39 deletions functions/routes/ecom/modules/calculate-shipping.js
Original file line number Diff line number Diff line change
Expand Up @@ -169,19 +169,15 @@ exports.post = ({ appSdk }, req, res) => {
})
}

console.log('Before quote', storeId)

if (params.items) {
let finalWeight = 0
let finalCubicWeight = 0
let pkgWeight = 0
let cartSubtotal = 0
const produtos = []
params.items.forEach((item) => {
const { quantity, dimensions, weight } = item
let cubicWeight = 0
cartSubtotal += (quantity * ecomUtils.price(item))
// parse cart items to kangu schema
let kgWeight = 0
let cubicWeight = 0
if (weight && weight.value) {
switch (weight.unit) {
case 'g':
Expand All @@ -194,12 +190,15 @@ exports.post = ({ appSdk }, req, res) => {
kgWeight = weight.value
}
}
const cmDimensions = {}
const sumDimensions = {}
const cmDimensions = {
height: 5,
width: 10,
length: 10
}
if (dimensions) {
for (const side in dimensions) {
const dimension = dimensions[side]
if (dimension && dimension.value) {
if (dimension?.value) {
switch (dimension.unit) {
case 'm':
cmDimensions[side] = dimension.value * 100
Expand All @@ -210,34 +209,30 @@ exports.post = ({ appSdk }, req, res) => {
default:
cmDimensions[side] = dimension.value
}
// add/sum current side to final dimensions object
if (cmDimensions[side]) {
sumDimensions[side] = sumDimensions[side]
? sumDimensions[side] + cmDimensions[side]
: cmDimensions[side]
}
}
}
for (const side in sumDimensions) {
if (sumDimensions[side]) {
cubicWeight = cubicWeight > 0
? cubicWeight * sumDimensions[side]
: sumDimensions[side]
let m3 = 1
for (const side in cmDimensions) {
if (cmDimensions[side]) {
m3 *= (cmDimensions[side] / 100)
}
}
if (cubicWeight > 0) {
cubicWeight /= 6000
finalCubicWeight += (quantity * cubicWeight)
if (m3 > 1) {
// 167 kg/m³
cubicWeight = m3 * 167
}
}
if (kgWeight > 0) {
finalWeight += (quantity * (cubicWeight < 0.5 || kgWeight > cubicWeight ? kgWeight : cubicWeight))
const unitFinalWeight = cubicWeight < 0.5 || kgWeight > cubicWeight
? kgWeight
: cubicWeight
pkgWeight += (quantity * unitFinalWeight)
}
produtos.push({
peso: kgWeight || 0.5,
altura: cmDimensions.height || 5,
largura: cmDimensions.width || 10,
comprimento: cmDimensions.length || 10,
altura: cmDimensions.height,
largura: cmDimensions.width,
comprimento: cmDimensions.length,
valor: ecomUtils.price(item),
quantidade: quantity
})
Expand All @@ -253,21 +248,18 @@ exports.post = ({ appSdk }, req, res) => {
'R',
'M'
],
ordernar,
produtos
ordernar
}

if (appData.use_kubic_weight) {
const num = Math.cbrt(finalCubicWeight)
const cubicDimension = Math.round(num * 100) / 100
delete body.produtos
if (appData.use_kubic_weight || appData.use_cubic_weight) {
body.volumes = [{
peso: finalWeight || 0.5,
altura: cubicDimension || 10,
largura: cubicDimension || 10,
comprimento: cubicDimension || 10,
peso: pkgWeight || 0.5,
altura: 4,
largura: 16,
comprimento: 24,
valor: cartSubtotal
}]
} else {
body.produtos = produtos
}

// send POST request to kangu REST API
Expand Down Expand Up @@ -355,7 +347,7 @@ exports.post = ({ appSdk }, req, res) => {
},
package: {
weight: {
value: finalWeight,
value: pkgWeight,
unit: 'kg'
}
},
Expand Down
12 changes: 10 additions & 2 deletions functions/routes/ecom/webhook.js
Original file line number Diff line number Diff line change
Expand Up @@ -64,9 +64,17 @@ exports.post = ({ appSdk }, req, res) => {
return
}
logger.info(`Shipping tag for #${storeId} ${orderId}`)
return createTag(order, kanguToken, storeId, appData, appSdk)
return createTag({
order,
shippingLine,
kanguToken,
storeId,
appData,
appSdk
})
.then(data => {
const trackingCode = data?.[0]?.codigo?.replaceAll(' ', '')
const trackingCode = data?.codigo?.replaceAll(' ', '') ||
data?.[0]?.codigo?.replaceAll(' ', '')
if (!trackingCode) {
logger.warn(`Unexpected create tag response for ${orderId}`, { data })
return
Expand Down

0 comments on commit be2e1c8

Please sign in to comment.