Need UI to set shipping-from address

main
Ashelyn Dawn 3 years ago
parent c5ae39fd62
commit ba2d2a6cea

@ -205,16 +205,29 @@ router.post('/:uuid/ship/delivery', ensureAdmin, parseJSON, async (req, res) =>
})
router.post('/:uuid/ship/easypost', ensureAdmin, parseJSON, async (req, res) => {
const order = await db.order.shipEasyPost(
const order = await db.order.findByUUID(req.params.uuid)
let itemsByUUID = {}
for(const transaction of order.transactions)
for(const item of transaction.cart.items)
if(itemsByUUID[item.uuid])
itemsByUUID[item.uuid].count += item.count
else
itemsByUUID[item.uuid] = item
const items = Object.values(itemsByUUID)
const updatedOrder = await db.order.shipEasyPost(
req.params.uuid,
req.body.length,
req.body.width,
req.body.height,
req.body.weight
req.body.weight,
items
)
const user = await db.order.getUser(order.uuid)
await email.sendShippingNotification(user, order)
res.json(order)
res.json(updatedOrder)
})

@ -21,7 +21,11 @@ module.exports = [{
'urlslug',
'price_cents',
'published',
'number_in_stock'
'number_in_stock',
'hs_tariff_number',
'customs_description',
'customs_origin_country',
'weight_oz'
],
collections: [
{name: 'images', mapId: 'imageMap', columnPrefix: 'image_'}

@ -45,7 +45,8 @@ module.exports = [{
'zip',
'country',
'phone',
'easypost_id'
'easypost_id',
'verified'
]
},{
mapId: 'couponMap',

@ -10,20 +10,19 @@ const address = module.exports = {}
address.create = async (name, street1, street2, city, state, zip, country) => {
const epAddress = new easypost.Address({
name, street1, street2, city, state, zip,
name, street1, street2, city, state, zip, country,
verify: ['delivery']
})
await epAddress.save()
const {success} = epAddress.verifications.delivery
if (!success) {
// TODO: Send back an error?
if (!success)
console.error(`Could not verify address: ${epAddress.id}`)
}
const query = {
text: 'select * from sos.create_address($1, $2, $3, $4, $5, $6, $7, $8, $9, $10)',
text: 'select * from sos.create_address($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11)',
values: [
epAddress.name,
epAddress.company,
@ -34,7 +33,8 @@ address.create = async (name, street1, street2, city, state, zip, country) => {
epAddress.zip,
epAddress.country,
epAddress.phone,
epAddress.id
epAddress.id,
!!success
]
}

@ -294,7 +294,7 @@ order.setDelivery = (uuid, description, deliveryDate) =>
single: true
})
order.shipEasyPost = async ( uuid, length, width, height, weight ) => {
order.shipEasyPost = async ( uuid, length, width, height, weight, items ) => {
// Retrieve address
const {address} = await order.findByUUID(uuid)
const {shipping_from} = await config.getLatestConfig()
@ -302,20 +302,53 @@ order.shipEasyPost = async ( uuid, length, width, height, weight ) => {
if(!shipping_from?.easypost_id)
throw new Error("Cannot ship - no from address set in config")
// Create shipment
const epShipment = new easypost.Shipment({
to_address: address.easypost_id,
from_address: shipping_from.easypost_id,
parcel: {length, width, height, weight}
})
// Save shipment
await epShipment.save()
if(!shipping_from?.phone)
throw new Error("Cannot ship - Selected from address has no phone")
let purchasedShipment;
try {
// Create shipment
const epShipment = new easypost.Shipment({
to_address: address.easypost_id,
from_address: shipping_from.easypost_id,
parcel: {length, width, height, weight}
})
if(address.country !== 'US') {
const customsInfo = new easypost.CustomsInfo({
eel_pfc: 'NOEEI 30.37(a)',
contents_type: 'merchandise',
contents_explanation: 'Goods purchased from societyofsocks.us',
customs_certify: true,
customs_signer: 'Kirk Hamilton',
restriction_type: 'none',
customs_items: items.map(({item, count}) => ({
description: item.customs_description,
quantity: count,
value: (item.price_cents * count / 100).toFixed(2),
weight: item.weight_oz * count,
hs_tariff_number: item.hs_tariff_number,
origin_countr: item.customs_origin_country
}))
})
await customsInfo.save()
epShipment.customs_info = customsInfo;
}
// Save shipment
await epShipment.save()
// Purchase shipment (lowest USPS rate)
const {tracking_code, id: easypost_id, selected_rate: {rate: price_string}}
= await epShipment.buy(epShipment.lowestRate(['USPS']))
purchasedShipment = await epShipment.buy(epShipment.lowestRate(['USPS']))
} catch (err) {
console.log(err)
throw new Error("Cannot purchase shipment - see log for details")
}
const {tracking_code, id: easypost_id, selected_rate: {rate: price_string}} = purchasedShipment
const price_cents = Math.floor(parseFloat(price_string) * 100)
// Save tracking code and easypost id

@ -49,6 +49,10 @@ create table sos."item" (
item_description text not null,
item_urlslug citext unique not null,
item_price_cents integer not null,
item_hs_tariff_number text not null,
item_customs_description text not null,
item_customs_origin_country text not null,
item_weight_oz integer not null,
item_published boolean not null default true
);
@ -104,7 +108,8 @@ create table sos."address" (
address_zip text not null,
address_country text not null,
address_phone text,
address_easypost_id text
address_easypost_id text,
address_verified boolean default false
);
create table sos."delivery" (

@ -21,7 +21,7 @@ create or replace function sos.change_password(_user_uuid uuid, _new_hash text)
language plpgsql
as $function$
begin
update sos."user"
update sos."user"
set (
user_password_hash,
user_time_password_changed
@ -657,7 +657,7 @@ begin
where order_uuid = _order_uuid;
end; $function$;
create or replace function sos.create_address(_name text, _company text, _street1 text, _street2 text, _city text, _state text, _zip text, _country text, _phone text, _easypost_id text)
create or replace function sos.create_address(_name text, _company text, _street1 text, _street2 text, _city text, _state text, _zip text, _country text, _phone text, _easypost_id text, _verified boolean)
returns setof sos."address"
language plpgsql
as $function$
@ -674,7 +674,8 @@ begin
address_zip,
address_country,
address_phone,
address_easypost_id
address_easypost_id,
address_verified
) values (
_name,
_company,
@ -685,7 +686,8 @@ begin
_zip,
_country,
_phone,
_easypost_id
_easypost_id,
_verified
) returning address_uuid into _address_uuid;
return query select * from sos."address" where address_uuid = _address_uuid;

@ -22,6 +22,10 @@ export default function EasypostPackageEntry({uuid}){
<DecimalInput label="Weight (ounces)" name="weight" hint="Please enter (in ounces) the weight of the package" prefix="" numDecimals={2} validate={val => val > 0} />
<Button type="submit">Submit</Button>
</FormController>
<p className="warning" style={{maxWidth: 380, marginTop: 40}}>
<strong>Note:</strong> orders with a total value of $2500 or more should not be shipped with EasyPost.
</p>
</>
)
}

@ -25,6 +25,7 @@ export default function InputAddress({address}){
<Input initialValue={address?.city} label="City" name="city" validate={value=>value.length > 0}/>
<Input initialValue={address?.state} label="State / Province" name="state" validate={value=>value.length > 0}/>
<Input initialValue={address?.zip} label="Postal Code" name="zip" validate={value=>value.length > 0}/>
<Input initialValue={address?.country} label="Country" name="country" validate={value=>value.length > 0}/>
<Button type="submit">Save Address</Button>
</FormController>
</>

@ -100,14 +100,25 @@ export default function CheckoutSummary({order: _order, addresses}){
{
order.address
? (
<div>
<p style={{marginTop: 0, fontWeight: 'bold'}}>Shipping To:</p>
<p style={{margin: 0}}>{order.address.name}</p>
<p style={{margin: 0}}>{order.address.street1}</p>
<p style={{margin: 0}}>{order.address.street2}</p>
<p style={{margin: 0}}>{order.address.city}, {order.address.state}, {order.address.zip}</p>
<p style={{marginBottom: '-20px'}}><Link href="/store/checkout/address"><a>(Edit Address)</a></Link></p>
</div>
<>
<div>
<p style={{marginTop: 0, fontWeight: 'bold'}}>Shipping To:</p>
<p style={{margin: 0}}>{order.address.name}</p>
<p style={{margin: 0}}>{order.address.street1}</p>
<p style={{margin: 0}}>{order.address.street2}</p>
<p style={{margin: 0}}>
{order.address.city}, {order.address.state}, {order.address.zip}
{order.address.country !== 'US' && `, ${order.address.country}`}
</p>
<p style={{marginBottom: '-20px'}}><Link href="/store/checkout/address"><a>(Edit Address)</a></Link></p>
</div>
{!order.address.verified && (
<p className="warning">
Your address could not be automatically verified. Please
double check it for accuracy before continuing checkout.
</p>
)}
</>
)
: (
<>

@ -52,13 +52,13 @@ main > p, main > section, main > h3, main > h4, main > h5, main > h6 {
margin-right: auto;
}
main > p.warning {
main p.warning {
padding: 8px;
border: solid 1px var(--error-color);
background: #ff74743d;
}
main > p.warning button.buttonLink {
main p.warning button.buttonLink {
color: red;
}

Loading…
Cancel
Save