Initial commit

This commit is contained in:
Senad Uka
2018-06-11 11:09:35 +02:00
commit ed7df7b11f
1954 changed files with 483354 additions and 0 deletions

View File

@@ -0,0 +1,184 @@
<?php
/**
* SuppliersController controls the actions for suppliers
*/
class SuppliersController{
private $model;
function __construct(){
$this->model = new SuppliersModel();
}
/**
* returns json array with table headers for suppliers
* @return list all columns headers
*/
public function getSuppliersHeaders(){
echo json_encode($this->model->getSuppliersHeaders('array'));
}
/**
* returns json response for suppliers
* @return list suppliers json
*/
public function getSuppliers(){
$getArray = isset($_REQUEST['getArray']) ? $_REQUEST['getArray'] : false;
$data = ['data' => $this->model->getSuppliers($getArray)];
echo json_encode($data);
}
/**
* returns json response for suppliers products
* @return list all products for suppliers json
*/
public function getSuppliersProducts(){
$idCountry = isset($_REQUEST['idCountry']) ? $_REQUEST['idCountry'] : 0;
$idProduct = isset($_REQUEST['idProduct']) ? $_REQUEST['idProduct'] : 0;
$data = ['data' => $this->model->getSuppliersProducts($idCountry, $idProduct)];
echo json_encode($data);
}
/**
* returns json array with table headers for suppliers products
* @return list all columns headers
*/
public function getSuppliersProductsHeaders(){
echo json_encode($this->model->getSuppliersProductsHeaders('array'));
}
/**
* parse input for suppliers info
* @return Array suppliers info
*/
private function parseSuppliersData(){
return [
'idSupplier' => isset($_REQUEST['idSupplier']) ? $_REQUEST['idSupplier'] : 0,
'name' => isset($_REQUEST['name']) ? $_REQUEST['name'] : '',
'phone' => isset($_REQUEST['phone']) ? $_REQUEST['phone'] : '',
'mail' => isset($_REQUEST['mail']) ? $_REQUEST['mail'] : '',
'vatCode' => isset($_REQUEST['vatCode']) ? $_REQUEST['vatCode'] : ''
];
}
/**
* edit supplier
* @return json message for the update
*/
public function editSupplier(){
$supplierData = $this->parseSuppliersData();
echo json_encode($this->model->editSupplier($supplierData));
}
/**
* parse input for prodcut
* @return Array product infos
*/
private function parseProductData(){
return [
'idCountry' => isset($_REQUEST['idCountry']) ? $_REQUEST['idCountry'] : 0,
'idProduct' => isset($_REQUEST['idProduct']) ? $_REQUEST['idProduct'] : 0,
'idSupplier' => isset($_REQUEST['idSupplier']) ? $_REQUEST['idSupplier'] : 0,
'idProductCategory' => isset($_REQUEST['productCategory']['id']) ? $_REQUEST['productCategory']['id'] : 0,
'name' => isset($_REQUEST['name']) ? $_REQUEST['name'] : '',
'description' => isset($_REQUEST['description']) ? $_REQUEST['description'] : '',
'unitCostPrice' => isset($_REQUEST['unitCostPrice']) ? $_REQUEST['unitCostPrice'] : '',
'unitVatCost' => isset($_REQUEST['unitVatCost']) ? $_REQUEST['unitVatCost'] : '',
'manufacturerProductNo' => isset($_REQUEST['manufacturerProductNo']) ? $_REQUEST['manufacturerProductNo'] : '',
'supplierProductNo' => isset($_REQUEST['supplierProductNo']) ? $_REQUEST['supplierProductNo'] : '',
'unit' => isset($_REQUEST['unit']) ? $_REQUEST['unit'] : '',
'isPriceRecurring' => isset($_REQUEST['isPriceRecurring']) ? $_REQUEST['isPriceRecurring'] : '',
'payPeriod' => isset($_REQUEST['payPeriod']) ? $_REQUEST['payPeriod'] : 0,
'isAvailable' => isset($_REQUEST['isAvailable']) ? $_REQUEST['isAvailable'] : 1
];
}
/**
* controll for adding a new supplier
* @return json message for the insert
*/
public function addSupplierProduct(){
$productData = $this->parseProductData();
echo json_encode($this->model->addSupplierProduct($productData));
}
/**
* controll for product edit
* @return json message for the update
*/
public function editSupplierProduct(){
$productData = $this->parseProductData();
echo json_encode($this->model->editSupplierProduct($productData));
}
/**
* upload product documents
* @return json messsage for upload documents
*/
public function uploadProductDocument(){
$file = isset($_FILES['file']) ? $_FILES['file'] : [];
$idSupplierProduct = isset($_REQUEST['idSupplierProduct']) ? $_REQUEST['idSupplierProduct'] : 0;
$idDocumentType = isset($_REQUEST['idDocumentType']) ? $_REQUEST['idDocumentType'] : 0;
$documentName = isset($_REQUEST['documentName']) ? $_REQUEST['documentName'] : '';
$visibleToCustomer = isset($_REQUEST['visibleToCustomer']) ? $_REQUEST['visibleToCustomer'] : null;
echo json_encode($this->model->uploadProductDocument($idDocumentType, $idSupplierProduct, $documentName, $visibleToCustomer, $file));
}
/**
* remove product documents
* @return json remove documents for products
*/
public function removeProductDocument(){
$idDocument = isset($_REQUEST['idDocument']) ? $_REQUEST['idDocument'] : 0;
echo json_encode($this->model->removeProductDocument($idDocument));
}
/**
* include suppliers template
*/
public function suppliersTemplate(){
global $user;
require_once('templates/SuppliersTemplate.php');
}
/**
* include suppliers template
*/
public function suppliersAddEditFormTemplate(){
require_once('templates/SuppliersAddEditFormTemplate.php');
}
/**
* include suppliers template
*/
public function suppliersProductsAddEditFormTemplate(){
require_once('templates/SuppliersProductsAddEditFormTemplate.php');
}
/**
* get product categories
*/
public function getProductCategories() {
echo json_encode($this->model->getProductCategories());
}
/**
* include upload product document template template
*/
public function uploadProductDocumentTempalte() {
require_once('templates/UploadProductDocumentTempalte.php');
}
public function showProductDocumentsTemplate() {
require_once('templates/ShowProductDocumentsTemplate.php');
}
/**
* open suppliers page
*/
public function showPage(){
require_once('SuppliersPage.php');
}
}
?>

View File

@@ -0,0 +1,240 @@
<?php
class SuppliersModel{
private $headersHelper;
private $suppliersProducts;
function __construct(){
$this->headersHelper = new HeadersHelper();
$this->suppliersProducts = new SuppliersProducts();
}
/**
* Get the headers requried for the suppliers
* @param string $type type of the headere, posible values array or sql
* @return string|array returns the sql header or the array of for the headers
*/
public function getSuppliersHeaders( $type = 'array'){
$headers = [
's.id' => 'id',
's.name' => 'name',
's.phone' => 'phone',
'u.mail' => 'mail',
'GROUP_CONCAT(countries.countryName)' => 'sellsIn'
];
return $this->headersHelper->getHeader($headers, $type);
}
/**
* get the list of suppliers
* @return Array array of suppliers
*/
public function getSuppliers(){
global $database;
$headersSql = $this->getSuppliersHeaders('sql');
$sql = "SELECT $headersSql
FROM
".TABLES['suppliers']." s
LEFT OUTER JOIN
(
SELECT DISTINCT scp.idSupplier, c.name as countryName
FROM ".TABLES['suppliers_countries_products']." scp
INNER JOIN ".TABLES['countries']." c
ON c.id=scp.idCountry
) AS countries
ON s.id=countries.idSupplier
INNER JOIN ".TABLES['users']." u
ON u.id = s.idUser
GROUP BY s.id
ORDER BY s.name";
return $database->fetchResultArray($sql);
}
/**
* Get the headers requried for products for the suppliers
* @param string $type type of the headere, posible values array or sql
* @return string|array returns the sql header or the array of for the headers
*/
public function getSuppliersProductsHeaders( $type = 'array'){
return $this->suppliersProducts->getSuppliersProductsHeaders($type);
}
/**
* get the list with all products for a country
* @param integer $country id of the country to get the products
* @return Array array with all productus for the suppiers in a specific country
*/
public function getSuppliersProducts($idCountry = 0, $idProduct = 0){
return $this->suppliersProducts->getSuppliersProducts($idCountry, $idProduct);
}
/**
* check if supplier data is valid
* @param HashArray $supplierData suppliers input
* @return Array empty array if vali or error message array
*/
private function validateSupplierData($supplierData, $action){
global $database;
$data = [];
$whereSql = $action === 'edit' ? ' AND s.id!='.$supplierData['idSupplier'] : '';
$sql = "SELECT s.id
FROM ".TABLES['suppliers']." s
WHERE s.name='".$supplierData['name']."' $whereSql
LIMIT 1";
$query = $database->query($sql);
if($database->numRows($query) !== 0){
$data['messages'][] = [
'code' => 'error',
'message' => 'DUPLICATE_SUPPLIER_NAME'
];
return $data;
}
$checkMessage = $database->isEmpty('name', $supplierData['name']);
if($checkMessage){
$data['messages'][] = $checkMessage;
}
$checkMessage = $database->invalidLength('name', $supplierData['name'], 70);
if($checkMessage){
$data['messages'][] = $checkMessage;
}
$checkMessage = $database->isEmpty('phone', $supplierData['phone']);
if($checkMessage){
$data['messages'][] = $checkMessage;
}
$checkMessage = $database->invalidLength('phone', $supplierData['phone'], 40);
if($checkMessage){
$data['messages'][] = $checkMessage;
}
if(!preg_match('/^([0-9\(\)\/\+ \-]*)$/', $supplierData['phone'])){
$data['messages'][] = [
'code' => 'error',
'message' => 'INVALID_NUMBER',
'key' => 'phone'
];
}
$checkMessage = $database->isEmpty('mail', $supplierData['mail']);
if($checkMessage){
$data['messages'][] = $checkMessage;
}
$checkMessage = $database->invalidLength('mail', $supplierData['mail'], 200);
if($checkMessage){
$data['messages'][] = $checkMessage;
}
if(!filter_var( $supplierData['mail'], FILTER_VALIDATE_EMAIL)){
$data['messages'][] = [
'code' => 'error',
'message' => 'INVALID_MAIL',
'key' => 'mail'
];
}
return $data;
}
/**
* eddit supplier
* @param HashArray $supplierData supplier data input
* @return Array update message
*/
public function editSupplier($supplierData){
global $database;
$affectedRows = 0;
foreach ($supplierData as $key => $value) {
$supplierData[$key] = $database->escapeValue($value);
}
$data = $this->validateSupplierData($supplierData, 'edit');
if(!empty($data)){
return $data;
}
$sql = "UPDATE ".TABLES['suppliers']."
SET name='".$supplierData['name']."',
phone='".$supplierData['phone']."'
WHERE id='".$supplierData['idSupplier']."'
LIMIT 1";
$query = $database->query($sql);
$affectedRows = $database->affectedRows();
$sql = "UPDATE ".TABLES['users']."
SET mail='".$supplierData['mail']."'
WHERE id=(
SELECT idUser
FROM ".TABLES['suppliers']."
WHERE id = ".$supplierData['idSupplier']."
)";
$query = $database->query($sql);
$affectedRows += $database->affectedRows();
if($affectedRows < 1){
$data['messages'][] = [
'code' => 'warning',
'message' => 'NO_CHANGES'
];
return $data;
}
$data['messages'][] = [
'code' => 'success',
'message' => 'SUPPLIER_EDITED'
];
return $data;
}
/**
* add new product
* @param HashArray $productData product data input
* @return Array insert message
*/
public function addSupplierProduct($productData){
return $this->suppliersProducts->addSupplierProduct($productData);
}
/**
* edit product data
* @param HashArray $productData product data input
* @return Array update message
*/
public function editSupplierProduct($productData){
return $this->suppliersProducts->editSupplierProduct($productData);
}
/**
* @return Array id and name of the available product categories
*/
public function getProductCategories() {
return $this->suppliersProducts->getProductCategories();
}
/**
* upload document for a product
* @param INT $idDocumentType id for document type
* @param INT $idSupplierProduct id for product
* @param String $documentName name for the document
* @param INT $visibleToCustomer document will be visible for customer
* @param FILE $file file to be uploaded
* @return ARRAY upload message
*/
public function uploadProductDocument($idDocumentType, $idSupplierProduct, $documentName, $visibleToCustomer, $file) {
return $this->suppliersProducts->uploadProductDocument($idDocumentType, $idSupplierProduct, $documentName, $visibleToCustomer, $file);
}
/**
* remove product documents
* @param INT $idDocument id for document
* @return Array update message
*/
public function removeProductDocument($idDocument){
return $this->suppliersProducts->removeProductDocument($idDocument);
}
}
?>

View File

@@ -0,0 +1,10 @@
<script src="<?php echo PATH_JS_COMPONENTS.'suppliers/suppliers.directive.js?v='.APPLICATION_VERSION;?>" type="text/javascript"></script>
<script src="<?php echo PATH_JS_COMPONENTS.'suppliers/suppliers-add-edit.directive.js?v='.APPLICATION_VERSION;?>" type="text/javascript"></script>
<script src="<?php echo PATH_JS_COMPONENTS.'suppliers/suppliers-products-add-edit.directive.js?v='.APPLICATION_VERSION;?>" type="text/javascript"></script>
<script src="<?php echo PATH_JS_COMPONENTS.'suppliers/upload-product-document.directive.js?v='.APPLICATION_VERSION;?>" type="text/javascript"></script>
<script src="<?php echo PATH_JS_COMPONENTS.'suppliers/show-product-documents.directive.js?v='.APPLICATION_VERSION;?>" type="text/javascript"></script>
<div id="suppliers-module" class="container-fluid col-md-12">
<h1>{{ 'suppliers.TITLE' | translate }}</h1>
<suppliers ng-controller="suppliersController"></suppliers>
</div>

View File

@@ -0,0 +1,518 @@
<?php
class SuppliersProducts {
private $headersHelper;
function __construct(){
$this->headersHelper = new HeadersHelper();
}
/**
* add new product
* @param HashArray $productData product data input
* @return Array insert message
*/
public function addSupplierProduct($productData){
global $database;
foreach ($productData as $key => $value) {
$productData[$key] = $database->escapeValue($value);
}
if(intval($productData['isPriceRecurring']) === 0){
$productData['payPeriod'] = 0;
}
$data = $this->validateProductData($productData, 'add');
if(!empty($data)){
return $data;
}
$sql = "INSERT INTO ".TABLES['suppliers_countries_products']."
(idCountry, idSupplier, idProductCategory, unitCostPrice, unitVatCost, productName, productDescription, manufacturerProductNo, supplierProductNo, unit, isPriceRecurring, payPeriod)
VALUES('".$productData['idCountry']."',
'".$productData['idSupplier']."',
'".$productData['idProductCategory']."',
'".$productData['unitCostPrice']."',
'".$productData['unitVatCost']."',
'".$productData['name']."',
'".$productData['description']."',
'".$productData['manufacturerProductNo']."',
'".$productData['supplierProductNo']."',
'".$productData['unit']."',
'".$productData['isPriceRecurring']."',
'".$productData['payPeriod']."'
)";
$query = $database->query($sql);
if($database->affectedRows() !== 1){
$data['messages'][] =[
'code' => 'error',
'message' => 'SERVER_ERROR'
];
return $data;
}
$data['messages'][] = [
'code' => 'success',
'message' => 'SUPPLIER_PRODCT_ADDED'
];
return $data;
}
public function updatePackageAvailability($idProduct = 0, $idPackage =0){
global $database;
$whereSql = " 1=1 ";
if($idProduct !== 0){
$whereSql .= " AND idProduct=$idProduct";
}
if($idPackage !== 0){
$whereSql .= " AND idPackage=$idPackage";
}
$sql = "UPDATE packages p
INNER JOIN
(
SELECT rpp.idPackage,
SUM(scp.isAvailable) AS availableProducts,
count(scp.idProduct) as totalProducts
FROM ".TABLES['suppliers_countries_products']." scp
INNER JOIN ".TABLES['rel_package_products']." rpp
ON rpp.idProduct=scp.idProduct
INNER JOIN
(
SELECT idPackage, max(packageInstance) AS packageInstance
FROM ".TABLES['rel_package_products']."
WHERE $whereSql
GROUP BY idPackage
) maxInst
ON maxInst.idPackage=rpp.idPackage AND maxInst.packageInstance=rpp.packageInstance
GROUP BY rpp.idPackage
) newStatus
ON newStatus.idPackage=p.id
SET p.status=CASE WHEN availableProducts=totalProducts THEN 'available' ELSE 'not-available' END";
$query = $database->query($sql);
return $database->affectedRows() > 0;
}
/**
* edit product data
* @param HashArray $productData product data input
* @return Array update message
*/
public function editSupplierProduct($productData){
global $database;
$prices = new Prices();
foreach ($productData as $key => $value) {
$productData[$key] = $database->escapeValue($value);
}
if(intval($productData['isPriceRecurring']) === 0){
$productData['payPeriod'] = 0;
}
$data = $this->validateProductData($productData, 'edit');
if(!empty($data)){
return $data;
}
$sql = "UPDATE ".TABLES['suppliers_countries_products']."
SET unitCostPrice='".$productData['unitCostPrice']."',
unitVatCost='".$productData['unitVatCost']."',
productName='".$productData['name']."',
productDescription='".$productData['description']."',
manufacturerProductNo='".$productData['manufacturerProductNo']."',
supplierProductNo='".$productData['supplierProductNo']."',
unit='".$productData['unit']."',
idProductCategory='".$productData['idProductCategory']."',
isPriceRecurring='".$productData['isPriceRecurring']."',
payPeriod='".$productData['payPeriod']."',
isAvailable=".$productData['isAvailable']."
WHERE idProduct='".$productData['idProduct']."'
LIMIT 1";
$query = $database->query($sql);
if($database->affectedRows() !== 1){
$data['messages'][] = [
'code' => 'warning',
'message' => 'NO_CHANGES'
];
return $data;
}
$packageUpdate = $this->updatePackageAvailability($productData['idProduct']);
if($packageUpdate > 0){
$data['messages'][] = [
'code' => 'warning',
'message' => 'PACKAGES_AVAILABLITY_CHANGED'
];
}
$priceChange = $prices->checkPackagePriceMargin($productData['idProduct'], 0);
if($priceChange > 0){
$data['messages'][] = [
'code' => 'warning',
'message' => 'PACKAGES_HIGH_PRICE_CHANGED'
];
}
$data['messages'][] = [
'code' => 'success',
'message' => 'SUPPLIER_PRODUCT_EDITED'
];
return $data;
}
/**
* @return Array id and name of the available product categories
*/
public function getProductCategories() {
global $database;
$sql = "SELECT
id,
category
FROM ".TABLES['product_categories']."
ORDER BY category";
return $database->fetchResultArray($sql);
}
/**
* check if product data is valid
* @param HashArray $productData product data input
* @return Array empty array if valid or error message array
*/
private function validateProductData($productData, $action){
global $database;
$data = [];
$whereSql = $action === 'edit' ? ' AND idProduct!='.$productData['idProduct'] : '';
$sql = "SELECT idProduct
FROM ".TABLES['suppliers_countries_products']."
WHERE productName='".$productData['name']."' AND idCountry=".$productData['idCountry']." AND idSupplier=".$productData['idSupplier']." $whereSql
LIMIT 1";
$query = $database->query($sql);
if($database->numRows($query) !== 0){
$data['messages'][] = [
'code' => 'error',
'message' => 'DUPLICATE_ENTRY'
];
return $data;
}
if(!$productData['idCountry'] ){
$data['messages'][] = [
'code' => 'error',
'message' => 'SELECT_COUNTRY'
];
return $data;
}
if(!$productData['idSupplier']){
$data['messages'][] = [
'code' => 'error',
'message' => 'SELECT_SUPPLIER'
];
return $data;
}
if($action === 'edit' && (intval($productData['isAvailable']) !== 1 && intval($productData['isAvailable']) !== 0)){
$data['messages'][] = [
'code' => 'error',
'message' => 'INVALID_VALUE_IS_AVAILABLE'
];
return $data;
}
if(!$productData['idProductCategory']){
$data['messages'][] = [
'code' => 'error',
'message' => 'SELECT_CATEGORY'
];
return $data;
}
$checkMessage = $database->isEmpty('name', $productData['name']);
if($checkMessage){
$data['messages'][] = $checkMessage;
}
$checkMessage = $database->invalidLength('name', $productData['name'], 70);
if($checkMessage){
$data['messages'][] = $checkMessage;
}
$checkMessage = $database->isEmpty('description', $productData['description']);
if($checkMessage){
$data['messages'][] = $checkMessage;
}
$checkMessage = $database->invalidLength('description', $productData['description'], 500);
if($checkMessage){
$data['messages'][] = $checkMessage;
}
$checkMessage = $database->isEmpty('unitCostPrice', $productData['unitCostPrice']);
if($checkMessage){
$data['messages'][] = $checkMessage;
}
$checkMessage = $database->invalidNumber('unitCostPrice', $productData['unitCostPrice'], 0, 10000000000);
if($checkMessage){
$data['messages'][] = $checkMessage;
}
$checkMessage = $database->isEmpty('unitVatCost', $productData['unitVatCost']);
if($checkMessage){
$data['messages'][] = $checkMessage;
}
$checkMessage = $database->invalidNumber('unitVatCost', $productData['unitVatCost'], 0, 10000000000);
if($checkMessage){
$data['messages'][] = $checkMessage;
}
$checkMessage = $database->isEmpty('manufacturerProductNo', $productData['manufacturerProductNo']);
if($checkMessage){
$data['messages'][] = $checkMessage;
}
$checkMessage = $database->invalidLength('manufacturerProductNo', $productData['manufacturerProductNo'], 45);
if($checkMessage){
$data['messages'][] = $checkMessage;
}
$checkMessage = $database->isEmpty('supplierProductNo', $productData['supplierProductNo']);
if($checkMessage){
$data['messages'][] = $checkMessage;
}
$checkMessage = $database->invalidLength('supplierProductNo', $productData['supplierProductNo'], 45);
if($checkMessage){
$data['messages'][] = $checkMessage;
}
$checkMessage = $database->isEmpty('isPriceRecurring', $productData['isPriceRecurring']);
if($checkMessage){
$data['messages'][] = $checkMessage;
}
if($productData['isPriceRecurring'] !== '1' && $productData['isPriceRecurring'] !== '0'){
$data['messages'][] = [
'code' => 'error',
'message' => 'INVALID_VALUE_RECURRING'
];
}
if($productData['isPriceRecurring'] === '1'){
$checkMessage = $database->isEmpty('payPeriod', $productData['payPeriod']);
if($checkMessage){
$data['messages'][] = $checkMessage;
}
$checkMessage = $database->invalidNumber('payPeriod', $productData['payPeriod'], 0, 36);
if($checkMessage){
$data['messages'][] = $checkMessage;
}
}
return $data;
}
/**
* get produts documents
* @param INT $idProduct id for product, if 0 all values are retrieved
* @return Array list of documents grouped by product id
*/
private function getSupplierProductsDocuments($idProduct = 0){
global $database;
$idProduct = $database->escapeValue($idProduct);
$data = [];
$whereSql = "";
if($idProduct){
$whereSql = "WHERE rpd.idProduct=$idProduct";
}
$sql = "SELECT
d.id AS idDocument,
d.documentName,
d.documentPath,
dt.type AS documentType,
d.extension,
rpd.idProduct
FROM ".TABLES['documents']." d
INNER JOIN ".TABLES['document_types']." dt
ON dt.id=d.idDocumentType
INNER JOIN ".TABLES['rel_product_documents']." rpd
ON rpd.idDocument=d.id
$whereSql";
$query = $database->query($sql);
while($row = $database->fetchArray($query)){
$data[$row['idProduct']][] = $row;
}
return $data;
}
/**
* get the list with all products for a country
* @param integer $country id of the country to get the products
* @return Array array with all productus for the suppiers in a specific country
*/
public function getSuppliersProducts($idCountry = 0, $idProduct = 0){
global $database;
$whereSql = " WHERE 1=1";
$data = [];
if($idCountry != 0){
$whereSql .= " AND c.id=$idCountry ";
}
if($idProduct != 0){
$whereSql .= " AND scp.idProduct=$idProduct ";
}
$headersSql = $this->getSuppliersProductsHeaders('sql');
$productsDocuments =$this->getSupplierProductsDocuments($idProduct);
$sql = "SELECT $headersSql
FROM ".TABLES['suppliers_countries_products']." scp
INNER JOIN ".TABLES['suppliers']." s
ON s.id=scp.idSupplier
INNER JOIN ".TABLES['countries']." c
ON c.id=scp.idCountry
INNER JOIN ".TABLES['product_categories']." pc
ON pc.id=scp.idProductCategory
$whereSql
ORDER BY c.name, scp.productName, s.name ASC";
$query = $database->query($sql);
while($row = $database->fetchArray($query)){
$row['documents'] = isset($productsDocuments[$row['idProduct']]) ? $productsDocuments[$row['idProduct']] : [];
$data[] = $row;
}
return $data;
}
/**
* Get the headers requried for products for the suppliers
* @param string $type type of the header, posible values array or sql
* @return string|array returns the sql header or the array of for the headers
*/
public function getSuppliersProductsHeaders($type = 'array'){
$headers = [
'scp.idProduct' => 'idProduct',
'scp.idSupplier' => 'idSupplier',
'pc.idType' => 'idProductType',
'pc.category' => 'category',
'scp.productName' => 'name',
'scp.productDescription' => 'description',
'scp.manufacturerProductNo' => 'manufacturerProductNo',
'scp.supplierProductNo' => 'supplierProductNo',
'scp.unit' => 'unit',
'scp.idCountry' => 'idCountry',
'scp.isPriceRecurring' => 'isPriceRecurring',
'scp.payPeriod' => 'payPeriod',
'scp.unitCostPrice' => 'unitCostPrice',
'scp.unitVatCost' => 'unitVatCost',
'scp.isAvailable' => 'isAvailable',
's.name' => 'supplierName',
'c.name' => 'country',
'\'\'' => 'documents'
];
return $this->headersHelper->getHeader($headers, $type);
}
/**
* upload document for a product
* @param INT $idDocumentType id for document type
* @param INT $idSupplierProduct id for product
* @param String $documentName name for the document
* @param INT $visibleToCustomer document will be visible for customer
* @param FILE $file file to be uploaded
* @return ARRAY upload message
*/
public function uploadProductDocument($idDocumentType, $idSupplierProduct, $documentName, $visibleToCustomer, $file){
global $database;
if(!$idDocumentType){
$data['messages'][] = [
'code' => 'error',
'message' => 'NO_DOC_TYPE'
];
return $data;
}
if($visibleToCustomer != 0 && $visibleToCustomer != 1){
$data['messages'][] = [
'code' => 'error',
'message' => 'WRONG_VISIBLE_TO_CUST_VAL'
];
return $data;
}
if(!$documentName){
$data['messages'][] = [
'code' => 'error',
'message' => 'NO_NAME'
];
return $data;
}
$fileManager = new FileManager();
$data = $fileManager->uploadFile($file, $idDocumentType, $documentName, 0, 0, $visibleToCustomer);
if(isset($data['messages'])){
return $data;
}
$idDocument = $data['idDocument'];
$sql = "INSERT INTO ".TABLES['rel_product_documents']."
(idProduct, idDocument)
VALUES($idSupplierProduct, $idDocument)";
$query = $database->query($sql);
$data['messages'][] = [
'code' => 'success',
'message' => 'DOCUMENT_UPLOADED'
];
return $data;
}
/**
* remove product documents
* @param INT $idDocument id for document
* @return Array update message
*/
public function removeProductDocument($idDocument){
global $database, $user;
if($user->getUserType() !== USER_TYPES['BROKER']){
$data['messages'][] = [
'code' => 'error',
'message' => 'NO_RIGHTS'
];
return $data;
}
$fileManager = new FileManager();
$data = $fileManager->removeDocument($idDocument);
return $data;
}
}

View File

@@ -0,0 +1,9 @@
<div class="col-md-4 show-product-documents-layer">
<h4>Product documents:</h4>
<div class="documnet-row" ng-repeat="document in data.documents">
<a href="utils/api/downloadFile?idDocument={{document.idDocument}}&fileName={{document.documentName}}.{{document.extension}}">
{{document.documentName}} ( {{document.extension}} )
</a>
<span ng-click="removeProductDocument(document.idDocument)" class="glyphicon glyphicon-trash remove-document-icon"></span>
</div>
</div>

View File

@@ -0,0 +1,37 @@
<div class="col-sm-6">
<form id="supplier-add-edit-form">
<div class="form-group supplier-group">
<label for="supplier-name">{{'suppliers.tables.headers.name' | translate}}:</label>
<input class="form-control supplier-input"
type="text"
placeholder="{{'suppliers.tables.headers.name' | translate}}"
id="supplier-name"
ng-model="data.name"
value="{{data.name}}"
autofocus="on"
required>
</div>
<div class="form-group supplier-group">
<label for="phone">{{'suppliers.tables.headers.phone' | translate}}:</label>
<input type="text"
placeholder="{{'suppliers.tables.headers.phone' | translate}}"
class="form-control supplier-input"
id="supplier-phone"
ng-model="data.phone"
value="{{data.phone}}">
</div>
<div class="form-group supplier-group">
<label for="mail">{{'suppliers.tables.headers.mail' | translate}}:</label>
<input type="text"
placeholder="{{'suppliers.tables.headers.mail' | translate}}"
class="form-control supplier-input"
id="supplier-mail"
ng-model="data.mail"
value="{{data.mail}}">
</div>
<button type="submit" ng-click="addEditSupplier()" class="btn btn-primary">{{'suppliers.buttons.SUPPLIERS_'+formAction | translate}}</button>
</form>
</div>

View File

@@ -0,0 +1,170 @@
<div class="row">
<div class="col-sm-8">
<form id="supplier-product-add-edit-form">
<div ng-if="isAddAction()" class="form-group product-group">
<label for="country-id">{{'suppliers.tables.headers.country' | translate}}:</label>
<select id="country-id"
class="form-control-static"
ng-model="data.idCountry"
required>
<option ng-repeat="countryInfo in countries" value={{countryInfo.id}}>
{{countryInfo.name}}
</option>
</select>
</div>
<div ng-if="isAddAction()" class="form-group product-group">
<label for="supplier-id">{{'suppliers.tables.headers.supplierName' | translate}}:</label>
<select id="supplier-id"
class="form-control-static"
ng-model="data.idSupplier"
required>
<option ng-repeat="supplier in suppliers" value={{supplier.id}}>
{{supplier.name}}
</option>
</select>
</div>
<div class="form-group product-group">
<label for="product-name">{{'suppliers.tables.headers.name' | translate}}:</label>
<input class="form-control product-input"
type="text"
placeholder="{{'suppliers.tables.headers.name' | translate}}"
id="product-name"
ng-model="data.name"
value="{{data.name}}"
required>
</div>
<div ng-if="!isAddAction()" class="form-group product-group">
<label for="product-is-available">{{'suppliers.tables.headers.isAvailable' | translate}}:</label>
<div class="product-radio-layer">
<input class="product-radio"
type="radio"
id="product-is-available-yes"
ng-model="data.isAvailable"
value="1">
{{'suppliers.headers.YES' | translate}}
</div>
<div class="product-radio-layer">
<input class="product-radio"
type="radio"
id="product-is-available-no"
ng-model="data.isAvailable"
value="0">
{{'suppliers.headers.NO' | translate}}
</div>
</div>
<div class="form-group product-group">
<label for="product-descrtiption">{{'suppliers.tables.headers.description' | translate}}:</label>
<textarea class="form-control product-input"
placeholder="{{'suppliers.tables.headers.description' | translate}}"
id="product-description"
ng-model="data.description"
required>{{data.description}}</textarea>
</div>
<div class="form-group product-group">
<label for="product-category-name">{{'suppliers.tables.headers.category' | translate}}:</label>
<select id="product-category-name"
class="form-control-static"
ng-model="data.productCategory"
ng-options="productCategory.category for productCategory in productCategories track by productCategory.id"
required>
</select>
</div>
<div class="form-group product-group">
<label for="product-is-price-recurring">{{'suppliers.tables.headers.isPriceRecurring' | translate}}:</label>
<div class="product-radio-layer">
<input class="product-radio"
type="radio"
id="product-is-price-recurring-yes"
ng-model="data.isPriceRecurring"
value="1">
{{'suppliers.headers.YES' | translate}}
</div>
<div class="product-radio-layer">
<input class="product-radio"
type="radio"
id="product-is-price-recurring-no"
ng-model="data.isPriceRecurring"
value="0">
{{'suppliers.headers.NO' | translate}}
</div>
</div>
<div ng-if="isPriceRecurring()" class="form-group product-group">
<label for="product-pay-period">{{'suppliers.tables.headers.payPeriod' | translate}}:</label>
<input class="form-control product-input"
type="text"
placeholder="{{'suppliers.tables.headers.payPeriod' | translate}}"
id="product-pay-period"
ng-model="data.payPeriod"
value="{{data.payPeriod}}">
</div>
<div class="form-group product-group">
<label for="product-unit-cost-price">{{'suppliers.tables.headers.unitCostPrice' | translate}}:</label>
<input class="form-control product-input"
type="text"
placeholder="{{'suppliers.tables.headers.unitCostPrice' | translate}}"
id="product-unit-cost-price"
ng-model="data.unitCostPrice"
value="{{data.unitCostPrice}}"
required>
</div>
<div class="form-group product-group">
<label for="product-unit-vat-cost">{{'suppliers.tables.headers.unitVatCost' | translate}}:</label>
<input class="form-control product-input"
type="text"
placeholder="{{'suppliers.tables.headers.unitVatCost' | translate}}"
id="product-unit-vat-cost"
ng-model="data.unitVatCost"
value="{{data.unitVatCost}}"
required>
</div>
<div class="form-group product-group">
<label for="product-manufacturere-no">{{'suppliers.tables.headers.manufacturerProductNo' | translate}}:</label>
<input class="form-control product-input"
type="text"
placeholder="{{'suppliers.tables.headers.manufacturerProductNo' | translate}}"
id="product-manufacturere-no"
ng-model="data.manufacturerProductNo"
value="{{data.manufacturerProductNo}}"
required>
</div>
<div class="form-group product-group">
<label for="product-supplier-no">{{'suppliers.tables.headers.supplierProductNo' | translate}}:</label>
<input class="form-control product-input"
type="text"
placeholder="{{'suppliers.tables.headers.supplierProductNo' | translate}}"
id="product-supplier-no"
ng-model="data.supplierProductNo"
value="{{data.supplierProductNo}}"
required>
</div>
<div class="form-group product-group">
<label for="product-unit">{{'suppliers.tables.headers.unit' | translate}}:</label>
<input class="form-control product-input"
type="text"
placeholder="{{'suppliers.tables.headers.unit' | translate}}"
id="product-unit"
ng-model="data.unit"
value="{{data.unit}}">
</div>
<button type="submit" ng-click="addEditSupplierProducts()" class="btn btn-primary">{{'suppliers.buttons.SUPPLIERS_PRODUCTS_'+formAction | translate}}</button>
</form>
</div>
<div ng-if="!isAddAction()" class="col-sm-4">
<h4>Upload Product Documents</h4>
<upload-product-document ng-controller="uploadProductDocumentCtrl" ng-init="getDocumentTypes()"/>
</div>
</div>

View File

@@ -0,0 +1,46 @@
<button type="button"
id="suppliersBtn"
subModule="suppliers"
class="btn btn-default"
ng-click="setSubModule($event)">{{ 'suppliers.buttons.SHOW_SUPPLIERS' | translate }}</button>
<button type="button"
id="suppliersProductsBtn"
subModule="suppliersProducts"
class="btn btn-default"
ng-click="setSubModule($event)">{{ 'suppliers.buttons.SHOW_SUPPLIERS_PRODUCTS' | translate }}</button>
<button type="button"
id="suppliersProductsAddBtn"
subModule="suppliersProductsAdd"
class="btn btn-default"
ng-click="setSubModule($event)">{{ 'suppliers.buttons.SUPPLIERS_PRODUCTS_ADD' | translate }}</button>
<div class="row">
<div class="col-sm-12"
id="suppliers-layer"
ng-if="isSubmoduleVisible('suppliers')"
ng-init="getSuppliers()">
<h3>{{ 'suppliers.headers.SHOW_SUPPLIERS' | translate }}</h3>
<table class="table table-striped table-hover" id="suppliers"></table>
</div>
</div>
<div class="row">
<div class="col-sm-12"
id="suppliers-products-layer"
ng-if="isSubmoduleVisible('suppliersProducts')"
ng-init="getSuppliersProducts()">
<h3>{{ 'suppliers.headers.SHOW_SUPPLIERS_PRODUCTS' | translate }}</h3>
<table class="table table-striped table-hover" id="suppliers-products"></table>
</div>
</div>
<div class="row">
<div class="col-sm-12"
id="suppliers-products-add-layer"
ng-if="isSubmoduleVisible('suppliersProductsAdd')">
<h3>{{ 'suppliers.headers.SUPPLIERS_PRODUCTS_ADD' | translate }}</h3>
<suppliers-products-add-edit ng-controller="suppliersProductsAddEditCtrl" ng-init="productsFormInit('ADD')"></suppliers-products-add-edit>
</div>
</div>

