diff --git a/app/Booking.php b/app/Booking.php index 43bd80d4..f0decadf 100644 --- a/app/Booking.php +++ b/app/Booking.php @@ -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; diff --git a/app/Http/Controllers/BookingController.php b/app/Http/Controllers/BookingController.php index 9c82209f..7641c6bf 100644 --- a/app/Http/Controllers/BookingController.php +++ b/app/Http/Controllers/BookingController.php @@ -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'); diff --git a/app/Http/Controllers/InvoiceController.php b/app/Http/Controllers/InvoiceController.php index c56f38ff..6e0d8c83 100644 --- a/app/Http/Controllers/InvoiceController.php +++ b/app/Http/Controllers/InvoiceController.php @@ -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', diff --git a/app/Invoice.php b/app/Invoice.php index 647b3bff..9e3bffa8 100644 --- a/app/Invoice.php +++ b/app/Invoice.php @@ -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'); diff --git a/database/migrations/2020_09_25_154412_add_service_charge_to_bookings.php b/database/migrations/2020_09_25_154412_add_service_charge_to_bookings.php new file mode 100644 index 00000000..114601b7 --- /dev/null +++ b/database/migrations/2020_09_25_154412_add_service_charge_to_bookings.php @@ -0,0 +1,32 @@ +double('service_charge')->default(null)->nullable(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::table('bookings', function (Blueprint $table) { + $table->dropColumn('service_charge'); + }); + } +} diff --git a/database/migrations/2020_09_25_154539_add_adjustment_to_invoices.php b/database/migrations/2020_09_25_154539_add_adjustment_to_invoices.php new file mode 100644 index 00000000..815200ad --- /dev/null +++ b/database/migrations/2020_09_25_154539_add_adjustment_to_invoices.php @@ -0,0 +1,32 @@ +double('adjustment')->default(null)->nullable(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::table('invoices', function (Blueprint $table) { + $table->dropColumn('adjustment'); + }); + } +} diff --git a/database/migrations/2020_09_25_161945_add_billing_charge_to_bookings.php b/database/migrations/2020_09_25_161945_add_billing_charge_to_bookings.php new file mode 100644 index 00000000..ebfd7e76 --- /dev/null +++ b/database/migrations/2020_09_25_161945_add_billing_charge_to_bookings.php @@ -0,0 +1,32 @@ +double('billing_charge')->default(null)->nullable(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::table('bookings', function (Blueprint $table) { + $table->dropColumn('billing_charge'); + }); + } +} diff --git a/fixinvoice.txt b/fixinvoice.txt new file mode 100644 index 00000000..d857f15b --- /dev/null +++ b/fixinvoice.txt @@ -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. diff --git a/resources/assets/js/components/NewInvoice.vue b/resources/assets/js/components/NewInvoice.vue index 84afda88..b6d5b3c4 100644 --- a/resources/assets/js/components/NewInvoice.vue +++ b/resources/assets/js/components/NewInvoice.vue @@ -278,6 +278,30 @@   + + + + Adjustment + + + {{ form.formData.adjustment || 'auto' }} + + +   + + + + + + Billing Charge + + + {{ billing_charge }} + + +   + + @@ -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() }) }, diff --git a/resources/views/pdf/invoice.blade.php b/resources/views/pdf/invoice.blade.php index a8c8eb16..5b30de30 100644 --- a/resources/views/pdf/invoice.blade.php +++ b/resources/views/pdf/invoice.blade.php @@ -87,6 +87,9 @@ td.address { text-align: left; } + .right { + text-align: right; + } @@ -169,26 +172,38 @@ {{$line->description}} {{$line->quantity}} {{number_format($line->unit_price_rm, 2)}} - {{number_format($line->total, 2)}} + {{number_format($line->total, 2)}} @endforeach - Subtotal - {{ number_format($amount, 2) }} + Subtotal + {{ number_format($subtotal, 2) }} + @if($adjustment) + + + Adjustment + {{ number_format($adjustment, 2) }} + + @endif + @if($billingcharges) + + + Billing Charges + {{ number_format($billingcharges, 2) }} + + @endif - Total - {{ number_format($amount, 2) }} + Total + {{ number_format($total, 2) }} - - \ No newline at end of file diff --git a/resources/views/pdf/po.blade.php b/resources/views/pdf/po.blade.php index 885c3c43..fd2b32d9 100644 --- a/resources/views/pdf/po.blade.php +++ b/resources/views/pdf/po.blade.php @@ -46,6 +46,9 @@ .center { text-align: center; } + .right { + text-align: right; + } .middle { vertical-align: middle; } @@ -147,20 +150,34 @@ {{$line->description}} {{$line->quantity}} {{number_format($line->unit_price_rm, 2)}} - {{number_format($line->total, 2)}} + {{number_format($line->total, 2)}} @endforeach - Subtotal - {{ number_format($amount, 2) }} + Subtotal + {{ number_format($subtotal, 2) }} + @if($adjustment) + + + Adjustment + {{ number_format($adjustment, 2) }} + + @endif + @if($billingcharges) + + + Billing Charges + {{ number_format($billingcharges, 2) }} + + @endif - Total - {{ number_format($amount, 2) }} + Total + {{ number_format($total, 2) }} diff --git a/utils b/utils deleted file mode 160000 index 47ddd6de..00000000 --- a/utils +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 47ddd6dedb1f32c45b66b701f5300dacc71bd715