Skip to content

Commit

Permalink
feat(ghn): add ghn command
Browse files Browse the repository at this point in the history
  • Loading branch information
lamngockhuong committed Dec 19, 2023
1 parent b2096c9 commit 20b7e9f
Show file tree
Hide file tree
Showing 12 changed files with 424 additions and 70 deletions.
9 changes: 9 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
root = true

[*]
indent_style = space
indent_size = 2
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true
quote_type = single
1 change: 1 addition & 0 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ DEBUG_MODE=true
PORT=3000
VNPOST_TOKEN=xxx
GHTK_TOKEN=xxx
GHN_TOKEN=xxx
KIOTVIET_CLIENT_ID=xxx
KIOTVIET_SECRET=xxx
KIOTVIET_RETAILER=xxx
Expand Down
8 changes: 5 additions & 3 deletions src/commands/cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,11 @@

import 'dotenv/config';
import { Command } from 'commander';
import { ghtkCommand } from './ghtk.command';
import { kiotvietCommand } from './kiotviet.command';
import { vnpostCommand } from './vnpost.command';
import { ghtkCommand } from './ghtk/ghtk.command';
import { kiotvietCommand } from './kiotviet/kiotviet.command';
import { vnpostCommand } from './vnpost/vnpost.command';
import { settingCommand } from './setting.command';
import { ghnCommand } from './ghn/ghn.command';

if (process.env.NODE_ENV === 'production')
console.debug = () => {};
Expand All @@ -30,6 +31,7 @@ program
program.addCommand(settingCommand());
program.addCommand(ghtkCommand());
program.addCommand(vnpostCommand());
program.addCommand(ghnCommand());
program.addCommand(kiotvietCommand());
program.showHelpAfterError('(add --help for additional information)');
program.showSuggestionAfterError();
Expand Down
64 changes: 64 additions & 0 deletions src/commands/ghn/ghn.command.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import { Command } from 'commander';
import { setEnvValue } from '../../util/env.util';
import { UTC_TIME_FORMAT } from '../../config/constant';
import { info, log } from '../../util/console';
import { getGHNOrder, showOrders } from '../../services/ghn.service';

export const ghnCommand = (): Command => {
const ghn = new Command('ghn').description('manage order, get information,...');

ghn
.command('token')
.description('Set GHN token')
.option('-s, --set <token>', 'Save access token into .env')
.action(async (options) => {
try {
if (options.set) {
setEnvValue('GHN_TOKEN', options.set);
}
} catch (error) {
console.error(error.message);
}
});

ghn
.command('get')
.description('get order information')
.option('-c, --code <value>', 'order code')
.option('-d, --date <yyyy-MM-dd>', 'created date')
.option('-f, --from <yyyy-MM-dd>', 'from date')
.option('-t, --to <yyyy-MM-dd>', 'to date')
.action(async (options) => {
if (options.code) {
const order = await getGHNOrder(options.code);

if (order) {
info(order);
} else {
info(`❌ Can not find order with code: ${options.code}`);
}
}

if (options.date || options.from || options.to) {
const { date, from, to } = options;
let fromPurchaseDate;
let toPurchaseDate;
if (date) {
fromPurchaseDate = toPurchaseDate = new Date(
`${date}${UTC_TIME_FORMAT}`
);
} else {
fromPurchaseDate = from
? new Date(`${from}${UTC_TIME_FORMAT}`)
: new Date();
toPurchaseDate = to
? new Date(`${to}${UTC_TIME_FORMAT}`)
: new Date();
}
log(`From: ${fromPurchaseDate}, to: ${toPurchaseDate}`);
await showOrders(fromPurchaseDate, toPurchaseDate);
}
});

return ghn;
};
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Command } from 'commander';
import { setEnvValue } from '../util/env.util';
import { getGHTKOrder } from '../services/ghtk.service';
import { info } from '../util/console';
import { setEnvValue } from '../../util/env.util';
import { getGHTKOrder } from '../../services/ghtk.service';
import { info } from '../../util/console';

