【Laravel 8】 expiry date management/ tracking


https://github.com/edward1986/inventory



 <?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

class CreateProductsTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('products', function (Blueprint $table) {
$table->id();
$table->integer('quantity')->unsigned();
$table->string('name');
$table->timestamps();
});
}

/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('products');
}
}

<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

class CreateTransactionsTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('transactions', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('product_id')->unsigned()->nullable();
$table->foreign('product_id')->references('id')
->on('products')->onDelete('cascade');
$table->string('purchase_order')->nullable();
$table->integer('quantity')->unsigned();
$table->integer('display_quantity')->unsigned();
$table->integer('type')->unsigned();
$table->string('expiry_date', 30)->nullable();

$table->timestamps();
});
}

/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('transactions');
}
}

require('./bootstrap');
window.Vue = require('vue')
import VueRouter from 'vue-router'

Vue.use(VueRouter)

const routes = [
{
path: '', component: resolve => require(["./components/Product/product"], resolve), children: [
{
path: '', component: resolve => require(["./components/Product/index"], resolve), name: 'index_product'
},
{
path: 'create',
component: resolve => require(["./components/Product/create"], resolve),
name: 'create_product'
},
{
path: ':id', component: resolve => require(["./components/Product/show"], resolve), name: 'show_product'
}
]
}
]
const router = new VueRouter({
routes
});
new Vue({
router,
data() {
return {

store: {
state: {
products: [],
transactions: [],
id: 1,
},
mutations: {
create(state, data) {
state[data.state].push(data.push)
},
incrementId(state, data) {
state.id++
}
},
dispatch(mutation, data = {}) { //$root.store.dispatch
this.mutations[mutation](this.state, data)
}
}
}
},
render: h => h(require('./components/App.vue').default)
}).$mount('#app')

<template>
<div>
<button v-if="!isCheck" @click="checkType = 1; isCheck = !isCheck">check in</button>
<button v-if="!isCheck" @click="checkType = 0; isCheck = !isCheck">check out</button>
<router-link v-if="!isCheck" :to="{name:'show_product', params:{id: product.id}}">view</router-link>
<div v-if="isCheck">
<input v-if="checkType == 1" type="text" placeholder="purchase number" v-model="purchase_order">
<input type="number" v-model="quantity">
<input type="date" v-if="checkType == 1" v-model="expire_date">
<button v-if="checkType == 1" :disabled="!(quantity > 0 && purchase_order)" @click="check(1)">Check in
</button>
<button v-if="checkType == 0" :disabled="!(quantity > 0 && quantity < product.quantity)" @click="check(0)">
Check out
</button>
<button @click="isCheck = false">cancel</button>
</div>

</div>
</template>

<script>
export default {
name: "check-in",
props: ['product'],
data() {
return {
quantity: 0,
checkType: 0,
isCheck: false,
purchase_order: '',
expire_date: ''
}
},
methods: {
check(type) {
var vm = this
if (type === 0) {
var requested = parseInt(vm.quantity);
var lastTransaction;
axios.get(`/api/transaction/filter/${vm.product.id}` ).then(response => {
lastTransaction = response.data
return lastTransaction
}).then(()=>{
while (requested) {

var quantity = lastTransaction.quantity
if (quantity >= requested) {


axios.post('/api/transactions',{
product_id: vm.product.id,
type: type,
display_quantity: requested,
quantity: requested,
purchase_order: lastTransaction.purchase_order,
expiry_date: lastTransaction.expiry_date
}).then(response =>{
vm.$emit('new-value', response.data)
})
requested = 0;
} else if (requested >= quantity) {
lastTransaction.quantity = 0
axios.post('/api/transactions', {
product_id: vm.product.id,
type: type,
display_quantity: quantity,
quantity: quantity,
purchase_order: lastTransaction.purchase_order,
expire_date: lastTransaction.expire_date
}).then(response =>{
vm.$emit('new-value', response.data)
})

requested = requested - quantity;
}

}
})


} else if (type === 1) {
axios.post('/api/transactions', {
purchase_order: vm.purchase_order,
product_id: vm.product.id,
type: type,
display_quantity: vm.quantity,
quantity: vm.quantity,
expire_date: vm.expire_date
}).then(response =>{
vm.$emit('new-value', response.data)
})
}

vm.quantity = 0
}
}
}
</script>

