Files
fe-accone/test/vuex/acc-one-approve-po-inventaris/modules/po.js

1475 lines
59 KiB
JavaScript

// 1 => LOADING
// 2 => DONE
// 3 => ERROR
import * as api from "../api/po.js";
import { validatePurchaseOrder, groupPurchaseRequestsByItemId, calculateSummaryTotal } from "../functions/functions.js";
export default {
namespaced: true,
state: {
statusOptions: [
{ value: 'All', title: "All" },
{ value: 'Draft', title: "Draft" },
{ value: 'Pending', title: "Pending" },
{ value: 'Approved', title: "Approved" },
{ value: 'Rejected', title: "Rejected" },
{ value: 'Completed', title: "Completed" },
],
selectedStatus: { value: 'All', title: "All" },
selectedDate: moment(new Date()).format('YYYY-MM-DD'),
search: '',
totalPage: 0,
selectedPage: 1,
loading: false,
poList: [
{
"poNumber": "PO1234566",
"poDate": "01-01-2025",
"poVendor": "PT ABC 123",
"poTotal": "1000000",
"poStatus": "DRAFT",
}
],
dialogForm: false,
detailData: [],
selectedPr: {},
loadingDetail: false,
snackbar: {
state: false,
type: 'success',
message: '',
},
//FORM
selectedDateForm: moment(new Date()).format('YYYY-MM-DD'),
selectedDateEnd: moment(new Date()).format('YYYY-MM-DD'),
selectedSupplier: {},
refNumber: '',
taxPpn: 0,
taxPph: 0,
paymentTerm: 0,
discountType: 'Percentage',
discountTypeList: ['Percentage', 'Absolute'],
discountAmount: 0,
note: '',
warehouseTypeList: ['Single', 'Multiple'],
warehouseType: 'Single',
warehouseList: [],
selectedWarehouse: {},
itemList: [],
selectedItemTemp: [],
selectedItem: [],
searchItem: '',
itemTotal: {
total: 0,
ppn: 0,
pph: 0,
tax: 0,
discount: 0,
finalTotal: 0,
},
defaultWarehouse: {},
shippingCost: 0,
shippingCostStatus: true,//Sudah di bayar atau belum
//END FORM
supplierList: [],
loadingAutocomplete: false,
searchSupplier: "",
dialogConfirmation: false,
dialogDelete: false,
selectedPO: {},
dialogItem: false,
currentPageItem: 1,
totalPageItem: 0,
dialogFormAct: 'ADD',
summary: [],
summaryTotal: {
total: 0,
ppn: 0,
pph: 0,
tax: 0,
discount: 0,
finalTotal: 0,
},
deletedItem: [],//kalau edit item sebelumnya yang dihapus masuk sini agar bisa dipilih lagi ,
dialogView: false,
itemCategoryList: [],
selectedItemCategory: {},
open_print: false,
// isValidMultipleWarehouse: false, // Flag untuk validasi multiple warehouse
isValidMultipleWarehouse: {
status: false,
message: '',
},
approve_level: 0,
status: '',
xstartdate: '',
itemDesc: '',
flag: '',
typePpn: ['Percentage', 'Absolute'],
typePpnSelected: 'Percentage',
},
mutations: {
update_shippingCost(state, val) {
state.shippingCost = val;
},
update_shippingCostStatus(state, val) {
state.shippingCostStatus = val;
},
update_selectedItemCategory(state, val) {
state.selectedItemCategory = val;
},
update_itemCategoryList(state, val) {
state.itemCategoryList = val;
},
update_dialogView(state, val) {
state.dialogView = val;
},
update_deletedItem(state, val) {
state.deletedItem = val;
},
update_summaryTotal(state, val) {
state.summaryTotal = val;
},
update_summary(state, val) {
state.summary = val;
},
update_dialogFormAct(state, val) {
state.dialogFormAct = val;
},
update_totalPageItem(state, val) {
state.totalPageItem = val;
},
update_currentPageItem(state, val) {
state.currentPageItem = val;
},
update_dialogItem(state, val) {
state.dialogItem = val;
},
update_selectedPO(state, val) {
state.selectedPO = val;
},
update_dialogDelete(state, val) {
state.dialogDelete = val;
},
update_dialogConfirmation(state, val) {
state.dialogConfirmation = val;
},
update_defaultWarehouse(state, val) {
state.defaultWarehouse = val;
},
update_itemTotal(state, val) {
state.itemTotal = val;
},
update_searchItem(state, val) {
state.searchItem = val;
},
update_selectedItemTemp(state, val) {
state.selectedItemTemp = val;
},
update_selectedItem(state, val) {
state.selectedItem = val;
},
update_itemList(state, val) {
state.itemList = val;
},
update_warehouseList(state, val) {
state.warehouseList = val;
},
update_supplierList(state, val) {
state.supplierList = val;
},
update_searchSupplier(state, val) {
state.searchSupplier = val;
},
update_loadingAutocomplete(state, val) {
state.loadingAutocomplete = val;
},
update_selectedWarehouse(state, val) {
state.selectedWarehouse = val;
},
update_warehouseTypeList(state, val) {
state.warehouseTypeList = val;
},
update_warehouseType(state, val) {
state.warehouseType = val;
// Disable and clear selectedWarehouse when type is Multiple
if (val === 'Multiple') {
state.selectedWarehouse = {};
}
},
update_note(state, val) {
state.note = val;
},
update_discountAmount(state, val) {
// debugger;
if (state.discountType === 'Percentage' && val > 100) {
state.snackbar = {
state: true,
type: 'warning',
message: 'Diskon tidak boleh lebih dari 100',
};
state.discountAmount = 100;
return;
}
if (state.discountType === 'Absolute' && val > state.itemTotal.total && state.itemTotal.total > 0) {
state.snackbar = {
state: true,
type: 'warning',
message: 'Diskon tidak boleh lebih dari total',
};
state.discountAmount = state.itemTotal.total;
return;
}
state.discountAmount = val;
},
update_discountType(state, val) {
state.discountType = val;
},
update_paymentTerm(state, val) {
state.paymentTerm = val;
},
update_taxPpn(state, val) {
if (state.typePpnSelected === 'Percentage' && val > 100) {
state.snackbar = {
state: true,
type: 'warning',
message: 'Persen tidak boleh lebih dari 100',
};
state.taxPpn = 100;
return;
}
if (state.typePpnSelected === 'Absolute' && val > state.itemTotal.total && state.itemTotal.total > 0) {
state.snackbar = {
state: true,
type: 'warning',
message: 'Ppn tidak boleh lebih dari total',
};
state.taxPpn = state.itemTotal.total;
return;
}
state.taxPpn = val;
// if (val > 0) {
// state.taxPpn = val;
// } else {
// state.taxPpn = 0;
// }
},
update_taxPph(state, val) {
if (val > 0) {
state.taxPph = val;
} else {
state.taxPph = 0;
}
},
update_refNumber(state, val) {
state.refNumber = val;
},
update_selectedSupplier(state, val) {
state.selectedSupplier = val;
},
update_selectedDateForm(state, val) {
state.selectedDateForm = val;
},
update_selectedDateEnd(state, val) {
state.selectedDateEnd = val;
},
update_snackbar(state, val) {
state.snackbar = val;
},
update_loadingDetail(state, val) {
state.loadingDetail = val;
},
update_selectedPr(state, val) {
state.selectedPr = val;
},
update_detailData(state, val) {
state.detailData = val;
},
update_dialogForm(state, val) {
state.dialogForm = val;
},
update_selectedStatus(state, val) {
state.selectedStatus = val;
},
update_selectedDate(state, val) {
state.selectedDate = val;
},
update_search(state, val) {
state.search = val;
},
update_loading(state, val) {
state.loading = val;
},
update_totalPage(state, val) {
state.totalPage = val;
},
update_selectedPage(state, val) {
state.selectedPage = val;
},
update_poList(state, val) {
state.poList = val;
},
update_open_print(state, value) {
state.open_print = value
},
update_isValidMultipleWarehouse(state, value) {
state.isValidMultipleWarehouse = value;
},
update_approve_level(state, data) {
state.approve_level = data
},
update_status(state, val) {
state.status = val
},
update_xstartdate(state, val) {
state.xstartdate = val
},
update_itemDesc(state, val) {
state.itemDesc = val;
},
update_flag(state, val) {
state.flag = val
},
update_typePpn(state, val) {
state.typePpn = val;
},
update_typePpnSelected(state, val) {
state.typePpnSelected = val;
},
},
actions: {
async deleteItemFromSummary(context, { itemId = null, detailId = null }) {
// Jika itemId ada, hapus seluruh item dan detailsnya
if (itemId) {
const newSummary = context.state.summary.filter(item => item.keyID !== itemId);
const newSelectedItem = context.state.selectedItem.filter(item => item.keyID !== itemId);
if (context.state.dialogFormAct === 'EDIT') {
let deletedItemBefore = JSON.parse(JSON.stringify(context.state.deletedItem))
const deletedItem = context.state.selectedItem.filter(item => item.keyID === itemId
&& item.PurchaseOrderDetailID !== undefined
&& item.PurchaseOrderDetailID !== null
&& item.PurchaseOrderDetailID !== 0);
let newDeletedItem = []
deletedItem.forEach(de => {
let cek = deletedItemBefore.find((element) =>
element.M_ItemID === de.M_ItemID
&& element.PurchaseRequestFlagID === de.PurchaseRequestFlagID
&& element.PurchaseOrderDetailID === de.PurchaseOrderDetailID)
if (!cek) {
newDeletedItem.push(de)
}
});
context.commit('update_deletedItem', [...deletedItemBefore, ...newDeletedItem]);
}
context.commit('update_summary', newSummary);
context.commit('update_selectedItem', newSelectedItem);
}
// Jika detailId ada, hapus detail spesifik
if (detailId) {
// Hapus dari selectedItem
const newSelectedItem = context.state.selectedItem.filter(
item => item.PurchaseRequestFlagID !== detailId
);
if (context.state.dialogFormAct === 'EDIT') {
let deletedItemBefore = JSON.parse(JSON.stringify(context.state.deletedItem))
const deletedItem = context.state.selectedItem.filter(
item => item.PurchaseRequestFlagID === detailId
&& item.PurchaseOrderDetailID !== undefined
&& item.PurchaseOrderDetailID !== null
&& item.PurchaseOrderDetailID !== 0
);
let newDeletedItem = []
deletedItem.forEach(de => {
let cek = deletedItemBefore.find((element) =>
element.M_ItemID === de.M_ItemID
&& element.PurchaseRequestFlagID === de.PurchaseRequestFlagID
&& element.PurchaseOrderDetailID === de.PurchaseOrderDetailID)
if (!cek) {
newDeletedItem.push(de)
}
});
context.commit('update_deletedItem', [...deletedItemBefore, ...newDeletedItem]);
}
// Regenerate summary dari selectedItem yang baru
const newSummary = await groupPurchaseRequestsByItemId(newSelectedItem, context);
context.commit('update_summary', newSummary);
context.commit('update_selectedItem', newSelectedItem);
}
// Hitung ulang total
context.dispatch('countItemTotal');
context.dispatch('generateSummary');
},
generateSummaryTotal(context) {
const summaryTotal = calculateSummaryTotal(
context.state.summary,
context.state.typePpnSelected,
context.state.taxPpn,
context.state.taxPph,
context.state.discountType,
context.state.discountAmount
);
context.commit('update_summaryTotal', summaryTotal);
},
async generateSummary(context) {
let data = JSON.parse(JSON.stringify(context.state.selectedItem));
console.log("Data untuk param groupPurchaseRequestsByItemId:", JSON.parse(JSON.stringify(data)));
/**
* Tambah validasi:
* > Apakah bisa multiple warehouse?
*/
context.dispatch('isValidMultipleWarehouse');
if (context.state.warehouseType === "Multiple") {
data.forEach((element) => {
element.warehouse = {
WarehouseID: element.WarehouseID,
WarehouseName: element.WarehouseName,
};
});
} else if (context.state.warehouseType === "Single") {
data.forEach((element) => {
element.warehouse = context.state.selectedWarehouse; // Semua item pakai warehouse yang sama
});
}
let summary = await groupPurchaseRequestsByItemId(data, context);
context.commit('update_summary', summary);
console.log("Summary setelah grouping:", JSON.parse(JSON.stringify(summary)));
// Hitung summary total menggunakan fungsi dari functions.js
const summaryTotal = calculateSummaryTotal(
summary,
context.state.typePpnSelected,
context.state.taxPpn,
context.state.taxPph,
context.state.discountType,
context.state.discountAmount
);
context.commit('update_summaryTotal', summaryTotal);
},
multipleWarehouseValidation(context, selectedItem) {
let data;
if (!selectedItem || selectedItem.length === 0) {
data = JSON.parse(JSON.stringify(context.state.selectedItem));
} else {
data = JSON.parse(JSON.stringify(selectedItem));
}
// Pakai 'Set' JS Object yang hanya menyimpan nilai unik.
const warehouseIds = new Set();
data.forEach(item => {
if (item.WarehouseID) {
// Kalau ada yang sama maka disimpan sekali.
warehouseIds.add(item.WarehouseID);
}
});
if (warehouseIds.size > 1) {
return true; // Ada lebih dari satu WarehouseID
} else {
return false; // Hanya ada satu WarehouseID
}
},
async isValidMultipleWarehouse(context) {
/**
* @param: array of PurchaseRequestDetailID dari selectedItem
* @api: api.isValidMultipleWarehouse
* @return: JSON -> {data.status (boolean), data.message (string)}
*
*/
if (context.state.selectedItem.length === 0) {
return false; // Tidak ada item yang dipilih
}
try {
let payload = {
"PurchaseRequestDetailIDs": context.state.selectedItem.map(item => item.PurchaseRequestDetailID),
"token": one_token(),
};
let response = await api.isValidMultipleWarehouse(payload)
console.log("Payload untuk isValidMultipleWarehouse:", JSON.parse(JSON.stringify(payload.PurchaseRequestDetailIDs)));
console.log("Response dari isValidMultipleWarehouse:", JSON.parse(JSON.stringify(response)));
if (response.status !== "OK") {
let snackbar = {
state: true,
type: "error",
message: response.message,
}
context.commit("update_isValidMultipleWarehouse", {
status: false,
message: '',
});
context.commit("update_snackbar", snackbar);
} else {;
context.commit("update_isValidMultipleWarehouse", {
status: response.data.status,
message: response.data.message,
});
if(response.data.status == false) {
context.commit("update_warehouseType", 'Single');
context.commit("update_selectedWarehouse", context.state.selectedWarehouse);
}
};
} catch (e) {
let snackbar = {
state: true,
type: "error",
message: e.message,
}
context.commit("update_snackbar", snackbar);
}
},
assignEdit(context) {
let data = context.state.selectedPO
context.commit("update_selectedDateForm", data.PurchaseOrderDate);
context.commit("update_searchSupplier", data.SupplierName);
context.commit("update_selectedSupplier", {
"SupplierID": data.PurchaseOrderSupplierID,
"SupplierCode": data.SupplierCode,
"SupplierName": data.SupplierName
});
context.commit("update_selectedItemCategory", {
"itemCategoryID": data.itemCategoryID,
"itemCategoryName": data.itemCategoryName
});
context.commit("update_refNumber", data.PurchaseOrderRefNumber);
context.commit("update_shippingCost", data.PurchaseOrderShippingCost);
context.commit("update_shippingCostStatus", data.PurchaseOrderShippingCostStatus === 'Y' ? true : false);
context.commit("update_typePpnSelected", data.PurchaseOrderTaxPercentPpn > 0 ? 'Percentage' : 'Absolute');
if (data.PurchaseOrderTaxPercentPpn > 0) {
context.commit("update_taxPpn", parseFloat(data.PurchaseOrderTaxPercentPpn));
} else {
context.commit("update_taxPpn", parseFloat(data.PurchaseOrderTaxAmountPpn));
}
context.commit("update_taxPph", data.PurchaseOrderTaxPercentPph);
context.commit("update_paymentTerm", data.PurchaseOrderPaymentTerm);
context.commit("update_discountType", data.PurchaseOrderDiscountPercent > 0 ? 'Percentage' : 'Absolute');
if (data.PurchaseOrderDiscountPercent > 0) {
context.commit("update_discountAmount", parseFloat(data.PurchaseOrderDiscountPercent));
} else {
context.commit("update_discountAmount", parseFloat(data.PurchaseOrderDiscountAmount));
}
context.commit("update_note", data.PurchaseOrderNote);
context.commit("update_warehouseType", data.PurchaseOrderWarehouseType);
context.commit("update_selectedWarehouse", {
"WarehouseID": data.PurchaseOrderWarehouseID,
"WarehouseCode": data.WarehouseCode,
"WarehouseName": data.WarehouseName,
});
context.commit("update_dialogFormAct", 'EDIT');
context.dispatch("countItemTotal");
},
resetForm(context) {
context.commit("update_selectedDateForm", moment(new Date()).format('YYYY-MM-DD'));
context.commit("update_selectedSupplier", {});
context.commit("update_refNumber", '');
context.commit("update_taxPpn", 0);
context.commit("update_typePpnSelected", 'Percentage');
context.commit("update_taxPph", 0);
context.commit("update_paymentTerm", 0);
context.commit("update_discountType", 'Percentage');
context.commit("update_discountAmount", 0);
context.commit("update_note", '');
context.commit("update_warehouseType", 'Single');
context.commit("update_selectedWarehouse", context.state.defaultWarehouse);
context.commit("update_itemList", []);
context.commit("update_selectedItemTemp", []);
context.commit("update_selectedItem", []);
context.commit("update_deletedItem", []);
context.commit("update_selectedItemCategory", {});
context.commit("update_summary", []);
context.commit("update_searchItem", '');
context.commit("update_shippingCost", 0);
context.commit("update_shippingCostStatus", true);
context.commit("update_dialogFormAct", 'ADD');
context.commit("update_summaryTotal", {
total: 0,
tax: 0,
ppn: 0,
pph: 0,
discount: 0,
finalTotal: 0,
});
context.commit("update_itemTotal", {
total: 0,
tax: 0,
ppn: 0,
pph: 0,
discount: 0,
finalTotal: 0,
});
},
countItemTotal(context) {
let selectedItem = context.state.selectedItem;
if (selectedItem.length === 0) {
let hasil = {
total: 0,
tax: 0,
ppn: 0,
pph: 0,
discount: 0,
finalTotal: 0,
}
context.commit("update_itemTotal", hasil);
return;
}
// Fix: Ensure we're working with numeric values
let total = selectedItem.reduce((acc, item) => {
// Convert string to number if needed
const itemTotal = typeof item.Total === 'string' ?
parseFloat(item.Total.replace(/\./g, '').replace(',', '.')) :
item.Total;
return acc + (isNaN(itemTotal) ? 0 : itemTotal);
}, 0);
total = Math.round(total * 100) / 100;
let discount = parseFloat(context.state.discountAmount) || 0;
if (context.state.discountType === 'Percentage') {
discount = Math.round((discount / 100) * total * 100) / 100;
}
let newTotal = Math.round((total - discount) * 100) / 100;
let ppn = 0;
if (context.state.typePpnSelected === 'Absolute') {
ppn = context.state.taxPpn;
} else {
ppn = Math.round((parseFloat(context.state.taxPpn) / 100) * newTotal * 100) / 100;
}
let pph = Math.round((parseFloat(context.state.taxPph) / 100) * newTotal * 100) / 100;
let pajak = Math.round((ppn + pph) * 100) / 100;
let final = Math.round((newTotal + pajak) * 100) / 100;
let hasil = {
total: total,
tax: pajak,
ppn: ppn,
pph: pph,
discount: discount,
finalTotal: final,
}
context.commit("update_itemTotal", hasil);
},
updatePoQty(context, { itemId, newPoQty }) {
let updatedSelectedItem = context.state.selectedItem.map(item => {
if (item.PurchaseRequestFlagID === itemId) {
// Convert string to number and ensure minimum value of 1
const numericPoQty = Number(newPoQty);
item.PoQty = Math.max(1, Math.floor(isNaN(numericPoQty) ? 1 : numericPoQty));
// Recalculate item total
let price = item.DefaultPurchase?.SupplierPricePrice || 0;
// Apply discount if exists
if (item.discount > 0) {
if (item.discountType === 'P') {
price = price - (item.discount * price / 100);
} else if (item.discountType === 'R') {
price = price - item.discount;
}
}
item.Total = item.PoQty * price;
}
return item;
});
context.commit('update_selectedItem', updatedSelectedItem);
// Regenerate summary
context.dispatch('generateSummary');
context.dispatch('countItemTotal');
context.dispatch('generateSummaryTotal');
},
async getSupplier(context) {
if (context.state.searchSupplier.length < 2) return;
context.commit("update_loadingAutocomplete", true);
try {
var payload = {
token: one_token(),
search: context.state.searchSupplier,
};
let response = await api.getSupplier(payload);
if (response.status != "OK") {
let snackbar = {
state: true,
type: "error",
message: response.message,
}
context.commit("update_snackbar", snackbar);
context.commit("update_loadingAutocomplete", false);
} else {
let data = {
records: response.data.records,
total: response.data.total,
};
context.commit("update_supplierList", data.records);
context.commit("update_loadingAutocomplete", false);
}
} catch (e) {
let snackbar = {
state: true,
type: "error",
message: e.message,
}
context.commit("update_snackbar", snackbar);
context.commit("update_loadingAutocomplete", false);
}
},
async getItemCategory(context) {
context.commit("update_loadingAutocomplete", true);
try {
var payload = {
token: one_token(),
};
let response = await api.getItemCategory(payload);
if (response.status != "OK") {
let snackbar = {
state: true,
type: "error",
message: response.message,
}
context.commit("update_snackbar", snackbar);
context.commit("update_loadingAutocomplete", false);
} else {
let data = {
records: response.data.records,
total: response.data.total,
};
context.commit("update_itemCategoryList", data.records);
context.commit("update_loadingAutocomplete", false);
}
} catch (e) {
let snackbar = {
state: true,
type: "error",
message: e.message,
}
context.commit("update_snackbar", snackbar);
context.commit("update_loadingAutocomplete", false);
}
},
async getWarehouse(context) {
context.commit("update_loadingAutocomplete", true);
try {
var payload = {
regionalId: one_user().S_RegionalID,
token: one_token(),
};
let response = await api.getWarehouse(payload);
if (response.status != "OK") {
let snackbar = {
state: true,
type: "error",
message: response.message,
}
context.commit("update_snackbar", snackbar);
context.commit("update_loadingAutocomplete", false);
} else {
let data = {
records: response.data.records,
total: response.data.total,
};
response.data.records.forEach(element => {
if (element.WarehouseIsDefault === 'Y') {
context.commit("update_defaultWarehouse", element);
}
});
context.commit("update_warehouseList", response.data.records);
context.commit("update_loadingAutocomplete", false);
}
} catch (e) {
let snackbar = {
state: true,
type: "error",
message: e.message,
}
context.commit("update_snackbar", snackbar);
context.commit("update_loadingAutocomplete", false);
}
},
async getItem(context) {
context.commit("update_loading", true);
try {
var payload = {
"search": context.state.searchItem,
"currentPage": context.state.currentPageItem,
"supplierID": context.state.selectedSupplier.SupplierID,
"itemCategoryID": context.state.selectedItemCategory.itemCategoryID,
"regionalId": one_user().S_RegionalID,
"token": one_token(),
};
let response = await api.getItem(payload);
if (response.status != "OK") {
let snackbar = {
state: true,
type: "error",
message: response.message,
}
context.commit("update_snackbar", snackbar);
context.commit("update_loading", false);
} else {
let data = {
records: response.data.records,
total: response.data.totalPage,
};
context.commit("update_itemList", data.records);
context.commit("update_totalPageItem", data.total);
context.commit("update_loading", false);
}
} catch (e) {
let snackbar = {
state: true,
type: "error",
message: e.message,
}
context.commit("update_snackbar", snackbar);
context.commit("update_loading", false);
}
},
async getItemUpdate(context) {
context.commit("update_loading", true);
try {
var payload = {
"POID": context.state.selectedPO.PurchaseOrderID,
"token": one_token(),
};
let response = await api.getItemUpdate(payload);
if (response.status != "OK") {
let snackbar = {
state: true,
type: "error",
message: response.message,
}
context.commit("update_snackbar", snackbar);
context.commit("update_loading", false);
} else {
let data = {
records: response.data.records,
total: response.data.totalPage,
};
context.commit("update_selectedItem", data.records);
/**
* Tambah validasi:
* > Apakah bisa multiple warehouse?
*/
context.dispatch('isValidMultipleWarehouse');
context.commit("update_summary", response.data.summary)
context.dispatch("countItemTotal");
// Hitung summary total menggunakan fungsi dari functions.js
// TODO: Check ini akibat penyesuaian
const summaryTotal = calculateSummaryTotal(
response.data.summary,
context.state.typePpnSelected,
context.state.taxPpn,
context.state.taxPph,
context.state.discountType,
context.state.discountAmount
);
context.commit('update_summaryTotal', summaryTotal);
context.commit("update_loading", false);
}
} catch (e) {
let snackbar = {
state: true,
type: "error",
message: e.message,
}
context.commit("update_snackbar", snackbar);
context.commit("update_loading", false);
}
},
async saveOrder(context) {
try {
if (!validatePurchaseOrder(context)) {
return;
}
const invalidQtyItems = context.state.selectedItem.filter(item => {
// Convert string to number first
const poQty = Number(item.PoQty);
// Check if conversion failed (NaN), is less than 1, or not an integer
return isNaN(poQty) || poQty < 1 || !Number.isInteger(poQty);
});
if (invalidQtyItems.length > 0) {
let snackbar = {
state: true,
type: "error",
message: "Semua item harus memiliki quantity minimal 1",
}
context.commit("update_snackbar", snackbar);
return;
}
context.commit("update_loading", true);
// menambahkan pengecekan tax ppn 19-12-2025
// jika ppn persen maka masuk ke tax persentppn
// jika ppn absolute maka masuk ke tax amount ppn
let ppnPercent = 0;
if (context.state.typePpnSelected === 'Percentage') {
ppnPercent = context.state.taxPpn;
}
var payload = {
"token": one_token(),
"Date": context.state.selectedDateForm,
"RefNumber": context.state.refNumber,
"SupplierID": context.state.selectedSupplier.SupplierID,
"ItemCategoryID": context.state.selectedItemCategory.itemCategoryID,
"TaxPpnType": context.state.typePpnSelected === 'Percentage' ? 'P' : 'R',
"TaxPercent": ppnPercent,
"PaymentTerm": context.state.paymentTerm,
"DiscountPercent": context.state.discountType === 'Percentage' ? context.state.discountAmount : 0,
"DiscountAmount": context.state.discountType === 'Absolute' ? context.state.discountAmount : 0,
"WarehouseType": context.state.warehouseType,
"WarehouseID": context.state.selectedWarehouse.WarehouseID,
"Note": context.state.note,
"SubTotal": context.state.summaryTotal.total,
"TaxPercentPph": context.state.taxPph,
"TaxPercentPpn": ppnPercent,
"TaxAmount": context.state.summaryTotal.tax,
"TaxAmountPph": context.state.summaryTotal.pph,
"TaxAmountPpn": context.state.summaryTotal.ppn,
"GrandTotal": context.state.summaryTotal.finalTotal,
"ShippingCost": context.state.shippingCost,
"ShippingCostStatus": context.state.shippingCostStatus,
// "Details": detail,
"Summary": context.state.summary
};
// Validasi Total Tidak Boleh <0
const financialChecks = [
{ value: payload.GrandTotal, name: "Total" },
{ value: payload.SubTotal, name: "Sub Total" },
{ value: payload.TaxAmount, name: "Pajak" },
{ value: payload.TaxAmountPph, name: "Pajak PPH" },
{ value: payload.TaxAmountPpn, name: "Pajak PPN" },
{ value: payload.DiscountAmount, name: "Diskon" },
{ value: payload.ShippingCost, name: "Biaya Ekspedisi" }
];
for (const check of financialChecks) {
if (check.value < 0) {
let snackbar = {
state: true,
type: "error",
message: `${check.name} tidak boleh kurang dari 0`,
}
context.commit("update_snackbar", snackbar);
context.commit("update_loading", false);
return;
}
}
let response = await api.saveOrder(payload);
if (response.status != "OK") {
let snackbar = {
state: true,
type: "error",
message: response.message,
}
context.commit("update_snackbar", snackbar);
context.commit("update_loading", false);
} else {
let data = {
records: response.data.records,
total: response.data.total,
};
let snackbar = {
state: true,
type: "success",
message: "Berhasil simpan data",
}
context.commit("update_snackbar", snackbar);
context.commit("update_loading", false);
context.commit("update_dialogForm", false);
context.dispatch("resetForm");
context.dispatch("searchData");
}
} catch (e) {
let snackbar = {
state: true,
type: "error",
message: e.message,
}
context.commit("update_snackbar", snackbar);
context.commit("update_loading", false);
}
},
async searchData(context) {
context.commit("update_loading", true);
try {
var url_string = window.location.href
var url = new URL(url_string);
var status = url.searchParams.get("status");
var xstartdate = url.searchParams.get("startdate");
var xsearch = url.searchParams.get("search");
var xflag = url.searchParams.get("flag");
// untuk notifikasi
if (xflag == 'N') {
if (xsearch != null && xsearch != '') {
context.commit("update_search", xsearch);
}
if (status != null && status != '') {
context.commit("update_selectedStatus", { value: status, title: status });
}
if (xstartdate != null && xstartdate != '') {
context.commit("update_selectedDate", xstartdate);
context.commit("update_selectedEndDate", xstartdate);
}
} else if (xflag == 'G') {
// untuk get data param approve all
if (status != null && status != '') {
context.commit("update_selectedStatus", { value: status, title: status });
}
if (xstartdate != null && xstartdate != '') {
context.commit("update_selectedDate", xstartdate);
context.commit("update_selectedDateEnd", moment(new Date()).format('YYYY-MM-DD'));
}
context.commit("update_flag", xflag);
}
var payload = {
"token": one_token(),
"currentPage": context.state.selectedPage,
"search": context.state.search,
"startDate": context.state.selectedDate,
"endDate": context.state.selectedDateEnd,
"status": context.state.selectedStatus.value,
"flag": context.state.flag
};
let response = await api.search(payload);
if (response.status != "OK") {
let snackbar = {
state: true,
type: "error",
message: response.message,
}
context.commit("update_snackbar", snackbar);
context.commit("update_loading", false);
} else {
let data = {
records: response.data.records,
total: response.data.total,
};
context.commit("update_totalPage", response.data.totalPage);
context.commit("update_poList", data.records);
context.commit("update_loading", false);
}
} catch (e) {
let snackbar = {
state: true,
type: "error",
message: e.message,
}
context.commit("update_snackbar", snackbar);
context.commit("update_loading", false);
}
},
async requestOrder(context) {
context.commit("update_loading", true);
try {
var payload = {
"token": one_token(),
"ID": context.state.selectedPO.PurchaseOrderID,
};
let response = await api.requestOrder(payload);
if (response.status != "OK") {
let snackbar = {
state: true,
type: "error",
message: response.message,
}
context.commit("update_snackbar", snackbar);
context.commit("update_loading", false);
} else {
let data = {
records: response.data.records,
total: response.data.total,
};
let snackbar = {
state: true,
type: "success",
message: "Berhasil request order",
}
context.commit("update_snackbar", snackbar);
context.commit("update_loading", false);
context.commit("update_dialogConfirmation", false);
}
} catch (e) {
let snackbar = {
state: true,
type: "error",
message: e.message,
}
context.commit("update_snackbar", snackbar);
context.commit("update_loading", false);
}
},
async deleteOrder(context) {
context.commit("update_loading", true);
try {
var payload = {
"token": one_token(),
"PurchaseOrderId": context.state.selectedPO.PurchaseOrderID,
};
let response = await api.deleteOrder(payload);
if (response.status != "OK") {
let snackbar = {
state: true,
type: "error",
message: response.message,
}
context.commit("update_snackbar", snackbar);
context.commit("update_loading", false);
} else {
let data = {
records: response.data.records,
total: response.data.total,
};
let snackbar = {
state: true,
type: "success",
message: "Berhasil hapus order",
}
context.commit("update_snackbar", snackbar);
await context.dispatch("searchData");
context.commit("update_loading", false);
context.commit("update_dialogDelete", false);
}
} catch (e) {
let snackbar = {
state: true,
type: "error",
message: e.message,
}
context.commit("update_snackbar", snackbar);
context.commit("update_loading", false);
}
},
async updateOrder(context) {
try {
if (!validatePurchaseOrder(context)) {
return;
}
const invalidQtyItems = context.state.selectedItem.filter(item => {
// Convert string to number first
const poQty = Number(item.PoQty);
// Check if conversion failed (NaN), is less than 1, or not an integer
return isNaN(poQty) || poQty < 1 || !Number.isInteger(poQty);
});
console.log("InvalidQtyItem updateOrder", invalidQtyItems)
if (invalidQtyItems.length > 0) {
let snackbar = {
state: true,
type: "error",
message: "Semua item harus memiliki quantity minimal 1",
}
context.commit("update_snackbar", snackbar);
return;
}
// menambahkan pengecekan tax ppn 19-12-2025
// jika ppn persen maka masuk ke tax persentppn
// jika ppn absolute maka masuk ke tax amount ppn
let ppnPercent = 0;
if (context.state.typePpnSelected === 'Percentage') {
ppnPercent = context.state.taxPpn;
}
var payload = {
"token": one_token(),
"Date": context.state.selectedDateForm,
"RefNumber": context.state.refNumber,
"SupplierID": context.state.selectedSupplier.SupplierID,
"TaxPpnType": context.state.typePpnSelected === 'Percentage' ? 'P' : 'R',
"TaxPercent": ppnPercent,
"PaymentTerm": context.state.paymentTerm,
"ItemCategoryID": context.state.selectedItemCategory.itemCategoryID,
"DiscountPercent": context.state.discountType === 'Percentage' ? context.state.discountAmount : 0,
"DiscountAmount": context.state.discountType === 'Absolute' ? context.state.discountAmount : 0,
"WarehouseType": context.state.warehouseType,
"WarehouseID": context.state.selectedWarehouse.WarehouseID,
"Note": context.state.note,
"SubTotal": context.state.summaryTotal.total,
"TaxPercentPph": context.state.taxPph,
"TaxPercentPpn": ppnPercent,
"TaxAmount": context.state.summaryTotal.tax,
"TaxAmountPph": context.state.summaryTotal.pph,
"TaxAmountPpn": context.state.summaryTotal.ppn,
"GrandTotal": context.state.summaryTotal.finalTotal,
"ShippingCost": context.state.shippingCost,
"ShippingCostStatus": context.state.shippingCostStatus,
"PO": context.state.selectedPO,
"Summary": context.state.summary,
"deletedItem": context.state.deletedItem,
"IsApprovalEdit": true,
};
// Validasi Total Tidak Boleh <0
const financialChecks = [
{ value: payload.GrandTotal, name: "Total" },
{ value: payload.SubTotal, name: "Sub Total" },
{ value: payload.TaxAmount, name: "Pajak" },
{ value: payload.TaxAmountPph, name: "Pajak PPH" },
{ value: payload.TaxAmountPpn, name: "Pajak PPN" },
{ value: payload.DiscountAmount, name: "Diskon" },
{ value: payload.ShippingCost, name: "Biaya Ekspedisi" }
];
for (const check of financialChecks) {
if (check.value < 0) {
let snackbar = {
state: true,
type: "error",
message: `${check.name} tidak boleh kurang dari 0`,
}
context.commit("update_snackbar", snackbar);
context.commit("update_loading", false);
return;
}
}
context.commit("update_loading", true);
let response = await api.updateOrder(payload);
if (response.status != "OK") {
let snackbar = {
state: true,
type: "error",
message: response.message,
}
context.commit("update_snackbar", snackbar);
context.commit("update_loading", false);
} else {
let data = {
records: response.data.records,
total: response.data.total,
};
let snackbar = {
state: true,
type: "success",
message: "Berhasil simpan data",
}
context.commit("update_snackbar", snackbar);
context.commit("update_loading", false);
context.commit("update_dialogForm", false);
context.dispatch("resetForm");
context.dispatch("searchData");
}
} catch (e) {
let snackbar = {
state: true,
type: "error",
message: e.message,
}
context.commit("update_snackbar", snackbar);
context.commit("update_loading", false);
}
},
async approveOrder(context, payload) {
context.commit("update_loading", true);
try {
payload.token = one_token()
payload.approvelevel = context.state.approve_level
let response = await api.approvePOrder(payload);
if (response.status != 'OK') {
let snackbar = {
state: true,
type: "error",
message: response.message,
}
context.commit("update_snackbar", snackbar);
context.commit("update_loading", false);
} else {
if (context.state.approve_level == '2') {
let params = { token: one_token(), id: payload.poID }
let generateitempo = await api.generateItemPO(params)
if (generateitempo.status != 'OK') {
let snackbar = {
state: true,
type: "error",
message: response.message,
}
context.commit("update_snackbar", snackbar);
context.commit("update_loading", false);
} else {
let snackbar = {
state: true,
type: "success",
message: "Berhasil approve order",
}
context.commit("update_snackbar", snackbar);
await context.dispatch("searchData");
context.commit("update_loading", false);
}
} else {
let snackbar = {
state: true,
type: "success",
message: "Berhasil approve order manager",
}
context.commit("update_snackbar", snackbar);
await context.dispatch("searchData");
context.commit("update_loading", false);
}
}
} catch (e) {
let snackbar = {
state: true,
type: "error",
message: e.message,
}
context.commit("update_snackbar", snackbar);
context.commit("update_loading", false);
}
},
async getApprovalLevel(context) {
context.commit("update_loading", true);
try {
let response = await api.getApprovalLevel({token: one_token()});
if (response.status != 'OK') {
let snackbar = {
state: true,
type: "error",
message: response.message,
}
context.commit("update_snackbar", snackbar);
context.commit("update_loading", false);
} else {
let data = response.data.M_UserM_ApproveLevelID
context.commit("update_approve_level", data)
}
} catch (e) {
let snackbar = {
state: true,
type: "error",
message: e.message,
}
context.commit("update_snackbar", snackbar);
context.commit("update_loading", false);
}
},
async getDefaultSupplierPrice(context, payload) {
context.commit("update_loading", true);
try {
payload.token = one_token()
payload.supplierID = context.state.selectedSupplier.SupplierID
let response = await api.getDefaultSupplierPrice(payload);
if (response.status != "OK") {
let snackbar = {
state: true,
type: "error",
message: response.message,
}
context.commit("update_snackbar", snackbar);
context.commit("update_loading", false);
} else {
let data = {
records: response.data.records,
};
context.commit("update_loading", false);
return data.records;
}
} catch (e) {
let snackbar = {
state: true,
type: "error",
message: e.message,
}
context.commit("update_snackbar", snackbar);
context.commit("update_loading", false);
}
},
},
};