export const ghtkCommand = (): Command => {
const ghtk = new Command('ghtk').description('manage order, get information,...');
Expand All @@ -13,7 +13,7 @@ export const ghtkCommand = (): Command => {
.action(async (options) => {
try {
if (options.set) {
setEnvValue('GHTK_TOKEN111', options.set);
setEnvValue('GHTK_TOKEN', options.set);
}
} catch (error) {
console.error(error.message);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { Command, Option } from 'commander';
import { listBranchesCommand } from './kiotviet/branches.command';
import { createCustomersCommand } from './kiotviet/customers.command';
import { getInvoiceCommand, syncInvoiceCommand } from './kiotviet/invoices.command';
import { tokenCommand } from './kiotviet/token.command';
import { listBranchesCommand } from './branches.command';
import { createCustomersCommand } from './customers.command';
import { getInvoiceCommand, syncInvoiceCommand } from './invoices.command';
import { tokenCommand } from './token.command';

export const kiotvietCommand = (): Command => {
const kiotviet = new Command('kiotviet').description('manage, sync invoice, order,...');
Expand All @@ -28,7 +28,7 @@ export const kiotvietCommand = (): Command => {

customers
.command('create')
.description('create kiotviet customers from ghtk, vnpost order')
.description('create kiotviet customers from ghtk, ghn vnpost order')
.option('-d, --date <yyyy-MM-dd>', 'Purchase Date')
.addOption(new Option('-f, --from <yyyy-MM-dd>', 'From Purchase Date').conflicts('date'))
.addOption(new Option('-t, --to <yyyy-MM-dd>', 'To Purchase Date').conflicts('date'))
Expand All @@ -48,7 +48,7 @@ export const kiotvietCommand = (): Command => {

invoices
.command('sync')
.description('sync kiotviet invoice with ghtk, vnpost order')
.description('sync kiotviet invoice with ghtk, ghn, vnpost order')
.option('-c, --code <value>', 'Kiotviet invoice code')
.addOption(new Option('-d, --date <yyyy-MM-dd>', 'Purchase Date').conflicts('code'))
.addOption(new Option('-f, --from <yyyy-MM-dd>', 'From Purchase Date').conflicts('code').conflicts('date'))
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { Command } from 'commander';
import { setEnvValue } from '../util/env.util';
import { UTC_TIME_FORMAT } from '../config/constant';
import { getVNPostOrder, getVNPostOrderDetail, showOrders } from '../services/vnpost.service';
import { info, log } from '../util/console';
import { setEnvValue } from '../../util/env.util';
import { UTC_TIME_FORMAT } from '../../config/constant';
import { getVNPostOrder, getVNPostOrderDetail, showOrders } from '../../services/vnpost.service';
import { info, log } from '../../util/console';

export const vnpostCommand = (): Command => {
const vnpost = new Command('vnpost').description('manage order, get information,...');
Expand Down
9 changes: 9 additions & 0 deletions src/config/ghn.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
export const ghn = {
baseShipUrl: 'https://online-gateway.ghn.vn/shiip/public-api',
baseOrderTrackingUrl:
'https://online-gateway.ghn.vn/order-tracking/public-api',
searchOrder: '/v2/shipping-order/search',
getOrder: '/v2/shipping-order/detail',
trackingLogs: '/client/tracking-logs',
token: process.env.GHN_TOKEN,
};
2 changes: 1 addition & 1 deletion src/dtos/order.dto.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
export class Order {
id: string;
statusCode: number;
statusCode?: number;
status: string;
fullName: string;
phone: string;
Expand Down
107 changes: 107 additions & 0 deletions src/services/ghn.service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
import { info } from '../util/console';
import { Order } from '../dtos/order.dto';
import { Order as GHNOrder, getOrder as getGHNOrder, getTrackingLogs, searchOrder } from '../util/ghn.util';

const showOrders = async (fromPurchaseDate: Date, toPurchaseDate: Date) => {
try {
const orders: Order[] = await getOrders(
fromPurchaseDate.toISOString(),
toPurchaseDate.toISOString()
);
info(
`🙌 Find ${
orders?.length
} GHN orders from ${fromPurchaseDate.toLocaleDateString()} to ${toPurchaseDate.toLocaleDateString()}!`
);

orders.forEach(async (order, index) => {
info(
`-------------------- 🔰 GHN Order #${index + 1}: ${
order.code
} 🔰 --------------------`
);
showOrder(order);
});

info(`(Total: ${orders?.length} orders)`);
} catch (error) {
console.error(error.message);
}
};

const showOrder = (order: Order) => {
info('• Order Id: ' + order.id);
info('• Order Code: ' + order.code);
info('• Order delivery status: ' + order.status);
info('• Order products: ' + order.products);
info('• Order delivery date: ' + order.doneAt);
};

const getOrders = async (
fromDate: string,
toDate: string
): Promise<Order[]> => {
return [];
// const data: OrderRequestDto = {
// ChildUserId: '',
// CreateTimeStart: fromDate,
// CreateTimeEnd: toDate,
// KeySearch: '',
// OrderByDescending: true,
// PageIndex: 0,
// PageSize: 1000,
// };

// const orders: VNPostListOrder = await searchOrder(data);

// return orders?.Items?.map((item: VNPostOrder) => {
// const order = {
// id: item.Id,
// statusCode: item.OrderStatusId,
// status: item.OrderStatusName,
// fullName: item.ReceiverFullname,
// phone: item.ReceiverTel,
// codAmount: item.CodAmount,
// feeShip: Number(item.TotalFreightIncludeVat),
// products: item.PackageContent.substring(
// 0,
// item.PackageContent.indexOf('TMĐT')
// ),
// code: item.OrderCode,
// createdAt: new Date(item.CreateTime),
// doneAt: new Date(item.DeliveryTime),
// };

// return order;
// });
};

const getOrder = async (orderCode: string): Promise<Order> => {
const order: GHNOrder = await getGHNOrder(orderCode);
if (order && !order.returnFee) {
const orderFromTrackingLogs = await getTrackingLogs(orderCode);

order.statusName = orderFromTrackingLogs?.statusName;
order.returnFee = orderFromTrackingLogs?.returnFee;
order.mainServiceFee = orderFromTrackingLogs?.mainServiceFee;
order.totalFee = orderFromTrackingLogs?.totalFee;
}

return {
id: order.id,
statusCode: undefined,
status: order.status,
fullName: order.toName,
phone: order.toPhone,
address: order.toAddress,
codAmount: order.codAmount,
feeShip: order.totalFee,
products: order.items.map((p) => p.name).join(','),
code: order.orderCode,
createdAt: order.orderDate,
doneAt: order.finishDate,
returnAt: order.returnTime,
} as Order;
};

export { getOrder as getGHNOrder, showOrders };
Loading

0 comments on commit 20b7e9f

Please sign in to comment.