<style scoped>

</style>
<template>
<div>
create Product

<input type="text" v-model="name" placeholder="name">
<input type="text" v-model="purchase_order" placeholder="purchase_number">
<input type="number" placeholder="quantity" v-model="quantity">
<input type="date" v-model="expire_date">
<button :disabled="!(quantity.length > 0)" @click="create">submit</button>
</div>
</template>

<script>
export default {
name: "create_product",
data(){
return{
name: '',
quantity: 0,
purchase_order: '',
expire_date: ''
}
},
methods:{
create(){
axios.post('/api/products', {name: this.name, quantity: this.quantity, purchase_order: this.purchase_order, expire_date: this.expire_date } ).then(response => {

})
}
}
}
</script>

<style scoped>

</style>

<template>
<div>
<ul v-if="products.length">
<li v-for="(product, index) in products">{{product.name}} - {{product.quantity}} <check-in @new-value="checkOperation(index, $event)" :product="product"/></li>
</ul>
<div v-else>No data</div>
</div>
</template>

<script>
import CheckIn from './check-in'
export default {
name: "index_product",
components:{
'check-in': CheckIn
},
data(){
return {
list:[]
}
},
mounted(){
var vm = this
axios.get('/api/products').then(response => {
vm.list = response.data.data
})
},
methods:{
checkOperation(index, event){
var vm = this
vm.list[index].transactions.push(event)
}
},
computed:{
products(){
var vm = this
return _.map(vm.list, function(product){
var transactions = _.filter(product.transactions, function(transaction){
return new Date(transaction.expiry_date).getTime() >= new Date().getTime()
})
product.quantity = _.reduce(transactions, function(sum, transaction) {
return transaction.type == 1 ? sum + _.toInteger(transaction.display_quantity) : sum - _.toInteger(transaction.display_quantity);
}, 0);
return product
})

}
},
}
</script>

<style scoped>

</style>

<template>
<div>
Products
<ul>
<router-link :to="{name: 'create_product'}">Create Product</router-link>
</ul>
<router-view></router-view>


</div>
</template>

<script>
export default {
name: "product"
}
</script>

<style scoped>

</style>

<template>
<div>
Name:{{product.length ? product.name : ''}}
<h4>Transactions</h4>
<ul v-if="product.transactions.length">
<li v-for="transaction in product.transactions"><span style="color: white;"
:style="`background: ${transaction.type === 1 ? 'green' : 'red'}`">{{`purchase order: ${transaction.purchase_order} ${transaction.type === 1 ? 'in' : 'out'} - ${transaction.display_quantity}`}}{{` expire date: ${transaction.expiry_date}`}}</span>
</li>
</ul>
<div v-else>
no data
</div>
</div>
</template>

<script>
export default {
name: "show_product",
data() {
return {
product: {}
}
},
mounted() {
var vm = this
axios.get(`/api/products/${vm.$route.params.id}`).then(response => {
vm.product = response.data
})
},
}
</script>

<style scoped>

</style>


<template>
<div>
<h2>Home</h2>
<ul>
<li>
<router-link to="/">Products</router-link>
</li>
</ul>
<router-view></router-view>
</div>

</template>

<script>
export default {
name: "App"
}
</script>

<style scoped>

</style>

<?php

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Route;
use App\Http\Controllers\ProductController;
use App\Http\Controllers\TransactionController;

/*
|--------------------------------------------------------------------------
| API Routes
|--------------------------------------------------------------------------
|
| Here is where you can register API routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| is assigned the "api" middleware group. Enjoy building your API!
|
*/

Route::middleware('auth:api')->get('/user', function (Request $request) {
return $request->user();
});
Route::apiResources([
'products' => ProductController::class,
'transactions' => TransactionController::class
]);

