26 Commits

Author SHA1 Message Date
0c8848c18a feature: serah terima & print barcode 2026-07-22 11:42:50 +07:00
a38e9b1d38 Merge remote-tracking branch 'origin/feat-add-report' into develop 2026-07-22 08:33:52 +07:00
a12a34f073 feature: payment instruction & cashier case cicilan dan downpayment 2026-07-21 15:22:18 +07:00
Hanan Askarim
5370d08529 add button report request barang 2026-07-21 11:43:58 +07:00
Hanan Askarim
3a875230eb add button report pengeluaran barang 2026-07-21 11:14:53 +07:00
Hanan Askarim
7491892aea add button report pemakaian item per divisi 2026-07-21 11:07:39 +07:00
Hanan Askarim
2bbebe20fe add button report request mutasi 2026-07-21 10:40:41 +07:00
Hanan Askarim
6c69ab1d6b add button report penyerahan mutasi 2026-07-21 10:32:52 +07:00
Hanan Askarim
984049cb01 add button report penerimaan mutasi 2026-07-21 10:25:08 +07:00
Hanan Askarim
33a5e07566 add button report faktur 2026-07-21 10:09:02 +07:00
Hanan Askarim
90602d4aa7 add button report payment voucher 2026-07-21 09:52:01 +07:00
Hanan Askarim
927d009c15 add button report receive order asset 2026-07-21 09:43:00 +07:00
Hanan Askarim
ba320134f8 add button report po asset 2026-07-21 09:21:31 +07:00
Hanan Askarim
5d0351d2a5 add button report receive po jasa 2026-07-21 09:12:43 +07:00
Hanan Askarim
bee1396917 add button report po jasa 2026-07-21 09:05:39 +07:00
Hanan Askarim
b8a7f777cc add button report receive item po inventaris 2026-07-21 08:57:48 +07:00
Hanan Askarim
b867fca7b7 add button report receive item po 2026-07-21 08:38:19 +07:00
Hanan Askarim
8cc82e79d1 add button report receive surat jalan 2026-07-20 16:56:32 +07:00
Hanan Askarim
10719f2efe add button report surat jalan 2026-07-20 16:50:12 +07:00
Hanan Askarim
e0536e554d add button report pr non persediaan 2026-07-20 16:42:49 +07:00
Hanan Askarim
4c7ef4dce7 add request stock button report 2026-07-20 16:26:51 +07:00
Hanan Askarim
1ffe6ad384 add button report purchase request direct approval 2026-07-20 16:14:56 +07:00
Hanan Askarim
79c5cb513a add button report purchase request direct 2026-07-20 15:59:00 +07:00
d92fb57751 feature: po pay downpayment 2026-07-20 13:14:28 +07:00
dd5f0b6ab4 fix bug undefined array filter & snackbar tidak muncul saat konfirmasi handover inventaris 2026-07-09 09:15:37 +07:00
1f5bcfacd5 change dialog form po aset, separate form order / form aset 2026-07-08 17:14:35 +07:00
88 changed files with 10496 additions and 2494 deletions

View File

@@ -0,0 +1,64 @@
const URL = "/one-api/mockup/purchase/order/PurchaseOrderAset";
const URLRO = "/one-api/mockup/receive-item-po/ReceiveItemPOAsset";
async function request(endpoint, params) {
try {
const resp = await axios.post(URL + endpoint, params)
if (resp.status !== 200) {
throw new Error(resp.statusText);
}
return resp.data;
} catch (error) {
return {
status: "ERR",
message: error.message
}
}
}
export async function getListSupplier(params) {
return request("/getListSupplier", params);
}
export async function getListCabang(params) {
return request("/getListCabang", params);
}
export async function getListGudang(params) {
return request("/getListGudang", params);
}
export async function getDaftarPoAset(params) {
return request("/getDaftarPoAset", params);
}
export async function getDaftarAttachment(params) {
return request("/getDaftarAttachment", params);
}
export async function getUserApproveLevel(params) {
return request("/getUserApproveLevel", params);
}
export async function updateApprovalPO(params) {
return request("/updateApprovalPO", params);
}
export async function getDataKontrakPoAset(params) {
return request("/getDataKontrakPoAset", params);
}
export async function generatePOItemReceive(params) {
try {
const resp = await axios.post(URLRO + "/generatePOItemReceive", params)
if (resp.status !== 200) {
throw new Error(resp.statusText);
}
return resp.data;
} catch (error) {
return {
status: "ERR",
message: error.message
}
}
}

View File

@@ -0,0 +1,104 @@
<template>
<div>
<v-dialog v-model="dialog_attachment" persistent max-width="60vw">
<v-card>
<v-card-title class="headline grey lighten-2" primary-title>
VIEW ATTACHMENT
</v-card-title>
<v-card-text>
<v-layout row wrap>
<v-flex
v-for="(nota) in list_attachment"
xs4 class="pa-2" :key="nota.attach_id"
>
<div style="position: relative; padding-bottom: 35px;">
<v-img
:src="makeImageURL(nota)" aspect-ratio="1" contain
class="grey lighten-2" @click="fullview(nota)"
></v-img>
</div>
</v-flex>
</v-layout>
</v-card-text>
<v-card-actions>
<v-spacer></v-spacer>
<v-btn @click="tutupViewAttachment()" color="error" class="white--text">Tutup</v-btn>
</v-card-actions>
</v-card>
</v-dialog>
<v-dialog v-model="dialog_fullview" persistent max-width="60vw">
<v-card>
<v-card-title class="headline grey lighten-2" primary-title>
{{ view_title }}
</v-card-title>
<v-card-text style="max-height: 80vh; overflow-y: auto;">
<div class="pa-2">
<v-img :src="view_url" contain class="grey lighten-2"></v-img>
</div>
</v-card-text>
<v-card-actions>
<v-spacer></v-spacer>
<v-btn class="mr-2" color="red" flat outline @click="dialog_fullview = false">
Tutup
</v-btn>
</v-card-actions>
</v-card>
</v-dialog>
</div>
</template>
<style scoped>
.close-button {
position: absolute;
top: 5px;
right: 5px;
z-index: 1;
cursor: pointer;
}
</style>
<script>
module.exports = {
data() {
return {
dialog_fullview: false,
view_title: "",
view_url: ""
}
},
computed: {
dialog_attachment: {
get() {
return this.$store.state.orderAsset.dialog_attachment;
},
set(val) {
this.$store.commit("orderAsset/update_dialog_attachment", val);
}
},
list_attachment() {
return this.$store.state.orderAsset.list_attachment;
}
},
methods: {
makeImageURL(nota) {
const year = new Date(nota.created).getFullYear();
const baseURL = BASE_URL + `/one-media/order-asset/${year}/`;
return baseURL + nota.img_url;
},
fullview(nota) {
this.view_title = nota.img_url;
this.view_url = this.makeImageURL(nota)
this.dialog_fullview = true;
},
tutupViewAttachment() {
this.view_title = ""
this.view_url = ""
this.dialog_attachment = false
}
},
watch: {
}
}
</script>

View File

@@ -0,0 +1,186 @@
<template>
<v-dialog v-model="dialog_confirm_order" persistent width="80vw">
<v-card class="style-card">
<v-card-title class="headline grey lighten-2">KONFIRMASI ORDER ASET</v-card-title>
<template>
<div class="style-content">
<v-stepper non-linear v-model="steps">
<v-stepper-header>
<v-stepper-step editable step="1" @click="steps = 1">
FORM ORDER ASET
</v-stepper-step>
<v-divider></v-divider>
<v-stepper-step editable step="2" @click="steps = 2">
FORM KONTRAK ASET
</v-stepper-step>
<v-divider></v-divider>
<v-stepper-step editable step="3" @click="steps = 3">
ITEM ORDER ASET
</v-stepper-step>
</v-stepper-header>
<v-stepper-items>
<v-stepper-content step="1">
<form-order-asset></form-order-asset>
</v-stepper-content>
<v-stepper-content step="2">
<form-kontrak-asset></form-kontrak-asset>
</v-stepper-content>
<v-stepper-content step="3">
<form-item-request-asset></form-item-request-asset>
<dialog-select-request-asset></dialog-select-request-asset>
</v-stepper-content>
</v-stepper-items>
</v-stepper>
<v-card-text>
<v-layout v-for="(item, index) in summary_items" :key="index"
row wrap align-center>
<v-flex xs2 pa-1>
<strong>{{ item.label }}</strong>
</v-flex>
<v-flex grow></v-flex>
<v-flex xs2 pa-1 class="text-xs-right">
<strong>Rp. {{ formatCurrency(item.value) }}</strong>
</v-flex>
</v-layout>
</v-card-text>
</div>
</template>
<v-card-actions>
<v-btn @click="lihatLampiran()" color="info" class="white--text">Lampiran</v-btn>
<v-spacer></v-spacer>
<v-btn @click="batalConfirm()" color="error" class="white--text">Batal</v-btn>
<v-btn @click="confirmOrder()" color="primary" class="white--text"
v-show="!view_detail_mode">
{{ user.M_UserM_ApproveLevelID == '1' ? "Verifikasi" : "Approve" }}
</v-btn>
</v-card-actions>
</v-card>
</v-dialog>
</template>
<style scoped>
.style-card {
max-height: 60vh;
display: flex;
flex-direction: column;
}
.style-content {
overflow-y: auto;
flex: 1 1 auto;
min-height: 0;
}
</style>
<script>
module.exports = {
data() {
return {
steps: 1
}
},
components: {
'form-order-asset': httpVueLoader('./form-order-asset.vue'),
'form-kontrak-asset': httpVueLoader('./form-kontrak-asset.vue'),
'form-item-request-asset': httpVueLoader('./form-item-request-asset.vue'),
'dialog-select-request-asset': httpVueLoader('./dialog-select-request-asset.vue')
},
computed: {
dialog_confirm_order: {
get() {
return this.$store.state.orderAsset.dialog_confirm_order;
},
set(val) {
this.$store.commit("orderAsset/update_dialog_confirm_order", val);
}
},
summary_order: {
get() {
return this.$store.state.formView.summary_order;
},
set(val) {
this.$store.commit("formView/update_summary_order", val);
}
},
summary_items() {
if (!this.summary_order) return [];
return [
{label: 'JUMLAH', value: this.summary_order.subtotal},
{label: 'DISKON', value: this.summary_order.diskon},
{label: 'PAJAK', value: this.summary_order.pajak},
{label: 'DOWN PAYMENT', value: this.summary_order.downpayment},
{label: 'TOTAL', value: this.summary_order.total}
]
},
loading_process() {
return this.$store.state.orderAsset.loading_process;
},
selected_order() {
return this.$store.state.orderAsset.selected_order;
},
view_detail_mode() {
return this.$store.state.orderAsset.view_detail_mode;
},
user() {
return this.$store.state.orderAsset.user
}
},
methods: {
formatCurrency(value) {
const num = parseFloat(value);
if (isNaN(num)) return 0;
return num.toFixed(2).replace('.', ',').replace(/\B(?=(\d{3})+(?!\d))/g, ".");
},
lihatLampiran() {
this.$store.commit("orderAsset/update_dialog_attachment", true)
},
confirmOrder() {
if (!this.loading_process) {
const poID = this.selected_order.PurchaseOrderID
this.$store.dispatch("orderAsset/confirmOrderAsset", poID)
}
},
batalConfirm() {
this.$store.commit("formView/update_form_order", {
podate: moment(new Date()).format('YYYY-MM-DD'),
supplierID: "",
reference: "",
branchID: "",
typepajak: "percent",
valuepajak: 0,
typediskon: "percent",
valuediskon: 0
});
this.$store.commit("formView/update_form_kontrak", {
nama_kontrak: '',
tanggal_kontrak: moment(new Date()).format('YYYY-MM-DD'),
tanggalAwal_kontrak: moment(new Date()).format('YYYY-MM-DD'),
tanggalAkhir_kontrak: moment(new Date()).format('YYYY-MM-DD'),
durasi_cicilan: 1,
jumlah_cicilan: 1,
tanggalBayar_cicilan: 1,
besarNilai_cicilan: 0,
type_downpayment: 'percent',
besarNilai_downpayment: 0
});
this.$store.commit("formView/update_received_order", []);
this.summary_order = {
subtotal: 0,
diskon: 0,
pajak: 0,
downpayment: 0,
total_before_downpayment: 0,
total: 0
};
this.$store.commit("orderAsset/update_view_detail_mode", false);
this.dialog_confirm_order = false;
}
},
watch: { }
}
</script>

View File

@@ -0,0 +1,95 @@
<template>
<v-dialog v-model="dialog_select_item" persistent width="60vw">
<v-card class="style-limit-heightcard">
<v-card-title class="headline grey lighten-2" primary title>
TAMBAH ITEM REQUEST
</v-card-title>
<v-card-text class="style-limit-heightcontent">
<v-flex xs12>
<v-text-field
label="Cari" hide-details outline
v-model="keyword" placeholder="Nama item, nomor request"
readonly
></v-text-field>
</v-flex>
<v-flex xs12 mt-2>
<v-data-table
:headers="headers" :items="requested_asset.records"
class="elevation-1" hide-actions
>
<template v-slot:items="props">
<tr>
<td class="text-xs-center pa-2">{{ props.item.PurchaseRequestNumber }}</td>
<td class="text-xs-start pa-2">
{{ props.item.Requestedby }} <br>
{{ props.item.M_BranchName }}
</td>
<td class="text-xs-start pa-2">
{{ props.item.M_ItemCode }} <br>
{{ props.item.M_ItemDesc }}
</td>
<td class="text-xs-center pa-2">{{ props.item.ItemUnitName }}</td>
<td class="text-xs-center pa-2">{{ props.item.RequestQty }}</td>
</tr>
</template>
</v-data-table>
</v-flex>
</v-card-text>
<v-card-actions>
<v-spacer></v-spacer>
<v-btn @click="dialog_select_item = false" color="error" class="white--text">Tutup</v-btn>
</v-card-actions>
</v-card>
</v-dialog>
</template>
<style scoped>
.style-limit-heightcard {
max-height: 60vh;
display: flex;
flex-direction: column;
}
.style-limit-heightcontent {
overflow-y: auto;
flex: 1 1 auto;
min-height: 0;
}
</style>
<script>
module.exports = {
data() {
return {
dialog_select_item: false,
keyword: "",
requested_asset: {
records: [],
total: 0
},
headers: [
{
text: "NO PURCHASE REQ", align: "center", sortable: false,
value: "noreq", width: "20%", class: "pa-1 blue lighten-3 white--text",
},
{
text: "REQUESTER", align: "center", sortable: false,
value: "kode", width: "20%", class: "pa-1 blue lighten-3 white--text",
},
{
text: "ITEM", align: "center", sortable: false,
value: "serve", width: "20%", class: "pa-1 blue lighten-3 white--text",
},
{
text: "SATUAN", align: "center", sortable: false,
value: "unit", width: "20%", class: "pa-1 blue lighten-3 white--text",
},
{
text: "REQ QTY", align: "center", sortable: false,
value: "qty", width: "10%", class: "pa-1 blue lighten-3 white--text",
},
],
}
}
}
</script>

View File

@@ -0,0 +1,157 @@
<template>
<v-layout row wrap>
<v-flex xs12>
<v-data-table
:headers="headers" :items="received_order"
:expand="expand" class="elevation-1" hide-actions
item-key="M_ItemID"
>
<template v-slot:items="props">
<tr @click="props.expanded = !props.expanded">
<td class="text-xs-center pa-2">
<v-icon>{{ props.expanded
? "keyboard_arrow_down"
: "keyboard_arrow_right"
}}</v-icon>
</td>
<td class="text-xs-center pa-2">{{ props.item.M_ItemDesc }}</td>
<td class="text-xs-center pa-2">{{ props.item.RequestQty }}</td>
<td class="text-xs-center pa-2">
Rp. {{ formatCurrency(props.item.SupplierPrice) }}
</td>
<td class="text-xs-center pa-2">
<span v-if="props.item.DiskonType == 'P'">
{{ props.item.DiskonAmount }}%
</span>
<span v-else>
Rp. {{ formatCurrency(props.item.DiskonAmount) }}
</span>
</td>
<td class="text-xs-center pa-2">
Rp. {{ formatCurrency(props.item.EndPrice) }}
</td>
<td class="text-xs-center pa-2">
Rp. {{ formatCurrency(props.item.TempTotal) }}
</td>
</tr>
</template>
<template v-slot:expand="props">
<v-card flat>
<v-card-text>
<v-data-table
:headers="b_headers" class="elevation-0"
:items="props.item.detail" hide-actions
item-key="PurchaseRequestDetailID"
>
<template v-slot:items="det">
<tr>
<td class="text-xs-center pa-2">{{ det.item.M_ItemDesc }}</td>
<td class="text-xs-center pa-2">{{ det.item.PurchaseRequestNumber }}</td>
<td class="text-xs-center pa-2">{{ det.item.M_BranchName }}</td>
<td class="text-xs-center pa-2">{{ det.item.RequestQty }}</td>
<td class="text-xs-center pa-2">{{ det.item.ItemUnitName }}</td>
<td class="text-xs-center pa-2">
Rp. {{ formatCurrency(det.item.SupplierPrice) }}
</td>
</tr>
</template>
</v-data-table>
</v-card-text>
</v-card>
</template>
</v-data-table>
</v-flex>
</v-layout>
</template>
<script>
module.exports = {
data() {
return {
expand: false,
headers: [
{
text: "", align: "center", sortable: false,
value: "item", width: "5%", class: "pa-1 blue lighten-3 white--text",
},
{
text: "ITEM", align: "center", sortable: false,
value: "item", width: "20%", class: "pa-1 blue lighten-3 white--text",
},
{
text: "JUMLAH", align: "center", sortable: false,
value: "qty", width: "10%", class: "pa-1 blue lighten-3 white--text",
},
{
text: "HARGA", align: "center", sortable: false,
value: "price", width: "15%", class: "pa-1 blue lighten-3 white--text",
},
{
text: "DISKON", align: "center", sortable: false,
value: "disc", width: "15%", class: "pa-1 blue lighten-3 white--text",
},
{
text: "HARGA SETELAH DISKON", align: "center", sortable: false,
value: "disc", width: "20%", class: "pa-1 blue lighten-3 white--text",
},
{
text: "TOTAL", align: "center", sortable: false,
value: "disc", width: "15%", class: "pa-1 blue lighten-3 white--text",
},
],
b_headers: [
{
text: "NAMA PRODUK", align: "center", sortable: false,
value: "prod", width: "25%", class: "pa-1 blue lighten-4 black--text",
},
{
text: "NO REQUEST", align: "center", sortable: false,
value: "noreq", width: "20%", class: "pa-1 blue lighten-4 black--text",
},
{
text: "REQUESTER", align: "center", sortable: false,
value: "req", width: "20%", class: "pa-1 blue lighten-4 black--text",
},
{
text: "JUMLAH", align: "center", sortable: false,
value: "qty", width: "10%", class: "pa-1 blue lighten-4 black--text",
},
{
text: "UNIT", align: "center", sortable: false,
value: "unit", width: "10%", class: "pa-1 blue lighten-4 black--text",
},
{
text: "HARGA", align: "center", sortable: false,
value: "price", width: "15%", class: "pa-1 blue lighten-4 black--text",
}
]
}
},
computed: {
received_order: {
get() {
return this.$store.state.formView.received_order;
},
set(val) {
this.$store.commit("formView/update_received_order", val)
}
},
summary_order: {
get() {
return this.$store.state.formView.summary_order;
},
set(val) {
this.$store.commit("formView/update_summary_order", val)
}
}
},
methods: {
formatCurrency(value) {
const num = parseFloat(value);
if (isNaN(num)) return 0;
return num.toFixed(2).replace('.', ',').replace(/\B(?=(\d{3})+(?!\d))/g, ".");
}
}
}
</script>

View File

@@ -0,0 +1,114 @@
<template>
<div>
<v-layout row wrap>
<v-flex xs3 pa-1>
<v-text-field
v-model="form_kontrak.nama_kontrak" hide-details outline
label="Nama Kontrak" placeholder="masukan nama kontrak" readonly
></v-text-field>
</v-flex>
<v-flex xs3 pa-1>
<v-text-field
:value="formattedDateKontrak" hide-details readonly outline
label="Tanggal Kontrak"
></v-text-field>
</v-flex>
<v-flex xs3 pa-1>
<v-text-field
:value="formattedStartdateKontrak" outline hide-details
label="Tanggal Mulai Kontrak" readonly
></v-text-field>
</v-flex>
<v-flex xs3 pa-1>
<v-text-field
:value="formattedEnddateKontrak" outline hide-details
label="Tanggal Akhir Kontrak" readonly
></v-text-field>
</v-flex>
</v-layout>
<v-layout row wrap>
<v-flex xs2 pa-1>
<v-text-field
v-model="form_kontrak.durasi_cicilan" hide-details outline
placeholder="1" label="Durasi Kontrak (Bulan)" readonly
></v-text-field>
</v-flex>
<v-flex xs2 pa-1>
<v-text-field
v-model="form_kontrak.jumlah_cicilan" hide-details
placeholder="1" outline label="Jumlah Cicilan" readonly
></v-text-field>
</v-flex>
<v-flex xs2 pa-1>
<v-text-field
v-model="form_kontrak.tanggalBayar_cicilan" hide-details
placeholder="1" outline label="Tanggal Bayar Cicilan" readonly
></v-text-field>
</v-flex>
<v-flex xs2 pa-1>
<v-text-field
v-model="form_kontrak.besarNilai_cicilan" hide-details
label="Besar Bayar Cicilan" placeholder="0" prefix="Rp."
outline readonly
></v-text-field>
</v-flex>
<v-flex xs1 pa-1>
<v-autocomplete
:items="['nominal', 'percent']" label="Tipe Nilai"
v-model="form_kontrak.type_downpayment" hide-details
outline disabled
></v-autocomplete>
</v-flex>
<v-flex xs3 pa-1>
<v-text-field
v-if="form_kontrak.type_downpayment == 'percent'"
label="Jumlah Uang Muka" hide-details
v-model="form_kontrak.besarNilai_downpayment"
placeholder="0" suffix="%" outline readonly
></v-text-field>
<v-text-field
v-else label="Jumlah Uang Muka" hide-details
placeholder="0" prefix="Rp." outline readonly
v-model="form_kontrak.besarNilai_downpayment"
></v-text-field>
</v-flex>
</v-layout>
</div>
</template>
<script>
module.exports = {
data() {
return {
};
},
computed: {
form_kontrak: {
get() {
return this.$store.state.formView.form_kontrak;
},
set(val) {
this.$store.commit("formView/update_form_kontrak", val);
}
},
formattedDateKontrak() {
return this.formatDate(this.form_kontrak.tanggal_kontrak);
},
formattedStartdateKontrak() {
return this.formatDate(this.form_kontrak.tanggalAwal_kontrak);
},
formattedEnddateKontrak() {
return this.formatDate(this.form_kontrak.tanggalAkhir_kontrak);
},
},
methods: {
formatDate(date) {
if (!date) return null;
const [year, month, day] = date.split('-');
return `${day}-${month}-${year}`;
}
}
}
</script>

View File

@@ -0,0 +1,123 @@
<template>
<div>
<v-layout row wrap>
<v-flex xs4 pa-1>
<v-text-field
:value="formattedPOdate" label="Tanggal PO"
hide-details readonly outline
></v-text-field>
</v-flex>
<v-flex xs4 pa-1>
<v-autocomplete
:items="list_supplier" hide-details outline disabled
v-model="form_order.supplierID" label="Supplier"
item-text="SupplierName" item-value="SupplierID"
></v-autocomplete>
</v-flex>
<v-flex xs4 pa-1>
<v-text-field
v-model="form_order.reference" hide-details outline
label="Referensi" placeholder="nomor request" readonly
></v-text-field>
</v-flex>
</v-layout>
<v-layout row wrap>
<v-flex xs2 pa-1>
<v-autocomplete
:items="list_cabang" hide-details outline disabled
v-model="form_order.branchID" label="Cabang"
item-text="M_BranchName" item-value="M_BranchID"
></v-autocomplete>
</v-flex>
<v-flex xs2 pa-1>
<v-autocomplete
:items="list_gudang" hide-details outline disabled
v-model="form_order.gudangID" label="Gudang"
item-text="WarehouseName" item-value="WarehouseID"
></v-autocomplete>
</v-flex>
<v-flex xs2 pa-1>
<v-autocomplete
:items="['nominal', 'percent']" label="Tipe Nilai"
v-model="form_order.typepajak" hide-details outline disabled
></v-autocomplete>
</v-flex>
<v-flex xs2 pa-1>
<v-text-field
v-if="form_order.typepajak == 'percent'" label="Pajak"
v-model="form_order.valuepajak" hide-details outline
placeholder="besar pajak dalam persen" suffix="%" readonly
></v-text-field>
<v-text-field
v-else label="Pajak" outline prefix="Rp."
v-model="form_order.valuepajak" hide-details
placeholder="besar pajak dalam rupiah" readonly
></v-text-field>
</v-flex>
<v-flex xs2 pa-1>
<v-autocomplete
:items="['nominal', 'percent']" hide-details outline disabled
v-model="form_order.typediskon" label="Tipe Nilai"
></v-autocomplete>
</v-flex>
<v-flex xs2 pa-1>
<v-text-field
v-if="form_order.typediskon == 'percent'" label="Diskon"
v-model="form_order.valuediskon" hide-details outline
placeholder="besar diskon dalam persen" suffix="%" readonly
></v-text-field>
<v-text-field
v-else label="Diskon" outline prefix="Rp."
v-model="form_order.valuediskon" hide-details
placeholder="besar diskon dalam rupiah" readonly
></v-text-field>
</v-flex>
<v-flex xs12 pa-1>
<v-textarea
v-model="form_order.catatan" auto-grow readonly
rows="1" outline label="Catatan" hide-details
></v-textarea>
</v-flex>
</v-layout>
</div>
</template>
<script>
module.exports = {
data() {
return {
}
},
computed: {
form_order: {
get() {
return this.$store.state.formView.form_order
},
set(val) {
this.$store.commit("formView/update_form_order", val)
}
},
formattedPOdate() {
return this.formatDate(this.form_order.podate);
},
list_cabang() {
return this.$store.state.orderAsset.list_cabang;
},
list_gudang() {
return this.$store.state.orderAsset.list_gudang;
},
list_supplier() {
return this.$store.state.orderAsset.list_supplier;
}
},
methods: {
formatDate(date) {
if (!date) return null;
const [year, month, day] = date.split('-');
return `${day}-${month}-${year}`;
}
}
}
</script>

View File

@@ -0,0 +1,269 @@
<template>
<div>
<v-toolbar color="primary" dark>
<v-toolbar-title class="white--text">APPROVE PURCHASE ORDER ASET</v-toolbar-title>
<v-spacer></v-spacer>
</v-toolbar>
<v-card class="pa-2">
<v-layout row align-center>
<v-flex xs3>
<v-menu v-model="menuStartdateFilter" offset-y lazy min-width="290px" transition="scale-transition"
max-width="290px" full-width :nudge-right="40" :close-on-content-click="false">
<template v-slot:activator="{ on }">
<v-text-field v-model="formattedStartdate" label="Tanggal Awal" hide-details readonly
v-on="on" outline></v-text-field>
</template>
<v-date-picker v-model="filter.startdate" no-title
@input="menuStartdateFilter = false"></v-date-picker>
</v-menu>
</v-flex>
<v-flex xs3 pl-2>
<v-menu v-model="menuEnddateFilter" offset-y lazy min-width="290px" transition="scale-transition"
max-width="290px" full-width :nudge-right="40" :close-on-content-click="false">
<template v-slot:activator="{ on }">
<v-text-field v-model="formattedEnddate" label="Tanggal Akhir" hide-details readonly
v-on="on" outline></v-text-field>
</template>
<v-date-picker v-model="filter.enddate" no-title
@input="menuEnddateFilter = false"></v-date-picker>
</v-menu>
</v-flex>
<v-flex xs3 pl-2>
<v-autocomplete :items="list_status" hide-details outline v-model="filter.status"
label="Status"></v-autocomplete>
</v-flex>
<v-flex xs3 pl-2>
<v-text-field v-model="filter.search" hide-details outline label="Cari"
placeholder="cari nomor po"></v-text-field>
</v-flex>
</v-layout>
</v-card>
<v-card class="pa-2 mt-2">
<v-data-table
:headers="headers" :items="list_order.records"
class="elevation-1" hide-actions
>
<template v-slot:items="props">
<tr>
<td class="text-xs-center pa-2">{{ props.item.PurchaseOrderNumber }}</td>
<td class="text-xs-center pa-2">{{ props.item.PurchaseOrderDate }}</td>
<td class="text-xs-center pa-2">{{ props.item.SupplierName }}</td>
<td class="text-xs-center pa-2">{{ props.item.M_BranchName }}</td>
<td class="text-xs-center pa-2">{{ props.item.PurchaseOrderNote }}</td>
<td class="text-xs-center pa-2">
Rp. {{ formatCurrency(props.item.PurchaseOrderGrandTotal) }}
</td>
<td class="text-xs-center pa-2">{{ props.item.PurchaseOrderStatus }}</td>
<td class="text-xs-center pa-2">
<v-layout
v-if="props.item.PurchaseOrderStatus != 'Draft'"
align-center justify-center row
>
<v-flex shrink pr-1>
<v-btn
color="warning" @click="viewdetail(props.item)" small
>
detail
<v-icon small right>list_alt</v-icon>
</v-btn>
<v-chip
v-if="props.item.approvedby != '0'"
label color="success" text-color="white"
>
APPROVED
</v-chip>
</v-flex>
<v-flex pl-1 v-if="props.item.approvedby == '0'">
<v-btn
color="info" @click="updateStatusPO(props.item)" small
:disabled="user.M_UserM_ApproveLevelID != '1'"
:outline="props.item.verifiedby == '0'"
>
verifikasi
<v-icon small right>done</v-icon>
</v-btn>
<v-btn
color="success" @click="updateStatusPO(props.item)" small
:disabled="user.M_UserM_ApproveLevelID != '2'"
:outline="props.item.PurchaseOrderStatus != 'Approved'"
>
approve
<v-icon small right>done_all</v-icon>
</v-btn>
</v-flex>
</v-layout>
</td>
</tr>
</template>
</v-data-table>
<v-divider class="my-1"></v-divider>
<div class="po-2 mt-1 text-xs-center">
<v-pagination v-model="currpage" :length="pagelength" :total-visible="10"></v-pagination>
</div>
</v-card>
<v-snackbar v-model="snackbar.state" multi-line top :timeout="3000" :color="snackbar.color">
{{ snackbar.msg }}
<v-btn class="ml-2" round flat @click="snackbar.state = false">Tutup</v-btn>
</v-snackbar>
<dialog-confirm></dialog-confirm>
<dialog-attachment></dialog-attachment>
</div>
</template>
<script>
module.exports = {
components: {
'dialog-confirm': httpVueLoader('./dialog-confirm.vue'),
'dialog-attachment': httpVueLoader('./dialog-attachment.vue')
},
mounted() {
this.$store.dispatch("orderAsset/getListingPOAsset")
this.$store.dispatch("orderAsset/getUserApproveLevel")
this.$store.dispatch("orderAsset/listingCabang")
this.$store.dispatch("orderAsset/listingSupplier")
},
data() {
return {
menuStartdateFilter: false,
menuEnddateFilter: false,
headers: [
{
text: "No PO", align: "center", sortable: false,
value: "action", width: "15%", class: "pa-1 blue lighten-3 white--text",
},
{
text: "TANGGAL", align: "center", sortable: false,
value: "action", width: "10%", class: "pa-1 blue lighten-3 white--text",
},
{
text: "VENDOR", align: "center", sortable: false,
value: "action", width: "15%", class: "pa-1 blue lighten-3 white--text",
},
{
text: "CABANG", align: "center", sortable: false,
value: "action", width: "10%", class: "pa-1 blue lighten-3 white--text",
},
{
text: "KETERANGAN", align: "center", sortable: false,
value: "action", width: "20%", class: "pa-1 blue lighten-3 white--text",
},
{
text: "TOTAL", align: "center", sortable: false,
value: "action", width: "10%", class: "pa-1 blue lighten-3 white--text",
},
{
text: "STATUS", align: "center", sortable: false,
value: "action", width: "5%", class: "pa-1 blue lighten-3 white--text",
},
{
text: "AKSI", align: "center", sortable: false,
value: "action", width: "15%", class: "pa-1 blue lighten-3 white--text",
},
]
}
},
computed: {
snackbar: {
get() {
return this.$store.state.orderAsset.snackbar;
},
set(val) {
this.$store.commit("orderAsset/update_snackbar", val);
}
},
filter: {
get() {
return this.$store.state.orderAsset.filter;
},
set(val) {
this.$store.commit("orderAsset/update_filter", val);
}
},
currpage: {
get() {
return this.$store.state.orderAsset.currpage;
},
set(val) {
this.$store.commit("orderAsset/update_currpage", val);
this.$store.dispatch("orderAsset/getListingPOAsset");
}
},
list_order: {
get() {
return this.$store.state.orderAsset.list_order;
},
set(val) {
this.$store.commit("orderAsset/update_list_order", val);
}
},
pagelength() {
let total = this.list_order.total
if (total === undefined || total < 1) return 1
return Math.ceil(total/10)
},
formattedStartdate() {
return this.formatDate(this.filter.startdate)
},
formattedEnddate() {
return this.formatDate(this.filter.enddate)
},
list_status() {
return this.$store.state.orderAsset.list_status
},
user() {
return this.$store.state.orderAsset.user
}
},
methods: {
formatDate(date) {
if (!date) return null;
const [year, month, day] = date.split('-');
return `${day}-${month}-${year}`;
},
formatCurrency(value) {
const num = parseFloat(value);
if (isNaN(num)) return 0;
return num.toFixed(2).replace('.', ',').replace(/\B(?=(\d{3})+(?!\d))/g, ".");
},
updateStatusPO(item) {
const userlvl = this.user.M_UserM_ApproveLevelID
if (item.verifiedby == '0' || userlvl != '1') {
this.$store.dispatch("orderAsset/getAssetAttachment", {
contractID: item.contractID,
poID: item.PurchaseOrderID
});
this.$store.dispatch("formView/getDetailDataPO", item.PurchaseOrderID);
this.$store.commit("orderAsset/update_selected_order", item)
this.$store.commit("orderAsset/update_dialog_confirm_order", true)
} else {
const snac = { color: "info", msg: "PO sudah diverifikasi", state: true }
this.snackbar = snac
}
},
viewdetail(item) {
this.$store.dispatch("orderAsset/getAssetAttachment", {
contractID: item.contractID,
poID: item.PurchaseOrderID
});
this.$store.dispatch("formView/getDetailDataPO", item.PurchaseOrderID);
this.$store.commit("orderAsset/update_view_detail_mode", true);
this.$store.commit("orderAsset/update_dialog_confirm_order", true);
}
},
watch: {
filter: {
handler(val) {
this.$store.dispatch("orderAsset/getListingPOAsset")
},
deep: true
}
}
}
</script>

View File

@@ -0,0 +1,60 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<link rel="stylesheet" href="../../../libs/vendor/css/google-fonts.css">
<link rel="stylesheet" href="../../../libs/vendor/css/icomoon-fonts.css">
<link rel="stylesheet" href="../../../libs/vendor/css/vuetify.min.css">
<title>One</title>
</head>
<body>
<div v-cloak id="app">
<v-app id="smartApp">
<one-navbar></one-navbar>
<v-content style="background: #F5E8DF!important">
<v-container fluid fill-height class="px-1 py-2">
<v-flex xs12 fill-height pa-1>
<main-layout></main-layout>
</v-flex>
</v-container>
</v-content>
<one-footer></one-footer>
</v-app>
</div>
<!-- Vendor -->
<script src="../../../libs/vendor/moment.min.js"></script>
<script src="../../../libs/vendor/numeral.min.js"></script>
<script src="../../../libs/vendor/moment-locale-id.js"></script>
<script src="../../../libs/vendor/lodash.js"></script>
<script src="../../../libs/vendor/axios.min.js"></script>
<script src="../../../libs/vendor/vue.js"></script>
<script src="../../../libs/vendor/vuex.js"></script>
<script src="../../../libs/vendor/vuetify.js"></script>
<script src="../../../libs/vendor/httpVueLoader.js"></script>
<script src="../../../libs/one_global.js"></script>
<!-- App Script -->
<script type="module">
import { store } from './store.js';
window.store = store;
new Vue({
store,
el: "#app",
methods: {},
components: {
'one-navbar': httpVueLoader('../../../apps/components/oneNavbarComponent.vue'),
'one-footer': httpVueLoader('../../../apps/components/oneFooter.vue'),
'main-layout': httpVueLoader('./components/main-layout.vue')
}
})
</script>
<style>
[v-cloak] {
display: none;
}
</style>
</body>
</html>

View File

@@ -0,0 +1,197 @@
import * as api from "../api/api.js";
export default {
namespaced: true,
state: {
form_order: {
podate: moment(new Date()).format('YYYY-MM-DD'),
supplierID: "",
reference: "",
branchID: "",
gudangID: "",
typepajak: "percent",
valuepajak: 0,
typediskon: "percent",
valuediskon: 0,
catatan: ""
},
form_kontrak: {
nama_kontrak: '',
tanggal_kontrak: moment(new Date()).format('YYYY-MM-DD'),
tanggalAwal_kontrak: moment(new Date()).format('YYYY-MM-DD'),
tanggalAkhir_kontrak: moment(new Date()).format('YYYY-MM-DD'),
durasi_cicilan: 1,
jumlah_cicilan: 1,
tanggalBayar_cicilan: 1,
besarNilai_cicilan: 0,
type_downpayment: 'percent',
besarNilai_downpayment: 0
},
received_order: [],
summary_order: {
subtotal: 0,
diskon: 0,
pajak: 0,
downpayment: 0,
total_before_downpayment: 0,
total: 0
}
},
mutations: {
update_form_order(state, val) {
state.form_order = val
},
update_form_kontrak(state, val) {
state.form_kontrak = val
},
update_received_order(state, val) {
state.received_order = val
},
update_summary_order(state, val) {
state.summary_order = val
}
},
actions: {
async getDetailDataPO(context, poID) {
try {
const params = {
token: one_token(),
poID: poID,
};
const resp = await api.getDataKontrakPoAset(params);
if (resp.status != 'OK') {
throw new Error(resp.message);
}
let formOrder = {
podate: resp.data.podate,
supplierID: resp.data.supplierID,
reference: resp.data.reference,
branchID: resp.data.branchID,
gudangID: resp.data.gudangID,
typepajak: resp.data.typepajak,
valuepajak: parseFloat(resp.data.valuepajak),
typediskon: resp.data.typediskon,
valuediskon: parseFloat(resp.data.valuediskon),
catatan: resp.data.catatan
};
let formKontrak = {
nama_kontrak: resp.data.contractName,
tanggal_kontrak: resp.data.contractDate,
tanggalAwal_kontrak: resp.data.contractStart,
tanggalAkhir_kontrak: resp.data.contractEnd,
durasi_cicilan: resp.data.contractDuration,
jumlah_cicilan: resp.data.installmentNumber,
tanggalBayar_cicilan: resp.data.installmentDate,
besarNilai_cicilan: parseFloat(resp.data.installmentPayAmount),
type_downpayment: resp.data.installmentDownPaymentType,
besarNilai_downpayment: parseFloat(resp.data.installmentDownPayment),
};
let summary = resp.data.summary;
let selected_request = resp.data.detail;
selected_request.forEach(item => {
item.SupplierPrice = parseFloat(item.SupplierPrice)
item.DiskonAmount = parseFloat(item.DiskonAmount)
});
context.dispatch('orderAsset/listingGudang', resp.data.branchID, { root: true });
context.commit('update_form_kontrak', formKontrak);
context.commit("update_form_order", formOrder);
context.commit("update_received_order", selected_request);
context.commit("update_summary_order", summary);
context.dispatch('recalculateOrderSummary');
} catch (e) {
const snac = { color: 'error', msg: e.message, state: true };
context.commit("orderAsset/update_snackbar", snac, { root: true });
}
},
async recalculateOrderSummary(context) {
const formOrder = context.state.form_order;
const formKontrak = context.state.form_kontrak;
const items = JSON.parse(JSON.stringify(context.state.received_order));
const calculatedItems = items.map(item => {
const supplierPrice = parseCurrency(item.SupplierPrice);
const requestQty = item.detail.reduce((sum, detail) => {
return sum + parseCurrency(detail.RequestQty);
}, 0);
let itemDiscount = 0;
if (item.DiskonType == 'P') {
itemDiscount = supplierPrice * parseCurrency(item.DiskonAmount) / 100;
} else {
itemDiscount = parseCurrency(item.DiskonAmount);
}
const endPrice = Math.max(supplierPrice - itemDiscount, 0);
const tempTotal = requestQty * endPrice;
return {
...item,
RequestQty: requestQty,
EndPrice: endPrice,
TempTotal: tempTotal,
detail: item.detail.map(detail => ({
...detail,
SupplierPrice: supplierPrice
}))
};
});
const subtotal = calculatedItems.reduce((sum, item) => {
return sum + parseCurrency(item.TempTotal);
}, 0);
const diskon = calculateByType(
formOrder.typediskon,
formOrder.valuediskon,
subtotal
);
const subtotalAfterDiskon = Math.max(subtotal - diskon, 0);
const pajak = calculateByType(
formOrder.typepajak,
formOrder.valuepajak,
subtotalAfterDiskon
);
const totalBeforeDownpayment = subtotalAfterDiskon + pajak;
const downpayment = calculateByType(
formKontrak.type_downpayment,
formKontrak.besarNilai_downpayment,
totalBeforeDownpayment
);
const total = Math.max(totalBeforeDownpayment - downpayment, 0);
context.commit('update_received_order', calculatedItems);
context.commit('update_summary_order', {
subtotal: subtotal,
diskon: diskon,
pajak: pajak,
downpayment: downpayment,
total_before_downpayment: totalBeforeDownpayment,
total: total
});
}
}
}
function parseCurrency(value) {
let cleanValue = String(value || 0).replace(/\./g, '');
cleanValue = cleanValue.replace(',', '.');
return parseFloat(cleanValue) || 0;
}
function calculateByType(type, value, base) {
const amount = parseCurrency(value);
if (type == 'percent') {
return base * amount / 100;
}
return amount;
}

View File

@@ -0,0 +1,216 @@
import * as api from '../api/api.js';
export default {
namespaced: true,
state: {
snackbar: {
color: 'success',
msg: '',
state: false
},
user: {},
loading_process: false,
filter: {
startdate: moment(new Date()).format('YYYY-MM-DD'),
enddate: moment(new Date()).format('YYYY-MM-DD'),
status: "All",
search: ""
},
list_status: ['All', 'Draft', 'Pending', 'Approved', 'Rejected', 'Completed'],
list_order: {
records: [],
total: 0
},
currpage: 1,
list_cabang: [],
list_gudang: [],
list_supplier: [],
/* dialog confirm order */
dialog_confirm_order: false,
selected_order: {},
view_detail_mode: false,
dialog_attachment: false,
list_attachment: []
},
mutations: {
update_snackbar(state, val) {
state.snackbar = val
},
update_user(state, val) {
state.user = val
},
update_loading_process(state, val) {
state.loading_process = val
},
update_filter(state, val) {
state.filter = val
},
update_list_status(state, val) {
state.list_status = val
},
update_list_order(state, val) {
state.list_order = val
},
update_currpage(state, val) {
state.currpage = val
},
update_list_cabang(state, val) {
state.list_cabang = val
},
update_list_gudang(state, val) {
state.list_gudang = val
},
update_list_supplier(state, val) {
state.list_supplier = val
},
update_dialog_confirm_order(state, val) {
state.dialog_confirm_order = val
},
update_selected_order(state, val) {
state.selected_order = val
},
update_view_detail_mode(state, val) {
state.view_detail_mode = val
},
update_dialog_attachment(state, val) {
state.dialog_attachment = val
},
update_list_attachment(state, val) {
state.list_attachment = val
}
},
actions: {
async listingCabang(context) {
try {
let param = { token: one_token() }
const resp = await api.getListCabang(param);
if (resp.status != "OK") {
throw new Error(resp.message);
}
context.commit('update_list_cabang', resp.data);
} catch (e) {
const snac = { color: 'error', msg: e.message, state: true };
context.commit("common/update_snackbar", snac, { root: true });
}
},
async listingGudang(context, branchID) {
try {
let param = {
token: one_token(),
M_BranchID: branchID
}
const resp = await api.getListGudang(param);
if (resp.status != "OK") {
throw new Error(resp.message);
}
context.commit('update_list_gudang', resp.data);
} catch (e) {
const snac = { color: 'error', msg: e.message, state: true };
context.commit("common/update_snackbar", snac, { root: true });
}
},
async listingSupplier(context) {
try {
const params = { token: one_token() };
const resp = await api.getListSupplier(params);
if (resp.status != 'OK') {
throw new Error(resp.message);
}
context.commit('update_list_supplier', resp.data);
} catch (e) {
const snac = { color: 'error', msg: e.message, state: true };
context.commit("update_snackbar", snac, { root: true });
}
},
async getListingPOAsset(context) {
try {
const params = {
token: one_token(),
currpage: context.state.currpage,
...context.state.filter
};
const resp = await api.getDaftarPoAset(params);
if (resp.status != 'OK') {
throw new Error(resp.message);
}
context.commit('update_list_order', resp.data);
} catch (e) {
const snac = { color: 'error', msg: e.message, state: true };
context.commit("update_snackbar", snac);
}
},
async getUserApproveLevel(context) {
try {
const params = { token: one_token() };
const resp = await api.getUserApproveLevel(params);
if (resp.status != 'OK') {
throw new Error(resp.message);
}
context.commit('update_user', resp.data);
} catch (e) {
const snac = { color: 'error', msg: e.message, state: true };
context.commit("update_snackbar", snac);
}
},
async getAssetAttachment(context, param) {
try {
const params = {
token: one_token(),
contractID: param.contractID,
poID: param.poID
};
const resp = await api.getDaftarAttachment(params);
if (resp.status != 'OK') {
throw new Error(resp.message);
}
context.commit('update_list_attachment', resp.data);
} catch (e) {
const snac = { color: 'error', msg: e.message, state: true };
context.commit("update_snackbar", snac);
}
},
async confirmOrderAsset(context, poID) {
try {
context.state.loading_process = true;
const userlvl = context.state.user.M_UserM_ApproveLevelID
const params = {
token: one_token(),
approvelevel: userlvl,
poID: poID,
};
const resp = await api.updateApprovalPO(params);
if (resp.status != 'OK') {
throw new Error(resp.message);
}
if (userlvl == '2') {
const generate = await api.generatePOItemReceive(params);
if (generate.status !== 'OK') {
throw new Error(generate.message);
}
}
context.dispatch("getListingPOAsset");
context.state.loading_process = false;
context.state.view_detail_mode = false;
context.state.dialog_confirm_order = false;
} catch (e) {
context.state.loading_process = false;
const snac = { color: 'error', msg: e.message, state: true };
context.commit("update_snackbar", snac);
}
},
}
}

View File

@@ -0,0 +1,14 @@
import system from "../../../apps/modules/system/system.js";
import formView from "./modules/form-view.js";
import orderAsset from "./modules/order-asset.js";
export const store = new Vuex.Store({
modules: {
system: system,
orderAsset: orderAsset,
formView: formView
},
state: {},
mutations: {},
actions: {}
})

View File

@@ -91,6 +91,9 @@ module.exports = {
case "2": case "2":
baseURL += `/one-media/order-inventaris/${year}/` baseURL += `/one-media/order-inventaris/${year}/`
return baseURL + docs.img_url return baseURL + docs.img_url
case "3":
baseURL += `/one-media/order-asset/${year}/`
return baseURL + docs.img_url
default: default:
return null return null
} }

View File

@@ -168,22 +168,6 @@
<strong>Rp. {{ toRupiah(form_faktur.form_disc_amount) }}</strong> <strong>Rp. {{ toRupiah(form_faktur.form_disc_amount) }}</strong>
</td> </td>
</tr> </tr>
<!-- <tr>
<td :colspan="6" class="text-xs-right">
<strong class="ml-2">PAJAK (PPN)</strong>
</td>
<td :colspan="1" class="text-xs-right">
<strong>Rp. {{ toRupiah(form_faktur.form_tax_amount_ppn) }}</strong>
</td>
</tr> -->
<!-- <tr>
<td :colspan="6" class="text-xs-right">
<strong class="ml-2">PAJAK PENGHASILAN (PPH)</strong>
</td>
<td :colspan="1" class="text-xs-right">
<strong>Rp. {{ toRupiah(form_faktur.form_tax_amount_pph) }}</strong>
</td>
</tr> -->
<tr> <tr>
<td :colspan="6"> <td :colspan="6">
<strong class="ml-2">PAJAK</strong> <strong class="ml-2">PAJAK</strong>
@@ -192,6 +176,14 @@
<strong>Rp. {{ toRupiah(form_faktur.form_tax_amount_ppn + form_faktur.form_tax_amount_pph) }}</strong> <strong>Rp. {{ toRupiah(form_faktur.form_tax_amount_ppn + form_faktur.form_tax_amount_pph) }}</strong>
</td> </td>
</tr> </tr>
<tr v-show="form_faktur.type_purchase == 'aset'">
<td :colspan="6">
<strong class="ml-2">UANG MUKA</strong>
</td>
<td :colspan="1" class="text-xs-right">
<strong>Rp. {{ toRupiah(form_faktur.dp_amount) }}</strong>
</td>
</tr>
<tr> <tr>
<td :colspan="6"> <td :colspan="6">
<strong class="ml-2">GRAND TOTAL</strong> <strong class="ml-2">GRAND TOTAL</strong>

View File

@@ -96,7 +96,7 @@
<td class="text-xs-center pa-2">Rp. {{ toRupiah(props.item.SupplierInvoiceGrandTotal) }}</td> <td class="text-xs-center pa-2">Rp. {{ toRupiah(props.item.SupplierInvoiceGrandTotal) }}</td>
<td class="text-xs-center pa-2">{{ props.item.SupplierInvoiceStatus }}</td> <td class="text-xs-center pa-2">{{ props.item.SupplierInvoiceStatus }}</td>
<td class="text-xs-center pa-2"> <td class="text-xs-center pa-2">
<v-layout align-center justify-center row fill-height> <v-layout align-center justify-center row fill-height style="white-space: nowrap;">
<v-tooltip bottom class="pr-1"> <v-tooltip bottom class="pr-1">
<template v-slot:activator="{ on }"> <template v-slot:activator="{ on }">
<v-btn <v-btn
@@ -162,7 +162,7 @@
</v-tooltip> </v-tooltip>
</div> </div>
<div v-show="props.item.SupplierInvoiceStatus == 'Approved'"> <div v-show="props.item.SupplierInvoiceStatus == 'Approved'">
<v-tooltip bottom> <v-tooltip bottom class="pr-1">
<template v-slot:activator="{on}"> <template v-slot:activator="{on}">
<v-btn <v-btn
style="min-width: 40px; margin: 0;" style="min-width: 40px; margin: 0;"
@@ -175,6 +175,18 @@
<span>Detail Faktur</span> <span>Detail Faktur</span>
</v-tooltip> </v-tooltip>
</div> </div>
<v-tooltip bottom v-if="props.item.SupplierInvoiceStatus != 'Draft'">
<template v-slot:activator="{on}">
<v-btn
style="min-width: 40px; margin: 0;"
color="primary" small v-on="on" dark
@click="printout(props.item)"
>
<v-icon small>print</v-icon>
</v-btn>
</template>
<span>Cetak PDF</span>
</v-tooltip>
</v-layout> </v-layout>
</td> </td>
</tr> </tr>
@@ -218,6 +230,15 @@
</v-card-actions> </v-card-actions>
</v-card> </v-card>
</v-dialog> </v-dialog>
<one-dialog-print
:title="printtitle"
:width="printwidth"
:height="600"
:status="openprint"
:urlprint="urlprint"
@close-dialog-print="openprint = false"
></one-dialog-print>
</div> </div>
</template> </template>
@@ -237,6 +258,7 @@
"dialog-item": httpVueLoader("./dialogItem.vue"), "dialog-item": httpVueLoader("./dialogItem.vue"),
"dialog-view": httpVueLoader("./viewFaktur.vue"), "dialog-view": httpVueLoader("./viewFaktur.vue"),
"dialog-attachment": httpVueLoader("./dialog-attachment.vue"), "dialog-attachment": httpVueLoader("./dialog-attachment.vue"),
"one-dialog-print": httpVueLoader("../../common/oneDialogPrintX.vue"),
}, },
mounted() { mounted() {
this.$store.dispatch("data/getListSupplier") this.$store.dispatch("data/getListSupplier")
@@ -244,6 +266,10 @@
}, },
data() { data() {
return { return {
urlprint: "",
printtitle: "",
printwidth: "60%",
openprint: false,
filterDateForm: false, filterDateForm: false,
filterEndDateForm: false, filterEndDateForm: false,
confirmDialog: false, confirmDialog: false,
@@ -468,6 +494,15 @@
if (item.SupplierInvoiceID != '') { if (item.SupplierInvoiceID != '') {
this.$store.dispatch("form/verifyFaktur", {fakturID: item.SupplierInvoiceID}); this.$store.dispatch("form/verifyFaktur", {fakturID: item.SupplierInvoiceID});
} }
},
printout(val) {
this.printwidth = "60%";
this.printtitle = "";
let user = one_user();
let username = user && user.M_StaffName ? user.M_StaffName : "";
let tm = Date.now();
this.urlprint = BASE_URL + "/one-api/report/rpt_faktur/pdf?id=" + val.SupplierInvoiceID + "&username=" + username + "&tm=" + tm;
this.openprint = true;
} }
}, },
watch: { watch: {

View File

@@ -177,7 +177,7 @@ export default {
let duedate = moment(po.PurchaseOrderDate).add(Number(po.PurchaseOrderPaymentTerm), 'days').format("YYYY-MM-DD") let duedate = moment(po.PurchaseOrderDate).add(Number(po.PurchaseOrderPaymentTerm), 'days').format("YYYY-MM-DD")
form.form_duedate = duedate form.form_duedate = duedate
form.form_refnumber = po.PurchaseOrderRefNumber form.form_refnumber = po.SupplierInvoiceDeliveryOrderNumber
form.form_tax_percent_pph = po.PurchaseOrderTaxPercentPph form.form_tax_percent_pph = po.PurchaseOrderTaxPercentPph
form.form_tax_percent_ppn = po.PurchaseOrderTaxPercentPpn form.form_tax_percent_ppn = po.PurchaseOrderTaxPercentPpn
form.form_disc_po = po.DiscountType == 'R' ? po.SupplierInvoiceDiscountAmount : po.SupplierInvoiceDiscountPercent form.form_disc_po = po.DiscountType == 'R' ? po.SupplierInvoiceDiscountAmount : po.SupplierInvoiceDiscountPercent
@@ -288,7 +288,7 @@ export default {
let po = faktur.form_po let po = faktur.form_po
console.log(po) console.log(po)
context.commit("update_list_po", po) context.commit("update_list_po", po)
faktur.form_refnumber = temp.SupplierInvoiceRefNumber faktur.form_refnumber = temp.SupplierInvoiceDeliveryOrderNumber
faktur.form_supplier_invoicenum = temp.SupplierInvoiceSupplierInvoiceNumber faktur.form_supplier_invoicenum = temp.SupplierInvoiceSupplierInvoiceNumber
faktur.form_supplier_invoicedate = temp.SupplierInvoiceSupplierInvoiceDate faktur.form_supplier_invoicedate = temp.SupplierInvoiceSupplierInvoiceDate
faktur.form_tax_percent_pph = temp.SupplierInvoiceTaxPercentPph faktur.form_tax_percent_pph = temp.SupplierInvoiceTaxPercentPph
@@ -300,6 +300,8 @@ export default {
faktur.form_adjust_note = temp.SupplierInvoiceAdjustmentNote faktur.form_adjust_note = temp.SupplierInvoiceAdjustmentNote
faktur.form_shipping_cost = temp.SupplierInvoiceShippingCost faktur.form_shipping_cost = temp.SupplierInvoiceShippingCost
faktur.fakturID = temp.SupplierInvoiceID faktur.fakturID = temp.SupplierInvoiceID
faktur.type_purchase = temp.typePurchase
faktur.dp_amount = temp.dp_amount
context.commit("form/update_form_faktur", faktur, {root: true}) context.commit("form/update_form_faktur", faktur, {root: true})

View File

@@ -107,7 +107,17 @@ export default {
let pph = (sub - podisc) * (Number(faktur.form_tax_percent_pph) / 100) let pph = (sub - podisc) * (Number(faktur.form_tax_percent_pph) / 100)
let ppn = (sub - podisc) * (Number(faktur.form_tax_percent_ppn) / 100) let ppn = (sub - podisc) * (Number(faktur.form_tax_percent_ppn) / 100)
let grandtotal = (sub - podisc + pph + ppn) + Number(faktur.form_adjust_amount) + Number(faktur.form_shipping_cost)
let grandtotal = 0;
let dpamount = Number(faktur.dp_amount);
if (faktur.type_purchase == 'aset') {
grandtotal = (sub - podisc) + ( pph + ppn) - dpamount
grandtotal = grandtotal + Number(faktur.form_adjust_amount) + Number(faktur.form_shipping_cost)
} else {
grandtotal = (sub - podisc + pph + ppn) + Number(faktur.form_adjust_amount) + Number(faktur.form_shipping_cost)
}
// Store exact values with 2 decimal places using floor instead of rounding // Store exact values with 2 decimal places using floor instead of rounding
// This prevents rounding errors in financial calculations // This prevents rounding errors in financial calculations
@@ -124,6 +134,7 @@ export default {
faktur.form_tax_amount_ppn = 0.00 faktur.form_tax_amount_ppn = 0.00
faktur.form_adjust_amount = 0.00 faktur.form_adjust_amount = 0.00
faktur.form_adjust_note = "" faktur.form_adjust_note = ""
faktur.dp_amount = 0.00
} }
context.commit("update_form_faktur", faktur) context.commit("update_form_faktur", faktur)

View File

@@ -228,6 +228,7 @@
</td> </td>
<td <td
class="text-xs-center pa-2" class="text-xs-center pa-2"
style="white-space: nowrap;"
v-bind:class="{ v-bind:class="{
'amber lighten-4': isSelected(props.item), 'amber lighten-4': isSelected(props.item),
}" }"
@@ -263,24 +264,6 @@
> >
<v-icon small color="white">check_circle_outline</v-icon> <v-icon small color="white">check_circle_outline</v-icon>
</v-btn> </v-btn>
<!-- <v-btn
v-if="props.item.T_ItemOutIsConfirm == 'N' && approveLevelID == '2' && props.item.T_ItemOutApproveID == null"
style="min-width: 25px; height: 25px; margin: 0;"
small
color="black" title="Edit"
@click="updateRequest(props.item)"
>
<v-icon small color="white">edit</v-icon>
</v-btn>
<v-btn
v-if="props.item.T_ItemOutIsConfirm == 'N' && approveLevelID == '2' && props.item.T_ItemOutApproveID == null"
style="min-width: 25px; height: 25px; margin: 0;"
small
color="red" title="Hapus"
@click="deleteRequest(props.item)"
>
<v-icon small color="white">delete</v-icon>
</v-btn> -->
</span> </span>
<span v-if="props.item.T_ItemOutStatus == 'Process' || props.item.T_ItemOutStatus == 'Rejected'"> <span v-if="props.item.T_ItemOutStatus == 'Process' || props.item.T_ItemOutStatus == 'Rejected'">
<v-btn <v-btn
@@ -292,6 +275,19 @@
<v-icon small color="white">receipt</v-icon> <v-icon small color="white">receipt</v-icon>
</v-btn> </v-btn>
</span> </span>
<v-tooltip bottom v-if="props.item.T_ItemOutStatus != 'Draft'">
<template v-slot:activator="{ on }">
<v-btn
style="min-width: 25px; height: 25px; margin: 0;"
small
color="primary" title="Cetak PDF" v-on="on"
@click="printout(props.item)"
>
<v-icon small color="white">print</v-icon>
</v-btn>
</template>
<span>Cetak PDF</span>
</v-tooltip>
</td> </td>
</template> </template>
</v-data-table> </v-data-table>
@@ -377,6 +373,14 @@
<dialog-item-process></dialog-item-process> <dialog-item-process></dialog-item-process>
<dialog-item-preview></dialog-item-preview> <dialog-item-preview></dialog-item-preview>
<dialog-item-confirm></dialog-item-confirm> <dialog-item-confirm></dialog-item-confirm>
<one-dialog-print
:title="printtitle"
:width="printwidth"
:height="600"
:status="openprint"
:urlprint="urlprint"
@close-dialog-print="openprint = false"
></one-dialog-print>
</div> </div>
</template> </template>
@@ -415,9 +419,14 @@ module.exports = {
"dialog-item-confirm": httpVueLoader("./dialogItemConfirm.vue"), "dialog-item-confirm": httpVueLoader("./dialogItemConfirm.vue"),
"one-dialog-alert": httpVueLoader("../../common/oneDialogAlert.vue"), "one-dialog-alert": httpVueLoader("../../common/oneDialogAlert.vue"),
"one-dialog-error": httpVueLoader("../../common/oneDialogError.vue"), "one-dialog-error": httpVueLoader("../../common/oneDialogError.vue"),
"one-dialog-print": httpVueLoader("../../common/oneDialogPrintX.vue"),
}, },
data() { data() {
return { return {
urlprint: "",
printtitle: "",
printwidth: "60%",
openprint: false,
msgAlertDeleteRequest: "", msgAlertDeleteRequest: "",
dialogAlertDeleteRequest: false, dialogAlertDeleteRequest: false,
dialogAlertDeleteDetail: false, dialogAlertDeleteDetail: false,
@@ -935,6 +944,15 @@ module.exports = {
this.$store.dispatch("requester/getItemOuts", { this.$store.dispatch("requester/getItemOuts", {
ioID: val.T_ItemOutID ioID: val.T_ItemOutID
}); });
},
printout(val) {
this.printwidth = "60%";
this.printtitle = "";
let user = one_user();
let username = user && user.M_StaffName ? user.M_StaffName : "";
let tm = Date.now();
this.urlprint = BASE_URL + "/one-api/report/rpt_pengeluaran_barang/pdf?id=" + val.T_ItemOutID + "&username=" + username + "&tm=" + tm;
this.openprint = true;
} }
}, },

View File

@@ -38,6 +38,9 @@
>DAFTAR ITEM DIGUNAKAN</v-toolbar-title >DAFTAR ITEM DIGUNAKAN</v-toolbar-title
> >
<v-spacer></v-spacer> <v-spacer></v-spacer>
<v-btn icon @click="printout()" title="Cetak PDF">
<v-icon>print</v-icon>
</v-btn>
</v-toolbar> </v-toolbar>
<v-card class="pa-2"> <v-card class="pa-2">
<div class="d-flex justify-start align-center" style="gap: 0.5rem"> <div class="d-flex justify-start align-center" style="gap: 0.5rem">
@@ -317,6 +320,14 @@
</v-dialog> </v-dialog>
</template> </template>
<one-dialog-print
:title="printtitle"
:width="printwidth"
:height="600"
:status="openprint"
:urlprint="urlprint"
@close-dialog-print="openprint = false"
></one-dialog-print>
</div> </div>
</template> </template>
@@ -346,9 +357,14 @@ module.exports = {
components: { components: {
"one-dialog-alert": httpVueLoader("../../common/oneDialogAlert.vue"), "one-dialog-alert": httpVueLoader("../../common/oneDialogAlert.vue"),
"one-dialog-error": httpVueLoader("../../common/oneDialogError.vue"), "one-dialog-error": httpVueLoader("../../common/oneDialogError.vue"),
"one-dialog-print": httpVueLoader("../../common/oneDialogPrintX.vue"),
}, },
data() { data() {
return { return {
urlprint: "",
printtitle: "",
printwidth: "60%",
openprint: false,
headers: [ headers: [
{ {
text: "TANGGAL/NO", text: "TANGGAL/NO",
@@ -684,6 +700,23 @@ module.exports = {
enddate: this.$store.state.used.fEndDate enddate: this.$store.state.used.fEndDate
}; };
this.$store.dispatch("used/confirmItemUsed", prm); this.$store.dispatch("used/confirmItemUsed", prm);
},
printout() {
this.printwidth = "60%";
this.printtitle = "";
let user = one_user();
let username = user && user.M_StaffName ? user.M_StaffName : "";
let tm = Date.now();
let division_id = this.$store.state.usage.selectedDivision && this.$store.state.usage.selectedDivision.DivisionID
? this.$store.state.usage.selectedDivision.DivisionID
: 0;
let start_date = this.$store.state.used.fStartDate || moment(new Date()).format("YYYY-MM-DD");
let end_date = this.$store.state.used.fEndDate || moment(new Date()).format("YYYY-MM-DD");
this.urlprint = BASE_URL + "/one-api/report/rpt_pemakaian_item_divisi/pdf?start_date=" + start_date + "&end_date=" + end_date + "&division_id=" + division_id + "&username=" + username + "&tm=" + tm;
this.openprint = true;
} }
}, },
}; };

View File

@@ -0,0 +1,62 @@
const URL = "/one-api/map/InventarisCoaMapping";
async function request(endpoint, params) {
try {
const resp = await axios.post(URL + endpoint, params)
if (resp.status !== 200) {
throw new Error(resp.statusText);
}
return resp.data;
} catch (error) {
return {
status: "ERR",
message: error.message
}
}
}
export async function getListCoa(params) {
return request("/getListCoa", params);
}
export async function getListingInventarisGol(params) {
return request("/getListInventarisGol", params);
}
export async function getListItemInventaris(params) {
return request("/getListItemInventaris", params);
}
export async function getListInventorygolMapping(params) {
return request("/getListInventorygolMapping", params);
}
export async function getInvCoaMappingDetail(params) {
return request("/getInvCoaMappingDetail", params);
}
export async function createInvCoaMapping(params) {
return request("/createInvCoaMapping", params);
}
export async function editInvCoaMapping(params) {
return request("/editInvCoaMapping", params);
}
export async function deleteInvCoaMapping(params) {
return request("/deleteInvCoaMapping", params);
}
/* item inventory */
export async function createInvItemCoaMapping(params) {
return request("/createInvItemCoaMapping", params);
}
export async function editInvItemCoaMapping(params) {
return request("/editInvItemCoaMapping", params);
}
export async function deleteInvItemCoaMapping(params) {
return request("/deleteInvItemCoaMapping", params);
}

View File

@@ -0,0 +1,248 @@
<template>
<v-dialog v-model="dialog_add_mapping_default" persistent width="40vw">
<v-card>
<v-card-title class="headline grey lighten-2">Add Form</v-card-title>
<v-card-text>
<v-layout row wrap>
<v-flex xs12 pa-1>
<v-autocomplete :items="list_gol_inventaris.records" hide-details outline
label="Golongan Inventaris" item-text="M_InventarisGolName" item-value="M_InventarisGolID"
v-model="form.golID"></v-autocomplete>
</v-flex>
<v-flex xs12 pa-1>
<v-autocomplete :items="invCoa" hide-details outline label="Account Inventaris"
v-model="form.invCoaID" item-text="coaDescription" item-value="coaID"
:search-input.sync="searchInv" no-filter clearable>
<template slot="item" slot-scope="data">
<v-list-tile-content>
<v-list-tile-title v-html="data.item.coaAccountNo"></v-list-tile-title>
<v-list-tile-sub-title v-html="data.item.coaDescription"></v-list-tile-sub-title>
</v-list-tile-content>
</template>
</v-autocomplete>
</v-flex>
<v-flex xs12 pa-1>
<v-autocomplete :items="debtCoa" hide-details outline label="Account Hutang Inventaris"
v-model="form.debtCoaID" item-text="coaDescription" item-value="coaID"
:search-input.sync="searchDebt" no-filter clearable>
<template slot="item" slot-scope="data">
<v-list-tile-content>
<v-list-tile-title v-html="data.item.coaAccountNo"></v-list-tile-title>
<v-list-tile-sub-title v-html="data.item.coaDescription"></v-list-tile-sub-title>
</v-list-tile-content>
</template>
</v-autocomplete>
</v-flex>
<v-flex xs12 pa-1>
<v-autocomplete :items="bebanCoa" hide-details outline item-value="coaID"
label="Account Beban Penyusutan Inventaris" item-text="coaDescription"
v-model="form.bebanCoaID" :search-input.sync="searchBeban" no-filter clearable>
<template slot="item" slot-scope="data">
<v-list-tile-content>
<v-list-tile-title v-html="data.item.coaAccountNo"></v-list-tile-title>
<v-list-tile-sub-title v-html="data.item.coaDescription"></v-list-tile-sub-title>
</v-list-tile-content>
</template>
</v-autocomplete>
</v-flex>
<v-flex xs12 pa-1>
<v-autocomplete :items="accumCoa" hide-details outline item-value="coaID"
label="Account Akumulasi Penyusutan Inventaris" item-text="coaDescription"
v-model="form.accumCoaID" :search-input.sync="searchAccum" no-filter clearable>
<template slot="item" slot-scope="data">
<v-list-tile-content>
<v-list-tile-title v-html="data.item.coaAccountNo"></v-list-tile-title>
<v-list-tile-sub-title v-html="data.item.coaDescription"></v-list-tile-sub-title>
</v-list-tile-content>
</template>
</v-autocomplete>
</v-flex>
<v-flex xs12 pa-1>
<v-autocomplete :items="labaCoa" hide-details outline item-value="coaID"
label="Account Laba Pelepasan Inventaris" item-text="coaDescription"
v-model="form.labaCoaID" :search-input.sync="searchLaba" no-filter clearable>
<template slot="item" slot-scope="data">
<v-list-tile-content>
<v-list-tile-title v-html="data.item.coaAccountNo"></v-list-tile-title>
<v-list-tile-sub-title v-html="data.item.coaDescription"></v-list-tile-sub-title>
</v-list-tile-content>
</template>
</v-autocomplete>
</v-flex>
<v-flex xs12 pa-1>
<v-autocomplete :items="rugiCoa" hide-details outline item-value="coaID"
label="Account Rugi Pelepasan Inventaris" item-text="coaDescription"
v-model="form.rugiCoaID" :search-input.sync="searchRugi" no-filter clearable>
<template slot="item" slot-scope="data">
<v-list-tile-content>
<v-list-tile-title v-html="data.item.coaAccountNo"></v-list-tile-title>
<v-list-tile-sub-title v-html="data.item.coaDescription"></v-list-tile-sub-title>
</v-list-tile-content>
</template>
</v-autocomplete>
</v-flex>
</v-layout>
</v-card-text>
<v-card-actions>
<v-spacer></v-spacer>
<v-btn @click="batalForm()" color="error" class="white--text">Batal</v-btn>
<v-btn @click="simpanForm()" color="primary" class="white--text">Simpan</v-btn>
</v-card-actions>
</v-card>
</v-dialog>
</template>
<script>
module.exports = {
data() {
return {
searchInv: null,
searchDebt: null,
searchBeban: null,
searchAccum: null,
searchLaba: null,
searchRugi: null,
debounceTimeout: null
}
},
computed: {
dialog_add_mapping_default: {
get() {
return this.$store.state.invMap.dialog_add_mapping_default;
},
set(val) {
this.$store.commit("invMap/update_dialog_add_mapping_default", val);
}
},
form: {
get() {
return this.$store.state.invMap.form_gol;
},
set(val) {
this.$store.commit("invMap/update_form_gol", val);
}
},
list_gol_inventaris: {
get() {
return this.$store.state.invMap.list_gol_inventaris;
},
set(val) {
this.$store.commit("invMap/update_list_gol_inventaris", val);
}
},
loading_process() {
return this.$store.state.datacoa.loading_process;
},
invCoa() {
return this.$store.state.datacoa.invCoa;
},
debtCoa() {
return this.$store.state.datacoa.debtCoa;
},
bebanCoa() {
return this.$store.state.datacoa.bebanCoa;
},
accumCoa() {
return this.$store.state.datacoa.accumCoa;
},
labaCoa() {
return this.$store.state.datacoa.labaCoa;
},
rugiCoa() {
return this.$store.state.datacoa.rugiCoa;
},
},
methods: {
fetchCoa(keyword, key) {
this.$store.dispatch("datacoa/getListCoa", { keyword: keyword, key: key });
},
batalForm() {
this.form = {
golID: 0,
invCoaID: 0,
debtCoaID: 0,
bebanCoaID: 0,
accumCoaID: 0,
labaCoaID: 0,
rugiCoaID: 0
}
this.dialog_add_mapping_default = false;
},
simpanForm() {
if (!this.loading_process) {
const form = this.form;
const param = {
M_InventarisGolID: form.golID,
CoaInventarisID: form.invCoaID,
CoaHutangID: form.debtCoaID,
CoaPembelianID: form.invCoaID,
CoaBebanPenyusutanID: form.bebanCoaID,
CoaAkumulasiPenyusutanID: form.accumCoaID,
CoaLabaPelepasanID: form.labaCoaID,
CoaRugiPelepasanID: form.rugiCoa
}
if (form.M_InventarisCoaMappingID) {
param.M_InventarisCoaMappingID = form.M_InventarisCoaMappingID;
this.$store.dispatch("invMap/editInventarisGolMapping", param);
} else {
this.$store.dispatch("invMap/createInventarisGolMapping", param);
}
} else {
const snac = { state: true, msg: "terdapat ongoing proses", color: "warning" };
this.$store.commit('update_snackbar', snac);
}
}
},
watch: {
searchInv(val) {
if (!val) return;
clearTimeout(this.debounceTimeout);
this.debounceTimeout = setTimeout(() => {
this.fetchCoa(val, 'invCoa');
}, 500)
},
searchDebt(val) {
if (!val) return;
clearTimeout(this.debounceTimeout);
this.debounceTimeout = setTimeout(() => {
this.fetchCoa(val, 'debtCoa');
}, 500)
},
searchBeban(val) {
if (!val) return;
clearTimeout(this.debounceTimeout);
this.debounceTimeout = setTimeout(() => {
this.fetchCoa(val, 'bebanCoa');
}, 500)
},
searchAccum(val) {
if (!val) return;
clearTimeout(this.debounceTimeout);
this.debounceTimeout = setTimeout(() => {
this.fetchCoa(val, 'accumCoa');
}, 500)
},
searchLaba(val) {
if (!val) return;
clearTimeout(this.debounceTimeout);
this.debounceTimeout = setTimeout(() => {
this.fetchCoa(val, 'labaCoa');
}, 500)
},
searchRugi(val) {
if (!val) return;
clearTimeout(this.debounceTimeout);
this.debounceTimeout = setTimeout(() => {
this.fetchCoa(val, 'rugiCoa');
}, 500)
}
}
}
</script>

View File

@@ -0,0 +1,251 @@
<template>
<v-dialog v-model="dialog_add_mapping_item" persistent width="40vw">
<v-card>
<v-card-title class="headline grey lighten-2">
{{ selected_inventaris_item.itemCoaMapID > 0
? "Edit Account Item"
: "Add Account Item"
}} {{ selected_inventaris_item.M_ItemDesc }}
</v-card-title>
<v-card-text>
<v-layout row wrap>
<v-flex xs12 pa-1>
<v-autocomplete :items="invCoa" hide-details outline label="Account Inventaris"
v-model="form.invCoaID" item-text="coaDescription" item-value="coaID"
:search-input.sync="searchInv" no-filter clearable>
<template slot="item" slot-scope="data">
<v-list-tile-content>
<v-list-tile-title v-html="data.item.coaAccountNo"></v-list-tile-title>
<v-list-tile-sub-title v-html="data.item.coaDescription"></v-list-tile-sub-title>
</v-list-tile-content>
</template>
</v-autocomplete>
</v-flex>
<v-flex xs12 pa-1>
<v-autocomplete :items="debtCoa" hide-details outline label="Account Hutang Inventaris"
v-model="form.debtCoaID" item-text="coaDescription" item-value="coaID"
:search-input.sync="searchDebt" no-filter clearable>
<template slot="item" slot-scope="data">
<v-list-tile-content>
<v-list-tile-title v-html="data.item.coaAccountNo"></v-list-tile-title>
<v-list-tile-sub-title v-html="data.item.coaDescription"></v-list-tile-sub-title>
</v-list-tile-content>
</template>
</v-autocomplete>
</v-flex>
<v-flex xs12 pa-1>
<v-autocomplete :items="bebanCoa" hide-details outline item-value="coaID"
label="Account Beban Penyusutan Inventaris" item-text="coaDescription"
v-model="form.bebanCoaID" :search-input.sync="searchBeban" no-filter clearable>
<template slot="item" slot-scope="data">
<v-list-tile-content>
<v-list-tile-title v-html="data.item.coaAccountNo"></v-list-tile-title>
<v-list-tile-sub-title v-html="data.item.coaDescription"></v-list-tile-sub-title>
</v-list-tile-content>
</template>
</v-autocomplete>
</v-flex>
<v-flex xs12 pa-1>
<v-autocomplete :items="accumCoa" hide-details outline item-value="coaID"
label="Account Akumulasi Penyusutan Inventaris" item-text="coaDescription"
v-model="form.accumCoaID" :search-input.sync="searchAccum" no-filter clearable>
<template slot="item" slot-scope="data">
<v-list-tile-content>
<v-list-tile-title v-html="data.item.coaAccountNo"></v-list-tile-title>
<v-list-tile-sub-title v-html="data.item.coaDescription"></v-list-tile-sub-title>
</v-list-tile-content>
</template>
</v-autocomplete>
</v-flex>
<v-flex xs12 pa-1>
<v-autocomplete :items="labaCoa" hide-details outline item-value="coaID"
label="Account Laba Pelepasan Inventaris" item-text="coaDescription"
v-model="form.labaCoaID" :search-input.sync="searchLaba" no-filter clearable>
<template slot="item" slot-scope="data">
<v-list-tile-content>
<v-list-tile-title v-html="data.item.coaAccountNo"></v-list-tile-title>
<v-list-tile-sub-title v-html="data.item.coaDescription"></v-list-tile-sub-title>
</v-list-tile-content>
</template>
</v-autocomplete>
</v-flex>
<v-flex xs12 pa-1>
<v-autocomplete :items="rugiCoa" hide-details outline item-value="coaID"
label="Account Rugi Pelepasan Inventaris" item-text="coaDescription"
v-model="form.rugiCoaID" :search-input.sync="searchRugi" no-filter clearable>
<template slot="item" slot-scope="data">
<v-list-tile-content>
<v-list-tile-title v-html="data.item.coaAccountNo"></v-list-tile-title>
<v-list-tile-sub-title v-html="data.item.coaDescription"></v-list-tile-sub-title>
</v-list-tile-content>
</template>
</v-autocomplete>
</v-flex>
</v-layout>
</v-card-text>
<v-card-actions>
<v-spacer></v-spacer>
<v-btn @click="batalForm()" color="error" class="white--text">Batal</v-btn>
<v-btn @click="simpanForm()" color="primary" class="white--text">Simpan</v-btn>
</v-card-actions>
</v-card>
</v-dialog>
</template>
<script>
module.exports = {
data() {
return {
searchInv: null,
searchDebt: null,
searchBeban: null,
searchAccum: null,
searchLaba: null,
searchRugi: null,
debounceTimeout: null
}
},
computed: {
dialog_add_mapping_item: {
get() {
return this.$store.state.invItemMap.dialog_add_mapping_item;
},
set(val) {
this.$store.commit("invItemMap/update_dialog_add_mapping_item", val);
}
},
list_gol_inventaris: {
get() {
return this.$store.state.invMap.list_gol_inventaris;
},
set(val) {
this.$store.commit("invMap/update_list_gol_inventaris", val);
}
},
form: {
get() {
return this.$store.state.invItemMap.form;
},
set(val) {
this.$store.commit("invItemMap/update_form", val);
}
},
selected_inventaris_item() {
return this.$store.state.invItemMap.selected_inventaris_item;
},
loading_process() {
return this.$store.state.datacoa.loading_process;
},
invCoa() {
return this.$store.state.datacoa.invCoa;
},
debtCoa() {
return this.$store.state.datacoa.debtCoa;
},
bebanCoa() {
return this.$store.state.datacoa.bebanCoa;
},
accumCoa() {
return this.$store.state.datacoa.accumCoa;
},
labaCoa() {
return this.$store.state.datacoa.labaCoa;
},
rugiCoa() {
return this.$store.state.datacoa.rugiCoa;
},
},
methods: {
fetchCoa(keyword, key) {
this.$store.dispatch("datacoa/getListCoa", { keyword: keyword, key: key });
},
batalForm() {
this.form = {
invCoaID: 0,
debtCoaID: 0,
bebanCoaID: 0,
accumCoaID: 0,
labaCoaID: 0,
rugiCoaID: 0
}
this.dialog_add_mapping_item = false;
},
simpanForm() {
if (!this.loading_process) {
const form = this.form;
const selected = this.selected_inventaris_item
const param = {
M_ItemID: selected.M_ItemID,
M_InventarisItemCoaMappingID: selected.itemCoaMapID,
CoaInventarisID: form.invCoaID,
CoaHutangID: form.debtCoaID,
CoaPembelianID: form.invCoaID,
CoaBebanPenyusutanID: form.bebanCoaID,
CoaAkumulasiPenyusutanID: form.accumCoaID,
CoaLabaPelepasanID: form.labaCoaID,
CoaRugiPelepasanID: form.rugiCoaID
}
if (selected.itemCoaMapID > 0) {
this.$store.dispatch("invItemMap/editInvItemCoaMapping", param);
} else {
this.$store.dispatch("invItemMap/createInvItemCoaMapping", param);
}
} else {
const snac = { state: true, msg: "terdapat ongoing proses", color: "warning" };
this.$store.commit('update_snackbar', snac);
}
}
},
watch: {
searchInv(val) {
if (!val) return;
clearTimeout(this.debounceTimeout);
this.debounceTimeout = setTimeout(() => {
this.fetchCoa(val, 'invCoa');
}, 500)
},
searchDebt(val) {
if (!val) return;
clearTimeout(this.debounceTimeout);
this.debounceTimeout = setTimeout(() => {
this.fetchCoa(val, 'debtCoa');
}, 500)
},
searchBeban(val) {
if (!val) return;
clearTimeout(this.debounceTimeout);
this.debounceTimeout = setTimeout(() => {
this.fetchCoa(val, 'bebanCoa');
}, 500)
},
searchAccum(val) {
if (!val) return;
clearTimeout(this.debounceTimeout);
this.debounceTimeout = setTimeout(() => {
this.fetchCoa(val, 'accumCoa');
}, 500)
},
searchLaba(val) {
if (!val) return;
clearTimeout(this.debounceTimeout);
this.debounceTimeout = setTimeout(() => {
this.fetchCoa(val, 'labaCoa');
}, 500)
},
searchRugi(val) {
if (!val) return;
clearTimeout(this.debounceTimeout);
this.debounceTimeout = setTimeout(() => {
this.fetchCoa(val, 'rugiCoa');
}, 500)
}
}
}
</script>

View File

@@ -0,0 +1,41 @@
<template>
<v-dialog v-model="dialog_add_mapping" persistent width="50vw">
<v-card>
<v-card-title class="headline grey lighten-2">Add Form</v-card-title>
<v-card-text>
<v-layout></v-layout>
</v-card-text>
<v-card-actions>
<v-spacer></v-spacer>
<v-btn @click="batalForm()" color="error" class="white--text">Batal</v-btn>
<v-btn @click="simpanForm()" color="primary" class="white--text">Simpan</v-btn>
</v-card-actions>
</v-card>
</v-dialog>
</template>
<script>
module.exports = {
data() {
return {}
},
computed: {
dialog_add_mapping: {
get() {
return this.$store.state.invMap.dialog_add_mapping;
},
set(val) {
this.$store.commit("invMap/update_dialog_add_mapping", val);
}
}
},
methods: {
batalForm() {
},
simpanForm() {
}
}
}
</script>

View File

@@ -0,0 +1,72 @@
<template>
<v-dialog v-model="dialog_confirm_item" persistent width="40vw">
<v-card>
<v-card-title class="headline grey lighten-2">Konfirmasi Hapus</v-card-title>
<v-card-text>
<v-layout row wrap>
<v-flex xs12>
<p>
Apakah anda yakin akan menghapus data mapping item coa inventaris golongan
: <strong>{{ selected_inventaris_item.M_ItemDesc }}</strong> ?
</p>
</v-flex>
</v-layout>
</v-card-text>
<v-card-actions>
<v-spacer></v-spacer>
<v-btn @click="batal()" color="error" class="white--text">Batal</v-btn>
<v-btn @click="konfirmasi()" color="primary" class="white--text">Konfirmasi</v-btn>
</v-card-actions>
</v-card>
</v-dialog>
</template>
<script>
module.exports = {
data() {
return {}
},
computed: {
dialog_confirm_item: {
get() {
return this.$store.state.invItemMap.dialog_confirm_item;
},
set(val) {
this.$store.commit("invItemMap/update_dialog_confirm_item", val);
}
},
selected_inventaris_item: {
get() {
return this.$store.state.invItemMap.selected_inventaris_item;
},
set(val) {
this.$store.commit("invItemMap/update_selected_inventaris_item", val);
}
},
loading_process() {
return this.$store.state.invMap.loading_process;
}
},
methods: {
checkEmpty(obj) {
return obj && Object.keys(obj).length === 0 && obj.constructor === Object;
},
batal() {
this.selected_inventaris_item = {};
this.dialog_confirm_item = false;
},
konfirmasi() {
if (!this.loading_process) {
const itm = this.selected_inventaris_item;
this.$store.dispatch("invItemMap/deleteInvItemCoaMapping", {
M_InventarisItemCoaMappingID: itm.itemCoaMapID
})
} else {
const snac = { state: true, msg: "terdapat proses masih berjalan", color: "warning" };
this.$store.commit('invMap/update_snackbar', snac);
}
}
}
}
</script>

View File

@@ -0,0 +1,69 @@
<template>
<v-dialog v-model="dialog_confirm" persistent width="40vw">
<v-card>
<v-card-title class="headline grey lighten-2">Konfirmasi Hapus</v-card-title>
<v-card-text>
<v-layout row wrap>
<v-flex xs12>
<p>
Apakah anda yakin akan menghapus data mapping coa inventaris golongan
: <strong>{{ selected_inventaris_gol.M_InventarisGolName }}</strong> ?
</p>
</v-flex>
</v-layout>
</v-card-text>
<v-card-actions>
<v-spacer></v-spacer>
<v-btn @click="batal()" color="error" class="white--text">Batal</v-btn>
<v-btn @click="konfirmasi()" color="primary" class="white--text">Konfirmasi</v-btn>
</v-card-actions>
</v-card>
</v-dialog>
</template>
<script>
module.exports = {
data() {
return {}
},
computed: {
dialog_confirm: {
get() {
return this.$store.state.invMap.dialog_confirm;
},
set(val) {
this.$store.commit("invMap/update_dialog_confirm", val);
}
},
selected_inventaris_gol: {
get() {
return this.$store.state.invMap.selected_inventaris_gol;
},
set(val) {
this.$store.commit("invMap/update_selected_inventaris_gol", val);
}
},
loading_process() {
return this.$store.state.invMap.loading_process;
}
},
methods: {
checkEmpty(obj) {
return obj && Object.keys(obj).length === 0 && obj.constructor === Object;
},
batal() {
this.selected_inventaris_gol = {};
this.dialog_confirm = false;
},
konfirmasi() {
if (!this.loading_process) {
const inv = this.selected_inventaris_gol;
this.$store.dispatch("invMap/deleteInventarisGolMapping", inv.M_InventarisCoaMappingID);
} else {
const snac = { state: true, msg: "terdapat proses masih berjalan", color: "warning" };
this.$store.commit('invMap/update_snackbar', snac);
}
}
}
}
</script>

View File

@@ -0,0 +1,192 @@
<template>
<div>
<v-toolbar color="primary" dark>
<v-toolbar-title class="white--text">Inventaris Category</v-toolbar-title>
<v-spacer></v-spacer>
<v-btn icon @click="openDialogAdd()">
<v-icon large>add_box</v-icon>
</v-btn>
</v-toolbar>
<v-card class="pa-2">
<v-layout row wrap>
<v-flex xs4 pa-1>
<v-text-field v-model="keyword" hide-details outline
label="Cari" placeholder="Cari"></v-text-field>
</v-flex>
</v-layout>
</v-card>
<v-card class="pa-2 mt-2">
<v-data-table :headers="headers" :items="list_inventarisMapping.records" hide-actions class="elevation-1">
<template v-slot:items="props">
<tr @click="selected(props.item)" :class="{ 'amber lighten-4': isSelected(props.item) }">
<td class="text-xs-center pa-2">
{{ props.index + 1 }}
</td>
<td class="text-xs-left pa-2">
{{ props.item.M_InventarisGolName }}
</td>
<td class="text-xs-center pa-2">
<v-tooltip bottom>
<template v-slot:activator="{ on }">
<v-btn color="info" dark v-on="on" @click="openDialogEdit(props.item)"
small style="min-width: 40px; margin: 0;">
<v-icon small>edit</v-icon>
</v-btn>
</template>
<span>Edit</span>
</v-tooltip>
<v-tooltip bottom>
<template v-slot:activator="{ on }">
<v-btn color="error" dark v-on="on" @click="openDialogDelete(props.item)"
small style="min-width: 40px; margin: 0;">
<v-icon small>delete</v-icon>
</v-btn>
</template>
<span>Delete</span>
</v-tooltip>
</td>
</tr>
</template>
</v-data-table>
</v-card>
<v-snackbar v-model="snackbar.state" multi-line top :timeout="3000" :color="snackbar.color">
{{ snackbar.msg }}
<v-btn class="ml-2" round flat @click="snackbar.state = false">Tutup</v-btn>
</v-snackbar>
<dialog-add-form></dialog-add-form>
<dialog-add-form-item></dialog-add-form-item>
<dialog-confirm></dialog-confirm>
<dialog-confirm-item></dialog-confirm-item>
</div>
</template>
<script>
module.exports = {
components: {
'dialog-add-form': httpVueLoader('./dialog-add-mapping-def.vue'),
'dialog-add-form-item': httpVueLoader('./dialog-add-mapping-item.vue'),
'dialog-confirm': httpVueLoader('./dialog-confirm.vue'),
'dialog-confirm-item': httpVueLoader('./dialog-confirm-item.vue'),
},
mounted() {
this.$store.dispatch("invMap/getListingInventarisGol");
this.$store.dispatch("invMap/getListInventorygolMapping", "");
},
data() {
return {
keyword: "",
headers: [
{
text: "NO", align: "center", sortable: false, value: "nomor",
width: "10%", class: "pa-1 blue lighten-3 white--text",
},
{
text: "GOLONGAN INVENTARIS", align: "center", sortable: false, value: "nomor",
width: "60%", class: "pa-1 blue lighten-3 white--text",
},
{
text: "AKSI", align: "center", sortable: false, value: "nomor",
width: "30%", class: "pa-1 blue lighten-3 white--text",
},
]
}
},
computed: {
snackbar: {
get() {
return this.$store.state.invMap.snackbar;
},
set(val) {
this.$store.commit("invMap/update_snackbar", val);
}
},
selected_inventaris_gol: {
get() {
return this.$store.state.invMap.selected_inventaris_gol;
},
set(val) {
this.$store.commit("invMap/update_selected_inventaris_gol", val);
}
},
list_inventarisMapping: {
get() {
return this.$store.state.invMap.list_inventarisMapping;
},
set(val) {
this.$store.commit("invMap/update_list_inventarisMapping;", val);
}
}
},
methods: {
cariGolMapInventaris(keyword) {
setTimeout(() => {
this.$store.dispatch("invMap/getListInventorygolMapping", keyword);
}, 500);
},
openDialogAdd() {
this.hidrateCoaAutocomplete({});
this.$store.commit("invMap/update_dialog_add_mapping_default", true);
},
selected(item) {
this.$store.dispatch("invMap/getListItemInventaris", item.M_InventarisGolID);
this.selected_inventaris_gol = item;
},
isSelected(item) {
return item.M_InventarisGolID == this.selected_inventaris_gol.M_InventarisGolID
},
openDialogEdit(item) {
this.hidrateCoaAutocomplete(item);
this.selected_inventaris_gol = item;
const form = {
golID: item.M_InventarisGolID,
invCoaID: item.M_InventarisCoaMappingCoaInventarisID,
debtCoaID: item.M_InventarisCoaMappingCoaHutangID,
bebanCoaID: item.M_InventarisCoaMappingCoaBebanPenyusutanID,
accumCoaID: item.M_InventarisCoaMappingCoaAkumulasiPenyusutanID,
labaCoaID: item.M_InventarisCoaMappingCoaLabaPelepasanID,
rugiCoaID: item.M_InventarisCoaMappingCoaRugiPelepasanID,
M_InventarisCoaMappingID: item.M_InventarisCoaMappingID
}
this.$store.commit("invMap/update_form_gol", form);
this.$store.commit("invMap/update_dialog_add_mapping_default", true);
},
openDialogDelete(item) {
this.selected_inventaris_gol = item;
this.$store.commit("invMap/update_dialog_confirm", true);
},
hidrateCoaAutocomplete(item) {
this.$store.dispatch("datacoa/getListCoa", {
keyword: item.CoaInventarisAccountNo ?? "", key: "invCoa"
});
this.$store.dispatch("datacoa/getListCoa", {
keyword: item.CoaHutangAccountNo ?? "", key: "debtCoa"
});
this.$store.dispatch("datacoa/getListCoa", {
keyword: item.CoaBebanPenyusutanAccountNo ?? "", key: "bebanCoa"
});
this.$store.dispatch("datacoa/getListCoa", {
keyword: item.CoaAkumulasiPenyusutanAccountNo ?? "", key: "accumCoa"
});
this.$store.dispatch("datacoa/getListCoa", {
keyword: item.CoaLabaPelepasanAccountNo ?? "", key: "labaCoa"
});
this.$store.dispatch("datacoa/getListCoa", {
keyword: item.CoaRugiPelepasanAccountNo ?? "", key: "rugiCoa"
});
}
},
watch: {
keyword(newval, oldval) {
if (newval == oldval) return;
if (!newval) return;
if (newval.lenght < 1) return;
this.cariGolMapInventaris(newval);
}
}
}
</script>

View File

@@ -0,0 +1,227 @@
<template>
<div class="right-layout-container">
<v-toolbar color="primary" dark>
<v-toolbar-title class="white--text">Inventaris Item</v-toolbar-title>
<v-spacer></v-spacer>
</v-toolbar>
<v-card class="pa-2">
<v-layout row wrap>
<v-flex xs12 pa-1>
<h2>Setting Default Akun Inventaris</h2>
</v-flex>
<v-flex xs4 pa-1>
<strong>Akun Inventaris: </strong> <br>
{{ selected_inventaris_gol.CoaInventarisAccountNo }} <br>
{{ selected_inventaris_gol.CoaInventarisDescription }} <br>
</v-flex>
<v-flex xs4 pa-1>
<strong>Akun Inventaris Hutang: </strong> <br>
{{ selected_inventaris_gol.CoaHutangAccountNo }} <br>
{{ selected_inventaris_gol.CoaHutangDescription }} <br>
</v-flex>
<v-flex xs4 pa-1>
<strong>Akun Inventaris Beban Depresiasi: </strong> <br>
{{ selected_inventaris_gol.CoaBebanPenyusutanAccountNo }} <br>
{{ selected_inventaris_gol.CoaBebanPenyusutanDescription }} <br>
</v-flex>
<v-flex xs4 pa-1>
<strong>Akun Inventaris Akumulasi Depresiasi: </strong> <br>
{{ selected_inventaris_gol.CoaAkumulasiPenyusutanAccountNo }} <br>
{{ selected_inventaris_gol.CoaAkumulasiPenyusutanDescription }} <br>
</v-flex>
<v-flex xs4 pa-1>
<strong>Akun Inventaris Laba Pelepasan: </strong> <br>
{{ selected_inventaris_gol.CoaLabaPelepasanAccountNo }} <br>
{{ selected_inventaris_gol.CoaLabaPelepasanDescription }} <br>
</v-flex>
<v-flex xs4 pa-1>
<strong>Akun Inventaris Rugi Pelepasan: </strong> <br>
{{ selected_inventaris_gol.CoaRugiPelepasanAccountNo }} <br>
{{ selected_inventaris_gol.CoaRugiPelepasanDescription }} <br>
</v-flex>
</v-layout>
</v-card>
<v-card class="pa-2 table-card mt-2">
<v-layout row wrap>
<v-flex xs3 pa-1>
<v-text-field hide-details outline label="Cari" placeholder="Cari"></v-text-field>
</v-flex>
</v-layout>
<div class="table-scroll-wrapper">
<v-data-table :headers="headers" :items="list_item_inventaris.records" :pagination.sync="pagination"
:rows-per-page-items="[5, 10, 25]" class="elevation-1">
<template v-slot:items="props">
<tr>
<td class="text-xs-center pa-1">
{{ props.index + 1 }}
</td>
<td class="text-xs-left pa-1">
{{ props.item.M_ItemDesc }}
</td>
<td class="text-xs-left pa-1">
<v-layout row wrap>
<v-flex xs4 pa-1>
<strong>Akun Inventaris: </strong> <br>
{{ props.item.CoaInventarisAccountNo }} <br>
{{ props.item.CoaInventarisDescription }} <br>
</v-flex>
<v-flex xs4 pa-1>
<strong>Akun Inventaris Hutang: </strong> <br>
{{ props.item.CoaHutangAccountNo }} <br>
{{ props.item.CoaHutangDescription }} <br>
</v-flex>
<v-flex xs4 pa-1>
<strong>Akun Inventaris Beban Depresiasi: </strong> <br>
{{ props.item.CoaBebanPenyusutanAccountNo }} <br>
{{ props.item.CoaBebanPenyusutanDescription }} <br>
</v-flex>
<v-flex xs4 pa-1>
<strong>Akun Inventaris Akumulasi Depresiasi: </strong> <br>
{{ props.item.CoaAkumulasiPenyusutanAccountNo }} <br>
{{ props.item.CoaAkumulasiPenyusutanDescription }} <br>
</v-flex>
<v-flex xs4 pa-1>
<strong>Akun Inventaris Laba Pelepasan: </strong> <br>
{{ props.item.CoaLabaPelepasanAccountNo }} <br>
{{ props.item.CoaLabaPelepasanDescription }} <br>
</v-flex>
<v-flex xs4 pa-1>
<strong>Akun Inventaris Rugi Pelepasan: </strong> <br>
{{ props.item.CoaRugiPelepasanAccountNo }} <br>
{{ props.item.CoaRugiPelepasanDescription }} <br>
</v-flex>
</v-layout>
</td>
<td class="text-xs-center pa-1">
<v-tooltip bottom>
<template v-slot:activator="{ on }">
<v-btn color="info" dark v-on="on"
@click="editAcc(props.item)" small
style="min-width: 40px; margin: 0;"
>
<v-icon small>edit</v-icon>
</v-btn>
</template>
<span>Edit</span>
</v-tooltip>
<v-tooltip bottom>
<template v-slot:activator="{ on }">
<v-btn color="error" dark v-on="on"
@click="deleteAcc(props.item)" small
style="min-width: 40px; margin: 0;"
>
<v-icon small>delete</v-icon>
</v-btn>
</template>
<span>Delete</span>
</v-tooltip>
</td>
</tr>
</template>
</v-data-table>
</div>
</v-card>
</div>
</template>
<style scoped>
.right-layout-container {
display: flex;
flex-direction: column;
}
.table-card {
flex: 1;
min-height: 0;
display: flex;
flex-direction: column;
overflow: hidden;
}
</style>
<script>
module.exports = {
components: {
},
data() {
return {
pagination: {},
headers: [
{
text: "NO", align: "center", sortable: false, value: "nomor",
width: "5%", class: "pa-1 blue lighten-3 white--text",
},
{
text: "ITEM INVENTARIS", align: "center", sortable: false, value: "nomor",
width: "25%", class: "pa-1 blue lighten-3 white--text",
},
{
text: "ACCOUNT KHUSUS", align: "center", sortable: false, value: "nomor",
width: "60%", class: "pa-1 blue lighten-3 white--text",
},
{
text: "AKSI", align: "center", sortable: false, value: "nomor",
width: "10%", class: "pa-1 blue lighten-3 white--text",
},
]
}
},
computed: {
list_item_inventaris: {
get() {
return this.$store.state.invItemMap.list_item_inventaris
},
set(val) {
this.$store.commit("invItemMap/update_list_item_inventaris", val)
}
},
selected_inventaris_gol() {
return this.$store.state.invMap.selected_inventaris_gol;
}
},
methods: {
editAcc(item) {
this.hidrateCoaAutocomplete(item);
const form = {
invCoaID: item.M_InventarisItemCoaMappingCoaInventarisID,
debtCoaID: item.M_InventarisItemCoaMappingCoaHutangID,
bebanCoaID: item.M_InventarisItemCoaMappingCoaBebanPenyusutanID,
accumCoaID: item.M_InventarisItemCoaMappingCoaAkumulasiPenyusutanID,
labaCoaID: item.M_InventarisItemCoaMappingCoaLabaPelepasanID,
rugiCoaID: item.M_InventarisItemCoaMappingCoaRugiPelepasanID
}
this.$store.commit("invItemMap/update_form", form);
this.$store.commit("invItemMap/update_selected_inventaris_item", item)
this.$store.commit("invItemMap/update_dialog_add_mapping_item", true)
},
deleteAcc(item) {
this.$store.commit("invItemMap/update_selected_inventaris_item", item);
this.$store.commit("invItemMap/update_dialog_confirm_item", true);
},
hidrateCoaAutocomplete(item) {
this.$store.dispatch("datacoa/getListCoa", {
keyword: item.CoaInventarisAccountNo ?? "", key: "invCoa"
});
this.$store.dispatch("datacoa/getListCoa", {
keyword: item.CoaHutangAccountNo ?? "", key: "debtCoa"
});
this.$store.dispatch("datacoa/getListCoa", {
keyword: item.CoaBebanPenyusutanAccountNo ?? "", key: "bebanCoa"
});
this.$store.dispatch("datacoa/getListCoa", {
keyword: item.CoaAkumulasiPenyusutanAccountNo ?? "", key: "accumCoa"
});
this.$store.dispatch("datacoa/getListCoa", {
keyword: item.CoaLabaPelepasanAccountNo ?? "", key: "labaCoa"
});
this.$store.dispatch("datacoa/getListCoa", {
keyword: item.CoaRugiPelepasanAccountNo ?? "", key: "rugiCoa"
});
}
}
}
</script>

View File

@@ -0,0 +1,64 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<link rel="stylesheet" href="../../../libs/vendor/css/google-fonts.css">
<link rel="stylesheet" href="../../../libs/vendor/css/icomoon-fonts.css">
<link rel="stylesheet" href="../../../libs/vendor/css/vuetify.min.css">
<title>ONE</title>
</head>
<body>
<div v-cloak id="app">
<v-app id="smartApp">
<one-navbar></one-navbar>
<v-content style="background: #F5E8DF!important">
<v-container fluid fill-height class="px-1 py-2">
<v-flex xs4 class="left" fill-height pa-1>
<one-left></one-left>
</v-flex>
<v-flex xs8 class="right" fill-height pa-1>
<one-right></one-right>
</v-flex>
</v-container>
</v-content>
<one-footer></one-footer>
</v-app>
</div>
<!-- Vendor -->
<script src="../../../libs/vendor/moment.min.js"></script>
<script src="../../../libs/vendor/numeral.min.js"></script>
<script src="../../../libs/vendor/moment-locale-id.js"></script>
<script src="../../../libs/vendor/lodash.js"></script>
<script src="../../../libs/vendor/axios.min.js"></script>
<script src="../../../libs/vendor/vue.js"></script>
<script src="../../../libs/vendor/vuex.js"></script>
<script src="../../../libs/vendor/vuetify.js"></script>
<script src="../../../libs/vendor/httpVueLoader.js"></script>
<script src="../../../libs/one_global.js"></script>
<!-- App Script -->
<script type="module">
import { store } from './store.js';
window.store = store;
new Vue({
store,
el: "#app",
methods: {},
components: {
'one-navbar': httpVueLoader('../../../apps/components/oneNavbarComponent.vue'),
'one-footer': httpVueLoader('../../../apps/components/oneFooter.vue'),
'one-left': httpVueLoader('./components/left-layout.vue'),
'one-right': httpVueLoader('./components/right-layout.vue'),
}
})
</script>
<style>
[v-cloak] {
display: none;
}
</style>
</body>
</html>

View File

@@ -0,0 +1,53 @@
import * as api from "../api/api.js";
export default {
namespaced: true,
state: {
invCoa: [],
debtCoa: [],
bebanCoa: [],
accumCoa: [],
labaCoa: [],
rugiCoa: []
},
mutations: {
update_invCoa(state, val) {
state.invCoa = val
},
update_debtCoa(state, val) {
state.debtCoa = val
},
update_bebanCoa(state, val) {
state.bebanCoa = val
},
update_accumCoa(state, val) {
state.accumCoa = val
},
update_labaCoa(state, val) {
state.labaCoa = val
},
update_rugiCoa(state, val) {
state.rugiCoa = val
}
},
actions: {
async getListCoa(context, param) {
try {
let params = {
token: one_token(),
keyword: param.keyword
}
const resp = await api.getListCoa(params);
if (resp.status != 'OK') {
throw new Error(resp.message);
}
let update = "update_" + param.key;
context.commit(update, resp.data);
} catch (e) {
const snac = { state: true, msg: e.message, color: "error" };
context.commit('invMap/update_snackbar', snac, { root: true });
}
},
}
}

View File

@@ -0,0 +1,113 @@
import * as api from "../api/api.js";
export default {
namespaced: true,
state: {
list_item_inventaris: {
records: [],
total: 0
},
dialog_add_mapping_item: false,
selected_inventaris_item: {},
form: {
invCoaID: 0,
debtCoaID: 0,
bebanCoaID: 0,
accumCoaID: 0,
labaCoaID: 0,
rugiCoaID: 0
},
dialog_confirm_item: false
},
mutations: {
update_dialog_add_mapping_item(state, val) {
state.dialog_add_mapping_item = val
},
update_selected_inventaris_item(state, val) {
state.selected_inventaris_item = val
},
update_list_item_inventaris(state, val) {
state.list_item_inventaris = val;
},
update_form(state, val) {
state.form = val
},
update_dialog_confirm_item(state, val) {
state.dialog_confirm_item = val
}
},
actions: {
async createInvItemCoaMapping(context, params) {
try {
context.commit("invMap/update_loading_process", true, {root: true});
params.token = one_token();
const resp = await api.createInvItemCoaMapping(params);
if (resp.status != 'OK') {
throw new Error(resp.message);
}
const snac = { state: true, msg: resp.data, color: "success" };
context.commit('invMap/update_snackbar', snac, {root: true});
const golID = context.state.selected_inventaris_item.itemGolID;
context.dispatch("invMap/getListItemInventaris", golID, {root: true});
context.commit("update_selected_inventaris_item", {});
context.commit("invMap/update_loading_process", false, {root: true});
context.commit('update_dialog_add_mapping_item', false);
} catch (error) {
context.commit("invMap/update_loading_process", false, {root: true});
const snac = { state: true, msg: error.message, color: "error" };
context.commit('invMap/update_snackbar', snac, {root: true});
}
},
async editInvItemCoaMapping(context, params) {
try {
context.commit("invMap/update_loading_process", true, {root: true});
params.token = one_token();
const resp = await api.editInvItemCoaMapping(params);
if (resp.status != 'OK') {
throw new Error(resp.message);
}
const snac = { state: true, msg: resp.data, color: "success" };
context.commit('invMap/update_snackbar', snac, {root: true});
const golID = context.state.selected_inventaris_item.itemGolID;
context.dispatch("invMap/getListItemInventaris", golID, {root: true});
context.commit("update_selected_inventaris_item", {});
context.commit("invMap/update_loading_process", false, {root: true});
context.commit('update_dialog_add_mapping_item', false);
} catch (error) {
context.commit("invMap/update_loading_process", false, {root: true});
const snac = { state: true, msg: error.message, color: "error" };
context.commit('invMap/update_snackbar', snac, {root: true});
}
},
async deleteInvItemCoaMapping(context, params) {
try {
context.commit("invMap/update_loading_process", true, {root: true});
params.token = one_token();
const resp = await api.deleteInvItemCoaMapping(params);
if (resp.status != 'OK') {
throw new Error(resp.message);
}
const snac = { state: true, msg: resp.data, color: "success" };
context.commit('invMap/update_snackbar', snac, {root: true});
const golID = context.state.selected_inventaris_item.itemGolID;
context.dispatch("invMap/getListItemInventaris", golID, {root: true});
context.commit("update_selected_inventaris_item", {});
context.commit("invMap/update_loading_process", false, {root: true});
context.commit("update_dialog_confirm_item", false);
} catch (error) {
context.commit("invMap/update_loading_process", false, {root: true});
const snac = { state: true, msg: error.message, color: "error" };
context.commit('invMap/update_snackbar', snac, {root: true});
}
}
}
}

View File

@@ -0,0 +1,179 @@
import * as api from "../api/api.js";
export default {
namespaced: true,
state: {
snackbar: {
state: false,
msg: "",
color: "error"
},
loading_process: false,
list_inventarisMapping: {
records: [],
total: 0
},
selected_inventaris_gol: {},
/* dialog inventaris gol for default */
dialog_add_mapping_default: false,
form_gol: {
golID: 0,
invCoaID: 0,
debtCoaID: 0,
bebanCoaID: 0,
accumCoaID: 0,
labaCoaID: 0,
rugiCoaID: 0
},
list_gol_inventaris: {
records: [],
total: 0
},
dialog_confirm: false
},
mutations: {
update_snackbar(state, val) {
state.snackbar = val;
},
update_loading_process(state, val) {
state.loading_process = val;
},
update_list_inventarisMapping(state, val) {
state.list_inventarisMapping = val
},
update_selected_inventaris_gol(state, val) {
state.selected_inventaris_gol = val
},
/* dialog invetaris gol for default */
update_dialog_add_mapping_default(state, val) {
state.dialog_add_mapping_default = val
},
update_form_gol(state, val) {
state.form_gol = val
},
update_list_gol_inventaris(state, val) {
state.list_gol_inventaris = val;
},
update_dialog_confirm(state, val) {
state.dialog_confirm = val
}
},
actions: {
async getListingInventarisGol(context) {
try {
let params = { token: one_token() }
const resp = await api.getListingInventarisGol(params);
if (resp.status != 'OK') {
throw new Error(resp.message);
}
context.commit('update_list_gol_inventaris', resp.data);
} catch (e) {
const snac = { state: true, msg: e.message, color: "error" };
context.commit('update_snackbar', snac);
}
},
async getListItemInventaris(context, id) {
try {
let params = {
token: one_token(),
golID: id
}
const resp = await api.getListItemInventaris(params);
if (resp.status != 'OK') {
throw new Error(resp.message);
}
context.commit('invItemMap/update_list_item_inventaris', resp.data, {root: true});
} catch (e) {
const snac = { state: true, msg: e.message, color: "error" };
context.commit('update_snackbar', snac);
}
},
async getListInventorygolMapping(context, keyword) {
try {
let params = {
token: one_token(),
keyword: keyword,
currpage: 1
}
const resp = await api.getListInventorygolMapping(params);
if (resp.status != 'OK') {
throw new Error(resp.message);
}
context.commit("update_list_inventarisMapping", resp.data);
} catch (e) {
const snac = { state: true, msg: e.message, color: "error" };
context.commit('update_snackbar', snac);
}
},
async createInventarisGolMapping(context, params) {
try {
context.state.loading_process = true;
params.token = one_token();
const resp = await api.createInvCoaMapping(params);
if (resp.status != 'OK') {
throw new Error(resp.message);
}
const snac = { state: true, msg: resp.data, color: "success" };
context.commit('update_snackbar', snac);
context.dispatch("getListInventorygolMapping");
context.state.loading_process = false;
context.state.dialog_add_mapping_default = false;
} catch (e) {
context.state.loading_process = false;
const snac = { state: true, msg: e.message, color: "error" };
context.commit('update_snackbar', snac);
}
},
async editInventarisGolMapping(context, params) {
try {
context.state.loading_process = true;
params.token = one_token();
const resp = await api.editInvCoaMapping(params);
if (resp.status != 'OK') {
throw new Error(resp.message);
}
const snac = { state: true, msg: resp.data, color: "success" };
context.commit('update_snackbar', snac);
context.state.loading_process = false;
context.state.dialog_add_mapping_default = false;
} catch (e) {
context.state.loading_process = false;
const snac = { state: true, msg: e.message, color: "error" };
context.commit('update_snackbar', snac);
}
},
async deleteInventarisGolMapping(context, id) {
try {
context.state.loading_process = true;
params = {
token: one_token(),
M_InventarisCoaMappingID: id
};
const resp = await api.deleteInvCoaMapping(params);
if (resp.status != 'OK') {
throw new Error(resp.message);
}
const snac = { state: true, msg: resp.data, color: "success" };
context.commit('update_snackbar', snac);
context.state.loading_process = false;
context.state.dialog_add_mapping_default = false;
} catch (e) {
context.state.loading_process = false;
const snac = { state: true, msg: e.message, color: "error" };
context.commit('update_snackbar', snac);
}
}
}
}

View File

@@ -0,0 +1,16 @@
import system from "../../../apps/modules/system/system.js";
import datacoa from "./modules/datacoa.js";
import invItemMap from "./modules/invItemMap.js";
import invMap from "./modules/invMap.js";
export const store = new Vuex.Store({
modules: {
system: system,
invMap: invMap,
datacoa: datacoa,
invItemMap: invItemMap
},
state: {},
mutations: {},
actions: {}
})

View File

@@ -217,7 +217,8 @@
</td> </td>
<td <td
class="text-xs-center" class="text-xs-center pa-2"
style="white-space: nowrap;"
v-bind:class="{ v-bind:class="{
'amber lighten-4': isSelected(props.item), 'amber lighten-4': isSelected(props.item),
}" }"
@@ -235,6 +236,18 @@
</template> </template>
<span>Lihat Detail</span> <span>Lihat Detail</span>
</v-tooltip> </v-tooltip>
<v-tooltip bottom v-if="props.item.MutasiRequestStatus != 'Draft'">
<template v-slot:activator="{ on }">
<v-btn
style="min-width: 30px; height: 30px; margin: 0;"
small @click="printout(props.item)" color="primary"
class="mt-1 mb-1"
>
<v-icon small color="white" v-on="on">print</v-icon>
</v-btn>
</template>
<span>Cetak PDF</span>
</v-tooltip>
</div> </div>
<div v-show="props.item.MutasiRequestStatus == 'Approved'"> <div v-show="props.item.MutasiRequestStatus == 'Approved'">
<v-tooltip bottom> <v-tooltip bottom>
@@ -249,6 +262,18 @@
</template> </template>
<span>Kirim Mutasi</span> <span>Kirim Mutasi</span>
</v-tooltip> </v-tooltip>
<v-tooltip bottom>
<template v-slot:activator="{ on }">
<v-btn
style="min-width: 30px; height: 30px; margin: 0;"
small @click="printout(props.item)" color="primary"
class="mt-1 mb-1"
>
<v-icon small color="white" v-on="on">print</v-icon>
</v-btn>
</template>
<span>Cetak PDF</span>
</v-tooltip>
</div> </div>
</td> </td>
</tr> </tr>
@@ -267,6 +292,14 @@
<one-dialog-item-mutasi></one-dialog-item-mutasi> <one-dialog-item-mutasi></one-dialog-item-mutasi>
<one-dialog-send-layout></one-dialog-send-layout> <one-dialog-send-layout></one-dialog-send-layout>
<one-dialog-view-layout></one-dialog-view-layout> <one-dialog-view-layout></one-dialog-view-layout>
<one-dialog-print
:title="printtitle"
:width="printwidth"
:height="600"
:status="openprint"
:urlprint="urlprint"
@close-dialog-print="openprint = false"
></one-dialog-print>
</div> </div>
</template> </template>
@@ -303,9 +336,14 @@ module.exports = {
"approve-dialog": httpVueLoader("./approveDialog.vue"), "approve-dialog": httpVueLoader("./approveDialog.vue"),
"one-dialog-alert": httpVueLoader("../../common/oneDialogAlert.vue"), "one-dialog-alert": httpVueLoader("../../common/oneDialogAlert.vue"),
"one-dialog-error": httpVueLoader("../../common/oneDialogError.vue"), "one-dialog-error": httpVueLoader("../../common/oneDialogError.vue"),
"one-dialog-print": httpVueLoader("../../common/oneDialogPrintX.vue"),
}, },
data() { data() {
return { return {
urlprint: "",
printtitle: "",
printwidth: "60%",
openprint: false,
msgAlertDeleteRequest: "", msgAlertDeleteRequest: "",
dialogAlertDeleteRequest: false, dialogAlertDeleteRequest: false,
dialogAlertDeleteDetail: false, dialogAlertDeleteDetail: false,
@@ -593,6 +631,16 @@ module.exports = {
this.$store.dispatch("form/getCategory"); this.$store.dispatch("form/getCategory");
this.$store.dispatch("form/getBranchAsal"); this.$store.dispatch("form/getBranchAsal");
this.$store.dispatch("form/getBranchTujuan"); this.$store.dispatch("form/getBranchTujuan");
},
printout(val) {
this.printwidth = "60%";
this.printtitle = "";
let user = one_user();
let username = user && user.M_StaffName ? user.M_StaffName : "";
let tm = Date.now();
let id = val.MutasiHandoverID ? val.MutasiHandoverID : val.MutasiRequestID;
this.urlprint = BASE_URL + "/one-api/report/rpt_penyerahan_mutasi/pdf?id=" + id + "&username=" + username + "&tm=" + tm;
this.openprint = true;
} }
}, },
}; };

View File

@@ -223,7 +223,8 @@
</td> </td>
<td <td
class="text-xs-center" class="text-xs-center pa-2"
style="white-space: nowrap;"
v-bind:class="{ v-bind:class="{
'amber lighten-4': isSelected(props.item), 'amber lighten-4': isSelected(props.item),
}" }"
@@ -253,6 +254,18 @@
</template> </template>
<span>Lihat Detail</span> <span>Lihat Detail</span>
</v-tooltip> </v-tooltip>
<v-tooltip bottom>
<template v-slot:activator="{ on }">
<v-btn
style="min-width: 30px; height: 30px; margin: 0;"
small @click="printout(props.item)" color="primary"
class="mt-1 mb-1"
>
<v-icon small color="white" v-on="on">print</v-icon>
</v-btn>
</template>
<span>Cetak PDF</span>
</v-tooltip>
</div> </div>
<div v-show="props.item.MutasiHandoverStatus == 'Sent'"> <div v-show="props.item.MutasiHandoverStatus == 'Sent'">
<v-tooltip bottom> <v-tooltip bottom>
@@ -286,6 +299,14 @@
<one-dialog-receive-layout></one-dialog-receive-layout> <one-dialog-receive-layout></one-dialog-receive-layout>
<one-dialog-view-layout></one-dialog-view-layout> <one-dialog-view-layout></one-dialog-view-layout>
<one-dialog-mutasi></one-dialog-mutasi> <one-dialog-mutasi></one-dialog-mutasi>
<one-dialog-print
:title="printtitle"
:width="printwidth"
:height="600"
:status="openprint"
:urlprint="urlprint"
@close-dialog-print="openprint = false"
></one-dialog-print>
</div> </div>
</template> </template>
@@ -323,9 +344,14 @@ module.exports = {
"approve-dialog": httpVueLoader("./approveDialog.vue"), "approve-dialog": httpVueLoader("./approveDialog.vue"),
"one-dialog-alert": httpVueLoader("../../common/oneDialogAlert.vue"), "one-dialog-alert": httpVueLoader("../../common/oneDialogAlert.vue"),
"one-dialog-error": httpVueLoader("../../common/oneDialogError.vue"), "one-dialog-error": httpVueLoader("../../common/oneDialogError.vue"),
"one-dialog-print": httpVueLoader("../../common/oneDialogPrintX.vue"),
}, },
data() { data() {
return { return {
urlprint: "",
printtitle: "",
printwidth: "60%",
openprint: false,
msgAlertDeleteRequest: "", msgAlertDeleteRequest: "",
dialogAlertDeleteRequest: false, dialogAlertDeleteRequest: false,
dialogAlertDeleteDetail: false, dialogAlertDeleteDetail: false,
@@ -624,6 +650,15 @@ module.exports = {
this.$store.commit("mutasi/update_indeterminatex", false); this.$store.commit("mutasi/update_indeterminatex", false);
this.$store.commit("mutasi/update_selected_barcode", []); this.$store.commit("mutasi/update_selected_barcode", []);
this.$store.dispatch("mutasi/getBarcodes"); this.$store.dispatch("mutasi/getBarcodes");
},
printout(val) {
this.printwidth = "60%";
this.printtitle = "";
let user = one_user();
let username = user && user.M_StaffName ? user.M_StaffName : "";
let tm = Date.now();
this.urlprint = BASE_URL + "/one-api/report/rpt_penerimaan_mutasi/pdf?id=" + val.MutasiHandoverID + "&username=" + username + "&tm=" + tm;
this.openprint = true;
} }
}, },
}; };

View File

@@ -217,12 +217,13 @@
</td> </td>
<td <td
class="text-xs-center" class="text-xs-center pa-2"
style="white-space: nowrap;"
v-bind:class="{ v-bind:class="{
'amber lighten-4': isSelected(props.item), 'amber lighten-4': isSelected(props.item),
}" }"
> >
<div v-show="props.item.MutasiRequestStatus === 'Draft'"> <template v-if="props.item.MutasiRequestStatus === 'Draft'">
<v-tooltip bottom> <v-tooltip bottom>
<template v-slot:activator="{ on }"> <template v-slot:activator="{ on }">
<v-btn <v-btn
@@ -247,7 +248,21 @@
</template> </template>
<span>Hapus</span> <span>Hapus</span>
</v-tooltip> </v-tooltip>
</div> </template>
<template v-else>
<v-tooltip bottom>
<template v-slot:activator="{ on }">
<v-btn
style="min-width: 30px; height: 30px; margin: 0;"
small @click="printout(props.item)" color="primary"
class="mt-1 mb-1"
>
<v-icon small color="white" v-on="on">print</v-icon>
</v-btn>
</template>
<span>Cetak PDF</span>
</v-tooltip>
</template>
</td> </td>
</tr> </tr>
</template> </template>
@@ -265,6 +280,14 @@
<one-dialog-item-mutasi></one-dialog-item-mutasi> <one-dialog-item-mutasi></one-dialog-item-mutasi>
<one-dialog-form-edit-mutasi></one-dialog-form-edit-mutasi> <one-dialog-form-edit-mutasi></one-dialog-form-edit-mutasi>
<one-dialog-rm-layout></one-dialog-rm-layout> <one-dialog-rm-layout></one-dialog-rm-layout>
<one-dialog-print
:title="printtitle"
:width="printwidth"
:height="600"
:status="openprint"
:urlprint="urlprint"
@close-dialog-print="openprint = false"
></one-dialog-print>
</div> </div>
</template> </template>
@@ -301,9 +324,14 @@ module.exports = {
"approve-dialog": httpVueLoader("./approveDialog.vue"), "approve-dialog": httpVueLoader("./approveDialog.vue"),
"one-dialog-alert": httpVueLoader("../../common/oneDialogAlert.vue"), "one-dialog-alert": httpVueLoader("../../common/oneDialogAlert.vue"),
"one-dialog-error": httpVueLoader("../../common/oneDialogError.vue"), "one-dialog-error": httpVueLoader("../../common/oneDialogError.vue"),
"one-dialog-print": httpVueLoader("../../common/oneDialogPrintX.vue"),
}, },
data() { data() {
return { return {
urlprint: "",
printtitle: "",
printwidth: "60%",
openprint: false,
msgAlertDeleteRequest: "", msgAlertDeleteRequest: "",
dialogAlertDeleteRequest: false, dialogAlertDeleteRequest: false,
dialogAlertDeleteDetail: false, dialogAlertDeleteDetail: false,
@@ -546,6 +574,15 @@ module.exports = {
deleteRM(data) { deleteRM(data) {
this.$store.commit("mutasi/update_selected_list_data", data); this.$store.commit("mutasi/update_selected_list_data", data);
this.$store.commit("mutasi/update_dialog_delete", true); this.$store.commit("mutasi/update_dialog_delete", true);
},
printout(val) {
this.printwidth = "60%";
this.printtitle = "";
let user = one_user();
let username = user && user.M_StaffName ? user.M_StaffName : "";
let tm = Date.now();
this.urlprint = BASE_URL + "/one-api/report/rpt_request_mutasi/pdf?id=" + val.MutasiRequestID + "&username=" + username + "&tm=" + tm;
this.openprint = true;
} }
}, },
}; };

View File

@@ -192,25 +192,43 @@
</v-chip> </v-chip>
</td> </td>
<template v-if="props.item.PaymentVoucherStatus == 'Draft'"> <template v-if="props.item.PaymentVoucherStatus == 'Draft'">
<td class="text-xs-center pa-2" <td class="text-xs-center pa-2" style="white-space: nowrap;"
v-bind:class="{ 'amber lighten-4': isSelected(props.item) }" v-bind:class="{ 'amber lighten-4': isSelected(props.item) }"
@click="selectMe(props.item)"
> >
<v-icon small @click="openUpdateVoucher(props.item)" <v-btn
>edit</v-icon style="min-width: 25px; height: 25px; margin: 0;"
@click.stop="openUpdateVoucher(props.item)"
small title="Edit"
color="black"
> >
<v-icon small @click="deleteVoucher(props.item)" <v-icon small color="white">edit</v-icon>
>delete</v-icon </v-btn>
<v-btn
style="min-width: 25px; height: 25px; margin: 0;"
@click.stop="deleteVoucher(props.item)"
small title="Hapus"
color="red"
> >
<v-icon small color="white">delete</v-icon>
</v-btn>
</td> </td>
</template> </template>
<template v-else> <template v-else>
<td <td
class="text-xs-center pa-2" class="text-xs-center pa-2" style="white-space: nowrap;"
v-bind:class="{ v-bind:class="{
'amber lighten-4': isSelected(props.item), 'amber lighten-4': isSelected(props.item),
}" }"
></td> >
<v-btn
style="min-width: 25px; height: 25px; margin: 0;"
@click.stop="printout(props.item)"
small title="Cetak PDF"
color="primary"
>
<v-icon small color="white">print</v-icon>
</v-btn>
</td>
</template> </template>
</template> </template>
</v-data-table> </v-data-table>
@@ -234,6 +252,15 @@
@forget-dialog-alert="dialogAlertDelete = false" @forget-dialog-alert="dialogAlertDelete = false"
@close-dialog-alert="closeAndDelete()" @close-dialog-alert="closeAndDelete()"
></one-dialog-alert> ></one-dialog-alert>
<one-dialog-print
:title="printtitle"
:width="printwidth"
:height="600"
:status="openprint"
:urlprint="urlprint"
@close-dialog-print="openprint = false"
></one-dialog-print>
</div> </div>
</template> </template>
@@ -263,10 +290,15 @@ module.exports = {
components: { components: {
"dialog-form-voucher": httpVueLoader("./dialogFormVoucher.vue"), "dialog-form-voucher": httpVueLoader("./dialogFormVoucher.vue"),
"one-dialog-alert": httpVueLoader("../../common/oneDialogAlert.vue"), "one-dialog-alert": httpVueLoader("../../common/oneDialogAlert.vue"),
"one-dialog-error": httpVueLoader("../../common/oneDialogError.vue") "one-dialog-error": httpVueLoader("../../common/oneDialogError.vue"),
"one-dialog-print": httpVueLoader("../../common/oneDialogPrintX.vue"),
}, },
data() { data() {
return { return {
urlprint: "",
printtitle: "",
printwidth: "60%",
openprint: false,
msgAlertDelete: "", msgAlertDelete: "",
dialogAlertDelete: false, dialogAlertDelete: false,
xPVID: 0, xPVID: 0,
@@ -306,7 +338,7 @@ module.exports = {
}, },
{ {
text: "AKSI", text: "AKSI",
align: "left", align: "center",
sortable: false, sortable: false,
value: "status", value: "status",
width: "15%", width: "15%",
@@ -570,6 +602,15 @@ module.exports = {
this.$store.commit("voucher/update_selected_purchase", this.$store.state.voucher.details); this.$store.commit("voucher/update_selected_purchase", this.$store.state.voucher.details);
this.$store.commit("voucher/update_resume_total", {"totalRealitation": data.PaymentVoucherTotal} ); this.$store.commit("voucher/update_resume_total", {"totalRealitation": data.PaymentVoucherTotal} );
},
printout(val) {
this.printwidth = "60%";
this.printtitle = "";
let user = one_user();
let username = user && user.M_StaffName ? user.M_StaffName : "";
let tm = Date.now();
this.urlprint = BASE_URL + "/one-api/report/rpt_payment_voucher/pdf?id=" + val.PaymentVoucherID + "&username=" + username + "&tm=" + tm;
this.openprint = true;
} }
}, },
watch: { watch: {

View File

@@ -1,81 +1,68 @@
const URL = "/one-api/mockup/purchase/order/PurchaseOrderAset/"; const URL = "/one-api/mockup/purchase/order/PurchaseOrderAset";
async function request(endpoint, params) {
try {
const resp = await axios.post(URL + endpoint, params);
if (resp.status !== 200) {
throw new Error(resp.statusText);
}
return resp.data;
} catch (e) {
return {
status: "ERR",
message: e.message
}
}
}
export async function getListSupplier(params) { export async function getListSupplier(params) {
try { return request("/getListSupplier", params);
var response = await axios.post(URL + "getListSupplier", params)
if (response.status !== 200) {
return {
status: 'ERR',
message: responsep.statusText
};
}
let data = response.data
return data
} catch (error) {
return {
status: 'ERR',
message: error.message
};
}
} }
export async function getListCabang(params) { export async function getListCabang(params) {
try { return request("/getListCabang", params);
var response = await axios.post(URL + "getListCabang", params) }
if (response.status !== 200) {
return {
status: 'ERR',
message: responsep.statusText
};
}
let data = response.data export async function getListGudang(params) {
return data return request("/getListGudang", params);
} catch (error) {
return {
status: 'ERR',
message: error.message
};
}
} }
export async function searchRequestAset(params) { export async function searchRequestAset(params) {
try { return request("/searchRequestAset", params);
var response = await axios.post(URL + "searchRequestAset", params) }
if (response.status !== 200) {
return {
status: 'ERR',
message: responsep.statusText
};
}
let data = response.data export async function getDaftarPoAset(params) {
return data return request("/getDaftarPoAset", params);
} catch (error) { }
return {
status: 'ERR', export async function getDaftarAttachment(params) {
message: error.message return request("/getDaftarAttachment", params);
}; }
}
export async function getDataKontrakPoAset(params) {
return request("/getDataKontrakPoAset", params);
}
export async function createPoAsset(params) {
return request("/createPoAsset", params);
}
export async function editPoAsset(params) {
return request("/editPoAsset", params);
}
export async function deletePoAsset(params) {
return request("/deletePoAsset", params);
}
export async function updateApprovalPO(params) {
return request("/updateApprovalPO", params);
} }
export async function getUserApproveLevel(params) { export async function getUserApproveLevel(params) {
try { return request("/getUserApproveLevel", params);
var response = await axios.post(URL + "getUserApproveLevel", params) }
if (response.status !== 200) {
return { export async function uploadAttachment(params) {
status: 'ERR', return request("/uploadAttachment", params);
message: responsep.statusText
};
}
let data = response.data
return data
} catch (error) {
return {
status: 'ERR',
message: error.message
};
}
} }

View File

@@ -11,6 +11,7 @@
<input <input
type="file" id="files" ref="files" multiple type="file" id="files" ref="files" multiple
accept="image/*" v-on:change="addAttach($event)" accept="image/*" v-on:change="addAttach($event)"
v-show="!viewonlymode"
> >
</v-flex> </v-flex>
<v-flex <v-flex
@@ -44,7 +45,7 @@
<v-card-actions> <v-card-actions>
<v-spacer></v-spacer> <v-spacer></v-spacer>
<v-btn @click="cancel_file()" color="error" class="white--text">Batal</v-btn> <v-btn @click="cancel_file()" color="error" class="white--text">Batal</v-btn>
<v-btn @click="save_file()" color="primary" class="white--text">Simpan</v-btn> <v-btn v-show="!viewonlymode" @click="save_file()" color="primary" class="white--text">Simpan</v-btn>
</v-card-actions> </v-card-actions>
</v-card> </v-card>
</v-dialog> </v-dialog>
@@ -90,25 +91,28 @@ module.exports = {
computed: { computed: {
dialog_attachment: { dialog_attachment: {
get() { get() {
return this.$store.state.poasset.dialog_attachment return this.$store.state.common.dialog_attachment
}, },
set(val) { set(val) {
this.$store.commit("poasset/update_dialog_attachment", val) this.$store.commit("common/update_dialog_attachment", val)
} }
}, },
selected_orderaset: { selected_orderaset: {
get() { get() {
return this.$store.state.poasset.selected_orderaset return this.$store.state.common.selected_orderaset
}, },
set(val) { set(val) {
this.$store.commit("poasset/update_selected_orderaset", val) this.$store.commit("common/update_selected_orderaset", val)
} }
}, },
prview_attachment() { prview_attachment() {
return this.$store.state.poasset.prview_attachment return this.$store.state.common.assets_attachment
}, },
loading_process() { loading_process() {
return this.$store.state.poasset.loading_process return this.$store.state.common.loading_process
},
viewonlymode() {
return this.$store.state.common.viewonlymode;
} }
}, },
methods: { methods: {
@@ -128,7 +132,7 @@ module.exports = {
}, },
makeImageUrl(docs) { makeImageUrl(docs) {
const year = new Date(docs.created).getFullYear(); const year = new Date(docs.created).getFullYear();
const baseURL = BASE_URL + `/one-media/order-aset/${year}`; const baseURL = BASE_URL + `/one-media/order-asset/${year}/`;
return baseURL + docs.img_url; return baseURL + docs.img_url;
}, },
fullview(docs, index) { fullview(docs, index) {
@@ -150,6 +154,7 @@ module.exports = {
cancel_file() { cancel_file() {
this.tempdocs_file = []; this.tempdocs_file = [];
this.tempdocs_view = []; this.tempdocs_view = [];
this.$store.commit("common/update_viewonlymode", false);
this.dialog_attachment = false; this.dialog_attachment = false;
}, },
save_file() { save_file() {
@@ -163,15 +168,16 @@ module.exports = {
form_data.append(`files[${index}]`, file); form_data.append(`files[${index}]`, file);
} }
form_data.append('KontrakAsetID', orderaset.T_KontrakAsetID); form_data.append('contractID', orderaset.contractID);
form_data.append('POrderID', orderaset.PurchaseOrderID); form_data.append('poID', orderaset.PurchaseOrderID);
form_data.append('POnumber', orderaset.PurchaseOrderNumber); form_data.append('ponumber', orderaset.PurchaseOrderNumber);
form_data.append('contractDate', orderaset.contractDate);
form_data.append('token', one_token()); form_data.append('token', one_token());
this.$store.dispatch('poasset/'); this.$store.dispatch('common/uploadAttachment', form_data);
} else { } else {
const snac = { color: 'warning', msg: 'proses sedang berjalan', state: true }; const snac = { color: 'warning', msg: 'proses sedang berjalan', state: true };
this.$store.commit('poasset/update_snackbar', snac); this.$store.commit('common/update_snackbar', snac);
} }
} }
}, },

View File

@@ -104,42 +104,42 @@ module.exports = {
computed: { computed: {
dialog_add_itemaset: { dialog_add_itemaset: {
get() { get() {
return this.$store.state.poasset.dialog_add_itemaset return this.$store.state.common.dialog_add_itemaset
}, },
set(val) { set(val) {
this.$store.commit('poasset/update_dialog_add_itemaset', val) this.$store.commit('common/update_dialog_add_itemaset', val)
} }
}, },
list_requestaset: { list_requestaset: {
get() { get() {
return this.$store.state.poasset.list_requestaset return this.$store.state.common.list_requestaset
}, },
set(val) { set(val) {
this.$store.commit('poasset/update_list_requestaset', val) this.$store.commit('common/update_list_requestaset', val)
} }
}, },
form_orderaset: { form_orderaset: {
get() { get() {
return this.$store.state.poasset.form_orderaset return this.$store.state.common.form_orderaset
}, },
set(val) { set(val) {
this.$store.commit('poasset/update_form_orderaset', val) this.$store.commit('common/update_form_orderaset', val)
} }
}, },
item_orderaset: { item_orderaset: {
get() { get() {
return this.$store.state.poasset.item_orderaset return this.$store.state.common.item_orderaset
}, },
set(val) { set(val) {
this.$store.commit('poasset/update_item_orderaset', val) this.$store.commit('common/update_item_orderaset', val)
} }
}, },
summary_orderaset: { summary_orderaset: {
get() { get() {
return this.$store.state.poasset.summary_orderaset return this.$store.state.common.summary_orderaset
}, },
set(val) { set(val) {
this.$store.commit('poasset/update_summary_orderaset', val) this.$store.commit('common/update_summary_orderaset', val)
} }
} }
}, },
@@ -147,7 +147,7 @@ module.exports = {
searchrequest(search) { searchrequest(search) {
this.loading = true this.loading = true
setTimeout(() => { setTimeout(() => {
this.$store.dispatch('poasset/lookupOrderRequest', search) this.$store.dispatch('common/lookupOrderRequest', search)
this.loading = false this.loading = false
}, 500); }, 500);
}, },

View File

@@ -0,0 +1,259 @@
<template>
<v-dialog v-model="dialog_create_order" persistent width="80vw">
<v-card class="style-card">
<v-card-title class="headline grey lighten-2">
{{ viewonlymode
? "VIEW ORDER ASSET"
: selected_orderaset.PurchaseOrderID
? "EDIT ORDER ASET"
: "BUAT ORDER ASET"
}}
</v-card-title>
<template>
<div class="style-content">
<v-stepper non-linear v-model="steps">
<v-stepper-header>
<v-stepper-step editable step="1" @click="steps = 1">
FORM ORDER ASET
</v-stepper-step>
<v-divider></v-divider>
<v-stepper-step editable step="2" @click="steps = 2">
FORM KONTRAK ASET
</v-stepper-step>
<v-divider></v-divider>
<v-stepper-step editable step="3" @click="steps = 3">
ITEM ORDER ASET
</v-stepper-step>
</v-stepper-header>
<v-stepper-items>
<v-stepper-content step="1">
<form-order-asset></form-order-asset>
</v-stepper-content>
<v-stepper-content step="2">
<form-kontrak-asset></form-kontrak-asset>
</v-stepper-content>
<v-stepper-content step="3">
<form-item-request-asset></form-item-request-asset>
<dialog-select-request-asset></dialog-select-request-asset>
</v-stepper-content>
</v-stepper-items>
</v-stepper>
<v-card-text>
<v-layout v-for="(item, index) in summary_items" :key="index"
row wrap align-center>
<v-flex xs2 pa-1>
<strong>{{ item.label }}</strong>
</v-flex>
<v-flex grow></v-flex>
<v-flex xs2 pa-1 class="text-xs-right">
<strong>Rp. {{ formatCurrency(item.value) }}</strong>
</v-flex>
</v-layout>
</v-card-text>
</div>
</template>
<v-card-actions>
<v-spacer></v-spacer>
<v-btn @click="batalOrderAsset()" color="error" class="white--text">Batal</v-btn>
<v-btn :disabled="viewonlymode" @click="simpanOrderAsset()" color="primary" class="white--text">Simpan</v-btn>
</v-card-actions>
</v-card>
</v-dialog>
</template>
<style scoped>
.style-card {
max-height: 60vh;
display: flex;
flex-direction: column;
}
.style-content {
overflow-y: auto;
flex: 1 1 auto;
min-height: 0;
}
</style>
<script>
module.exports = {
data() {
return {
steps: 1
}
},
components: {
'form-order-asset': httpVueLoader('./form-order-asset.vue'),
'form-kontrak-asset': httpVueLoader('./form-kontrak-asset.vue'),
'form-item-request-asset': httpVueLoader('./form-item-request-asset.vue'),
'dialog-select-request-asset': httpVueLoader('./dialog-select-request-asset.vue')
},
computed: {
loading_process() {
return this.$store.state.common.loading_process;
},
dialog_create_order: {
get() {
return this.$store.state.orderAsset.dialog_create_order
},
set(val) {
this.$store.commit("orderAsset/update_dialog_create_order", val)
}
},
form_kontrak: {
get() {
return this.$store.state.kontrakAsset.form_kontrak
},
set(val) {
this.$store.commit("kontrakAsset/update_form_kontrak", val);
}
},
form_order_asset: {
get() {
return this.$store.state.orderAsset.form_order_asset;
},
set(val) {
this.$store.commit("orderAsset/update_form_order_asset", val);
}
},
selected_request_asset: {
get() {
return this.$store.state.orderAsset.selected_request_asset
},
set(val) {
this.$store.commit("orderAsset/update_selected_request_asset", val)
}
},
summary_order: {
get() {
return this.$store.state.orderAsset.summary_order;
},
set(val) {
this.$store.commit("orderAsset/update_summary_order", val);
}
},
summary_items() {
if (!this.summary_order) return [];
return [
{label: 'JUMLAH', value: this.summary_order.subtotal},
{label: 'DISKON', value: this.summary_order.diskon},
{label: 'PAJAK', value: this.summary_order.pajak},
{label: 'DOWN PAYMENT', value: this.summary_order.downpayment},
{label: 'TOTAL', value: this.summary_order.total}
]
},
viewonlymode() {
return this.$store.state.common.viewonlymode;
},
selected_orderaset() {
return this.$store.state.common.selected_orderaset;
}
},
methods: {
formatCurrency(value) {
const num = parseFloat(value);
if (isNaN(num)) return 0;
return num.toFixed(2).replace('.', ',').replace(/\B(?=(\d{3})+(?!\d))/g, ".");
},
parseCurrency(value) {
let cleanValue = String(value).replace(/\./g, '');
cleanValue = cleanValue.replace(',', '.');
return parseFloat(cleanValue) || 0;
},
simpanOrderAsset() {
if (!this.loading_process) {
let formOrder = JSON.parse(JSON.stringify(this.form_order_asset));
let formKontrak = JSON.parse(JSON.stringify(this.form_kontrak));
let requestItem = JSON.parse(JSON.stringify(this.selected_request_asset));
let summaryOrder = JSON.parse(JSON.stringify(this.summary_order));
if (requestItem.length < 1) {
const snac = { color: 'warning', msg: 'Item masih kosong', state: true };
this.$store.commit("common/update_snackbar", snac);
return;
}
/* make sure the value is not in IDR format */
formOrder.valuepajak = this.parseCurrency(formOrder.valuepajak);
formOrder.valuediskon = this.parseCurrency(formOrder.valuediskon);
formKontrak.besarNilai_cicilan = this.parseCurrency(formKontrak.besarNilai_cicilan);
formKontrak.besarNilai_downpayment = this.parseCurrency(formKontrak.besarNilai_downpayment);
requestItem.forEach(item => {
item.SupplierPrice = this.parseCurrency(item.SupplierPrice);
item.DiskonAmount = this.parseCurrency(item.DiskonAmount);
});
let param = {
...formOrder,
assetAttachmentID: 0,
contractName: formKontrak.nama_kontrak,
contractDate: formKontrak.tanggal_kontrak,
contractStart: formKontrak.tanggalAwal_kontrak,
contractEnd: formKontrak.tanggalAkhir_kontrak,
contractDuration: formKontrak.durasi_cicilan,
installmentNumber: formKontrak.jumlah_cicilan,
installmentDate: formKontrak.tanggalBayar_cicilan,
installmentPayAmount: formKontrak.besarNilai_cicilan,
installmentDownPaymentType: formKontrak.type_downpayment,
installmentDownPayment: formKontrak.besarNilai_downpayment,
detail: requestItem,
summary: summaryOrder
}
if (!this.selected_orderaset.PurchaseOrderID) {
this.$store.dispatch("kontrakAsset/saveOrderAsset", param);
} else {
param.PurchaseOrderID = this.selected_orderaset.PurchaseOrderID;
param.assetAttachmentID = this.selected_orderaset.assetAttachmentID,
param.SupplierDownpaymentID = this.selected_orderaset.SupplierDownpaymentID;
this.$store.dispatch("kontrakAsset/editOrderAsset", param);
}
} else {
const snac = { color: 'warning', msg: 'Proses masih berjalan', state: true };
this.$store.commit("common/update_snackbar", snac);
}
},
batalOrderAsset() {
this.form_order_asset = {
podate: moment(new Date()).format('YYYY-MM-DD'),
supplierID: "",
reference: "",
branchID: "",
typepajak: "percent",
valuepajak: 0,
typediskon: "percent",
valuediskon: 0
};
this.form_kontrak = {
nama_kontrak: '',
tanggal_kontrak: moment(new Date()).format('YYYY-MM-DD'),
tanggalAwal_kontrak: moment(new Date()).format('YYYY-MM-DD'),
tanggalAkhir_kontrak: moment(new Date()).format('YYYY-MM-DD'),
durasi_cicilan: 1,
jumlah_cicilan: 1,
tanggalBayar_cicilan: 1,
besarNilai_cicilan: 0,
type_downpayment: 'percent',
besarNilai_downpayment: 0
};
this.selected_request_asset = [];
this.summary_order = {
subtotal: 0,
diskon: 0,
pajak: 0,
downpayment: 0,
total_before_downpayment: 0,
total: 0
};
this.$store.commit("common/update_viewonlymode", false);
this.$store.commit('common/update_selected_orderaset', {});
this.dialog_create_order = false;
}
}
}
</script>

View File

@@ -39,14 +39,17 @@ module.exports = {
computed: { computed: {
dialog_deleteorder: { dialog_deleteorder: {
get() { get() {
return this.$store.state.poasset.dialog_deleteorder return this.$store.state.common.dialog_deleteorder
}, },
set(val) { set(val) {
this.$store.commit('update_dialog_deleteorder', val) this.$store.commit('common/update_dialog_deleteorder', val)
} }
}, },
selected_orderaset() { selected_orderaset() {
return this.$store.state.poasset.selected_orderaset return this.$store.state.common.selected_orderaset
},
loading_process() {
return this.$store.state.common.loading_process
} }
}, },
methods: { methods: {
@@ -54,7 +57,12 @@ module.exports = {
this.dialog_deleteorder = false this.dialog_deleteorder = false
}, },
hapusorder() { hapusorder() {
if (!this.loading_process) {
this.$store.dispatch("common/deleteOrderAsset")
} else {
const snac = { color: 'warning', msg: 'proses sedang berjalan', state: true };
this.$store.commit('common/update_snackbar', snac);
}
} }
}, },
} }

View File

@@ -364,44 +364,44 @@ module.exports = {
computed: { computed: {
dialog_form_orderaset: { dialog_form_orderaset: {
get() { get() {
return this.$store.state.poasset.dialog_form_orderaset; return this.$store.state.common.dialog_form_orderaset;
}, },
set(val) { set(val) {
this.$store.commit('poasset/update_dialog_form_orderaset', val); this.$store.commit('common/update_dialog_form_orderaset', val);
} }
}, },
form_orderaset: { form_orderaset: {
get() { get() {
return this.$store.state.poasset.form_orderaset; return this.$store.state.common.form_orderaset;
}, },
set(val) { set(val) {
this.$store.commit('poasset/update_form_orderaset', val); this.$store.commit('common/update_form_orderaset', val);
} }
}, },
item_orderaset: { item_orderaset: {
get() { get() {
return this.$store.state.poasset.item_orderaset; return this.$store.state.common.item_orderaset;
}, },
set(val) { set(val) {
this.$store.commit('poasset/update_item_orderaset', val); this.$store.commit('common/update_item_orderaset', val);
} }
}, },
summary_orderaset: { summary_orderaset: {
get() { get() {
return this.$store.state.poasset.summary_orderaset return this.$store.state.common.summary_orderaset
}, },
set(val) { set(val) {
this.$store.commit('poasset/update_summary_orderaset', val) this.$store.commit('common/update_summary_orderaset', val)
} }
}, },
formatPOdate() { formatPOdate() {
return this.formatDate(this.form_orderaset.podate); return this.formatDate(this.form_orderaset.podate);
}, },
list_supplier() { list_supplier() {
return this.$store.state.poasset.list_supplier; return this.$store.state.common.list_supplier;
}, },
list_branch() { list_branch() {
return this.$store.state.poasset.list_branch; return this.$store.state.common.list_branch;
} }
}, },
methods: { methods: {
@@ -498,8 +498,8 @@ module.exports = {
this.calculateFormSummary(form) this.calculateFormSummary(form)
}, },
addItemRequest() { addItemRequest() {
this.$store.dispatch('poasset/lookupOrderRequest', 'SR') this.$store.dispatch('common/lookupOrderRequest', 'SR')
this.$store.commit('poasset/update_dialog_add_itemaset', true) this.$store.commit('common/update_dialog_add_itemaset', true)
}, },
changeDiscountPerItem(name, item) { changeDiscountPerItem(name, item) {
switch (name) { switch (name) {

View File

@@ -0,0 +1,246 @@
<template>
<v-dialog v-model="dialog_select_item" persistent width="60vw">
<v-card class="style-limit-heightcard">
<v-card-title class="headline grey lighten-2" primary title>
TAMBAH ITEM REQUEST
</v-card-title>
<v-card-text class="style-limit-heightcontent">
<v-flex xs12>
<v-text-field label="Cari" hide-details outline
v-model="keyword" placeholder="Nama item, nomor request"
></v-text-field>
</v-flex>
<v-flex xs12 mt-2>
<v-data-table :headers="headers" :items="requested_asset.records" class="elevation-1"
v-model="selected_local" item-key="PurchaseRequestDetailID" hide-actions :loading="loading">
<template v-slot:headers="props">
<tr>
<th class="blue lighten-3 white--text" style="width: 10%;">
<v-checkbox
:input-value="props.all" primary
:indeterminate="props.indeterminate"
@click.native="toggleAll" hide-details
></v-checkbox>
</th>
<th v-for="header in props.headers" :key="header.text"
:class="header.class" :style="{ width: header.width }"
>
{{ header.text }}
</th>
</tr>
</template>
<template v-slot:items="props">
<tr>
<td>
<v-checkbox v-model="props.selected" primary hide-details></v-checkbox>
</td>
<td class="text-xs-center pa-2">{{ props.item.PurchaseRequestNumber }}</td>
<td class="text-xs-start pa-2">
{{ props.item.Requestedby }} <br>
{{ props.item.M_BranchName }}
</td>
<td class="text-xs-start pa-2">
{{ props.item.M_ItemCode }} <br>
{{ props.item.M_ItemDesc }}
</td>
<td class="text-xs-center pa-2">{{ props.item.ItemUnitName }}</td>
<td class="text-xs-center pa-2">{{ props.item.RequestQty }}</td>
</tr>
</template>
</v-data-table>
</v-flex>
</v-card-text>
<v-card-actions>
<v-spacer></v-spacer>
<v-btn @click="batalTambah()" color="error" class="white--text">Batal</v-btn>
<v-btn @click="simpanItem()" color="primary" class="white--text">Simpan</v-btn>
</v-card-actions>
</v-card>
</v-dialog>
</template>
<style scoped>
.style-limit-heightcard {
max-height: 60vh;
display: flex;
flex-direction: column;
}
.style-limit-heightcontent {
overflow-y: auto;
flex: 1 1 auto;
min-height: 0;
}
</style>
<script>
module.exports = {
data() {
return {
keyword: "",
loading: false,
selected_local: [],
headers: [
{
text: "NO PURCHASE REQ", align: "center", sortable: false,
value: "noreq", width: "20%", class: "pa-1 blue lighten-3 white--text",
},
{
text: "REQUESTER", align: "center", sortable: false,
value: "kode", width: "20%", class: "pa-1 blue lighten-3 white--text",
},
{
text: "ITEM", align: "center", sortable: false,
value: "serve", width: "20%", class: "pa-1 blue lighten-3 white--text",
},
{
text: "SATUAN", align: "center", sortable: false,
value: "unit", width: "20%", class: "pa-1 blue lighten-3 white--text",
},
{
text: "REQ QTY", align: "center", sortable: false,
value: "qty", width: "10%", class: "pa-1 blue lighten-3 white--text",
},
],
}
},
computed: {
dialog_select_item: {
get() {
return this.$store.state.orderAsset.dialog_select_asset;
},
set(val) {
this.$store.commit("orderAsset/update_dialog_select_asset", val);
}
},
form_order_asset: {
get() {
return this.$store.state.orderAsset.form_order_asset;
},
set(val) {
this.$store.commit("orderAsset/update_form_order_asset", val);
}
},
requested_asset: {
get() {
return this.$store.state.orderAsset.requested_asset
},
set(val) {
this.$store.commit('orderAsset/update_requested_asset', val)
}
},
selected_request_asset: {
get() {
return this.$store.state.orderAsset.selected_request_asset
},
set(val) {
this.$store.commit("orderAsset/update_selected_request_asset", val)
}
},
summary_order: {
get() {
return this.$store.state.orderAsset.summary_order;
},
set(val) {
this.$store.commit("orderAsset/update_summary_order", val);
}
}
},
methods: {
isFormEmpty() {
const form = this.form_order_asset;
if (form.supplierID != "" && form.branchID != "") {
return false;
}
return true;
},
cariRequest(newval) {
this.loading = true;
setTimeout(() => {
this.$store.dispatch("orderAsset/searchItemRequest", newval);
this.loading = false;
}, 500);
},
tambahItem() {
this.cariRequest("")
this.dialog_select_item = true;
},
toggleAll() {
if (this.selected_local.length) {
this.selected_local = [];
} else {
this.selected_local = this.requested_asset.records.slice();
}
},
simpanItem() {
const requestedAsset = JSON.parse(JSON.stringify(this.selected_local));
let form_asset = JSON.parse(JSON.stringify(this.form_order_asset));
const PRnumber = [...new Set(requestedAsset.map(item => item.PurchaseRequestNumber))].join(', ');
form_asset.reference = PRnumber;
const selected = Object.values(requestedAsset.reduce((acc, current) => {
const itemcode = current.M_ItemCode
if (!acc[itemcode]) {
acc[itemcode] = {
M_ItemID: current.M_ItemID,
M_ItemCode: itemcode,
M_ItemDesc: current.M_ItemDesc,
ItemUnitID: current.ItemUnitID,
ItemUnitName: current.ItemUnitName,
SupplierPrice: Number(current.SupplierPrice),
M_BranchName: current.M_BranchName,
RequestQty: 0.00,
DiskonAmount: 0.00,
DiskonType: 'R',
EndPrice: 0.00,
TempTotal: 0.00,
detail: []
}
}
acc[itemcode].RequestQty += Number(current.RequestQty)
acc[itemcode].detail.push(current)
acc[itemcode].EndPrice = acc[itemcode].SupplierPrice - acc[itemcode].DiskonAmount
acc[itemcode].TempTotal = acc[itemcode].RequestQty * acc[itemcode].EndPrice
return acc
}, {}));
this.selected_request_asset = selected;
this.form_order_asset = form_asset;
this.$store.dispatch("orderAsset/recalculateOrderSummary");
this.selected_local = [];
this.dialog_select_item = false;
},
batalTambah() {
this.requested_asset = {
records: [],
total: 0
};
this.selected_local = [];
this.dialog_select_item = false;
}
},
watch: {
dialog_select_item(val) {
if (val) {
this.cariRequest("");
let current = [];
let newly = this.selected_request_asset
newly.forEach((item) => {
current.push(...item.detail);
});
this.selected_local = current;
}
},
keyword(newval, oldval) {
if (!newval) return;
if (newval == oldval) return;
if (newval.length < 1) return;
this.cariRequest(newval);
}
}
}
</script>

View File

@@ -0,0 +1,337 @@
<template>
<v-layout row wrap>
<v-flex grow></v-flex>
<v-flex shrink>
<v-btn
@click="tambahItem()" color="primary" class="white--text"
:disabled="isFormEmpty()"
>Tambah Item</v-btn>
</v-flex>
<v-flex xs12>
<v-data-table :headers="headers" :items="selected_request_asset"
:expand="expand" class="elevation-1" hide-actions item-key="M_ItemID">
<!-- item request grouped -->
<template v-slot:items="props">
<tr @click="props.expanded = !props.expanded">
<td class="text-xs-center pa-2">
<v-icon>{{ props.expanded
? "keyboard_arrow_down"
: "keyboard_arrow_right"
}}</v-icon>
</td>
<td class="text-xs-center pa-2">{{ props.item.M_ItemDesc }}</td>
<td class="text-xs-center pa-2">{{ props.item.RequestQty }}</td>
<td class="text-xs-center pa-2">
<v-text-field
v-model="props.item.SupplierPrice"
hide-details prefix="Rp." solo :readonly="viewonlymode"
@input="$store.dispatch('orderAsset/recalculateOrderSummary')"
@focus="handleFocus(props.item, 'price')"
@blur="handleBlur(props.item, 'price')"
></v-text-field>
</td>
<td class="text-xs-center pa-2">
<v-layout row>
<v-menu open-on-hover top offset-y attach>
<v-btn slot="activator" color="primary" dark small>
<span v-if="props.item.DiskonType == 'R'">Rp</span>
<span v-else>%</span>
</v-btn>
<v-list>
<v-list-tile
v-for="(item, index) in type_disc" :key="index"
@click="changeDiscountPerItem(item.name, props.item)"
>
<v-list-tile-title>{{ item.name }}</v-list-tile-title>
</v-list-tile>
</v-list>
</v-menu>
<v-text-field
v-if="props.item.DiskonType == 'R'" prefix="Rp." :readonly="viewonlymode"
v-model="props.item.DiskonAmount" hide-details solo
@input="$store.dispatch('orderAsset/recalculateOrderSummary')"
@focus="handleFocus(props.item, 'diskon')"
@blur="handleBlur(props.item, 'diskon')"
></v-text-field>
<v-text-field
v-if="props.item.DiskonType == 'P'" :readonly="viewonlymode"
v-model="props.item.DiskonAmount" solo
type="number" min="0" suffix="%" hide-details
@input="$store.dispatch('orderAsset/recalculateOrderSummary')"
></v-text-field>
</v-layout>
</td>
<td class="text-xs-center pa-2">
Rp. {{ formatCurrency(props.item.EndPrice) }}
</td>
<td class="text-xs-center pa-2">
Rp. {{ formatCurrency(props.item.TempTotal) }}
</td>
<td class="text-xs-center pa-2">
<v-btn
color="red" dark @click="removeRequestItem(props.item)"
style="min-width: 40px; margin: 0;" small
>
<v-icon small>delete</v-icon>
</v-btn>
</td>
</tr>
</template>
<!-- expanded item request -->
<template v-slot:expand="props">
<v-card flat>
<v-card-text>
<v-data-table
:headers="b_headers" class="elevation-0"
:items="props.item.detail" hide-actions
item-key="PurchaseRequestDetailID"
>
<template v-slot:items="det">
<tr>
<td class="text-xs-center pa-2">{{ det.item.M_ItemDesc }}</td>
<td class="text-xs-center pa-2">{{ det.item.PurchaseRequestNumber }}</td>
<td class="text-xs-center pa-2">{{ det.item.M_BranchName }}</td>
<td class="text-xs-center pa-2">
<v-text-field
v-model="det.item.RequestQty" hide-details
solo type="number" min="0" :readonly="viewonlymode"
@input="$store.dispatch('orderAsset/recalculateOrderSummary')"
></v-text-field>
</td>
<td class="text-xs-center pa-2">{{ det.item.ItemUnitName }}</td>
<td class="text-xs-center pa-2">
Rp. {{ formatCurrency(det.item.SupplierPrice) }}
</td>
<td class="text-xs-center pa-2">
<v-btn
color="red" flat @click="removeRequestDetail(det.item)"
style="min-width: 40px; margin: 0;" small
>
<v-icon>delete</v-icon>
</v-btn>
</td>
</tr>
</template>
</v-data-table>
</v-card-text>
</v-card>
</template>
</v-data-table>
</v-flex>
</v-layout>
</template>
<style scoped>
.style-limit-heightcard {
max-height: 60vh;
display: flex;
flex-direction: column;
}
.style-limit-heightcontent {
overflow-y: auto;
flex: 1 1 auto;
min-height: 0;
}
</style>
<script>
module.exports = {
data() {
return {
expand: false,
headers: [
{
text: "", align: "center", sortable: false,
value: "item", width: "5%", class: "pa-1 blue lighten-3 white--text",
},
{
text: "ITEM", align: "center", sortable: false,
value: "item", width: "15%", class: "pa-1 blue lighten-3 white--text",
},
{
text: "JUMLAH", align: "center", sortable: false,
value: "qty", width: "10%", class: "pa-1 blue lighten-3 white--text",
},
{
text: "HARGA", align: "center", sortable: false,
value: "price", width: "15%", class: "pa-1 blue lighten-3 white--text",
},
{
text: "DISKON", align: "center", sortable: false,
value: "disc", width: "20%", class: "pa-1 blue lighten-3 white--text",
},
{
text: "HARGA SETELAH DISKON", align: "center", sortable: false,
value: "disc", width: "15%", class: "pa-1 blue lighten-3 white--text",
},
{
text: "TOTAL", align: "center", sortable: false,
value: "disc", width: "15%", class: "pa-1 blue lighten-3 white--text",
},
{
text: "AKSI", align: "center", sortable: false,
value: "disc", width: "5%", class: "pa-1 blue lighten-3 white--text",
},
],
b_headers: [
{
text: "NAMA PRODUK", align: "center", sortable: false,
value: "prod", width: "20%", class: "pa-1 blue lighten-4 black--text",
},
{
text: "NO REQUEST", align: "center", sortable: false,
value: "noreq", width: "20%", class: "pa-1 blue lighten-4 black--text",
},
{
text: "REQUESTER", align: "center", sortable: false,
value: "req", width: "20%", class: "pa-1 blue lighten-4 black--text",
},
{
text: "JUMLAH", align: "center", sortable: false,
value: "qty", width: "10%", class: "pa-1 blue lighten-4 black--text",
},
{
text: "UNIT", align: "center", sortable: false,
value: "unit", width: "10%", class: "pa-1 blue lighten-4 black--text",
},
{
text: "HARGA", align: "center", sortable: false,
value: "price", width: "15%", class: "pa-1 blue lighten-4 black--text",
},
{
text: "AKSI", align: "center", sortable: false,
value: "act", width: "5%", class: "pa-1 blue lighten-4 black--text",
}
],
type_disc: [{name: 'percent'}, {name: 'nominal'}]
}
},
computed: {
form_order_asset: {
get() {
return this.$store.state.orderAsset.form_order_asset;
},
set(val) {
this.$store.commit("orderAsset/update_form_order_asset", val);
}
},
requested_asset: {
get() {
return this.$store.state.orderAsset.requested_asset
},
set(val) {
this.$store.commit('orderAsset/update_requested_asset', val)
}
},
selected_request_asset: {
get() {
return this.$store.state.orderAsset.selected_request_asset
},
set(val) {
this.$store.commit("orderAsset/update_selected_request_asset", val)
}
},
summary_order: {
get() {
return this.$store.state.orderAsset.summary_order;
},
set(val) {
this.$store.commit("orderAsset/update_summary_order", val);
}
},
viewonlymode() {
return this.$store.state.common.viewonlymode;
}
},
methods: {
isFormEmpty() {
const form = this.form_order_asset;
if (this.viewonlymode) {
return true;
}
if (form.supplierID != "" && form.branchID != "") {
return false;
}
return true;
},
tambahItem() {
this.$store.commit("orderAsset/update_dialog_select_asset", true);
},
formatCurrency(value) {
const num = parseFloat(value);
if (isNaN(num)) return 0;
return num.toFixed(2).replace('.', ',').replace(/\B(?=(\d{3})+(?!\d))/g, ".");
},
parseCurrency(value) {
let cleanValue = String(value).replace(/\./g, '');
cleanValue = cleanValue.replace(',', '.');
return parseFloat(cleanValue) || 0;
},
handleFocus(item, field) {
if (field == 'price') {
const currprice = item.SupplierPrice;
const parsedprice = this.parseCurrency(currprice);
item.SupplierPrice = parsedprice;
}
if (field == 'diskon') {
const currdisc = item.DiskonAmount;
const parseddisc = this.parseCurrency(currdisc);
item.DiskonAmount = parseddisc;
}
},
handleBlur(item, field) {
if (field == 'price') {
const currprice = item.SupplierPrice;
const parsedprice = this.parseCurrency(currprice);
item.SupplierPrice = this.formatCurrency(parsedprice);
}
if (field == 'diskon') {
const currdisc = item.DiskonAmount;
const parseddisc = this.parseCurrency(currdisc);
item.DiskonAmount = this.formatCurrency(parseddisc);
}
},
removeRequestItem(item) {
const current = JSON.parse(JSON.stringify(this.selected_request_asset));
let newitem = current.filter(ele => ele.M_ItemCode != item.M_ItemCode);
this.selected_request_asset = newitem;
this.$store.dispatch('orderAsset/recalculateOrderSummary');
},
removeRequestDetail(item) {
const current = JSON.parse(JSON.stringify(this.selected_request_asset));
let changed = current.find(ele => ele.M_ItemCode == item.M_ItemCode);
let newdetail = changed.detail.filter(
d => d.PurchaseRequestDetailID != item.PurchaseRequestDetailID
);
if (newdetail.length > 0) {
changed.detail = newdetail;
this.selected_request_asset = current;
this.$store.dispatch('orderAsset/recalculateOrderSummary');
} else {
this.removeRequestItem(changed);
}
},
changeDiscountPerItem(type, item) {
if (type == 'percent') {
item.DiskonType = 'P'
item.DiskonAmount = 0.00
} else {
item.DiskonType = 'R'
item.DiskonAmount = 0.00
}
this.$store.dispatch('orderAsset/recalculateOrderSummary');
}
},
watch: { }
}
</script>

View File

@@ -0,0 +1,194 @@
<template>
<div>
<v-layout row wrap>
<v-flex xs3 pa-1>
<v-text-field v-model="form_kontrak.nama_kontrak" hide-details outline label="Nama Kontrak"
placeholder="masukan nama kontrak" :readonly="viewonlymode"></v-text-field>
</v-flex>
<v-flex xs3 pa-1>
<v-menu v-model="menuKontrakDate" offset-y lazy min-width="290px" transition="scale-transition"
max-width="290px" full-width :nudge-right="40" :close-on-content-click="false">
<template v-slot:activator="{ on }">
<v-text-field v-model="formattedDateKontrak" v-on="on" hide-details readonly outline
label="Tanggal Kontrak"></v-text-field>
</template>
<v-date-picker v-model="form_kontrak.tanggal_kontrak" no-title
@input="menuKontrakDate = false" :readonly="viewonlymode"></v-date-picker>
</v-menu>
</v-flex>
<v-flex xs3 pa-1>
<v-menu v-model="menuKontrakStartdate" offset-y lazy min-width="290px" transition="scale-transition"
max-width="290px" full-width :nudge-right="40" :close-on-content-click="false">
<template v-slot:activator="{ on }">
<v-text-field v-model="formattedStartdateKontrak" outline v-on="on" hide-details
label="Tanggal Mulai Kontrak" readonly></v-text-field>
</template>
<v-date-picker v-model="form_kontrak.tanggalAwal_kontrak" no-title
@input="menuKontrakStartdate = false" :readonly="viewonlymode"></v-date-picker>
</v-menu>
</v-flex>
<v-flex xs3 pa-1>
<v-menu v-model="menuKontrakEnddate" offset-y lazy min-width="290px" transition="scale-transition"
max-width="290px" full-width :nudge-right="40" :close-on-content-click="false">
<template v-slot:activator="{ on }">
<v-text-field v-model="formattedEnddateKontrak" outline v-on="on" hide-details
label="Tanggal Akhir Kontrak" readonly></v-text-field>
</template>
<v-date-picker v-model="form_kontrak.tanggalAkhir_kontrak" no-title
@input="menuKontrakEnddate = false" :readonly="viewonlymode"></v-date-picker>
</v-menu>
</v-flex>
</v-layout>
<v-layout row wrap>
<v-flex xs2 pa-1>
<v-text-field v-model="form_kontrak.durasi_cicilan" hide-details outline placeholder="1"
label="Durasi Kontrak (Bulan)" readonly></v-text-field>
</v-flex>
<v-flex xs2 pa-1>
<v-text-field v-model="form_kontrak.jumlah_cicilan" hide-details placeholder="1" outline
label="Jumlah Cicilan" :readonly="viewonlymode"></v-text-field>
</v-flex>
<v-flex xs2 pa-1>
<v-text-field v-model="form_kontrak.tanggalBayar_cicilan" hide-details placeholder="1" outline
label="Tanggal Bayar Cicilan" :readonly="viewonlymode"></v-text-field>
</v-flex>
<v-flex xs2 pa-1>
<v-text-field v-model="form_kontrak.besarNilai_cicilan"
placeholder="0" prefix="Rp." outline hide-details :readonly="viewonlymode"
@blur="handleBlur(form_kontrak, 'cicil')" label="Besar Bayar Cicilan"
@focus="handleFocus(form_kontrak, 'cicil')"></v-text-field>
</v-flex>
<v-flex xs1 pa-1>
<v-autocomplete :items="['nominal', 'percent']" label="Tipe Nilai" :readonly="viewonlymode"
v-model="form_kontrak.type_downpayment" hide-details @input="changeTypeAmount('DP')"
@change="$store.dispatch('orderAsset/recalculateOrderSummary')" outline></v-autocomplete>
</v-flex>
<v-flex xs3 pa-1>
<v-text-field v-if="form_kontrak.type_downpayment == 'percent'" label="Jumlah Uang Muka" hide-details
v-model="form_kontrak.besarNilai_downpayment" placeholder="0" suffix="%" outline :readonly="viewonlymode"
@input="$store.dispatch('orderAsset/recalculateOrderSummary')"></v-text-field>
<v-text-field v-else label="Jumlah Uang Muka" hide-details placeholder="0"
v-model="form_kontrak.besarNilai_downpayment" prefix="Rp." outline
@input="$store.dispatch('orderAsset/recalculateOrderSummary')"
@blur="handleBlur(form_kontrak, 'dp')" :readonly="viewonlymode"
@focus="handleFocus(form_kontrak, 'dp')"></v-text-field>
</v-flex>
</v-layout>
</div>
</template>
<script>
module.exports = {
data() {
return {
menuKontrakDate: false,
menuKontrakStartdate: false,
menuKontrakEnddate: false,
};
},
computed: {
form_kontrak: {
get() {
return this.$store.state.kontrakAsset.form_kontrak
},
set(val) {
this.$store.commit("kontrakAsset/update_form_kontrak", val);
}
},
formattedDateKontrak() {
return this.formatDate(this.form_kontrak.tanggal_kontrak);
},
formattedStartdateKontrak() {
return this.formatDate(this.form_kontrak.tanggalAwal_kontrak);
},
formattedEnddateKontrak() {
return this.formatDate(this.form_kontrak.tanggalAkhir_kontrak);
},
viewonlymode() {
return this.$store.state.common.viewonlymode;
}
},
methods: {
formatDate(date) {
if (!date) return null;
const [year, month, day] = date.split('-');
return `${day}-${month}-${year}`;
},
countMonths(startdate, enddate) {
const start = new Date(startdate);
const end = new Date(enddate);
let months = (end.getFullYear() - start.getFullYear()) * 12 + (end.getMonth() - start.getMonth());
if (end.getDate() > start.getDate()) {
months += 1;
}
return Math.max(months, 1);
},
updateDurasiCicilan() {
const form = this.form_kontrak;
if (!form.tanggalAwal_kontrak || !form.tanggalAkhir_kontrak) return;
form.durasi_cicilan = this.countMonths(
form.tanggalAwal_kontrak,
form.tanggalAkhir_kontrak
);
this.form_kontrak = form;
},
changeTypeAmount(name) {
let form = this.form_kontrak;
if (name == 'DP') {
form.besarNilai_downpayment = 0;
}
this.$store.dispatch('orderAsset/recalculateOrderSummary');
},
formatCurrency(value) {
const num = parseFloat(value);
if (isNaN(num)) return 0;
return num.toFixed(2).replace('.', ',').replace(/\B(?=(\d{3})+(?!\d))/g, ".");
},
parseCurrency(value) {
let cleanValue = String(value).replace(/\./g, '');
cleanValue = cleanValue.replace(',', '.');
return parseFloat(cleanValue) || 0;
},
handleFocus(item, field) {
if (field == 'dp') {
const currprice = item.besarNilai_downpayment;
const parsedprice = this.parseCurrency(currprice);
item.besarNilai_downpayment = parsedprice;
}
if (field == 'cicil') {
const currdisc = item.besarNilai_cicilan;
const parseddisc = this.parseCurrency(currdisc);
item.besarNilai_cicilan = parseddisc;
}
},
handleBlur(item, field) {
if (field == 'dp') {
const currprice = item.besarNilai_downpayment;
const parsedprice = this.parseCurrency(currprice);
item.besarNilai_downpayment = this.formatCurrency(parsedprice);
}
if (field == 'cicil') {
const currdisc = item.besarNilai_cicilan;
const parseddisc = this.parseCurrency(currdisc);
item.besarNilai_cicilan = this.formatCurrency(parseddisc);
}
},
},
watch: {
"form_kontrak.tanggalAwal_kontrak"() {
this.updateDurasiCicilan();
},
"form_kontrak.tanggalAkhir_kontrak"() {
this.updateDurasiCicilan();
}
}
}
</script>

View File

@@ -0,0 +1,152 @@
<template>
<div>
<!-- first row -->
<v-layout row wrap>
<v-flex xs4 pa-1>
<v-menu
v-model="menuPOdate" offset-y lazy min-width="290px"
transition="scale-transition" max-width="290px" full-width
:nudge-right="40" :close-on-content-click="false"
>
<template v-slot:activator="{on}">
<v-text-field
v-model="formatPOdate" label="Tanggal PO"
hide-details readonly v-on="on" outline
></v-text-field>
</template>
<v-date-picker
v-model="form_order_asset.podate" no-title
@input="menuPOdate = false" :readonly="viewonlymode"
></v-date-picker>
</v-menu>
</v-flex>
<v-flex xs4 pa-1>
<v-autocomplete
:items="list_supplier" hide-details outline :readonly="viewonlymode"
v-model="form_order_asset.supplierID" label="Supplier"
item-text="SupplierName" item-value="SupplierID"
></v-autocomplete>
</v-flex>
<v-flex xs4 pa-1>
<v-text-field
v-model="form_order_asset.reference" hide-details outline
label="Referensi" placeholder="nomor request" readonly
></v-text-field>
</v-flex>
</v-layout>
<!-- 2nd row -->
<v-layout row wrap>
<v-flex xs2 pa-1>
<v-autocomplete
:items="list_cabang" hide-details outline
v-model="form_order_asset.branchID" label="Cabang"
item-text="M_BranchName" item-value="M_BranchID"
@change="onChangeCabang" :readonly="viewonlymode"
></v-autocomplete>
</v-flex>
<v-flex xs2 pa-1>
<v-autocomplete
:items="list_gudang" hide-details outline :readonly="viewonlymode"
v-model="form_order_asset.gudangID" label="Gudang"
item-text="WarehouseName" item-value="WarehouseID"
></v-autocomplete>
</v-flex>
<v-flex xs2 pa-1>
<v-autocomplete
:items="['nominal', 'percent']" label="Tipe Nilai" :readonly="viewonlymode"
v-model="form_order_asset.typepajak" hide-details outline
@change="$store.dispatch('orderAsset/recalculateOrderSummary')"
></v-autocomplete>
</v-flex>
<v-flex xs2 pa-1>
<v-text-field
v-if="form_order_asset.typepajak == 'percent'" label="Pajak"
v-model="form_order_asset.valuepajak" hide-details outline
placeholder="besar pajak dalam persen" suffix="%"
@input="$store.dispatch('orderAsset/recalculateOrderSummary')"
></v-text-field>
<v-text-field
v-else label="Pajak" outline prefix="Rp." :readonly="viewonlymode"
v-model="form_order_asset.valuepajak" hide-details
placeholder="besar pajak dalam rupiah"
@input="$store.dispatch('orderAsset/recalculateOrderSummary')"
></v-text-field>
</v-flex>
<v-flex xs2 pa-1>
<v-autocomplete
:items="['nominal', 'percent']" hide-details outline :readonly="viewonlymode"
v-model="form_order_asset.typediskon" label="Tipe Nilai"
@change="$store.dispatch('orderAsset/recalculateOrderSummary')"
></v-autocomplete>
</v-flex>
<v-flex xs2 pa-1>
<v-text-field
v-if="form_order_asset.typediskon == 'percent'" label="Diskon"
v-model="form_order_asset.valuediskon" hide-details outline
placeholder="besar diskon dalam persen" suffix="%"
@input="$store.dispatch('orderAsset/recalculateOrderSummary')"
></v-text-field>
<v-text-field
v-else label="Diskon" outline prefix="Rp."
v-model="form_order_asset.valuediskon" hide-details
placeholder="besar diskon dalam rupiah" :readonly="viewonlymode"
@input="$store.dispatch('orderAsset/recalculateOrderSummary')"
></v-text-field>
</v-flex>
<v-flex xs12 pa-1>
<v-textarea
v-model="form_order_asset.catatan" auto-grow :readonly="viewonlymode"
rows="1" outline label="Catatan" hide-details
></v-textarea>
</v-flex>
</v-layout>
</div>
</template>
<script>
module.exports = {
data() {
return {
menuPOdate: false,
}
},
computed: {
form_order_asset: {
get() {
return this.$store.state.orderAsset.form_order_asset;
},
set(val) {
this.$store.commit('orderAsset/update_form_order_asset', val);
}
},
formatPOdate() {
return this.formatDate(this.form_order_asset.podate);
},
list_supplier() {
return this.$store.state.orderAsset.list_supplier;
},
list_cabang() {
return this.$store.state.orderAsset.list_cabang;
},
list_gudang() {
return this.$store.state.orderAsset.list_gudang;
},
viewonlymode() {
return this.$store.state.common.viewonlymode;
}
},
methods: {
formatDate(date) {
if (!date) return null;
const [year, month, day] = date.split('-');
return `${day}-${month}-${year}`;
},
onChangeCabang(branchID) {
if (!branchID) return;
this.$store.dispatch("orderAsset/listingGudang", branchID);
}
}
}
</script>

View File

@@ -1,11 +1,8 @@
<template> <template>
<div> <div>
<v-toolbar color="primary" dark> <v-toolbar color="primary" dark>
<v-toolbar-title class="white--text">PURCHASE ORDER ASET</v-toolbar-title> <v-toolbar-title class="white--text">PURCHASE ORDER ASET</v-toolbar-title>
<v-spacer></v-spacer> <v-spacer></v-spacer>
<v-btn icon @click="createNewContract()">
<v-icon large>add_box</v-icon>
</v-btn>
<v-btn icon @click="createNewOrder()"> <v-btn icon @click="createNewOrder()">
<v-icon large>add_box</v-icon> <v-icon large>add_box</v-icon>
</v-btn> </v-btn>
@@ -14,61 +11,40 @@
<v-card class="pa-2"> <v-card class="pa-2">
<v-layout row align-center> <v-layout row align-center>
<v-flex xs3> <v-flex xs3>
<v-menu <v-menu v-model="menuStartdateFilter" offset-y lazy min-width="290px" transition="scale-transition"
v-model="menuStartdateFilter" offset-y lazy min-width="290px" max-width="290px" full-width :nudge-right="40" :close-on-content-click="false">
transition="scale-transition" max-width="290px" full-width
:nudge-right="40" :close-on-content-click="false"
>
<template v-slot:activator="{ on }"> <template v-slot:activator="{ on }">
<v-text-field <v-text-field v-model="formattedStartdate" label="Tanggal Awal" hide-details readonly
v-model="formattedStartdate" label="Tanggal Awal" v-on="on" outline></v-text-field>
hide-details readonly v-on="on" outline
></v-text-field>
</template> </template>
<v-date-picker <v-date-picker v-model="filterpo.startdate" no-title
v-model="filterpo.startdate" no-title @input="menuStartdateFilter = false"></v-date-picker>
@input="menuStartdateFilter = false"
></v-date-picker>
</v-menu> </v-menu>
</v-flex> </v-flex>
<v-flex xs3 pl-2> <v-flex xs3 pl-2>
<v-menu <v-menu v-model="menuEnddateFilter" offset-y lazy min-width="290px" transition="scale-transition"
v-model="menuEnddateFilter" offset-y lazy min-width="290px" max-width="290px" full-width :nudge-right="40" :close-on-content-click="false">
transition="scale-transition" max-width="290px" full-width
:nudge-right="40" :close-on-content-click="false"
>
<template v-slot:activator="{ on }"> <template v-slot:activator="{ on }">
<v-text-field <v-text-field v-model="formattedEnddate" label="Tanggal Akhir" hide-details readonly
v-model="formattedEnddate" label="Tanggal Akhir" v-on="on" outline></v-text-field>
hide-details readonly v-on="on" outline
></v-text-field>
</template> </template>
<v-date-picker <v-date-picker v-model="filterpo.enddate" no-title
v-model="filterpo.enddate" no-title @input="menuEnddateFilter = false"></v-date-picker>
@input="menuEnddateFilter = false"
></v-date-picker>
</v-menu> </v-menu>
</v-flex> </v-flex>
<v-flex xs3 pl-2> <v-flex xs3 pl-2>
<v-autocomplete <v-autocomplete :items="list_status" hide-details outline v-model="filterpo.status"
:items="list_status" hide-details outline label="Status"></v-autocomplete>
v-model="filterpo.status" label="Status"
></v-autocomplete>
</v-flex> </v-flex>
<v-flex xs3 pl-2> <v-flex xs3 pl-2>
<v-text-field <v-text-field v-model="filterpo.search" hide-details outline label="Cari"
v-model="filterpo.search" hide-details outline placeholder="cari nomor po"></v-text-field>
label="Cari" placeholder="cari nomor po"
></v-text-field>
</v-flex> </v-flex>
</v-layout> </v-layout>
</v-card> </v-card>
<v-card class="pa-2 mt-2"> <v-card class="pa-2 mt-2">
<v-data-table <v-data-table :headers="headers" class="elevation-1" :items="list_asetpo.records" hide-actions>
:headers="headers" class="elevation-1"
:items="list_asetpo.records" hide-actions
>
<template v-slot:items="props"> <template v-slot:items="props">
<tr> <tr>
<td class="text-xs-center pa-2">{{ props.item.PurchaseOrderNumber }}</td> <td class="text-xs-center pa-2">{{ props.item.PurchaseOrderNumber }}</td>
@@ -80,15 +56,21 @@
Rp. {{ formatCurrency(props.item.PurchaseOrderGrandTotal) }} Rp. {{ formatCurrency(props.item.PurchaseOrderGrandTotal) }}
</td> </td>
<td class="text-xs-center pa-2">{{ props.item.PurchaseOrderStatus }}</td> <td class="text-xs-center pa-2">{{ props.item.PurchaseOrderStatus }}</td>
<td class="text-xs-center pa-2"> <td class="text-xs-center pa-2" style="white-space: nowrap;">
<div v-show="props.item.PurchaseOrderStatus == 'Draft'"> <div v-show="props.item.PurchaseOrderStatus == 'Draft'">
<v-tooltip bottom> <v-tooltip bottom>
<template v-slot:activator="{ on }"> <template v-slot:activator="{ on }">
<v-btn <v-btn color="green" dark v-on="on" @click="openDialogAttachment(props.item)"
color="warning" dark v-on="on" small style="min-width: 40px; margin: 0;">
@click="" small <v-icon small>attachment</v-icon>
style="min-width: 40px; margin: 0;" </v-btn>
> </template>
<span>Upload Attachment</span>
</v-tooltip>
<v-tooltip bottom>
<template v-slot:activator="{ on }">
<v-btn color="warning" dark v-on="on" @click="sendRequestPO(props.item)"
small style="min-width: 40px; margin: 0;">
<v-icon small>send</v-icon> <v-icon small>send</v-icon>
</v-btn> </v-btn>
</template> </template>
@@ -96,11 +78,8 @@
</v-tooltip> </v-tooltip>
<v-tooltip bottom> <v-tooltip bottom>
<template v-slot:activator="{ on }"> <template v-slot:activator="{ on }">
<v-btn <v-btn color="info" dark v-on="on" @click="openEditFormOrder(props.item)"
color="info" dark v-on="on" style="min-width: 40px; margin: 0;" small>
@click="" small
style="min-width: 40px; margin: 0;"
>
<v-icon small>edit</v-icon> <v-icon small>edit</v-icon>
</v-btn> </v-btn>
</template> </template>
@@ -108,11 +87,8 @@
</v-tooltip> </v-tooltip>
<v-tooltip bottom> <v-tooltip bottom>
<template v-slot:activator="{ on }"> <template v-slot:activator="{ on }">
<v-btn <v-btn color="error" dark v-on="on" @click="openDialogDeleteOrder(props.item)"
color="error" dark v-on="on" small style="min-width: 40px; margin: 0;">
@click="" small
style="min-width: 40px; margin: 0;"
>
<v-icon small>delete</v-icon> <v-icon small>delete</v-icon>
</v-btn> </v-btn>
</template> </template>
@@ -122,15 +98,30 @@
<div v-show="props.item.PurchaseOrderStatus != 'Draft'"> <div v-show="props.item.PurchaseOrderStatus != 'Draft'">
<v-tooltip bottom> <v-tooltip bottom>
<template v-slot:activator="{ on }"> <template v-slot:activator="{ on }">
<v-btn <v-btn color="green" dark v-on="on" @click="openDialogAttachment(props.item)"
color="warning" dark v-on="on" small style="min-width: 40px; margin: 0;">
@click="viewPO(props.item)" small <v-icon small>attachment</v-icon>
style="min-width: 40px; margin: 0;" </v-btn>
> </template>
<span>Upload Attachment</span>
</v-tooltip>
<v-tooltip bottom>
<template v-slot:activator="{ on }">
<v-btn color="warning" dark v-on="on" @click="viewDetailPO(props.item)"
small style="min-width: 40px; margin: 0;">
<v-icon small>visibility</v-icon> <v-icon small>visibility</v-icon>
</v-btn> </v-btn>
<span>Detail PO</span>
</template> </template>
<span>Detail PO</span>
</v-tooltip>
<v-tooltip bottom>
<template v-slot:activator="{ on }">
<v-btn color="primary" dark v-on="on" @click="printout(props.item)"
small style="min-width: 40px; margin: 0;">
<v-icon small>print</v-icon>
</v-btn>
</template>
<span>Cetak PDF</span>
</v-tooltip> </v-tooltip>
</div> </div>
</td> </td>
@@ -149,22 +140,32 @@
</v-snackbar> </v-snackbar>
<dialog-add-attchment></dialog-add-attchment> <dialog-add-attchment></dialog-add-attchment>
<dialog-form-order-aset></dialog-form-order-aset>
<dialog-add-item-aset></dialog-add-item-aset>
<dialog-delete-order></dialog-delete-order> <dialog-delete-order></dialog-delete-order>
<dialog-create-order></dialog-create-order>
<dialog-create-kontrak></dialog-create-kontrak> <one-dialog-print
</div> :title="printtitle"
:width="printwidth"
:height="600"
:status="openprint"
:urlprint="urlprint"
@close-dialog-print="openprint = false"
></one-dialog-print>
</div>
</template> </template>
<script> <script>
module.exports = { module.exports = {
mounted() { mounted() {
this.$store.dispatch('poasset/lookupVendor') this.$store.dispatch('orderAsset/listingCabang');
this.$store.dispatch('poasset/lookupCabang') this.$store.dispatch('orderAsset/listingSupplier');
this.$store.dispatch('common/getListingPOAsset');
}, },
data() { data() {
return { return {
urlprint: "",
printtitle: "",
printwidth: "60%",
openprint: false,
menuStartdateFilter: false, menuStartdateFilter: false,
menuEnddateFilter: false, menuEnddateFilter: false,
headers: [ headers: [
@@ -205,35 +206,34 @@ module.exports = {
}, },
components: { components: {
'dialog-add-attchment': httpVueLoader('./dialog-add-attachment.vue'), 'dialog-add-attchment': httpVueLoader('./dialog-add-attachment.vue'),
'dialog-form-order-aset': httpVueLoader('./dialog-form-order-aset.vue'),
'dialog-add-item-aset': httpVueLoader('./dialog-add-item-aset.vue'),
'dialog-delete-order': httpVueLoader('./dialog-delete-order.vue'), 'dialog-delete-order': httpVueLoader('./dialog-delete-order.vue'),
'dialog-create-order': httpVueLoader('./dialog-create-order.vue'),
'dialog-create-kontrak': httpVueLoader('./dialog-create-contract.vue'), 'one-dialog-print': httpVueLoader('../../common/oneDialogPrintX.vue'),
}, },
computed: { computed: {
snackbar: { snackbar: {
get() { get() {
return this.$store.state.poasset.snackbar; return this.$store.state.common.snackbar;
}, },
set(val) { set(val) {
return this.$store.commit("poasset/update_snackbar", val); return this.$store.commit("common/update_snackbar", val);
} }
}, },
filterpo: { filterpo: {
get() { get() {
return this.$store.state.poasset.filterpo; return this.$store.state.common.filterpo;
}, },
set(val) { set(val) {
this.$store.commit("poasset/update_filterpo", val); this.$store.commit("common/update_filterpo", val);
this.$store.dispatch('common/getListingPOAsset');
} }
}, },
currpage: { currpage: {
get() { get() {
return this.$store.state.poasset.currpage; return this.$store.state.common.currpage;
}, },
set(val) { set(val) {
this.$store.commit("poasset/update_currpage", val); this.$store.commit("common/update_currpage", val);
} }
}, },
formattedStartdate() { formattedStartdate() {
@@ -243,15 +243,18 @@ module.exports = {
return this.formatDate(this.filterpo.enddate); return this.formatDate(this.filterpo.enddate);
}, },
list_status() { list_status() {
return this.$store.state.poasset.list_status; return this.$store.state.common.list_status;
}, },
list_asetpo() { list_asetpo() {
return this.$store.state.poasset.list_asetpo; return this.$store.state.common.list_asetpo;
}, },
pagelength() { pagelength() {
const total = this.list_asetpo.total; const total = this.list_asetpo.total;
if (total === undefined || total < 1) return 1; if (total === undefined || total < 1) return 1;
return Math.ceil(total/10); return Math.ceil(total / 10);
},
loading_process() {
return this.$store.state.common.loading_process;
} }
}, },
methods: { methods: {
@@ -266,17 +269,66 @@ module.exports = {
return num.toFixed(2).replace('.', ',').replace(/\B(?=(\d{3})+(?!\d))/g, "."); return num.toFixed(2).replace('.', ',').replace(/\B(?=(\d{3})+(?!\d))/g, ".");
}, },
createNewOrder() { createNewOrder() {
this.$store.commit('poasset/update_dialog_form_orderaset', true); this.$store.commit("orderAsset/update_dialog_create_order", true);
}, },
createNewContract() { openDialogAttachment(item) {
this.$store.commit("kontrakAsset/update_dialog_create_contract", true); let param = {
}, contractID: item.contractID,
viewPO(item) { poID: item.PurchaseOrderID
};
if (item.PurchaseOrderStatus != 'Draft') {
this.$store.commit("common/update_viewonlymode", true);
}
this.$store.dispatch('common/getAssetAttachment', param);
this.$store.commit("common/update_selected_orderaset", item);
this.$store.commit("common/update_dialog_attachment", true);
},
openDialogDeleteOrder(item) {
if (!this.loading_process) {
this.$store.commit("common/update_selected_orderaset", item)
this.$store.commit("common/update_dialog_deleteorder", true);
} else {
const snac = { color: 'warning', msg: 'terdapat proses lain yang masih berjalan', state: true };
this.snackbar = snac;
}
},
sendRequestPO(item) {
if (item.AttachmentCount < 1) {
const snac = { color: 'warning', msg: 'belum upload attachment', state: true };
this.snackbar = snac;
} else if (!this.loading_process) {
this.$store.dispatch('kontrakAsset/sendRequestPO', item.PurchaseOrderID);
} else {
const snac = { color: 'warning', msg: 'terdapat proses lain yang masih berjalan', state: true };
this.snackbar = snac;
}
},
openEditFormOrder(item) {
this.$store.dispatch("kontrakAsset/getDetailDataPO", item.PurchaseOrderID);
},
viewDetailPO(item) {
this.$store.commit("common/update_viewonlymode", true);
this.$store.dispatch("kontrakAsset/getDetailDataPO", item.PurchaseOrderID);
},
printout(val) {
this.printwidth = "60%";
this.printtitle = "";
let user = one_user();
let username = user && user.M_StaffName ? user.M_StaffName : "";
let tm = Date.now();
this.urlprint = BASE_URL + "/one-api/report/rpt_purchase_order_asset/pdf?id=" + val.PurchaseOrderID + "&username=" + username + "&tm=" + tm;
this.openprint = true;
} }
}, },
watch: { watch: {
filterpo: {
handler(val) {
this.$store.dispatch('common/getListingPOAsset');
},
deep: true
}
}, },
} }
</script> </script>

View File

@@ -0,0 +1,165 @@
import * as api from '../api/api.js';
export default {
namespaced: true,
state: {
/* common */
snackbar: {
color: 'success',
msg: '',
state: false
},
loading_process: false,
selected_orderaset: {},
viewonlymode: false,
/* main layout */
filterpo: {
startdate: moment(new Date()).format('YYYY-MM-DD'),
enddate: moment(new Date()).format('YYYY-MM-DD'),
status: 'All',
search: ''
},
list_status: ['All', 'Draft', 'Pending', 'Approved', 'Rejected', 'Completed'],
list_asetpo: {
records: [],
total: 0
},
currpage: 1,
/* delete order */
dialog_deleteorder: false,
/* attachment */
dialog_attachment: false,
assets_attachment: []
},
mutations: {
/* common */
update_snackbar(state, val) {
state.snackbar = val
},
update_loading_process(state, val) {
state.loading_process = val
},
update_selected_orderaset(state, val) {
state.selected_orderaset = val
},
update_viewonlymode(state, val) {
state.viewonlymode = val
},
/* main layout */
update_filterpo(state, val) {
state.filterpo = val
},
update_list_status(state, val) {
state.list_status = val
},
update_list_asetpo(state, val) {
state.list_asetpo = val
},
update_currpage(state, val) {
state.currpage = val
},
/* delete order */
update_dialog_deleteorder(state, val) {
state.dialog_deleteorder = val
},
/* attachment */
update_dialog_attachment(state, val) {
state.dialog_attachment = val
},
update_assets_attachment(state, val) {
state.assets_attachment = val
}
},
actions: {
async getListingPOAsset(context) {
try {
const params = {
token: one_token(),
currpage: context.state.currpage,
...context.state.filterpo
};
const resp = await api.getDaftarPoAset(params);
if (resp.status != 'OK') {
throw new Error(resp.message);
}
context.commit('update_list_asetpo', resp.data);
} catch (e) {
const snac = { color: 'error', msg: e.message, state: true };
context.commit("update_snackbar", snac);
}
},
async getAssetAttachment(context, param) {
try {
const params = {
token: one_token(),
contractID: param.contractID,
poID: param.poID
};
const resp = await api.getDaftarAttachment(params);
if (resp.status != 'OK') {
throw new Error(resp.message);
}
context.commit('update_assets_attachment', resp.data);
} catch (e) {
const snac = { color: 'error', msg: e.message, state: true };
context.commit("update_snackbar", snac);
}
},
async uploadAttachment(context, params) {
try {
context.state.loading_process = true;
const resp = await api.uploadAttachment(params);
if (resp.status != 'OK') {
throw new Error(resp.message);
}
const snac = { color: 'success', msg: resp.data, state: true };
context.commit("update_snackbar", snac);
context.dispatch('getListingPOAsset');
context.state.loading_process = false;
context.state.dialog_attachment = false;
} catch (e) {
context.state.loading_process = false;
const snac = { color: 'error', msg: e.message, state: true };
context.commit("update_snackbar", snac);
}
},
async deleteOrderAsset(context) {
try {
context.state.loading_process = true;
const order = context.state.selected_orderaset;
const params = {
token: one_token(),
poID: order.PurchaseOrderID,
contractID: order.contractID,
ponumber: order.PurchaseOrderNumber,
SupplierDownpaymentID: order.SupplierDownpaymentID
};
const resp = await api.deletePoAsset(params);
if (resp.status != 'OK') {
throw new Error(resp.message);
}
const snac = { color: 'success', msg: resp.data, state: true };
context.commit("update_snackbar", snac);
context.dispatch('getListingPOAsset');
context.state.loading_process = false;
context.state.dialog_deleteorder = false;
} catch (e) {
context.state.loading_process = false;
const snac = { color: 'error', msg: e.message, state: true };
context.commit("update_snackbar", snac);
}
}
}
}

View File

@@ -1,30 +1,147 @@
import * as api from '../api/api.js';
export default { export default {
namespaced: true, namespaced: true,
state: { state: {
dialog_create_contract: false,
form_kontrak: { form_kontrak: {
nama_kontrak: '', nama_kontrak: '',
tanggal_kontrak: moment(new Date()).format('YYYY-MM-DD'), tanggal_kontrak: moment(new Date()).format('YYYY-MM-DD'),
supplierID_kontrak: '',
tanggalAwal_kontrak: moment(new Date()).format('YYYY-MM-DD'), tanggalAwal_kontrak: moment(new Date()).format('YYYY-MM-DD'),
tanggalAkhir_kontrak: moment(new Date()).format('YYYY-MM-DD'), tanggalAkhir_kontrak: moment(new Date()).format('YYYY-MM-DD'),
durasi_cicilan: 1, durasi_cicilan: 1,
jumlah_cicilan: 1, jumlah_cicilan: 1,
tanggalBayar_cicilan: 1, tanggalBayar_cicilan: 1,
besarNilai_cicilan: 0, besarNilai_cicilan: 0,
type_downpayment: 'nominal', type_downpayment: 'percent',
besarNilai_downpayment: 0, besarNilai_downpayment: 0
type_pajak: 'persen',
besarNilai_pajak: 0
} }
}, },
mutations: { mutations: {
update_dialog_create_contract(state, val) {
state.dialog_create_contract = val
},
update_form_kontrak(state, val) { update_form_kontrak(state, val) {
state.form_kontrak = val state.form_kontrak = val
} }
}, },
actions: {} actions: {
async saveOrderAsset(context, params) {
try {
context.commit("common/update_loading_process", true, { root: true });
params.token = one_token();
const resp = await api.createPoAsset(params);
if (resp.status != 'OK') {
throw new Error(resp.message);
}
const snac = { color: 'success', msg: resp.data, state: true };
context.commit("common/update_snackbar", snac, { root: true });
context.commit("common/update_loading_process", false, { root: true });
context.commit("orderAsset/update_dialog_create_order", false, { root: true });
context.dispatch('common/getListingPOAsset', {}, { root: true });
} catch (error) {
context.commit("common/update_loading_process", false, { root: true });
const snac = { color: 'error', msg: error.message, state: true };
context.commit("common/update_snackbar", snac, { root: true });
}
},
async editOrderAsset(context, params) {
try {
context.commit("common/update_loading_process", true, { root: true });
params.token = one_token();
const resp = await api.editPoAsset(params);
if (resp.status != 'OK') {
throw new Error(resp.message);
}
const snac = { color: 'success', msg: resp.data, state: true };
context.commit("common/update_snackbar", snac, { root: true });
context.commit("common/update_loading_process", false, { root: true });
context.commit("orderAsset/update_dialog_create_order", false, { root: true });
context.dispatch('common/getListingPOAsset', {}, { root: true });
} catch (error) {
context.commit("common/update_loading_process", false, { root: true });
const snac = { color: 'error', msg: error.message, state: true };
context.commit("common/update_snackbar", snac, { root: true });
}
},
async sendRequestPO(context, poID) {
try {
context.commit("common/update_loading_process", true, { root: true });
let params = {
token: one_token(),
approvelevel: "0",
poID: poID,
}
const resp = await api.updateApprovalPO(params);
if (resp.status != 'OK') {
throw new Error(resp.message);
}
const snac = { color: 'success', msg: resp.data, state: true };
context.commit("common/update_snackbar", snac, { root: true });
context.commit("common/update_loading_process", false, { root: true });
context.commit("orderAsset/update_dialog_create_order", false, { root: true });
context.dispatch('common/getListingPOAsset', {}, { root: true });
} catch (error) {
context.commit("common/update_loading_process", false, { root: true });
const snac = { color: 'error', msg: error.message, state: true };
context.commit("common/update_snackbar", snac, { root: true });
}
},
async getDetailDataPO(context, poID) {
try {
let params = {
token: one_token(),
poID: poID,
}
const resp = await api.getDataKontrakPoAset(params);
if (resp.status != 'OK') {
throw new Error(resp.message);
}
let formOrder = {
podate: resp.data.podate,
supplierID: resp.data.supplierID,
reference: resp.data.reference,
branchID: resp.data.branchID,
gudangID: resp.data.gudangID,
typepajak: resp.data.typepajak,
valuepajak: parseFloat(resp.data.valuepajak),
typediskon: resp.data.typediskon,
valuediskon: parseFloat(resp.data.valuediskon),
catatan: resp.data.catatan
};
let formKontrak = {
nama_kontrak: resp.data.contractName,
tanggal_kontrak: resp.data.contractDate,
tanggalAwal_kontrak: resp.data.contractStart,
tanggalAkhir_kontrak: resp.data.contractEnd,
durasi_cicilan: resp.data.contractDuration,
jumlah_cicilan: resp.data.installmentNumber,
tanggalBayar_cicilan: resp.data.installmentDate,
besarNilai_cicilan: parseFloat(resp.data.installmentPayAmount),
type_downpayment: resp.data.installmentDownPaymentType,
besarNilai_downpayment: parseFloat(resp.data.installmentDownPayment),
};
let summary = resp.data.summary;
let selected_request = resp.data.detail;
selected_request.forEach(item => {
item.SupplierPrice = parseFloat(item.SupplierPrice)
item.DiskonAmount = parseFloat(item.DiskonAmount)
});
context.dispatch('orderAsset/listingGudang', resp.data.branchID, { root: true });
context.commit('update_form_kontrak', formKontrak);
context.commit('orderAsset/update_form_order_asset', formOrder, { root: true });
context.commit('orderAsset/update_selected_request_asset', selected_request, { root: true });
context.commit('orderAsset/update_summary_order', summary, { root: true });
context.commit('common/update_selected_orderaset', resp.data, { root: true });
context.dispatch('orderAsset/recalculateOrderSummary', {}, { root: true });
context.commit('orderAsset/update_dialog_create_order', true, { root: true });
} catch (error) {
const snac = { color: 'error', msg: error.message, state: true };
context.commit("common/update_snackbar", snac, { root: true });
}
}
}
} }

View File

@@ -0,0 +1,224 @@
import * as api from '../api/api.js';
export default {
namespaced: true,
state: {
/* dialog create order */
dialog_create_order: false,
form_order_asset: {
podate: moment(new Date()).format('YYYY-MM-DD'),
supplierID: "",
reference: "",
branchID: "",
gudangID: "",
typepajak: "percent",
valuepajak: 0,
typediskon: "percent",
valuediskon: 0,
catatan: ""
},
list_supplier: [],
list_cabang: [],
list_gudang: [],
/* item request */
dialog_select_asset: false,
requested_asset: {
records: [],
total: 0,
},
selected_request_asset: [],
summary_order: {
subtotal: 0,
diskon: 0,
pajak: 0,
downpayment: 0,
total_before_downpayment: 0,
total: 0
}
},
mutations: {
update_dialog_create_order(state, val) {
state.dialog_create_order = val
},
update_form_order_asset(state, val) {
state.form_order_asset = val
},
update_list_supplier(state, val) {
state.list_supplier = val
},
update_list_cabang(state, val) {
state.list_cabang = val
},
update_list_gudang(state, val) {
state.list_gudang = val
},
update_dialog_select_asset(state, val) {
state.dialog_select_asset = val
},
update_requested_asset(state, val) {
state.requested_asset = val
},
update_selected_request_asset(state, val) {
state.selected_request_asset = val
},
update_summary_order(state, val) {
state.summary_order = val
}
},
actions: {
async listingCabang(context) {
try {
let param = { token: one_token() }
const resp = await api.getListCabang(param);
if (resp.status != "OK") {
throw new Error(resp.message);
}
context.commit('update_list_cabang', resp.data);
} catch (e) {
const snac = { color: 'error', msg: e.message, state: true };
context.commit("common/update_snackbar", snac, { root: true });
}
},
async listingGudang(context, branchID) {
try {
let param = {
token: one_token(),
M_BranchID: branchID
}
const resp = await api.getListGudang(param);
if (resp.status != "OK") {
throw new Error(resp.message);
}
context.commit('update_list_gudang', resp.data);
} catch (e) {
const snac = { color: 'error', msg: e.message, state: true };
context.commit("common/update_snackbar", snac, { root: true });
}
},
async listingSupplier(context) {
try {
const params = { token: one_token() };
const resp = await api.getListSupplier(params);
if (resp.status != 'OK') {
throw new Error(resp.message);
}
context.commit('update_list_supplier', resp.data);
} catch (e) {
const snac = { color: 'error', msg: e.message, state: true };
context.commit("update_snackbar", snac, { root: true });
}
},
async searchItemRequest(context, keyword) {
try {
const form = context.state.form_order_asset;
const params = {
token: one_token(),
search: keyword,
branchID: form.branchID,
supplierID: form.supplierID
};
const resp = await api.searchRequestAset(params);
if (resp.status != 'OK') {
throw new Error(resp.message);
}
context.commit('update_requested_asset', resp.data)
} catch (e) {
const snac = { color: 'error', msg: e.message, state: true };
context.commit("update_snackbar", snac, { root: true });
}
},
async recalculateOrderSummary(context) {
const formOrder = context.state.form_order_asset;
const formKontrak = context.rootState.kontrakAsset.form_kontrak;
const items = JSON.parse(JSON.stringify(context.state.selected_request_asset));
const calculatedItems = items.map(item => {
const supplierPrice = parseCurrency(item.SupplierPrice);
const requestQty = item.detail.reduce((sum, detail) => {
return sum + parseCurrency(detail.RequestQty);
}, 0);
let itemDiscount = 0;
if (item.DiskonType == 'P') {
itemDiscount = supplierPrice * parseCurrency(item.DiskonAmount) / 100;
} else {
itemDiscount = parseCurrency(item.DiskonAmount);
}
const endPrice = Math.max(supplierPrice - itemDiscount, 0);
const tempTotal = requestQty * endPrice;
return {
...item,
RequestQty: requestQty,
EndPrice: endPrice,
TempTotal: tempTotal,
detail: item.detail.map(detail => ({
...detail,
SupplierPrice: supplierPrice
}))
};
});
const subtotal = calculatedItems.reduce((sum, item) => {
return sum + parseCurrency(item.TempTotal);
}, 0);
const diskon = calculateByType(
formOrder.typediskon,
formOrder.valuediskon,
subtotal
);
const subtotalAfterDiskon = Math.max(subtotal - diskon, 0);
const pajak = calculateByType(
formOrder.typepajak,
formOrder.valuepajak,
subtotalAfterDiskon
);
const totalBeforeDownpayment = subtotalAfterDiskon + pajak;
const downpayment = calculateByType(
formKontrak.type_downpayment,
formKontrak.besarNilai_downpayment,
totalBeforeDownpayment
);
const total = Math.max(totalBeforeDownpayment - downpayment, 0);
context.commit('update_selected_request_asset', calculatedItems);
context.commit('update_summary_order', {
subtotal: subtotal,
diskon: diskon,
pajak: pajak,
downpayment: downpayment,
total_before_downpayment: totalBeforeDownpayment,
total: total
});
}
}
}
function parseCurrency(value) {
let cleanValue = String(value || 0).replace(/\./g, '');
cleanValue = cleanValue.replace(',', '.');
return parseFloat(cleanValue) || 0;
}
function calculateByType(type, value, base) {
const amount = parseCurrency(value);
if (type == 'percent') {
return base * amount / 100;
}
return amount;
}

View File

@@ -35,9 +35,9 @@ export default {
supplierID: "", supplierID: "",
reference: "", reference: "",
branchcode: "", branchcode: "",
typepajak: "percent", typepajak: "persen",
valuepajak: 0, valuepajak: 0,
typediskon: "percent", typediskon: "persen",
valuediskon: 0 valuediskon: 0
}, },
item_orderaset: [], item_orderaset: [],

View File

@@ -1,11 +1,14 @@
import system from "../../../apps/modules/system/system.js"; import system from "../../../apps/modules/system/system.js";
import common from "./modules/common.js";
import kontrakAsset from "./modules/kontrak-asset.js"; import kontrakAsset from "./modules/kontrak-asset.js";
import poasset from "./modules/poasset.js"; import orderAsset from "./modules/order-asset.js";
export const store = new Vuex.Store({ export const store = new Vuex.Store({
modules: { modules: {
system: system, system: system,
poasset: poasset, common: common,
kontrakAsset: kontrakAsset kontrakAsset: kontrakAsset,
orderAsset: orderAsset
}, },
state: {}, state: {},
mutations: {}, mutations: {},

View File

@@ -77,7 +77,7 @@
Rp. {{ formatCurrency(props.item.PurchaseOrderGrandTotal) }} Rp. {{ formatCurrency(props.item.PurchaseOrderGrandTotal) }}
</td> </td>
<td class="text-xs-center pa-2">{{ props.item.PurchaseOrderStatus }}</td> <td class="text-xs-center pa-2">{{ props.item.PurchaseOrderStatus }}</td>
<td class="text-xs-center pa-2"> <td class="text-xs-center pa-2" style="white-space: nowrap;">
<div v-show="props.item.PurchaseOrderStatus == 'Draft'"> <div v-show="props.item.PurchaseOrderStatus == 'Draft'">
<v-tooltip bottom> <v-tooltip bottom>
<template v-slot:activator="{ on }"> <template v-slot:activator="{ on }">
@@ -141,6 +141,18 @@
</template> </template>
<span>Detail PO</span> <span>Detail PO</span>
</v-tooltip> </v-tooltip>
<v-tooltip bottom>
<template v-slot:activator="{ on }">
<v-btn
color="primary" dark v-on="on" small
@click="printout(props.item)"
style="min-width: 40px; margin: 0;"
>
<v-icon small>print</v-icon>
</v-btn>
</template>
<span>Cetak PDF</span>
</v-tooltip>
</div> </div>
</td> </td>
</tr> </tr>
@@ -163,6 +175,14 @@
<dialog-jasa-delete></dialog-jasa-delete> <dialog-jasa-delete></dialog-jasa-delete>
<dialog-jasa-attach></dialog-jasa-attach> <dialog-jasa-attach></dialog-jasa-attach>
<dialog-view-jasa></dialog-view-jasa> <dialog-view-jasa></dialog-view-jasa>
<one-dialog-print
:title="printtitle"
:width="printwidth"
:height="600"
:status="openprint"
:urlprint="urlprint"
@close-dialog-print="openprint = false"
></one-dialog-print>
</div> </div>
</template> </template>
@@ -175,6 +195,7 @@ module.exports = {
'dialog-jasa-delete': httpVueLoader('./dialogDeletePoJasa.vue'), 'dialog-jasa-delete': httpVueLoader('./dialogDeletePoJasa.vue'),
'dialog-jasa-attach': httpVueLoader('./dialogAddAttachment.vue'), 'dialog-jasa-attach': httpVueLoader('./dialogAddAttachment.vue'),
'dialog-view-jasa': httpVueLoader('./dialogViewPoJasa.vue'), 'dialog-view-jasa': httpVueLoader('./dialogViewPoJasa.vue'),
'one-dialog-print': httpVueLoader('../../common/oneDialogPrintX.vue'),
}, },
mounted() { mounted() {
this.$store.dispatch("poservice/lookupVendor") this.$store.dispatch("poservice/lookupVendor")
@@ -183,6 +204,10 @@ module.exports = {
}, },
data() { data() {
return { return {
urlprint: "",
printtitle: "",
printwidth: "60%",
openprint: false,
menuStartdateFilter: false, menuStartdateFilter: false,
menuEnddateFilter: false, menuEnddateFilter: false,
headers: [ headers: [
@@ -311,6 +336,15 @@ module.exports = {
viewPO(item) { viewPO(item) {
this.$store.dispatch("poservice/lookupDataPOJasa", item.PurchaseOrderID) this.$store.dispatch("poservice/lookupDataPOJasa", item.PurchaseOrderID)
this.$store.commit("poservice/update_dialog_viewpo", true); this.$store.commit("poservice/update_dialog_viewpo", true);
},
printout(val) {
this.printwidth = "60%";
this.printtitle = "";
let user = one_user();
let username = user && user.M_StaffName ? user.M_StaffName : "";
let tm = Date.now();
this.urlprint = BASE_URL + "/one-api/report/rpt_purchase_order_jasa/pdf?id=" + val.PurchaseOrderID + "&username=" + username + "&tm=" + tm;
this.openprint = true;
} }
}, },
watch: { watch: {

View File

@@ -111,20 +111,29 @@
{{ props.item.PurchaseRequestDirectStatus }} {{ props.item.PurchaseRequestDirectStatus }}
</v-chip> </v-chip>
</td> </td>
<td class="text-xs-center pa-2"> <td class="text-xs-center pa-2" style="white-space: nowrap;">
<div v-if="props.item.PurchaseRequestDirectStatus != 'Draft'"> <div v-if="props.item.PurchaseRequestDirectStatus != 'Draft'">
<v-btn <v-btn
v-if="props.item.PurchaseRequestDirectStatus == 'Pending'" v-if="props.item.PurchaseRequestDirectStatus == 'Pending'"
small color="black" title="Edit" @click="{}" small color="black" title="Edit" @click="{}"
style="min-width: 25px; height: 25px; margin: 0;"
> >
<v-icon small color="white">edit</v-icon> <v-icon small color="white">edit</v-icon>
</v-btn> </v-btn>
<v-btn <v-btn
v-if="['Approved', 'Paid', 'Completed'].includes(props.item.PurchaseRequestDirectStatus)" v-if="['Approved', 'Paid', 'Completed'].includes(props.item.PurchaseRequestDirectStatus)"
small color="blue" title="Detail" small color="blue" title="Detail"
style="min-width: 25px; height: 25px; margin: 0;"
> >
<v-icon small color="white">visibility</v-icon> <v-icon small color="white">visibility</v-icon>
</v-btn> </v-btn>
<v-btn
v-if="['Approved', 'Paid', 'Completed'].includes(props.item.PurchaseRequestDirectStatus)"
small color="primary" title="Cetak PDF" @click="printout(props.item)"
style="min-width: 25px; height: 25px; margin: 0;"
>
<v-icon small color="white">print</v-icon>
</v-btn>
</div> </div>
</td> </td>
</tr> </tr>
@@ -325,6 +334,16 @@
<one-dialog-info :status="opendialoginfo" :msg="msginfo" <one-dialog-info :status="opendialoginfo" :msg="msginfo"
@close-dialog-info="opendialoginfo = false"></one-dialog-info> @close-dialog-info="opendialoginfo = false"></one-dialog-info>
</template> </template>
<!-- dialog print -->
<one-dialog-print
:title="printtitle"
:width="printwidth"
:height="600"
:status="openprint"
:urlprint="urlprint"
@close-dialog-print="openprint = false"
></one-dialog-print>
</v-layout> </v-layout>
</div> </div>
</template> </template>
@@ -349,9 +368,14 @@ module.exports = {
"one-dialog-info": httpVueLoader("../../common/oneDialogInfo.vue"), "one-dialog-info": httpVueLoader("../../common/oneDialogInfo.vue"),
"one-dialog-attachment": httpVueLoader("./formDialogAttachtment.vue"), "one-dialog-attachment": httpVueLoader("./formDialogAttachtment.vue"),
"one-dialog-edit-req": httpVueLoader("./formEditRequest.vue"), "one-dialog-edit-req": httpVueLoader("./formEditRequest.vue"),
"one-dialog-print": httpVueLoader("../../common/oneDialogPrintX.vue"),
}, },
data() { data() {
return { return {
urlprint: "",
printtitle: "",
printwidth: "60%",
openprint: false,
msgAlertDeleteOrReject: "", msgAlertDeleteOrReject: "",
dialogAlertRejectRequest: false, dialogAlertRejectRequest: false,
dialogAlertDeleteDetail: false, dialogAlertDeleteDetail: false,
@@ -376,7 +400,7 @@ module.exports = {
}, },
{ {
text: "TOTAL", align: "left", sortable: false, text: "TOTAL", align: "left", sortable: false,
value: "description", width: "20%", class: "blue lighten-3 white--text", value: "description", width: "15%", class: "blue lighten-3 white--text",
}, },
{ {
text: "STATUS", align: "center", sortable: false, text: "STATUS", align: "center", sortable: false,
@@ -384,7 +408,7 @@ module.exports = {
}, },
{ {
text: "AKSI", align: "center", sortable: false, text: "AKSI", align: "center", sortable: false,
value: "action", width: "10%", class: "blue lighten-3 white--text", value: "action", width: "15%", class: "blue lighten-3 white--text",
}, },
], ],
detail_headers: [ detail_headers: [
@@ -742,6 +766,15 @@ module.exports = {
}) })
} }
this.dialogAlertUnapprove = false; this.dialogAlertUnapprove = false;
},
printout(val) {
this.printwidth = "60%";
this.printtitle = "";
let user = one_user();
let username = user && user.M_StaffName ? user.M_StaffName : "";
let tm = Date.now();
this.urlprint = BASE_URL + "/one-api/report/rpt_pr_direct_approval/pdf?id=" + val.PurchaseRequestDirectID + "&username=" + username + "&tm=" + tm;
this.openprint = true;
} }
}, },
} }

View File

@@ -204,6 +204,7 @@
> >
<td <td
class="text-xs-center pa-2" class="text-xs-center pa-2"
style="white-space: nowrap;"
v-bind:class="{ v-bind:class="{
'amber lighten-4': isSelected(props.item), 'amber lighten-4': isSelected(props.item),
}" }"
@@ -229,10 +230,20 @@
<template v-else> <template v-else>
<td <td
class="text-xs-center pa-2" class="text-xs-center pa-2"
style="white-space: nowrap;"
v-bind:class="{ v-bind:class="{
'amber lighten-4': isSelected(props.item), 'amber lighten-4': isSelected(props.item),
}" }"
></td> >
<v-btn
style="min-width: 25px; height: 25px; margin: 0;"
@click="printout(props.item)"
small title="Cetak PDF"
color="primary"
>
<v-icon small color="white">print</v-icon>
</v-btn>
</td>
</template> </template>
</template> </template>
</v-data-table> </v-data-table>
@@ -559,6 +570,14 @@
<!-- <add-request-detail-dialog></add-request-detail-dialog> --> <!-- <add-request-detail-dialog></add-request-detail-dialog> -->
<form-add-request-detail-dialog></form-add-request-detail-dialog> <form-add-request-detail-dialog></form-add-request-detail-dialog>
<one-dialog-attachment></one-dialog-attachment> <one-dialog-attachment></one-dialog-attachment>
<one-dialog-print
:title="printtitle"
:width="printwidth"
:height="600"
:status="openprint"
:urlprint="urlprint"
@close-dialog-print="openprint = false"
></one-dialog-print>
<!-- <one-dialog-alert <!-- <one-dialog-alert
:status="dialogAlertDeleteRequest" :status="dialogAlertDeleteRequest"
@@ -606,9 +625,14 @@ module.exports = {
"one-dialog-alert": httpVueLoader("../../common/oneDialogAlert.vue"), "one-dialog-alert": httpVueLoader("../../common/oneDialogAlert.vue"),
"one-dialog-error": httpVueLoader("../../common/oneDialogError.vue"), "one-dialog-error": httpVueLoader("../../common/oneDialogError.vue"),
"one-dialog-attachment": httpVueLoader("./formDialogAttachtment.vue"), "one-dialog-attachment": httpVueLoader("./formDialogAttachtment.vue"),
"one-dialog-print": httpVueLoader("../../common/oneDialogPrintX.vue"),
}, },
data() { data() {
return { return {
urlprint: "",
printtitle: "",
printwidth: "60%",
openprint: false,
msgAlertDeleteRequest: "", msgAlertDeleteRequest: "",
dialogAlertDeleteRequest: false, dialogAlertDeleteRequest: false,
dialogAlertDeleteDetail: false, dialogAlertDeleteDetail: false,
@@ -1109,6 +1133,15 @@ module.exports = {
this.$store.commit("requester/update_dialog_form", true); this.$store.commit("requester/update_dialog_form", true);
this.$store.commit("requester/update_cekFile", false); this.$store.commit("requester/update_cekFile", false);
this.$store.commit("requester/update_actAttach", 'preview'); this.$store.commit("requester/update_actAttach", 'preview');
},
printout(val) {
this.printwidth = "60%";
this.printtitle = "";
let user = one_user();
let username = user && user.M_StaffName ? user.M_StaffName : "";
let tm = Date.now();
this.urlprint = BASE_URL + "/one-api/report/rpt_pr_direct/pdf?id=" + val.PurchaseRequestDirectID + "&username=" + username + "&tm=" + tm;
this.openprint = true;
} }
}, },
}; };

View File

@@ -59,11 +59,10 @@ module.exports = {
this.dialogConfirmHandover = false this.dialogConfirmHandover = false
}, },
itemNeedConfirming(data) { itemNeedConfirming(data) {
return data.filter(item => item.allHandedOver == 'N'); return Array.isArray(data) ? data.filter(item => item.allHandedOver == 'N') : [];
}, },
async saveConfirmHandOver() { async saveConfirmHandOver() {
const dataHanded = this.selected_main.itemHandedOver; const itemHanded = this.itemNeedConfirming(this.selected_main.itemHandedOver);
const itemHanded = dataHanded.filter(item => item.allHandedOver == 'N');
let prm = { let prm = {
purchaseRequestID: this.selected_main.prId, purchaseRequestID: this.selected_main.prId,

View File

@@ -101,32 +101,78 @@
</td> </td>
<template v-if="props.item.prStatus == 'Draft'"> <template v-if="props.item.prStatus == 'Draft'">
<td class="text-xs-center pa-2 pr-5" v-bind:class="{ <td class="text-xs-center pa-2" style="white-space: nowrap;" v-bind:class="{
'amber lighten-4': isSelected(props.item), 'amber lighten-4': isSelected(props.item),
}"> }">
<v-icon small @click="editRequest(props.item)">edit</v-icon> <v-btn
<v-icon small @click="deleteRequest(props.item)">delete</v-icon> style="min-width: 25px; height: 25px; margin: 0;"
@click="editRequest(props.item)"
small title="Edit"
color="black"
>
<v-icon small color="white">edit</v-icon>
</v-btn>
<v-btn
style="min-width: 25px; height: 25px; margin: 0;"
@click="deleteRequest(props.item)"
small title="Hapus"
color="red"
>
<v-icon small color="white">delete</v-icon>
</v-btn>
</td> </td>
</template> </template>
<template v-else-if="props.item.prStatus == 'Pending'"> <template v-else-if="props.item.prStatus == 'Pending'">
<td class="text-xs-center pa-2 pr-5" v-bind:class="{ <td class="text-xs-center pa-2" style="white-space: nowrap;" v-bind:class="{
'amber lighten-4': isSelected(props.item), 'amber lighten-4': isSelected(props.item),
}"> }">
<v-icon small @click="previewRequest(props.item)">receipt</v-icon> <v-btn
style="min-width: 25px; height: 25px; margin: 0;"
@click="previewRequest(props.item)"
small title="Preview Request"
color="blue"
>
<v-icon small color="white">receipt</v-icon>
</v-btn>
<v-btn
style="min-width: 25px; height: 25px; margin: 0;"
@click="printout(props.item)"
small title="Cetak PDF"
color="primary"
>
<v-icon small color="white">print</v-icon>
</v-btn>
</td> </td>
</template> </template>
<template v-else-if="hasHandover(props.item.itemHandedOver)"> <template v-else-if="hasHandover(props.item.itemHandedOver)">
<td class="text-xs-center pa-2 pr-5" <td class="text-xs-center pa-2" style="white-space: nowrap;"
v-bind:class="{ 'amber lighten-4': isSelected(props.item), }"> v-bind:class="{ 'amber lighten-4': isSelected(props.item), }">
<v-btn color="success" prepend-icon="mdi-check-circle" <v-btn color="success" prepend-icon="mdi-check-circle"
@click="confirmHandover(props.item)"> @click="confirmHandover(props.item)">
Konfirmasi Terima Konfirmasi Terima
</v-btn> </v-btn>
<v-btn
style="min-width: 25px; height: 25px; margin: 0;"
@click="printout(props.item)"
small title="Cetak PDF"
color="primary"
>
<v-icon small color="white">print</v-icon>
</v-btn>
</td> </td>
</template> </template>
<template v-else> <template v-else>
<td class="text-xs-center pa-2 pr-5" <td class="text-xs-center pa-2" style="white-space: nowrap;"
v-bind:class="{ 'amber lighten-4': isSelected(props.item), }"></td> v-bind:class="{ 'amber lighten-4': isSelected(props.item), }">
<v-btn
style="min-width: 25px; height: 25px; margin: 0;"
@click="printout(props.item)"
small title="Cetak PDF"
color="primary"
>
<v-icon small color="white">print</v-icon>
</v-btn>
</td>
</template> </template>
</template> </template>
</v-data-table> </v-data-table>
@@ -151,6 +197,15 @@
<one-dialog-alert :status="dialogAlertDeleteDetail" :msg="msgAlertDeleteRequest" <one-dialog-alert :status="dialogAlertDeleteDetail" :msg="msgAlertDeleteRequest"
@forget-dialog-alert="dialogAlertDeleteDetail = false" @forget-dialog-alert="dialogAlertDeleteDetail = false"
@close-dialog-alert="closeAndDeleteDetail()"></one-dialog-alert> @close-dialog-alert="closeAndDeleteDetail()"></one-dialog-alert>
<one-dialog-print
:title="printtitle"
:width="printwidth"
:height="600"
:status="openprint"
:urlprint="urlprint"
@close-dialog-print="openprint = false"
></one-dialog-print>
</div> </div>
</template> </template>
@@ -184,9 +239,14 @@ module.exports = {
"dialog-confirm-handover": httpVueLoader("./dialogConfirmHandover.vue"), "dialog-confirm-handover": httpVueLoader("./dialogConfirmHandover.vue"),
"one-dialog-alert": httpVueLoader("../../common/oneDialogAlert.vue"), "one-dialog-alert": httpVueLoader("../../common/oneDialogAlert.vue"),
"one-dialog-error": httpVueLoader("../../common/oneDialogError.vue"), "one-dialog-error": httpVueLoader("../../common/oneDialogError.vue"),
"one-dialog-print": httpVueLoader("../../common/oneDialogPrintX.vue"),
}, },
data() { data() {
return { return {
urlprint: "",
printtitle: "",
printwidth: "60%",
openprint: false,
msgAlertDeleteRequest: "", msgAlertDeleteRequest: "",
dialogAlertDeleteRequest: false, dialogAlertDeleteRequest: false,
dialogAlertDeleteDetail: false, dialogAlertDeleteDetail: false,
@@ -225,10 +285,10 @@ module.exports = {
}, },
{ {
text: "AKSI", text: "AKSI",
align: "left", align: "center",
sortable: false, sortable: false,
value: "action", value: "action",
width: "5%", width: "15%",
class: "blue lighten-3 white--text", class: "blue lighten-3 white--text",
}, },
], ],
@@ -686,12 +746,21 @@ module.exports = {
}, },
hasHandover(item) { hasHandover(item) {
// props.item.hasHandover === '1' && props.item.handoverConfirmedBy == '0' && props.item.handoverToUserID === user.M_UserID // props.item.hasHandover === '1' && props.item.handoverConfirmedBy == '0' && props.item.handoverToUserID === user.M_UserID
return item.length > 0 && item.every(obj => obj.allHandedOver == 'N') return Array.isArray(item) && item.length > 0 && item.every(obj => obj.allHandedOver == 'N')
}, },
confirmHandover(item) { confirmHandover(item) {
this.$store.commit("requester/updateSelectedMainTable", item); this.$store.commit("requester/updateSelectedMainTable", item);
this.$store.commit("requester/updateDialogConfirmHandover", true); this.$store.commit("requester/updateDialogConfirmHandover", true);
}, },
printout(val) {
this.printwidth = "60%";
this.printtitle = "";
let user = one_user();
let username = user && user.M_StaffName ? user.M_StaffName : "";
let tm = Date.now();
this.urlprint = BASE_URL + "/one-api/report/rpt_stock_request_np/pdf?id=" + val.prId + "&username=" + username + "&tm=" + tm;
this.openprint = true;
},
}, },
}; };
</script> </script>

View File

@@ -110,7 +110,7 @@ export default {
update_dialog_riwayat(state, val) { update_dialog_riwayat(state, val) {
state.dialog_riwayat = val state.dialog_riwayat = val
}, },
update_riwayat_item(state,val) { update_riwayat_item(state, val) {
state.riwayat_item = val state.riwayat_item = val
}, },
updateItemCategoryOptions(state, val) { updateItemCategoryOptions(state, val) {
@@ -705,7 +705,7 @@ export default {
}; };
context.commit("updateDivisionOptions", data.records); context.commit("updateDivisionOptions", data.records);
context.commit("updateSelectedDivision", data.selected); context.commit("updateSelectedDivision", data.selected);
context.dispatch("getItemGroupSubGroup",data.selected); context.dispatch("getItemGroupSubGroup", data.selected);
} }
} catch (e) { } catch (e) {
context.commit("updateLoadingAutocomplete", false) context.commit("updateLoadingAutocomplete", false)
@@ -766,7 +766,7 @@ export default {
context.commit("updateErrMessage", ""); context.commit("updateErrMessage", "");
context.commit("updateItems", response.data.records); context.commit("updateItems", response.data.records);
context.commit("updateItemTotalPage", response.data.total); context.commit("updateItemTotalPage", response.data.total);
if(!isEmpty(context.state.selectedMainTable)) { if (!isEmpty(context.state.selectedMainTable)) {
context.dispatch("getSelectedItem", context.state.selectedMainTable); context.dispatch("getSelectedItem", context.state.selectedMainTable);
} }
} }
@@ -910,7 +910,7 @@ export default {
context.commit("updateLoadingDetailRequest", true) context.commit("updateLoadingDetailRequest", true)
try { try {
payload.token = one_token(); payload.token = one_token();
let response = await api.getAPI('getDetailRequest',payload); let response = await api.getAPI('getDetailRequest', payload);
if (response.status != "OK") { if (response.status != "OK") {
context.commit("updateLoadingDetailRequest", false) context.commit("updateLoadingDetailRequest", false)
context.commit("updateErrMessage", response.message); context.commit("updateErrMessage", response.message);
@@ -929,7 +929,7 @@ export default {
context.commit("updateLoadingSave", true); context.commit("updateLoadingSave", true);
try { try {
payload.token = one_token(); payload.token = one_token();
let response = await api.getAPI('updatePurchaseRequest',payload); let response = await api.getAPI('updatePurchaseRequest', payload);
if (response.status != "OK") { if (response.status != "OK") {
context.commit("updateLoadingSave", false); context.commit("updateLoadingSave", false);
context.commit("updateErrMessage", response.message); context.commit("updateErrMessage", response.message);
@@ -940,7 +940,7 @@ export default {
context.commit("updateSnackbar", { context.commit("updateSnackbar", {
state: true, state: true,
type: 'success', type: 'success',
message: 'Purchase Request '+payload.PRNumber+' berhasil diupdate', message: 'Purchase Request ' + payload.PRNumber + ' berhasil diupdate',
}); });
console.log(context.state.snackbar); console.log(context.state.snackbar);
context.commit("updateSelectedItems", []); context.commit("updateSelectedItems", []);
@@ -958,7 +958,7 @@ export default {
}, },
async getRegionalBranchByUser(context) { async getRegionalBranchByUser(context) {
console.log("getRegionalBranchByUser"); console.log("getRegionalBranchByUser");
let response = await api.getAPI('getRegionalBranchByUser',{ token: one_token() }); let response = await api.getAPI('getRegionalBranchByUser', { token: one_token() });
if (response.status != "OK") { if (response.status != "OK") {
context.commit("updateErrMessage", response.message); context.commit("updateErrMessage", response.message);
context.commit("updateAlertError", true); context.commit("updateAlertError", true);
@@ -967,7 +967,7 @@ export default {
} }
}, },
async getItemCategory(context) { async getItemCategory(context) {
let response = await api.getAPI('getItemCategory',{ token: one_token() }); let response = await api.getAPI('getItemCategory', { token: one_token() });
if (response.status != "OK") { if (response.status != "OK") {
context.commit("updateErrMessage", response.message); context.commit("updateErrMessage", response.message);
context.commit("updateAlertError", true); context.commit("updateAlertError", true);
@@ -1002,6 +1002,11 @@ export default {
context.commit("updateLoadingSave", false); context.commit("updateLoadingSave", false);
context.commit("updateErrMessage", response.message); context.commit("updateErrMessage", response.message);
context.commit("updateAlertError", true); context.commit("updateAlertError", true);
context.commit("updateSnackbar", {
state: true,
type: 'error',
message: response.message,
});
} else { } else {
context.commit("updateLoadingSave", false); context.commit("updateLoadingSave", false);
context.commit("updateDialogConfirmHandover", false); context.commit("updateDialogConfirmHandover", false);

View File

@@ -211,29 +211,54 @@
v-if="props.item.prStatus == 'Draft'" v-if="props.item.prStatus == 'Draft'"
> >
<td <td
class="text-xs-center pa-2 pr-5" class="text-xs-center pa-2"
style="white-space: nowrap;"
v-bind:class="{ v-bind:class="{
'amber lighten-4': isSelected(props.item), 'amber lighten-4': isSelected(props.item),
}" }"
> >
<v-icon small @click="editRequest(props.item)" <v-btn
>edit</v-icon style="min-width: 25px; height: 25px; margin: 0;"
@click="editRequest(props.item)"
small title="Edit"
color="black"
> >
<v-icon small @click="deleteRequest(props.item)" <v-icon small color="white">edit</v-icon>
>delete</v-icon </v-btn>
<v-btn
style="min-width: 25px; height: 25px; margin: 0;"
@click="deleteRequest(props.item)"
small title="Hapus"
color="red"
> >
<v-icon small color="white">delete</v-icon>
</v-btn>
</td> </td>
</template> </template>
<template v-else> <template v-else>
<td <td
class="text-xs-center pa-2 pr-5" class="text-xs-center pa-2"
style="white-space: nowrap;"
v-bind:class="{ v-bind:class="{
'amber lighten-4': isSelected(props.item), 'amber lighten-4': isSelected(props.item),
}" }"
> >
<v-icon small @click="previewRequest(props.item)" <v-btn
>receipt</v-icon style="min-width: 25px; height: 25px; margin: 0;"
@click="previewRequest(props.item)"
small title="Preview Request"
color="blue"
> >
<v-icon small color="white">receipt</v-icon>
</v-btn>
<v-btn
style="min-width: 25px; height: 25px; margin: 0;"
@click="printout(props.item)"
small title="Cetak PDF"
color="primary"
>
<v-icon small color="white">print</v-icon>
</v-btn>
</td> </td>
</template> </template>
</template> </template>
@@ -254,6 +279,14 @@
<add-purchase-request-dialog></add-purchase-request-dialog> <add-purchase-request-dialog></add-purchase-request-dialog>
<add-request-detail-dialog></add-request-detail-dialog> <add-request-detail-dialog></add-request-detail-dialog>
<riwayat-dialog></riwayat-dialog> <riwayat-dialog></riwayat-dialog>
<one-dialog-print
:title="printtitle"
:width="printwidth"
:height="600"
:status="openprint"
:urlprint="urlprint"
@close-dialog-print="openprint = false"
></one-dialog-print>
<one-dialog-alert <one-dialog-alert
:status="dialogAlertDeleteRequest" :status="dialogAlertDeleteRequest"
@@ -300,9 +333,14 @@ module.exports = {
"riwayat-dialog": httpVueLoader("./dialogRiwayat.vue"), "riwayat-dialog": httpVueLoader("./dialogRiwayat.vue"),
"one-dialog-alert": httpVueLoader("../../common/oneDialogAlert.vue"), "one-dialog-alert": httpVueLoader("../../common/oneDialogAlert.vue"),
"one-dialog-error": httpVueLoader("../../common/oneDialogError.vue"), "one-dialog-error": httpVueLoader("../../common/oneDialogError.vue"),
"one-dialog-print": httpVueLoader("../../common/oneDialogPrintX.vue"),
}, },
data() { data() {
return { return {
urlprint: "",
printtitle: "",
printwidth: "60%",
openprint: false,
msgAlertDeleteRequest: "", msgAlertDeleteRequest: "",
dialogAlertDeleteRequest: false, dialogAlertDeleteRequest: false,
dialogAlertDeleteDetail: false, dialogAlertDeleteDetail: false,
@@ -344,7 +382,7 @@ module.exports = {
align: "center", align: "center",
sortable: false, sortable: false,
value: "action", value: "action",
width: "10%", width: "15%",
class: "blue lighten-3 white--text", class: "blue lighten-3 white--text",
}, },
], ],
@@ -788,6 +826,15 @@ module.exports = {
}); });
} }
}, },
printout(val) {
this.printwidth = "60%";
this.printtitle = "";
let user = one_user();
let username = user && user.M_StaffName ? user.M_StaffName : "";
let tm = Date.now();
this.urlprint = BASE_URL + "/one-api/report/rpt_stock_request/pdf?id=" + val.prId + "&username=" + username + "&tm=" + tm;
this.openprint = true;
},
}, },
}; };
</script> </script>

View File

@@ -83,7 +83,7 @@
BELUM KONFIRMASI BELUM KONFIRMASI
</v-chip> </v-chip>
</td> </td>
<td class="text-xs-center"> <td class="text-xs-center" style="white-space: nowrap;">
<div v-show="props.item.ReceiveOrderPoConfirmed === 'N'"> <div v-show="props.item.ReceiveOrderPoConfirmed === 'N'">
<v-tooltip bottom> <v-tooltip bottom>
<template v-slot:activator="{ on }"> <template v-slot:activator="{ on }">
@@ -183,6 +183,17 @@
</template> </template>
<span>Lihat detail</span> <span>Lihat detail</span>
</v-tooltip> </v-tooltip>
<v-tooltip bottom>
<template v-slot:activator="{ on }">
<v-btn
style="min-width: 30px; height: 30px; margin: 0;"
small @click="printout(props.item)" color="primary"
>
<v-icon small color="white" v-on="on">print</v-icon>
</v-btn>
</template>
<span>Cetak PDF</span>
</v-tooltip>
<span v-show="props.item.ReceiveOrderPoIsHandover === 'N'"> <span v-show="props.item.ReceiveOrderPoIsHandover === 'N'">
<v-tooltip bottom> <v-tooltip bottom>
<template v-slot:activator="{ on }"> <template v-slot:activator="{ on }">
@@ -219,6 +230,14 @@
<one-dialog-ro-handover></one-dialog-ro-handover> <one-dialog-ro-handover></one-dialog-ro-handover>
<one-dialog-form-document></one-dialog-form-document> <one-dialog-form-document></one-dialog-form-document>
<one-dialog-print-barcode></one-dialog-print-barcode> <one-dialog-print-barcode></one-dialog-print-barcode>
<one-dialog-print
:title="printtitle"
:width="printwidth"
:height="600"
:status="openprint"
:urlprint="urlprint"
@close-dialog-print="openprint = false"
></one-dialog-print>
<!-- snackbar --> <!-- snackbar -->
<v-snackbar <v-snackbar
@@ -244,12 +263,17 @@ module.exports = {
'one-dialog-ro-handover': httpVueLoader('./dialogHandOver.vue'), 'one-dialog-ro-handover': httpVueLoader('./dialogHandOver.vue'),
'one-dialog-form-document': httpVueLoader('./formDialogDocument.vue'), 'one-dialog-form-document': httpVueLoader('./formDialogDocument.vue'),
'one-dialog-print-barcode': httpVueLoader('./dialogPrintBarcode.vue'), 'one-dialog-print-barcode': httpVueLoader('./dialogPrintBarcode.vue'),
'one-dialog-print': httpVueLoader('../../common/oneDialogPrintX.vue'),
}, },
mounted() { mounted() {
this.$store.dispatch("ro/search") this.$store.dispatch("ro/search")
}, },
data() { data() {
return { return {
urlprint: "",
printtitle: "",
printwidth: "60%",
openprint: false,
menuStartDateFilter: false, menuStartDateFilter: false,
menuEndDateFilter: false, menuEndDateFilter: false,
headers: [ headers: [
@@ -283,7 +307,7 @@ module.exports = {
}, },
{ {
text: "AKSI", align: "center", sortable: false, value: "act", text: "AKSI", align: "center", sortable: false, value: "act",
width: "10%", class: "pa-2 text-center blue lighten-3 white--text", width: "15%", class: "pa-2 text-center blue lighten-3 white--text",
}, },
] ]
} }
@@ -411,6 +435,15 @@ module.exports = {
this.$store.commit("ro/update_indeterminatex", false); this.$store.commit("ro/update_indeterminatex", false);
this.$store.commit("ro/update_selected_barcode", []); this.$store.commit("ro/update_selected_barcode", []);
this.$store.dispatch("ro/getBarcodes"); this.$store.dispatch("ro/getBarcodes");
},
printout(val) {
this.printwidth = "60%";
this.printtitle = "";
let user = one_user();
let username = user && user.M_StaffName ? user.M_StaffName : "";
let tm = Date.now();
this.urlprint = BASE_URL + "/one-api/report/rpt_receive_item_po_inventaris/pdf?id=" + val.ReceiveOrderPoID + "&username=" + username + "&tm=" + tm;
this.openprint = true;
} }
}, },
watch: { watch: {

View File

@@ -83,7 +83,7 @@
BELUM KONFIRMASI BELUM KONFIRMASI
</v-chip> </v-chip>
</td> </td>
<td class="text-xs-center"> <td class="text-xs-center" style="white-space: nowrap;">
<div v-show="props.item.ReceiveOrderPoConfirmed === 'N'"> <div v-show="props.item.ReceiveOrderPoConfirmed === 'N'">
<v-tooltip bottom> <v-tooltip bottom>
<template v-slot:activator="{ on }"> <template v-slot:activator="{ on }">
@@ -131,6 +131,17 @@
</template> </template>
<span>Lihat detail</span> <span>Lihat detail</span>
</v-tooltip> </v-tooltip>
<v-tooltip bottom>
<template v-slot:activator="{ on }">
<v-btn
style="min-width: 30px; height: 30px; margin: 0;"
small @click="printout(props.item)" color="primary"
>
<v-icon small color="white" v-on="on">print</v-icon>
</v-btn>
</template>
<span>Cetak PDF</span>
</v-tooltip>
</div> </div>
</td> </td>
</tr> </tr>
@@ -151,6 +162,14 @@
<one-dialog-item-batch></one-dialog-item-batch> <one-dialog-item-batch></one-dialog-item-batch>
<one-dialog-ro-layout></one-dialog-ro-layout> <one-dialog-ro-layout></one-dialog-ro-layout>
<one-dialog-ro-view></one-dialog-ro-view> <one-dialog-ro-view></one-dialog-ro-view>
<one-dialog-print
:title="printtitle"
:width="printwidth"
:height="600"
:status="openprint"
:urlprint="urlprint"
@close-dialog-print="openprint = false"
></one-dialog-print>
<!-- snackbar --> <!-- snackbar -->
<v-snackbar <v-snackbar
@@ -173,12 +192,17 @@ module.exports = {
'one-dialog-item-batch': httpVueLoader('./dialogBatchItem.vue'), 'one-dialog-item-batch': httpVueLoader('./dialogBatchItem.vue'),
'one-dialog-ro-layout': httpVueLoader('./dialogRoLayout.vue'), 'one-dialog-ro-layout': httpVueLoader('./dialogRoLayout.vue'),
'one-dialog-ro-view': httpVueLoader('./dialogViewRO.vue'), 'one-dialog-ro-view': httpVueLoader('./dialogViewRO.vue'),
'one-dialog-print': httpVueLoader('../../common/oneDialogPrintX.vue'),
}, },
mounted() { mounted() {
this.$store.dispatch("ro/search") this.$store.dispatch("ro/search")
}, },
data() { data() {
return { return {
urlprint: "",
printtitle: "",
printwidth: "60%",
openprint: false,
menuStartDateFilter: false, menuStartDateFilter: false,
menuEndDateFilter: false, menuEndDateFilter: false,
headers: [ headers: [
@@ -212,7 +236,7 @@ module.exports = {
}, },
{ {
text: "AKSI", align: "center", sortable: false, value: "act", text: "AKSI", align: "center", sortable: false, value: "act",
width: "10%", class: "pa-2 text-center blue lighten-3 white--text", width: "15%", class: "pa-2 text-center blue lighten-3 white--text",
}, },
] ]
} }
@@ -293,6 +317,15 @@ module.exports = {
this.$store.dispatch("ro/getWarehouse"); this.$store.dispatch("ro/getWarehouse");
this.$store.dispatch("ro/getItemUpdate"); this.$store.dispatch("ro/getItemUpdate");
this.$store.commit("form/update_dialog_form_receive_item_edit", true); this.$store.commit("form/update_dialog_form_receive_item_edit", true);
},
printout(val) {
this.printwidth = "60%";
this.printtitle = "";
let user = one_user();
let username = user && user.M_StaffName ? user.M_StaffName : "";
let tm = Date.now();
this.urlprint = BASE_URL + "/one-api/report/rpt_receive_item_po/pdf?id=" + val.ReceiveOrderPoID + "&username=" + username + "&tm=" + tm;
this.openprint = true;
} }
}, },
watch: { watch: {

View File

@@ -92,7 +92,7 @@
</div> </div>
</td> </td>
<td class="text-xs-center pa-2"> <td class="text-xs-center pa-2" style="white-space: nowrap;">
<div v-show="props.item.ReceiveOrderPoConfirmed != 'Y'"> <div v-show="props.item.ReceiveOrderPoConfirmed != 'Y'">
<v-tooltip bottom pr-2> <v-tooltip bottom pr-2>
<template v-slot:activator="{ on }"> <template v-slot:activator="{ on }">
@@ -151,7 +151,7 @@
</template> </template>
<span>Detail Order</span> <span>Detail Order</span>
</v-tooltip> </v-tooltip>
<v-tooltip bottom> <v-tooltip bottom pr-2>
<template v-slot:activator="{ on }"> <template v-slot:activator="{ on }">
<v-btn <v-btn
color="green" dark @click="addAttachment(props.item)" color="green" dark @click="addAttachment(props.item)"
@@ -162,6 +162,17 @@
</template> </template>
<span>View Nota</span> <span>View Nota</span>
</v-tooltip> </v-tooltip>
<v-tooltip bottom>
<template v-slot:activator="{ on }">
<v-btn
color="primary" dark @click="printout(props.item)"
style="min-width: 40px; margin: 0;" small v-on="on"
>
<v-icon small>print</v-icon>
</v-btn>
</template>
<span>Cetak PDF</span>
</v-tooltip>
</div> </div>
</td> </td>
</tr> </tr>
@@ -185,6 +196,14 @@
<dialog-delete-ro></dialog-delete-ro> <dialog-delete-ro></dialog-delete-ro>
<dialog-confirm-ro></dialog-confirm-ro> <dialog-confirm-ro></dialog-confirm-ro>
<dialog-edit-ro></dialog-edit-ro> <dialog-edit-ro></dialog-edit-ro>
<one-dialog-print
:title="printtitle"
:width="printwidth"
:height="600"
:status="openprint"
:urlprint="urlprint"
@close-dialog-print="openprint = false"
></one-dialog-print>
</div> </div>
</template> </template>
@@ -198,6 +217,7 @@ module.exports = {
'dialog-delete-ro': httpVueLoader('./dialog-delete-ro.vue'), 'dialog-delete-ro': httpVueLoader('./dialog-delete-ro.vue'),
'dialog-confirm-ro': httpVueLoader('./dialog-confirm-ro.vue'), 'dialog-confirm-ro': httpVueLoader('./dialog-confirm-ro.vue'),
'dialog-edit-ro': httpVueLoader('./dialog-edit-ro.vue'), 'dialog-edit-ro': httpVueLoader('./dialog-edit-ro.vue'),
'one-dialog-print': httpVueLoader('../../common/oneDialogPrintX.vue'),
}, },
mounted() { mounted() {
this.$store.dispatch('roservice/lookupCabang'); this.$store.dispatch('roservice/lookupCabang');
@@ -207,6 +227,10 @@ module.exports = {
}, },
data() { data() {
return { return {
urlprint: "",
printtitle: "",
printwidth: "60%",
openprint: false,
menuStartdateFilter: false, menuStartdateFilter: false,
menuEnddateFilter: false, menuEnddateFilter: false,
headers: [ headers: [
@@ -315,6 +339,15 @@ module.exports = {
this.$store.commit("roservice/update_selected_rojasa", item) this.$store.commit("roservice/update_selected_rojasa", item)
this.$store.commit("roservice/update_dialog_deletero", true) this.$store.commit("roservice/update_dialog_deletero", true)
} }
},
printout(val) {
this.printwidth = "60%";
this.printtitle = "";
let user = one_user();
let username = user && user.M_StaffName ? user.M_StaffName : "";
let tm = Date.now();
this.urlprint = BASE_URL + "/one-api/report/rpt_receive_order_jasa/pdf?id=" + val.ReceiveOrderPoID + "&username=" + username + "&tm=" + tm;
this.openprint = true;
} }
}, },
watch: { watch: {

View File

@@ -0,0 +1,88 @@
const URL = "/one-api/mockup/receive-item-po/ReceiveItemPOAsset";
async function request(endpoint, params) {
try {
const resp = await axios.post(URL + endpoint, params);
if (resp.status !== 200) {
throw new Error(resp.statusText);
}
return resp.data;
} catch (e) {
return {
status: "ERR",
message: e.message
}
}
}
export async function getListSupplier(params) {
return request("/getListSupplier", params);
}
export async function getListCabang(params) {
return request("/getListCabang", params);
}
export async function getListGudang(params) {
return request("/getListGudang", params);
}
export async function getListStaff(params) {
return request("/getListStaff", params);
}
export async function searchOrderAsset(params) {
return request("/searchOrderAsset", params);
}
export async function getListingROAsset(params) {
return request("/getListingROAsset", params);
}
export async function generatePOItemReceive(params) {
return request("/generatePOItemReceive", params);
}
export async function createReceiveOrder(params) {
return request("/createReceiveOrder", params);
}
export async function editReceiveOrder(params) {
return request("/editReceivedOrder", params);
}
export async function deleteReceiveOrder(params) {
return request("/deleteReceiveOrder", params);
}
export async function confirmReceiveOrder(params) {
return request("/confirmReceiveOrder", params);
}
export async function uploadAttachment(params) {
return request("/uploadAttachment", params)
}
export async function getListAttachment(params) {
return request("/getListAttachment", params)
}
export async function getDetailDataROAsset(params) {
return request("/getDetailDataROAsset", params)
}
export async function getRuangan(params) {
return request("/getRuangan", params)
}
export async function getAssetBelumSerahTerima(params) {
return request("/getAssetBelumSerahTerima", params)
}
export async function saveHandover(params) {
return request("/saveHandover", params)
}
export async function getBarcodes(params) {
return request("/getBarcodes", params)
}

View File

@@ -0,0 +1,212 @@
<template>
<div>
<v-dialog v-model="dialog_attachment" persistent max-width="60vw">
<v-card>
<v-card-title class="headline grey lighten-2" primary-title>
UPLOAD BUKTI TERIMA ASET
</v-card-title>
<v-card-text>
<v-layout row wrap>
<v-flex xs12 class="mb-2 pa-2" style="border: 1px solid black;">
<input type="file" id="files" ref="files" multiple accept="image/*"
v-on:change="addAttachment($event)">
</v-flex>
<v-flex v-for="(nota) in preview_attachment" xs4 class="pa-2"
:key="nota.attach_id || nota.img_url">
<div style="position: relative; padding-bottom: 35px;">
<v-img :src="makeImageURL(nota)" aspect-ratio="1" contain class="grey lighten-2"
@click="fullview(nota, -1)"></v-img>
</div>
</v-flex>
<v-flex v-for="(url, index) in attachViews" xs4 class="pa-2" :key="index">
<div style="position: relative; padding-bottom: 35px;">
<v-img :src="url" aspect-ratio="1" contain class="grey lighten-2"
@click="fullview(url, index)"></v-img>
<v-icon color="red" class="close-button" @click="removeAttachment(index)">close</v-icon>
</div>
</v-flex>
</v-layout>
</v-card-text>
<v-card-actions>
<v-spacer></v-spacer>
<v-btn @click="BatalAddAttachment()" color="error" class="white--text">Batal</v-btn>
<v-btn v-if="selected_roasset.ReceiveOrderPoConfirmed != 'Y'" @click="SimpanAttachment()"
color="primary" class="white--text">Simpan</v-btn>
</v-card-actions>
</v-card>
</v-dialog>
<v-dialog v-model="dialog_fullview" persistent max-width="50vw">
<v-card>
<v-card-title class="headline grey lighten-2" primary-title>
{{ viewtitle }}
<v-spacer></v-spacer>
<v-btn color="red" fab small outline @click="dialog_fullview = false">
<v-icon color="red">close</v-icon>
</v-btn>
</v-card-title>
<v-card-text style="max-height: 80vh; overflow-y: auto;">
<div class="pa-2">
<v-img :src="viewurl" contain class="grey lighten-2"></v-img>
</div>
</v-card-text>
<v-card-actions>
<v-spacer></v-spacer>
<v-btn class="mr-2" color="red" flat outline @click="dialog_fullview = false">
Tutup
</v-btn>
</v-card-actions>
</v-card>
</v-dialog>
</div>
</template>
<style>
.close-button {
position: absolute;
top: 5px;
right: 5px;
z-index: 1;
cursor: pointer;
}
</style>
<script>
module.exports = {
data() {
return {
attachViews: [],
attachFiles: [],
dialog_fullview: false,
viewtitle: "",
viewurl: ""
}
},
computed: {
dialog_attachment: {
get() {
return this.$store.state.roasset.dialog_attachment
},
set(val) {
this.$store.commit("roasset/update_dialog_attachment", val)
}
},
selected_roasset: {
get() {
return this.$store.state.roasset.selected_roasset
},
set(val) {
this.$store.commit("roasset/update_selected_roasset", val)
}
},
preview_attachment: {
get() {
return this.$store.state.roasset.preview_attachment
},
set(val) {
this.$store.commit("roasset/update_preview_attachment", val)
}
},
loading_process: {
get() {
return this.$store.state.roasset.loading_process
},
set(val) {
this.$store.commit("roasset/update_loading_process", val)
}
}
},
methods: {
addAttachment(event) {
const files = event.target.files;
if (files.length == 0) {
return;
}
for (let index = 0; index < files.length; index++) {
const file = files[index];
const url = URL.createObjectURL(file);
this.attachFiles.push(file);
this.attachViews.push(url);
}
event.target.value = null;
},
fullview(url, index) {
if (index < 0) {
this.viewtitle = url.img_url;
this.viewurl = this.makeImageURL(url);
} else {
this.viewtitle = this.attachFiles[index].name;
this.viewurl = url;
}
this.dialog_fullview = true;
},
makeImageURL(nota) {
if (nota.url) {
return nota.url;
}
if (nota.src) {
return nota.src;
}
const year = new Date(nota.created).getFullYear();
const baseURL = BASE_URL + `/one-media/order-asset/${year}/`;
return baseURL + nota.img_url;
},
removeAttachment(index) {
URL.revokeObjectURL(this.attachViews[index]);
this.attachFiles.splice(index, 1);
this.attachViews.splice(index, 1);
},
clearAttachment() {
this.attachViews.forEach(function (url) {
URL.revokeObjectURL(url);
});
this.attachFiles = [];
this.attachViews = [];
},
BatalAddAttachment() {
this.clearAttachment();
this.preview_attachment = [];
this.dialog_attachment = false;
},
SimpanAttachment() {
if (!this.loading_process) {
let formdata = new FormData();
let listfiles = this.attachFiles;
let received = this.selected_roasset;
for (let index = 0; index < listfiles.length; index++) {
const file = listfiles[index];
formdata.append('files['+index+']', file);
}
formdata.append('token', one_token());
formdata.append('ronumber', received.ReceiveOrderPoNumber);
formdata.append('contractID', received.PurchaseOrderAssetContractID);
formdata.append('roID', received.ReceiveOrderPoID);
this.$store.dispatch("roasset/uploadAttachment", formdata);
} else {
let snac = { color: 'warning', msg: 'proses sedang berjalan', state: true };
this.$store.commit("roasset/update_snackbar", snac);
}
}
},
watch: {
dialog_fullview(val) {
if (!val) {
this.viewurl = "";
this.viewtitle = "";
}
},
dialog_attachment(val) {
if (val) {
this.clearAttachment();
}
}
}
}
</script>

View File

@@ -0,0 +1,89 @@
<template>
<v-dialog v-model="dialog_confirm" persistent width="40vw">
<v-card>
<v-card-title class="headline grey lighten-2">KONFIRMASI RECEIVE ORDER ASSET</v-card-title>
<v-card-text>
<v-layout row wrap>
<v-flex xs3 class="pr-2"><strong>Tanggal</strong></v-flex>
<v-flex xs9>: {{ selected_roasset.ReceiveOrderPoIDate }}</v-flex>
<v-flex xs3 class="pr-2"><strong>Nomor</strong></v-flex>
<v-flex xs9>: {{ selected_roasset.ReceiveOrderPoNumber }}</v-flex>
<v-flex xs3 class="pr-2"><strong>Nomor Referensi</strong></v-flex>
<v-flex xs9>: {{ selected_roasset.ReceiveOrderPoRefNumber }}</v-flex>
<v-flex xs3 class="pr-2"><strong>Supplier</strong></v-flex>
<v-flex xs9>: {{ selected_roasset.SupplierName }}</v-flex>
<v-flex xs3 class="pr-2"><strong>Catatan</strong></v-flex>
<v-flex xs9>: {{ selected_roasset.ReceiveOrderPoNote }}</v-flex>
</v-layout>
</v-card-text>
<v-card-actions>
<v-spacer></v-spacer>
<v-btn @click="batal()" color="error" class="white--text">Batal</v-btn>
<v-btn @click="confirmOrder()" color="primary" class="white--text">Konfirmasi</v-btn>
</v-card-actions>
</v-card>
</v-dialog>
</template>
<script>
module.exports = {
data() {
return {
}
},
computed: {
dialog_confirm: {
get() {
return this.$store.state.roasset.dialog_confirm;
},
set(val) {
this.$store.commit("roasset/update_dialog_confirm", val);
}
},
selected_roasset: {
get() {
return this.$store.state.roasset.selected_roasset;
},
set(val) {
this.$store.commit("roasset/update_selected_roasset", val);
}
},
loading_process() {
return this.$store.state.roasset.loading_process;
},
preview_attachment() {
return this.$store.state.roasset.preview_attachment
}
},
methods: {
batal() {
this.selected_roasset = {}
this.dialog_confirm = false
},
confirmOrder() {
if (this.preview_attachment.length < 1) {
const msg = "Belum upload bukti terima";
const snac = { color: 'error', msg: msg, state: false };
this.$store.commit("roasset/update_snackbar", snac);
return;
}
if (!this.loading_process) {
const received = this.selected_roasset;
this.$store.dispatch("roasset/confirmReceiveOrder", received.ReceiveOrderPoID);
} else {
const msg = "Masih terdapat proses lain yang berjalan";
const snac = { color: 'error', msg: msg, state: false };
this.$store.commit("roasset/update_snackbar", snac);
}
}
},
watch: {}
}
</script>

View File

@@ -0,0 +1,79 @@
<template>
<v-dialog v-model="dialog_delete" persistent width="40vw">
<v-card>
<v-card-title class="headline grey lighten-2">DELETE RECEIVE ORDER ASSET</v-card-title>
<v-card-text>
<v-layout row wrap>
<v-flex xs3 class="pr-2"><strong>Tanggal</strong></v-flex>
<v-flex xs9>: {{ selected_roasset.ReceiveOrderPoIDate }}</v-flex>
<v-flex xs3 class="pr-2"><strong>Nomor</strong></v-flex>
<v-flex xs9>: {{ selected_roasset.ReceiveOrderPoNumber }}</v-flex>
<v-flex xs3 class="pr-2"><strong>Nomor Referensi</strong></v-flex>
<v-flex xs9>: {{ selected_roasset.ReceiveOrderPoRefNumber }}</v-flex>
<v-flex xs3 class="pr-2"><strong>Supplier</strong></v-flex>
<v-flex xs9>: {{ selected_roasset.SupplierName }}</v-flex>
<v-flex xs3 class="pr-2"><strong>Catatan</strong></v-flex>
<v-flex xs9>: {{ selected_roasset.ReceiveOrderPoNote }}</v-flex>
</v-layout>
</v-card-text>
<v-card-actions>
<v-spacer></v-spacer>
<v-btn @click="batalDelete()" color="error" class="white--text">Batal</v-btn>
<v-btn @click="confirmDelete()" color="primary" class="white--text">Hapus</v-btn>
</v-card-actions>
</v-card>
</v-dialog>
</template>
<script>
module.exports = {
data() {
return {
}
},
computed: {
dialog_delete: {
get() {
return this.$store.state.roasset.dialog_delete;
},
set(val) {
this.$store.commit("roasset/update_dialog_delete", val);
}
},
selected_roasset: {
get() {
return this.$store.state.roasset.selected_roasset;
},
set(val) {
this.$store.commit("roasset/update_selected_roasset", val);
}
},
loading_process() {
return this.$store.state.roasset.loading_process;
}
},
methods: {
batalDelete() {
this.selected_roasset = {}
this.dialog_delete = false
},
confirmDelete() {
if (!this.loading_process) {
const received = this.selected_roasset;
this.$store.dispatch("roasset/deleteReceiveAsset", received.ReceiveOrderPoID);
} else {
const msg = "Masih terdapat proses lain yang berjalan";
const snac = { color: 'error', msg: msg, state: false };
this.$store.commit("roasset/update_snackbar", snac);
}
}
},
watch: {}
}
</script>

View File

@@ -0,0 +1,160 @@
<template>
<v-dialog v-model="dialog_handover_asset" persistent width="50vw">
<v-card>
<v-card-title class="headline grey lighten-2" primary-title>
SERAH TERIMA BARANG ASSET
</v-card-title>
<v-card-text>
<p>Apakah Anda yakin ingin melakukan serah terima barang inventaris kepada user pemohon</p>
<v-form ref="formhandover" lazy-validation v-model="valid_formhandover">
<v-data-table :headers="headers" :items="list_item_not_handed" hide-actions class="elevation-1">
<template v-slot:items="props">
<tr>
<td class="text-xs-center">
<v-checkbox v-if="props.item.isHandoverDone == 'N'" v-model="props.item.checked"
hide-details @change="onChangeCheckbox(props.item)">
</v-checkbox>
</td>
<td class="text-xs-center">{{ props.item.M_ItemDesc }}</td>
<td class="text-xs-center">{{ props.item.originalQty }}</td>
<td class="text-xs-center">
<v-text-field v-if="props.item.checked" v-model="props.item.serahQty" type="number"
solo :rules="qtyRules(props.item.sisaQty)"></v-text-field>
<div v-else>
{{ props.item.serahQty }}
</div>
</td>
</tr>
</template>
</v-data-table>
<v-layout row mt-2>
<v-flex xs6 pr-1>
<v-autocomplete v-model="selected_ruangan" :items="list_lokasi" label="Lokasi Penerima*"
:rules="ruang_rules" outline item-value="M_RuanganID"
item-text="M_RuanganName"></v-autocomplete>
</v-flex>
<v-flex xs6 pl-1>
<v-autocomplete label="Staff Penerima*" outline :rules="rules_staff"
v-model="selected_staff" :items="list_staff" item-value="M_UserID"
item-text="M_UserUsername"></v-autocomplete>
</v-flex>
</v-layout>
</v-form>
</v-card-text>
<v-card-actions>
<v-spacer></v-spacer>
<v-btn color="red" flat outline @click="closeHandOver()">Batal</v-btn>
<v-btn color="green" flat outline @click="simpanHandOver()">Ya, Serahkan Barang</v-btn>
</v-card-actions>
</v-card>
</v-dialog>
</template>
<script>
module.exports = {
data() {
return {
selected_ruangan: 0,
selected_staff: 0,
valid_formhandover: true,
ruang_rules: [v => (v && Object.keys(v).length > 0) || 'Lokasi ruangan harus diisi'],
rules_staff: [v => (v && Object.keys(v).length > 0) || 'Staff harus diisi'],
headers: [
{
text: "", align: "center", sortable: false, value: "checked",
width: "10%", class: "pa-2 blue lighten-3 white--text",
},
{
text: "ITEM", align: "center", sortable: false, value: "itemname",
width: "50%", class: "pa-2 blue lighten-3 white--text",
},
{
text: "QTY DITERIMA", align: "center", sortable: false, value: "qtyitem",
width: "20%", class: "pa-2 blue lighten-3 white--text",
},
{
text: "QTY HANDOVER", align: "center", sortable: false, value: "qtysend",
width: "20%", class: "pa-2 blue lighten-3 white--text",
},
],
}
},
computed: {
dialog_handover_asset: {
get() {
return this.$store.state.roasset.dialog_handover_asset;
},
set(val) {
this.$store.commit("roasset/update_dialog_handover_asset", val)
}
},
selected_roasset: {
get() {
return this.$store.state.roasset.selected_roasset
},
set(val) {
this.$store.commit("roasset/update_selected_roasset", val)
}
},
list_item_not_handed: {
get() {
return this.$store.state.roasset.list_item_not_handed;
},
set(val) {
this.$store.commit("roasset/update_list_item_not_handed", val)
}
},
list_staff() {
return this.$store.state.orderAsset.list_staff;
},
list_lokasi() {
return this.$store.state.roasset.list_lokasi;
}
},
methods: {
onChangeCheckbox(item) {
if (item.checked) {
item.serahQty = item.sisaQty
} else {
item.serahQty = item.originalQty - item.sisaQty
}
},
qtyRules(originalQty) {
return [
v => Number(v) > 0 || "Jumlah harus diatas 0",
v => Number(v) <= Number(originalQty) || "Jumlah melebihi inventaris yang diterima"
];
},
closeHandOver() {
this.selected_roasset = {};
this.selected_staff = 0;
this.selected_ruangan = 0;
this.$refs.formhandover.resetValidation();
this.dialog_handover_asset = false;
},
async simpanHandOver() {
if (this.$refs.formhandover.validate()) {
let checked = this.list_item_not_handed.filter((ele) => ele.checked);
if (checked.length < 1) {
const snac = { color: 'error', msg: 'tidak ada item yg diterima', state: true };
this.$store.commit("roasset/update_snackbar", snac);
return;
}
let param = {
staffID: this.selected_staff,
receiveOrderPoID: this.selected_roasset.ReceiveOrderPoID,
ruanganID: this.selected_ruangan,
item: checked
}
await this.$store.dispatch("roasset/saveHandoverAsset", param);
this.selected_staff = 0;
this.selected_ruangan = 0;
this.$refs.formhandover.resetValidation();
}
}
},
watch: {}
}
</script>

View File

@@ -0,0 +1,185 @@
<template>
<v-dialog v-model="dialog_inspeksi" persistent width="40vw">
<v-card>
<v-card-title class="headline grey lighten-2" primary-title>
FORM INSPEKSI ASET {{ selected_item_received.M_ItemDesc }}
</v-card-title>
<v-card-text>
<v-layout row>
<v-flex xs6 pr-1>
<v-text-field label="Jumlah Pesan" type="number" min="0" hide-details
v-model="form_inspeksi.qty_po" outline step="1"></v-text-field>
</v-flex>
<v-flex xs6 pl-1>
<v-text-field label="Jumlah Actual" type="number" min="0" hide-details
v-model="form_inspeksi.qty_ro" outline step="1"></v-text-field>
</v-flex>
</v-layout>
<v-layout row mt-2>
<v-flex xs6 pr-1>
<v-menu v-model="menuDatePo" lazy offset-y max-width="290px" full-width
transition="scale-transition" min-width="290px" :nudge-right="40"
:close-on-content-click="false">
<template v-slot:activator="{ on }">
<v-text-field :value="form_inspeksi.date_po" v-on="on" readonly
label="Tanggal Terima Pesan" outline hide-details></v-text-field>
</template>
<v-date-picker v-model="form_inspeksi.date_po" no-title
@input="menuDatePo = false"></v-date-picker>
</v-menu>
</v-flex>
<v-flex xs6 pl-1>
<v-menu v-model="menuDateRo" lazy offset-y max-width="290px" full-width
transition="scale-transition" min-width="290px" :nudge-right="40"
:close-on-content-click="false">
<template v-slot:activator="{ on }">
<v-text-field :value="form_inspeksi.date_ro" v-on="on" readonly
label="Tanggal Terima Actual" outline hide-details></v-text-field>
</template>
<v-date-picker v-model="form_inspeksi.date_ro" no-title
@input="menuDateRo = false"></v-date-picker>
</v-menu>
</v-flex>
</v-layout>
<v-layout row mt-2 wrap>
<v-flex xs12>
<v-radio-group v-model="form_inspeksi.condt_kemasan" label="Kondisi Kemasan" row hide-details>
<v-radio label="Baik" value="1"></v-radio>
<v-radio label="Tidak Baik" value="2"></v-radio>
</v-radio-group>
<v-text-field v-if="form_inspeksi.condt_kemasan == '2'" class="mt-2" label="Catatan Kemasan"
outline hide-details v-model="form_inspeksi.catatan_kemasan"></v-text-field>
</v-flex>
<v-flex xs12 mt-2>
<v-radio-group v-model="form_inspeksi.condt_pengiriman" label="Kondisi Pengiriman" row
hide-details>
<v-radio label="Sesuai" value="1"></v-radio>
<v-radio label="Tidak Sesuai" value="2"></v-radio>
</v-radio-group>
<v-text-field v-if="form_inspeksi.condt_pengiriman == '2'" class="mt-2" outline
label="Catatan Pengiriman" hide-details
v-model="form_inspeksi.catatan_kirim"></v-text-field>
</v-flex>
<v-flex xs12 mt-2>
<v-radio-group v-model="form_inspeksi.summary" row label="Kesimpulan" hide-details>
<v-radio label="Diterima" value="accept"></v-radio>
<v-radio label="Ditolak" value="reject"></v-radio>
<v-radio label="Diterima dengan Catatan" value="acceptnote"></v-radio>
</v-radio-group>
</v-flex>
<v-flex xs12 mt-2>
<v-textarea v-if="
form_inspeksi.summary == 'reject' ||
form_inspeksi.summary == 'acceptnote'
" v-model="form_inspeksi.catatan" outline auto-grow rows="1" label="Catatan"
hide-details></v-textarea>
</v-flex>
</v-layout>
<v-layout row mt-2>
<v-flex xs6 pr-1>
<v-autocomplete label="Staff Penerima" outline hide-details v-model="form_inspeksi.pemeriksa"
:items="list_staff" item-text="M_UserUsername" item-value="M_UserID"></v-autocomplete>
</v-flex>
<v-flex xs6 pl-1>
<v-text-field label="Petugas Pengirim" outline hide-details
v-model="form_inspeksi.pengirim"></v-text-field>
</v-flex>
</v-layout>
</v-card-text>
<v-card-actions>
<v-spacer></v-spacer>
<v-btn color="red" flat outline @click="closeInspeksi()">Tutup</v-btn>
<v-btn color="green" flat outline @click="simpanInspeksi()">Simpan</v-btn>
</v-card-actions>
</v-card>
</v-dialog>
</template>
<script>
module.exports = {
data() {
return {
menuDatePo: false,
menuDateRo: false
};
},
computed: {
dialog_inspeksi: {
get() {
return this.$store.state.orderAsset.dialog_inspeksi;
},
set(val) {
this.$store.commit("orderAsset/update_dialog_inspeksi", val);
}
},
form_inspeksi: {
get() {
return this.$store.state.orderAsset.form_inspeksi;
},
set(val) {
this.$store.commit("orderAsset/update_form_inspeksi", val);
}
},
selected_item_received: {
get() {
return this.$store.state.orderAsset.selected_item_received;
},
set(val) {
this.$store.commit("orderAsset/update_selected_item_received", val);
}
},
order_received: {
get() {
return this.$store.state.orderAsset.order_received;
},
set(val) {
this.$store.commit("orderAsset/update_order_received", val);
}
},
list_staff() {
return this.$store.state.orderAsset.list_staff;
}
},
methods: {
defaultFormInspeksi() {
return {
qty_po: 0,
qty_ro: 0,
date_po: moment(new Date()).format("YYYY-MM-DD"),
date_ro: moment(new Date()).format("YYYY-MM-DD"),
condt_kemasan: "",
catatan_kemasan: "",
condt_pengiriman: "",
catatan_kirim: "",
summary: "",
catatan: "",
pemeriksa: "",
pengirim: ""
};
},
closeInspeksi() {
this.form_inspeksi = this.defaultFormInspeksi();
this.selected_item_received = {};
this.dialog_inspeksi = false;
},
simpanInspeksi() {
const dataInspeksi = JSON.parse(JSON.stringify(this.form_inspeksi));
const selectedItem = JSON.parse(JSON.stringify(this.selected_item_received));
const listOrder = JSON.parse(JSON.stringify(this.order_received));
const idxToUpdate = listOrder.findIndex((obj) => obj.PODetailID == selectedItem.PODetailID);
if (idxToUpdate != -1) {
listOrder[idxToUpdate].inspeksi = dataInspeksi;
}
this.order_received = listOrder;
this.closeInspeksi();
}
}
};
</script>

View File

@@ -0,0 +1,233 @@
<template>
<v-dialog v-model="dialog_pick_contract" persistent width="60vw">
<v-card class="style-limit-heightcard">
<v-card-title class="headline grey lighten-2">PILIH ORDER ASET</v-card-title>
<v-card-text class="style-limit-heightcontent">
<v-layout row wrap>
<v-flex xs12>
<v-autocomplete
v-model="temp_selected" :loading="loading" hide-details
:items="list_item_order" hide-no-data outline
:search-input.sync="searchkey" cache-items clearable
label="Cari" placeholder="Nama Kontrak, nomor PO"
:item-text="formatOrderLabel" return-object
></v-autocomplete>
</v-flex>
<v-flex xs12 mt-2>
<v-data-table :headers="headers" class="elevation-1" hide-actions
:items="temp_selected ? [temp_selected] : []"
:expand="expand" item-key="PurchaseOrderID">
<template v-slot:items="props">
<tr @click="props.expanded = !props.expanded">
<td class="text-xs-center pa-2">
<v-icon>{{ props.expanded
? "keyboard_arrow_down"
: "keyboard_arrow_right"
}}</v-icon>
</td>
<td class="text-xs-start pa-2">
{{ props.item.PurchaseOrderNumber }}
</td>
<td class="text-xs-start pa-2">
{{ props.item.PurchaseOrderAssetContractDate }}
</td>
<td class="text-xs-start pa-2">
{{ props.item.PurchaseOrderAssetContractName }}
</td>
<td class="text-xs-start pa-2">
{{ props.item.SupplierCode }} <br>
{{ props.item.SupplierName }}
</td>
<td class="text-xs-start pa-2">
{{ props.item.PurchaseOrderNote }}
</td>
</tr>
</template>
<template v-slot:expand="props">
<v-card flat>
<v-card-text>
<v-data-table
:headers="b_headers" class="elevation-0"
:items="props.item.detail" hide-actions
>
<template v-slot:items="expnd">
<tr>
<td class="text-xs-center pa-2">
{{ expnd.item.M_ItemCode }}
</td>
<td class="text-xs-center pa-2">
{{ expnd.item.M_ItemDesc }}
</td>
<td class="text-xs-center pa-2">
{{ expnd.item.ItemUnitName }}
</td>
<td class="text-xs-center pa-2">
{{ expnd.item.qty }}
</td>
</tr>
</template>
</v-data-table>
</v-card-text>
</v-card>
</template>
</v-data-table>
</v-flex>
</v-layout>
</v-card-text>
<v-card-actions>
<v-spacer></v-spacer>
<v-btn @click="batalItemOrder()" color="error" class="white--text">Batal</v-btn>
<v-btn @click="simpanItemOrder()" color="primary" class="white--text">Simpan</v-btn>
</v-card-actions>
</v-card>
</v-dialog>
</template>
<style scoped>
.style-limit-heightcard {
max-height: 60vh;
display: flex;
flex-direction: column;
}
.style-limit-heightcontent {
overflow-y: auto;
flex: 1 1 auto;
min-height: 0;
}
</style>
<script>
module.exports = {
data() {
return {
searchkey: "",
loading: false,
expand: false,
temp_selected: null,
headers: [
{
text: " ", align: "center", sortable: false, value: "check",
width: "5%", class: "pa-1 blue lighten-3 white--text",
},
{
text: "NO PURCHASE ORDER", align: "center", sortable: false, value: "po",
width: "25%", class: "pa-1 blue lighten-3 white--text",
},
{
text: "TANGGAL KONTRAK", align: "center", sortable: false, value: "date",
width: "15%", class: "pa-1 blue lighten-3 white--text",
},
{
text: "NAMA KONTRAK", align: "center", sortable: false, value: "date",
width: "15%", class: "pa-1 blue lighten-3 white--text",
},
{
text: "SUPPLIER", align: "center", sortable: false, value: "unit",
width: "20%", class: "pa-1 blue lighten-3 white--text",
},
{
text: "CATATAN", align: "center", sortable: false, value: "qty",
width: "20%", class: "pa-1 blue lighten-3 white--text",
}
],
b_headers: [
{
text: "ITEM CODE", align: "center", sortable: false,
value: "code", width: "25%", class: "pa-1 blue lighten-4 black--text",
},
{
text: "ITEM", align: "center", sortable: false,
value: "item", width: "25%", class: "pa-1 blue lighten-4 black--text",
},
{
text: "UNIT", align: "center", sortable: false,
value: "unit", width: "25%", class: "pa-1 blue lighten-4 black--text",
},
{
text: "QTY", align: "center", sortable: false,
value: "qty", width: "25%", class: "pa-1 blue lighten-4 black--text",
},
]
}
},
computed: {
dialog_pick_contract: {
get() {
return this.$store.state.orderAsset.dialog_pick_contract;
},
set(val) {
this.$store.commit("orderAsset/update_dialog_pick_contract", val);
}
},
list_item_order: {
get() {
return this.$store.state.orderAsset.list_item_order;
},
set(val) {
this.$store.commit("orderAsset/update_list_item_order", val);
}
},
form_receive: {
get() {
return this.$store.state.orderAsset.form_receive
},
set(val) {
this.$store.commit("orderAsset/update_form_receive", val)
}
},
order_received: {
get() {
return this.$store.state.orderAsset.order_received
},
set(val) {
this.$store.commit("orderAsset/update_order_received", val)
}
},
},
methods: {
formatOrderLabel(item) {
if (!item) return "";
return `${item.PurchaseOrderNumber} - ${item.PurchaseOrderAssetContractName}`;
},
cariOrderAsset(newval) {
this.loading = true;
setTimeout(() => {
this.$store.dispatch("orderAsset/searchOrderAsset", newval);
this.loading = false;
}, 500);
},
batalItemOrder() {
this.temp_selected = null;
this.dialog_pick_contract = false;
},
simpanItemOrder() {
let form = JSON.parse(JSON.stringify(this.form_receive));
const receivedOrder = JSON.parse(JSON.stringify(this.temp_selected));
form.ponumber = receivedOrder.PurchaseOrderNumber;
form.shipping = receivedOrder.PurchaseOrderShippingCost;
form.shippingIsPaid = receivedOrder.PurchaseOrderShippingCostStatus
this.form_receive = form;
this.order_received = receivedOrder.detail;
this.temp_selected = null;
this.dialog_pick_contract = false;
}
},
watch: {
searchkey(newval, oldval) {
if (newval == oldval) return;
if (!newval) {
this.cariOrderAsset("");
return;
}
if (newval.length < 1) return;
this.cariOrderAsset(newval);
}
}
}
</script>

View File

@@ -0,0 +1,328 @@
<template>
<v-dialog v-model="dialog_receive_aset" persistent width="70vw">
<v-card class="style-limit-heightcard">
<v-card-title class="headline grey lighten-2">FORM TERIMA ASET</v-card-title>
<v-card-text class="style-limit-heightcontent">
<v-layout row wrap>
<v-flex xs4 pa-1>
<v-menu offset-y lazy min-width="290px" transition="scale-transition" max-width="290px"
v-model="menuROdate" full-width :nudge-right="40" :close-on-content-click="false">
<template v-slot:activator="{ on }">
<v-text-field label="Tanggal RO" hide-details readonly v-on="on" outline
v-model="formattedRODate"></v-text-field>
</template>
<v-date-picker no-title @input="menuROdate = false" :readonly="readonly_mode"
v-model="form_receive.date"></v-date-picker>
</v-menu>
</v-flex>
<v-flex xs4 pa-1>
<v-autocomplete :items="list_supplier" hide-details outline label="Vendor"
v-model="form_receive.supplier" item-text="SupplierName" :readonly="readonly_mode"
item-value="SupplierID"></v-autocomplete>
</v-flex>
<v-flex xs4 pa-1>
<v-text-field hide-details outline placeholder="Nomor Delivery / Supplier Invoice"
v-model="form_receive.reference" label="Referensi" :readonly="readonly_mode"></v-text-field>
</v-flex>
</v-layout>
<v-layout row wrap>
<v-flex xs4 pa-1>
<v-text-field hide-details outline label="No PO" placeholder="nomor po"
v-model="form_receive.ponumber" readonly></v-text-field>
</v-flex>
<v-flex xs2 pa-1>
<v-autocomplete :items="list_cabang" hide-details outline v-model="form_receive.branchID"
label="Cabang" item-text="M_BranchName" item-value="M_BranchID" @change="onChangeCabang"
:readonly="readonly_mode"></v-autocomplete>
</v-flex>
<v-flex xs2 pa-1>
<v-autocomplete :items="list_gudang" hide-details outline v-model="form_receive.gudangID"
label="Gudang" item-text="WarehouseName" item-value="WarehouseID"
:readonly="readonly_mode"></v-autocomplete>
</v-flex>
<v-flex xs4 pa-1>
<v-text-field hide-details outline label="Biaya Pengiriman" placeholder="0"
v-model="form_receive.shipping" :readonly="readonly_mode"></v-text-field>
</v-flex>
</v-layout>
<v-layout row wrap>
<v-flex xs12 pa-1>
<v-textarea auto-grow rows="1" outline label="Catatan" hide-details
v-model="form_receive.catatan" :readonly="readonly_mode"></v-textarea>
</v-flex>
<v-flex xs3 pa-1 mt-1>
<v-btn block color="info" @click="pickKontrakAset()" :disabled="isFormEmpty()"
v-show="!readonly_mode">
PILIH ORDER ASSET
</v-btn>
</v-flex>
</v-layout>
<v-layout row wrap class="mt-3">
<v-flex xs12 v-if="order_received.length > 0">
<v-data-table :headers="headers" :items="order_received" item-key="PODetailID"
class="elevation-1" hide-actions>
<template v-slot:items="props">
<tr>
<td class="text-xs-center pa-1">
<v-chip label small>{{ props.item.M_ItemCode }}</v-chip> <br>
{{ props.item.M_ItemDesc }}
</td>
<td class="text-xs-center pa-1">
{{ props.item.qty }}
</td>
<td class="text-xs-center pa-1">
{{ props.item.ItemUnitName }}
</td>
<td class="text-xs-center pa-1">
<div v-if="props.item.inspeksi">
<p v-if="props.item.inspeksi.summary == 'accept'" class="mb-0">
Diterima
</p>
<p v-else-if="props.item.inspeksi.summary == 'reject'" class="mb-0">
Ditolak <br>
{{ props.item.inspeksi.catatan }}
</p>
<p v-else class="mb-0">
Diterima dengan catatan <br>
{{ props.item.inspeksi.catatan }}
</p>
</div>
</td>
<td class="text-xs-center pa-1">
<v-tooltip bottom pr-2>
<template v-slot:activator="{ on }">
<v-btn color="green" dark @click="openInspeksi(props.item)"
style="min-width: 40px; margin: 0;" small v-on="on">
<v-icon small>note_add</v-icon>
</v-btn>
</template>
<span>Inspeksi Jasa</span>
</v-tooltip>
<v-tooltip bottom v-show="!readonly_mode">
<template v-slot:activator="{ on }">
<v-btn color="warning" dark @click="cancelOrder(props.item)"
style="min-width: 40px; margin: 0;" small v-on="on">
<v-icon small>cancel</v-icon>
</v-btn>
</template>
<span>Batal Order</span>
</v-tooltip>
</td>
</tr>
</template>
</v-data-table>
</v-flex>
</v-layout>
</v-card-text>
<v-card-actions>
<v-spacer></v-spacer>
<v-btn @click="batalReceiveOrder()" color="error" class="white--text">Batal</v-btn>
<v-btn :disabled="readonly_mode" @click="simpanReceivedOrder()" color="primary"
class="white--text">Simpan</v-btn>
</v-card-actions>
</v-card>
</v-dialog>
</template>
<style scoped>
.style-limit-heightcard {
max-height: 60vh;
display: flex;
flex-direction: column;
}
.style-limit-heightcontent {
overflow-y: auto;
flex: 1 1 auto;
min-height: 0;
}
</style>
<script>
module.exports = {
data() {
return {
menuROdate: false,
headers: [
{
text: "ITEM", align: "center", sortable: false, value: "item",
width: "40%", class: "pa-1 blue lighten-3 white--text",
},
{
text: "QTY", align: "center", sortable: false, value: "qty",
width: "10%", class: "pa-1 blue lighten-3 white--text",
},
{
text: "UNIT ITEM", align: "center", sortable: false, value: "unit",
width: "15%", class: "pa-1 blue lighten-3 white--text",
},
{
text: "INSPEKSI", align: "center", sortable: false, value: "inspec",
width: "20%", class: "pa-1 blue lighten-3 white--text",
},
{
text: "AKSI", align: "center", sortable: false, value: "act",
width: "15%", class: "pa-1 blue lighten-3 white--text",
},
]
}
},
computed: {
dialog_receive_aset: {
get() {
return this.$store.state.orderAsset.dialog_receive_aset
},
set(val) {
this.$store.commit("orderAsset/update_dialog_receive_aset", val)
}
},
form_receive: {
get() {
return this.$store.state.orderAsset.form_receive
},
set(val) {
this.$store.commit("orderAsset/update_form_receive", val)
}
},
order_received: {
get() {
return this.$store.state.orderAsset.order_received
},
set(val) {
this.$store.commit("orderAsset/update_order_received", val)
}
},
readonly_mode() {
return this.$store.state.orderAsset.readonly_mode
},
formattedRODate() {
return this.formatDate(this.form_receive.date);
},
list_cabang() {
return this.$store.state.orderAsset.list_cabang;
},
list_gudang() {
return this.$store.state.orderAsset.list_gudang;
},
list_supplier() {
return this.$store.state.orderAsset.list_supplier;
},
loading_process() {
return this.$store.state.roasset.loading_process;
}
},
methods: {
formatDate(date) {
if (!date) return null;
const [year, month, day] = date.split('-');
return `${day}-${month}-${year}`;
},
formatCurrency(value) {
const num = parseFloat(value);
if (isNaN(num)) return 0;
return num.toFixed(2).replace('.', ',').replace(/\B(?=(\d{3})+(?!\d))/g, ".");
},
onChangeCabang(branchID) {
if (!branchID) return;
this.$store.dispatch("orderAsset/listingGudang", branchID);
},
isFormEmpty() {
const form = this.form_receive;
if (form.supplier == "" || form.gudangID == "") return true;
return false;
},
pickKontrakAset() {
this.$store.dispatch("orderAsset/searchOrderAsset", "");
this.$store.commit("orderAsset/update_dialog_pick_contract", true);
},
openInspeksi(item) {
const selectedItem = JSON.parse(JSON.stringify(item));
const formInspeksi = item.inspeksi
? JSON.parse(JSON.stringify(item.inspeksi))
: {
qty_po: item.qty || 0,
qty_ro: item.qty || 0,
date_po: moment(new Date()).format("YYYY-MM-DD"),
date_ro: moment(new Date()).format("YYYY-MM-DD"),
condt_kemasan: "",
catatan_kemasan: "",
condt_pengiriman: "",
catatan_kirim: "",
summary: "",
catatan: "",
pemeriksa: "",
pengirim: ""
};
this.$store.dispatch("orderAsset/listingStaff", { ROID: "0", isSerahTerima: 'N' });
this.$store.commit("orderAsset/update_selected_item_received", selectedItem);
this.$store.commit("orderAsset/update_form_inspeksi", formInspeksi);
this.$store.commit("orderAsset/update_dialog_inspeksi", true);
},
cancelOrder(item) {
const current = JSON.parse(JSON.stringify(this.order_received));
const neworder = current.filter((obj) => obj.PODetailID != item.PODetailID);
this.order_received = neworder;
},
simpanReceivedOrder() {
if (this.order_received.length <= 0) {
let snac = { color: 'warning', msg: "item tidak boleh kosong", state: true }
this.$store.commit("roasset/update_snackbar", snac)
return;
}
if (!this.loading_process) {
if (!this.form_receive.ReceiveOrderPoID) {
this.$store.dispatch("orderAsset/createReceiveOrder");
} else {
this.$store.dispatch("orderAsset/editReceiveOrder");
}
} else {
let snac = { color: 'warning', msg: "proses masih berjalan", state: true }
this.$store.commit("roasset/update_snackbar", snac)
}
},
batalReceiveOrder() {
const formReceive = {
date: moment(new Date()).format("YYYY-MM-DD"),
supplier: "",
reference: "",
ponumber: "",
branchID: "",
gudangID: "",
shipping: 0,
shippingIsPaid: "N",
catatan: ""
};
const formInspeksi = {
qty_po: 0,
qty_ro: 0,
date_po: moment(new Date()).format("YYYY-MM-DD"),
date_ro: moment(new Date()).format("YYYY-MM-DD"),
condt_kemasan: "",
catatan_kemasan: "",
condt_pengiriman: "",
catatan_kirim: "",
summary: "",
catatan: "",
pemeriksa: "",
pengirim: ""
};
this.$store.commit("orderAsset/update_form_receive", formReceive);
this.$store.commit("orderAsset/update_order_received", []);
this.$store.commit("orderAsset/update_list_item_order", []);
this.$store.commit("orderAsset/update_selected_item_received", {});
this.$store.commit("orderAsset/update_form_inspeksi", formInspeksi);
this.$store.commit("orderAsset/update_readonly_mode", false)
this.dialog_receive_aset = false;
}
}
}
</script>

View File

@@ -0,0 +1,141 @@
<template>
<v-dialog v-model="dialog_barcode" persistent max-width="50vw">
<v-card>
<v-card-title class="headline grey lighten-2" primary-title>
CETAK BARCODE ASSET
</v-card-title>
<v-card-text>
<v-layout pa-2 class="grey lighten-2" row>
<v-flex xs1>
<v-checkbox style="padding-top: 0; margin-top: 0" hide-details color="grey darken-1"
v-model="bar_chx_all" :indeterminate="indeterminatex" @change="changeCbxAll(bar_chx_all)">
</v-checkbox>
</v-flex>
<v-flex xs3> ITEM </v-flex>
<v-flex xs3> RUANGAN </v-flex>
<v-flex xs4> NUMBER BARCODE </v-flex>
<v-flex xs1> CETAK </v-flex>
</v-layout>
<v-layout align-center pa-2 v-for="(vs, idx) in list_barcode" :key="vs.id" class="grey lighten-4" row>
<v-flex xs1>
<v-checkbox style="padding-top: 0; margin-top: 0" color="grey darken-1" hide-details
v-model="vs.chex" @change="checkTop()"></v-checkbox>
</v-flex>
<v-flex xs3>{{ vs.M_ItemDesc }}</v-flex>
<v-flex xs3>{{ vs.M_RuanganName }}</v-flex>
<v-flex xs4>{{ vs.T_BarcodeBarangNumber }}</v-flex>
<v-flex xs1>
<span @click="printSingleBarcode(vs)"
class="icon-medium-fill-base-small xs1 white--text grey darken-1 ml-1 icon-print"></span>
</v-flex>
</v-layout>
</v-card-text>
<v-card-actions>
<v-spacer></v-spacer>
<v-btn color="error" @click="closeDialogBarcode()">Tutup</v-btn>
<v-btn dark color="grey darken-1" @click="printMultipleBarcode()">Cetak terpilih
[ {{ selected_barcode.length }} ]
</v-btn>
</v-card-actions>
</v-card>
</v-dialog>
</template>
<script>
module.exports = {
data() {
return {
bar_chx_all: false,
indeterminatex: false,
selected_barcode: []
}
},
computed: {
dialog_barcode: {
get() {
return this.$store.state.roasset.dialog_barcode
},
set(val) {
this.$store.commit("roasset/update_dialog_barcode", val)
}
},
selected_roasset: {
get() {
return this.$store.state.roasset.selected_roasset
},
set(val) {
this.$store.commit("roasset/update_selected_roasset", val)
}
},
list_barcode: {
get() {
return this.$store.state.roasset.list_barcode
},
set(val) {
this.$store.commit("roasset/update_list_barcode", val)
}
}
},
methods: {
changeCbxAll(value) {
let arr = this.list_barcode;
this.indeterminatex = false;
arr.forEach((el) => {
el.chex = value;
});
let selected = _.filter(arr, function (o) {
return o.chex;
});
this.selected_barcode = selected;
},
checkTop() {
let barcodes = this.list_barcode;
let selected = _.filter(barcodes, function (o) {
return o.chex;
});
this.bar_chx_all = false;
this.indeterminatex = false;
if (selected.length > 0 && barcodes.length === selected.length) {
this.bar_chx_all = true;
this.indeterminatex = false;
}
if (selected.length > 0 && barcodes.length > selected.length) {
this.bar_chx_all = false;
this.indeterminatex = true;
}
this.selected_barcode = selected;
},
printSingleBarcode(value) {
var inp = {
nama_item: value.M_ItemDesc,
no_inv: value.T_BarcodeBarangNumber,
lokasi: value.M_RuanganName,
cabang: value.M_BranchName
};
one_print_qrcode_inv(inp);
},
printMultipleBarcode() {
var barcodes = this.selected_barcode;
barcodes.forEach(value => {
var inp = {
nama_item: value.M_ItemDesc,
no_inv: value.T_BarcodeBarangNumber,
lokasi: value.M_RuanganName,
cabang: value.M_BranchName
};
one_print_qrcode_inv(inp);
});
},
closeDialogBarcode() {
this.bar_chx_all = false
this.indeterminatex = false
this.selected_barcode = []
this.dialog_barcode = false
}
},
watch: {}
}
</script>

View File

@@ -3,7 +3,7 @@
<v-toolbar color="primary" dark> <v-toolbar color="primary" dark>
<v-toolbar-title class="white--text">RECEIVE ORDER ASET</v-toolbar-title> <v-toolbar-title class="white--text">RECEIVE ORDER ASET</v-toolbar-title>
<v-spacer></v-spacer> <v-spacer></v-spacer>
<v-btn icon> <v-btn icon @click="openDialogReceive()">
<v-icon large>add_box</v-icon> <v-icon large>add_box</v-icon>
</v-btn> </v-btn>
</v-toolbar> </v-toolbar>
@@ -11,20 +11,22 @@
<v-card class="pa-2"> <v-card class="pa-2">
<v-layout row align-center> <v-layout row align-center>
<v-flex xs3> <v-flex xs3>
<v-menu v-model="menuStartdateFilter" offset-y lazy min-width="290px" transition="scale-transition" max-width="290px" full-width <v-menu v-model="menuStartdateFilter" offset-y lazy min-width="290px" transition="scale-transition"
:nudge-right="40" :close-on-content-click="false"> max-width="290px" full-width :nudge-right="40" :close-on-content-click="false">
<template v-slot:activator="{ on }"> <template v-slot:activator="{ on }">
<v-text-field v-model="formattedStartdate" label="Tanggal Awal" hide-details readonly v-on="on" outline></v-text-field> <v-text-field label="Tanggal Awal" hide-details readonly v-on="on" outline
v-model="formattedStartdate"></v-text-field>
</template> </template>
<v-date-picker v-model="filterasset.startdate" no-title <v-date-picker v-model="filterasset.startdate" no-title
@input="menuStartdateFilter = false"></v-date-picker> @input="menuStartdateFilter = false"></v-date-picker>
</v-menu> </v-menu>
</v-flex> </v-flex>
<v-flex xs3 pl-2> <v-flex xs3 pl-2>
<v-menu v-model="menuEnddateFilter" offset-y lazy min-width="290px" transition="scale-transition" max-width="290px" full-width <v-menu v-model="menuEnddateFilter" offset-y lazy min-width="290px" transition="scale-transition"
:nudge-right="40" :close-on-content-click="false"> max-width="290px" full-width :nudge-right="40" :close-on-content-click="false">
<template v-slot:activator="{ on }"> <template v-slot:activator="{ on }">
<v-text-field v-model="formattedEnddate" label="Tanggal Akhir" hide-details readonly v-on="on" outline></v-text-field> <v-text-field v-model="formattedEnddate" label="Tanggal Akhir" hide-details readonly
v-on="on" outline></v-text-field>
</template> </template>
<v-date-picker v-model="filterasset.enddate" no-title <v-date-picker v-model="filterasset.enddate" no-title
@input="menuEnddateFilter = false"></v-date-picker> @input="menuEnddateFilter = false"></v-date-picker>
@@ -42,7 +44,122 @@
</v-card> </v-card>
<v-card class="pa-2 mt-2"> <v-card class="pa-2 mt-2">
<v-data-table :headers="headers" :items="list_roasset.records" class="elevation-1" hide-actions></v-data-table> <v-data-table :headers="headers" :items="list_roasset.records" class="elevation-1" hide-actions>
<template v-slot:items="props">
<tr>
<td class="text-xs-center pa-2">
{{ props.item.ReceiveOrderPoIDate }}
</td>
<td class="text-xs-center pa-2">
{{ props.item.ReceiveOrderPoNumber }} <br>
{{ props.item.PurchaseOrderNumber }}
</td>
<td class="text-xs-center pa-2">
{{ props.item.SupplierName }}
</td>
<td class="text-xs-center pa-2">
{{ props.item.ReceiveOrderPoNote }}
</td>
<td class="text-xs-center pa-2">
<div v-if="props.item.ReceiveOrderPoConfirmed == 'Y'">
<v-chip small color="primary" text-color="white">Confirmed</v-chip>
</div>
<div v-else>
<v-chip small color="warning" text-color="white">Unconfirmed</v-chip>
</div>
</td>
<td class="text-xs-center pa-2" style="white-space: nowrap;">
<div v-show="props.item.ReceiveOrderPoConfirmed != 'Y'">
<v-tooltip bottom pr-2>
<template v-slot:activator="{ on }">
<v-btn color="green" dark @click="uploadAttachment(props.item)"
style="min-width: 40px; margin: 0;" small v-on="on">
<v-icon small>attachment</v-icon>
</v-btn>
</template>
<span>Upload Bukti</span>
</v-tooltip>
<v-tooltip bottom pr-2>
<template v-slot:activator="{ on }">
<v-btn color="warning" dark @click="confirmRO(props.item)"
style="min-width: 40px; margin: 0;" small v-on="on">
<v-icon small>send</v-icon>
</v-btn>
</template>
<span>Konfirmasi Receive</span>
</v-tooltip>
<v-tooltip bottom pr-2>
<template v-slot:activator="{ on }">
<v-btn color="info" dark @click="editRO(props.item)" v-on="on"
style="min-width: 40px; margin: 0;" small>
<v-icon small>edit</v-icon>
</v-btn>
</template>
<span>Edit Receive</span>
</v-tooltip>
<v-tooltip bottom>
<template v-slot:activator="{ on }">
<v-btn color="red" dark @click="deleteRO(props.item)"
style="min-width: 40px; margin: 0;" small v-on="on">
<v-icon small>delete</v-icon>
</v-btn>
</template>
<span>Hapus Receive</span>
</v-tooltip>
</div>
<div v-show="props.item.ReceiveOrderPoConfirmed == 'Y'">
<v-tooltip bottom pr-2>
<template v-slot:activator="{ on }">
<v-btn color="black lighten-2" dark @click="viewBarcode(props.item)"
style="min-width: 40px; margin: 0;" small v-on="on">
<v-icon small>print</v-icon>
</v-btn>
</template>
<span>View Barcode</span>
</v-tooltip>
<v-tooltip bottom pr-2>
<template v-slot:activator="{ on }">
<v-btn color="info" dark @click="viewDetail(props.item)"
style="min-width: 40px; margin: 0;" small v-on="on">
<v-icon small>visibility</v-icon>
</v-btn>
</template>
<span>View Detail</span>
</v-tooltip>
<v-tooltip bottom pr-2>
<template v-slot:activator="{ on }">
<v-btn color="orange" dark @click="uploadAttachment(props.item)"
style="min-width: 40px; margin: 0;" small v-on="on">
<v-icon small>attach_file</v-icon>
</v-btn>
</template>
<span>View Document</span>
</v-tooltip>
<v-tooltip bottom pr-2>
<template v-slot:activator="{ on }">
<v-btn color="primary" dark @click="printout(props.item)"
style="min-width: 40px; margin: 0;" small v-on="on">
<v-icon small>print</v-icon>
</v-btn>
</template>
<span>Cetak PDF</span>
</v-tooltip>
<span v-show="props.item.ReceiveOrderPoIsHandover == 'N'">
<v-tooltip bottom>
<template v-slot:activator="{ on }">
<v-btn color="green" dark @click="handOverRO(props.item)"
style="min-width: 40px; margin: 0;" small v-on="on">
<v-icon small>move_to_inbox</v-icon>
</v-btn>
</template>
<span>Serah Terima</span>
</v-tooltip>
</span>
</div>
</td>
</tr>
</template>
</v-data-table>
<v-divider class="my-1"></v-divider> <v-divider class="my-1"></v-divider>
<div class="pa-2 mt-1 text-xs-center"> <div class="pa-2 mt-1 text-xs-center">
<v-pagination v-model="currpage" :length="pagelength" :total-visible="10"></v-pagination> <v-pagination v-model="currpage" :length="pagelength" :total-visible="10"></v-pagination>
@@ -53,43 +170,70 @@
{{ snackbar.msg }} {{ snackbar.msg }}
<v-btn class="ml-2" round flat @click="snackbar.state = false">Tutup</v-btn> <v-btn class="ml-2" round flat @click="snackbar.state = false">Tutup</v-btn>
</v-snackbar> </v-snackbar>
<dialog-receive-aset></dialog-receive-aset>
<dialog-add-attachment></dialog-add-attachment>
<dialog-delete-order-asset></dialog-delete-order-asset>
<dialog-confirm-order-asset></dialog-confirm-order-asset>
<dialog-pick-contract></dialog-pick-contract>
<dialog-inspeksi></dialog-inspeksi>
<dialog-view-barcode></dialog-view-barcode>
<dialog-handover-asset></dialog-handover-asset>
<one-dialog-print :title="printtitle" :width="printwidth" :height="600" :status="openprint" :urlprint="urlprint"
@close-dialog-print="openprint = false"></one-dialog-print>
</div> </div>
</template> </template>
<script> <script>
module.exports = { module.exports = {
components: {
'dialog-receive-aset': httpVueLoader('./dialog-receive-order-asset.vue'),
'dialog-add-attachment': httpVueLoader('./dialog-add-attachment.vue'),
'dialog-delete-order-asset': httpVueLoader('./dialog-delete-order-asset.vue'),
'dialog-confirm-order-asset': httpVueLoader('./dialog-confirm-receive.vue'),
'dialog-pick-contract': httpVueLoader('./dialog-pick-contract.vue'),
'dialog-inspeksi': httpVueLoader('./dialog-inspeksi.vue'),
'dialog-view-barcode': httpVueLoader('./dialog-view-barcode.vue'),
'dialog-handover-asset': httpVueLoader('./dialog-handover-asset.vue'),
'one-dialog-print': httpVueLoader('../../common/oneDialogPrintX.vue'),
},
mounted() {
this.$store.dispatch("orderAsset/listingCabang");
this.$store.dispatch("orderAsset/listingSupplier");
this.$store.dispatch("roasset/lookupOrderAssetReceived");
},
data() { data() {
return { return {
urlprint: "",
printtitle: "",
printwidth: "60%",
openprint: false,
menuStartdateFilter: false, menuStartdateFilter: false,
menuEnddateFilter: false, menuEnddateFilter: false,
headers: [ headers: [
{ {
text: "TANGGAL RO", align: "center", sortable: false, text: "TANGGAL RECEIVE", align: "center", sortable: false, value: "date",
value: "date", width: "10%", class: "pa-1 blue lighten-3 white--text", width: "15%", class: "pa-1 blue lighten-3 white--text",
}, },
{ {
text: "NOMOR RO", align: "center", sortable: false, text: "NOMOR RO/PO", align: "start", sortable: false, value: "noropo",
value: "noro", width: "15%", class: "pa-1 blue lighten-3 white--text", width: "20%", class: "pa-1 blue lighten-3 white--text",
}, },
{ {
text: "NOMOR PO", align: "center", sortable: false, text: "SUPPLIER", align: "center", sortable: false, value: "supplier",
value: "nopo", width: "15%", class: "pa-1 blue lighten-3 white--text", width: "15%", class: "pa-1 blue lighten-3 white--text",
}, },
{ {
text: "SUPPLIER", align: "center", sortable: false, text: "CATATAN", align: "center", sortable: false, value: "note",
value: "supp", width: "15%", class: "pa-1 blue lighten-3 white--text", width: "25%", class: "pa-1 blue lighten-3 white--text",
}, },
{ {
text: "CATATAN", align: "center", sortable: false, text: "STATUS", align: "center", sortable: false, value: "status",
value: "note", width: "20%", class: "pa-1 blue lighten-3 white--text", width: "10%", class: "pa-1 blue lighten-3 white--text",
}, },
{ {
text: "STATUS", align: "center", sortable: false, text: "AKSI", align: "center", sortable: false, value: "acts",
value: "status", width: "10%", class: "pa-1 blue lighten-3 white--text", width: "15%", class: "pa-1 blue lighten-3 white--text",
},
{
text: "AKSI", align: "center", sortable: false,
value: "acts", width: "15%", class: "pa-1 blue lighten-3 white--text",
}, },
] ]
} }
@@ -117,6 +261,7 @@ module.exports = {
}, },
set(val) { set(val) {
this.$store.commit("roasset/update_currpage", val) this.$store.commit("roasset/update_currpage", val)
this.$store.dispatch("roasset/lookupOrderAssetReceived")
} }
}, },
list_status() { list_status() {
@@ -128,7 +273,7 @@ module.exports = {
pagelength() { pagelength() {
let total = this.list_roasset.total let total = this.list_roasset.total
if (total === undefined || total < 1) return 1 if (total === undefined || total < 1) return 1
return Math.ceil(total/10) return Math.ceil(total / 10)
}, },
formattedStartdate() { formattedStartdate() {
return this.formatDate(this.filterasset.startdate) return this.formatDate(this.filterasset.startdate)
@@ -142,6 +287,66 @@ module.exports = {
if (!date) return null; if (!date) return null;
const [year, month, day] = date.split('-'); const [year, month, day] = date.split('-');
return `${day}-${month}-${year}`; return `${day}-${month}-${year}`;
},
openDialogReceive() {
this.$store.commit("orderAsset/update_dialog_receive_aset", true)
},
uploadAttachment(item) {
this.$store.dispatch("roasset/lookupAttachment", item.ReceiveOrderPoID);
this.$store.commit("roasset/update_selected_roasset", item);
this.$store.commit("roasset/update_dialog_attachment", true);
},
editRO(item) {
this.$store.dispatch("roasset/getDetailDataROAsset", item.ReceiveOrderPoID)
this.$store.commit("roasset/update_selected_roasset", item)
this.$store.commit("orderAsset/update_dialog_receive_aset", true)
},
viewDetail(item) {
this.$store.dispatch("roasset/getDetailDataROAsset", item.ReceiveOrderPoID)
this.$store.commit("roasset/update_selected_roasset", item)
this.$store.commit("orderAsset/update_readonly_mode", true)
this.$store.commit("orderAsset/update_dialog_receive_aset", true)
},
confirmRO(item) {
this.$store.dispatch("roasset/lookupAttachment", item.ReceiveOrderPoID);
this.$store.commit("roasset/update_selected_roasset", item)
this.$store.commit("roasset/update_dialog_confirm", true)
},
deleteRO(item) {
this.$store.commit("roasset/update_selected_roasset", item)
this.$store.commit("roasset/update_dialog_delete", true);
},
printout(val) {
this.printwidth = "60%";
this.printtitle = "";
let user = one_user();
let username = user && user.M_StaffName ? user.M_StaffName : "";
let tm = Date.now();
this.urlprint = BASE_URL + "/one-api/report/rpt_receive_order_asset/pdf?id=" + val.ReceiveOrderPoID + "&username=" + username + "&tm=" + tm;
this.openprint = true;
},
viewBarcode(item) {
this.$store.dispatch("roasset/lookupBarcodes", item.ReceiveOrderPoID);
this.$store.commit("roasset/update_selected_roasset", item);
this.$store.commit("roasset/update_dialog_barcode", true);
},
handOverRO(item) {
this.$store.commit("roasset/update_selected_roasset", item);
this.$store.dispatch("roasset/lookupRuangan");
this.$store.dispatch("orderAsset/listingStaff", { ROID: item.ReceiveOrderPoID, isSerahTerima: 'Y' });
this.$store.dispatch("roasset/lookupAssetNotHanded", item.ReceiveOrderPoID);
this.$store.commit("roasset/update_dialog_handover_asset", true);
}
},
watch: {
filterasset: {
handler(val) {
setTimeout(() => {
this.$store.dispatch("roasset/lookupOrderAssetReceived")
}, 500)
},
deep: true
} }
} }
} }

View File

@@ -4,10 +4,10 @@
<meta charset="UTF-8"> <meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge"> <meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>ACCONE | Receive Order Asset</title>
<link rel="stylesheet" href="../../../libs/vendor/css/google-fonts.css"> <link rel="stylesheet" href="../../../libs/vendor/css/google-fonts.css">
<link rel="stylesheet" href="../../../libs/vendor/css/icomoon-fonts.css"> <link rel="stylesheet" href="../../../libs/vendor/css/icomoon-fonts.css">
<link rel="stylesheet" href="../../../libs/vendor/css/vuetify.min.css"> <link rel="stylesheet" href="../../../libs/vendor/css/vuetify.min.css">
<title>One</title>
</head> </head>
<body> <body>
<div v-cloak id="app"> <div v-cloak id="app">
@@ -16,7 +16,7 @@
<v-content style="background: #F5E8DF!important"> <v-content style="background: #F5E8DF!important">
<v-container fluid fill-height class="px-1 py-2"> <v-container fluid fill-height class="px-1 py-2">
<v-flex xs12 fill-height pa-1> <v-flex xs12 fill-height pa-1>
<main-layout></main-layout>
</v-flex> </v-flex>
</v-container> </v-container>
</v-content> </v-content>
@@ -35,6 +35,8 @@
<script src="../../../libs/vendor/vuetify.js"></script> <script src="../../../libs/vendor/vuetify.js"></script>
<script src="../../../libs/vendor/httpVueLoader.js"></script> <script src="../../../libs/vendor/httpVueLoader.js"></script>
<script src="../../../libs/one_global.js"></script> <script src="../../../libs/one_global.js"></script>
<script src="../../../libs/one_print_barcode.js"></script>
<script src="../../../libs/vendor/sheetjs-master/xlsx.full.min.js"></script>
<!-- App Script --> <!-- App Script -->
<script type="module"> <script type="module">
@@ -46,7 +48,8 @@
methods: {}, methods: {},
components: { components: {
'one-navbar': httpVueLoader('../../../apps/components/oneNavbarComponent.vue'), 'one-navbar': httpVueLoader('../../../apps/components/oneNavbarComponent.vue'),
'one-footer': httpVueLoader('../../../apps/components/oneFooter.vue') 'one-footer': httpVueLoader('../../../apps/components/oneFooter.vue'),
'main-layout': httpVueLoader('./components/main-layout.vue')
} }
}) })
</script> </script>

View File

@@ -0,0 +1,223 @@
import * as api from "../api/api.js";
export default {
namespaced: true,
state: {
dialog_receive_aset: false,
readonly_mode: false,
form_receive: {
date: moment(new Date()).format('YYYY-MM-DD'),
supplier: "",
reference: "",
ponumber: "",
branchID: "",
gudangID: "",
shipping: 0,
shippingIsPaid: "N",
catatan: ""
},
list_cabang: [],
list_gudang: [],
list_supplier: [],
order_received: [],
dialog_pick_contract: false,
list_item_order: [],
dialog_inspeksi: false,
list_staff: [],
selected_item_received: {},
form_inspeksi: {
qty_po: 0,
qty_ro: 0,
date_po: moment(new Date()).format('YYYY-MM-DD'),
date_ro: moment(new Date()).format('YYYY-MM-DD'),
condt_kemasan: '',
catatan_kemasan: '',
condt_pengiriman: '',
catatan_kirim: '',
summary: '',
catatan: '',
pemeriksa: '',
pengirim: ''
}
},
mutations: {
update_dialog_receive_aset(state, val) {
state.dialog_receive_aset = val
},
update_readonly_mode(state, val) {
state.readonly_mode = val
},
update_form_receive(state, val) {
state.form_receive = val
},
update_list_cabang(state, val) {
state.list_cabang = val
},
update_list_gudang(state, val) {
state.list_gudang = val
},
update_list_supplier(state, val) {
state.list_supplier = val
},
update_order_received(state, val) {
state.order_received = val
},
update_dialog_pick_contract(state, val) {
state.dialog_pick_contract = val
},
update_list_item_order(state, val) {
state.list_item_order = val
},
update_dialog_inspeksi(state, val) {
state.dialog_inspeksi = val
},
update_list_staff(state, val) {
state.list_staff = val
},
update_selected_item_received(state, val) {
state.selected_item_received = val
},
update_form_inspeksi(state, val) {
state.form_inspeksi = val
}
},
actions: {
async listingCabang(context) {
try {
let param = { token: one_token() }
const resp = await api.getListCabang(param);
if (resp.status != "OK") {
throw new Error(resp.message);
}
context.commit('update_list_cabang', resp.data);
} catch (e) {
const snac = { color: 'error', msg: e.message, state: true };
context.commit("roasset/update_snackbar", snac, { root: true });
}
},
async listingGudang(context, branchID) {
try {
let param = {
token: one_token(),
M_BranchID: branchID
}
const resp = await api.getListGudang(param);
if (resp.status != "OK") {
throw new Error(resp.message);
}
context.commit('update_list_gudang', resp.data);
} catch (e) {
const snac = { color: 'error', msg: e.message, state: true };
context.commit("roasset/update_snackbar", snac, { root: true });
}
},
async listingSupplier(context) {
try {
const params = { token: one_token() };
const resp = await api.getListSupplier(params);
if (resp.status != 'OK') {
throw new Error(resp.message);
}
context.commit('update_list_supplier', resp.data);
} catch (e) {
const snac = { color: 'error', msg: e.message, state: true };
context.commit("roasset/update_snackbar", snac, { root: true });
}
},
async listingStaff(context, params) {
try {
params.token = one_token();
const resp = await api.getListStaff(params);
if (resp.status != 'OK') {
throw new Error(resp.message);
}
context.commit('update_list_staff', resp.data);
} catch (e) {
const snac = { color: 'error', msg: e.message, state: true };
context.commit("roasset/update_snackbar", snac, { root: true });
}
},
async searchOrderAsset(context, keyword) {
try {
const form = context.state.form_receive;
const params = {
token: one_token(),
search: keyword,
supplierID: form.supplier,
gudangID: form.gudangID
};
const resp = await api.searchOrderAsset(params);
if (resp.status != 'OK') {
throw new Error(resp.message);
}
context.commit("update_list_item_order", resp.data)
} catch (e) {
const snac = { color: 'error', msg: e.message, state: true };
context.commit("roasset/update_snackbar", snac, { root: true });
}
},
async createReceiveOrder(context) {
try {
context.commit("roasset/update_loading_process", true, { root: true });
const detail = context.state.order_received;
const params = {
...context.state.form_receive,
detail: detail,
token: one_token()
};
const resp = await api.createReceiveOrder(params);
if (resp.status != 'OK') {
throw new Error(resp.message);
}
const snac = { color: 'success', msg: resp.data, state: true };
context.commit("roasset/update_snackbar", snac, { root: true });
context.dispatch("roasset/lookupOrderAssetReceived", {}, {root: true});
context.commit("roasset/update_loading_process", false, { root: true });
context.state.dialog_receive_aset = false;
} catch (e) {
context.commit("roasset/update_loading_process", false, { root: true });
const snac = { color: 'error', msg: e.message, state: true };
context.commit("roasset/update_snackbar", snac, { root: true });
}
},
async editReceiveOrder(context) {
try {
context.commit("roasset/update_loading_process", true, { root: true });
const detail = context.state.order_received;
const params = {
...context.state.form_receive,
detail: detail,
token: one_token()
};
const resp = await api.editReceiveOrder(params);
if (resp.status != 'OK') {
throw new Error(resp.message);
}
const snac = { color: 'success', msg: resp.data, state: true };
context.commit("roasset/update_snackbar", snac, { root: true });
context.dispatch("roasset/lookupOrderAssetReceived", {}, {root: true});
context.commit("roasset/update_loading_process", false, { root: true });
context.state.dialog_receive_aset = false;
} catch (e) {
context.commit("roasset/update_loading_process", false, { root: true });
const snac = { color: 'error', msg: e.message, state: true };
context.commit("roasset/update_snackbar", snac, { root: true });
}
}
}
}

View File

@@ -22,7 +22,25 @@ export default {
records: [], records: [],
total: 0 total: 0
}, },
currpage: 1 currpage: 1,
selected_roasset: {},
/* upload attachment */
dialog_attachment: false,
preview_attachment: [],
/* delete */
dialog_delete: false,
/* confirm */
dialog_confirm: false,
/* barcode */
dialog_barcode: false,
list_barcode: [],
dialog_handover_asset: false,
list_item_not_handed: [],
list_lokasi: []
}, },
mutations: { mutations: {
/* common */ /* common */
@@ -45,7 +63,246 @@ export default {
}, },
update_currpage(state, val) { update_currpage(state, val) {
state.currpage = val state.currpage = val
},
update_selected_roasset(state, val) {
state.selected_roasset = val
},
/* attachment */
update_dialog_attachment(state, val) {
state.dialog_attachment = val
},
update_preview_attachment(state, val) {
state.preview_attachment = val
},
/* delete */
update_dialog_delete(state, val) {
state.dialog_delete = val
},
/* delete */
update_dialog_confirm(state, val) {
state.dialog_confirm = val
},
/* barcode */
update_dialog_barcode(state, val) {
state.dialog_barcode = val
},
update_list_barcode(state, val) {
state.list_barcode = val
},
update_dialog_handover_asset(state, val) {
state.dialog_handover_asset = val
},
update_list_item_not_handed(state, val) {
state.list_item_not_handed = val
},
update_list_lokasi(state, val) {
state.list_lokasi = val
} }
}, },
actions: {} actions: {
async lookupOrderAssetReceived(context) {
try {
const param = {
token: one_token(),
currpage: context.state.currpage,
...context.state.filterasset
}
const resp = await api.getListingROAsset(param);
if (resp.status != "OK") {
throw new Error(resp.message);
}
context.commit("update_list_roasset", resp.data);
} catch (e) {
const snac = { color: 'error', msg: e.message, state: false };
context.commit("update_snackbar", snac);
}
},
async lookupAttachment(context, roID) {
try {
const param = {
token: one_token(),
roID: roID
}
const resp = await api.getListAttachment(param);
if (resp.status != "OK") {
throw new Error(resp.message);
}
context.commit('update_preview_attachment', resp.data);
} catch (e) {
const snac = { color: 'error', msg: e.message, state: false };
context.commit("update_snackbar", snac);
}
},
async getDetailDataROAsset(context, roid) {
try {
context.commit('update_loading_process', true);
let params = {
token: one_token(),
roid: roid
}
const resp = await api.getDetailDataROAsset(params);
if (resp.status != "OK") {
throw new Error(resp.message);
}
context.commit('orderAsset/update_form_receive', resp.data.header, { root: true })
context.dispatch('orderAsset/listingGudang', resp.data.header.branchID, { root: true });
context.commit('orderAsset/update_order_received', resp.data.detail, { root: true })
context.commit('update_loading_process', false);
} catch (e) {
context.commit('update_loading_process', false);
const snac = { color: 'error', msg: e.message, state: false };
context.commit("update_snackbar", snac);
}
},
async uploadAttachment(context, params) {
try {
context.commit('update_loading_process', true);
const resp = await api.uploadAttachment(params);
if (resp.status != "OK") {
throw new Error(resp.message);
}
const snac = { color: 'success', msg: resp.data, state: true };
context.commit("update_snackbar", snac);
context.dispatch('lookupOrderAssetReceived');
context.commit('update_loading_process', false);
context.state.dialog_attachment = false;
} catch (e) {
context.commit('update_loading_process', false);
const snac = { color: 'error', msg: e.message, state: false };
context.commit("update_snackbar", snac);
}
},
async deleteReceiveAsset(context, roID) {
try {
context.commit('update_loading_process', true);
const param = {
token: one_token(),
roid: roID
}
const resp = await api.deleteReceiveOrder(param);
if (resp.status != "OK") {
throw new Error(resp.message);
}
const snac = { color: 'success', msg: resp.data, state: true };
context.commit("update_snackbar", snac);
context.dispatch('lookupOrderAssetReceived');
context.commit('update_loading_process', false);
context.state.dialog_delete = false;
} catch (e) {
context.commit('update_loading_process', false);
const snac = { color: 'error', msg: e.message, state: false };
context.commit("update_snackbar", snac);
}
},
async confirmReceiveOrder(context, roID) {
try {
context.commit('update_loading_process', true);
const param = {
token: one_token(),
roid: roID
}
const resp = await api.confirmReceiveOrder(param);
if (resp.status != "OK") {
throw new Error(resp.message);
}
const snac = { color: 'success', msg: resp.data, state: true };
context.commit("update_snackbar", snac);
context.dispatch('lookupOrderAssetReceived');
context.commit('update_loading_process', false);
context.state.dialog_confirm = false;
} catch (e) {
context.commit('update_loading_process', false);
const snac = { color: 'error', msg: e.message, state: false };
context.commit("update_snackbar", snac);
}
},
async lookupRuangan(context) {
try {
const params = {
token: one_token(),
search: ''
};
const resp = await api.getRuangan(params);
if (resp.status != 'OK') {
throw new Error(resp.message);
}
context.commit("update_list_lokasi", resp.data);
} catch (e) {
const snac = { color: 'error', msg: e.message, state: true };
context.commit("update_snackbar", snac);
}
},
async lookupAssetNotHanded(context, id) {
try {
const params = {
token: one_token(),
ROID: id
};
const resp = await api.getAssetBelumSerahTerima(params);
if (resp.status != 'OK') {
throw new Error(resp.message);
}
context.commit("update_list_item_not_handed", resp.data);
} catch (e) {
const snac = { color: 'error', msg: e.message, state: true };
context.commit("update_snackbar", snac);
}
},
async saveHandoverAsset(context, params) {
try {
params.token = one_token();
const resp = await api.saveHandover(params);
if (resp.status != 'OK') {
throw new Error(resp.message);
}
const snac = { color: 'success', msg: resp.data, state: true };
context.commit("update_snackbar", snac);
context.dispatch("lookupOrderAssetReceived");
context.commit("update_dialog_handover_asset", false);
} catch (e) {
const snac = { color: 'error', msg: e.message, state: true };
context.commit("update_snackbar", snac);
}
},
async lookupBarcodes(context, id) {
try {
const params = {
token: one_token(),
ROID: id
};
const resp = await api.getBarcodes(params);
if (resp.status != 'OK') {
throw new Error(resp.message);
}
context.commit('update_list_barcode', resp.data);
} catch (e) {
const snac = { color: 'error', msg: e.message, state: true };
context.commit("update_snackbar", snac);
}
},
}
} }

View File

@@ -1,10 +1,12 @@
import system from "../../../apps/modules/system/system.js"; import system from "../../../apps/modules/system/system.js";
import orderAsset from "./modules/order-asset.js";
import roasset from "./modules/roasset.js" import roasset from "./modules/roasset.js"
export const store = new Vuex.Store({ export const store = new Vuex.Store({
modules: { modules: {
system: system, system: system,
roasset:roasset roasset: roasset,
orderAsset: orderAsset
}, },
state: {}, state: {},
mutatios: {}, mutatios: {},

View File

@@ -83,6 +83,16 @@
{{ props.item.SuratJalanStatus }} {{ props.item.SuratJalanStatus }}
</v-chip> </v-chip>
</td> </td>
<td class="text-xs-center pa-2" style="white-space: nowrap;">
<v-btn
style="min-width: 25px; height: 25px; margin: 0;"
@click="printout(props.item)"
small title="Cetak PDF"
color="primary"
>
<v-icon small color="white">print</v-icon>
</v-btn>
</td>
</tr> </tr>
</template> </template>
</v-data-table> </v-data-table>
@@ -91,11 +101,23 @@
<v-pagination v-model="paginat" :length="paginat_len" :total-visible="5"></v-pagination> <v-pagination v-model="paginat" :length="paginat_len" :total-visible="5"></v-pagination>
</div> </div>
</v-card> </v-card>
<one-dialog-print
:title="printtitle"
:width="printwidth"
:height="600"
:status="openprint"
:urlprint="urlprint"
@close-dialog-print="openprint = false"
></one-dialog-print>
</v-layout> </v-layout>
</template> </template>
<script> <script>
module.exports = { module.exports = {
components: {
"one-dialog-print": httpVueLoader("../../common/oneDialogPrintX.vue"),
},
mounted() { mounted() {
this.$store.dispatch("suratjalan/LookupBranches") this.$store.dispatch("suratjalan/LookupBranches")
this.$store.dispatch("suratjalan/LookupEkpedisi") this.$store.dispatch("suratjalan/LookupEkpedisi")
@@ -105,6 +127,10 @@
}, },
data() { data() {
return { return {
urlprint: "",
printtitle: "",
printwidth: "60%",
openprint: false,
menuStartDate: false, menuStartDate: false,
menuEndDate: false, menuEndDate: false,
headers: [ headers: [
@@ -130,7 +156,11 @@
}, },
{ {
text: "STATUS", align: "center", sortable: false, text: "STATUS", align: "center", sortable: false,
value: "requestDate", width: "15%", class: "blue lighten-3 white--text", value: "requestDate", width: "10%", class: "blue lighten-3 white--text",
},
{
text: "AKSI", align: "center", sortable: false,
value: "action", width: "10%", class: "blue lighten-3 white--text",
} }
] ]
} }
@@ -232,6 +262,15 @@
default: default:
return "gray" return "gray"
} }
},
printout(val) {
this.printwidth = "60%";
this.printtitle = "";
let user = one_user();
let username = user && user.M_StaffName ? user.M_StaffName : "";
let tm = Date.now();
this.urlprint = BASE_URL + "/one-api/report/rpt_receive_transfer/pdf?id=" + val.SuratJalanID + "&username=" + username + "&tm=" + tm;
this.openprint = true;
} }
}, },
} }

View File

@@ -220,6 +220,7 @@
> >
<td <td
class="text-xs-center pa-2" class="text-xs-center pa-2"
style="white-space: nowrap;"
v-bind:class="{ v-bind:class="{
'amber lighten-4': isSelected(props.item), 'amber lighten-4': isSelected(props.item),
}" }"
@@ -247,6 +248,7 @@
<template v-else-if="props.item.rioStatus == 'Send Request'"> <template v-else-if="props.item.rioStatus == 'Send Request'">
<td <td
class="text-xs-center pa-2 pr-5" class="text-xs-center pa-2 pr-5"
style="white-space: nowrap;"
v-bind:class="{ v-bind:class="{
'amber lighten-4': isSelected(props.item), 'amber lighten-4': isSelected(props.item),
}" }"
@@ -277,15 +279,34 @@
> >
<v-icon color="white" small>receipt</v-icon> <v-icon color="white" small>receipt</v-icon>
</v-btn> </v-btn>
<v-btn
style="min-width: 25px; height: 25px; margin: 0;"
@click="printout(props.item)"
color="primary"
small title="Cetak PDF"
class="d-block mx-auto mb-2"
>
<v-icon color="white" small>print</v-icon>
</v-btn>
</td> </td>
</template> </template>
<template v-else> <template v-else>
<td <td
class="text-xs-center pa-2" class="text-xs-center pa-2"
style="white-space: nowrap;"
v-bind:class="{ v-bind:class="{
'amber lighten-4': isSelected(props.item), 'amber lighten-4': isSelected(props.item),
}" }"
></td> >
<v-btn
style="min-width: 25px; height: 25px; margin: 0;"
@click="printout(props.item)"
color="primary"
small title="Cetak PDF"
>
<v-icon color="white" small>print</v-icon>
</v-btn>
</td>
</template> </template>
</template> </template>
</v-data-table> </v-data-table>
@@ -336,6 +357,14 @@
</v-card> </v-card>
</v-dialog> </v-dialog>
<one-dialog-print
:title="printtitle"
:width="printwidth"
:height="600"
:status="openprint"
:urlprint="urlprint"
@close-dialog-print="openprint = false"
></one-dialog-print>
</div> </div>
</template> </template>
@@ -370,9 +399,14 @@ module.exports = {
"approve-dialog": httpVueLoader("./approveDialog.vue"), "approve-dialog": httpVueLoader("./approveDialog.vue"),
"one-dialog-alert": httpVueLoader("../../common/oneDialogAlert.vue"), "one-dialog-alert": httpVueLoader("../../common/oneDialogAlert.vue"),
"one-dialog-error": httpVueLoader("../../common/oneDialogError.vue"), "one-dialog-error": httpVueLoader("../../common/oneDialogError.vue"),
"one-dialog-print": httpVueLoader("../../common/oneDialogPrintX.vue"),
}, },
data() { data() {
return { return {
urlprint: "",
printtitle: "",
printwidth: "60%",
openprint: false,
msgAlertDeleteRequest: "", msgAlertDeleteRequest: "",
dialogAlertDeleteRequest: false, dialogAlertDeleteRequest: false,
dialogAlertDeleteDetail: false, dialogAlertDeleteDetail: false,
@@ -398,7 +432,7 @@ module.exports = {
align: "left", align: "left",
sortable: false, sortable: false,
value: "keterangan", value: "keterangan",
width: "40%", width: "35%",
class: "blue lighten-3 white--text", class: "blue lighten-3 white--text",
}, },
{ {
@@ -414,7 +448,7 @@ module.exports = {
align: "center", align: "center",
sortable: false, sortable: false,
value: "action", value: "action",
width: "10%", width: "15%",
class: "blue lighten-3 white--text", class: "blue lighten-3 white--text",
}, },
], ],
@@ -907,6 +941,15 @@ module.exports = {
}); });
} }
}, },
printout(val) {
this.printwidth = "60%";
this.printtitle = "";
let user = one_user();
let username = user && user.M_StaffName ? user.M_StaffName : "";
let tm = Date.now();
this.urlprint = BASE_URL + "/one-api/report/rpt_request_pengeluaran_barang/pdf?id=" + val.rioId + "&username=" + username + "&tm=" + tm;
this.openprint = true;
}
}, },
}; };
</script> </script>

View File

@@ -79,7 +79,6 @@ export async function searchcard(token,prm) {
export async function pay(prm) { export async function pay(prm) {
try { try {
// var resp = await axios.post(URL + 'payment/paymanual',prm);
var resp = await axios.post(URL + 'PaymentV2/paymanual',prm); var resp = await axios.post(URL + 'PaymentV2/paymanual',prm);
if (resp.status != 200) { if (resp.status != 200) {
return { return {

View File

@@ -93,7 +93,7 @@
v-bind:class="{'amber lighten-4':isSelected(props.item)}" v-bind:class="{'amber lighten-4':isSelected(props.item)}"
> >
{{ props.item.SupplierInvoiceNumber}} {{ props.item.SupplierInvoiceNumber}}
<p><v-btn v-if="props.item.SupplierInvoiceIsLunas === 'Y'" small color="success">Lunas</v-btn></p> <p><v-btn v-if="props.item.flaglunas === 'Y'" small color="success">Lunas</v-btn></p>
</td> </td>
<td <td
class="pa-2" @click="selectMe(props.item)" class="pa-2" @click="selectMe(props.item)"
@@ -189,7 +189,7 @@
v-bind:class="{'amber lighten-4':isSelected(props.item)}" v-bind:class="{'amber lighten-4':isSelected(props.item)}"
> >
{{ props.item.SupplierInvoiceNumber}} {{ props.item.SupplierInvoiceNumber}}
<p><v-btn v-if="props.item.SupplierInvoiceIsLunas === 'Y'" small color="success">Lunas</v-btn></p> <p><v-btn v-if="props.item.flaglunas === 'Y'" small color="success">Lunas</v-btn></p>
</td> </td>
<td <td
class="pa-2" @click="selectMe(props.item)" class="pa-2" @click="selectMe(props.item)"
@@ -457,7 +457,13 @@
return `${year}-${month.padStart(2, '0')}-${day.padStart(2, '0')}` return `${year}-${month.padStart(2, '0')}-${day.padStart(2, '0')}`
}, },
isSelected(p) { isSelected(p) {
return p.SupplierInvoiceID == this.$store.state.bill.selected_bill.SupplierInvoiceID const sel = this.$store.state.bill.selected_bill;
if (!sel || !sel.type) return false;
return p.type === sel.type && (
(sel.type === 'INVOICE' && p.SupplierInvoiceID == sel.SupplierInvoiceID) ||
(sel.type === 'DP' && p.DownpaymentID == sel.DownpaymentID) ||
(sel.type === 'INSTALLMENT' && p.InstallmentID == sel.InstallmentID)
);
}, },
closeDialogPaySuccess() { closeDialogPaySuccess() {
this.$store.commit("bill/update_dialog_pay_success", false) this.$store.commit("bill/update_dialog_pay_success", false)

View File

@@ -1199,9 +1199,21 @@
notes: this.$store.state.paymentmanual.notes, notes: this.$store.state.paymentmanual.notes,
totalbill : this.$store.state.bill.selected_bill.totalbill, totalbill : this.$store.state.bill.selected_bill.totalbill,
paid : this.$store.state.bill.selected_bill.paid, paid : this.$store.state.bill.selected_bill.paid,
tanggalbayar : this.xtanggalbayar tanggalbayar: this.xtanggalbayar,
type: this.$store.state.bill.selected_bill.type,
} }
//console.log(prm.amount)
if (this.$store.state.bill.selected_bill.type == 'DP') {
prm.DownpaymentID = this.$store.state.bill.selected_bill.DownpaymentID
prm.dpkode = this.$store.state.bill.selected_bill.SupplierInvoiceNumber
} else if (this.$store.state.bill.selected_bill.type == "INSTALLMENT") {
prm.InstallmentID = this.$store.state.bill.selected_bill.InstallmentID
prm.installmentkode = this.$store.state.bill.selected_bill.SupplierInvoiceNumber
} else {
prm.SupplierInvoiceID = this.$store.state.bill.selected_bill.SupplierInvoiceID
prm.invoicekode = this.$store.state.bill.selected_bill.SupplierInvoiceNumber
}
this.$store.dispatch("paymentmanual/pay", prm) this.$store.dispatch("paymentmanual/pay", prm)
}, },
deleteNote(note, idx) { deleteNote(note, idx) {
@@ -1248,8 +1260,14 @@
}, },
closeDialogDelete() { closeDialogDelete() {
let arrbill = this.$store.state.bill.bills let arrbill = this.$store.state.bill.bills
var idx = _.findIndex(arrbill, item => item.SupplierInvoiceID === this.$store.state.bill.selected_bill const sel = this.$store.state.bill.selected_bill;
.SupplierInvoiceID) var idx = _.findIndex(arrbill, item =>
item.type === sel.type && (
(sel.type === 'INVOICE' && item.SupplierInvoiceID == sel.SupplierInvoiceID) ||
(sel.type === 'DP' && item.DownpaymentID == sel.DownpaymentID) ||
(sel.type === 'INSTALLMENT' && item.InstallmentID == sel.InstallmentID)
)
);
this.$store.commit("paymentmanual/update_dialog_delete", false) this.$store.commit("paymentmanual/update_dialog_delete", false)
this.$store.commit("bill/update_selected_bill", {}) this.$store.commit("bill/update_selected_bill", {})
this.$store.dispatch("bill/search", { this.$store.dispatch("bill/search", {
@@ -1263,8 +1281,14 @@
}, },
closeDialogEdit() { closeDialogEdit() {
let arrbill = this.$store.state.bill.bills let arrbill = this.$store.state.bill.bills
var idx = _.findIndex(arrbill, item => item.SupplierInvoiceID === this.$store.state.bill.selected_bill const sel = this.$store.state.bill.selected_bill;
.SupplierInvoiceID) var idx = _.findIndex(arrbill, item =>
item.type === sel.type && (
(sel.type === 'INVOICE' && item.SupplierInvoiceID == sel.SupplierInvoiceID) ||
(sel.type === 'DP' && item.DownpaymentID == sel.DownpaymentID) ||
(sel.type === 'INSTALLMENT' && item.InstallmentID == sel.InstallmentID)
)
);
this.$store.commit("paymentmanual/update_dialog_edit", false) this.$store.commit("paymentmanual/update_dialog_edit", false)
this.$store.commit("bill/update_selected_bill", {}) this.$store.commit("bill/update_selected_bill", {})
this.$store.dispatch("bill/search", { this.$store.dispatch("bill/search", {

View File

@@ -1231,8 +1231,14 @@
}, },
closeDialogDelete() { closeDialogDelete() {
let arrbill = this.$store.state.bill.bills let arrbill = this.$store.state.bill.bills
var idx = _.findIndex(arrbill, item => item.SupplierInvoiceID === this.$store.state.bill.selected_bill const sel = this.$store.state.bill.selected_bill;
.SupplierInvoiceID) var idx = _.findIndex(arrbill, item =>
item.type === sel.type && (
(sel.type === 'INVOICE' && item.SupplierInvoiceID == sel.SupplierInvoiceID) ||
(sel.type === 'DP' && item.DownpaymentID == sel.DownpaymentID) ||
(sel.type === 'INSTALLMENT' && item.InstallmentID == sel.InstallmentID)
)
);
this.$store.commit("paymentmanual/update_dialog_delete", false) this.$store.commit("paymentmanual/update_dialog_delete", false)
this.$store.commit("bill/update_selected_bill", {}) this.$store.commit("bill/update_selected_bill", {})
this.$store.dispatch("bill/search", { this.$store.dispatch("bill/search", {
@@ -1246,8 +1252,14 @@
}, },
closeDialogEdit() { closeDialogEdit() {
let arrbill = this.$store.state.bill.bills let arrbill = this.$store.state.bill.bills
var idx = _.findIndex(arrbill, item => item.SupplierInvoiceID === this.$store.state.bill.selected_bill const sel = this.$store.state.bill.selected_bill;
.SupplierInvoiceID) var idx = _.findIndex(arrbill, item =>
item.type === sel.type && (
(sel.type === 'INVOICE' && item.SupplierInvoiceID == sel.SupplierInvoiceID) ||
(sel.type === 'DP' && item.DownpaymentID == sel.DownpaymentID) ||
(sel.type === 'INSTALLMENT' && item.InstallmentID == sel.InstallmentID)
)
);
this.$store.commit("paymentmanual/update_dialog_edit", false) this.$store.commit("paymentmanual/update_dialog_edit", false)
this.$store.commit("bill/update_selected_bill", {}) this.$store.commit("bill/update_selected_bill", {})
this.$store.dispatch("bill/search", { this.$store.dispatch("bill/search", {

View File

@@ -19,7 +19,6 @@ export async function lookup_type(token) {
} }
} }
export async function lookup_banks(token) { export async function lookup_banks(token) {
try { try {
var resp = await axios.post(URL + 'payment/lookup_banks',{token:token}); var resp = await axios.post(URL + 'payment/lookup_banks',{token:token});
@@ -39,7 +38,6 @@ export async function lookup_banks(token) {
} }
} }
export async function lookup_accounts(token) { export async function lookup_accounts(token) {
try { try {
var resp = await axios.post(URL + 'payment/lookup_accounts',{token:token}); var resp = await axios.post(URL + 'payment/lookup_accounts',{token:token});
@@ -59,7 +57,6 @@ export async function lookup_accounts(token) {
} }
} }
export async function searchcard(token,prm) { export async function searchcard(token,prm) {
try { try {
var resp = await axios.post(URL + 'payment/searchcard',{token:token,search:prm}); var resp = await axios.post(URL + 'payment/searchcard',{token:token,search:prm});
@@ -98,6 +95,44 @@ export async function pay(prm) {
} }
} }
export async function payDownpayment(prm) {
try {
var resp = await axios.post(URL + 'payment/payDownpayment',prm);
if (resp.status != 200) {
return {
status: "ERR",
message: resp.statusText
};
}
let data = resp.data;
return data;
} catch (e) {
return {
status: "ERR",
message: e.message
};
}
}
export async function payInstallment(prm) {
try {
var resp = await axios.post(URL + 'payment/payInstallment',prm);
if (resp.status != 200) {
return {
status: "ERR",
message: resp.statusText
};
}
let data = resp.data;
return data;
} catch (e) {
return {
status: "ERR",
message: e.message
};
}
}
export async function editpay(prm) { export async function editpay(prm) {
try { try {
var resp = await axios.post(URL + 'payment/editpaymanual',prm); var resp = await axios.post(URL + 'payment/editpaymanual',prm);

View File

@@ -5,14 +5,14 @@
<v-menu class="xs3 pr-2" v-model="menustartdate" :close-on-content-click="false" :nudge-right="40" lazy transition="scale-transition" <v-menu class="xs3 pr-2" v-model="menustartdate" :close-on-content-click="false" :nudge-right="40" lazy transition="scale-transition"
offset-y full-width max-width="290px" min-width="290px"> offset-y full-width max-width="290px" min-width="290px">
<template v-slot:activator="{ on }"> <template v-slot:activator="{ on }">
<v-text-field class="mt-1" v-model="startDateFormatted" label="Tgl. Awal" outline readonly v-on="on" @blur="date = deFormatedDate(startDateFormatted)"></v-text-field> <v-text-field class="mt-1" v-model="startDateFormatted" label="Tgl. Awal" outline readonly v-on="on"></v-text-field>
</template> </template>
<v-date-picker v-model="init_sdate" no-title @input="menustartdate = false"></v-date-picker> <v-date-picker v-model="init_sdate" no-title @input="menustartdate = false"></v-date-picker>
</v-menu> </v-menu>
<v-menu class="xs3 pl-2" v-model="menuenddate" :close-on-content-click="false" :nudge-right="40" lazy transition="scale-transition" <v-menu class="xs3 pl-2" v-model="menuenddate" :close-on-content-click="false" :nudge-right="40" lazy transition="scale-transition"
offset-y full-width max-width="290px" min-width="290px"> offset-y full-width max-width="290px" min-width="290px">
<template v-slot:activator="{ on }"> <template v-slot:activator="{ on }">
<v-text-field class="mt-1" v-model="endDateFormatted" label="Tgl. Akhir" outline readonly v-on="on" @blur="date = deFormatedDate(endDateFormatted)"></v-text-field> <v-text-field class="mt-1" v-model="endDateFormatted" label="Tgl. Akhir" outline readonly v-on="on"></v-text-field>
</template> </template>
<v-date-picker v-model="init_edate" no-title @input="menuenddate = false"></v-date-picker> <v-date-picker v-model="init_edate" no-title @input="menuenddate = false"></v-date-picker>
</v-menu> </v-menu>
@@ -37,7 +37,7 @@
<template slot="items" slot-scope="props"> <template slot="items" slot-scope="props">
<td class="text-xs-left pa-2" v-bind:class="{'amber lighten-4':isSelected(props.item)}" @click="selectMe(props.item)">{{ props.item.tanggalbayar}}</td> <td class="text-xs-left pa-2" v-bind:class="{'amber lighten-4':isSelected(props.item)}" @click="selectMe(props.item)">{{ props.item.tanggalbayar}}</td>
<td class="text-xs-left pa-2" v-bind:class="{'amber lighten-4':isSelected(props.item)}" @click="selectMe(props.item)">{{ props.item.SupplierInvoiceNumber}} <td class="text-xs-left pa-2" v-bind:class="{'amber lighten-4':isSelected(props.item)}" @click="selectMe(props.item)">{{ props.item.SupplierInvoiceNumber}}
<p><v-btn v-if="props.item.SupplierInvoiceIsLunas === 'Y'" small color="success">Lunas</v-btn></p></td> <p><v-btn v-if="props.item.flaglunas === 'Y'" small color="success">Lunas</v-btn></p></td>
<td class="pa-2" v-bind:class="{'amber lighten-4':isSelected(props.item)}" @click="selectMe(props.item)">{{ props.item.SupplierPaymentNumber}} <td class="pa-2" v-bind:class="{'amber lighten-4':isSelected(props.item)}" @click="selectMe(props.item)">{{ props.item.SupplierPaymentNumber}}
<p style="color:#800000" class="mb-0 font-weight-bold caption">{{props.item.SupplierPaymentCashierNumber}}</p></td> <p style="color:#800000" class="mb-0 font-weight-bold caption">{{props.item.SupplierPaymentCashierNumber}}</p></td>
<td class="text-xs-left pa-2" v-bind:class="{'amber lighten-4':isSelected(props.item)}" @click="selectMe(props.item)">{{ props.item.SupplierName}}</td> <td class="text-xs-left pa-2" v-bind:class="{'amber lighten-4':isSelected(props.item)}" @click="selectMe(props.item)">{{ props.item.SupplierName}}</td>
@@ -110,7 +110,13 @@
return `${year}-${month.padStart(2, '0')}-${day.padStart(2, '0')}` return `${year}-${month.padStart(2, '0')}-${day.padStart(2, '0')}`
}, },
isSelected(p) { isSelected(p) {
return p.SupplierInvoiceID == this.$store.state.bill.selected_bill.SupplierInvoiceID const sel = this.$store.state.bill.selected_bill;
if (!sel || !sel.type) return false;
return p.type === sel.type && (
(sel.type === 'INVOICE' && p.SupplierInvoiceID == sel.SupplierInvoiceID) ||
(sel.type === 'DP' && p.DownpaymentID == sel.DownpaymentID) ||
(sel.type === 'INSTALLMENT' && p.InstallmentID == sel.InstallmentID)
);
}, },
convertMoney(money) { convertMoney(money) {
return one_money(money) return one_money(money)

View File

@@ -44,7 +44,6 @@
<v-layout style="border-top:1px dashed rgb(221,221,221)" row mt-1 mb-1></v-layout> <v-layout style="border-top:1px dashed rgb(221,221,221)" row mt-1 mb-1></v-layout>
<v-layout row mt-1 mb-1 pl-2 pr-2> <v-layout row mt-1 mb-1 pl-2 pr-2>
</v-layout> </v-layout>
</v-flex>
</v-card> </v-card>
<v-card> <v-card>
@@ -1165,16 +1164,23 @@
bills: this.$store.state.paymentmanual.selected_tagihan, bills: this.$store.state.paymentmanual.selected_tagihan,
totalbill : this.$store.state.bill.selected_bill.totalbill, totalbill : this.$store.state.bill.selected_bill.totalbill,
paid : this.$store.state.bill.selected_bill.paid, paid : this.$store.state.bill.selected_bill.paid,
tanggalbayar : this.xtanggalbayar tanggalbayar: this.xtanggalbayar,
type: this.$store.state.bill.selected_bill.type
} }
//console.log(prm.amount)
if (this.$store.state.bill.selected_bill.type == 'DP') {
prm.orderid = this.$store.state.bill.selected_bill.DownpaymentID
this.$store.dispatch("paymentmanual/payDownpayment", prm)
} else if (this.$store.state.bill.selected_bill.type == 'INSTALLMENT') {
prm.orderid = this.$store.state.bill.selected_bill.InstallmentID
this.$store.dispatch("paymentmanual/payInstallment", prm)
} else {
prm.orderid = this.$store.state.bill.selected_bill.SupplierInvoiceID
this.$store.dispatch("paymentmanual/pay", prm) this.$store.dispatch("paymentmanual/pay", prm)
}
}, },
async editpay() { async editpay() {
// alert(this.xbayar) // alert(this.xbayar)
if (this.in_saving) return; if (this.in_saving) return;
this.in_saving = true; this.in_saving = true;
var go_pay = true var go_pay = true
@@ -1183,11 +1189,20 @@
orderid: this.$store.state.bill.selected_bill.SupplierInvoiceID, orderid: this.$store.state.bill.selected_bill.SupplierInvoiceID,
headerid: this.$store.state.bill.selected_bill.SupplierPaymentID, headerid: this.$store.state.bill.selected_bill.SupplierPaymentID,
xnumber: this.$store.state.bill.selected_bill.SupplierPaymentNumber, xnumber: this.$store.state.bill.selected_bill.SupplierPaymentNumber,
tanggalbayar : this.xtanggalbayar tanggalbayar : this.xtanggalbayar,
type: this.$store.state.bill.selected_bill.type
} }
//console.log(prm.amount) //console.log(prm.amount)
if (this.$store.state.bill.selected_bill.type == 'DP') {
prm.orderid = this.$store.state.bill.selected_bill.DownpaymentID
this.$store.dispatch("paymentmanual/editpay", prm) this.$store.dispatch("paymentmanual/editpay", prm)
} else if (this.$store.state.bill.selected_bill.type == 'INSTALLMENT') {
prm.orderid = this.$store.state.bill.selected_bill.InstallmentID
this.$store.dispatch("paymentmanual/editpay", prm)
} else {
prm.orderid = this.$store.state.bill.selected_bill.SupplierInvoiceID
this.$store.dispatch("paymentmanual/editpay", prm)
}
}, },
deleteNote(note, idx) { deleteNote(note, idx) {

View File

@@ -210,6 +210,7 @@ export default {
context.commit("update_lookup_error_message", e.message) context.commit("update_lookup_error_message", e.message)
} }
}, },
async lookup_banks(context) { async lookup_banks(context) {
context.commit("bill/update_get_data_status", 1, { context.commit("bill/update_get_data_status", 1, {
root: true root: true
@@ -243,6 +244,7 @@ export default {
console.log(e) console.log(e)
} }
}, },
async lookup_accounts(context) { async lookup_accounts(context) {
context.commit("update_lookup_status", 1) context.commit("update_lookup_status", 1)
try { try {
@@ -264,6 +266,7 @@ export default {
context.commit("update_lookup_error_message", e.message) context.commit("update_lookup_error_message", e.message)
} }
}, },
async searchcard(context, prm) { async searchcard(context, prm) {
context.commit("update_lookup_status", 1) context.commit("update_lookup_status", 1)
try { try {
@@ -282,6 +285,7 @@ export default {
context.commit("update_lookup_status", 3) context.commit("update_lookup_status", 3)
} }
}, },
async pay(context, prm) { async pay(context, prm) {
context.commit("update_lookup_status", 1) context.commit("update_lookup_status", 1)
try { try {
@@ -312,6 +316,69 @@ export default {
context.commit("update_lookup_error_message", e.message) context.commit("update_lookup_error_message", e.message)
} }
}, },
async payDownpayment(context, prm) {
context.commit("update_lookup_status", 1)
try {
prm.token = one_token()
let resp = await api.payDownpayment(prm)
if (resp.status != "OK") {
context.commit("update_lookup_status", 3)
context.commit("update_lookup_error_message", resp.message)
} else {
context.commit("update_lookup_status", 2)
context.commit("update_lookup_error_message", "")
let data = {
records: resp.data.records.types,
total: resp.data.total
}
let xnumber = resp.data.records.data.numberx
let id = resp.data.records.data.idx
context.commit("update_disable_btn_pay", 'Y')
context.commit("update_idx", id)
context.commit("update_total_payment", 0)
context.commit("update_paynumber", "Payment Instruction nomor <span style='color:red'>" + xnumber + "</span> telah berhasil")
context.commit("update_dialog_pay_success", true)
context.commit("update_in_saving", false)
context.commit("update_xbayar", 0)
}
} catch (e) {
context.commit("update_lookup_status", 3)
context.commit("update_lookup_error_message", e.message)
}
},
async payInstallment(context, prm) {
context.commit("update_lookup_status", 1)
try {
prm.token = one_token()
let resp = await api.payInstallment(prm)
if (resp.status != "OK") {
context.commit("update_lookup_status", 3)
context.commit("update_lookup_error_message", resp.message)
} else {
context.commit("update_lookup_status", 2)
context.commit("update_lookup_error_message", "")
let data = {
records: resp.data.records.types,
total: resp.data.total
}
let xnumber = resp.data.records.data.numberx
let id = resp.data.records.data.idx
context.commit("update_disable_btn_pay", 'Y')
context.commit("update_idx", id)
context.commit("update_total_payment", 0)
context.commit("update_paynumber", "Payment Instruction nomor <span style='color:red'>" + xnumber + "</span> telah berhasil")
context.commit("update_dialog_pay_success", true)
context.commit("update_in_saving", false)
context.commit("update_xbayar", 0)
}
} catch (e) {
context.commit("update_lookup_status", 3)
context.commit("update_lookup_error_message", e.message)
}
},
async editpay(context, prm) { async editpay(context, prm) {
context.commit("update_lookup_status", 1) context.commit("update_lookup_status", 1)
try { try {
@@ -342,6 +409,7 @@ export default {
context.commit("update_lookup_error_message", e.message) context.commit("update_lookup_error_message", e.message)
} }
}, },
async edit_note(context, prm) { async edit_note(context, prm) {
context.commit("update_lookup_status", 1) context.commit("update_lookup_status", 1)
try { try {
@@ -363,6 +431,7 @@ export default {
context.commit("update_lookup_error_message", e.message) context.commit("update_lookup_error_message", e.message)
} }
}, },
async delete_note(context, prm) { async delete_note(context, prm) {
context.commit("update_lookup_status", 1) context.commit("update_lookup_status", 1)
try { try {
@@ -384,6 +453,7 @@ export default {
context.commit("update_lookup_error_message", e.message) context.commit("update_lookup_error_message", e.message)
} }
}, },
async selectpaymenttype(context,payload) { async selectpaymenttype(context,payload) {
context.commit("bill/update_get_data_status", 1, { context.commit("bill/update_get_data_status", 1, {
root: true root: true
@@ -421,6 +491,7 @@ export default {
console.log(e) console.log(e)
} }
}, },
async selectpaymenttypeold(context) { async selectpaymenttypeold(context) {
context.commit("bill/update_get_data_status", 1, { context.commit("bill/update_get_data_status", 1, {
root: true root: true
@@ -456,6 +527,7 @@ export default {
console.log(e) console.log(e)
} }
}, },
async selectcard(context) { async selectcard(context) {
context.commit("bill/update_get_data_status", 1, { context.commit("bill/update_get_data_status", 1, {
root: true root: true
@@ -488,6 +560,7 @@ export default {
console.log(e) console.log(e)
} }
}, },
async selectedc(context) { async selectedc(context) {
context.commit("bill/update_get_data_status", 1, { context.commit("bill/update_get_data_status", 1, {
root: true root: true

View File

@@ -84,13 +84,24 @@
{{ props.item.SuratJalanStatus }} {{ props.item.SuratJalanStatus }}
</v-chip> </v-chip>
</td> </td>
<td class="text-xs-center pa-2"> <td class="text-xs-center pa-2" style="white-space: nowrap;">
<v-icon <v-btn
small @click="deleteSJ(props.item)" color="red" style="min-width: 25px; height: 25px; margin: 0;"
@click="deleteSJ(props.item)"
small title="Hapus"
color="red"
:disabled="props.item.SuratJalanStatus != 'Draft'" :disabled="props.item.SuratJalanStatus != 'Draft'"
> >
delete <v-icon small color="white">delete</v-icon>
</v-icon> </v-btn>
<v-btn
style="min-width: 25px; height: 25px; margin: 0;"
@click="printout(props.item)"
small title="Cetak PDF"
color="primary"
>
<v-icon small color="white">print</v-icon>
</v-btn>
</td> </td>
</tr> </tr>
</template> </template>
@@ -100,18 +111,33 @@
<v-pagination v-model="paginat" :length="paginat_len" :total-visible="5"></v-pagination> <v-pagination v-model="paginat" :length="paginat_len" :total-visible="5"></v-pagination>
</div> </div>
</v-card> </v-card>
<one-dialog-print
:title="printtitle"
:width="printwidth"
:height="600"
:status="openprint"
:urlprint="urlprint"
@close-dialog-print="openprint = false"
></one-dialog-print>
</v-layout> </v-layout>
</template> </template>
<script> <script>
module.exports = { module.exports = {
components: {}, components: {
"one-dialog-print": httpVueLoader("../../common/oneDialogPrintX.vue"),
},
mounted() { mounted() {
this.$store.dispatch("suratjalan/getBranches"); this.$store.dispatch("suratjalan/getBranches");
this.$store.dispatch("suratjalan/listingSuratJalan"); this.$store.dispatch("suratjalan/listingSuratJalan");
}, },
data() { data() {
return { return {
urlprint: "",
printtitle: "",
printwidth: "60%",
openprint: false,
menuStartDate: false, menuStartDate: false,
menuEndDate: false, menuEndDate: false,
headers: [ headers: [
@@ -287,6 +313,15 @@
}, },
newForm() { newForm() {
this.$store.dispatch("suratjalan/newForm") this.$store.dispatch("suratjalan/newForm")
},
printout(val) {
this.printwidth = "60%";
this.printtitle = "";
let user = one_user();
let username = user && user.M_StaffName ? user.M_StaffName : "";
let tm = Date.now();
this.urlprint = BASE_URL + "/one-api/report/rpt_surat_jalan/pdf?id=" + val.SuratJalanID + "&username=" + username + "&tm=" + tm;
this.openprint = true;
} }
}, },
watch: { watch: {