Merge branch 'fixinvoice' into 'master'

All fixes for invoice is complete.

See merge request CIEFWorldwideSdnBhd/exchange!155
This commit is contained in:
omair saleh
2020-09-26 13:13:46 +00:00
12 changed files with 295 additions and 44 deletions
+1 -1
View File
@@ -24,7 +24,7 @@ class Booking extends Model
"usd_book_bank_branch");
protected $fillable = ['id', 'term', 'rate_id', 'user_id', 'amount', 'account_name', 'account_num', 'bank_name',
'bank_branch', 'company_name'];
'bank_branch', 'company_name', 'service_charge', 'billing_charge'];
public $timestamps = true;
@@ -448,6 +448,8 @@ class BookingController extends Controller
$bankin_amount = round($subtotal + $taxAmount + $billingChargeAmount , 2);
$booking = new Booking();
$booking->billing_charge = $billingChargeAmount;
$booking->service_charge = $svcharge;
$booking->account_name = $request->input('account_name');
$booking->account_num = $request->input('account_num');
$booking->bank_name = $request->input('bank_name');
+90 -20
View File
@@ -65,6 +65,7 @@ class InvoiceController extends Controller
'contact_no' => 'required',
'marking' => 'required',
'reg_no' => 'required',
'adjustment' => 'required|numeric',
'lines.*.order' => 'required|numeric',
'lines.*.stock_code' => 'required',
'lines.*.description' => 'max:256',
@@ -92,9 +93,13 @@ class InvoiceController extends Controller
function ($line) { return $line['total']; },
$validatedData['lines']
);
$total = array_reduce($subtotalArray, function ($v1, $v2) {
$subtotal = array_reduce($subtotalArray, function ($v1, $v2) {
return $v1 + $v2;
});
$adjustment = $request->adjustment;
$billing_charges = $booking->billing_charge;
$total = $subtotal + $adjustment + $billing_charges;
if ($total !== $booking->bia) {
return response()->json([
'message' => 'Booking amount expected is '.$booking->bia.'. Your Invoice amount is '.$total
@@ -120,6 +125,7 @@ class InvoiceController extends Controller
$invoice->address = $validatedData['address'];
$invoice->contact_no = $validatedData['contact_no'];
$invoice->po_number = $po_number;
$invoice->adjustment = $adjustment;
$invoice->save();
if (!$invoice) {
@@ -174,6 +180,7 @@ class InvoiceController extends Controller
'contact_no' => 'required',
'marking' => 'required',
'reg_no' => 'required',
'adjustment' => 'required|numeric',
'lines.*.order' => 'required|numeric',
'lines.*.stock_code' => 'required',
'lines.*.description' => 'max:256',
@@ -213,12 +220,16 @@ class InvoiceController extends Controller
function ($line) { return $line['total']; },
$validatedData['lines']
);
$total = array_reduce($subtotalArray, function ($v1, $v2) {
$subtotal = array_reduce($subtotalArray, function ($v1, $v2) {
return $v1 + $v2;
});
if ($total != $booking->amount) {
$adjustment = $request->adjustment;
$billing_charges = $booking->billing_charge;
$total = $subtotal + $adjustment + $billing_charges;
if ($total !== $booking->bia) {
return response()->json([
'message' => 'Booking amount expected is '.$booking->amount.'. Your Invoice amount is '.$total
'message' => 'Booking amount expected is '.$booking->bia.'. Your Invoice amount is '.$total
], 400);
}
@@ -233,6 +244,7 @@ class InvoiceController extends Controller
$invoice->address = $validatedData['address'];
$invoice->contact_no = $validatedData['contact_no'];
$invoice->po_number = $po_number;
$invoice->adjustment = $adjustment;
$invoice->save();
if (!$invoice) {
@@ -300,13 +312,28 @@ class InvoiceController extends Controller
$booking = Booking::find($id);
$monthlycount = Invoice::where('ei', 'like', 'EI-'.Carbon::createFromFormat('Y-m-d H:i:s', $booking->created_at)->format('Ym').'%')->count() + 1;
$generatednumber = Carbon::createFromFormat('Y-m-d H:i:s', $booking->created_at)->format('Ym').'-'.sprintf("%05d", $monthlycount);
// Generate EI and EDO only if not exist
$invoice = Invoice::where('booking_id', $id)->first();
$invoice->ei = 'EI-'.$generatednumber;
$invoice->edo = 'EDO-'.$generatednumber;
$invoice->save();
var_dump($invoice->ei);
if (!$invoice->ei && !$invoice->edo) {
$monthlycount = Invoice::where('ei', 'like', 'EI-'.Carbon::createFromFormat('Y-m-d H:i:s', $booking->created_at)->format('Ym').'%')->count() + 1;
$generatednumber = Carbon::createFromFormat('Y-m-d H:i:s', $booking->created_at)->format('Ym').'-'.sprintf("%05d", $monthlycount);
$invoice->ei = 'EI-'.$generatednumber;
$invoice->edo = 'EDO-'.$generatednumber;
// Skip to next count if already exist
while (Invoice::where('ei', $invoice->ei)->exists() || Invoice::where('edo', $invoice->edo)->exists()) {
$monthlycount = $monthlycount + 1;
$generatednumber = Carbon::createFromFormat('Y-m-d H:i:s', $booking->created_at)->format('Ym').'-'.sprintf("%05d", $monthlycount);
$invoice->ei = 'EI-'.$generatednumber;
$invoice->edo = 'EDO-'.$generatednumber;
}
$invoice->save();
}
if(!$status) {
return response()->json(['message' => 'Unable to Update Status'], 500);
@@ -347,17 +374,16 @@ class InvoiceController extends Controller
}
}
// Ensure Invoice Status is Approve
// if ($this->invoiceStatus($id) !== 'approve') {
// return response()->json(['message' => 'Invoice must and exist and approve status.'], 403);
// }
// Generate PO
$booking = Booking::where('id', $id)->first();
$invoice = Invoice::where('booking_id', $booking['id'])->first();
$lines = InvoiceDetails::where('invoice_id', $invoice->id)->get();
$marking = User::find($booking->user_id)->marking;
$subtotal = InvoiceDetails::where('invoice_id', $invoice->id)->sum('total');
$adjustment = $invoice->adjustment;
$billing_charges = $booking->billing_charge;
$total = $subtotal + $adjustment + $billing_charges;
$data = [
'title' => 'Purchase Order',
@@ -383,7 +409,10 @@ class InvoiceController extends Controller
'phone' => '018 2909252',
],
'lines' => $lines,
'amount' => $invoice->amount
'subtotal' => $subtotal,
'adjustment' => $adjustment,
'billingcharges' => $billing_charges,
'total' => $total
];
$defaultConfig = (new \Mpdf\Config\ConfigVariables())->getDefaults();
@@ -441,9 +470,30 @@ class InvoiceController extends Controller
$booking = Booking::where('id', $id)->first();
$invoice = Invoice::where('booking_id', $booking['id'])->first();
$lines = InvoiceDetails::where('invoice_id', $invoice->id)->get();
$supplierbooking = SupplierBooking::where('booking_id', $id)->first();
$lines = DB::table('invoices')
->join('invoice_details', function ($join) use ($id) {
$join->where('invoices.booking_id', '=', $id);
$join->on('invoice_details.invoice_id', '=', 'invoices.id');
})
->join('supplier_bookings', 'invoices.booking_id', '=', 'supplier_bookings.booking_id')
->select(
'order',
'stock_code',
'description',
'quantity',
DB::raw('ROUND((invoice_details.unit_price_rmb / supplier_bookings.rate), 2) as unit_price_rm'),
DB::raw('ROUND((invoice_details.quantity * ROUND((invoice_details.unit_price_rmb / supplier_bookings.rate), 2)), 2) as total'),
// subtotal
// adjustment
// total
)->get();
$supplierbooking = SupplierBooking::where('booking_id', $id)->first();
$supplier = SettingSupplier::where('id', $supplierbooking->supplier_id)->first();
$subtotal = $lines->sum('total');
$billing_charges = null;
$total = $supplierbooking->amount_after_tax;
$adjustment = $total - $subtotal;
$data = [
'title' => 'Delivery Order',
@@ -469,7 +519,10 @@ class InvoiceController extends Controller
'phone' => '',
],
'lines' => $lines,
'amount' => $invoice->amount
'subtotal' => $subtotal,
'adjustment' => $adjustment,
'billingcharges' => $billing_charges,
'total' => $total
];
$defaultConfig = (new \Mpdf\Config\ConfigVariables())->getDefaults();
$fontDirs = $defaultConfig['fontDir'];
@@ -520,6 +573,11 @@ class InvoiceController extends Controller
$booking = Booking::where('id', $id)->first();
$invoice = Invoice::where('booking_id', $booking['id'])->first();
$lines = InvoiceDetails::where('invoice_id', $invoice->id)->get();
$subtotal = InvoiceDetails::where('invoice_id', $invoice->id)->sum('total');
$adjustment = $invoice->adjustment;
$billing_charges = $booking->billing_charge;
$total = $subtotal + $adjustment + $billing_charges;
$data = [
'title' => 'Invoice',
@@ -539,7 +597,10 @@ class InvoiceController extends Controller
],
'total_page' => (count($lines) / 10),
'lines' => $lines,
'amount' => $invoice->amount
'subtotal' => $subtotal,
'adjustment' => $adjustment,
'billingcharges' => $billing_charges,
'total' => $total
];
$defaultConfig = (new \Mpdf\Config\ConfigVariables())->getDefaults();
@@ -591,6 +652,11 @@ class InvoiceController extends Controller
$booking = Booking::where('id', $id)->first();
$invoice = Invoice::where('booking_id', $booking['id'])->first();
$lines = InvoiceDetails::where('invoice_id', $invoice->id)->get();
$subtotal = InvoiceDetails::where('invoice_id', $invoice->id)->sum('total');
$adjustment = $invoice->adjustment;
$billing_charges = $booking->billing_charge;
$total = $subtotal + $adjustment + $billing_charges;
$data = [
'title' => 'Delivery Order',
@@ -609,7 +675,10 @@ class InvoiceController extends Controller
'marking_no' => ''
],
'lines' => $lines,
'amount' => $invoice->amount
'subtotal' => $subtotal,
'adjustment' => $adjustment,
'billingcharges' => $billing_charges,
'total' => $total
];
$defaultConfig = (new \Mpdf\Config\ConfigVariables())->getDefaults();
@@ -617,6 +686,7 @@ class InvoiceController extends Controller
$defaultFontConfig = (new \Mpdf\Config\FontVariables())->getDefaults();
$fontData = $defaultFontConfig['fontdata'];
$mpdf = new \Mpdf\Mpdf([
'fontDir' => array_merge($fontDirs, [
__DIR__ . '/custom/font/directory',
+1 -1
View File
@@ -6,7 +6,7 @@ use Illuminate\Database\Eloquent\Model;
class Invoice extends Model
{
protected $fillable = ['invoice_url','amount','booking_id', 'buyer_company', 'address', 'contact_no', 'po_number'];
protected $fillable = ['invoice_url','amount','booking_id', 'buyer_company', 'address', 'contact_no', 'po_number', 'adjustment'];
public function booking(){
return $this->belongsTo('App\Booking');
@@ -0,0 +1,32 @@
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class AddServiceChargeToBookings extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('bookings', function (Blueprint $table) {
$table->double('service_charge')->default(null)->nullable();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('bookings', function (Blueprint $table) {
$table->dropColumn('service_charge');
});
}
}
@@ -0,0 +1,32 @@
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class AddAdjustmentToInvoices extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('invoices', function (Blueprint $table) {
$table->double('adjustment')->default(null)->nullable();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('invoices', function (Blueprint $table) {
$table->dropColumn('adjustment');
});
}
}
@@ -0,0 +1,32 @@
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class AddBillingChargeToBookings extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('bookings', function (Blueprint $table) {
$table->double('billing_charge')->default(null)->nullable();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('bookings', function (Blueprint $table) {
$table->dropColumn('billing_charge');
});
}
}
+9
View File
@@ -0,0 +1,9 @@
1. create migration field service_charge in bookings. (nullable, default null, double)
2. create migration field adjustment in invoices. (nullable, default null, double)
3. save service charge on confirm
4. pass service from backend
5. display in frontend.
6. When RMB value match auto adjustment.
7. Vue validation before post and edit.
8. post and edit invoice needs to have adjustment. validate.
9. change pdf documents.
+52 -9
View File
@@ -278,6 +278,30 @@
&nbsp;
</td>
</tr>
<tr class="subtotal-line">
<td colspan="5"/>
<td class="subtotal-title text-center">
Adjustment
</td>
<td class="subtotal text-center">
{{ form.formData.adjustment || 'auto' }}
</td>
<td>
&nbsp;
</td>
</tr>
<tr class="service-charge">
<td colspan="5"/>
<td class="subtotal-title text-center">
Billing Charge
</td>
<td class="subtotal text-center">
{{ billing_charge }}
</td>
<td>
&nbsp;
</td>
</tr>
<tr v-if="tax > 0" class="gst-line">
<td colspan="5"/>
<td class="gst-title text-center">
@@ -476,11 +500,12 @@ export default {
default: function () {
return {
id: null,
amount: null,
bia: null,
amount: null,
user_bankslip_path: null,
china_bankslip_path: null,
marking: null
marking: null,
billing_charge: null
}
}
}
@@ -495,6 +520,7 @@ export default {
marking: this.booking_details.marking,
gst_id: '',
reg_no: '',
adjustment: '',
lines: []
},
addLine: {
@@ -512,10 +538,12 @@ export default {
}
},
rate: 0,
service_charge: 0,
billing_charge: 0,
amount: 0,
bia: 0,
invoice_total: 0,
tax: 0,
billing_fee: 0,
subtotal: 0,
total: 0,
role: null,
@@ -549,6 +577,8 @@ export default {
},
gst_id: {
},
adjustment: {
}
},
addLine: {
@@ -592,18 +622,19 @@ export default {
const {
marking,
tax,
service_charge,
amount,
bia,
rate
amount,
rate,
billing_charge
} = this.booking_details
this.form.formData.marking = marking
this.tax = tax
this.service_charge = service_charge
this.amount = amount
this.bia = bia
this.rate = rate
this.billing_charge = billing_charge
this.total = this.billing_charge // Will not work if there is tax. Temporary fix.
}
},
mounted () {
@@ -654,11 +685,21 @@ export default {
setTotal: function () {
if (this.form.formData.lines.length < 1) {
this.subtotal = 0
this.total = 0
this.form.formData.adjustment = 0
this.total = this.billing_charge // Temporary fix. Will return error if GST is implemented.
return
}
this.subtotal = parseFloat(this.form.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)
// Set Adjustment if CNY total is equal to Invoice CNY Total
const cnyTotal = this.form.formData.lines.map(l => +l.unit_price_rmb * +l.quantity).reduce((a, b) => a + b)
if (cnyTotal === this.amount) {
this.form.formData.adjustment = parseFloat(+this.bia - +this.subtotal - this.billing_charge).toFixed(2)
} else {
this.form.formData.adjustment = 0
}
this.total = parseFloat(+this.subtotal + (+this.subtotal * (+this.tax || 0) / 100) + +this.billing_charge + +this.form.formData.adjustment).toFixed(2)
},
clearAddLine: function () {
this.form.addLine.order = null
@@ -746,6 +787,8 @@ export default {
this.currentStatus = resp.data.status[resp.data.status.length - 1].status
this.form.formData.adjustment = resp.data.adjustment
this.setTotal()
})
},
+22 -7
View File
@@ -87,6 +87,9 @@
td.address {
text-align: left;
}
.right {
text-align: right;
}
</style>
</head>
@@ -169,26 +172,38 @@
<td class="description" >{{$line->description}}</td>
<td width="10%">{{$line->quantity}}</td>
<td width="12%">{{number_format($line->unit_price_rm, 2)}}</td>
<td width="20%">{{number_format($line->total, 2)}}</td>
<td width="20%" class="right">{{number_format($line->total, 2)}}</td>
</tr>
@endforeach
</tbody>
<tfoot>
<tr class="subtotal">
<td colspan="4"></td>
<td>Subtotal</td>
<td>{{ number_format($amount, 2) }}</td>
<td class="right">Subtotal</td>
<td class="right">{{ number_format($subtotal, 2) }}</td>
</tr>
@if($adjustment)
<tr class="adjustment">
<td colspan="3"></td>
<td colspan="2" class="right">Adjustment</td>
<td class="right">{{ number_format($adjustment, 2) }}</td>
</tr>
@endif
@if($billingcharges)
<tr class="billingcharges">
<td colspan="4"></td>
<td class="right">Billing Charges</td>
<td class="right">{{ number_format($billingcharges, 2) }}</td>
</tr>
@endif
<tr>
<td colspan="4"></td>
<td>Total</td>
<td class="total">{{ number_format($amount, 2) }}</td>
<td class="right">Total</td>
<td class="total right">{{ number_format($total, 2) }}</td>
</tr>
</tfoot>
</table>
</body>
</html>
+22 -5
View File
@@ -46,6 +46,9 @@
.center {
text-align: center;
}
.right {
text-align: right;
}
.middle {
vertical-align: middle;
}
@@ -147,20 +150,34 @@
<td class="description" >{{$line->description}}</td>
<td width="10%" class="center top">{{$line->quantity}}</td>
<td width="12%" class="center top">{{number_format($line->unit_price_rm, 2)}}</td>
<td width="20%" class="center top">{{number_format($line->total, 2)}}</td>
<td width="20%" class="right top">{{number_format($line->total, 2)}}</td>
</tr>
@endforeach
</tbody>
<tfoot>
<tr class="subtotal">
<td colspan="4"></td>
<td class="center middle">Subtotal</td>
<td class="center middle">{{ number_format($amount, 2) }}</td>
<td class="right middle">Subtotal</td>
<td class="right middle">{{ number_format($subtotal, 2) }}</td>
</tr>
@if($adjustment)
<tr class="adjustment">
<td colspan="4"></td>
<td class="right middle">Adjustment</td>
<td class="right middle">{{ number_format($adjustment, 2) }}</td>
</tr>
@endif
@if($billingcharges)
<tr class="billingcharges">
<td colspan="4"></td>
<td class="right middle">Billing Charges</td>
<td class="right middle">{{ number_format($billingcharges, 2) }}</td>
</tr>
@endif
<tr>
<td colspan="4"></td>
<td class="center center middle">Total</td>
<td class="total center middle">{{ number_format($amount, 2) }}</td>
<td class="right middle">Total</td>
<td class="total right middle">{{ number_format($total, 2) }}</td>
</tr>
</tfoot>
</table>
Submodule utils deleted from 47ddd6dedb