summaryrefslogtreecommitdiff
path: root/src/lib/transaction
diff options
context:
space:
mode:
authorRafi Zadanly <zadanlyr@gmail.com>2023-02-21 12:04:20 +0700
committerRafi Zadanly <zadanlyr@gmail.com>2023-02-21 12:04:20 +0700
commitfdfb47c3a825258b871ac5921605642e5e05fdd8 (patch)
tree9d8ee50a5a28bd67fad7a5699aa88c415b6fc60c /src/lib/transaction
parentfa45f8bc91adef3bacd3460ef4e3b1151ee13e71 (diff)
fix
Diffstat (limited to 'src/lib/transaction')
-rw-r--r--src/lib/transaction/api/transactionApi.js10
-rw-r--r--src/lib/transaction/api/uploadPoApi.js10
-rw-r--r--src/lib/transaction/components/Transaction.jsx149
-rw-r--r--src/lib/transaction/components/Transactions.jsx32
-rw-r--r--src/lib/transaction/hooks/useTransaction.js13
-rw-r--r--src/lib/transaction/utils/transactions.js12
6 files changed, 209 insertions, 17 deletions
diff --git a/src/lib/transaction/api/transactionApi.js b/src/lib/transaction/api/transactionApi.js
new file mode 100644
index 00000000..7186f847
--- /dev/null
+++ b/src/lib/transaction/api/transactionApi.js
@@ -0,0 +1,10 @@
+import odooApi from "@/core/api/odooApi"
+import { getAuth } from "@/core/utils/auth"
+
+const transactionApi = async ({ id }) => {
+ const auth = getAuth()
+ const dataTransaction = await odooApi('GET', `/api/v1/partner/${auth.partnerId}/sale_order/${id}`)
+ return dataTransaction
+}
+
+export default transactionApi \ No newline at end of file
diff --git a/src/lib/transaction/api/uploadPoApi.js b/src/lib/transaction/api/uploadPoApi.js
new file mode 100644
index 00000000..00ad1d8d
--- /dev/null
+++ b/src/lib/transaction/api/uploadPoApi.js
@@ -0,0 +1,10 @@
+import odooApi from "@/core/api/odooApi"
+import { getAuth } from "@/core/utils/auth"
+
+const uploadPoApi = async ({ id, data }) => {
+ const auth = getAuth()
+ const dataUploadPo = await odooApi('POST', `/api/v1/partner/${auth.partnerId}/sale_order/${id}/upload_po`, data)
+ return dataUploadPo
+}
+
+export default uploadPoApi \ No newline at end of file
diff --git a/src/lib/transaction/components/Transaction.jsx b/src/lib/transaction/components/Transaction.jsx
new file mode 100644
index 00000000..c9bdf715
--- /dev/null
+++ b/src/lib/transaction/components/Transaction.jsx
@@ -0,0 +1,149 @@
+import Spinner from "@/core/components/elements/Spinner/Spinner"
+import useTransaction from "../hooks/useTransaction"
+import TransactionStatusBadge from "./TransactionStatusBadge"
+import Divider from "@/core/components/elements/Divider/Divider"
+import { useRef, useState } from "react"
+import { downloadPurchaseOrder } from "../utils/transactions"
+import BottomPopup from "@/core/components/elements/Popup/BottomPopup"
+import uploadPoApi from "../api/uploadPoApi"
+import { toast } from "react-hot-toast"
+import getFileBase64 from "@/core/utils/getFileBase64"
+import currencyFormat from "@/core/utils/currencyFormat"
+import VariantGroupCard from "@/lib/variant/components/VariantGroupCard"
+
+const Transaction = ({ id }) => {
+ const { transaction } = useTransaction({ id })
+
+ const poNumber = useRef('')
+ const poFile = useRef('')
+ const [ uploadPo, setUploadPo ] = useState(false)
+ const openUploadPo = () => setUploadPo(true)
+ const closeUploadPo = () => setUploadPo(false)
+ const submitUploadPo = async () => {
+ const file = poFile.current.files[0]
+ const name = poNumber.current.value
+ if (typeof file === 'undefined' || !name) {
+ toast.error('Nomor dan Dokumen PO harus diisi', { position: 'bottom-center' })
+ return
+ }
+ if (file.size > 5000000) {
+ toast.error('Maksimal ukuran file adalah 5MB', { position: 'bottom-center' })
+ return
+ }
+ const data = { name, file: await getFileBase64(file) }
+ const isUploaded = await uploadPoApi({ id, data })
+ if (isUploaded) {
+ toast.success('Berhasil upload PO')
+ transaction.refetch()
+ closeUploadPo()
+ return
+ }
+ toast.error('Terjadi kesalahan internal, coba lagi nanti atau hubungi kami')
+ }
+
+ return (
+ <>
+ { transaction.isLoading && (
+ <div className="flex justify-center my-4">
+ <Spinner className="w-6 text-gray_r-12/50 fill-gray_r-12" />
+ </div>
+ ) }
+
+ { transaction.data?.name && (
+ <>
+ <div className="flex flex-col gap-y-4 p-4">
+ <DescriptionRow label="Status Transaksi">
+ <div className="flex justify-end">
+ <TransactionStatusBadge status={transaction.data?.status} />
+ </div>
+ </DescriptionRow>
+ <DescriptionRow label="No Transaksi">
+ { transaction.data?.name }
+ </DescriptionRow>
+ <DescriptionRow label="Ketentuan Pembayaran">
+ { transaction.data?.paymentTerm }
+ </DescriptionRow>
+ <DescriptionRow label="Nama Sales">
+ { transaction.data?.sales }
+ </DescriptionRow>
+ <DescriptionRow label="Waktu Transaksi">
+ { transaction.data?.dateOrder }
+ </DescriptionRow>
+ </div>
+
+ <Divider />
+
+ <div className="p-4 flex flex-col gap-y-4">
+ <DescriptionRow label="Purchase Order">
+ { transaction.data?.purchaseOrderName || '-' }
+ </DescriptionRow>
+ <div className="flex items-center">
+ <p className="text-gray_r-11 leading-none">Dokumen PO</p>
+ <button
+ type="button"
+ className="btn-light py-1.5 px-3 ml-auto"
+ onClick={transaction.data?.purchaseOrderFile ? () => downloadPurchaseOrder(transaction.data) : openUploadPo}
+ >
+ { transaction.data?.purchaseOrderFile ? 'Download' : 'Upload' }
+ </button>
+ </div>
+ </div>
+
+ <Divider />
+
+ <div className="font-medium p-4">Detail Produk</div>
+
+ <div className="p-4 pt-0 flex flex-col gap-y-3">
+ <VariantGroupCard
+ variants={transaction.data?.products}
+ buyMore
+ />
+ <div className="flex justify-between mt-3 font-medium">
+ <p>Total Belanja</p>
+ <p>{ currencyFormat(transaction.data?.amountTotal) }</p>
+ </div>
+ </div>
+
+ <Divider />
+
+ <BottomPopup
+ title="Upload PO"
+ close={closeUploadPo}
+ active={uploadPo}
+ >
+ <div>
+ <label>Nomor PO</label>
+ <input type="text" className="form-input mt-3" ref={poNumber} />
+ </div>
+ <div className="mt-4">
+ <label>Dokumen PO</label>
+ <input type="file" className="form-input mt-3 py-2" ref={poFile} />
+ </div>
+ <div className="grid grid-cols-2 gap-x-3 mt-6">
+ <button
+ type="button"
+ className="btn-light w-full"
+ onClick={closeUploadPo}
+ >Batal</button>
+ <button
+ type="button"
+ className="btn-solid-red w-full"
+ onClick={submitUploadPo}
+ >Upload</button>
+ </div>
+ </BottomPopup>
+ </>
+ )}
+
+ </>
+ )
+}
+
+const DescriptionRow = ({ children, label }) => (
+ <div className="grid grid-cols-2">
+ <span className="text-gray_r-11">{ label }</span>
+ <span className="text-right">{ children }</span>
+ </div>
+)
+
+export default Transaction \ No newline at end of file
diff --git a/src/lib/transaction/components/Transactions.jsx b/src/lib/transaction/components/Transactions.jsx
index 5eb1d947..246a4a2c 100644
--- a/src/lib/transaction/components/Transactions.jsx
+++ b/src/lib/transaction/components/Transactions.jsx
@@ -14,6 +14,7 @@ import BottomPopup from "@/core/components/elements/Popup/BottomPopup"
import Pagination from "@/core/components/elements/Pagination/Pagination"
import { toQuery } from "lodash-contrib"
import _ from "lodash"
+import Alert from "@/core/components/elements/Alert/Alert"
const Transactions = () => {
const router = useRouter()
@@ -29,24 +30,22 @@ const Transactions = () => {
offset: (page - 1) * limit,
limit
}
-
- const [ inputQuery, setInputQuery ] = useState(q)
-
const { transactions } = useTransactions({ query })
+ const [ inputQuery, setInputQuery ] = useState(q)
const [ toOthers, setToOthers ] = useState(null)
- const [ toDelete, setToDelete ] = useState(null)
+ const [ toCancel, setToCancel ] = useState(null)
const submitCancelTransaction = async () => {
const isCancelled = await cancelTransactionApi({
partnerId: auth.partnerId,
- transaction: toDelete
+ transaction: toCancel
})
if (isCancelled) {
toast.success('Berhasil batalkan transaksi')
transactions.refetch()
}
- setToDelete(null)
+ setToCancel(null)
}
const pageCount = Math.ceil(transactions?.data?.saleOrderTotal / limit)
@@ -82,6 +81,13 @@ const Transactions = () => {
<Spinner className="w-6 text-gray_r-12/50 fill-gray_r-12" />
</div>
) }
+
+ { !transactions.isLoading && transactions.data?.saleOrders?.length === 0 && (
+ <Alert type="info" className="text-center">
+ Tidak ada data transaksi
+ </Alert>
+ ) }
+
{ transactions.data?.saleOrders?.map((saleOrder, index) => (
<div className="p-4 shadow border border-gray_r-3 rounded-md" key={index}>
<div className="grid grid-cols-2">
@@ -132,21 +138,21 @@ const Transactions = () => {
<button
className="text-left disabled:opacity-60"
disabled={!toOthers?.purchaseOrderFile}
- onClick={() => { downloadPurchaseOrder(auth.partnerId, toOthers); setToOthers(null) }}
+ onClick={() => { downloadPurchaseOrder(toOthers); setToOthers(null) }}
>
Download PO
</button>
<button
className="text-left disabled:opacity-60"
disabled={toOthers?.status != 'draft'}
- onClick={() => { downloadQuotation(auth.partnerId, toOthers); setToOthers(null) }}
+ onClick={() => { downloadQuotation(toOthers); setToOthers(null) }}
>
Download Quotation
</button>
<button
className="text-left disabled:opacity-60"
disabled={ toOthers?.status != 'waiting' }
- onClick={() => { setToDelete(toOthers); setToOthers(null) }}
+ onClick={() => { setToCancel(toOthers); setToOthers(null) }}
>
Batalkan Transaksi
</button>
@@ -154,12 +160,12 @@ const Transactions = () => {
</BottomPopup>
<BottomPopup
- active={toDelete}
- close={() => setToDelete(null)}
+ active={toCancel}
+ close={() => setToCancel(null)}
title="Batalkan Transaksi"
>
<div className="leading-7 text-gray_r-12/80">
- Apakah anda yakin membatalkan transaksi <span className="underline">{toDelete?.name}</span>?
+ Apakah anda yakin membatalkan transaksi <span className="underline">{toCancel?.name}</span>?
</div>
<div className="flex mt-6 gap-x-4">
<button
@@ -172,7 +178,7 @@ const Transactions = () => {
<button
className="btn-light flex-1"
type="button"
- onClick={() => setToDelete(null)}
+ onClick={() => setToCancel(null)}
>
Batal
</button>
diff --git a/src/lib/transaction/hooks/useTransaction.js b/src/lib/transaction/hooks/useTransaction.js
new file mode 100644
index 00000000..f2b493ee
--- /dev/null
+++ b/src/lib/transaction/hooks/useTransaction.js
@@ -0,0 +1,13 @@
+import { useQuery } from "react-query"
+import transactionApi from "../api/transactionApi"
+
+const useTransaction = ({ id }) => {
+ const fetchTransaction = async () => await transactionApi({ id })
+ const { data, isLoading, refetch } = useQuery(`transaction-${id}`, fetchTransaction)
+
+ return {
+ transaction: { data, isLoading, refetch }
+ }
+}
+
+export default useTransaction \ No newline at end of file
diff --git a/src/lib/transaction/utils/transactions.js b/src/lib/transaction/utils/transactions.js
index 166e8a7e..03d4dbd4 100644
--- a/src/lib/transaction/utils/transactions.js
+++ b/src/lib/transaction/utils/transactions.js
@@ -1,10 +1,14 @@
-const downloadPurchaseOrder = (partnerId, transaction) => {
- const url = `${process.env.ODOO_HOST}/api/v1/partner/${partnerId}/sale_order/${transaction.id}/download_po/${transaction.token}`
+import { getAuth } from "@/core/utils/auth"
+
+const downloadPurchaseOrder = (transaction) => {
+ const auth = getAuth()
+ const url = `${process.env.ODOO_HOST}/api/v1/partner/${auth.partnerId}/sale_order/${transaction.id}/download_po/${transaction.token}`
window.open(url, 'download')
}
-const downloadQuotation = (partnerId, transaction) => {
- const url = `${process.env.ODOO_HOST}/api/v1/partner/${partnerId}/sale_order/${transaction.id}/download/${transaction.token}`
+const downloadQuotation = (transaction) => {
+ const auth = getAuth()
+ const url = `${process.env.ODOO_HOST}/api/v1/partner/${auth.partnerId}/sale_order/${transaction.id}/download/${transaction.token}`
window.open(url, 'download')
}