mirror of
https://gitlab.com/CIEFWorldwideSdnBhd/exchange-2.0.git
synced 2026-08-19 04:23:55 +00:00
250 lines
21 KiB
Vue
250 lines
21 KiB
Vue
<template>
|
|
<div class="row">
|
|
<div class="col">
|
|
<div class="row no-margin">
|
|
<div class="col p-t-25 p-t-25">
|
|
<div class="row">
|
|
<div class="col p-b-10 b-b b-grey">
|
|
<div class="row align-items-center">
|
|
<div class="col-auto p-r-0" style="min-width: 40px;">
|
|
<div class="font-heading all-caps fs-10"></div>
|
|
</div>
|
|
<div class="col p-r-5">
|
|
<div class="font-heading all-caps fs-10 muted">Stock Code</div>
|
|
</div>
|
|
<div class="col-4 p-r-5 p-l-5">
|
|
<div class="font-heading all-caps fs-10 muted">description</div>
|
|
</div>
|
|
<div class="col text-center p-r-5 p-l-5">
|
|
<div class="font-heading all-caps fs-10 muted">quantity</div>
|
|
</div>
|
|
<div class="col text-center p-r-5 p-l-5">
|
|
<div class="font-heading all-caps fs-10 muted">Unit Price</div>
|
|
</div>
|
|
<div class="col-1 text-center p-r-5 p-l-5">
|
|
<div class="font-heading all-caps fs-10 muted"></div>
|
|
</div>
|
|
<div class="col-1 text-right p-r-5 p-l-5">
|
|
<div class="font-heading all-caps fs-10 muted">Total</div>
|
|
</div>
|
|
<div class="col-auto text-center">
|
|
<button class="btn btn-xs btn-outline-success b-rad-none invisible"><i class="fa fa-check"></i></button>
|
|
<button class="btn btn-xs btn-outline-success b-rad-none invisible"><i class="fa fa-pencil"></i></button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="row m-b-20">
|
|
<div class="col">
|
|
<div class="row" v-if="!submitted">
|
|
<div class="col p-b-5 p-t-5 b-b b-grey">
|
|
<div class="row align-items-center">
|
|
<div class="col-auto p-r-0" style="min-width: 40px;">
|
|
<div class="font-heading all-caps fs-10"></div>
|
|
</div>
|
|
<div class="col p-r-5">
|
|
<input type="text" class="form-control fs-10 b-rad-none" placeholder="Stock Code" v-model="product.stockCode" />
|
|
</div>
|
|
<div class="col-4 p-r-5 p-l-5">
|
|
<textarea class="form-control fs-10 b-rad-none" placeholder="Description" rows="1" @keyup="onlyEnglish($event)" v-model="product.description"></textarea>
|
|
</div>
|
|
<div class="col text-center p-r-5 p-l-5">
|
|
<input type="text" class="form-control fs-10 b-rad-none text-center" placeholder="Quantity" v-model.lazy="product.quantity" v-mask="'#########'"/>
|
|
</div>
|
|
<div class="col text-center p-r-5 p-l-5">
|
|
<input type="text" class="form-control fs-10 b-rad-none text-center" placeholder="Unit Price" v-model.lazy="product.unit_price" v-money="productPrice" />
|
|
</div>
|
|
<div class="col-1 text-center p-r-5 p-l-5">
|
|
<div class="font-heading all-caps fs-10">{{data.fixed_currency.short_code}}</div>
|
|
</div>
|
|
<div class="col-1 text-right p-r-5 p-l-5">
|
|
<div class="font-heading all-caps fs-10">{{(Math.round((productTotal + Number.EPSILON) * 100) / 100).toFixed(2) }}</div>
|
|
</div>
|
|
<div class="col-auto">
|
|
<button class="btn btn-xs btn-outline-success b-rad-none" @click="addProduct()"><i class="fa fa-check"></i></button>
|
|
<button class="btn btn-xs btn-outline-success b-rad-none invisible"><i class="fa fa-pencil"></i></button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="row" v-for="(product, index) in products">
|
|
<div class="col p-b-10 p-t-10 b-b b-grey">
|
|
<purchase-order-item-form-component :data="product" :index="index" :currency="data.fixed_currency.short_code" :editable="!submitted" :section="section" @change="updateProduct($event, index)" v-on:remove="removeProduct(index)"></purchase-order-item-form-component>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="row">
|
|
<div class="col-7">
|
|
<div class="row" v-if="(Math.round((poTotal + Number.EPSILON) * 1000) / 1000).toFixed(3) > (Math.round((data.amount + Number.EPSILON) * 1000) / 1000).toFixed(3)">
|
|
<div class="col">
|
|
<div class="alert alert-warning padding-15" role="alert" v-if="false">
|
|
<div class="font-heading fs-12 all-caps bold m-b-15">Can't Complete Your Purchase Order ?</div>
|
|
<div class="row m-b-15">
|
|
<div class="col">
|
|
<div class="font-heading fs-10 m-b-10">If your Purchase Order total amount doesn't match your transfer total amount we are unable to confirm your purchase order and generate the invoice for you, this usually happen when you pay for your purchase order with multiple transfer orders.</div>
|
|
<div class="font-heading fs-10">But don't worry you can always merge your transfer orders into one to complete your purchase order successfully and generate your invoice.</div>
|
|
</div>
|
|
</div>
|
|
<!--link to merge: route('booking.merge',this.data.marking) -->
|
|
<a class="btn btn-xs all-caps b-rad-none btn-warning" href="#">Merge Transfer Orders</a>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="col-5" v-if="data.company.address">
|
|
<div class="row align-items-end p-t-10 p-b-10">
|
|
<div class="col">
|
|
<div class="font-heading all-caps fs-12 bold">Total:</div>
|
|
</div>
|
|
<div class="col-auto text-right">
|
|
<div class="font-heading muted"><span v-if="!submitted" class="bold m-r-5" :class="[{'text-danger' : (Math.round((poTotal + Number.EPSILON) * 1000) / 1000).toFixed(3) !== (Math.round((data.amount + Number.EPSILON) * 1000) / 1000).toFixed(3)}, {'text-success' : (Math.round((this.poTotal + Number.EPSILON) * 1000) / 1000).toFixed(3) === (Math.round((this.data.amount + Number.EPSILON) * 1000) / 1000).toFixed(3)}]">{{(Math.round(( poTotal + Number.EPSILON) * 1000) / 1000).toFixed(3)}}/</span><span class="text-primary bold m-l-5">{{(Math.round((data.amount + Number.EPSILON) * 1000) / 1000).toFixed(3)}} {{data.fixed_currency.short_code}}</span></div>
|
|
</div>
|
|
</div>
|
|
<div class="row" v-if="poTotal > 0 && !submitted">
|
|
<div class="col">
|
|
<div class="row m-b-10">
|
|
<div class="col">
|
|
<button class="btn btn-xs all-caps b-rad-none btn-primary btn-block" @click="submitForm()">{{(Math.round((poTotal + Number.EPSILON) * 1000) / 1000).toFixed(3) !== (Math.round((data.amount + Number.EPSILON) * 1000) / 1000).toFixed(3) ? 'Save Purchase Order' : 'Save & Confirm'}}</button>
|
|
</div>
|
|
</div>
|
|
<div class="row" v-if="(Math.round((poTotal + Number.EPSILON) * 1000) / 1000).toFixed(3) !== data.amount">
|
|
<div class="col">
|
|
<div class="fs-10">** you purchase order will be saved but wont be approved until your <span class="text-danger bold all-caps">purchase order's total</span> matches your <span class="text-success bold all-caps">transfer order's total</span>.</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="row" v-if="submitted && data.status !== 3">
|
|
<div class="col-12 col-md-7">
|
|
<div class="row m-b-15">
|
|
<div class="col">
|
|
<button class="btn btn-xs btn-success b-rad-none" v-if="$store.getters.isAdmin && data.purchase_order.status === 1" @click="submit(route('api.booking.po.approval', data.id), 'post', section, true, true)">Approve Purchase Order</button>
|
|
</div>
|
|
</div>
|
|
<div class="row">
|
|
<div class="col-12 col-lg-6">
|
|
<document-file-viewer-component :file="data.documents.proforma_invoice.files[0]" v-if="data.documents.proforma_invoice">
|
|
<template slot="button">
|
|
<div class="text-center b-a b-info b-dashed b-thick padding-20 pointer m-b-10">
|
|
<div class="m-b-10">
|
|
<svg xmlns="http://www.w3.org/2000/svg" x="0px" y="0px"
|
|
width="45" height="45"
|
|
viewBox="0 0 172 172"
|
|
style=" fill:#000000;"><defs><linearGradient x1="118.25" y1="63.41425" x2="118.25" y2="88.92669" gradientUnits="userSpaceOnUse" id="color-1_Ya7GVcPz6Vqb_gr1"><stop offset="0" stop-color="#4ec9ff"></stop><stop offset="1" stop-color="#2bffe6"></stop></linearGradient><linearGradient x1="72.5625" y1="20.87113" x2="72.5625" y2="158.79631" gradientUnits="userSpaceOnUse" id="color-2_Ya7GVcPz6Vqb_gr2"><stop offset="0" stop-color="#009add"></stop><stop offset="1" stop-color="#00baa4"></stop></linearGradient><linearGradient x1="56.4375" y1="20.87113" x2="56.4375" y2="158.79631" gradientUnits="userSpaceOnUse" id="color-3_Ya7GVcPz6Vqb_gr3"><stop offset="0" stop-color="#009add"></stop><stop offset="1" stop-color="#00baa4"></stop></linearGradient><linearGradient x1="45.6875" y1="20.87113" x2="45.6875" y2="158.79631" gradientUnits="userSpaceOnUse" id="color-4_Ya7GVcPz6Vqb_gr4"><stop offset="0" stop-color="#009add"></stop><stop offset="1" stop-color="#00baa4"></stop></linearGradient><linearGradient x1="69.875" y1="20.87113" x2="69.875" y2="158.79631" gradientUnits="userSpaceOnUse" id="color-5_Ya7GVcPz6Vqb_gr5"><stop offset="0" stop-color="#009add"></stop><stop offset="1" stop-color="#00baa4"></stop></linearGradient><linearGradient x1="80.625" y1="20.87113" x2="80.625" y2="158.79631" gradientUnits="userSpaceOnUse" id="color-6_Ya7GVcPz6Vqb_gr6"><stop offset="0" stop-color="#009add"></stop><stop offset="1" stop-color="#00baa4"></stop></linearGradient><linearGradient x1="91.375" y1="20.87113" x2="91.375" y2="158.79631" gradientUnits="userSpaceOnUse" id="color-7_Ya7GVcPz6Vqb_gr7"><stop offset="0" stop-color="#009add"></stop><stop offset="1" stop-color="#00baa4"></stop></linearGradient><linearGradient x1="86" y1="20.87113" x2="86" y2="158.79631" gradientUnits="userSpaceOnUse" id="color-8_Ya7GVcPz6Vqb_gr8"><stop offset="0" stop-color="#009add"></stop><stop offset="1" stop-color="#00baa4"></stop></linearGradient><linearGradient x1="52.40625" y1="20.87113" x2="52.40625" y2="158.79631" gradientUnits="userSpaceOnUse" id="color-9_Ya7GVcPz6Vqb_gr9"><stop offset="0" stop-color="#009add"></stop><stop offset="1" stop-color="#00baa4"></stop></linearGradient></defs><g fill="none" fill-rule="nonzero" stroke="none" stroke-width="1" stroke-linecap="butt" stroke-linejoin="miter" stroke-miterlimit="10" stroke-dasharray="" stroke-dashoffset="0" font-family="none" font-weight="none" font-size="none" text-anchor="none" style="mix-blend-mode: normal"><path d="M0,172v-172h172v172z" fill="none"></path><g id="Layer_1"><circle cx="44" cy="30" transform="scale(2.6875,2.6875)" r="4" fill="url(#color-1_Ya7GVcPz6Vqb_gr1)"></circle><rect x="12" y="14" transform="scale(2.6875,2.6875)" width="30" height="2" fill="url(#color-2_Ya7GVcPz6Vqb_gr2)"></rect><path d="M80.625,102.125v-43c0,-2.95625 -2.41875,-5.375 -5.375,-5.375h-37.625c-2.95625,0 -5.375,2.41875 -5.375,5.375v43c0,2.95625 2.41875,5.375 5.375,5.375h37.625c2.95625,0 5.375,-2.41875 5.375,-5.375zM53.75,102.125h-16.125v-10.75h16.125zM53.75,86h-16.125v-10.75h16.125zM53.75,69.875h-16.125v-10.75h16.125zM75.25,102.125h-16.125v-10.75h16.125zM75.25,86h-16.125v-10.75h16.125zM75.25,69.875h-16.125v-10.75h16.125z" fill="url(#color-3_Ya7GVcPz6Vqb_gr3)"></path><rect x="12" y="47" transform="scale(2.6875,2.6875)" width="10" height="2" fill="url(#color-4_Ya7GVcPz6Vqb_gr4)"></rect><rect x="25" y="47" transform="scale(2.6875,2.6875)" width="2" height="2" fill="url(#color-5_Ya7GVcPz6Vqb_gr5)"></rect><rect x="29" y="47" transform="scale(2.6875,2.6875)" width="2" height="2" fill="url(#color-6_Ya7GVcPz6Vqb_gr6)"></rect><rect x="33" y="47" transform="scale(2.6875,2.6875)" width="2" height="2" fill="url(#color-7_Ya7GVcPz6Vqb_gr7)"></rect><path d="M141.3625,73.90625c-1.88125,-6.45 -6.45,-11.825 -12.3625,-14.78125v-34.9375c0,-4.56875 -3.49375,-8.0625 -8.0625,-8.0625h-96.75c-4.56875,0 -8.0625,3.49375 -8.0625,8.0625v110.1875v2.6875v10.75c0,4.56875 3.49375,8.0625 8.0625,8.0625h96.75c4.56875,0 8.0625,-3.49375 8.0625,-8.0625v-10.75v-22.30625c1.6125,0.5375 3.49375,0.80625 5.375,0.80625c11.825,0 21.5,-9.675 21.5,-21.5c0,-9.1375 -5.9125,-17.2 -14.5125,-20.15625zM137.0625,80.625c0,10.48125 -8.33125,18.8125 -18.8125,18.8125c-10.48125,0 -18.8125,-8.33125 -18.8125,-18.8125c0,-10.48125 8.33125,-18.8125 18.8125,-18.8125c10.48125,0 18.8125,8.33125 18.8125,18.8125zM123.625,147.8125c0,1.6125 -1.075,2.6875 -2.6875,2.6875h-96.75c-1.6125,0 -2.6875,-1.075 -2.6875,-2.6875v-3.225c0.80625,0.26875 1.6125,0.5375 2.6875,0.5375h96.75c1.075,0 1.88125,-0.26875 2.6875,-0.5375zM123.625,134.375v2.6875c0,1.6125 -1.075,2.6875 -2.6875,2.6875h-96.75c-1.6125,0 -2.6875,-1.075 -2.6875,-2.6875v-2.6875v-110.1875c0,-1.6125 1.075,-2.6875 2.6875,-2.6875h96.75c1.6125,0 2.6875,1.075 2.6875,2.6875v32.7875c-1.6125,-0.26875 -3.49375,-0.5375 -5.375,-0.5375c-13.4375,0 -24.1875,10.75 -24.1875,24.1875c0,12.3625 9.40625,22.84375 21.76875,24.1875c1.88125,3.49375 4.56875,6.18125 7.79375,8.0625zM134.375,110.1875c-4.8375,0 -9.1375,-2.15 -12.3625,-5.64375c11.55625,-1.88125 20.425,-11.825 20.425,-23.91875c0,-0.26875 0,-0.26875 0,-0.5375c4.8375,2.95625 8.0625,8.0625 8.0625,13.975c0,8.86875 -7.25625,16.125 -16.125,16.125z" fill="url(#color-8_Ya7GVcPz6Vqb_gr8)"></path><rect x="12" y="43" transform="scale(2.6875,2.6875)" width="15" height="2" fill="url(#color-9_Ya7GVcPz6Vqb_gr9)"></rect></g></g></svg>
|
|
</div>
|
|
<p class="no-margin fs-12">Proforma Invoice</p>
|
|
</div>
|
|
</template>
|
|
</document-file-viewer-component>
|
|
<button class="btn btn-xs btn-danger b-rad-none btn-block" v-if="data.documents.proforma_invoice" @click="submit(route('api.booking.proforma.create', data.id), 'post', section, true, true)">Regenerate Proforma Invoice</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="col" v-if="submitted">
|
|
<div class="alert alert-success padding-15" role="alert">
|
|
<div class="font-heading fs-12 all-caps bold m-b-15">Your Purchase Order {{data.purchase_order.status === 1 ? 'is Being Processed for Verification' : 'has been Approved' }}</div>
|
|
<div class="row m-b-15">
|
|
<div class="col">
|
|
<div class="font-heading fs-10">If you would like to still edit your Purchase Order you can do that by clicking on the edit button below, but your purchase order verification request will be reset.</div>
|
|
</div>
|
|
</div>
|
|
<button class="btn btn-xs all-caps b-rad-none btn-default bg-master-lightest w-100" @click="submitted = false">Edit Purchase Order</button>
|
|
<button class="btn btn-xs all-caps b-rad-none btn-success w-100 m-t-5" v-if="!data.documents.proforma_invoice && data.outstanding_amount != 0" @click="submit(route('api.booking.proforma.create', data.id), 'post', section, true, true)">Generate Proforma Invoice</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
<script>
|
|
import formHandler from '../../../general/mixins/formHandler';
|
|
export default {
|
|
data(){
|
|
return {
|
|
submitted: false,
|
|
product: {
|
|
stockCode: '',
|
|
description: '',
|
|
quantity: 1,
|
|
unit_price: 0,
|
|
},
|
|
products: [],
|
|
}
|
|
},
|
|
created() {
|
|
this.products = this.data.purchase_order ? this.data.purchase_order.details : [];
|
|
this.submitted = this.data.purchase_order ? this.data.purchase_order.status === 1 || this.data.purchase_order.status === 2: false;
|
|
},
|
|
computed: {
|
|
productTotal(){
|
|
return this.product.quantity * parseFloat((this.product.unit_price).toString().replace(',', ''));
|
|
},
|
|
poTotal(){
|
|
return this.products.reduce(function(last, product) {
|
|
return last + product.total;
|
|
}, 0);
|
|
}
|
|
},
|
|
methods: {
|
|
onlyEnglish(event){
|
|
let value = event.target.value,
|
|
regex = /^[^~`!@#$%^&*()_+=[\]\{}|;':",.\/<>?a-zA-Z0-9-]+$/;
|
|
|
|
event.preventDefault();
|
|
|
|
if(regex.test(value)){
|
|
this.product.description = value.replace(regex, '');
|
|
}
|
|
|
|
},
|
|
submitForm(){
|
|
|
|
this.parameters = {
|
|
products: this.products
|
|
};
|
|
|
|
this.submit(route('api.transaction.po.create', this.data.id), 'post', this.section, true, true);
|
|
},
|
|
successHandler(){
|
|
if((Math.round((this.poTotal + Number.EPSILON) * 1000) / 1000).toFixed(3) === (Math.round((this.data.amount + Number.EPSILON) * 1000) / 1000).toFixed(3)){
|
|
this.submitted = true;
|
|
}
|
|
this.updateList()
|
|
},
|
|
addProduct(){
|
|
this.products.push({
|
|
stockCode: this.product.stockCode,
|
|
description: this.product.description,
|
|
quantity: this.product.quantity,
|
|
unit_price: this.product.unit_price,
|
|
total: this.productTotal
|
|
});
|
|
|
|
this.product = {
|
|
stockCode: '',
|
|
description: '',
|
|
quantity: 1,
|
|
unit_price: 0,
|
|
};
|
|
},
|
|
updateProduct(product, index){
|
|
this.$set(this.products, index, {
|
|
stockCode: product.stockCode,
|
|
description: product.description,
|
|
quantity: product.quantity,
|
|
unit_price: parseFloat((product.unit_price).toString().replace(',', '')),
|
|
total: product.quantity * parseFloat((product.unit_price).toString().replace(',', ''))
|
|
});
|
|
},
|
|
removeProduct(index){
|
|
this.products.splice(index, 1);
|
|
}
|
|
},
|
|
mixins: [formHandler]
|
|
}
|
|
</script> |