ID: {{ record?.id }}
diff --git a/app/handlers/material.handler.ts b/app/handlers/material.handler.ts
new file mode 100644
index 00000000..0abd6554
--- /dev/null
+++ b/app/handlers/material.handler.ts
@@ -0,0 +1,80 @@
+import { ref } from 'vue'
+
+// Services
+import { postSourceMaterial, putSourceMaterial, removeSourceMaterial } from '~/services/material.service'
+
+const recId = ref
(0)
+const recAction = ref('')
+const recItem = ref(null)
+const isFormEntryDialogOpen = ref(false)
+const isRecordConfirmationOpen = ref(false)
+
+function onResetState() {
+ recId.value = 0
+ recAction.value = ''
+ recItem.value = null
+}
+
+export async function handleActionSave(values: any, refresh: () => void, reset: () => void) {
+ let isSuccess = false
+ try {
+ const result = await postSourceMaterial(values)
+ if (result.success) {
+ isFormEntryDialogOpen.value = false
+ isSuccess = true
+ if (refresh) refresh()
+ }
+ } catch (error) {
+ console.warn('Error saving form:', error)
+ isSuccess = false
+ } finally {
+ if (isSuccess) {
+ setTimeout(() => {
+ reset()
+ }, 500)
+ }
+ }
+}
+
+export async function handleActionEdit(id: number | string, values: any, refresh: () => void, reset: () => void) {
+ let isSuccess = false
+ try {
+ const result = await putSourceMaterial(id, values)
+ if (result.success) {
+ isFormEntryDialogOpen.value = false
+ isSuccess = true
+ if (refresh) refresh()
+ }
+ } catch (error) {
+ console.warn('Error editing form:', error)
+ isSuccess = false
+ } finally {
+ if (isSuccess) {
+ setTimeout(() => {
+ reset()
+ }, 500)
+ }
+ }
+}
+
+export async function handleActionRemove(id: number | string, refresh: () => void) {
+ try {
+ const result = await removeSourceMaterial(id)
+ if (result.success) {
+ if (refresh) refresh()
+ }
+ } catch (error) {
+ console.error('Error deleting record:', error)
+ } finally {
+ onResetState()
+ }
+}
+
+export function handleCancelForm(reset: () => void) {
+ isFormEntryDialogOpen.value = false
+ setTimeout(() => {
+ reset()
+ }, 500)
+}
+
+export { recId, recAction, recItem, isFormEntryDialogOpen, isRecordConfirmationOpen }
diff --git a/app/models/equipment-material.ts b/app/models/equipment-material.ts
deleted file mode 100644
index 3adac0b2..00000000
--- a/app/models/equipment-material.ts
+++ /dev/null
@@ -1,6 +0,0 @@
-export interface EquipmentMaterial {
- code: string;
- name: string;
- uom_code: string;
- stock: number;
-}
diff --git a/app/models/material.ts b/app/models/material.ts
new file mode 100644
index 00000000..5e259256
--- /dev/null
+++ b/app/models/material.ts
@@ -0,0 +1,6 @@
+export interface Material {
+ code: string
+ name: string
+ uom_code: string
+ stock: number
+}
diff --git a/app/models/uom.ts b/app/models/uom.ts
new file mode 100644
index 00000000..8c42a56d
--- /dev/null
+++ b/app/models/uom.ts
@@ -0,0 +1,4 @@
+export interface Uom {
+ code: string
+ name: string
+}
diff --git a/app/schemas/material.ts b/app/schemas/material.ts
index 27e9c68b..ff6252a7 100644
--- a/app/schemas/material.ts
+++ b/app/schemas/material.ts
@@ -1,5 +1,5 @@
import { z } from 'zod'
-import type { EquipmentMaterial } from '~/models/equipment-material'
+import type { Material } from '~/models/material'
const MaterialSchema = z.object({
code: z.string({ required_error: 'Kode harus diisi' }).min(1, 'Kode minimum 1 karakter'),
@@ -8,7 +8,7 @@ const MaterialSchema = z.object({
stock: z.preprocess((val) => Number(val), z.number({ invalid_type_error: 'Stok harus berupa angka' }).min(1, 'Stok harus lebih besar dari 0')),
})
-type MaterialFormData = z.infer & EquipmentMaterial
+type MaterialFormData = z.infer & Material
export { MaterialSchema }
export type { MaterialFormData }
diff --git a/app/services/material.service.ts b/app/services/material.service.ts
new file mode 100644
index 00000000..2b9a6d3c
--- /dev/null
+++ b/app/services/material.service.ts
@@ -0,0 +1,87 @@
+import { xfetch } from '~/composables/useXfetch'
+
+export async function getSourceMaterials(params: any = null) {
+ try {
+ let url = '/api/v1/material';
+ if (params && typeof params === 'object' && Object.keys(params).length > 0) {
+ const searchParams = new URLSearchParams();
+ for (const key in params) {
+ if (params[key] !== null && params[key] !== undefined && params[key] !== '') {
+ searchParams.append(key, params[key]);
+ }
+ }
+ const queryString = searchParams.toString();
+ if (queryString) url += `?${queryString}`;
+ }
+ const resp = await xfetch(url, 'GET');
+ const result: any = {};
+ result.success = resp.success;
+ if (resp.success) {
+ result.data = (resp.body as Record).data;
+ }
+ return result;
+ } catch (error) {
+ console.error('Error fetching source materials:', error);
+ throw new Error('Failed to fetch source materials');
+ }
+}
+
+export async function getSourceMaterialDetail(id: number | string) {
+ try {
+ const resp = await xfetch(`/api/v1/material/${id}`, 'GET');
+ const result: any = {}
+ result.success = resp.success
+ if (resp.success) {
+ result.data = (resp.body as Record).data
+ }
+ return result
+ } catch (error) {
+ console.error('Error fetching source material detail:', error)
+ throw new Error('Failed to get source material detail')
+ }
+}
+
+export async function postSourceMaterial(record: any) {
+ try {
+ const resp = await xfetch('/api/v1/material', 'POST', record);
+ const result: any = {}
+ result.success = resp.success
+ if (resp.success) {
+ result.data = (resp.body as Record).data
+ }
+ return result
+ } catch (error) {
+ console.error('Error posting source material:', error)
+ throw new Error('Failed to post source material')
+ }
+}
+
+export async function putSourceMaterial(id: number | string, record: any) {
+ try {
+ const resp = await xfetch(`/api/v1/material/${id}`, 'PUT', record);
+ const result: any = {}
+ result.success = resp.success
+ if (resp.success) {
+ result.data = (resp.body as Record).data
+ }
+ return result
+ } catch (error) {
+ console.error('Error putting source material:', error)
+ throw new Error('Failed to put source material')
+ }
+}
+
+export async function removeSourceMaterial(id: number | string) {
+ try {
+ const resp = await xfetch(`/api/v1/material/${id}`, 'DELETE')
+ const result: any = {}
+ result.success = resp.success
+ if (resp.success) {
+ result.data = (resp.body as Record).data
+ }
+ return result
+ } catch (error) {
+ console.error('Error deleting record:', error)
+ throw new Error('Failed to delete source material')
+ }
+}
diff --git a/app/services/source-material.service.ts b/app/services/source-material.service.ts
deleted file mode 100644
index 6de45ff5..00000000
--- a/app/services/source-material.service.ts
+++ /dev/null
@@ -1,9 +0,0 @@
-import { xfetch } from '~/composables/useXfetch'
-
-export async function getSourceMaterials() {
- const resp = await xfetch('/api/v1/material')
- if (resp.success) {
- return (resp.body as Record).data
- }
- throw new Error('Failed to fetch source materials')
-}
diff --git a/app/services/source-uom.service.ts b/app/services/source-uom.service.ts
deleted file mode 100644
index 2569c05d..00000000
--- a/app/services/source-uom.service.ts
+++ /dev/null
@@ -1,9 +0,0 @@
-import { xfetch } from '~/composables/useXfetch'
-
-export async function getSourceUoms() {
- const resp = await xfetch('/api/v1/uom')
- if (resp.success) {
- return (resp.body as Record).data
- }
- throw new Error('Failed to fetch source uoms')
-}
diff --git a/app/services/uom.service.ts b/app/services/uom.service.ts
new file mode 100644
index 00000000..8ebe3e2a
--- /dev/null
+++ b/app/services/uom.service.ts
@@ -0,0 +1,27 @@
+import { xfetch } from '~/composables/useXfetch'
+
+export async function getSourceUoms(params: any = null) {
+ try {
+ let url = '/api/v1/uom'
+ if (params && typeof params === 'object' && Object.keys(params).length > 0) {
+ const searchParams = new URLSearchParams()
+ for (const key in params) {
+ if (params[key] !== null && params[key] !== undefined && params[key] !== '') {
+ searchParams.append(key, params[key])
+ }
+ }
+ const queryString = searchParams.toString()
+ if (queryString) url += `?${queryString}`
+ }
+ const resp = await xfetch(url, 'GET')
+ const result: any = {}
+ result.success = resp.success
+ if (resp.success) {
+ result.data = (resp.body as Record).data
+ }
+ return result
+ } catch (error) {
+ console.error('Error fetching source uoms:', error)
+ throw new Error('Failed to fetch source uoms')
+ }
+}