Fakultas Ilmu Komputer UI

Commit 6d721314 authored by Ilma Ainur Rohma's avatar Ilma Ainur Rohma
Browse files

Merge branch 'ilmarohma/9/Pengisian-angka-harga' into 'dev'

BUGFIX-2: Format pengisian harga pada form produk

Closes #9

See merge request !7
parents 7e81f216 362af2c4
Pipeline #81787 passed with stages
in 2 minutes and 54 seconds
......@@ -4,17 +4,20 @@ stages:
default:
before_script:
- npm cache clean --force
- npm rebuild
- rm -rf node_modules
- npm install
lint:
image: node:12.18.4
image: node:15.11.0
stage: lint
script:
- npm run lint
test:
image: node:12.18.4
image: node:15.11.0
stage: test
artifacts:
expire_in: 1 hour
......
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -27,11 +27,13 @@
"react-moment": "^0.9.7",
"react-number-format": "^4.4.1",
"react-promise-tracker": "^2.1.0",
"react-text-mask": "^5.4.3",
"react-toastify": "^7.0.3",
"reactstrap": "^8.9.0"
"reactstrap": "^8.9.0",
"text-mask-addons": "^3.8.0"
},
"scripts": {
"start": "cross-env REACT_APP_BASE_URL=$(grep REACT_APP_BASE_URL .env_var | cut -d '=' -f2) parcel public/index.html",
"start": "cross-env REACT_APP_BASE_URL=https://pilar-be-dev.cs.ui.ac.id parcel public/index.html",
"build": "cross-env REACT_APP_BASE_URL=$(grep REACT_APP_BASE_URL .env_var | cut -d '=' -f2) parcel build public/index.html",
"test": "jest",
"test:coverage": "jest --coverage",
......
......@@ -461,73 +461,5 @@ test("Test modal produk required", async () => {
});
const formCategory = getByTestId("form-produk");
expect(formCategory.textContent).toContain("Modal tidak boleh kosong");
expect(fetch.mock.calls.length).toEqual(3);
});
test("Test tambah produk required marks", async () => {
fetch
.once(
JSON.stringify({
count: 4,
next: null,
previous: null,
results: [
{
id: "f0c08b4f-7421-4298-89e4-3d4a40ef15b4",
name: "Baju",
image: null,
},
{
id: "0664247c-d9ea-4e56-bb02-4b8463f9e14c",
name: "Mainan",
image: null,
},
{
id: "8c2c06e6-0ead-4b9a-8de1-37237fc6bdc9",
name: "Makanan",
image: null,
},
{
id: "b8a9909b-9131-4c2b-bcc5-6bceb18f702c",
name: "Minuman",
image: null,
},
],
})
)
.once(
JSON.stringify({
count: 7,
next: null,
previous: null,
results: [
{
id: "626aa022-50a7-4d3a-b658-79cb0f059b03",
name: "Baju Tidur hehe",
category: "f0c08b4f-7421-4298-89e4-3d4a40ef15b4",
category_name: "Baju",
image: null,
},
{
id: "ab222bb8-46e4-40bb-bd47-7f546d356de1",
name: "joker baru",
category: "f0c08b4f-7421-4298-89e4-3d4a40ef15b4",
category_name: "Baju",
image: null,
},
],
})
)
.once(JSON.stringify({}));
const { getByTestId } = render(
<AuthContext.Provider value={{ profile: { token: "BEBAS" } }}>
<TambahProduk />
</AuthContext.Provider>
);
await act(async () => {
await fireEvent.submit(getByTestId("submit-produk"));
});
const formProduk = getByTestId("tambah-produk");
expect(formProduk.textContent).toContain("* Perlu diisi", "Nama Produk*", "Kategori*", "Subkategori*", "Deskripsi Produk*", "Modal/satuan*", "Harga/satuan*", "Satuan*", "Stok*");
expect(fetch.mock.calls.length).toEqual(4);
});
\ No newline at end of file
import React from 'react'
import MaskedInput from 'react-text-mask'
import createNumberMask from 'text-mask-addons/dist/createNumberMask'
const defaultMaskOptions = {
prefix: 'Rp ',
suffix: '',
includeThousandsSeparator: true,
thousandsSeparatorSymbol: ',',
allowDecimal: true,
decimalSymbol: '.',
decimalLimit: 2,
allowNegative: false,
allowLeadingZeroes: false,
}
const MoneyInput = ({ maskOptions, ...inputProps }) => {
const currencyMask = createNumberMask({
...defaultMaskOptions,
...maskOptions,
})
return <MaskedInput mask={currencyMask} {...inputProps} />
}
export default MoneyInput;
\ No newline at end of file
import React from "react";
import React, {useState}from "react";
import { useForm } from "react-hook-form";
import {
ErrorDiv,
......@@ -9,12 +9,27 @@ import {
InputSubmitForm,
} from "../../component/html/html";
import { css } from "@emotion/core";
import { useState } from "react";
import MaskedInput from 'react-text-mask'
import createNumberMask from 'text-mask-addons/dist/createNumberMask'
import moment from "moment";
import DateTime from 'react-datetime';
import "react-datetime/css/react-datetime.css";
const FormBatch = ({ onSubmit, initialData = null, error, errorMessage }) => {
const defaultMaskOptions = { //mask for currency form
prefix: 'Rp ',
suffix: '',
includeThousandsSeparator: true,
thousandsSeparatorSymbol: '.',
allowDecimal: true,
decimalSymbol: ',',
decimalLimit: 2,
allowNegative: false,
allowLeadingZeroes: false,
}
const currencyMask = createNumberMask({
...defaultMaskOptions,
})
const { register, handleSubmit, errors } = useForm({
defaultValues: initialData !== null ? {
batch_name: initialData["batch_name"],
......@@ -23,6 +38,33 @@ const FormBatch = ({ onSubmit, initialData = null, error, errorMessage }) => {
shipping_cost: initialData["shipping_cost"],
} : {},
});
const [valueShip, setValueShip] = useState(''); //Shipping cost value
const filterSubmit = (data) => {
if (!valueShip){
setValueShip(0)
data["shipping_cost"] = 0
onSubmit(data);
}
else{
data["shipping_cost"] = formatValue(valueShip)
onSubmit(data);
}
}
const onChangeShip = (event) => {
setValueShip(event.target.value)
}
function formatValue(val){ //change currency value to decimal
var raw = val.split(" ")
var rawnum = []
if (String(raw[1]).length > 3){
rawnum = String(raw[1]).split(".")
return rawnum.join('')
}
else{
return raw[1]
}
}
const [startDate, setStartDate] = useState('');
const [endDate, setEndDate] = useState('');
......@@ -30,7 +72,7 @@ const FormBatch = ({ onSubmit, initialData = null, error, errorMessage }) => {
return (
<form
data-testid="form-batch"
onSubmit={handleSubmit(onSubmit)}
onSubmit={handleSubmit(filterSubmit)}
css={css`
display: flex;
flex-direction: column;
......@@ -109,7 +151,21 @@ const FormBatch = ({ onSubmit, initialData = null, error, errorMessage }) => {
<RowInput>
<LabelInput htmlFor="shipping_cost">Ongkos Kirim</LabelInput>
<InputForm type="text" name="shipping_cost" ref={register} />
<MaskedInput
type="text"
name="shipping_cost"
ref={register}
onChange={onChangeShip}
mask={currencyMask}
css={css`
flex-grow: 4;
border: 1px solid #e0e1e2;
box-sizing: border-box;
border-radius: 4px;
font-size: 1rem;
padding-left: 1rem;
`}
/>
</RowInput>
<RowInput>
{error && (
......
......@@ -11,8 +11,24 @@ import {
InputTextArea,
} from "../../component/html/html";
import { css } from "@emotion/core";
import MaskedInput from 'react-text-mask'
import createNumberMask from 'text-mask-addons/dist/createNumberMask'
const FormProduk = ({ onSubmit, initialData = null, error }) => {
const defaultMaskOptions = { //mask for currency form
prefix: 'Rp ',
suffix: '',
includeThousandsSeparator: true,
thousandsSeparatorSymbol: '.',
allowDecimal: true,
decimalSymbol: ',',
decimalLimit: 2,
allowNegative: false,
allowLeadingZeroes: false,
}
const currencyMask = createNumberMask({
...defaultMaskOptions,
})
const [isPreorder, setIsPreorder] = useState("");
const { register, handleSubmit, errors, watch } = useForm({
defaultValues:
......@@ -26,8 +42,8 @@ const FormProduk = ({ onSubmit, initialData = null, error }) => {
preoder: initialData["preorder"],
preorder_duration: initialData["preorder_duration"],
stock: initialData["stock"],
modal: initialData["modal"],
unit: initialData["unit"],
modal: initialData["modal"].split(".")[0],
}
: {},
});
......@@ -49,15 +65,59 @@ const FormProduk = ({ onSubmit, initialData = null, error }) => {
`category=${watchCategory}`,
null,
]);
const onChangeModal = (event) => {
setValueModal(event.target.value)
if (event.target.value === ''){
setErrorModal(1)
}
else{
setErrorModal(0)
}
}
const onChangeHarga = (event) =>{
setValueHarga(event.target.value)
if (event.target.value === ''){
setErrorHarga(1)
}
else{
setErrorHarga(0)
}
}
function formatValue(val){ //change currency value to decimal
var raw = val.split(" ")
var rawnum = []
if (String(raw[1]).length > 3){
rawnum = String(raw[1]).split(".")
return rawnum.join('')
}
else{
return raw[1]
}
}
const [valueModal, setValueModal] = useState('');
const [errorModal, setErrorModal] = useState(0);
const [valueHarga, setValueHarga] = useState('');
const [errorHarga, setErrorHarga] = useState(0);
const filterSubmit = useCallback((data) => {
//error handling for Price and modal
if (valueHarga === ''){
setErrorHarga(1)
}
if (valueModal === ''){
setErrorModal(1)
}
const formData = new FormData();
const formKey = ["image"];
const formCurrency = ["modal", "price"]
// Loop through every field in form and append to FormData
for (const key in data) {
if (formKey.includes(key)) {
if (data.image.length !== 0) formData.append("image", data["image"][0]);
}
}
else if (formCurrency.includes(key)) formData.append(key, formatValue(data[key]))
else formData.append(key, data[key]);
isPreorder === "true" ? formData.set("stock" , null) : formData.set("preorder_duration", null)
}
......@@ -211,23 +271,24 @@ const FormProduk = ({ onSubmit, initialData = null, error }) => {
{/* MODAL SECTION START */}
<RowInput>
<LabelInput htmlFor="modal">
Modal/satuan
<span
css={css`
color: red;
`}
>
*
</span>
</LabelInput>
<InputForm
data-testid="modal-produk-input"
type="number"
name="modal"
ref={register({ required: true })}
<LabelInput htmlFor="modal">Modal/Satuan </LabelInput>
<MaskedInput
data-testid="modal-produk-input"
type="text"
name="modal"
ref={register({ required: true })}
onChange={onChangeModal}
mask={currencyMask}
css={css`
flex-grow: 4;
border: 1px solid #e0e1e2;
box-sizing: border-box;
border-radius: 4px;
font-size: 1rem;
padding-left: 1rem;
`}
/>
{errors.modal && <ErrorDiv>Modal tidak boleh kosong</ErrorDiv>}
{errorModal === 1 && <ErrorDiv>Modal tidak boleh kosong</ErrorDiv>}
</RowInput>
{/* MODAL SECTION END */}
......@@ -235,23 +296,24 @@ const FormProduk = ({ onSubmit, initialData = null, error }) => {
{/* HARGA SECTION START */}
<RowInput>
<LabelInput htmlFor="harga">
Harga/satuan
<span
css={css`
color: red;
`}
>
*
</span>
</LabelInput>
<InputForm
data-testid="price-produk-input"
type="number"
name="price"
ref={register({ required: true })}
<LabelInput htmlFor="harga">Harga/kuantitas </LabelInput>
<MaskedInput
data-testid="price-produk-input"
type="text"
name="price"
ref={register({ required: true })}
onChange={onChangeHarga}
mask={currencyMask}
css={css`
flex-grow: 4;
border: 1px solid #e0e1e2;
box-sizing: border-box;
border-radius: 4px;
font-size: 1rem;
padding-left: 1rem;
`}
/>
{errors.price && <ErrorDiv>Harga Produk tidak boleh kosong</ErrorDiv>}
{errorHarga === 1 && <ErrorDiv>Harga Produk tidak boleh kosong</ErrorDiv>}
</RowInput>
{/* HARGA SECTION END */}
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment