mirror of
https://gitlab.com/CIEFWorldwideSdnBhd/exchange.git
synced 2026-08-19 04:14:04 +00:00
before createPO
This commit is contained in:
@@ -10,6 +10,7 @@
|
||||
"@vue/standard"
|
||||
],
|
||||
"rules": {
|
||||
"vue/max-attributes-per-line": "off"
|
||||
"vue/max-attributes-per-line": "off",
|
||||
"vue/camelcase": "off"
|
||||
}
|
||||
}
|
||||
@@ -22,3 +22,4 @@ vendor/composer/autoload_classmap.php
|
||||
package-lock.json
|
||||
composer.lock
|
||||
config/database.php
|
||||
notes.txt
|
||||
|
||||
@@ -43,6 +43,7 @@
|
||||
"vue-loading-spinner": "^1.0.11",
|
||||
"vue-meta": "^1.4.4",
|
||||
"vue-router": "^3.0.1",
|
||||
"vuelidate": "^0.7.5",
|
||||
"vuex": "^3.0.1",
|
||||
"vuex-router-sync": "^5.0.0"
|
||||
},
|
||||
|
||||
@@ -0,0 +1,562 @@
|
||||
/* eslint-disable camelcase */
|
||||
<template>
|
||||
<div class="invoice">
|
||||
<h3 class="title">Purchase Order</h3>
|
||||
|
||||
<div class="invoice-container">
|
||||
<div class="buyer-detail card">
|
||||
<div class="card-body">
|
||||
<div class="card-title">
|
||||
<h5>
|
||||
My Infomation
|
||||
</h5>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="marking">Marking</label>
|
||||
<input id="marking" v-model="$v.formData.marking.$model" type="text" class="form-control" disabled>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="buyer-company">Buyer's Company</label>
|
||||
<input id="buyer-company"
|
||||
v-model="$v.formData.buyer_company.$model"
|
||||
:class="{
|
||||
'is-invalid': $v.formData.buyer_company.$invalid && $v.formData.buyer_company.$dirty,
|
||||
'is-valid': !$v.formData.buyer_company.$invalid && $v.formData.buyer_company.$dirty
|
||||
}"
|
||||
type="text"
|
||||
class="form-control"
|
||||
@blur="$v.formData.buyer_company.$touch()">
|
||||
<div class="invalid-feedback">
|
||||
Buyer Company Required
|
||||
</div>
|
||||
</div>
|
||||
<!-- <div class="form-group">
|
||||
<label for="gst-id">GST ID</label>
|
||||
<input id="gst-id" type="text" class="form-control" disabled>
|
||||
</div> -->
|
||||
<div class="form-group">
|
||||
<label for="contact-number">Contact Number</label>
|
||||
<input id="contact-number"
|
||||
v-model.trim="$v.formData.contact_no.$model"
|
||||
:class="{
|
||||
'is-invalid': $v.formData.contact_no.$invalid && $v.formData.contact_no.$dirty,
|
||||
'is-valid': !$v.formData.contact_no.$invalid && $v.formData.contact_no.$dirty
|
||||
}"
|
||||
type="tel"
|
||||
class="form-control"
|
||||
@blur="$v.formData.contact_no.$touch()">
|
||||
<div class="invalid-feedback">
|
||||
Contact Number Required
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="address">Address</label>
|
||||
<textarea id="address"
|
||||
v-model="$v.formData.address.$model"
|
||||
:class="{
|
||||
'is-invalid': $v.formData.address.$invalid && $v.formData.address.$dirty,
|
||||
'is-valid': !$v.formData.address.$invalid && $v.formData.address.$dirty
|
||||
}"
|
||||
class="form-control"
|
||||
cols="30"
|
||||
rows="4"
|
||||
@blur="$v.formData.address.$touch()"/>
|
||||
<div class="invalid-feedback">
|
||||
Address Required
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="conversion-rate">
|
||||
<h5>
|
||||
Conversion: {{ rate }}
|
||||
</h5>
|
||||
</div>
|
||||
<div class="billing-detail-title">
|
||||
<h5>Billing Detail</h5>
|
||||
</div>
|
||||
<div class="billing-detail-lines">
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="align-middle">#</th>
|
||||
<th class="align-middle">Stock Code</th>
|
||||
<th class="align-middle">Description</th>
|
||||
<th class="text-center align-middle">Qty</th>
|
||||
<th class="text-center align-middle">Unit Price (RMB)</th>
|
||||
<th class="text-center align-middle">Unit Price (RM)</th>
|
||||
<th class="text-center align-middle">Total Amount (RM)</th>
|
||||
<th> </th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td> </td>
|
||||
<td>
|
||||
<div class="form-group">
|
||||
<input v-model="$v.addLine.stock_code.$model"
|
||||
:class="{
|
||||
'is-invalid': $v.addLine.stock_code.$invalid && $v.addLine.stock_code.$dirty,
|
||||
'is-valid': !$v.addLine.stock_code.$invalid && $v.addLine.stock_code.$dirty
|
||||
}"
|
||||
name="stockcode" type="text"
|
||||
class="form-control"
|
||||
@blur="$v.addLine.stock_code.$touch()">
|
||||
<div class="invalid-feedback">
|
||||
Stock Code Required
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<div class="form-group">
|
||||
<textarea id="description"
|
||||
v-model="$v.addLine.description.$model"
|
||||
:class="{
|
||||
'is-invalid': $v.addLine.description.$invalid && $v.addLine.description.$dirty,
|
||||
'is-valid': !$v.addLine.description.$invalid && $v.addLine.description.$dirty
|
||||
}"
|
||||
name="description" cols="20" rows="2"
|
||||
@blur="$v.addLine.description.$touch()"/>
|
||||
<div class="invalid-feedback">
|
||||
Description Required
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<div class="form-group">
|
||||
<input id="quantity"
|
||||
v-model="$v.addLine.quantity.$model"
|
||||
:class="{
|
||||
'is-invalid': $v.addLine.quantity.$invalid && $v.addLine.quantity.$dirty,
|
||||
'is-valid': !$v.addLine.quantity.$invalid && $v.addLine.quantity.$dirty
|
||||
}"
|
||||
type="number"
|
||||
min="1"
|
||||
class="form-control"
|
||||
name="quantity"
|
||||
@change="onUnitPriceRM()"
|
||||
@blur="$v.addLine.quantity.$touch()">
|
||||
<div class="invalid-feedback">
|
||||
Quantity Required
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<div class="form-group">
|
||||
<input id="rmb-unit-price"
|
||||
v-model="$v.addLine.unit_price_rmb.$model"
|
||||
:class="{
|
||||
'is-invalid': $v.addLine.unit_price_rmb.$invalid && $v.addLine.unit_price_rmb.$dirty,
|
||||
'is-valid': !$v.addLine.unit_price_rmb.$invalid && $v.addLine.unit_price_rmb.$dirty
|
||||
}"
|
||||
type="number"
|
||||
min="0"
|
||||
name="rmb-unit-price"
|
||||
class="form-control"
|
||||
@change="onUnitPriceRMB()"
|
||||
@blur="$v.addLine.unit_price_rmb.$touch()">
|
||||
<div class="invalid-feedback">
|
||||
Unit Price Required
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<div class="form-group">
|
||||
<input id="rm-unit-price"
|
||||
v-model="$v.addLine.unit_price_rm.$model"
|
||||
:class="{
|
||||
'is-invalid': $v.addLine.unit_price_rm.$invalid && $v.addLine.unit_price_rm.$dirty,
|
||||
'is-valid': !$v.addLine.unit_price_rm.$invalid && $v.addLine.unit_price_rm.$dirty
|
||||
}"
|
||||
type="number"
|
||||
min="0"
|
||||
name="rm-unit-price"
|
||||
class="form-control"
|
||||
@change="onUnitPriceRM()"
|
||||
@blur="$v.addLine.unit_price_rm.$touch()">
|
||||
<div class="invalid-feedback">
|
||||
Unit Price Required
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<div class="form-group">
|
||||
<input id="total"
|
||||
v-model="$v.addLine.total.$model"
|
||||
type="number"
|
||||
min="0"
|
||||
name="subtotal"
|
||||
class="form-control"
|
||||
disabled>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<button class="btn btn-success" type="button" @click="onAddLine()">
|
||||
Add
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
<tr v-for="(line, index) in formData.lines" :key="index">
|
||||
<td class="line-number text-center align-middle">
|
||||
{{ index + 1 }}
|
||||
</td>
|
||||
<td class="stock-code text-center align-middle">
|
||||
{{ line.stock_code }}
|
||||
</td>
|
||||
<td class="description align-middle">
|
||||
{{ line.description }}
|
||||
</td>
|
||||
<td class="quantity text-center align-middle">
|
||||
{{ line.quantity }}
|
||||
</td>
|
||||
<td class="unit-price-rmb text-center align-middle">
|
||||
{{ line.unit_price_rmb }}
|
||||
</td>
|
||||
<td class="unit-price-rm text-center align-middle">
|
||||
{{ line.unit_price_rm }}
|
||||
</td>
|
||||
<td class="line-subtotal text-center align-middle">
|
||||
{{ line.total }}
|
||||
</td>
|
||||
<td>
|
||||
<button class="btn btn-danger" @click="onRemoveLine(index)">
|
||||
Remove
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
<tfoot>
|
||||
<tr class="subtotal-line">
|
||||
<td colspan="5"/>
|
||||
<td class="subtotal-title text-center">
|
||||
Subtotal
|
||||
</td>
|
||||
<td class="subtotal text-center">
|
||||
{{ subtotal }}
|
||||
</td>
|
||||
<td>
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr v-if="tax > 0" class="gst-line">
|
||||
<td colspan="5"/>
|
||||
<td class="gst-title text-center">
|
||||
GST
|
||||
</td>
|
||||
<td class="gst-total text-center">
|
||||
{{ tax }}
|
||||
</td>
|
||||
<td>
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="total-line">
|
||||
<td colspan="5"/>
|
||||
<td class="total-title text-center">
|
||||
Total
|
||||
</td>
|
||||
<td class="total text-center">
|
||||
{{ total }}
|
||||
</td>
|
||||
<td>
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="5"> </td>
|
||||
<td colspan="2">
|
||||
<button class="btn btn-success btn-block">
|
||||
Create PO
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
</tfoot>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<style>
|
||||
.container {
|
||||
margin-left: 10% !important;
|
||||
margin-right: 10% !important;
|
||||
}
|
||||
.el-main {
|
||||
padding-left: 0 !important;
|
||||
padding-right: 0 !important;
|
||||
}
|
||||
.title {
|
||||
margin-top: 1em;
|
||||
padding-left: 1.7em;
|
||||
padding-bottom: 0 !important;
|
||||
}
|
||||
.buyer-detail {
|
||||
grid-area: buyer-detail;
|
||||
width: 100%;
|
||||
}
|
||||
.card-body {
|
||||
display: flex !important;
|
||||
flex-direction: row !important;
|
||||
flex-wrap: wrap !important;
|
||||
justify-content: space-around !important;
|
||||
}
|
||||
.buyer-detail .form-group {
|
||||
width: 45%;
|
||||
}
|
||||
.card-title {
|
||||
width: 100%;
|
||||
}
|
||||
.conversion-rate {
|
||||
grid-area: conversion-rate;
|
||||
}
|
||||
.conversion-rate h5 {
|
||||
float: right;
|
||||
background-color: lightblue;
|
||||
padding-left: 1em;
|
||||
padding-right: 1em;
|
||||
}
|
||||
.billing-detail-title {
|
||||
width: 100%;
|
||||
grid-area: billing-detail-title;
|
||||
}
|
||||
.billing-detail-lines {
|
||||
width: 100%;
|
||||
grid-area: billing-detail-lines;
|
||||
}
|
||||
.invoice-container {
|
||||
padding: 2em 3em;
|
||||
display: grid;
|
||||
grid-template-areas:
|
||||
'buyer-detail buyer-detail'
|
||||
'billing-detail-title conversion-rate'
|
||||
'billing-detail-lines billing-detail-lines';
|
||||
}
|
||||
</style>
|
||||
|
||||
<script>
|
||||
import Vue from 'vue'
|
||||
import Vuelidate from 'vuelidate'
|
||||
import { required, numeric, or, decimal } from 'vuelidate/lib/validators'
|
||||
Vue.use(Vuelidate)
|
||||
|
||||
export default {
|
||||
name: 'NewComponent',
|
||||
props: {
|
||||
trackerConfig: {
|
||||
type: Object,
|
||||
default: function () {
|
||||
return {
|
||||
status: 5,
|
||||
term: null
|
||||
}
|
||||
}
|
||||
},
|
||||
booking_id: {
|
||||
type: String,
|
||||
default: null
|
||||
},
|
||||
booking_details: {
|
||||
type: Object,
|
||||
default: function () {
|
||||
return {
|
||||
id: null,
|
||||
amount: null,
|
||||
bia: null,
|
||||
user_bankslip_path: null,
|
||||
china_bankslip_path: null,
|
||||
marking: null
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
data: function () {
|
||||
return {
|
||||
formData: {
|
||||
buyer_company: '',
|
||||
address: '',
|
||||
contact_no: '',
|
||||
marking: this.booking_details.marking,
|
||||
gst_id: '',
|
||||
lines: []
|
||||
},
|
||||
addLine: {
|
||||
order: null,
|
||||
description: null,
|
||||
quantity: null,
|
||||
unit_price_rmb: null,
|
||||
unit_price_rm: null,
|
||||
stock_code: null,
|
||||
total: null
|
||||
},
|
||||
rate: 0,
|
||||
service_charge: 0,
|
||||
amount: 0,
|
||||
invoice_total: 0,
|
||||
tax: 0,
|
||||
subtotal: 0,
|
||||
total: 0
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
},
|
||||
validations: {
|
||||
formData: {
|
||||
buyer_company: {
|
||||
required
|
||||
},
|
||||
address: {
|
||||
required
|
||||
},
|
||||
contact_no: {
|
||||
required
|
||||
},
|
||||
marking: {
|
||||
required
|
||||
},
|
||||
gst_id: {
|
||||
|
||||
},
|
||||
lines: [
|
||||
{
|
||||
stock_code: {
|
||||
required
|
||||
},
|
||||
description: {
|
||||
required
|
||||
},
|
||||
quantity: {
|
||||
required,
|
||||
numeric
|
||||
},
|
||||
unit_price_rmb: {
|
||||
required,
|
||||
mycustomval: or(numeric, decimal)
|
||||
},
|
||||
unit_price_rm: {
|
||||
required,
|
||||
mycustomval: or(numeric, decimal)
|
||||
},
|
||||
total: {
|
||||
required,
|
||||
mycustomval: or(numeric, decimal)
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
addLine: {
|
||||
stock_code: {
|
||||
required
|
||||
},
|
||||
description: {
|
||||
required
|
||||
},
|
||||
quantity: {
|
||||
required,
|
||||
numeric
|
||||
},
|
||||
unit_price_rmb: {
|
||||
required,
|
||||
mycustomval: or(numeric, decimal)
|
||||
},
|
||||
unit_price_rm: {
|
||||
required,
|
||||
mycustomval: or(numeric, decimal)
|
||||
},
|
||||
total: {
|
||||
required,
|
||||
mycustomval: or(numeric, decimal)
|
||||
}
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
booking_details: function () {
|
||||
const {
|
||||
buyer_company,
|
||||
reg_no,
|
||||
address,
|
||||
contact_no,
|
||||
marking,
|
||||
tax,
|
||||
service_charge,
|
||||
amount,
|
||||
rate
|
||||
} = this.booking_details
|
||||
|
||||
this.formData.buyer_company = buyer_company
|
||||
this.formData.reg_no = reg_no
|
||||
this.formData.address = address
|
||||
this.formData.contact_no = contact_no
|
||||
this.formData.marking = marking
|
||||
this.tax = tax
|
||||
this.service_charge = service_charge
|
||||
this.amount = amount
|
||||
this.rate = rate
|
||||
|
||||
}
|
||||
},
|
||||
created: {
|
||||
|
||||
},
|
||||
methods: {
|
||||
onAddLine: function () {
|
||||
if (this.$v.addLine.$invalid) {
|
||||
console.log('invalid', this.$v.addLine.$invalid)
|
||||
this.$v.addLine.$touch()
|
||||
return
|
||||
}
|
||||
const {
|
||||
order,
|
||||
description,
|
||||
quantity,
|
||||
stock_code,
|
||||
unit_price_rmb,
|
||||
unit_price_rm,
|
||||
total
|
||||
} = this.addLine
|
||||
const data = {
|
||||
order: order,
|
||||
description,
|
||||
quantity,
|
||||
stock_code,
|
||||
unit_price_rmb,
|
||||
unit_price_rm,
|
||||
total
|
||||
}
|
||||
|
||||
this.formData.lines.push(data)
|
||||
this.setTotal()
|
||||
this.clearAddLine()
|
||||
},
|
||||
onUnitPriceRMB: function () {
|
||||
console.log(this.addLine.unit_price_rmb)
|
||||
this.addLine.unit_price_rm = (+this.addLine.unit_price_rmb * +this.rate).toFixed(2)
|
||||
this.addLine.total = (+this.addLine.unit_price_rm * +this.addLine.quantity).toFixed(2)
|
||||
},
|
||||
onUnitPriceRM: function () {
|
||||
this.addLine.unit_price_rmb = (this.addLine.unit_price_rm / this.rate).toFixed(2)
|
||||
this.addLine.total = (+this.addLine.unit_price_rm * +this.addLine.quantity).toFixed(2)
|
||||
},
|
||||
onRemoveLine: function (line) {
|
||||
this.formData.lines.splice(line)
|
||||
this.setTotal()
|
||||
},
|
||||
setTotal: function () {
|
||||
console.log(this.formData.lines)
|
||||
console.log(this.formData.lines.map(line => line.total))
|
||||
console.log(this.formData.lines.map(line => line.total).reduce((a, b) => +a + +b))
|
||||
this.subtotal = parseFloat(this.formData.lines.map(line => line.total).reduce((a, b) => parseFloat(a) + parseFloat(b))).toFixed(2)
|
||||
this.total = parseFloat(+this.subtotal + (+this.subtotal * (+this.tax || 0) / 100)).toFixed(2)
|
||||
},
|
||||
clearAddLine: function () {
|
||||
this.addLine.order = null
|
||||
this.addLine.description = null
|
||||
this.addLine.quantity = null
|
||||
this.addLine.unit_price_rmb = null
|
||||
this.addLine.unit_price_rm = null
|
||||
this.addLine.stock_code = null
|
||||
this.addLine.total = null
|
||||
this.$v.addLine.$reset()
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -1,8 +1,8 @@
|
||||
<template>
|
||||
<el-main>
|
||||
<x2-progress-track v-if="(trackerConfig.term == 'x2_cash' || trackerConfig.term == 'x2_cheque' || trackerConfig.term == 'x2_ba')" v-model="trackerConfig" />
|
||||
<progress-track v-else v-model="trackerConfig" />
|
||||
<div v-if="isLegacy" id="legacy-invoice">
|
||||
<x2-progress-track v-if="(trackerConfig.term == 'x2_cash' || trackerConfig.term == 'x2_cheque' || trackerConfig.term == 'x2_ba')" v-model="trackerConfig" />
|
||||
<progress-track v-else v-model="trackerConfig" />
|
||||
<h1>Transfer Completed</h1>
|
||||
<h2> Please upload your purchase order </h2>
|
||||
<!-- upload card -->
|
||||
@@ -121,7 +121,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<div v-else id="new-invoice">
|
||||
<h3>This is new invoice</h3>
|
||||
<new-invoice :booking_details="booking_details" :booking_id="booking_id.toString()"/>
|
||||
</div>
|
||||
</el-main>
|
||||
</template>
|
||||
@@ -188,13 +188,15 @@
|
||||
<script>
|
||||
import ProgressTrack from '~/components/ProgressTrack'
|
||||
import X2ProgressTrack from '~/components/X2ProgressTrack'
|
||||
import NewInvoice from '~/components/NewInvoice'
|
||||
import axios from 'axios'
|
||||
import ImageCompressor from 'image-compressor.js'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
'progress-track': ProgressTrack,
|
||||
'x2-progress-track': X2ProgressTrack
|
||||
'x2-progress-track': X2ProgressTrack,
|
||||
'new-invoice': NewInvoice
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
|
||||
Reference in New Issue
Block a user