392 lines
16 KiB
Vue
392 lines
16 KiB
Vue
<template>
|
|
<v-dialog v-model="dialog_form_realise" persistent width="50vw">
|
|
<v-card>
|
|
<v-card-title class="headline grey lighten-2" primary-title>
|
|
FORM REALISASI
|
|
</v-card-title>
|
|
|
|
<v-card-text>
|
|
<v-layout row wrap>
|
|
<v-flex xs12 class="mb-2">
|
|
<v-textarea
|
|
filled outline hide-details label="Catatan*"
|
|
rows="3" v-model="xnote"
|
|
></v-textarea>
|
|
<p v-show="checkErrorForm('requireNote')" class="error">Catatan harus diisi</p>
|
|
</v-flex>
|
|
|
|
<v-flex xs3 class="pr-1">
|
|
<v-text-field
|
|
prefix="Rp." v-model="formated_total_price" outline
|
|
label="Total Bayar" hide-details readonly
|
|
></v-text-field>
|
|
</v-flex>
|
|
<v-flex xs3 class="px-1">
|
|
<v-text-field
|
|
prefix="Rp." v-model="formatted_adj_price" outline
|
|
readonly hide-details label="Tambahan"
|
|
></v-text-field>
|
|
</v-flex>
|
|
<v-flex xs3 class="px-1">
|
|
<v-text-field
|
|
prefix="Rp." v-model="formated_rest_price" outline
|
|
readonly hide-details label="Harga"
|
|
></v-text-field>
|
|
</v-flex>
|
|
<v-flex xs3 class="pl-1">
|
|
<v-text-field
|
|
prefix="Rp." v-model="formated_sisa_price" outline
|
|
readonly hide-details label="Sisa"
|
|
></v-text-field>
|
|
</v-flex>
|
|
</v-layout>
|
|
|
|
<v-expansion-panel class="mt-4">
|
|
<v-expansion-panel-content v-for="(item, index) in listing_item_realise" :key="index">
|
|
<template v-slot:header>
|
|
<div>{{ item.PurchaseRequestDirectDescription }}</div>
|
|
</template>
|
|
<v-card>
|
|
<v-card-text>
|
|
<v-layout row wrap>
|
|
<v-flex xs3 class="pr-1">
|
|
<p class="mb-0">{{ item.PurchaseRequestDirectNumber }}</p>
|
|
</v-flex>
|
|
<v-flex xs3 class="px-1">
|
|
<p class="mb-0">{{ item.PurchaseRequestDirectDescription }}</p>
|
|
<p class="mb-0 font-weight-bold" style="color:#000000">
|
|
Kategori: {{ item.PurchaseDirectCategoryName }}
|
|
</p>
|
|
</v-flex>
|
|
<v-flex xs3>
|
|
<p class="mb-0">Harga Estimasi: </p>
|
|
<p class="mb-0">Rp. {{ oneMoney(item.estimate_price) }}</p>
|
|
</v-flex>
|
|
<v-flex xs3 class="pl-1">
|
|
<v-text-field
|
|
prefix="Rp" v-model="item.realised_price"
|
|
outline hide-details label="Harga Realisasi"
|
|
@input="processMoney()"
|
|
></v-text-field>
|
|
</v-flex>
|
|
<v-flex xs12 style="border:1px solid black" class="pa-2 mt-2">
|
|
<input
|
|
type="file" id="files" ref="files"
|
|
accept="image/*" multiple
|
|
v-on:change="onFilePicked(item, $event)"
|
|
/>
|
|
</v-flex>
|
|
<v-flex
|
|
v-for="(nota) in item.prevNota"
|
|
xs4 class="pa-2" :key="nota.nota_id"
|
|
>
|
|
<div class="image-container">
|
|
<v-img
|
|
:src="makeImgUrl(nota)" aspect-ratio="1" contain
|
|
class="grey lighten-2" @click="viewImage(makeImgUrl(nota))"
|
|
></v-img>
|
|
</div>
|
|
</v-flex>
|
|
<v-flex
|
|
v-for="(url, index) in item.attachPreview"
|
|
xs4 class="pa-2" :key="index"
|
|
>
|
|
<div class="image-container">
|
|
<v-img
|
|
:src="url" aspect-ratio="1" contain
|
|
class="grey lighten-2" @click="viewImage(url)"
|
|
></v-img>
|
|
<v-icon
|
|
color="red"
|
|
class="close-button"
|
|
@click="removeImage(index, item)"
|
|
>
|
|
close
|
|
</v-icon>
|
|
</div>
|
|
</v-flex>
|
|
</v-layout>
|
|
</v-card-text>
|
|
</v-card>
|
|
</v-expansion-panel-content>
|
|
</v-expansion-panel>
|
|
</v-card-text>
|
|
|
|
<v-card-actions>
|
|
<v-spacer></v-spacer>
|
|
<v-btn
|
|
color="error" flat outline
|
|
@click="closeFormRealise()"
|
|
>Tutup</v-btn>
|
|
<v-btn
|
|
color="primary" dark
|
|
@click="realiseForm()"
|
|
>Simpan & Realisasi</v-btn>
|
|
</v-card-actions>
|
|
</v-card>
|
|
</v-dialog>
|
|
</template>
|
|
|
|
<style>
|
|
.close-button {
|
|
position: absolute;
|
|
top: 5px;
|
|
right: 5px;
|
|
z-index: 1;
|
|
cursor: pointer;
|
|
}
|
|
.image-container {
|
|
position: relative;
|
|
padding-bottom: 35px;
|
|
}
|
|
</style>
|
|
|
|
<script>
|
|
module.exports = {
|
|
data() {
|
|
return {
|
|
store_temp_attach: {},
|
|
penyesuaian: 0
|
|
}
|
|
},
|
|
computed: {
|
|
dialog_form_realise: {
|
|
get() {
|
|
return this.$store.state.cashier.dialog_cashier;
|
|
},
|
|
set(val) {
|
|
this.$store.commit("cashier/update_dialog_cashier", val);
|
|
}
|
|
},
|
|
xnote: {
|
|
get() {
|
|
return this.$store.state.cashier.note
|
|
},
|
|
set(val) {
|
|
this.$store.commit("cashier/update_note", val)
|
|
}
|
|
},
|
|
formated_total_price() {
|
|
const price = this.$store.state.cashier.selected_cashier
|
|
if (price.PaymentVoucherTotal) {
|
|
return this.oneMoney(price.PaymentVoucherTotal)
|
|
}
|
|
return this.oneMoney(0)
|
|
},
|
|
formated_rest_price() {
|
|
let rest = this.$store.state.cashier.restPrice || 0
|
|
return this.oneMoney(rest)
|
|
},
|
|
formated_sisa_price() {
|
|
let sisa = this.$store.state.cashier.total_akhir || 0
|
|
return this.oneMoney(sisa)
|
|
},
|
|
formatted_adj_price() {
|
|
return this.oneMoney(this.calcAdjustmentMoney());
|
|
},
|
|
selected_cashier() {
|
|
return this.$store.state.cashier.selected_cashier;
|
|
},
|
|
listing_item_realise: {
|
|
get() {
|
|
return this.$store.state.cashier.listing_item_realise
|
|
},
|
|
set(val) {
|
|
this.$store.commit("cashier/update_listing_item_realise", val);
|
|
}
|
|
},
|
|
detail_voucher() {
|
|
return this.$store.state.cashier.details;
|
|
},
|
|
dialog_error: {
|
|
get() {
|
|
return this.$store.state.cashier.alert_error;
|
|
},
|
|
set(val) {
|
|
this.$store.commit("cashier/update_alert_error", val);
|
|
},
|
|
},
|
|
msgError: {
|
|
get() {
|
|
return this.$store.state.cashier.error_message;
|
|
},
|
|
set(val) {
|
|
this.$store.commit("cashier/update_error_message", val);
|
|
}
|
|
},
|
|
},
|
|
methods: {
|
|
roundToThreeSignificantDigits(digit) {
|
|
const num = parseInt(digit, 10)
|
|
if (isNaN(num) || num <= 0) {
|
|
return '00';
|
|
}
|
|
|
|
const scale = 10 ** digit.length;
|
|
const decimal = num / scale
|
|
return Math.round(decimal * 100);
|
|
},
|
|
oneMoney(value) {
|
|
let splitValue = value.toString().split(".");
|
|
|
|
if(splitValue.length > 1) {
|
|
let val = splitValue[0]
|
|
return val.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ".") + "," + this.roundToThreeSignificantDigits(splitValue[1]);
|
|
} else {
|
|
return value.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ".");
|
|
}
|
|
},
|
|
processMoney() {
|
|
let data = JSON.parse(JSON.stringify(this.listing_item_realise))
|
|
let realised = 0
|
|
data.forEach(element => {
|
|
if (!element.realised_price) {
|
|
element.realised_price = 0
|
|
}
|
|
|
|
realised = realised + Number(element.realised_price)
|
|
element.realised_price = Number(element.realised_price)
|
|
});
|
|
|
|
this.listing_item_realise = data
|
|
|
|
let adjusment = this.calcAdjustmentMoney();
|
|
let total = Number(this.selected_cashier.PaymentVoucherTotal) + adjusment
|
|
let sisa = total - realised
|
|
|
|
this.$store.commit("cashier/update_restPrice", realised)
|
|
this.$store.commit("cashier/update_total_akhir", sisa)
|
|
},
|
|
checkErrorForm(val) {
|
|
let errors = this.$store.state.cashier.errors;
|
|
if (errors.includes(val)) {
|
|
return true
|
|
} else {
|
|
return false
|
|
}
|
|
},
|
|
onFilePicked(item, event) {
|
|
const files = event.target.files;
|
|
|
|
if (files.length == 0) {
|
|
return
|
|
}
|
|
|
|
if (!this.store_temp_attach[item.detail_id]) {
|
|
this.$set(this.store_temp_attach, item.detail_id, {
|
|
files: []
|
|
})
|
|
}
|
|
|
|
for (let index = 0; index < files.length; index++) {
|
|
const file = files[index];
|
|
const url = URL.createObjectURL(file);
|
|
|
|
this.store_temp_attach[item.detail_id].files.push(file);
|
|
item.attachFiles.push(file);
|
|
item.attachPreview.push(url);
|
|
}
|
|
event.target.value = null;
|
|
},
|
|
removeImage(index, item) {
|
|
URL.revokeObjectURL(item.attachPreview[index])
|
|
item.attachPreview.splice(index, 1)
|
|
item.attachFiles.splice(index, 1)
|
|
|
|
// remove that in local
|
|
const filestore = this.store_temp_attach[item.detail_id];
|
|
if (filestore && filestore.files.length > index) {
|
|
filestore.files.splice(index, 1);
|
|
}
|
|
},
|
|
viewImage(url) {
|
|
this.$store.commit("cashier/update_selected_img_view", url)
|
|
this.$store.commit("cashier/update_dialog_view_img", true)
|
|
},
|
|
makeImgUrl(nota) {
|
|
const imgbase_url = BASE_URL + "/one-media/cashier/";
|
|
return imgbase_url + nota.img_url
|
|
},
|
|
calcAdjustmentMoney() {
|
|
const detail = this.detail_voucher
|
|
const adj_val = detail.reduce((sum, item) => sum + Number(item.PurchaseRequestDirectAdjustment), 0)
|
|
return adj_val;
|
|
},
|
|
closeFormRealise() {
|
|
this.store_temp_attach = {}
|
|
this.listing_item_realise = []
|
|
this.$store.commit("cashier/update_selected_cashier", {})
|
|
this.dialog_form_realise = false
|
|
},
|
|
realiseForm() {
|
|
let detail = this.detail_voucher
|
|
const nota_pending = detail.filter(element => element.PurchaseRequestDirectNotaStatus == 'Pending');
|
|
if (nota_pending.length > 0) {
|
|
const req_number = nota_pending.map(item => item.PurchaseRequestDirectNumber).join(',');
|
|
this.dialog_error = true;
|
|
this.msgError = 'Terdapat nota yang belum di-approve pada ' + req_number;
|
|
return;
|
|
}
|
|
|
|
const voucher = this.selected_cashier
|
|
if (voucher.PaymentVoucherRealitationApproved == 'N') {
|
|
this.dialog_error = true;
|
|
this.msgError = 'Voucher ini belum di approve realisasi oleh kacab';
|
|
return;
|
|
}
|
|
|
|
this.$store.commit("cashier/update_errors", []);
|
|
var errors = this.$store.state.cashier.errors;
|
|
if (_.isEmpty(this.xnote)) {
|
|
errors.push('requireNote')
|
|
}
|
|
if (errors.length === 0) {
|
|
var formData = new FormData()
|
|
|
|
const dataSerialize = JSON.parse(JSON.stringify(this.listing_item_realise));
|
|
let allFiles = [];
|
|
|
|
let notanotfound = [];
|
|
dataSerialize.forEach(item => {
|
|
const detail_id = item.detail_id;
|
|
const file = this.store_temp_attach[detail_id] ? this.store_temp_attach[detail_id].files : []
|
|
|
|
item.fileCount = file.length;
|
|
allFiles = allFiles.concat(file);
|
|
|
|
if (item.attachFiles.length < 1) {
|
|
if (item.prevNota.length < 1) {
|
|
notanotfound.push(item.PurchaseRequestDirectDescription);
|
|
}
|
|
}
|
|
|
|
delete item.attachFiles;
|
|
delete item.attachPreview;
|
|
});
|
|
|
|
if (notanotfound.length > 0) {
|
|
const nonota = notanotfound.join(", ");
|
|
this.dialog_error = true;
|
|
this.msgError = 'Belum ada nota realisasi pada barang berikut: ' + nonota;
|
|
return;
|
|
}
|
|
|
|
formData.append("data", JSON.stringify(dataSerialize));
|
|
allFiles.forEach(file => {
|
|
formData.append("files[]", file);
|
|
});
|
|
|
|
formData.append("token", one_token())
|
|
formData.append("note", this.xnote)
|
|
formData.append("restPrice", this.$store.state.cashier.restPrice)
|
|
formData.append("ID", this.$store.state.cashier.selected_cashier.PaymentVoucherID)
|
|
|
|
this.$store.dispatch("cashier/update", formData);
|
|
}
|
|
},
|
|
},
|
|
watch: {
|
|
|
|
},
|
|
}
|
|
</script> |