Skip to content

Commit 84358fe

Browse files
authored
Merge pull request #9 from purwadhikafullstack/development
Development
2 parents 574c7d6 + bf09ab7 commit 84358fe

File tree

266 files changed

+5640
-4501
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

266 files changed

+5640
-4501
lines changed

apps/api/package.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
"bcrypt": "^5.1.1",
2222
"cors": "^2.8.5",
2323
"cross-env": "^7.0.3",
24+
"date-fns": "^3.6.0",
2425
"dotenv": "^16.4.5",
2526
"express": "^4.18.2",
2627
"googleapis": "^140.0.0",
@@ -38,6 +39,7 @@
3839
"devDependencies": {
3940
"@types/bcrypt": "^5.0.2",
4041
"@types/cors": "^2.8.17",
42+
"@types/date-fns": "^2.6.0",
4143
"@types/express": "^4.17.21",
4244
"@types/haversine": "^1.1.8",
4345
"@types/jsonwebtoken": "^9.0.6",
@@ -53,4 +55,4 @@
5355
"prisma": {
5456
"seed": "ts-node --compiler-options {\"module\":\"CommonJS\"} prisma/seed.ts"
5557
}
56-
}
58+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
/*
2+
Warnings:
3+
4+
- You are about to drop the column `updated_by` on the `stock_histories` table. All the data in the column will be lost.
5+
- You are about to drop the column `updated_date` on the `stock_histories` table. All the data in the column will be lost.
6+
7+
*/
8+
-- DropForeignKey
9+
ALTER TABLE `stock_histories` DROP FOREIGN KEY `stock_histories_updated_by_fkey`;
10+
11+
-- AlterTable
12+
ALTER TABLE `stock_histories` DROP COLUMN `updated_by`,
13+
DROP COLUMN `updated_date`;
14+
15+
-- AlterTable
16+
ALTER TABLE `stores` ADD COLUMN `is_default` BOOLEAN NOT NULL DEFAULT false;

