ساخت اپلیکیشن مدیریت موجودی انبار با PHP و MySQL — از صفر تا صد

۵۶۳ بازدید
آخرین به‌روزرسانی: ۰۸ مهر ۱۴۰۲
زمان مطالعه: ۱۰ دقیقه
ساخت اپلیکیشن مدیریت موجودی انبار با PHP و MySQL — از صفر تا صد

بسیاری از شرکت‌ها برای مدیریت موثر موجودی انبار خود به یک نرم‌افزار پیچیده سازمانی نیاز ندارند. در این راهنما شیوه توسعه یک اپلیکیشن مدیریت موجودی انبار (به صورت سفارشی  شده) شرح داده شده است، تا بتوان این موجودی و داده‌های مرتبط به آن را دقیق‌تر دنبال و مدیریت کرد و بر همین مبنا تصمیم‌های هوشمندانه‌تری گرفت.

الزامات سیستم

سیستم موجودی انبار ما نیازمند phpGrid و phpChart با لایسنس استاندارد تجاری است. ما در واقع به برخی ویژگی‌های پیشرفته هر دو کامپوننت نیاز داریم.

  • +PHP 5.6 (البته PHP 7.x اکنون قویاً توصیه می‌شود)
  • MySQL / MariaDB
  • (phpGrid Lite (subgrid یا phpGrid Enterprise  با امکانات (Master detail ،Grouping)
  • phpChart (برای گزارش‌ها)

سیستم مدیریت موجودی انبار چیست؟

یک سیستم مدیریت موجودی انبار چند کامپوننت خیلی مهم دارد. این سیستم در هسته مرکزی خود باید امکان کنترل موجودی داشته باشد که با ردگیری دو کارکرد اصلی یک انبار کالا یعنی دریافت (ورودی) و ارسال (خروجی) کار می‌کند. فعالیت‌های دیگر مانند جابجایی یا تغییر مکان موجودی نیز ممکن است رخ دهند. مواد خام کاهش می‌یابند و محصولات نهایی افزایش پیدا می‌کنند.

  • ورود محموله‌ها
  • خروج سفارش‌ها
  • موجودی
  • تأمین‌کنندگان
  • اسکنر بارکد

طراحی پایگاه داده سیستم مدیریت موجودی انبار

به طور معمول یک سیستم مدیریت موجودی، چهار جزء اساسی به صورت محصولات، خریدها، سفارش‌ها و تأمین‌کنندگان دارد. هر عنصر باید بر اساس مکان خود، SKU و کمّیت ردگیری شود. موجودی فعلی یا محصولات موجود با ردگیری تحویل ورودی‌ها و سفارش‌های خروجی صورت می‌پذیرد. هشدارهای سفارشی می‌توانند طوری تنظیم شوند که وقتی سطوح موجود به کمتر از مقادیر کمینه تعریف شده سفارشی رسیدند، فعال شوند.

اپلیکیشن مدیریت موجودی انبار

راه‌اندازی پایگاه داده مدیریت موجودی

اسکریپت SQL به نام InventoryManager.sql را از این ریپازیتوری گیت‌هاب این راهنما (+) دانلود کنید و سپس اسکریپت را با استفاده از یک ابزار MySQL مانند MySQL Workbench اجرا کنید. بدین ترتیب پایگاه داده جدیدی به نام InventoryManager و همچنین جداول مورد نیاز این راهنما ایجاد خواهند شد.

راه‌اندازی phpGrid

ما از یک کامپوننت datagrid که به وسیله phpGrid ارائه شده برای مدیریت همه عملیات CRUD داخلی پایگاه داده استفاده می‌کنیم. منظور از عملیات CRUD چهار عملیات ایجاد، خواندن، به‌روزرسانی و حذف (create ،read ،update و delete) است.

مطمئن شوید که پیش از ادامه یک کپی از phpGrid (+) را دانلود کرده‌اید.

برای نصب phpGrid مراحل زیر را طی کنید:

  1. فایل دانلود phpGrid را از حالت فشرده خارج کنید.
  2. phpGrid را به پوشه phpGrid خود کپی کنید.
  3. فرایند نصب را با پیکربندی فایل conf.php به پایان ببرید.

پیش از آغاز کدنویسی باید اطلاعات زیر را در فایل پیکربندی conf.php قرار دهیم.

1define('PHPGRID_DB_HOSTNAME', 'localhost'); //  host name
2define('PHPGRID_DB_USERNAME', 'root'); // database user name
3define('PHPGRID_DB_PASSWORD', ''); // database password
4define('PHPGRID_DB_NAME', 'InventoryManager'); // our donation manager database name
5define('PHPGRID_DB_TYPE', 'mysql'); // database type
6define('PHPGRID_DB_CHARSET','utf8'); // always 'utf8' in MySQL

ایجاد رابط کاربری (UI)

سیستم مدیریت موجودی انبار ما شامل چهار صفحه است:

  • موجودی فعلی
  • خریدهای ورودی
  • سفارش‌های خروجی
  • گزارش‌ها

مدیریت موجودی انبار

منوها

فایل include برای منو در پوشه inc به نام menu.php ذخیره شده است. کد منو نیز سرراست است. به منظور ایجاد تمرکز بیشتر وارد جزییات زیاد نمی‌شویم. شما می‌توانید به کد درون پوشه inc نگاه کنید. همچنین یک آیتم منوی به نام Reports اضافه کرده‌ایم.

مدیریت موجودی انبار

صفحات

ما در این راهنما از یک قالب صفحه عمومی استفاده می‌کنیم.

موجودی فعلی

مدیریت موجودی انبار

ما کار خود را با کدنویسی صفحه موجودی فعلی آغاز می‌کنیم. خریدهای ورودی موجب افزایش موجودی انبار می‌شوند، در حالی که سفارش‌ها موجودی را کاهش می‌دهند. از چشم‌انداز کلی-جزئی (Master-Detail)، صفحه موجودی فعلی نه دارای 1 بلکه دارای 2 datagrid است، یعنی یکی Purchases (خریدهای ورودی) و دیگری  Orders (سفارشی‌های خروجی) را شامل می‌شود.

بنابراین صفحه موجودی فعلی از یک شبکه کلی (موجودی فعلی در انبار) و دو شبکه جزئی تفصیلی (خریدهای ورودی و سفارشی‌های خروجی) تشکیل یافته است. ما می‌توانیم روابط را با استفاده از یک phpGrid اصلی و چند datagrid جزئی نمایش دهیم.

phpGrid Lite در برابر نسخه‌های Professional و Enterprise

ویژگی‌های مستر/دیتیل و گروه‌بندی نیازمند نسخه‌های phpGrid Professional یا Enterprise هستند. اگر از نسخه phpGrid Lite استفاده می‌کنید همچنان می‌توانید از subgrid به جای ویژگی Master Detail استفاده کنید؛ اما البته ساده‌تر است. استفاده از نسخه‌های حرفه‌ای یا سازمانی قویاً توصیه می‌شود. برای قالب‌بندی اعداد صحیح نیز می‌توانید از تابع ()set_col_format به صورت زیر استفاده کنید:

1$dgProd = new C_DataGrid('SELECT * FROM products', 'id', 'products');
2$dgProd->set_col_hidden('id', false);
3$dgProd->enable_autowidth(true)->set_dimension('auto', '200px')->set_pagesize(100);
4
5$dgProd->set_col_title('ProductName', 'Name');
6$dgProd->set_col_title('PartNumber', 'Part Number');
7$dgProd->set_col_title('ProductLabel', 'Label');
8$dgProd->set_col_title('StartingInventory', 'Starting Inventory');
9$dgProd->set_col_title('InventoryReceived', 'Inventory Received');
10$dgProd->set_col_title('InventoryShipped', 'Inventory Shipped');
11$dgProd->set_col_title('InventoryOnHand', 'Inventory On Hand');
12$dgProd->set_col_title('MinimumRequired', 'Minimum Required');
13
14$dgProd->set_col_format('StartingInventory', 'integer', array('thousandsSeparator'=>',', 'defaultValue'=>'0'));
15$dgProd->set_col_format('InventoryReceived', 'integer', array('thousandsSeparator'=>',', 'defaultValue'=>'0'));
16$dgProd->set_col_format('InventoryShipped', 'integer', array('thousandsSeparator'=>',', 'defaultValue'=>'0'));
17$dgProd->set_col_format('InventoryOnHand', 'integer', array('thousandsSeparator'=>',', 'defaultValue'=>'0'));
18$dgProd->set_col_format('MinimumRequired', 'integer', array('thousandsSeparator'=>',', 'defaultValue'=>'0'));
19$dgProd->enable_edit('FORM');

این کد به datagrid موجودی فعلی مربوط است. فرایند کار تاکنون به صورت زیر بوده است:

مدیریت انبار

اکنون تغییرات معدودی اعمال می‌کنیم تا datagrid به نام Product را بهبود ببخشیم.

قبل از هر چیز مقداری قالب‌بندی شرطی اضافه می‌کنیم. هر زمان که InventoryOnHand برابر با صفر یا مقدار منفی تنظیم شود، با استفاده از رنگ پس‌زمینه متفاوت نمایش پیدا می‌کند. ما از تابع ()set_conditional_format به این منظور استفاده می‌کنیم.

1$dgProd->set_conditional_format(
2    'InventoryOnHand', 'CELL', 
3        array("condition"=>"lt",
4          "value"=>"1",
5          "css"=> array("color"=>"red","background-color"=>"#DCDCDC")));

کد فوق یک شرط نمایش اضافه می‌کند که هر زمان فیلد InventoryOnHand مقداری کمتر (lt) از یک داشته باشد، رنگ متن به قرمز (red) تغییر می‌یابد و رنگ پس‌زمینه نیز خاکستری تیره (DCDCDC#) می‌شود.

در ادامه زمانی که InventoryOnHand کمتر از مقدار نمایش یافته در MinimumRequired باشد، می‌خواهیم هشداری به کاربر نمایش داده شود که رنگ پس‌زمینه آن چیزی مانند طلایی باشد. برای مقایسه مقادیر بین دو فیلد باید به جاوا اسکریپت سوئیچ کنیم، زیرا ()set_conditional_format تنها روی یک تابع کار می‌کند.

در کد زیر از یک حلقه for برای تکرار روی همه ردیف‌ها در datagrid به نام Products استفاده شده است. این حلقه به مقایسه inventoryOnHand با theminimumRequired می‌پردازد و زمانی که شرط برقرار باشد، از تابع setCall برای تغییر رنگ پس‌زمینه استفاده می‌کند.

1$onGridLoadComplete = <<<ONGRIDLOADCOMPLETE
2function(status, rowid)
3{
4    var ids = jQuery("#products").jqGrid('getDataIDs');
5    for (var i = 0; i < ids.length; i++)
6    {
7        var rowId = ids[i];
8        var rowData = jQuery('#products').jqGrid ('getRowData', rowId);
9
10        var inventoryOnHand = $("#products").jqGrid("getCell", rowId, "InventoryOnHand");
11        var minimumRequired = $("#products").jqGrid("getCell", rowId, "MinimumRequired");
12
13        // compare two dates and set custom display in another field "status" 
14        console.log(inventoryOnHand + " | " + minimumRequired);
15        if(parseInt(inventoryOnHand) < parseInt(minimumRequired)){
16            
17            $("#products").jqGrid("setCell", rowId, "PartNumber", '', {'background-color':'gold'}); 
18                
19        }
20    }
21
22}
23ONGRIDLOADCOMPLETE;
24$dgProd->add_event("jqGridLoadComplete", $onGridLoadComplete);

سپس در همان صفحه، باید خریدهای ورودی (Incoming) و سفارشی‌های خروجی (Outgoing) را برای یک محصول خاص ببینیم.

Grid تفصیلی خریدها (ورودی)

1// Purchases detail grid
2$dgPur = new C_DataGrid('SELECT id, PurchaseDate, ProductId, NumberReceived, SupplierId FROM purchases', 'id', 'purchases');
3$dgPur->set_col_hidden('id', false)->set_caption('Incoming Purchases');
4$dgPur->set_col_edittype('ProductId', 'select', "select id, ProductLabel from products");
5$dgPur->set_col_edittype('SupplierId', 'select', "select id, supplier from suppliers");
6$dgPur->set_dimension('800px');

Grid تفصیلی سفارش‌ها (خروجی)

1// Orders detail grid
2$dgOrd = new C_DataGrid('SELECT id, OrderDate, ProductId, NumberShipped, First, Last FROM orders', 'id', 'orders');
3$dgOrd->set_sortname('OrderDate', 'DESC')->set_caption('Outgoing Orders');
4$dgOrd->set_col_hidden('id', false);
5$dgOrd->set_col_edittype('ProductId', 'select', "select id, ProductLabel from products");
6$dgOrd->set_dimension('800px');

هر دو grid تفصیلی فوق از کلید خارجی یکسانی به نام ProductId برای لینک کردن datagrid اصلی (Products) استفاده می‌کنند.

1$dgProd->set_masterdetail($dgPur, 'ProductId', 'id');
2$dgProd->set_masterdetail($dgOrd, 'ProductId', 'id');

در نهایت، کد کامل ما برای مدیریت صفحه «مدیریت موجودی» (Current Inventory) به صورت زیر است:

1$dgProd = new C_DataGrid('SELECT * FROM products', 'id', 'products');
2$dgProd->set_col_hidden('id', false);
3$dgProd->enable_autowidth(true)->set_dimension('auto', '200px')->set_pagesize(100);
4
5$dgProd->set_col_title('ProductName', 'Name');
6$dgProd->set_col_title('PartNumber', 'Part Number');
7$dgProd->set_col_title('ProductLabel', 'Label');
8$dgProd->set_col_title('StartingInventory', 'Starting Inventory');
9$dgProd->set_col_title('InventoryReceived', 'Inventory Received');
10$dgProd->set_col_title('InventoryShipped', 'Inventory Shipped');
11$dgProd->set_col_title('InventoryOnHand', 'Inventory On Hand');
12$dgProd->set_col_title('MinimumRequired', 'Minimum Required');
13
14$dgProd->set_col_format('StartingInventory', 'integer', array('thousandsSeparator'=>',', 'defaultValue'=>'0'));
15$dgProd->set_col_format('InventoryReceived', 'integer', array('thousandsSeparator'=>',', 'defaultValue'=>'0'));
16$dgProd->set_col_format('InventoryShipped', 'integer', array('thousandsSeparator'=>',', 'defaultValue'=>'0'));
17$dgProd->set_col_format('InventoryOnHand', 'integer', array('thousandsSeparator'=>',', 'defaultValue'=>'0'));
18$dgProd->set_col_format('MinimumRequired', 'integer', array('thousandsSeparator'=>',', 'defaultValue'=>'0'));
19
20$dgProd->set_conditional_format('InventoryOnHand', 'CELL', array("condition"=>"lt",
21                                                  "value"=>"1",
22                                                  "css"=> array("color"=>"red","background-color"=>"#DCDCDC")));
23                                                  
24$onGridLoadComplete = <<<ONGRIDLOADCOMPLETE
25function(status, rowid)
26{
27    var ids = jQuery("#products").jqGrid('getDataIDs');
28    for (var i = 0; i < ids.length; i++)
29    {
30        var rowId = ids[i];
31        var rowData = jQuery('#products').jqGrid ('getRowData', rowId);
32
33        var inventoryOnHand = $("#products").jqGrid("getCell", rowId, "InventoryOnHand");
34        var minimumRequired = $("#products").jqGrid("getCell", rowId, "MinimumRequired");
35
36        // compare two dates and set custom display in another field "status" 
37        console.log(inventoryOnHand + " | " + minimumRequired);
38        if(parseInt(inventoryOnHand) < parseInt(minimumRequired)){
39            
40            $("#products").jqGrid("setCell", rowId, "PartNumber", '', {'background-color':'gold'}); 
41                
42        }
43    }
44
45}
46ONGRIDLOADCOMPLETE;
47$dgProd->add_event("jqGridLoadComplete", $onGridLoadComplete);
48$dgProd->enable_edit('FORM');
49
50// Purchases detail grid
51$dgPur = new C_DataGrid('SELECT id, PurchaseDate, ProductId, NumberReceived, SupplierId FROM purchases', 'id', 'purchases');
52$dgPur->set_col_hidden('id', false)->set_caption('Incoming Purchases');
53$dgPur->set_col_edittype('ProductId', 'select', "select id, ProductLabel from products");
54$dgPur->set_col_edittype('SupplierId', 'select', "select id, supplier from suppliers");
55$dgPur->set_dimension('800px');
56
57// Orders detail grid
58$dgOrd = new C_DataGrid('SELECT id, OrderDate, ProductId, NumberShipped, First, Last FROM orders', 'id', 'orders');
59$dgOrd->set_sortname('OrderDate', 'DESC')->set_caption('Outgoing Orders');
60$dgOrd->set_col_hidden('id', false);
61$dgOrd->set_col_edittype('ProductId', 'select', "select id, ProductLabel from products");
62$dgOrd->set_dimension('800px');
63
64$dgProd->set_masterdetail($dgPur, 'ProductId', 'id');
65$dgProd->set_masterdetail($dgOrd, 'ProductId', 'id');
66$dgProd->display();

در ادامه تصویری از صفحه موجودی می‌بینید:

خریدهای ورودی

صفحه بعدی که می‌خواهیم بسازیم صفحه خریدهای ورودی است. این صفحه نیز مشابه دیتیل خریدها است که در زمان طراحی صفحه موجودی فعلی مشاهده کردیم. ما خریدها را بر اساس ProductId گروه‌بندی می‌کنیم و مجموع را در NumberReceived نمایش می‌دهیم. هر خرید ورودی موجب افزایش موجودی می‌شود.

نکته: قابلیت گروه‌بندی تنها در نسخه حرفه‌ای و سازمانی phpGrid وجود دارد. برای فیلتر کردن بدون استفاده از این قابلیت می‌توانید از «جستجوی یکپارچه‌سازی» (integration search) (+) استفاده کنید.

1$dgPur -> set_group_properties('ProductId', false, true, true, false);
2$dgPur -> set_group_summary('NumberReceived','sum');

کد کامل به صورت زیر است:

1$dgPur = new C_DataGrid('SELECT id, PurchaseDate, ProductId, NumberReceived, SupplierId FROM purchases', 'id', 'purchases');
2$dgPur->set_col_hidden('id', false);
3
4$dgPur->set_col_title('PurchaseDate', 'Date of Purchase');
5$dgPur->set_col_title('ProductId', 'Product');
6$dgPur->set_col_title('NumberReceived', 'Number Received');
7$dgPur->set_col_title('SupplierId', 'Supplier');
8
9$dgPur->set_col_edittype('ProductId', 'select', "select id, ProductLabel from products");
10$dgPur->set_col_edittype('SupplierId', 'select', "select id, supplier from suppliers");
11
12// $dgPur->enable_edit('FORM');
13$dgPur->set_pagesize(100);
14
15$dgPur->set_col_width('PurchaseDate', '50px');
16$dgPur->set_col_width('NumberReceived', '35px');
17
18$dgPur -> set_group_properties('ProductId', false, true, true, false);
19$dgPur -> set_group_summary('NumberReceived','sum');
20
21$dgPur->enable_autowidth(true);
22$dgPur->display();

در ادامه تصویری از صفحه خریدهای ورودی به همراه قابلیت گروه‌بندی مشاهده می‌کنید:

سفارش‌های خروجی

صفحه بعدی که می‌خواهیم بسازیم، صفحه «سفارش‌های خروجی» (Outgoing Orders) است. این صفحه نیز مشابه Grid تفصیلی سفارش‌ها از صفحه موجودی کنونی است. در این صفحه یک تابع پیشرفته به نام ()set_grid_method را معرفی می‌کنیم.

1$dgOrd = new C_DataGrid('SELECT id, OrderDate, ProductId, NumberShipped, First, Last FROM orders', 'id', 'orders');
2$dgOrd->set_sortname('OrderDate', 'DESC');
3$dgOrd->set_col_hidden('id', false);
4
5$dgOrd->set_col_title('OrderDate', 'Order Date');
6$dgOrd->set_col_title('ProductId', 'Product');
7$dgOrd->set_col_title('NumberShipped', 'Number Shipped');
8
9$dgOrd->set_col_edittype('ProductId', 'select', "select id, ProductLabel from products");
10
11// $dgOrd->enable_edit('FORM');
12$dgOrd->set_pagesize(100);
13
14$dgOrd->set_col_width('OrderDate', '30px');
15$dgOrd->set_col_width('NumberShipped', '35px');
16$dgOrd->set_col_width('First', '20px');
17$dgOrd->set_col_width('Last', '20px');
18
19$dgOrd->set_grid_method('setGroupHeaders', array(
20                                array('useColSpanStyle'=>true),
21                                'groupHeaders'=>array(
22                                        array('startColumnName'=>'First',
23                                              'numberOfColumns'=>2,
24                                              'titleText'=>'Customer Name') )));
25
26$dgOrd->enable_autowidth(true);
27$dgOrd->display();

جمع‌بندی

ما در این راهنما یک سیستم موجودی انبار ساده و قابل گسترش را با کمتر از 50 خط کد ساختیم. سبک پیش‌رونده این راهنما به خواننده کمک می‌کند که با معرفی چند خط کد محدود از ویژگی‌های phpGrid به صورت مکرر، در نهایت با همه ویژگی‌های آن آشنا شود. بدین ترتیب ما به انتهای کد مورد نیاز برای datagrid-های این راهنما رسیدیم. با این حال، هنوز کار ما به پایان نرسیده است. هنوز یک صفحه دیگر مانده است که باید ایجاد کنیم و آن صفحه گزارش‌ها است. پس از یک توضیح کوتاه آن را نیز بررسی می‌کنیم.

شاید بپرسید کاربرد سیستم موجودی انبار بدون وجود گزارش چیست؟ در این بخش، با روش استفاده از phpChart آشنا می‌شویم که به طور یکپارچه با phpGrid ادغام می‌شود تا گزارش‌های با ظاهر بصری خوشایند و مفید برای اپلیکیشن مدیریت موجودی انبار ما ایجاد کند. در نهایت صفحه اپلیکیشن ما به صورت زیر درخواهد آمد:

پیش از آغاز باید phpChart را نصب کنید. ما پیشنهاد می‌کنیم که نسخه کامل phpChart را دانلود کنید (+) زیرا نسخه رایگان یعنی phpChart Lite تنها از نمودار نوع خطی پشتیبانی می‌کند.

راه‌اندازی phpChart

لازم است که phpGrid و phpChart را در پوشه‌های مختلفی نگه‌داری کنیم. در ادامه سلسله‌مراتب پوشه پیشنهادی را می‌بینید:

www
    +-- Donation_Manager
    |   |-- phpGrid
    |   |   +-- conf.php
    |   |-- phpChart
    |   |   +-- conf.php
    |   +-- ...

طراحی گزارش

ما یک نمودار دایره‌ای را در کنار یک شبکه خلاصه موجودی انبار قرار می‌دهیم. datagrid داده‌های سری را برای رسم نمودار دایره‌ای در اختیار ما قرار می‌دهد.

یکپارچه‌سازی phpGrid و phpChart

قبل از هر چیز، فراخوانی‌ها به فایل‌های conf.php را در ابتدای کد قرار می‌دهیم.

1require_once("phpGrid/conf.php"); 
2require_once("phpChart/conf.php");

نمودار دایره‌ای

در ادامه کد کامل ایجاد نمودار دایره‌ای را مشاهده می‌کنید:

1$pc = new C_PhpChartX(array(array(null)), 'PieChart');
2$pc->set_title(array('text'=>'Current Inventory Summary'));
3$pc->set_series_default(array( 'shadow'=> false, 
4    'renderer'=> 'plugin::PieRenderer', 
5    'rendererOptions'=> array( 
6      'showDataLabels' => true,
7      'highlightMouseOver' => true,
8      'startAngle'=> 180, 
9      'sliceMargin'=> 4, 
10      'showDataLabels'=> true ) 
11  ));
12$pc->set_legend(array('show'=>true,'location'=> 'w'));
13// remove background
14$pc->set_grid(array(
15    'background'=>'white',
16    'borderWidth'=>0,
17    'borderColor'=>'#000000',
18    'shadow'=>false));
19$pc->add_custom_js("
20        $('#PieChart').bind('jqplotDataHighlight',
21            function (ev, seriesIndex, pointIndex, data) {
22               $('#label_info').text(data);      
23            }
24        );
25    ");
26$pc->draw(660,400);

در ادامه کد فوق را بررسی می‌کنیم.

خط اول سازنده است. ما (array(null را به عنوان داده‌های سری ارسال می‌کنیم، زیرا نمی‌خواهیم هیچ داده‌ای در ابتدا در نمودار دایره‌ای نمایش پیدا کند. داده‌های موجودی انبار که برای رسم یک نمودار استفاده خواهند شد هنوز در ابتدای مقداردهی آن در دسترس نیستند. داده‌ها بعداً از طریق JSON از datagrid ارائه می‌شوند. ما همچنین یک نام یکتا برای نمودار به صورت PieChart تعیین می‌کنیم.

1$pc = new C_PhpChartX(array(array(null)), 'PieChart');

سپس یک عنوان برای آن تعیین می‌کنیم که نکته خاصی ندارد.

1$pc->set_title(array('text'=>'Current Inventory Summary'));

حال که یک عنوان داریم تابع series default را فراخوانی می‌کنیم تا مقدار renderer را برابر با PieRenderer تعیین کنیم. نمودار دایره‌ای برخلاف یک نمودار میله‌ای، دارای محور Y نیست. ما همچنین می‌توانیم مشخصه rendererOptions را نیز تعیین کنیم. ما در اینجا وارد جزییات هر بخش نمی‌شویم اما می‌توانید اطلاعات بیشتری را در صفحه مستندات آنلاین (+) مشاهده می‌کنید.

1$pc->set_series_default(array( 'shadow'=> false, 
2    'renderer'=> 'plugin::PieRenderer', 
3    'rendererOptions'=> array(
4      'highlightMouseOver' => true,
5      'startAngle'=> 180,
6      'sliceMargin'=> 4,
7      'showDataLabels'=> true )
8  ));

همچنین باید یک راهنمای نمودار نشان دهیم. دستور set_legend زیر، یک راهنما در سمت غرب (با w مشخص شده) یا چپ نمودار دایره‌ای نمایش می‌دهد.

1$pc->set_legend(array('show'=>true,'location'=> 'w'));

همچنین حاشیه و پس‌زمینه را حذف می‌کنیم.

1$pc->set_grid(array(
2    'background'=>'white',
3    'borderWidth'=>0,
4    'borderColor'=>'#000000',
5    'shadow'=>false));

در نهایت نمودار را با تعیین عرض و ارتفاع برحسب پیکسل رسم می‌کنیم.

1$pc->draw(660,400);

با این حال اگر کد را هم اینک اجرا کنید، نمودار را نخواهید دید، زیرا داده‌های مورد استفاده برای رندر آن هنوز در دسترس ما نیستند.

Datagrid خلاصه موجودی

در این بخش ما از همان Datagrid موجودی که در صفحه Products استفاده کردیم، بهره می‌گیریم. کافی است یک مورد دیگر به صورت دستگیره رویداد اضافه کنیم. در phpGrid می‌توان یک دستگیره رویداد با تابع ()add_event اضافه کرد. ()add_event به یک دستگیره رویداد اضافه می‌شود که اساساً یک تابع جاوا اسکریپت برای یک رویداد خاص phpGrid است. فهرستی از رویدادهای ممکن را در این صفحه (+) می‌توانید ببینید.

از آنجا که ما باید تا پیش از آن که داده‌ها برای رسم به نمودار ارسال شوند، منتظر datagrid بمانیم تا آن‌ها را بارگذاری کند، از رویداد jqGridLoadComplete استفاده می‌کنیم.

phpGrid 101 - رویداد jqGridLoadComplete

jqGridLoadComplete آخرین رویدادی است که در زمان پایان بارگذاری بدنه datagrid رخ می‌دهد. توجه کنید که بدنه grid در صورتی که کاربر ترتیب یک ستون را مرتب‌سازی کرده و یا یک فیلتر تنظیم کند مجدداً بارگذاری خواهد شد.

ارسال داده‌ها با جاوا اسکریپت

کد زیر در دستگیره رویداد جاوا اسکریپت به نام jqGridLoadComplete قرار می‌گیرد:

1function(status, rowid)
2{
3	var dataX = [];
4	var dataY = [];
5
6	d1 = $('#products').jqGrid('getCol', 'ProductLabel', false);
7	d2 = $('#products').jqGrid('getCol', 'InventoryReceived', false);
8	
9	npoints = d1.length;
10	for(var i=0; i < npoints; i++){
11		dataX[i] = [i+1, d1[i]];
12		dataY[i] = [i+1, parseInt(d2[i])];
13	}
14
15    var pieData = [];
16    for(var j=0; j < dataX.length; j++)
17    {
18        pieData.push([dataX[j][1], dataY[j][1]]);
19    }
20    console.log(pieData);
21    _PieChart.series[0].data = pieData;
22    _PieChart.replot({resetAxes:true});
23}

کد کامل به صورت زیر است:

1$dgProd = new C_DataGrid('SELECT id, ProductLabel, InventoryReceived FROM products', 'id', 'products');
2$dgProd->set_col_hidden('id', false);
3$dgProd->set_dimension('auto', 'auto')->set_pagesize(100);
4$onGridLoadComplete = <<<ONGRIDLOADCOMPLETE
5function(status, rowid)
6{
7	var dataX = [];
8	var dataY = [];
9
10	d1 = $('#products').jqGrid('getCol', 'ProductLabel', false);
11	d2 = $('#products').jqGrid('getCol', 'InventoryReceived', false);
12	d3 = $('#products').jqGrid('getCol', 'InventoryShipped', false);
13	d4 = $('#products').jqGrid('getCol', 'InventoryOnHand', false);
14
15	
16	npoints = d1.length;
17	for(var i=0; i < npoints; i++){
18		dataX[i] = [i+1, d1[i]];
19		dataY[i] = [i+1, parseInt(d2[i])];
20	}
21
22    var pieData = [];
23    for(var j=0; j < dataX.length; j++)
24    {
25        pieData.push([dataX[j][1], dataY[j][1]]);
26    }
27    console.log(pieData);
28    _PieChart.series[0].data = pieData;
29    _PieChart.replot({resetAxes:true});
30}
31ONGRIDLOADCOMPLETE;
32$dgProd->add_event("jqGridLoadComplete", $onGridLoadComplete);
33$dgProd->display();

سخن پایانی

اینک ما موفق شدیم نخستین سیستم موجودی انبار خود را با استفاده از PHP و MySQL بسازیم. امیدواریم از مطالعه این راهنما بهره لازم را برده باشید. برای دانلود سورس کد کامل این راهنما می‌توانید به این صفحه گیت‌هاب (+) مراجعه کنید.

اگر این مطلب برای شما مفید بوده است، آموزش‌های زیر نیز به شما پیشنهاد می‌شوند:

==

بر اساس رای ۱ نفر
آیا این مطلب برای شما مفید بود؟
اگر بازخوردی درباره این مطلب دارید یا پرسشی دارید که بدون پاسخ مانده است، آن را از طریق بخش نظرات مطرح کنید.
منابع:
free-code-camp
نظر شما چیست؟

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *