Compare commits
2 Commits
38c4629302
...
9324f61d05
| Author | SHA1 | Date | |
|---|---|---|---|
| 9324f61d05 | |||
| d1682750dc |
@ -8,6 +8,7 @@ namespace PSTW_CentralSystem.Areas.Inventory.Models
|
|||||||
[Key]
|
[Key]
|
||||||
public int ProductId { get; set; }
|
public int ProductId { get; set; }
|
||||||
public required string ProductName { get; set; }
|
public required string ProductName { get; set; }
|
||||||
|
public required string ProductShortName { get; set; }
|
||||||
public required int ManufacturerId { get; set; }
|
public required int ManufacturerId { get; set; }
|
||||||
public required string Category { get; set; }
|
public required string Category { get; set; }
|
||||||
public required string ModelNo { get; set; }
|
public required string ModelNo { get; set; }
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
using System.ComponentModel.DataAnnotations;
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
using System.Diagnostics.CodeAnalysis;
|
||||||
|
|
||||||
namespace PSTW_CentralSystem.Areas.Inventory.Models
|
namespace PSTW_CentralSystem.Areas.Inventory.Models
|
||||||
{
|
{
|
||||||
@ -6,9 +7,13 @@ namespace PSTW_CentralSystem.Areas.Inventory.Models
|
|||||||
{
|
{
|
||||||
[Key]
|
[Key]
|
||||||
public int SupplierId { get; set; }
|
public int SupplierId { get; set; }
|
||||||
public required string SupplierName { get; set; }
|
public required string SupplierCompName { get; set; }
|
||||||
public required string SupplierGender { get; set; }
|
public required string SupplierAddress { get; set; }
|
||||||
public required string SupplierEmail { get; set; }
|
[AllowNull]
|
||||||
public required string SupplierPhoneNo { get; set; }
|
public string? SupplierPIC { get; set; }
|
||||||
|
[AllowNull]
|
||||||
|
public string? SupplierEmail { get; set; }
|
||||||
|
[AllowNull]
|
||||||
|
public string? SupplierPhoneNo { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -4,6 +4,14 @@
|
|||||||
Layout = "~/Views/Shared/_Layout.cshtml";
|
Layout = "~/Views/Shared/_Layout.cshtml";
|
||||||
}
|
}
|
||||||
<style>
|
<style>
|
||||||
|
@@font-face {
|
||||||
|
font-family: 'OCR-A';
|
||||||
|
src: url('../assets/fonts/ocraext.ttf');
|
||||||
|
}
|
||||||
|
|
||||||
|
.QrPrintFont {
|
||||||
|
font-family: 'OCR-A', monospace;
|
||||||
|
}
|
||||||
.table td img {
|
.table td img {
|
||||||
display: block !important;
|
display: block !important;
|
||||||
}
|
}
|
||||||
@ -45,17 +53,17 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="col-7 d-flex align-items-center justify-content-center">
|
<div class="col-7 d-flex align-items-center justify-content-center">
|
||||||
<div class="text-center fs-4 text">
|
<div class="text-center fs-4 text">
|
||||||
<div class="col-12 my-3">
|
|
||||||
{{thisQRInfo.uniqueID}}
|
|
||||||
</div>
|
|
||||||
<div class="col-12 my-3">
|
<div class="col-12 my-3">
|
||||||
{{thisQRInfo.departmentName}}
|
{{thisQRInfo.departmentName}}
|
||||||
</div>
|
</div>
|
||||||
<div class="col-12 my-3">
|
<div class="col-12 my-3">
|
||||||
{{thisQRInfo.productName}}
|
{{thisQRInfo.productShortName}}
|
||||||
</div>
|
</div>
|
||||||
<div class="col-12 my-3">
|
<div class="col-12 my-3">
|
||||||
{{thisQRInfo.endWDate}}
|
{{thisQRInfo.serialNumber}}
|
||||||
|
</div>
|
||||||
|
<div class="col-12 my-3">
|
||||||
|
{{thisQRInfo.partNumber}}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -554,13 +562,30 @@
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"title": "Category",
|
"title": "Print",
|
||||||
"data": "category",
|
"data": "uniqueID",
|
||||||
|
"render": function (data, type, full, meta) {
|
||||||
|
var printButton = `<button type="button" class="btn btn-success print-btn" data-id="${data}">Print</button>`;
|
||||||
|
return printButton;
|
||||||
|
},
|
||||||
|
"className": "align-middle",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"title": "Item Short Name",
|
||||||
|
"data": "productShortName",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"title": "Serial Number",
|
"title": "Serial Number",
|
||||||
"data": "serialNumber",
|
"data": "serialNumber",
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"title": "Part Number",
|
||||||
|
"data": "partNumber",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"title": "Category",
|
||||||
|
"data": "category",
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"title": "Quantity",
|
"title": "Quantity",
|
||||||
"data": "quantity",
|
"data": "quantity",
|
||||||
@ -601,21 +626,14 @@
|
|||||||
Station: ${currentStation}`
|
Station: ${currentStation}`
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"title": "Print",
|
|
||||||
"data": "uniqueID",
|
|
||||||
"render": function (data, type, full, meta) {
|
|
||||||
var printButton = `<button type="button" class="btn btn-success print-btn" data-id="${data}">Print</button>`;
|
|
||||||
return printButton;
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"title": "Delete",
|
"title": "Delete",
|
||||||
"data": "productId",
|
"data": "itemID",
|
||||||
"render": function (data) {
|
"render": function (data) {
|
||||||
var deleteButton = `<button type="button" class="btn btn-danger delete-btn" data-id="${data}">Delete</button>`;
|
var deleteButton = `<button type="button" class="btn btn-danger delete-btn" data-id="${data}">Delete</button>`;
|
||||||
return deleteButton;
|
return deleteButton;
|
||||||
},
|
},
|
||||||
|
"className": "align-middle",
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
responsive: true,
|
responsive: true,
|
||||||
@ -640,9 +658,9 @@
|
|||||||
correctLevel: QRCode.CorrectLevel.M
|
correctLevel: QRCode.CorrectLevel.M
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
container.on('click', function() {
|
// container.on('click', function() {
|
||||||
window.open(data.qrString, '_blank');
|
// window.open(data.qrString, '_blank');
|
||||||
});
|
// });
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
@ -663,10 +681,10 @@
|
|||||||
// Check if the table is collapsed
|
// Check if the table is collapsed
|
||||||
if ($row.hasClass('child')) {
|
if ($row.hasClass('child')) {
|
||||||
// For collapsed view: Look for the closest `.dtr-data` that contains the img
|
// For collapsed view: Look for the closest `.dtr-data` that contains the img
|
||||||
imageSrc = $row.prev('tr').find('td:first-child img').attr('src');
|
imageSrc = $row.prev('tr').find('td:nth-child(1) img').attr('src');
|
||||||
} else {
|
} else {
|
||||||
// For expanded view: Find the img in the first column of the current row
|
// For expanded view: Find the img in the first column of the current row
|
||||||
imageSrc = $row.find('td:first-child img').attr('src');
|
imageSrc = $row.find('td:nth-child(1) img').attr('src');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (imageSrc) {
|
if (imageSrc) {
|
||||||
@ -837,7 +855,7 @@
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
const response = await fetch(`/InvMainAPI/DeleteProduct/${itemId}`, {
|
const response = await fetch(`/InvMainAPI/DeleteItem/${itemId}`, {
|
||||||
method: 'DELETE',
|
method: 'DELETE',
|
||||||
headers: {
|
headers: {
|
||||||
'Content-Type': 'application/json',
|
'Content-Type': 'application/json',
|
||||||
@ -935,22 +953,22 @@
|
|||||||
|
|
||||||
// Populate the virtual DOM with content
|
// Populate the virtual DOM with content
|
||||||
virtualElement.innerHTML = `
|
virtualElement.innerHTML = `
|
||||||
<div class="container-fluid my-3" style="font-family: 'OCR A', monospace;">
|
<div class="container-fluid my-3 QrPrintFont" style="font-family: 'OCR A', monospace;">
|
||||||
<div class="row" >
|
<div class="row" >
|
||||||
<div class="col-5 text-center d-flex align-items-center justify-content-center">
|
<div class="col-5 text-center d-flex align-items-center justify-content-center">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-12">
|
<div class="col-12">
|
||||||
<div>${this.thisQRInfo.imgContainer}</div>
|
<div>${this.thisQRInfo.imgContainer}</div>
|
||||||
<div class="col-12 h4"><b>${this.thisQRInfo.uniqueID}</b></div>
|
<div class="col-12 h4"style="font-family: 'Arial', monospace;"><b>${this.thisQRInfo.uniqueID}</b></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-7 d-flex align-items-center justify-content-center">
|
<div class="col-7 d-flex align-items-center justify-content-left">
|
||||||
<div class="row-fluid">
|
<div class="row-fluid">
|
||||||
<div class="col-12 h4"><b>${this.thisQRInfo.departmentName}</b></div>
|
<div class="col-12 h3"style="font-family: 'Verdana', monospace;"><b>${this.thisQRInfo.departmentName}</b></div>
|
||||||
<div class="col-12 h4"><b>${this.thisQRInfo.serialNumber??"-"}</b></div>
|
<div class="col-12 h4"style="font-family: 'Arial', monospace;"><b>${this.thisQRInfo.productShortName}</b></div>
|
||||||
<div class="col-12 h4"><b>${this.thisQRInfo.productName}</b></div>
|
<div class="col-12 h4"style="font-family: 'Arial', monospace;"><b>${this.thisQRInfo.serialNumber??"-"}</b></div>
|
||||||
<div class="col-12 h4"><b>${this.thisQRInfo.endWDate}</b></div>
|
<div class="col-12 h4"style="font-family: 'Arial', monospace;"><b>${this.thisQRInfo.partNumber}</b></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -968,7 +986,6 @@
|
|||||||
}).then((canvas) => {
|
}).then((canvas) => {
|
||||||
// Convert the canvas to an image
|
// Convert the canvas to an image
|
||||||
const imgData = canvas.toDataURL('image/png');
|
const imgData = canvas.toDataURL('image/png');
|
||||||
|
|
||||||
// Open the image in a new tab for preview (optional)
|
// Open the image in a new tab for preview (optional)
|
||||||
// const newWindow = window.open();
|
// const newWindow = window.open();
|
||||||
// newWindow.location.href = imgData;
|
// newWindow.location.href = imgData;
|
||||||
|
|||||||
@ -28,6 +28,15 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@* Product Short Name *@
|
||||||
|
<div class="form-group row">
|
||||||
|
<label for="productName" class="col-sm-3">Product Short Name:</label>
|
||||||
|
<div class="col-sm-9">
|
||||||
|
<input type="text" id="productShortName" name="productShortName" class="form-control" maxlength="13" v-model="productShortName" required>
|
||||||
|
<p><em><small class="text-danger">* Product short name limited to 13 characters</small></em></p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
@* Manufacturer *@
|
@* Manufacturer *@
|
||||||
<div class="form-group row">
|
<div class="form-group row">
|
||||||
<label class="col-sm-3">Manufacturer:</label>
|
<label class="col-sm-3">Manufacturer:</label>
|
||||||
@ -126,6 +135,7 @@
|
|||||||
imageSrc: '',
|
imageSrc: '',
|
||||||
products: null,
|
products: null,
|
||||||
productDatatable: null,
|
productDatatable: null,
|
||||||
|
productShortName: null,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
@ -142,6 +152,9 @@
|
|||||||
{ "title": "Product Name",
|
{ "title": "Product Name",
|
||||||
"data": "productName",
|
"data": "productName",
|
||||||
},
|
},
|
||||||
|
{ "title": "Product Short Name",
|
||||||
|
"data": "productShortName",
|
||||||
|
},
|
||||||
{ "title": "Model Number",
|
{ "title": "Model Number",
|
||||||
"data": "modelNo",
|
"data": "modelNo",
|
||||||
},
|
},
|
||||||
@ -225,6 +238,7 @@
|
|||||||
// Create the payload
|
// Create the payload
|
||||||
const formData = {
|
const formData = {
|
||||||
productName: this.productName,
|
productName: this.productName,
|
||||||
|
productShortName: this.productShortName,
|
||||||
manufacturerId: this.manufacturer,
|
manufacturerId: this.manufacturer,
|
||||||
category: this.category,
|
category: this.category,
|
||||||
modelNo: this.modelNo,
|
modelNo: this.modelNo,
|
||||||
|
|||||||
@ -18,30 +18,35 @@
|
|||||||
|
|
||||||
@* Supplier Name *@
|
@* Supplier Name *@
|
||||||
<div class="form-group row">
|
<div class="form-group row">
|
||||||
<label for="supplierName" class="col-sm-3">Supplier Name:</label>
|
<label for="supplierCompName" class="col-sm-3">Supplier Company Name:</label>
|
||||||
<div class="col-sm-9">
|
<div class="col-sm-9">
|
||||||
<input type="text" id="supplierName" name="supplierName" class="form-control" required v-model="supplierName">
|
<input type="text" id="supplierCompName" name="supplierCompName" class="form-control" required v-model="supplierCompName">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@* Supplier Gender *@
|
@* Supplier Gender *@
|
||||||
<div class="form-group row">
|
<div class="form-group row">
|
||||||
<label class="col-sm-3">Supplier Gender:</label>
|
<label class="col-sm-3">Supplier Address:</label>
|
||||||
<div class="col-sm-9">
|
<div class="col-sm-9">
|
||||||
<div class="dropdown">
|
<div class="dropdown">
|
||||||
<select class="btn btn-primary dropdown-toggle w-100" v-model="supplierGender" required data-toggle="dropdown" aria-expanded="false">
|
<textarea type="text" id="supplierAddress" name="supplierAddress" class="form-control" required v-model="supplierAddress"></textarea>
|
||||||
<option value="" selected>Select Gender</option>
|
|
||||||
<option v-for="(item, index) in gender" :key="index" :value="item">{{ item }}</option>
|
|
||||||
</select>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@* Supplier PIC *@
|
||||||
|
<div class="form-group row">
|
||||||
|
<label class="col-sm-3">Supplier PIC:</label>
|
||||||
|
<div class="col-sm-9">
|
||||||
|
<input type="email" id="supplierPIC" name="supplierPIC" class="form-control" v-model="supplierPIC">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
@* Supplier Email *@
|
@* Supplier Email *@
|
||||||
<div class="form-group row">
|
<div class="form-group row">
|
||||||
<label class="col-sm-3">Supplier Email:</label>
|
<label class="col-sm-3">Supplier Email:</label>
|
||||||
<div class="col-sm-9">
|
<div class="col-sm-9">
|
||||||
<input type="email" id="supplierName" name="supplierEmail" class="form-control" required v-model="supplierEmail">
|
<input type="email" id="supplierEmail" name="supplierEmail" class="form-control" v-model="supplierEmail">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -49,7 +54,7 @@
|
|||||||
<div class="form-group row">
|
<div class="form-group row">
|
||||||
<label class="col-sm-3">Supplier Phone Number:</label>
|
<label class="col-sm-3">Supplier Phone Number:</label>
|
||||||
<div class="col-sm-9">
|
<div class="col-sm-9">
|
||||||
<input type="tel" id="supplierPhoneNo" name="supplierPhoneNo" class="form-control" required v-model="supplierPhoneNo">
|
<input type="tel" id="supplierPhoneNo" name="supplierPhoneNo" class="form-control" v-model="supplierPhoneNo">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -97,10 +102,11 @@
|
|||||||
const app = Vue.createApp({
|
const app = Vue.createApp({
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
supplierName : null,
|
supplierCompName : null,
|
||||||
supplierEmail : null,
|
supplierEmail : null,
|
||||||
supplierGender : '',
|
supplierAddress : null,
|
||||||
supplierPhoneNo : null,
|
supplierPhoneNo : null,
|
||||||
|
supplierPIC : null,
|
||||||
suuppliers: null,
|
suuppliers: null,
|
||||||
supplierDatatable: null,
|
supplierDatatable: null,
|
||||||
gender: ["Male", "Female", "Helicopter"],
|
gender: ["Male", "Female", "Helicopter"],
|
||||||
@ -145,15 +151,16 @@
|
|||||||
$('#loadingModal').modal('show');
|
$('#loadingModal').modal('show');
|
||||||
// Create the payload
|
// Create the payload
|
||||||
const formData = {
|
const formData = {
|
||||||
supplierName: this.supplierName,
|
supplierCompName: this.supplierCompName,
|
||||||
|
supplierAddress: this.supplierAddress,
|
||||||
|
supplierPIC: this.supplierPIC,
|
||||||
supplierEmail: this.supplierEmail,
|
supplierEmail: this.supplierEmail,
|
||||||
supplierGender: this.supplierGender,
|
supplierPhoneNo: this.supplierPhoneNo,
|
||||||
supplierPhoneNo: this.supplierPhoneNo
|
|
||||||
};
|
};
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// List of required fields
|
// List of required fields
|
||||||
const requiredFields = ['supplierName', 'supplierEmail', 'supplierGender', 'supplierPhoneNo'];
|
const requiredFields = ['supplierCompName', 'supplierAddress'];
|
||||||
|
|
||||||
// Loop through required fields and check if any are null or empty
|
// Loop through required fields and check if any are null or empty
|
||||||
for (let field of requiredFields) {
|
for (let field of requiredFields) {
|
||||||
@ -196,10 +203,11 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
resetForm() {
|
resetForm() {
|
||||||
this.supplierName = null;
|
this.supplierCompName = null;
|
||||||
|
this.supplierAddress = null;
|
||||||
this.supplierEmail = null;
|
this.supplierEmail = null;
|
||||||
this.supplierGender = '';
|
|
||||||
this.supplierPhoneNo = null;
|
this.supplierPhoneNo = null;
|
||||||
|
this.supplierPIC = null;
|
||||||
},
|
},
|
||||||
initiateTable() {
|
initiateTable() {
|
||||||
self = this;
|
self = this;
|
||||||
@ -207,12 +215,16 @@
|
|||||||
"data": this.suppliers,
|
"data": this.suppliers,
|
||||||
"columns": [
|
"columns": [
|
||||||
{
|
{
|
||||||
"title": "Supplier Name",
|
"title": "Supplier Company Name",
|
||||||
"data": "supplierName",
|
"data": "supplierCompName",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"title": "Supplier Gender",
|
"title": "Supplier Address",
|
||||||
"data": "supplierGender",
|
"data": "supplierAddress",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"title": "Company PIC",
|
||||||
|
"data": "supplierPIC",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"title": "Supplier Email",
|
"title": "Supplier Email",
|
||||||
|
|||||||
@ -17,17 +17,36 @@
|
|||||||
<div v-if="reportData">
|
<div v-if="reportData">
|
||||||
<div class="row justify-content-center">
|
<div class="row justify-content-center">
|
||||||
<div class="col-3">
|
<div class="col-3">
|
||||||
<h4>Statistic</h4>
|
<div class="row col-10">
|
||||||
<select class="form-select shadow-none mt-3" v-model="selectedDepartment" v-on:change="">
|
<h4>Department</h4>
|
||||||
<option value="" disabled selected>Please select</option>
|
<multiselect v-model="selectedDepartment" :options="compDeptList" :multiple="true" group-values="departments" group-label="companyName"
|
||||||
<option v-for="(dept, index) in compDeptList" :key="index" :value="dept.departmentId">{{ dept.departmentName }}</option>
|
:group-select="true" placeholder="Seach Department" track-by="departmentId" label="departmentName">
|
||||||
</select>
|
</multiselect>
|
||||||
|
<div class=""><button class="btn btn-danger" v-on:click="selectedDepartment = []">Clear</button></div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-3">
|
<div class="col-3">
|
||||||
<h4>Item Registered </h4>
|
<div class="row col-10">
|
||||||
|
<h4>Category</h4>
|
||||||
|
<multiselect v-model="selectedCategory" :options="categoryList" :multiple="true" placeholder="Seach Category">
|
||||||
|
</multiselect>
|
||||||
|
<div class=""><button class="btn btn-danger" v-on:click="selectedCategory = []">Clear</button></div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-3">
|
<div class="col-3">
|
||||||
<h4>Item Stock Out </h4>
|
<div class="row col-10">
|
||||||
|
<h4>Product</h4>
|
||||||
|
<multiselect v-model="selectedItem" :options="selectedCategory.length == 0 && selectedDepartment.length == 0 ? productList : filteredProduct " :multiple="true" placeholder="Seach Product" track-by="productId" label="productName">
|
||||||
|
</multiselect>
|
||||||
|
<div class=""><button class="btn btn-danger" v-on:click="selectedItem = []">Clear</button></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-3">
|
||||||
|
<div class="row col-10">
|
||||||
|
<h4>Date filter</h4>
|
||||||
|
<vue-date-picker v-model="selectedMonth" month-picker range></vue-date-picker>
|
||||||
|
<div class=""><button class="btn btn-danger" v-on:click="selectedMonth = []">Clear</button></div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -67,13 +86,16 @@
|
|||||||
<script>
|
<script>
|
||||||
$(function () {
|
$(function () {
|
||||||
app.mount('#invAdmin');
|
app.mount('#invAdmin');
|
||||||
|
|
||||||
$('.closeModal').on('click', function () {
|
$('.closeModal').on('click', function () {
|
||||||
// Show the modal with the ID 'addManufacturerModal'.
|
// Show the modal with the ID 'addManufacturerModal'.
|
||||||
$('.modal').modal('hide');
|
$('.modal').modal('hide');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
const app = Vue.createApp({
|
const app = Vue.createApp({
|
||||||
|
components: {
|
||||||
|
'multiselect': window.VueMultiselect.default,
|
||||||
|
VueDatePicker,
|
||||||
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
currentUser: null,
|
currentUser: null,
|
||||||
@ -83,13 +105,30 @@
|
|||||||
},
|
},
|
||||||
reportData: null,
|
reportData: null,
|
||||||
compDeptList: {},
|
compDeptList: {},
|
||||||
selectedDepartment: null,
|
productList: {},
|
||||||
|
categoryList:['Asset', 'Part', 'Disposable'],
|
||||||
|
monthList: ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'],
|
||||||
|
filteredProduct: [],
|
||||||
|
selectedMonth: [],
|
||||||
|
selectedDepartment: [],
|
||||||
|
selectedItem: [],
|
||||||
|
selectedCategory: []
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
this.fetchUser();
|
this.fetchUser();
|
||||||
|
this.fetchProductList();
|
||||||
this.fetchDepartmentsCompaniesList();
|
this.fetchDepartmentsCompaniesList();
|
||||||
},
|
},
|
||||||
|
watch: {
|
||||||
|
//watch selectedDepartment. when selectedDepartment is changed, if selectedCategory is null filter productList based on selectedDepartment only. otherwise filter the productList based on selectedDepartment and selectedCategory
|
||||||
|
selectedDepartment() {
|
||||||
|
this.filterProducts();
|
||||||
|
},
|
||||||
|
selectedCategory() {
|
||||||
|
this.filterProducts();
|
||||||
|
}
|
||||||
|
},
|
||||||
methods: {
|
methods: {
|
||||||
async fetchUser() {
|
async fetchUser() {
|
||||||
try {
|
try {
|
||||||
@ -142,25 +181,60 @@
|
|||||||
});
|
});
|
||||||
if (response.ok) {
|
if (response.ok) {
|
||||||
const data = await response.json();
|
const data = await response.json();
|
||||||
this.compDeptList = data.map(company => company.departments.map(department =>
|
this.compDeptList = data;
|
||||||
({
|
|
||||||
companyId: company.companyId,
|
|
||||||
companyName: company.companyName,
|
|
||||||
departmentId: department.departmentId,
|
|
||||||
departmentName: department.departmentName,
|
|
||||||
departmentCode: department.departmentCode
|
|
||||||
})
|
|
||||||
)).flat();
|
|
||||||
console.log(this.compDeptList);
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
console.error(`Failed to fetch comapny & department list: ${response.statusText}`);
|
console.error(`Failed to fetch company & department list: ${response.statusText}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (error) {
|
catch (error) {
|
||||||
console.error('There was a problem with the fetch operation:', error);
|
console.error('There was a problem with the fetch operation:', error);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
async fetchProductList(){
|
||||||
|
try {
|
||||||
|
const response = await fetch(`/InvMainAPI/ItemList/`, {
|
||||||
|
method: 'POST',
|
||||||
|
});
|
||||||
|
if (response.ok) {
|
||||||
|
const data = await response.json();
|
||||||
|
this.productList = data;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
console.error(`Failed to fetch item list: ${response.statusText}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (error) {
|
||||||
|
console.error('There was a problem with the fetch operation:', error);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
filterProducts() {
|
||||||
|
const selectedDepartmentIds = this.selectedDepartment.map(department => department.departmentId);
|
||||||
|
const selectedCategory = this.selectedCategory;
|
||||||
|
if (selectedDepartmentIds.length === 0 && selectedCategory.length === 0) {
|
||||||
|
// No filters applied
|
||||||
|
this.filteredProduct = this.productList;
|
||||||
|
}
|
||||||
|
else if (selectedDepartmentIds.length === 0) {
|
||||||
|
// Filter by category only
|
||||||
|
this.filteredProduct = this.productList.filter(product =>
|
||||||
|
selectedCategory.includes(product.category)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else if (selectedCategory.length === 0) {
|
||||||
|
// Filter by department only
|
||||||
|
this.filteredProduct = this.productList.filter(product =>
|
||||||
|
selectedDepartmentIds.includes(product.departmentId)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// Filter by both department and category
|
||||||
|
this.filteredProduct = this.productList.filter(product =>
|
||||||
|
selectedDepartmentIds.includes(product.departmentId) &&
|
||||||
|
selectedCategory.includes(product.category)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@ -261,7 +261,7 @@ namespace PSTW_CentralSystem.Controllers.API.Inventory
|
|||||||
}
|
}
|
||||||
|
|
||||||
var userRole = await _userManager.GetRolesAsync(user);
|
var userRole = await _userManager.GetRolesAsync(user);
|
||||||
var isAdmin = userRole.Contains("SystemAdmin") || userRole.Contains("SuperAdmin");
|
var isAdmin = userRole.Contains("SystemAdmin") || userRole.Contains("SuperAdmin") || userRole.Contains("Finance");
|
||||||
List<ItemModel> itemList = new List<ItemModel>();
|
List<ItemModel> itemList = new List<ItemModel>();
|
||||||
// Get the item list
|
// Get the item list
|
||||||
if (isAdmin)
|
if (isAdmin)
|
||||||
@ -324,6 +324,7 @@ namespace PSTW_CentralSystem.Controllers.API.Inventory
|
|||||||
item.Department?.DepartmentName,
|
item.Department?.DepartmentName,
|
||||||
CreatedBy=item.CreatedBy!.UserName,
|
CreatedBy=item.CreatedBy!.UserName,
|
||||||
item.Product!.ProductName,
|
item.Product!.ProductName,
|
||||||
|
item.Product!.ProductShortName,
|
||||||
item.Product!.Category,
|
item.Product!.Category,
|
||||||
//CurrentUser = item.Movement?.FromUser?.UserName,
|
//CurrentUser = item.Movement?.FromUser?.UserName,
|
||||||
CurrentUser = item.Movement?.FromUser?.UserName,
|
CurrentUser = item.Movement?.FromUser?.UserName,
|
||||||
@ -495,6 +496,7 @@ namespace PSTW_CentralSystem.Controllers.API.Inventory
|
|||||||
item.Department?.DepartmentName,
|
item.Department?.DepartmentName,
|
||||||
item.CreatedBy!.UserName,
|
item.CreatedBy!.UserName,
|
||||||
item.Product!.ProductName,
|
item.Product!.ProductName,
|
||||||
|
item.Product!.ProductShortName,
|
||||||
item.Product!.ImageProduct,
|
item.Product!.ImageProduct,
|
||||||
QRString = $"{HttpContext.Request.Scheme}://{HttpContext.Request.Host.Value}/I/{item.UniqueID}" // Generate QR String
|
QRString = $"{HttpContext.Request.Scheme}://{HttpContext.Request.Host.Value}/I/{item.UniqueID}" // Generate QR String
|
||||||
};
|
};
|
||||||
@ -553,6 +555,7 @@ namespace PSTW_CentralSystem.Controllers.API.Inventory
|
|||||||
item.Department?.DepartmentName,
|
item.Department?.DepartmentName,
|
||||||
CreatedBy = item.CreatedBy!.UserName,
|
CreatedBy = item.CreatedBy!.UserName,
|
||||||
item.Product!.ProductName,
|
item.Product!.ProductName,
|
||||||
|
item.Product!.ProductShortName,
|
||||||
item.Product!.Category,
|
item.Product!.Category,
|
||||||
//CurrentUser = item.Movement?.FromUser?.UserName,
|
//CurrentUser = item.Movement?.FromUser?.UserName,
|
||||||
CurrentUser = item.Movement?.FromUser?.UserName,
|
CurrentUser = item.Movement?.FromUser?.UserName,
|
||||||
|
|||||||
@ -76,6 +76,7 @@ namespace PSTW_CentralSystem.Controllers.API.Reporting
|
|||||||
item.Department?.DepartmentName,
|
item.Department?.DepartmentName,
|
||||||
CreatedBy = item.CreatedBy!.UserName,
|
CreatedBy = item.CreatedBy!.UserName,
|
||||||
item.Product!.ProductName,
|
item.Product!.ProductName,
|
||||||
|
item.Product!.ProductShortName,
|
||||||
item.Product!.Category,
|
item.Product!.Category,
|
||||||
//CurrentUser = item.Movement?.FromUser?.UserName,
|
//CurrentUser = item.Movement?.FromUser?.UserName,
|
||||||
CurrentUser = item.Movement?.FromUser?.UserName,
|
CurrentUser = item.Movement?.FromUser?.UserName,
|
||||||
|
|||||||
@ -22,7 +22,7 @@
|
|||||||
type="image/png"
|
type="image/png"
|
||||||
sizes="16x16"
|
sizes="16x16"
|
||||||
href="/assets/images/favicon.png" />
|
href="/assets/images/favicon.png" />
|
||||||
<link href="https://fonts.googleapis.com/css2?family=OCR+A&display=swap" rel="stylesheet">
|
|
||||||
|
|
||||||
<!-- Custom CSS -->
|
<!-- Custom CSS -->
|
||||||
<link rel="stylesheet" href="~/assets/libs/select2/dist/css/select2.min.css" />
|
<link rel="stylesheet" href="~/assets/libs/select2/dist/css/select2.min.css" />
|
||||||
@ -38,6 +38,9 @@
|
|||||||
@* <script src="~/js/vue.global.prod.js"></script> *@
|
@* <script src="~/js/vue.global.prod.js"></script> *@
|
||||||
<!-- QR Js -->
|
<!-- QR Js -->
|
||||||
<script src="~/lib/qrcode/qrcode.min.js"></script>
|
<script src="~/lib/qrcode/qrcode.min.js"></script>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<!-- HTML5 Shim and Respond.js IE8 support of HTML5 elements and media queries -->
|
<!-- HTML5 Shim and Respond.js IE8 support of HTML5 elements and media queries -->
|
||||||
<!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
|
<!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
|
||||||
<!--[if lt IE 9]>
|
<!--[if lt IE 9]>
|
||||||
@ -47,6 +50,7 @@
|
|||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<style>
|
<style>
|
||||||
|
|
||||||
.btn-teal {
|
.btn-teal {
|
||||||
background-color: #20c997; /* Teal color */
|
background-color: #20c997; /* Teal color */
|
||||||
color: #ffffff; /* White text */
|
color: #ffffff; /* White text */
|
||||||
@ -740,6 +744,12 @@
|
|||||||
<script src="~/assets/libs/jquery/dist/jquery.min.js"></script>
|
<script src="~/assets/libs/jquery/dist/jquery.min.js"></script>
|
||||||
@* <script src="~/dist/js/jquery.ui.touch-punch-improved.js"></script> *@
|
@* <script src="~/dist/js/jquery.ui.touch-punch-improved.js"></script> *@
|
||||||
<script src="~/dist/js/jquery-ui.min.js"></script>
|
<script src="~/dist/js/jquery-ui.min.js"></script>
|
||||||
|
<!-- VUE Multiselect-->
|
||||||
|
<script src="~/lib/vue-multiselect/vue-multiselect.js"></script>
|
||||||
|
<link href="~/lib/vue-multiselect/vue-multiselect.min.css" rel="stylesheet" />
|
||||||
|
<!-- VUE Date Picker-->
|
||||||
|
<link href="~/lib/vue-datepicker/mainvuedate.css" rel="stylesheet" />
|
||||||
|
<script src="~/lib/vue-datepicker/vue-datepicker.iife.js"></script>
|
||||||
<!-- Bootstrap tether Core JavaScript -->
|
<!-- Bootstrap tether Core JavaScript -->
|
||||||
<script src="~/assets/libs/bootstrap/dist/js/bootstrap.bundle.min.js"></script>
|
<script src="~/assets/libs/bootstrap/dist/js/bootstrap.bundle.min.js"></script>
|
||||||
<!-- slimscrollbar scrollbar JavaScript -->
|
<!-- slimscrollbar scrollbar JavaScript -->
|
||||||
|
|||||||
BIN
wwwroot/assets/Fonts/OCRAEXT.TTF
Normal file
BIN
wwwroot/assets/Fonts/OCRAEXT.TTF
Normal file
Binary file not shown.
1
wwwroot/lib/Vue-DatePicker/mainVueDate.css
Normal file
1
wwwroot/lib/Vue-DatePicker/mainVueDate.css
Normal file
File diff suppressed because one or more lines are too long
1
wwwroot/lib/Vue-DatePicker/vue-datepicker.iife.js
Normal file
1
wwwroot/lib/Vue-DatePicker/vue-datepicker.iife.js
Normal file
File diff suppressed because one or more lines are too long
1358
wwwroot/lib/Vue-MultiSelect/vue-multiselect.js
Normal file
1358
wwwroot/lib/Vue-MultiSelect/vue-multiselect.js
Normal file
File diff suppressed because it is too large
Load Diff
1
wwwroot/lib/Vue-MultiSelect/vue-multiselect.min.css
vendored
Normal file
1
wwwroot/lib/Vue-MultiSelect/vue-multiselect.min.css
vendored
Normal file
File diff suppressed because one or more lines are too long
2
wwwroot/lib/Vue-MultiSelect/vue-multiselect.umd.min.js
vendored
Normal file
2
wwwroot/lib/Vue-MultiSelect/vue-multiselect.umd.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
Loading…
Reference in New Issue
Block a user