Route::get('transaction/filter/{product_id}' , [TransactionController::class, 'filter']);

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class Product extends Model
{
use HasFactory;
public $fillable = ['quantity','name'];
public function transactions()
{
return $this->hasMany(Transaction::class);
}

}

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class Transaction extends Model
{
use HasFactory;

public $fillable = [
'purchase_order',
'quantity',
'display_quantity',
'type',
'expiry_date',
];

public function product()
{
return $this->belongsTo(Product::class);
}
}

<?php

namespace App\Http\Controllers;

use App\Models\Product;
use App\Models\Transaction;
use Illuminate\Http\Request;

class ProductController extends Controller
{
/**
* Display a listing of the resource.
*
* @return \Illuminate\Http\Response
*/
public function index()
{
return response()->json(Product::with('transactions')->paginate(10), 201);
}

/**
* Store a newly created resource in storage.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\Response
*/
public function store(Request $request)
{
$product = new Product;
$product->name = $request->name;
$product->quantity = $request->quantity;
$product->save();
$transaction = new Transaction([
'purchase_order' => $request->purchase_order,
'quantity' => $request->quantity,
'display_quantity' => $request->quantity,
'type' => 1,
'expiry_date' => $request->expire_date,
]
);
$product->transactions()->save($transaction);
return response()->json($product, 201);

}

/**
* Display the specified resource.
*
* @param \App\Models\Product $product
* @return \Illuminate\Http\Response
*/
public function show(Product $product)
{
$item = Product::whereId($product->id)->with('transactions')->first();
return response()->json($item);
}

/**
* Update the specified resource in storage.
*
* @param \Illuminate\Http\Request $request
* @param \App\Models\Product $product
* @return \Illuminate\Http\Response
*/
public function update(Request $request, Product $product)
{
//
}

/**
* Remove the specified resource from storage.
*
* @param \App\Models\Product $product
* @return \Illuminate\Http\Response
*/
public function destroy(Product $product)
{
//
}
}

<?php

namespace App\Http\Controllers;

use App\Models\Product;
use App\Models\Transaction;
use Carbon\Carbon;
use Illuminate\Http\Request;

class TransactionController extends Controller
{
/**
* Display a listing of the resource.
*
* @return \Illuminate\Http\Response
*/
public function index()
{
//
}

/**
* Store a newly created resource in storage.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\Response
*/

public function filter($product_id){
$transaction = Transaction::whereProductId($product_id)->whereDate('expiry_date', '>', Carbon::parse()->format('Y-m-d'))->where('quantity', '>', 0)->where('type', 1)->first();
return response()->json($transaction);
}

public function store(Request $request)
{
$product = Product::whereId($request->product_id)->first();
$transaction = new Transaction([
'purchase_order' => $request->purchase_order,
'quantity' => $request->quantity,
'display_quantity' => $request->quantity,
'type' => $request->type,
'expiry_date' => $request->expiry_date,
]
);
$product->transactions()->save($transaction);
return response()->json($transaction);
}

/**
* Display the specified resource.
*
* @param \App\Models\Transaction $transaction
* @return \Illuminate\Http\Response
*/
public function show(Transaction $transaction)
{
//
}

/**
* Update the specified resource in storage.
*
* @param \Illuminate\Http\Request $request
* @param \App\Models\Transaction $transaction
* @return \Illuminate\Http\Response
*/
public function update(Request $request, Transaction $transaction)
{
//
}

/**
* Remove the specified resource from storage.
*
* @param \App\Models\Transaction $transaction
* @return \Illuminate\Http\Response
*/
public function destroy(Transaction $transaction)
{
//
}
}

No comments:

When Bad People Make Good Art

I offer six guidelines on cancel culture ͏     ­͏     ­͏     ­͏     ­͏     ­͏     ­͏     ­͏     ­͏     ­͏     ­͏     ­͏     ­͏     ­͏     ­͏...

Contact Form

Name

Email *

Message *