Files
fe-accone/test/vuex/acc-one-purchase-order-v2/components/poForm_bckp.vue

1762 lines
58 KiB
Vue

<template>
<div>
<v-dialog v-model="dialogItem" persistent width="800">
<v-card>
<v-card-title class="headline grey lighten-2" primary-title>
TAMBAH ITEM
</v-card-title>
<v-card-text>
<v-text-field
v-model="searchItem"
label="Cari Item"
class="mb-2"
outline
hide-details
>
</v-text-field>
<v-data-table
v-model="selectedItemTemp"
:headers="HeadersItem"
:items="itemList"
:loading="loading"
hide-actions
select-all
item-key="PurchaseRequestFlagID"
class="elevation-1"
>
<template v-slot:headers="props">
<tr>
<th width="15%" class="blue lighten-3 white--text">
<v-checkbox
:input-value="props.all"
:indeterminate="props.indeterminate"
primary
hide-details
></v-checkbox>
<!-- @click.stop="toggleAll" -->
</th>
<!-- :class="['column sortable', pagination.descending ? 'desc' : 'asc', header.value === pagination.sortBy ? 'active' : '']"
@click="changeSort(header.value)" -->
<th
v-for="header in props.headers"
:key="header.text"
:width="header.width"
:class="header.class"
>
<!-- <v-icon small>arrow_upward</v-icon> -->
{{ header.text }}
</th>
</tr>
</template>
<template v-slot:items="props">
<tr
:active="props.selected"
@click="props.selected = !props.selected"
>
<td>
<v-checkbox
:input-value="props.selected"
primary
hide-details
></v-checkbox>
</td>
<td>{{ props.item.PurchaseRequestNumber }}</td>
<td>{{ props.item.M_ItemCode }}</td>
<td class="">{{ props.item.M_ItemDesc }}</td>
<td class="">
{{ props.item.M_BranchName ?? props.item.S_RegionalName }}
</td>
<td class="text-xs-center">
{{ props.item.FlagQty }} {{ props.item.ItemUnitName }}
</td>
</tr>
</template>
</v-data-table>
<v-card class="text-xs-left pa-2 mb-3">
<v-pagination
v-model="currentPageItem"
:length="totalPageItem"
></v-pagination>
<p
style="font-weight: bold;"
class="subheader"
v-if="deletedItem.length > 0"
>
ITEM YANG SEBELUMNYA DIHAPUS
</p>
<v-data-table
v-model="selectedItemTemp"
:headers="HeadersItem"
v-if="deletedItem.length > 0"
:items="deletedItem"
:loading="loading"
hide-actions
select-all
item-key="PurchaseRequestFlagID"
class="elevation-1"
>
<template v-slot:headers="props">
<tr>
<th width="15%" class="blue lighten-3 white--text">
<v-checkbox
:input-value="props.all"
:indeterminate="props.indeterminate"
primary
hide-details
></v-checkbox>
<!-- @click.stop="toggleAll" -->
</th>
<!-- :class="['column sortable', pagination.descending ? 'desc' : 'asc', header.value === pagination.sortBy ? 'active' : '']"
@click="changeSort(header.value)" -->
<th
v-for="header in props.headers"
:key="header.text"
:width="header.width"
:class="header.class"
>
<!-- <v-icon small>arrow_upward</v-icon> -->
{{ header.text }}
</th>
</tr>
</template>
<template v-slot:items="props">
<tr
:active="props.selected"
@click="props.selected = !props.selected"
>
<td>
<v-checkbox
:input-value="props.selected"
primary
hide-details
></v-checkbox>
</td>
<td>{{ props.item.M_ItemCode }}</td>
<td class="">{{ props.item.M_ItemDesc }}</td>
<td class="">
{{ props.item.M_BranchName ?? props.item.S_RegionalName }}
</td>
<td class="text-xs-center">
{{ props.item.FlagQty }} {{ props.item.ItemUnitName }}
</td>
</tr>
</template>
</v-data-table>
</v-card>
</v-card-text>
<v-divider></v-divider>
<v-card-actions>
<v-spacer></v-spacer>
<v-btn color="error" flat @click="dialogItem = false">
Tutup
</v-btn>
<v-btn color="green" flat @click="addItem()">
Tambahkan
</v-btn>
</v-card-actions>
</v-card>
</v-dialog>
<v-dialog v-model="dialogForm" persistent width="98vw">
<v-card>
<v-card-title class="headline grey lighten-2" primary-title>
FORM PURCHASE ORDER
<v-spacer></v-spacer>
<div v-if="dialogFormAct === 'EDIT'">
<kbd>{{ selectedPO.PurchaseOrderNumber ?? "" }}</kbd>
</div>
</v-card-title>
<v-progress-linear
:indeterminate="true"
v-if="loading"
></v-progress-linear>
<v-card-text>
<v-layout row wrap class="px-2 py-2">
<v-flex xs6>
<v-menu
v-model="menuselectedDateForm"
:close-on-content-click="false"
transition="scale-transition"
:nudge-right="40"
lazy
offset-y
max-width="290px"
min-width="290px"
>
<template v-slot:activator="{ on }">
<v-text-field
:value="selectedDateFormFormatted"
label="Tanggal"
readonly
:readonly="loading"
hide-details
class="mr-2"
outline
hide-details
v-on="on"
></v-text-field>
</template>
<v-date-picker
no-title
hide-details
v-model="selectedDateForm"
@input="menuselectedDateForm = false"
></v-date-picker>
</v-menu>
</v-flex>
<v-flex xs6>
<v-text-field
v-model="refNumber"
label="Nomor Referensi"
class="mr-2"
:readonly="loading"
outline
hide-details
>
</v-text-field>
</v-flex>
<v-flex xs3>
<v-text-field
type="number"
v-model="taxPpn"
label="Pajak Pendapatan (PPN)"
class="mr-2"
:readonly="loading"
outline
suffix="%"
hide-details
>
</v-text-field>
</v-flex>
<v-flex xs3>
<v-text-field
type="number"
v-model="taxPph"
label="Pajak Penghasilan (PPH)"
class="mr-2"
outline
:readonly="loading"
suffix="%"
hide-details
>
</v-text-field>
</v-flex>
<v-flex xs3>
<v-autocomplete
v-model="selectedSupplier"
:loading="loadingAutocomplete"
:items="supplierList"
:search-input.sync="searchSupplier"
cache-items
class="mr-2"
return-object
:readonly="loading"
item-text="SupplierName"
flat
hide-no-data
hide-details
label="Vendor"
outline
></v-autocomplete>
</v-flex>
<v-flex xs3>
<v-autocomplete
v-model="selectedItemCategory"
:loading="loadingAutocomplete"
:items="itemCategoryList"
cache-items
class="mr-2"
return-object
:readonly="loading"
:disabled="selectedItem.length > 0 "
item-text="itemCategoryName"
flat
hide-no-data
hide-details
label="Kategori Item"
outline
></v-autocomplete>
</v-flex>
<v-flex xs6>
<v-text-field
type="number"
v-model="paymentTerm"
:readonly="loading"
label="Jangka Waktu Pembayaran"
class="mr-2 mt-3"
outline
suffix="Hari"
hide-details
>
</v-text-field>
</v-flex>
<v-flex xs2>
<v-select
:items="discountTypeList"
label="Tipe Diskon"
hide-details
:readonly="loading"
class="mini-select mr-2 mt-3"
v-model="discountType"
outline
></v-select>
</v-flex>
<v-flex xs4>
<!-- <v-text-field
type="number"
v-model="discountAmount"
label="Diskon"
:readonly="loading"
class="mt-3"
outline
hide-details
>
<template v-slot:append-outer>
<div>
{{
discountType === "Absolute"
? oneMoney(discountAmount)
: ""
}}
</div>
</template>
</v-text-field> -->
<v-text-field
:prefix="discountType === 'Absolute' ? 'Rp' : ''"
:suffix="discountType === 'Percentage' ? '%' : ''"
:type="discountType === 'Absolute' ? 'text' : 'number'"
v-model="formattedDiscountAmount"
:label="discountType === 'Percentage' ? 'Diskon' : ''"
:readonly="loading"
class="mt-3"
outline
hide-details
>
</v-text-field>
<!-- :hint="discountType === 'Absolute' ? oneMoney(props.item.Price):''" -->
</v-flex>
<v-flex xs3>
<v-select
:items="warehouseTypeList"
label="Tipe Gudang"
:readonly="selectedItem.length > 0 && loading"
class="mini-select mr-2 mt-3"
v-model="warehouseType"
outline
></v-select>
</v-flex>
<v-flex xs3>
<v-autocomplete
v-model="selectedWarehouse"
:loading="loadingAutocomplete"
:items="warehouseList"
return-object
:readonly="loading"
label="Gudang"
:readonly="warehouseType === 'Single'"
class="mini-select mr-2 mt-3"
item-text="WarehouseName"
flat
outline
hide-no-data
hide-details
></v-autocomplete>
</v-flex>
<v-flex xs4>
<v-text-field
prefix="Rp"
v-model="formattedShippingCost"
label="Biaya Ekspedisi"
:readonly="loading"
class="mr-2 mt-3"
outline
hide-details
>
</v-text-field>
<!-- <v-text-field
type="number"
v-model="shippingCost"
label="Biaya Ekspedisi"
:readonly="loading"
class="mr-2 mt-3"
outline
hide-details
>
<template v-slot:append-outer>
<div>
{{ oneMoney(shippingCost) }}
</div>
</template>
</v-text-field> -->
<!-- :hint="discountType === 'Absolute' ? oneMoney(props.item.Price):''" -->
</v-flex>
<v-flex xs2 class="text-xs-center">
<v-checkbox
v-model="shippingCostStatus"
class="mr-2 mt-3"
label="Biaya ekspedisi di bayar di muka"
:readonly="loading"
hide-details
></v-checkbox>
<!-- :hint="discountType === 'Absolute' ? oneMoney(props.item.Price):''" -->
</v-flex>
<!-- <v-flex xs6>
<v-autocomplete
v-model="selectedWarehouse"
:loading="loadingAutocomplete"
:items="warehouseList"
cache-items
class="mr-2 mt-3"
return-object
item-text="WarehouseName"
flat
hide-no-data
hide-details
label="Gudang"
outline
></v-autocomplete>
</v-flex> -->
<v-flex xs12>
<v-textarea
outline
v-model="note"
auto-grow
hide-details
:readonly="loading"
rows="2"
label="Keterangan"
></v-textarea>
<v-divider class="my-3"></v-divider>
</v-flex>
<v-flex xs9 class="mb-3">
<!-- <v-autocomplete
v-model="selectedItemTemp"
:loading="loadingAutocomplete"
:items="itemList"
:search-input.sync="searchItem"
class="mr-2"
return-object
item-text="M_ItemDesc"
flat
return-object
hide-no-data
hide-details
label="Cari Item"
outline
></v-autocomplete> -->
</v-flex>
<v-flex xs3 class="mb-3">
<v-btn
block
color="info"
:disabled="isObjectEmpty(selectedSupplier) || isObjectEmpty(selectedItemCategory)"
@click="openDialogAddItem()"
>TAMBAHKAN ITEM</v-btn
>
</v-flex>
<v-flex xs12>
<!-- <v-data-table
v-if="selectedItem.length > 0"
:headers="headers"
:items="selectedItem"
:loading="loading"
hide-actions
class="elevation-1"
>
<template v-slot:items="props">
<td class="">{{ props.item.M_ItemCode }}</td>
<td class="">{{ props.item.M_ItemDesc }}</td>
<td class="">
<div v-if="warehouseType === 'Single'">
{{ props.item.warehouse.WarehouseName }}
</div>
<div v-if="warehouseType === 'Multiple'">
<v-autocomplete
v-model="props.item.warehouse"
:loading="loadingAutocomplete"
:items="warehouseList"
return-object
item-text="WarehouseName"
solo
hide-no-data
hide-details
></v-autocomplete>
</div>
</td>
<td class="text-xs-center">{{ props.item.ItemUnitName }}</td>
<td class="text-xs-center">{{ props.item.FlagQty }}</td>
<td class="text-xs-center">
<v-text-field
type="number"
v-model="props.item.PoQty"
class="mr-2 mt-3"
solo
@change="handleChangeQty(props.item)"
hide-details
>
</v-text-field>
</td>
<td class="text-xs-right">
{{ oneMoney(props.item.Price) }}
</td>
<td class="text-xs-right">
{{ oneMoney(props.item.Total) }}
</td>
<td class="text-xs-center">
<v-btn
icon
small
@click="deleteItem(props.item.PurchaseRequestFlagID)"
>
<v-icon color="red">delete</v-icon>
</v-btn>
</td>
</template>
</v-data-table> -->
<!-- <v-divider class="my-3" v-if="summary.length > 0"></v-divider>
<p
v-if="summary.length > 0"
style="font-weight: bold;"
class="text-xs-center mb-3"
>
SUMMARY
</p> -->
<v-data-table
v-if="summary.length > 0"
:headers="summaryHeaders"
:items="summary"
:loading="loading"
hide-actions
class="elevation-1 mt-4"
expand
item-key="keyID"
>
<template slot="items" slot-scope="props">
<tr>
<td
class="text-xs-center"
@click="props.expanded = !props.expanded"
>
<v-icon>{{
props.expanded
? "keyboard_arrow_down"
: "keyboard_arrow_right"
}}</v-icon>
</td>
<td class="" @click="props.expanded = !props.expanded">
<kbd>{{ props.item.M_ItemCode }}</kbd>
{{ props.item.M_ItemDesc }}
</td>
<td
class="text-xs-center"
@click="props.expanded = !props.expanded"
>
{{ props.item.PoQty }}
{{ props.item.ItemUnitName }}
</td>
<td
class="text-xs-right"
@click="props.expanded = !props.expanded"
>
{{ oneMoney(props.item.RealPrice) }}
</td>
<td class="text-xs-right">
<div>
<v-text-field
:messages="oneMoney(getDiscountAmountSummaryPerItem(props.item))"
@input="handleChangeDiscountPerItemSummary(props.item)"
v-model="props.item.discount"
type="number"
solo
>
<template v-slot:prepend>
<v-menu offset-y>
<template v-slot:activator="{ on }">
<v-btn small color="primary" dark v-on="on">
<div v-if="props.item.discountType =='R'">
Rp
</div>
<div v-if="props.item.discountType =='P'">
%
</div>
</v-btn>
</template>
<v-list>
<v-list-tile
@click="handleChangeDiscountSummary('R', props.item)"
>
<v-list-tile-title>Rupiah</v-list-tile-title>
</v-list-tile>
<v-list-tile
@click="handleChangeDiscountSummary('P', props.item)"
>
<v-list-tile-title>Percent</v-list-tile-title>
</v-list-tile>
</v-list>
</v-menu>
</template>
</v-text-field>
</div>
</td>
<td
class="text-xs-right"
@click="props.expanded = !props.expanded"
>
{{ oneMoney(props.item.Price) }}
</td>
<td
class="text-xs-right"
@click="props.expanded = !props.expanded"
>
{{ oneMoney(props.item.Total) }}
</td>
<td class="text-xs-right">
<v-btn
icon
small
:disabled="loading"
@click="deleteEntireItem(props.item.keyID)"
>
<!-- @click="tryDeleteItem(props.item, 'S')" -->
<v-icon color="red">delete</v-icon>
</v-btn>
</td>
</tr>
</template>
<template slot="expand" slot-scope="props">
<v-card flat>
<v-card-text class="pl-3">
<div class="ml-3 mb-3">
<v-data-table
:headers="detailHeaders"
:items="props.item.Details"
hide-actions
class="elevation-0"
>
<template slot="items" slot-scope="detailProps">
<td class="">
<kbd>{{ detailProps.item.M_ItemCode }}</kbd>
{{ detailProps.item.M_ItemDesc }}
</td>
<td class="">
{{
detailProps.item.M_BranchName ??
detailProps.item.S_RegionalName
}}
</td>
<td class="py-1">
<div v-if="warehouseType === 'Single'">
{{ detailProps.item.warehouse.WarehouseName }}
</div>
<div v-if="warehouseType === 'Multiple'">
<v-autocomplete
:disabled="loading"
v-model="detailProps.item.warehouse"
:loading="loadingAutocomplete"
:items="warehouseList"
return-object
item-text="WarehouseName"
solo
hide-no-data
hide-details
></v-autocomplete>
</div>
</td>
<!-- <td class="text-xs-center">
{{ detailProps.item.ItemUnitName }}
</td> -->
<td class="text-xs-center">
{{ detailProps.item.PoQty }}
{{ detailProps.item.ItemUnitName }}
</td>
<td class="text-xs-center">
<v-btn
icon
small
:disabled="loading"
@click="deleteItem(detailProps.item.PurchaseRequestFlagID)"
>
<!-- @click="tryDeleteItem(detailProps.item,'i')" -->
<v-icon color="red">delete</v-icon>
</v-btn>
</td>
</template>
</v-data-table>
</div>
</v-card-text>
</v-card>
</template>
<template v-slot:footer>
<tr>
<td :colspan="4">
<strong class="ml-2">JUMLAH</strong>
</td>
<td :colspan="3" class="text-xs-right">
<strong>{{ oneMoney(summaryTotal.total) }}</strong>
</td>
</tr>
<tr>
<td :colspan="4">
<strong class="ml-2">DISKON</strong>
</td>
<td :colspan="3" class="text-xs-right">
<strong>{{ oneMoney(summaryTotal.discount) }}</strong>
</td>
</tr>
<tr>
<td :colspan="4">
<strong class="ml-5"
>PAJAK PENDAPATAN(PPN) {{ taxPpn }}%</strong
>
</td>
<td :colspan="3" class="text-xs-right">
<strong>{{ oneMoney(summaryTotal.ppn) }}</strong>
</td>
</tr>
<tr>
<td :colspan="4">
<strong class="ml-5"
>PAJAK PENGHASILAN(PPH) {{ taxPph }}%</strong
>
</td>
<td :colspan="3" class="text-xs-right">
<strong>{{ oneMoney(summaryTotal.pph) }}</strong>
</td>
</tr>
<tr>
<td :colspan="4">
<strong class="ml-2">PAJAK</strong>
</td>
<td :colspan="3" class="text-xs-right">
<strong>{{ oneMoney(summaryTotal.tax) }}</strong>
</td>
</tr>
<tr>
<td :colspan="4">
<strong>TOTAL</strong>
</td>
<td :colspan="3" class="text-xs-right">
<strong>{{
oneMoney(summaryTotal.finalTotal)
}}</strong>
</td>
</tr>
</template>
</v-data-table>
</v-flex>
</v-layout>
</v-card-text>
<v-divider v-if="!loading"></v-divider>
<v-progress-linear
:indeterminate="true"
v-if="loading"
></v-progress-linear>
<v-card-actions>
<v-spacer></v-spacer>
<v-btn
color="error"
:disabled="loading"
flat
@click="dialogForm = false"
>
BATAL
</v-btn>
<v-btn color="green" :disabled="loading" flat @click="saveOrder()">
SIMPAN
</v-btn>
</v-card-actions>
</v-card>
</v-dialog>
</div>
</template>
<style scoped>
.date-type-table {
display: flex;
flex-direction: column;
gap: 0.5rem;
}
.flex-items-center {
display: flex;
align-items: center;
gap: 0.25rem;
}
.table.v-table tbody td,
.table.v-table tbody tr {
height: 40px;
}
.table.v-table thead tr {
height: 40px;
}
</style>
<script>
module.exports = {
components: {},
data() {
return {
menuselectedDateForm: false,
msgAlertDeleteOrReject: "",
dialogAlertRejectRequest: false,
dialogAlertDeleteDetail: false,
amountRules: [(v) => v >= 0 || "Jumlah harus diisi"],
validationDetail: false,
detailHeaders: [
// {
// text: "KODE ITEM",
// align: "center",
// sortable: false,
// value: "M_ItemCode",
// width: "15%",
// class: "blue lighten-4 black--text",
// },
{
text: "NAMA PRODUK",
align: "center",
sortable: false,
value: "M_ItemDesc",
width: "20%",
class: "blue lighten-4 black--text",
},
{
text: "PR Number",
align: "center",
sortable: false,
value: "M_ItemDesc",
width: "10%",
class: "blue lighten-4 black--text",
},
{
text: "CABANG",
align: "center",
sortable: false,
value: "M_BranchName",
width: "20%",
class: "blue lighten-4 black--text",
},
{
text: "GUDANG",
align: "center",
sortable: false,
value: "M_BranchName",
width: "30%",
class: "blue lighten-4 black--text",
},
// {
// text: "UNIT",
// align: "center",
// sortable: false,
// value: "ItemUnitName",
// width: "10%",
// class: "blue lighten-4 black--text",
// },
{
text: "QTY",
align: "center",
sortable: false,
value: "PoQty",
width: "15%",
class: "blue lighten-4 black--text",
},
{
text: "AKSI",
align: "center",
sortable: false,
value: "PoQty",
width: "5%",
class: "blue lighten-4 black--text",
},
],
summaryHeaders: [
{
text: "",
align: "center",
sortable: false,
value: "expand",
width: "5%",
class: "blue lighten-3 white--text",
},
{
text: "ITEM",
align: "center",
sortable: false,
value: "M_ItemCode",
width: "10%",
class: "blue lighten-3 white--text",
},
{
text: "QTY",
align: "center",
sortable: false,
value: "PoQty",
width: "10%",
class: "blue lighten-3 white--text",
},
{
text: "HARGA",
align: "center",
sortable: false,
value: "price",
width: "15%",
class: "blue lighten-3 white--text",
},
{
text: "DISKON",
align: "center",
sortable: false,
value: "price",
width: "20%",
class: "blue lighten-3 white--text",
},
{
text: "HARGA SETELAH DISKON",
align: "center",
sortable: false,
value: "price",
width: "15%",
class: "blue lighten-3 white--text",
},
{
text: "TOTAL",
align: "center",
sortable: false,
value: "Total",
width: "20%",
class: "blue lighten-3 white--text",
},
{
text: "AKSI",
align: "center",
sortable: false,
value: "Total",
width: "5%",
class: "blue lighten-3 white--text",
},
],
headers: [
{
text: "NO ITEM",
align: "center",
sortable: false,
value: "no",
width: "5%",
class: "blue lighten-3 white--text",
},
{
text: "NAMA PRODUK",
align: "center",
sortable: false,
value: "no",
width: "15%",
class: "blue lighten-3 white--text",
},
{
text: "GUDANG",
align: "center",
sortable: false,
value: "no",
width: "15%",
class: "blue lighten-3 white--text",
},
{
text: "UNIT",
align: "center",
sortable: false,
value: "no",
width: "10%",
class: "blue lighten-3 white--text",
},
{
text: "QTY",
align: "center",
sortable: false,
value: "no",
width: "10%",
class: "blue lighten-3 white--text",
},
{
text: "PO QTY",
align: "center",
sortable: false,
value: "no",
width: "15%",
class: "blue lighten-3 white--text",
},
{
text: "Harga",
align: "center",
sortable: false,
value: "no",
width: "10%",
class: "blue lighten-3 white--text",
},
{
text: "TOTAL",
align: "center",
sortable: false,
value: "no",
width: "15%",
class: "blue lighten-3 white--text",
},
{
text: "AKSI",
align: "center",
sortable: false,
value: "no",
width: "5%",
class: "blue lighten-3 white--text",
},
],
HeadersItem: [
{
text: "No PurchaseReq",
align: "center",
sortable: false,
value: "no",
width: "15%",
class: "blue lighten-3 white--text",
},
{
text: "KODE ITEM",
align: "center",
sortable: false,
value: "no",
width: "15%",
class: "blue lighten-3 white--text",
},
{
text: "NAMA ITEM",
align: "left",
sortable: false,
value: "requestDate",
width: "35%",
class: "blue lighten-3 white--text",
},
{
text: "CABANG",
align: "left",
sortable: false,
value: "requestDate",
width: "20%",
class: "blue lighten-3 white--text",
},
{
text: "QTY",
align: "left",
sortable: false,
value: "requestDate",
width: "15%",
class: "blue lighten-3 white--text",
},
],
};
},
mounted() {
this.$store.dispatch("po/getWarehouse");
},
computed: {
formattedDiscountAmount: {
get() {
if (this.discountType === 'Absolute') {
return this.oneMoney(this.discountAmount); // Format angka dengan titik
} else {
return this.discountAmount?.toString() || '';
}
},
set(value) {
if (this.discountType === 'Absolute') {
const raw = value.replace(/\./g, '').replace(',', '.');
this.discountAmount = parseFloat(raw) || 0;
} else {
this.discountAmount = parseFloat(value) || 0;
}
}
},
formattedShippingCost: {
get() {
return this.oneMoney(this.shippingCost);
},
set(value) {
// Hilangkan titik dan koma, ubah jadi number
let raw = value.replace(/\./g, '').replace(',', '.');
this.shippingCost = parseFloat(raw) || 0;
}
},
selectedPO() {
return this.$store.state.po.selectedPO;
},
statusOptions() {
return this.$store.state.prkacab.statusOptions;
},
dialogFormAct() {
return this.$store.state.po.dialogFormAct;
},
totalPageItem: {
get() {
return this.$store.state.po.totalPageItem;
},
set(val) {
this.$store.commit("po/update_totalPageItem", val);
},
},
shippingCost: {
get() {
return this.$store.state.po.shippingCost;
},
set(val) {
this.$store.commit("po/update_shippingCost", val);
},
},
shippingCostStatus: {
get() {
return this.$store.state.po.shippingCostStatus;
},
set(val) {
this.$store.commit("po/update_shippingCostStatus", val);
},
},
currentPageItem: {
get() {
return this.$store.state.po.currentPageItem;
},
set(val) {
this.$store.commit("po/update_currentPageItem", val);
this.$store.dispatch("po/getItem");
},
},
dialogItem: {
get() {
return this.$store.state.po.dialogItem;
},
set(val) {
this.$store.commit("po/update_dialogItem", val);
},
},
itemTotal: {
get() {
return this.$store.state.po.itemTotal;
},
set(val) {
this.$store.commit("po/update_itemTotal", val);
},
},
searchItem: {
get() {
return this.$store.state.po.searchItem;
},
set(val) {
this.$store.commit("po/update_searchItem", val);
},
},
selectedItem: {
get() {
return this.$store.state.po.selectedItem;
},
set(val) {
this.$store.commit("po/update_selectedItem", val);
},
},
deletedItem: {
get() {
return this.$store.state.po.deletedItem;
},
set(val) {
this.$store.commit("po/update_deletedItem", val);
},
},
itemList: {
get() {
return this.$store.state.po.itemList;
},
set(val) {
this.$store.commit("po/update_itemList", val);
},
},
warehouseList: {
get() {
return this.$store.state.po.warehouseList;
},
set(val) {
this.$store.commit("po/update_warehouseList", val);
},
},
selectedWarehouse: {
get() {
return this.$store.state.po.selectedWarehouse;
},
set(val) {
this.$store.commit("po/update_selectedWarehouse", val);
if (this.warehouseType === "Single") {
// this.$store.dispatch("po/generateSummary");
this.changeWarehouse();
}
},
},
warehouseTypeList: {
get() {
return this.$store.state.po.warehouseTypeList;
},
set(val) {
this.$store.commit("po/update_warehouseTypeList", val);
},
},
warehouseType: {
get() {
return this.$store.state.po.warehouseType;
},
set(val) {
this.$store.commit("po/update_warehouseType", val);
},
},
note: {
get() {
return this.$store.state.po.note;
},
set(val) {
this.$store.commit("po/update_note", val);
},
},
loadingAutocomplete: {
get() {
return this.$store.state.po.loadingAutocomplete;
},
set(val) {
this.$store.commit("po/update_loadingAutocomplete", val);
},
},
selectedSupplier: {
get() {
return this.$store.state.po.selectedSupplier;
},
set(val) {
this.$store.commit("po/update_selectedSupplier", val);
},
},
supplierList: {
get() {
return this.$store.state.po.supplierList;
},
set(val) {
this.$store.commit("po/update_supplierList", val);
},
},
searchSupplier: {
get() {
return this.$store.state.po.searchSupplier;
},
set(val) {
this.$store.commit("po/update_searchSupplier", val);
},
},
discountAmount: {
get() {
return this.$store.state.po.discountAmount;
},
set(val) {
this.$store.commit("po/update_discountAmount", val);
this.$store.dispatch("po/countItemTotal");
this.$store.dispatch("po/generateSummaryTotal");
},
},
discountTypeList: {
get() {
return this.$store.state.po.discountTypeList;
},
set(val) {
this.$store.commit("po/update_discountTypeList", val);
},
},
discountType: {
get() {
return this.$store.state.po.discountType;
},
set(val) {
this.$store.commit("po/update_discountType", val);
this.$store.dispatch("po/countItemTotal");
this.$store.dispatch("po/generateSummary");
},
},
paymentTerm: {
get() {
return this.$store.state.po.paymentTerm;
},
set(val) {
this.$store.commit("po/update_paymentTerm", val);
},
},
taxPpn: {
get() {
return this.$store.state.po.taxPpn;
},
set(val) {
this.$store.commit("po/update_taxPpn", val);
this.$store.dispatch("po/countItemTotal");
this.$store.dispatch("po/generateSummaryTotal");
},
},
taxPph: {
get() {
return this.$store.state.po.taxPph;
},
set(val) {
this.$store.commit("po/update_taxPph", val);
this.$store.dispatch("po/countItemTotal");
this.$store.dispatch("po/generateSummaryTotal");
},
},
refNumber: {
get() {
return this.$store.state.po.refNumber;
},
set(val) {
this.$store.commit("po/update_refNumber", val);
},
},
selectedDateForm: {
get() {
return this.$store.state.po.selectedDateForm;
},
set(val) {
this.$store.commit("po/update_selectedDateForm", val);
},
},
selectedDateFormFormatted() {
return this.formatDate(this.selectedDateForm);
},
endDateFormatted() {
return this.formatDate(this.fEndDate);
},
poList() {
return this.$store.state.po.poList;
},
selectedItemTemp: {
get() {
return this.$store.state.po.selectedItemTemp;
},
set(val) {
this.$store.commit("po/update_selectedItemTemp", val);
},
},
loading: {
get() {
return this.$store.state.po.loading;
},
set(val) {
this.$store.commit("po/update_loading", val);
},
},
dialogForm: {
get() {
return this.$store.state.po.dialogForm;
},
set(val) {
this.$store.commit("po/update_dialogForm", val);
},
},
snackbar: {
get() {
return this.$store.state.po.snackbar;
},
set(val) {
this.$store.commit("po/update_snackbar", val);
},
},
defaultWarehouse: {
get() {
return this.$store.state.po.defaultWarehouse;
},
set(val) {
this.$store.commit("po/update_defaultWarehouse", val);
},
},
summary: {
get() {
return this.$store.state.po.summary;
},
set(val) {
this.$store.commit("po/update_summary", val);
},
},
summaryTotal: {
get() {
return this.$store.state.po.summaryTotal;
},
set(val) {
this.$store.commit("po/update_summaryTotal", val);
},
},
selectedItemCategory: {
get() {
return this.$store.state.po.selectedItemCategory;
},
set(val) {
this.$store.commit("po/update_selectedItemCategory", val);
},
},
itemCategoryList: {
get() {
return this.$store.state.po.itemCategoryList;
},
set(val) {
this.$store.commit("po/update_itemCategoryList", val);
},
},
},
methods: {
roundToThreeSignificantDigits(num) {
if (num === 0) return 0;
// Hitung jumlah digit
const absNum = Math.abs(num);
const magnitude = Math.floor(Math.log10(absNum)) + 1;
// Jika kurang dari 3 digit, tidak perlu dibulatkan
if (magnitude <= 3) return num;
// Hitung faktor pembulatan
const factor = Math.pow(10, magnitude - 3);
// Bulatkan
return Math.round(num / factor) * factor;
},
oneMoney(value){
//return one_money(value);
let splitValue = value.toString().split(".");
if(splitValue.length > 1) {
let val = splitValue[0]
return val.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ".") + "," + this.roundToThreeSignificantDigits(splitValue[1]);
} else {
return value.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ".");
}
},
getDiscountAmountSummaryPerItem(data) {
let discountAmount = 0;
if (data.discountType === "R") {
// debugger;
discountAmount = parseFloat(data.discount);
}
if (data.discountType === "P") {
// debugger;
discountAmount =
(parseFloat(data.discount) / 100) * parseFloat(data.RealPrice);
}
if (isNaN(discountAmount)) {
discountAmount = 0;
}
return discountAmount;
},
handleChangeDiscountPerItemSummary(data) {
console.debug("Data Diskon", data.discount);
if (!data.discount || data.discount == "") {
data.discount = 0
}
let tmpSelectedItem = JSON.parse(JSON.stringify(this.selectedItem));
let dataDetail = {};
this.summary.forEach((element) => {
if (element.keyID == data.keyID) {
dataDetail = element.Details[0];
}
});
tmpSelectedItem.forEach((element) => {
// 'M_ItemID', 'ItemUnitID'
if (
element.M_ItemID === dataDetail.M_ItemID &&
element.ItemUnitID === dataDetail.ItemUnitID
) {
element.discount = data.discount;
}
});
this.selectedItem = tmpSelectedItem;
// this.$store.dispatch("po/countItemTotal");
// this.$store.dispatch("po/generateSummary");
let newPrice = 0;
if (data.discountType === "R") {
// debugger;
newPrice = parseFloat(data.RealPrice) - parseFloat(data.discount);
}
if (data.discountType === "P") {
// debugger;
newPrice =
parseFloat(data.RealPrice) -
(parseFloat(data.discount) / 100) * parseFloat(data.RealPrice);
}
if (isNaN(newPrice)) {
newPrice = 0;
}
if (newPrice <= 0) {
this.snackbar = {
state: true,
type: "warning",
message: "Diskon tidak boleh melebihi harga !",
};
}
data.Price = newPrice;
let newTotal = parseInt(data.PoQty) * newPrice;
data.Total = newTotal;
this.$store.dispatch("po/generateSummaryTotal");
},
handleChangeDiscountSummary(typeDisc, data) {
console.debug("Data Diskon HandleChangeDiscountSummary", data.discount);
if (!data.discount || data.discount == "") {
data.discount = 0
}
// debugger;
let tmpSummary = JSON.parse(JSON.stringify(this.summary));
let tmpSelectedItem = JSON.parse(JSON.stringify(this.selectedItem));
let dataDetail = {};
tmpSummary.forEach((element) => {
if (element.keyID == data.keyID) {
element.discountType = typeDisc;
element.Price = element.RealPrice;
element.discount = 0;
element.Total = element.PoQty * element.RealPrice;
dataDetail = element.Details[0];
}
});
tmpSelectedItem.forEach((element) => {
if (
element.M_ItemID === dataDetail.M_ItemID &&
element.ItemUnitID === dataDetail.ItemUnitID
) {
element.discount = 0;
element.discountType = typeDisc;
}
});
this.selectedItem = tmpSelectedItem;
this.summary = tmpSummary;
this.$store.dispatch("po/countItemTotal");
this.$store.dispatch("po/generateSummaryTotal");
},
tryDeleteItem(data, type) {
},
deleteItem(itemID) {
// Menghapus item berdasarkan PurchaseRequestFlagID (detail)
this.$store.dispatch("po/deleteItemFromSummary", { detailId: itemID });
},
// Jika ingin menghapus seluruh item dan detailsnya
deleteEntireItem(itemId) {
this.$store.dispatch("po/deleteItemFromSummary", { itemId: itemId });
},
handleChangeQty(data) {
cek = parseInt(data.PoQty);
if (isNaN(cek)) {
data.Total = 0;
this.$store.dispatch("po/countItemTotal");
this.$store.dispatch("po/generateSummary");
// this.snackbar = {
// state: true,
// type: "warning",
// message: "Belum ada item yang di pilih",
// };
return;
}
if (cek < 0) {
data.PoQty = 1;
this.snackbar = {
state: true,
type: "warning",
message: "PO Qty minimal 1",
};
data.Total = parseInt(data.PoQty) * parseFloat(data.Price);
this.$store.dispatch("po/countItemTotal");
this.$store.dispatch("po/generateSummary");
return;
}
if (cek > parseInt(data.FlagQty)) {
data.PoQty = data.FlagQty;
this.snackbar = {
state: true,
type: "warning",
message: "PO Qty tidak boleh melebihi batas",
};
data.Total = parseInt(data.PoQty) * parseFloat(data.Price);
this.$store.dispatch("po/countItemTotal");
this.$store.dispatch("po/generateSummary");
return;
}
data.Total = parseInt(data.PoQty) * parseFloat(data.Price);
this.$store.dispatch("po/countItemTotal");
this.$store.dispatch("po/generateSummary");
},
saveOrder() {
if (this.loading) {
this.snackbar = {
state: true,
type: "warning",
message: "Proses sedang berjalan, harap tunggu hingga selesai.",
};
return;
}
if (this.dialogFormAct === "ADD") {
this.$store.dispatch("po/saveOrder");
} else if (this.dialogFormAct === "EDIT") {
this.$store.dispatch("po/updateOrder");
}
},
isObjectEmpty(obj) {
return Object.keys(obj).length === 0 && obj.constructor === Object;
},
openDialogAddItem() {
if (this.loading) {
this.snackbar = {
state: true,
type: "warning",
message: "Proses sedang berjalan, harap tunggu hingga selesai.",
};
return;
}
this.selectedItemTemp = JSON.parse(JSON.stringify(this.selectedItem));
this.itemList = [];
// this.$store.dispatch("po/getItem");
this.dialogItem = true;
},
addItem() {
if (this.selectedItemTemp.length === 0) {
this.snackbar = {
state: true,
type: "warning",
message: "Belum ada item yang di pilih",
};
}
let newItem = JSON.parse(JSON.stringify(this.selectedItemTemp));
//cek apakah semua memenuhi
// let arrCek = [];
// newItem.forEach((element) => {
// let cekQty =
// parseInt(element.PoQty) /
// parseInt(element.DefaultPurchase.UnitConvertAmount) ?? 1;
// arrCek.push(Number.isInteger(cekQty));
// });
// this.warehouseType = arrCek.every(Boolean) ? "Multiple" : "Single";
// if (this.warehouseType === "Multiple") {
// newItem.forEach((element) => {
// element.warehouse = {
// WarehouseID: element.WarehouseID,
// WarehouseName: element.WarehouseName,
// };
// });
// } else if (this.warehouseType === "Single") {
// newItem.forEach((element) => {
// element.warehouse = this.selectedWarehouse;
// });
// }
this.selectedItem = newItem;
this.$store.dispatch("po/countItemTotal");
this.$store.dispatch("po/generateSummary");
this.selectedItemTemp = [];
this.dialogItem = false;
// if (this.isObjectEmpty(this.selectedItemTemp)) return;
// let newItem = this.selectedItemTemp;
// newItem["warehouse"] = this.defaultWarehouse;
// let tmp = JSON.parse(JSON.stringify(this.selectedItem));
// console.log(tmp);
// const existingItem = tmp.find(
// (item) => item.PurchaseRequestFlagID === newItem.PurchaseRequestFlagID
// );
// if (existingItem) {
// this.snackbar = {
// state: true,
// type: "warning",
// console.log(this.selectedItem);
},
changeWarehouse() {
if (this.warehouseType === "Single") {
this.selectedItem.forEach((item) => {
item.warehouse = this.selectedWarehouse;
});
}
this.$store.dispatch("po/generateSummary");
},
// deleteItem(itemID) {
// let tmp = JSON.parse(JSON.stringify(this.selectedItem));
// tmp = tmp.filter((item) => item.PurchaseRequestFlagID !== itemID);
// this.selectedItem = tmp;
// this.$store.dispatch("po/countItemTotal");
// this.$store.dispatch("po/generateSummary");
// },
formatRupiah(angka) {
const format = new Intl.NumberFormat("id-ID", {
style: "currency",
currency: "IDR",
minimumFractionDigits: 0,
});
return format.format(angka).trim();
},
formatDate(date) {
if (!date) return null;
const [year, month, day] = date.split("-");
return `${day}-${month}-${year}`;
},
deFormatedDate(date) {
if (!date) return null;
const [day, month, year] = date.split("-");
return `${year}-${month.padStart(2, "0")}-${day.padStart(2, "0")}`;
},
},
watch: {
searchSupplier(val, old) {
if (val == old) return;
if (!val) return;
if (val.length < 2) return;
this.$store.dispatch("po/getSupplier");
},
searchItem(val, old) {
if (val == old) return;
// if (!val) return;
// if (val.length < 2) return;
this.$store.dispatch("po/getItem");
},
warehouseType(val, old) {
if (this.selectedItem.length == 0) return;
if (val !== old) {
if (val === "Multiple" && old === "Single") {
this.snackbar = {
state: true,
type: "info",
message:
"Tipe gudang berubah dari Single ke Multiple, silahkan pilih gudang tiap item.",
};
} else if (val === "Single" && old === "Multiple") {
this.snackbar = {
state: true,
type: "warning",
message:
"Tipe gudang berubah dari Multiple ke Single, tiap item akan dikirim ke gudang default yang sudah dipilih.",
};
}
}
},
dialogItem(val, old) {
if (val) this.$store.dispatch("po/getItem");
},
},
};
</script>