View File

@@ -0,0 +1,46 @@
<div class="upload-product-document">
<div class="document-types">
<label>{{'orders.headers.DOCUMENT_TYPES' | translate}}: </label>
<select id="document-types-for-prod"
class="form-control-static add-document-value"
ng-model="docType"
ng-options="docType.type for docType in documentTypes track by docType.idDocumentType"
ng-change="selectFileType(docType)">
<option value="" disabled selected>{{'orders.headers.SELECT_DOCUMENT_TYPE' | translate}}</option>
</select>
</div>
<div class="document-name">
<label>Document name: </label>
<input id="new-doc-name"
class="add-document-value"
type="text"
placeholder="Document name"
ng-model="documentName" />
</div>
<div class="document-name">
<label>Visible To Customer </label>
<span class="product-radio-layer">
<input class="product-radio"
type="radio"
id="document-is-visible-yes"
ng-model="visibleToCustomer"
value="1">
{{'suppliers.headers.YES' | translate}}
</span>
<span class="product-radio-layer">
<input class="product-radio"
type="radio"
id="document-is-visible-no"
ng-model="visibleToCustomer"
value="0">
{{'suppliers.headers.NO' | translate}}
</span>
</div>
<div ngf-drop="uploadFile($file)"
ng-model="files"
ngf-drag-over-class="'dragover'"
ngf-select="uploadFile($file)"
ngf-pattern="'.pdf,.docx,.doc,.xlsx,.xls,.odt,.ods,.png,.jpg,.jpeg'"
ngf-max-size="20MB"
class="drop-box">Select Document</div>
</div>