apps/api/prisma/schema.prisma

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,6 @@ model User {
8181
updatedProducts Product[] @relation("UpdatedProducts")
8282
userAddress UserAddress[]
8383
createdStockHistories StockHistory[] @relation("CreatedStockHistories")
84-
updatedStockHistories StockHistory[] @relation("UpdatedStockHistories")
8584
carts Cart[]
8685
orders Order[]
8786
accounts Account[]
@@ -124,6 +123,7 @@ model Store {
124123
postalCode String? @map(name: "postal_code")
125124
longitude Float?
126125
latitude Float?
126+
isDefault Boolean @default(false) @map(name: "is_default")
127127
createdDate DateTime @default(now()) @map(name: "created_date")
128128
updatedDate DateTime @updatedAt @map(name: "updated_date")
129129
stocks Stock[]
@@ -212,9 +212,6 @@ model StockHistory {
212212
createdByUser User? @relation("CreatedStockHistories", fields: [createdBy], references: [id])
213213
createdBy String? @map(name: "created_by")
214214
createdDate DateTime @default(now()) @map(name: "created_date")
215-
updatedByUser User? @relation("UpdatedStockHistories", fields: [updatedBy], references: [id])
216-
updatedBy String? @map(name: "updated_by")
217-
updatedDate DateTime @updatedAt @map(name: "updated_date")
218215
219216
@@map(name: "stock_histories")
220217
}

apps/api/src/actions/auth.action.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import { API_KEY } from '../config';
1313
import { sign } from 'jsonwebtoken';
1414
import { createCartQuery, getCartByUserIDQuery } from '@/queries/cart.query';
1515
import { getStoresQuery } from '@/queries/store.query';
16-
import { getNearestStores } from '@/utils/store.util';
16+
import { getNearestStore } from '@/utils/store.util';
1717

1818
const registerAction = async (data: RegisterAuth): Promise<User> => {
1919
try {
@@ -49,7 +49,7 @@ const loginAction = async (data: Auth) => {
4949

5050
if (!cart?.id) {
5151
const { stores } = await getStoresQuery({});
52-
const store = getNearestStores({ stores, userLocation });
52+
const store = getNearestStore({ stores, userLocation });
5353

5454
await createCartQuery({
5555
userId: user.id,

apps/api/src/actions/discount.action.ts

Lines changed: 25 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,10 @@ import {
88
createDiscountQuery,
99
getDiscountByIDQuery,
1010
getDiscountByProductIdAndStoreIdQuery,
11-
getDiscountQuery,
11+
getDiscountsQuery,
1212
getDiscountsByStoreIDQuery,
1313
updateDiscountQuery,
14+
deleteDiscountQuery,
1415
} from '@/queries/discount.query';
1516
import { Discount } from '@prisma/client';
1617

@@ -25,11 +26,11 @@ const createDiscountAction = async (
2526
}
2627
};
2728

28-
const getDiscountAction = async (
29+
const getDiscountsAction = async (
2930
filters: IFilterDiscount,
3031
): Promise<IResultDiscount> => {
3132
try {
32-
const data = await getDiscountQuery(filters);
33+
const data = await getDiscountsQuery(filters);
3334
return data;
3435
} catch (err) {
3536
throw err;
@@ -62,11 +63,18 @@ const getDiscountByIDAction = async (id: string): Promise<Discount | null> => {
6263
}
6364
};
6465

65-
const getDiscountByProductIdAndStoreIdAction = async (productId: string, storeId: string): Promise<Discount | null> => {
66+
const getDiscountByProductIdAndStoreIdAction = async (
67+
productId: string,
68+
storeId: string,
69+
): Promise<Discount | null> => {
6670
try {
67-
if (!productId || !storeId) throw new Error("Please fill product ID and store ID");
71+
if (!productId || !storeId)
72+
throw new Error('Please fill product ID and store ID');
6873

69-
const discount = await getDiscountByProductIdAndStoreIdQuery(productId, storeId);
74+
const discount = await getDiscountByProductIdAndStoreIdQuery(
75+
productId,
76+
storeId,
77+
);
7078
if (!discount) throw new HttpException(404, 'Data not found');
7179

7280
return discount;
@@ -87,11 +95,21 @@ const updateDiscountAction = async (
8795
}
8896
};
8997

98+
const deleteDiscountAction = async (id: string): Promise<Discount> => {
99+
try {
100+
const discount = await deleteDiscountQuery(id);
101+
return discount;
102+
} catch (err) {
103+
throw err;
104+
}
105+
};
106+
90107
export {
108+
deleteDiscountAction,
91109
updateDiscountAction,
92110
getDiscountByIDAction,
93111
createDiscountAction,
94-
getDiscountAction,
112+
getDiscountsAction,
95113
getDiscountsByStoreIDAction,
96114
getDiscountByProductIdAndStoreIdAction,
97115
};

apps/api/src/actions/order.action.ts

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@ import {
55
IResultOrder,
66
} from '@/interfaces/order.interface';
77
import {
8-
confirmShippingOrderQuery,
8+
cancelUnconfirmedOrdersQuery,
9+
confirmShippingOrdersQuery,
910
createOrderQuery,
1011
getOrderByIDQuery,
1112
getOrdersQuery,
@@ -43,17 +44,27 @@ const createOrderAction = async (data: IOrder): Promise<Order | null> => {
4344
}
4445
};
4546

46-
const confirmShippingOrderAction = async () => {
47+
const confirmShippingOrdersAction = async () => {
4748
try {
48-
const orders = await confirmShippingOrderQuery();
49+
const orders = await confirmShippingOrdersQuery();
50+
return orders;
51+
} catch (err) {
52+
throw err;
53+
}
54+
};
55+
56+
const cancelUnconfirmedOrdersAction = async () => {
57+
try {
58+
const orders = await cancelUnconfirmedOrdersQuery();
4959
return orders;
5060
} catch (err) {
5161
throw err;
5262
}
5363
};
5464

5565
export {
56-
confirmShippingOrderAction,
66+
confirmShippingOrdersAction,
67+
cancelUnconfirmedOrdersAction,
5768
getOrdersAction,
5869
getOrderByIDAction,
5970
createOrderAction,

apps/api/src/actions/payment.action.ts

Lines changed: 73 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import path from 'path';
1010
import fs from 'fs';
1111
import * as handlebars from 'handlebars';
1212
import { transporter } from '../helpers/nodemailer';
13+
import { ORDER_STATUS } from '@/constants/order.constant';
1314

1415
const prisma = new PrismaClient();
1516

@@ -36,7 +37,7 @@ const createPaymentAction = async (orderId: string) => {
3637
'paymentReminder.hbs',
3738
);
3839

39-
const url = `http://localhost:3000/users/orders/confirmation/${order.id}`;
40+
const url = `${process.env.FRONTEND_URL}/users/orders/confirmation/${order.id}`;
4041

4142
const templateSource = fs.readFileSync(templatePath, 'utf-8');
4243

@@ -77,6 +78,77 @@ const updatePaymentStatusAction = async (
7778
): Promise<Order> => {
7879
try {
7980
const order = await updatePaymentStatusQuery(orderId, orderStatus);
81+
if (
82+
order.paymentMethod === 'BANK' &&
83+
orderStatus === ORDER_STATUS.menungguPembayaran
84+
) {
85+
try {
86+
const user = await prisma.user.findUnique({
87+
where: {
88+
id: order.userId,
89+
},
90+
});
91+
92+
const templatePath = path.join(
93+
__dirname,
94+
'../templates',
95+
'paymentFailed.hbs',
96+
);
97+
98+
const templateSource = fs.readFileSync(templatePath, 'utf-8');
99+
100+
const compiledTemplate = handlebars.compile(templateSource);
101+
102+
const html = compiledTemplate({
103+
email: user?.email,
104+
});
105+
106+
await transporter.sendMail({
107+
from: 'sender address',
108+
to: user?.email || '',
109+
subject: 'Payment Failed',
110+
html,
111+
});
112+
} catch (err) {
113+
throw err;
114+
}
115+
}
116+
117+
if (
118+
order.paymentMethod === 'BANK' &&
119+
orderStatus === ORDER_STATUS.diproses
120+
) {
121+
try {
122+
const user = await prisma.user.findUnique({
123+
where: {
124+
id: order.userId,
125+
},
126+
});
127+
128+
const templatePath = path.join(
129+
__dirname,
130+
'../templates',
131+
'paymentSuccess.hbs',
132+
);
133+
134+
const templateSource = fs.readFileSync(templatePath, 'utf-8');
135+
136+
const compiledTemplate = handlebars.compile(templateSource);
137+
138+
const html = compiledTemplate({
139+
email: user?.email,
140+
});
141+
142+
await transporter.sendMail({
143+
from: 'sender address',
144+
to: user?.email || '',
145+
subject: 'Payment Success',
146+
html,
147+
});
148+
} catch (err) {
149+
throw err;
150+
}
151+
}
80152
return order;
81153
} catch (err) {
82154
throw err;

apps/api/src/actions/product.action.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import {
44
createProductQuery,
55
deleteProductImageQuery,
66
deleteProductQuery,
7+
getAvailableProductsByStoreIDQuery,
78
getProductByIDQuery,
89
getProductBySlugOrNameQuery,
910
getProductsQuery,
@@ -28,6 +29,16 @@ const getProductsAction = async (
2829
}
2930
};
3031

32+
const getAvailableProductsByStoreIDAction = async (
33+
filters: IFilterProduct,
34+
): Promise<IResultProduct> => {
35+
try {
36+
const products = await getAvailableProductsByStoreIDQuery(filters);
37+
return products;
38+
} catch (err) {
39+
throw err;
40+
}
41+
};
3142
const getProductByIDAction = async (id: string): Promise<Product | null> => {
3243
try {
3344
const product = await getProductByIDQuery(id);
@@ -120,4 +131,5 @@ export {
120131
getProductBySlugAction,
121132
createProductImageAction,
122133
deleteProductImageAction,
134+
getAvailableProductsByStoreIDAction,
123135
};

apps/api/src/actions/report.action.ts

Lines changed: 45 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,12 @@ import {
22
getSalesReportPerCategoryQuery,
33
getSalesReportPerMonthQuery,
44
getSalesReportPerProductQuery,
5+
getSalesReportTotalCategoryQuery,
6+
getSalesReportTotalProductQuery,
7+
getStockReportDetailQuery,
8+
getStockReportPerMonthQuery,
59
} from '@/queries/report.query';
6-
import { IFilterReport } from '@/interfaces/report.interface';
10+
import { IFilterReport, IFilterReportTable } from '@/interfaces/report.interface';
711

812
const getSalesReportPerMonthAction = async (filters: IFilterReport) => {
913
try {
@@ -32,8 +36,48 @@ const getSalesReportPerCategoryAction = async (filters: IFilterReport) => {
3236
}
3337
};
3438

39+
const getSalesReportTotalProductAction = async (filters: IFilterReport) => {
40+
try {
41+
const data = await getSalesReportTotalProductQuery(filters);
42+
return data;
43+
} catch (err) {
44+
throw err;
45+
}
46+
};
47+
48+
const getSalesReportTotalCategoryAction = async (filters: IFilterReport) => {
49+
try {
50+
const data = await getSalesReportTotalCategoryQuery(filters);
51+
return data;
52+
} catch (err) {
53+
throw err;
54+
}
55+
};
56+
57+
const getStockReportPerMonthAction = async (filters: IFilterReport) => {
58+
try {
59+
const data = await getStockReportPerMonthQuery(filters);
60+
return data;
61+
} catch (err) {
62+
throw err;
63+
}
64+
};
65+
66+
const getStockReportDetailAction = async (filters: IFilterReportTable) => {
67+
try {
68+
const data = await getStockReportDetailQuery(filters);
69+
return data;
70+
} catch (err) {
71+
throw err;
72+
}
73+
};
74+
3575
export {
3676
getSalesReportPerMonthAction,
3777
getSalesReportPerProductAction,
3878
getSalesReportPerCategoryAction,
79+
getSalesReportTotalProductAction,
80+
getSalesReportTotalCategoryAction,
81+
getStockReportPerMonthAction,
82+
getStockReportDetailAction,
3983
};

0 commit comments

Comments
 (0)