PageRenderTime 29ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 0ms

/opensourcepos/application/controllers/procurement.php

https://bitbucket.org/jit_bec/shopifine
PHP | 1531 lines | 1093 code | 248 blank | 190 comment | 145 complexity | 88003cd95807d22a61b298206b7ebea0 MD5 | raw file
Possible License(s): LGPL-3.0
  1. <?php
  2. require_once ("secure_area.php");
  3. class Procurement extends Secure_area
  4. {
  5. private $user;
  6. private $username;
  7. function __construct()
  8. {
  9. parent::__construct('procurement');
  10. $this->load->model('Purchase_order_master');
  11. $this->load->model('Purchase_invoice_master');
  12. $this->load->model('Purchase_invoice_item');
  13. $this->load->model('Purchase_order_item');
  14. $this->load->model('Purchase_quote_master');
  15. $this->load->model('Purchase_quote_item');
  16. $this->load->model('Receipt_master');
  17. $this->load->model('Receipt_item');
  18. $this->load->model('Delivery_point');
  19. $this->load->model('Product_price');
  20. $this->load->model('Outgoing_payment');
  21. // $this->load->model('acl/User','Userview');
  22. $this->user= $this->User->get_logged_in_employee_info();
  23. $this->username = $this->user->last_name." ".$this->user->first_name;
  24. $param = array('user' => $this->user->username);
  25. $this->load->library('acl-library/Acl',$param,'Acl');
  26. }
  27. /* PURCHASE QUOTE GRID START */
  28. function index()
  29. {
  30. $users = $this->User->getAllUsersByRole(null,array('field_name'=>'role_name',array('Everyone','Guest')));
  31. foreach($users as $user) {
  32. $user_id=$user["person_id"];
  33. $username=$user["username"];
  34. //$value = $denom["denom_json"];
  35. if (!empty($user_id)){
  36. $userOptions.="<OPTION VALUE=\"$user_id\">".$username;
  37. }
  38. }
  39. $data['userOptions'] = $userOptions;
  40. $this->load->view("procurement/quote/purchase_quote_grid",$data);
  41. }
  42. /* common functions */
  43. function populateSuppliers(){
  44. $suppliers= $this->Supplier->getAll();
  45. foreach($suppliers as $supplier) {
  46. $id=$supplier["id"];
  47. $thing=$supplier["supplier_name"];
  48. $supplieroptions.="<OPTION VALUE=\"$id\">".$thing;
  49. }
  50. echo $supplieroptions;
  51. }
  52. function getCostPrice(){
  53. $id = $_REQUEST['productid'];
  54. $productDetails = $this->Product_price->getByProductId($id);
  55. echo $productDetails->cost_price;
  56. }
  57. /* end common */
  58. /*start quote */
  59. function populateRFQ(){
  60. $page = $_REQUEST['page'];
  61. $limit = $_REQUEST['rows'];
  62. $sidx = $_REQUEST['sidx'];
  63. $sord = $_REQUEST['sord'];
  64. $searchOn = $_REQUEST['_search'];
  65. $status = $_REQUEST['status'];
  66. //$where = array('status'=>'rfq');
  67. if ($status!=self::ALL){
  68. $where['owner_id'] = $this->user->person_id;
  69. $where['status'] = $status;
  70. }
  71. //standard response parameters
  72. $quotedata = array();
  73. $count = $this->Purchase_quote_master->totalNoOfRows($where);
  74. if( $count > 0 && $limit > 0) {
  75. $total_pages = ceil($count/$limit);
  76. } else {
  77. $total_pages = 0;
  78. }
  79. if ($page > $total_pages) $page=$total_pages;
  80. $start = $limit*$page - $limit;
  81. // if for some reasons start position is negative set it to 0
  82. // typical case is that the user type 0 for the requested page
  83. if($start <0) $start = 0;
  84. $clauses = array('orderBy'=>$sidx,'orderDir'=>$sord,'startLimit'=>$start,'limit'=>$limit);
  85. $data['total'] = $total_pages;
  86. $data['page'] = $page;
  87. $data['records'] = $count;
  88. if($searchOn=='true') {
  89. $filters = json_decode($_REQUEST['filters'],true);
  90. $groupOp = $filters['groupOp'];
  91. $rules = $filters['rules'];
  92. $like_condition = array();
  93. foreach ($rules as $rule){
  94. $field = $rule['field'];
  95. $op= $rule['op'];
  96. $input = $rule['data'];
  97. $like_condition[$field] = trim($input);
  98. }
  99. $quotes = $this->Purchase_quote_master->getAll(false,$where,$clauses,$like_condition);
  100. }
  101. else {
  102. $quotes = $this->Purchase_quote_master->getAll(false,$where);
  103. }
  104. foreach ($quotes as $dp){
  105. if ($status==self::WAITING_FOR_APPROVAL){
  106. /* we dont need actions column in approval grid . So not passing the blank */
  107. array_push($quotedata, array('id'=> $dp['id'],'dprow' => array($dp['reference'],$dp['supplier_name'],$dp['estimated_value'],$dp['status'],$dp['raised_by_name'],$dp['owner_name'],$dp['needed_by_date'])));
  108. }
  109. else if ($status==self::REJECTED){
  110. /* Add Extra Columns Rejected and Rejected Notes Remove Status */
  111. array_push($quotedata, array('id'=> $dp['id'],'dprow' => array($dp['reference'],$dp['supplier_name'],$dp['estimated_value'],$dp['raised_by_name'],$dp['owner_name'],$dp['needed_by_date'],$dp['approved_by_name'],$dp['approval_notes'])));
  112. }
  113. else if ($status==self::OPEN){
  114. array_push($quotedata, array('id'=> $dp['id'],'dprow' => array('',$dp['reference'],$dp['supplier_name'],$dp['estimated_value'],$dp['status'],$dp['raised_by_name'],$dp['owner_name'],$dp['needed_by_date'])));
  115. }
  116. else {
  117. array_push($quotedata, array('id'=> $dp['id'],'dprow' => array($dp['reference'],$dp['supplier_name'],$dp['estimated_value'],$dp['status'],$dp['raised_by_name'],$dp['owner_name'],$dp['needed_by_date'],$dp['notes'],$dp['approved_by_name'],$dp['approval_notes'])));
  118. }
  119. }
  120. $data['quotedata'] = $quotedata;
  121. echo json_encode($data);
  122. }
  123. function createRFQ(){
  124. $id = $_REQUEST['quoteId'];
  125. $purchase_quote_data['supplier_id'] = $_REQUEST['supplierId'];
  126. $purchase_quote_data['warehouse_id'] = $_REQUEST['warehouseId'];
  127. $dateObj = DateTime::createFromFormat('d/m/Y', $_REQUEST['reqdate']);
  128. log_message('debug','converted '.$dateObj->format('Y-m-d'));
  129. $purchase_quote_data['needed_by_date'] = $dateObj->format('Y-m-d');
  130. $purchase_quote_data['notes'] = $_REQUEST['notes'];
  131. $purchase_quote_data['owner_id'] = $this->user->person_id;
  132. if (empty($id)){
  133. $purchase_quote_data['raised_by'] = $this->user->person_id;
  134. $id = $this->Purchase_quote_master->createQuote($purchase_quote_data);
  135. }
  136. else {
  137. $where_clause = array('id'=>$id);
  138. $this->Purchase_quote_master->update($where_clause, $purchase_quote_data);
  139. }
  140. echo $id;
  141. }
  142. //this function validates the record after close button of dialog being pressed. If no items are aadded the record is deleted
  143. function closeValidate(){
  144. $id = $_REQUEST['id'];
  145. if (!empty($id)){
  146. $ifExists = $this->Purchase_quote_master->exists($id);
  147. if ($ifExists){
  148. $where_clause_quote = array('id'=>$id);
  149. $this->Purchase_quote_master->update($where_clause_quote,array('status'=>self::CANCELLED));
  150. $where_clause_quote_item = array('quote_id'=>$id);
  151. $this->Purchase_quote_item->update($where_clause_quote_item,array('status'=>self::CANCELLED));
  152. }
  153. }
  154. }
  155. function modifyQuote (){
  156. $id = $_REQUEST['id'];
  157. $oper = $_REQUEST['oper'];
  158. $this->db->trans_start();
  159. if ($oper=='edit'){
  160. //$dateObj = DateTime::createFromFormat('d/m/Y', $_REQUEST['needed_by_date']);
  161. //log_message('debug','converted item date '.$dateObj->format('Y-m-d'));
  162. $purchase_quote_data['needed_by_date'] = $_REQUEST['needed_by_date'];
  163. //while editing the supplier id is passed.
  164. $purchase_quote_data['supplier_id'] = $_REQUEST['supplier_name'];
  165. $where_clause_quote = array('id'=>$id);
  166. $this->Purchase_quote_master->update($where_clause_quote,$purchase_quote_data);
  167. }
  168. else if ($oper=='del'){
  169. $idAraay = explode(",", $id);
  170. foreach($idAraay as $tempId){
  171. $where_clause_quote = array('id'=>$tempId);
  172. $this->Purchase_quote_master->update($where_clause_quote,array('status'=>'cancelled'));
  173. $where_clause_quote_item = array('quote_id'=>$tempId);
  174. $this->Purchase_quote_item->update($where_clause_quote_item,array('status'=>'cancelled'));
  175. }
  176. }
  177. $this->db->trans_complete();
  178. }
  179. //
  180. function testdate(){
  181. // $date = '25/10/2012';
  182. // $dateObj = DateTime::createFromFormat('d/m/Y', $date);
  183. // $mysqldt = $dateObj->format('Y-m-d');
  184. echo date("Y-m-d H:i:s", time());
  185. }
  186. function addQuoteItem (){
  187. //$id = $_REQUEST['quoteId'];
  188. $product_id = $_REQUEST['productid'];
  189. $purchase_quote_data['quote_id'] = $_REQUEST['quoteid'];
  190. $purchase_quote_data['product_id'] = $product_id;
  191. $dateObj = DateTime::createFromFormat('d/m/Y', $_REQUEST['needeedByDate']);
  192. log_message('debug','converted item date '.$dateObj->format('Y-m-d'));
  193. $purchase_quote_data['needed_by_date'] = $dateObj->format('Y-m-d');
  194. $purchase_quote_data['quoted_quantity'] = $_REQUEST['quantity'];
  195. $purchase_quote_data['expected_price'] = $_REQUEST['exprice'];
  196. $purchase_quote_data['estimated_value'] = $_REQUEST['quantity']*$_REQUEST['exprice'];
  197. $purchase_quote_data['comments'] = $_REQUEST['descItem'];
  198. $productDetails = $this->Product->getByProductId($product_id);
  199. $purchase_quote_data['sku'] = $productDetails->barcode;
  200. $purchase_quote_data['name'] = $productDetails->product_name;
  201. $id = $this->createQuoteItem($purchase_quote_data);
  202. }
  203. //business logic
  204. function createQuoteItem($purchase_quote_data){
  205. $this->db->trans_start();
  206. /* insert into quote item */
  207. $this->Purchase_quote_item->insert($purchase_quote_data);
  208. log_message('debug','insert statement ='.$this->db->last_query());
  209. $id = $this->db->insert_id();
  210. /* end insert */
  211. /* update reference number in quote item */
  212. $where_clause = array('id'=>$id);
  213. $this->Purchase_quote_item->update($where_clause, array('reference' => 10000000 + $id));
  214. /* end update */
  215. /* update estimated value in quote master */
  216. $quote_id = $purchase_quote_data['quote_id'];
  217. $quote_details=$this->Purchase_quote_master->getById($quote_id);
  218. $estimated_value = $quote_details->estimated_value + $purchase_quote_data['estimated_value'];
  219. $this->Purchase_quote_master->update(array('id'=>$quote_id),array('estimated_value'=>$estimated_value));
  220. log_message('debug','update statement ='.$this->db->last_query());
  221. /* end update estimated value in quote master */
  222. $this->db->trans_complete();
  223. return $id;
  224. }
  225. function modifyQuoteItem (){
  226. $id = $_REQUEST['id'];
  227. $item_details=$this->Purchase_quote_item->getById($id);
  228. $quote_id = $item_details->quote_id;
  229. $current_est_value = $item_details->estimated_value;
  230. $oper = $_REQUEST['oper'];
  231. $this->db->trans_start();
  232. if ($oper=='edit'){
  233. //$dateObj = DateTime::createFromFormat('d/m/Y', $_REQUEST['needed_by_date']);
  234. //log_message('debug','converted item date '.$dateObj->format('Y-m-d'));
  235. $purchase_quote_data['needed_by_date'] = $_REQUEST['needed_by_date'];
  236. $purchase_quote_data['quoted_quantity'] = $_REQUEST['quoted_quantity'];
  237. $purchase_quote_data['expected_price'] = $_REQUEST['expected_price'];
  238. $purchase_quote_data['comments'] = $_REQUEST['comments'];
  239. $purchase_quote_data['estimated_value'] = $_REQUEST['quoted_quantity']*$_REQUEST['expected_price'];
  240. $where_clause = array('id'=>$id);
  241. $this->Purchase_quote_item->update($where_clause,$purchase_quote_data);
  242. $quote_details=$this->Purchase_quote_master->getById($quote_id);
  243. $estimated_value = $quote_details->estimated_value - $current_est_value + $purchase_quote_data['estimated_value'];
  244. $this->Purchase_quote_master->update(array('id'=>$quote_id),array('estimated_value'=>$estimated_value));
  245. }
  246. else if ($oper=='del'){
  247. $quote_details=$this->Purchase_quote_master->getById($quote_id);
  248. $estimated_value = $quote_details->estimated_value - $item_details->estimated_value;
  249. $this->Purchase_quote_master->update(array('id'=>$quote_id),array('estimated_value'=>$estimated_value));
  250. $where_clause = array('id'=>$id);
  251. $this->Purchase_quote_item->update($where_clause,array('status'=>'cancelled'));
  252. }
  253. $this->db->trans_complete();
  254. }
  255. function populateQuoteItems(){
  256. $quoteid = $_REQUEST['quoteId'];
  257. if (!empty($quoteid)){
  258. $page = $_REQUEST['page'];
  259. $limit = $_REQUEST['rows'];
  260. $sidx = $_REQUEST['sidx'];
  261. $sord = $_REQUEST['sord'];
  262. //standard response parameters
  263. $quotedata = array();
  264. $where = array('quote_id' => $quoteid );
  265. $count = $this->Purchase_quote_item->totalNoOfRows($where);
  266. if( $count > 0 && $limit > 0) {
  267. $total_pages = ceil($count/$limit);
  268. } else {
  269. $total_pages = 0;
  270. }
  271. if ($page > $total_pages) $page=$total_pages;
  272. $start = $limit*$page - $limit;
  273. // if for some reasons start position is negative set it to 0
  274. // typical case is that the user type 0 for the requested page
  275. if($start <0) $start = 0;
  276. $clauses = array('orderBy'=>$sidx,'orderDir'=>$sord,'startLimit'=>$start,'limit'=>$limit);
  277. $data['total'] = $total_pages;
  278. $data['page'] = $page;
  279. $data['records'] = $count;
  280. $quotes = $this->Purchase_quote_item->getAll(false,$where);
  281. foreach ($quotes as $dp){
  282. array_push($quotedata, array('id'=> $dp['id'],'dprow' => array($dp['name'],$dp['quoted_quantity'],$dp['needed_by_date'],$dp['expected_price'],$dp['estimated_value'],$dp['comments'])));
  283. }
  284. $data['quoteitemdata'] = $quotedata;
  285. echo json_encode($data);
  286. }
  287. }
  288. function generatePOFromRFQ(){
  289. $ids= $_REQUEST['ids'];
  290. foreach($ids as $id){
  291. log_message('debug',' id '.$id);
  292. $quote_details=$this->Purchase_quote_master->getById($id,true);
  293. if ($quote_details['status']==self::OPEN ||$quote_details['status']==self::WAITING_FOR_APPROVAL ) {
  294. $this->db->trans_start();
  295. $this->Purchase_quote_master->update(array('id'=>$id),array('approved_by'=>$this->user->person_id));
  296. $this->generatePOInternal($quote_details);
  297. $this->db->trans_complete();
  298. }
  299. }
  300. }
  301. /* PURCHASE QUOTE GRID END*/
  302. /* APPROVAL GRUD START */
  303. function approveOrReject(){
  304. $id= $_REQUEST['quoteId'];
  305. $action= $_REQUEST['action'];
  306. log_message('debug',' id '.$id);
  307. log_message('debug',' action '.$action);
  308. $quote_details=$this->Purchase_quote_master->getById($id,true);
  309. if ($quote_details['status']==self::WAITING_FOR_APPROVAL ) {
  310. if ($action == 'approve'){
  311. $this->db->trans_start();
  312. $this->Purchase_quote_master->update(array('id'=>$id),array('approved_by'=>$this->user->person_id,'approval_notes'=>$_REQUEST['quote_approval_notes']));
  313. $this->generatePOInternal($quote_details);
  314. $this->db->trans_complete();
  315. }
  316. else if ($action == 'reject'){
  317. $this->db->trans_start();
  318. $this->Purchase_quote_master->update(array('id'=>$id),array('status'=>self::REJECTED,'approved_by'=>$this->user->person_id,'approval_notes'=>$_REQUEST['quote_approval_notes']));
  319. $item_details=$this->Purchase_quote_item->getByQuoteId($id);
  320. foreach ($item_details as $item_data){
  321. $this->Purchase_quote_item->update(array('id'=>$item_data['id']),array('status'=>self::REJECTED));
  322. }
  323. $this->db->trans_complete();
  324. }
  325. }
  326. }
  327. /* APPROVAL GRID END */
  328. /* REJECTED GRID START*/
  329. function reopenRFQ (){
  330. $ids= $_REQUEST['ids'];
  331. foreach($ids as $id){
  332. log_message('debug',' id '.$id);
  333. $quote_details=$this->Purchase_quote_master->getById($id,true);
  334. if ($quote_details['status']==self::REJECTED ) {
  335. $this->db->trans_start();
  336. $this->Purchase_quote_master->update(array('id'=>$id),array('status'=>self::OPEN,'last_updated_by'=>$this->user->person_id));
  337. $item_details=$this->Purchase_quote_item->getByQuoteId($id);
  338. foreach ($item_details as $item_data){
  339. $this->Purchase_quote_item->update(array('id'=>$item_data['id']),array('status'=>self::OPEN));
  340. }
  341. $this->db->trans_complete();
  342. }
  343. }
  344. }
  345. /* REJECTED GRID END*/
  346. /* COMMON FUNCTIONS FOR RFQ GRIDS */
  347. private function generatePOInternal($quote_details){
  348. $id=$quote_details['id'];
  349. $order_data['owner_id'] = $quote_details['owner_id'];
  350. $order_data['needed_by_date'] = $quote_details['needed_by_date'];
  351. $order_data['generated_by'] = $this->user->person_id;
  352. $order_data['quote_id'] = $quote_details['id'];
  353. log_message('debug',json_encode($order_data));
  354. $order_id = $this->Purchase_order_master->createOrder($order_data);
  355. log_message('debug',$this->db->last_query());
  356. $this->Purchase_quote_master->update(array('id'=>$id),array('status'=>self::ORDERED,'order_id'=>$order_id));
  357. log_message('debug',$this->db->last_query());
  358. //now update line item status
  359. $item_details=$this->Purchase_quote_item->getByQuoteId($id);
  360. foreach ($item_details as $item_data){
  361. if ($item_data['status'] == self::OPEN || $item_data['status'] == self::WAITING_FOR_APPROVAL){
  362. $order_item_data['name'] = $item_data['name'];
  363. $order_item_data['sku'] = $item_data['sku'];
  364. $order_item_data['product_id'] = $item_data['product_id'];
  365. $order_item_data['estimated_value'] = $item_data['estimated_value'];
  366. $order_item_data['needed_by_date'] = $item_data['needed_by_date'];
  367. $order_item_data['quoted_quantity'] = $item_data['quoted_quantity'];
  368. //repeatative ..as of now as no difference between quoted and ordered quantity
  369. $order_item_data['ordered_quantity'] = $item_data['quoted_quantity'];
  370. $order_item_data['expected_price'] = $item_data['expected_price'];
  371. $order_item_data['order_id'] =$order_id;
  372. $order_item_data['quote_line_id'] = $item_data['id'];
  373. $order_line_id = $this->createOrderItem($order_item_data);
  374. $this->Purchase_quote_item->update(array('id'=>$item_data['id']),array('status'=>self::ORDERED,'order_line_id'=>$order_line_id));
  375. }
  376. }
  377. }
  378. /*end quote */
  379. /* RECEIVING GRID START */
  380. function populatePOToReceive(){
  381. $person_id = $this->user->person_id;
  382. $in_where=array('field_name'=>'status','id_array'=>array(self::OPEN,self::RECEIVING)) ;
  383. $this->populatePOInternal($person_id,$in_where);
  384. }
  385. /* RECEIVING GRID END */
  386. function populatePayments(){
  387. $invoiceId = $_REQUEST['invoiceId'];
  388. if (!empty($invoiceId)){
  389. $page = $_REQUEST['page'];
  390. $limit = $_REQUEST['rows'];
  391. $sidx = $_REQUEST['sidx'];
  392. $sord = $_REQUEST['sord'];
  393. //standard response parameters
  394. $quotedata = array();
  395. $where = array('invoice_id' => $invoiceId );
  396. $count = $this->Outgoing_payment->totalNoOfRows($where);
  397. if( $count > 0 && $limit > 0) {
  398. $total_pages = ceil($count/$limit);
  399. } else {
  400. $total_pages = 0;
  401. }
  402. if ($page > $total_pages) $page=$total_pages;
  403. $start = $limit*$page - $limit;
  404. // if for some reasons start position is negative set it to 0
  405. // typical case is that the user type 0 for the requested page
  406. if($start <0) $start = 0;
  407. $clauses = array('orderBy'=>$sidx,'orderDir'=>$sord,'startLimit'=>$start,'limit'=>$limit);
  408. $data['total'] = $total_pages;
  409. $data['page'] = $page;
  410. $data['records'] = $count;
  411. $quotes = $this->Outgoing_payment->getAll(false,$where);
  412. foreach ($quotes as $dp){
  413. array_push($quotedata, array('id'=> $dp['id'],'dprow' => array($dp['payment_reference'],$dp['payment_type'],$dp['amount'],$dp['comments'])));
  414. }
  415. $data['quoteitemdata'] = $quotedata;
  416. echo json_encode($data);
  417. }
  418. }
  419. function populateReceived(){
  420. $person_id = $this->user->person_id;
  421. $in_where=array('field_name'=>'status','id_array'=>array(self::RECEIVED)) ;
  422. // for Invoices to Pay Grid ..Override Status
  423. $invoice_id = $_REQUEST['invoiceId'];
  424. if (!empty($invoice_id)){
  425. $where['invoice_id'] = $invoice_id;
  426. $in_where=array('field_name'=>'status','id_array'=>array(self::INVOICED)) ;
  427. }
  428. $page = $_REQUEST['page'];
  429. $limit = $_REQUEST['rows'];
  430. $sidx = $_REQUEST['sidx'];
  431. $sord = $_REQUEST['sord'];
  432. $searchOn = $_REQUEST['_search'];
  433. if (!empty($person_id)){
  434. $where['owner_id'] = $person_id;
  435. }
  436. //standard response parameters
  437. $quotedata = array();
  438. $count = $this->Receipt_master->totalNoOfRows($where);
  439. if( $count > 0 && $limit > 0) {
  440. $total_pages = ceil($count/$limit);
  441. } else {
  442. $total_pages = 0;
  443. }
  444. if ($page > $total_pages) $page=$total_pages;
  445. $start = $limit*$page - $limit;
  446. // if for some reasons start position is negative set it to 0
  447. // typical case is that the user type 0 for the requested page
  448. if($start <0) $start = 0;
  449. $clauses = array('orderBy'=>$sidx,'orderDir'=>$sord,'startLimit'=>$start,'limit'=>$limit);
  450. $data['total'] = $total_pages;
  451. $data['page'] = $page;
  452. $data['records'] = $count;
  453. if($searchOn=='true') {
  454. $filters = json_decode($_REQUEST['filters'],true);
  455. $groupOp = $filters['groupOp'];
  456. $rules = $filters['rules'];
  457. $like_condition = array();
  458. foreach ($rules as $rule){
  459. $field = $rule['field'];
  460. $op= $rule['op'];
  461. $input = $rule['data'];
  462. if ($field == 'order_reference' ){
  463. $orderDetails = $this->Purchase_order_master->getGridByReference($input);
  464. $like_condition['order_id'] = $orderDetails['id'];
  465. }
  466. else if ($field == 'quote_reference'){
  467. $orderDetails = $this->Purchase_order_master->getGridByQuoteReference($input);
  468. $like_condition['order_id'] = $orderDetails['id'];
  469. }
  470. else if ($field == 'supplier_name'){
  471. $supplierDetails = $this->Supplier->getByName($input);
  472. $like_condition['supplier_id'] = $supplierDetails['id'];
  473. }
  474. else {
  475. $like_condition[$field] = trim($input);
  476. }
  477. }
  478. $quotes = $this->Receipt_master->getAll(false,$where,null,$clauses,$like_condition,$in_where);
  479. }
  480. else {
  481. $quotes = $this->Receipt_master->getAll(false,$where,null,null,null,$in_where);
  482. }
  483. foreach ($quotes as $dp){
  484. $orderDetails = $this->Purchase_order_master->getGridById($dp['order_id']);
  485. array_push($quotedata, array('id'=> $dp['id'],'dprow' => array($dp['reference'],$dp['supplier_receipt_number'],$orderDetails['supplier_name'],$dp['status'],$dp['order_id'],$orderDetails['reference'],$orderDetails['quote_reference'])));
  486. }
  487. $data['quotedata'] = $quotedata;
  488. echo json_encode($data);
  489. }
  490. function populatePOInternal($person_id,$in_where){
  491. $page = $_REQUEST['page'];
  492. $limit = $_REQUEST['rows'];
  493. $sidx = $_REQUEST['sidx'];
  494. $sord = $_REQUEST['sord'];
  495. $searchOn = $_REQUEST['_search'];
  496. if (!empty($person_id)){
  497. $where['owner_id'] = $person_id;
  498. }
  499. //standard response parameters
  500. $quotedata = array();
  501. $count = $this->Purchase_order_master->totalNoOfRows($where);
  502. if( $count > 0 && $limit > 0) {
  503. $total_pages = ceil($count/$limit);
  504. } else {
  505. $total_pages = 0;
  506. }
  507. if ($page > $total_pages) $page=$total_pages;
  508. $start = $limit*$page - $limit;
  509. // if for some reasons start position is negative set it to 0
  510. // typical case is that the user type 0 for the requested page
  511. if($start <0) $start = 0;
  512. $clauses = array('orderBy'=>$sidx,'orderDir'=>$sord,'startLimit'=>$start,'limit'=>$limit);
  513. $data['total'] = $total_pages;
  514. $data['page'] = $page;
  515. $data['records'] = $count;
  516. if($searchOn=='true') {
  517. $filters = json_decode($_REQUEST['filters'],true);
  518. $groupOp = $filters['groupOp'];
  519. $rules = $filters['rules'];
  520. $like_condition = array();
  521. foreach ($rules as $rule){
  522. $field = $rule['field'];
  523. $op= $rule['op'];
  524. $input = $rule['data'];
  525. $like_condition[$field] = trim($input);
  526. }
  527. $quotes = $this->Purchase_order_master->getAll(false,$where,$clauses,$like_condition,$in_where);
  528. }
  529. else {
  530. $quotes = $this->Purchase_order_master->getAll(false,$where,null,null,$in_where);
  531. }
  532. foreach ($quotes as $dp){
  533. array_push($quotedata, array('id'=> $dp['id'],'dprow' => array($dp['reference'],$dp['supplier_id'],$dp['supplier_name'],$dp['estimated_value'],$dp['status'],$dp['raised_by_name'],$dp['needed_by_date'])));
  534. }
  535. $data['quotedata'] = $quotedata;
  536. echo json_encode($data);
  537. }
  538. function validateReceiving(){
  539. $order_id = $_REQUEST['order_id'];
  540. $receiving_notes = $_REQUEST['receiving_notes'];
  541. //check the no of order line items with status receiving.
  542. $totalNoOfRowsByOrderIdReceived = $this->Purchase_order_item->totalNoOfRows(array('order_id'=>$order_id,'status'=>self::RECEIVED));
  543. $totalNoOfRowsByOrderIdTotal = $this->Purchase_order_item->totalNoOfRows(array('order_id'=>$order_id));
  544. if ($totalNoOfRowsByOrderIdReceived == $totalNoOfRowsByOrderIdTotal){
  545. // all the order lines are received
  546. $this->Purchase_order_master->update(array('id'=>$order_id,'status'=>self::RECEIVING),array('status'=>self::RECEIVED,'receiving_notes'=>$receiving_notes));
  547. $this->Receipt_master->update(array('order_id'=>$order_id,'status'=>self::RECEIVING),array('status'=>self::RECEIVED));
  548. }
  549. else {
  550. $this->Purchase_order_master->update(array('id'=>$order_id,'status'=>self::RECEIVING),array('receiving_notes'=>$receiving_notes));
  551. }
  552. }
  553. // function validateReceivingc
  554. // $order_id = $_REQUEST['order_id'];
  555. // $receiving_notes = $_REQUEST['receiving_notes'];
  556. // //check the no of order line items with status receiving.
  557. // $totalNoOfRowsByOrderIdReceived = $this->Purchase_order_item->totalNoOfRows(array('order_id'=>$order_id,'status'=>self::RECEIVING));
  558. // $totalNoOfRowsByOrderIdOpen = $this->Purchase_order_item->totalNoOfRows(array('order_id'=>$order_id,'status'=>self::OPEN));
  559. // if ($totalNoOfRowsByOrderIdReceiving == 0 && $totalNoOfRowsByOrderIdOpen==0){
  560. // // none of the line items are in Open or receiving State
  561. //
  562. // $this->Purchase_order_master->update(array('id'=>$order_id,'status'=>self::RECEIVING),array('status'=>self::RECEIVED,'receiving_notes'=>$receiving_notes));
  563. // $this->Receipt_master->update(array('order_id'=>$order_id,'status'=>self::RECEIVING),array('status'=>self::RECEIVED));
  564. // }
  565. // else {
  566. // $this->Purchase_order_master->update(array('id'=>$order_id,'status'=>self::RECEIVING),array('receiving_notes'=>$receiving_notes));
  567. // }
  568. //
  569. //
  570. // }
  571. function modifyOrder (){
  572. $id = $_REQUEST['id'];
  573. $oper = $_REQUEST['oper'];
  574. $this->db->trans_start();
  575. if ($oper=='edit'){
  576. //$dateObj = DateTime::createFromFormat('d/m/Y', $_REQUEST['needed_by_date']);
  577. //log_message('debug','converted item date '.$dateObj->format('Y-m-d'));
  578. $purchase_quote_data['needed_by_date'] = $_REQUEST['needed_by_date'];
  579. $purchase_quote_data['supplier_name'] = $_REQUEST['supplier_name'];
  580. $where_clause_quote = array('id'=>$id);
  581. $this->Purchase_quote_master->update($where_clause_quote,$purchase_quote_data);
  582. }
  583. else if ($oper=='del'){
  584. $idAraay = explode(",", $id);
  585. foreach($idAraay as $tempId){
  586. $where_clause_quote = array('id'=>$tempId);
  587. $this->Purchase_quote_master->update($where_clause_quote,array('status'=>'cancelled'));
  588. $where_clause_quote_item = array('quote_id'=>$tempId);
  589. $this->Purchase_quote_item->update($where_clause_quote_item,array('status'=>'cancelled'));
  590. }
  591. }
  592. $this->db->trans_complete();
  593. }
  594. function addOrderItem (){
  595. //$id = $_REQUEST['quoteId'];
  596. $product_id = $_REQUEST['productid'];
  597. $purchase_quote_data['quote_id'] = $_REQUEST['orderId'];
  598. $purchase_quote_data['product_id'] = $product_id;
  599. $dateObj = DateTime::createFromFormat('d/m/Y', $_REQUEST['needeedByDate']);
  600. log_message('debug','converted item date '.$dateObj->format('Y-m-d'));
  601. $purchase_quote_data['needed_by_date'] = $dateObj->format('Y-m-d');
  602. $purchase_quote_data['quoted_quantity'] = $_REQUEST['quantity'];
  603. $purchase_quote_data['expected_price'] = $_REQUEST['exprice'];
  604. $purchase_quote_data['estimated_value'] = $_REQUEST['quantity']*$_REQUEST['exprice'];
  605. $purchase_quote_data['comments'] = $_REQUEST['descItem'];
  606. $productDetails = $this->Product->getByProductId($product_id);
  607. $purchase_quote_data['sku'] = $productDetails->barcode;
  608. $purchase_quote_data['name'] = $productDetails->product_name;
  609. $id = $this->createQuoteItem($purchase_quote_data);
  610. }
  611. //business logic
  612. function createOrderItem($purchase_quote_data){
  613. $this->db->trans_start();
  614. /* insert into quote item */
  615. $this->Purchase_order_item->insert($purchase_quote_data);
  616. log_message('debug','insert statement ='.$this->db->last_query());
  617. $id = $this->db->insert_id();
  618. /* end insert */
  619. /* update reference number in quote item */
  620. $where_clause = array('id'=>$id);
  621. $this->Purchase_order_item->update($where_clause, array('reference' => 10000000 + $id));
  622. /* end update */
  623. $this->db->trans_complete();
  624. return $id;
  625. }
  626. function modifyOrderItem (){
  627. $id = $_REQUEST['id'];
  628. $item_details=$this->Purchase_quote_item->getById($id);
  629. $quote_id = $item_details->quote_id;
  630. $current_est_value = $item_details->estimated_value;
  631. $oper = $_REQUEST['oper'];
  632. $this->db->trans_start();
  633. if ($oper=='edit'){
  634. //$dateObj = DateTime::createFromFormat('d/m/Y', $_REQUEST['needed_by_date']);
  635. //log_message('debug','converted item date '.$dateObj->format('Y-m-d'));
  636. $purchase_quote_data['needed_by_date'] = $_REQUEST['needed_by_date'];
  637. $purchase_quote_data['quoted_quantity'] = $_REQUEST['quoted_quantity'];
  638. $purchase_quote_data['expected_price'] = $_REQUEST['expected_price'];
  639. $purchase_quote_data['comments'] = $_REQUEST['comments'];
  640. $purchase_quote_data['estimated_value'] = $_REQUEST['quoted_quantity']*$_REQUEST['expected_price'];
  641. $where_clause = array('id'=>$id);
  642. $this->Purchase_quote_item->update($where_clause,$purchase_quote_data);
  643. $quote_details=$this->Purchase_quote_master->getById($quote_id);
  644. $estimated_value = $quote_details->estimated_value - $current_est_value + $purchase_quote_data['estimated_value'];
  645. $this->Purchase_quote_master->update(array('id'=>$quote_id),array('estimated_value'=>$estimated_value));
  646. }
  647. else if ($oper=='del'){
  648. $quote_details=$this->Purchase_quote_master->getById($quote_id);
  649. $estimated_value = $quote_details->estimated_value - $item_details->estimated_value;
  650. $this->Purchase_quote_master->update(array('id'=>$quote_id),array('estimated_value'=>$estimated_value));
  651. $where_clause = array('id'=>$id);
  652. $this->Purchase_quote_item->update($where_clause,array('status'=>'cancelled'));
  653. }
  654. $this->db->trans_complete();
  655. }
  656. function populateOrderItems(){
  657. $orderid = $_REQUEST['orderId'];
  658. if (!empty($orderid)){
  659. $page = $_REQUEST['page'];
  660. $limit = $_REQUEST['rows'];
  661. $sidx = $_REQUEST['sidx'];
  662. $sord = $_REQUEST['sord'];
  663. //standard response parameters
  664. $quotedata = array();
  665. $where = array('order_id' => $orderid );
  666. $count = $this->Purchase_order_item->totalNoOfRows($where);
  667. if( $count > 0 && $limit > 0) {
  668. $total_pages = ceil($count/$limit);
  669. } else {
  670. $total_pages = 0;
  671. }
  672. if ($page > $total_pages) $page=$total_pages;
  673. $start = $limit*$page - $limit;
  674. // if for some reasons start position is negative set it to 0
  675. // typical case is that the user type 0 for the requested page
  676. if($start <0) $start = 0;
  677. $clauses = array('orderBy'=>$sidx,'orderDir'=>$sord,'startLimit'=>$start,'limit'=>$limit);
  678. $data['total'] = $total_pages;
  679. $data['page'] = $page;
  680. $data['records'] = $count;
  681. $quotes = $this->Purchase_order_item->getAll(false,$where);
  682. foreach ($quotes as $dp){
  683. array_push($quotedata, array('id'=> $dp['id'],'dprow' => array($dp['product_id'],$dp['name'],$dp['quoted_quantity'],$dp['received_quantity'],$dp['returned_quantity'],$dp['needed_by_date'],$dp['expected_price'],$dp['estimated_value'],$dp['received_value'],$dp['returned_value'],$dp['comments'])));
  684. }
  685. $data['orderitemdata'] = $quotedata;
  686. echo json_encode($data);
  687. }
  688. }
  689. function populateReceiptItems(){
  690. $receiptId = $_REQUEST['receiptId'];
  691. $orderLineId = $_REQUEST['orderLineId'];
  692. // as of now keep default oper as "receipt"
  693. $oper = "receipt";
  694. if (!empty($_REQUEST['oper'])){
  695. $oper = $_REQUEST['oper'];
  696. }
  697. $page = $_REQUEST['page'];
  698. $limit = $_REQUEST['rows'];
  699. $sidx = $_REQUEST['sidx'];
  700. $sord = $_REQUEST['sord'];
  701. //standard response parameters
  702. $quotedata = array();
  703. if ($oper=="receipt"){
  704. $where = array('receipt_id' => $receiptId );
  705. }
  706. else if ($oper=="orderline"){
  707. $where = array('order_line_id' => $orderLineId );
  708. }
  709. $count = $this->Receipt_item->totalNoOfRows($where);
  710. if( $count > 0 && $limit > 0) {
  711. $total_pages = ceil($count/$limit);
  712. } else {
  713. $total_pages = 0;
  714. }
  715. if ($page > $total_pages) $page=$total_pages;
  716. $start = $limit*$page - $limit;
  717. // if for some reasons start position is negative set it to 0
  718. // typical case is that the user type 0 for the requested page
  719. if($start <0) $start = 0;
  720. $clauses = array('orderBy'=>$sidx,'orderDir'=>$sord,'startLimit'=>$start,'limit'=>$limit);
  721. $data['total'] = $total_pages;
  722. $data['page'] = $page;
  723. $data['records'] = $count;
  724. $quotes = $this->Receipt_item->getAll(false,$where);
  725. foreach ($quotes as $dp){
  726. $receipt_data = $this->Receipt_master->getById($dp['receipt_id'],true);
  727. array_push($quotedata, array('id'=> $dp['id'],'dprow' => array($receipt_data['supplier_receipt_number'],$receipt_data['reference'],
  728. $dp['receipt_id'], $dp['order_line_id'],$dp['product_id'],$dp['name'],$dp['ordered_quantity'],$dp['received_quantity'],$dp['received_value'],$dp['returned_quantity'],$dp['returned_value'],$dp['receiving_notes'],$dp['returned_notes'])));
  729. }
  730. $data['receiptitemdata'] = $quotedata;
  731. echo json_encode($data);
  732. }
  733. function getOrderDetails(){
  734. $orderId=$_REQUEST['orderId'];
  735. if (!empty($orderId)){
  736. $order = $this->Purchase_order_master->getGridById($orderId);
  737. echo json_encode($order);
  738. }
  739. }
  740. function getQuoteDetails(){
  741. $quoteId=$_REQUEST['quoteId'];
  742. if (!empty($quoteId)){
  743. $quote = $this->Purchase_quote_master->getGridById($quoteId);
  744. echo json_encode($quote);
  745. }
  746. }
  747. function loadPOGrid()
  748. {
  749. $this->load->view("procurement/purchaseorder/purchase_order_grid",$data);
  750. }
  751. function loadOpenInvoicesGrid()
  752. {
  753. $this->load->view("procurement/invoice/purchase_invoice_grid",$data);
  754. }
  755. function loadFormFragment(){
  756. $this->load->view("procurement/purchaseorder/po_details",$data);
  757. }
  758. function loadNotesFragment(){
  759. $this->load->view("procurement/purchaseorder/po_notes",$data);
  760. }
  761. function loadWaitingForApprovalQuotesGrid (){
  762. $this->load->view("procurement/quote/approval/quote_approval_grid",$data);
  763. }
  764. function loadRejectedQuotesGrid (){
  765. $this->load->view("procurement/quote/rejected/quote_rejected_grid",$data);
  766. }
  767. function loadQuoteFormFragment(){
  768. $this->load->view("procurement/quote/approval/quote_details",$data);
  769. }
  770. function loadQuoteNotesFragment(){
  771. $this->load->view("procurement/quote/approval/quote_notes",$data);
  772. }
  773. function loadCreateQuotesGrid (){
  774. $productArray = $this->Product->getValues();
  775. foreach ($productArray as $product){
  776. //$data = array('label' => $model['model_name'], 'value' => $model['id']);
  777. //array_push($autoData,$data);
  778. $id = $product['id'];
  779. $name = $product['product_name'].'->'.$product['manufacturer'].' '.$product['model']
  780. .' '.$product['measurement_denomination'].' '.$product['uom'];
  781. $productOptions.="<OPTION VALUE=\"$id\">".$name;
  782. }
  783. $data['productOptions'] = $productOptions;
  784. $this->load->view("procurement/quote/create/quote_create_grid",$data);
  785. }
  786. function loadReceivedGrid (){
  787. $this->load->view("procurement/purchaseorder/received/received_order_grid",$data);
  788. }
  789. function loadCreateQuoteFormFragment(){
  790. $deliveryPoints = $this->Delivery_point->getAll();
  791. foreach($deliveryPoints as $deliveryPoint) {
  792. $id=$deliveryPoint["id"];
  793. $thing=$deliveryPoint["name"];
  794. $options.="<OPTION VALUE=\"$id\">".$thing;
  795. }
  796. $suppliers= $this->Supplier->getAll();
  797. foreach($suppliers as $supplier) {
  798. $id=$supplier["id"];
  799. $thing=$supplier["supplier_name"];
  800. $supplieroptions.="<OPTION VALUE=\"$id\">".$thing;
  801. }
  802. $data['warehouseOptions']=$options;
  803. $data['supplierOptions']=$supplieroptions;
  804. $this->load->view("procurement/quote/create/quote_details",$data);
  805. }
  806. function loadCreateQuoteNotesFragment(){
  807. $this->load->view("procurement/quote/create/quote_notes",$data);
  808. }
  809. function submitForApproval(){
  810. $idArray = $_REQUEST['ids'];
  811. if (!empty($idArray)){
  812. foreach($idArray as $tempId){
  813. $this->db->trans_start();
  814. $where_clause_quote = array('id'=>$tempId);
  815. $this->Purchase_quote_master->update($where_clause_quote,array('status'=> self::WAITING_FOR_APPROVAL));
  816. log_message('debug',$this->db->last_query());
  817. $where_clause_quote_item = array('quote_id'=>$tempId);
  818. $this->Purchase_quote_item->update($where_clause_quote_item,array('status'=>self::WAITING_FOR_APPROVAL));
  819. log_message('debug',$this->db->last_query());
  820. $this->db->trans_complete();
  821. }
  822. }
  823. }
  824. function assign(){
  825. $inv_id_array = json_decode($_REQUEST['sel_quote']);
  826. foreach($inv_id_array as $id){
  827. $quote_details = $this->Purchase_quote_master->getById($id);
  828. $notes= $quote_details->notes;
  829. $notes .= '<br/>Assigned By:' .$this->username.' Assignment Notes:'.$_REQUEST['assignment_notes'];
  830. $where_clause_array= array('id'=>$id);
  831. $inv_data = array
  832. (
  833. 'owner_id'=>$_REQUEST['userId'],
  834. 'notes'=>$notes
  835. );
  836. $this->Purchase_quote_master->update($where_clause_array,$inv_data);
  837. }
  838. }
  839. //receivings
  840. function receiveItems(){
  841. $oper = $_REQUEST["oper"];
  842. $action = $_REQUEST["action"];
  843. $order_line_id = $_REQUEST["order_line_id"];
  844. $order_id = $_REQUEST["order_id"];
  845. $receiptOp = $_REQUEST["receipt"];
  846. $receiptIp = $_REQUEST["receipt_ip"];
  847. $received_quantity = $_REQUEST["received_quantity"];
  848. $received_value = $_REQUEST["received_value"];
  849. $returned_quantity = $_REQUEST["returned_quantity"];
  850. $returned_value = $_REQUEST["returned_value"];
  851. if ($oper == "return"){
  852. if (!empty($_REQUEST["returned_notes"])){
  853. $receipt_item_data['returned_notes']=$_REQUEST["returned_notes"];
  854. }
  855. }
  856. else if ($oper == "receive"){
  857. if (!empty($_REQUEST["receiving_notes"])){
  858. $receipt_item_data['receiving_notes']=$_REQUEST["receiving_notes"];
  859. }
  860. }
  861. //if (!empty($rcvd_note)){
  862. $fmatted_rcvd_note = "&#013;&#010; **** ".date("Y-m-d H:i:s", time()). " ****&#013;&#010;".$_REQUEST["receiving_notes"];
  863. $rcvd_note="CONCAT(`receiving_notes`, '$fmatted_rcvd_note')";
  864. $notes_array['receiving_notes'] = $rcvd_note;
  865. //}
  866. //if (!empty($rtrnd_note)){
  867. $fmatted_rtrnd_note = "&#013;&#010; **** ".date("Y-m-d H:i:s", time()). " ****&#013;&#010;".$_REQUEST["returned_notes"];
  868. $rtrnd_note = "CONCAT(`returned_notes`, '$fmatted_rtrnd_note')";
  869. // $receipt_item_data['returned_notes']="CONCAT(`returned_notes`, $fmatted_rtrnd_note);";
  870. $notes_array['returned_notes'] = $rtrnd_note;
  871. //}
  872. $product_id = $_REQUEST["product_id"];
  873. $supplierId=$_REQUEST["supplier_id"];
  874. $productdetails = $this->Product->getByProductId($product_id,true);
  875. $receipt_item_data['product_id'] = $product_id;
  876. $receipt_item_data['name'] = $productdetails['product_name'];
  877. $receipt_item_data['sku'] = $productdetails['barcode'];
  878. $receipt_item_data['order_line_id'] = $order_line_id;
  879. $receipt_item_data['received_quantity']=$received_quantity;
  880. // total received and value for order line items
  881. $total_received_for_order = $_REQUEST['total_received_quantity'];
  882. $total_received_value_for_order = $_REQUEST['total_received_value'];
  883. $total_returned_for_order = $_REQUEST['total_returned_quantity'];
  884. $total_returned_value_for_order = $_REQUEST['total_returned_value'];
  885. $ordered_quantity = $_REQUEST['quantity'];
  886. $order_line_item_matched = 0;
  887. $line_status= self::RECEIVING;
  888. if ($ordered_quantity == $total_received_for_order + $total_returned_for_order){
  889. $line_status= self::RECEIVED;
  890. $order_line_item_matched = 1;
  891. }
  892. $this->db->trans_start();
  893. //if new receipt number for this particular suppler create obe entry in recepipt table
  894. if (empty($receiptOp) && !empty($receiptIp)){
  895. $receiptData = array ('supplier_receipt_number'=>trim($receiptIp),'supplier_id'=>$supplierId
  896. ,'order_id'=>$order_id,'status'=>self::RECEIVING,'owner_id'=>$this->user->person_id);
  897. $this->Receipt_master->insert($receiptData);
  898. log_message('debug','insert statement ='.$this->db->last_query());
  899. $id = $this->db->insert_id();
  900. $where_clause = array('id'=>$id);
  901. $this->Receipt_master->update($where_clause, array('reference' => 10000000 + $id));
  902. log_message('debug','update statement ='.$this->db->last_query());
  903. $receiptOp = $id;
  904. }
  905. $receipt_item_data['receipt_id'] = $receiptOp;
  906. //receipt line items are unique by order line id and receiot id.
  907. //a single order line can have multiple recepit
  908. // a single supplier receipt can also have multiple order line and multiple order
  909. // but system receipt can only have single order and lultiple order line
  910. $itemDetails = $this->Receipt_item->getByOrderLineAndReceipt($order_line_id,$receiptOp);
  911. //adding up with already received
  912. if (!empty($itemDetails) ){
  913. if ($action == 'add'){
  914. // for received goods
  915. $savedValue = $itemDetails['received_value']; //this is the receipt line items total value
  916. $savedQuantity= $itemDetails['received_quantity'];
  917. //update new total
  918. $received_value += $savedValue;
  919. $received_quantity += $savedQuantity;
  920. //for returned goods
  921. $savedReturnedValue = $itemDetails['returned_value']; //this is the receipt line items total value
  922. $savedReturnedQuantity= $itemDetails['returned_quantity'];
  923. //update new total
  924. $returned_value += $savedReturnedValue;
  925. $returned_quantity += $savedReturnedQuantity;
  926. }
  927. }
  928. $receipt_item_data['received_value'] = $received_value;
  929. $receipt_item_data['received_quantity'] = $received_quantity;
  930. $receipt_item_data['returned_value'] = $returned_value;
  931. $receipt_item_data['returned_quantity'] = $returned_quantity;
  932. $receipt_item_data['status'] = $line_status;
  933. $receipt_item_data['ordered_quantity'] = $ordered_quantity;
  934. //save receipt line item
  935. if (empty($itemDetails)){
  936. $this->Receipt_item->insert($receipt_item_data);
  937. log_message('debug','insert statement ='.$this->db->last_query());
  938. $id = $this->db->insert_id();
  939. /* end insert */
  940. /* update reference number in quote item */
  941. $where_clause = array('id'=>$id);
  942. $this->Receipt_item->update($where_clause, array('reference' => 10000000 + $id));
  943. }
  944. else {
  945. $this->Receipt_item->updateWithNotes(array('id'=>$itemDetails['id']),array('received_quantity'=>$received_quantity,'received_value'=>$received_value,'returned_quantity'=>$returned_quantity,
  946. 'returned_value'=>$returned_value,'status'=>$line_status),$notes_array);
  947. // $this->Receipt_item->updateWithoutEscape(array('id'=>$itemDetails['id']),'receiving_notes',$rcvd_note);
  948. // $this->Receipt_item->updateWithoutEscape(array('id'=>$itemDetails['id']),'returned_notes',$rtrnd_note);
  949. }
  950. //if completed then update all the receipt line items with same order line id to "RECEIVED"
  951. // as the parent order line id status is soon going to be set as "RECEIVED"
  952. if ($line_status==self::RECEIVED){
  953. $this->Receipt_item->update(array('order_line_id'=>$order_line_id),array('status'=>$line_status));
  954. }
  955. // update PO line with total value. Note This could be different from the received quantity
  956. // as there could be multiple receipt line for a single order line
  957. $this->Purchase_order_item->update(array('id'=>$order_line_id),array('received_quantity'=>$total_received_for_order,'received_value'=>$total_received_value_for_order,
  958. 'returned_quantity'=>$total_returned_for_order,'returned_value'=>$total_returned_value_for_order,'status'=>$line_status,'matched'=>$order_line_item_matched));
  959. //update Purchase Order So That It Can be Ready For Invoicing
  960. $this->Purchase_order_master->update(array('id'=>$order_id),array('status'=>self::RECEIVING));
  961. $this->db->trans_complete();
  962. }
  963. // function receiveItems(){}
  964. function populateReceiptOptions (){
  965. $order_id= $_REQUEST['order_id'];
  966. $receipts = $this->Receipt_master->getAll(false,array('order_id'=>$order_id),array('id','supplier_receipt_number'));
  967. foreach($receipts as $receipt) {
  968. $id=$receipt["id"];
  969. $details=$receipt["supplier_receipt_number"];
  970. //$value = $denom["denom_json"];
  971. if (!empty($id)){
  972. $receiptOptions.="<OPTION VALUE=\"$id\">".$details;
  973. }
  974. }
  975. echo $receiptOptions;
  976. }
  977. function createInvoiceUpdateOrderReceipt (){
  978. $receiptIds = $_REQUEST['receipt_ids'];
  979. $order_id = $_REQUEST['order_id'];
  980. $total_invoice_value = 0;
  981. $this->db->trans_start();
  982. $invoice_data=array('status'=>self::PENDING,'order_id'=>$order_id,
  983. 'invoiced_by'=>$this->user->person_id,'owner_id'=>$this->user->person_id);
  984. $newInvId = $this->createInvoice($invoice_data);
  985. $order_line_array = array();
  986. foreach ($receiptIds as $receiptId){
  987. // create Invoice items
  988. $receipt_items = $this->Receipt_item->getAll(false,array('receipt_id'=>$receiptId,'status'=>self::RECEIVED),
  989. array('sku','name','product_id','price','order_line_id','received_value','received_quantity'));
  990. foreach ($receipt_items as $receipt_item){
  991. $item_data['sku'] = $receipt_item['sku'];
  992. $item_data['name'] = $receipt_item['name'];
  993. $item_data['product_id'] = $receipt_item['product_id'];
  994. $item_data['price'] = $receipt_item['price'];
  995. $item_data['order_line_id'] = $receipt_item['order_line_id'];
  996. $item_data['total_invoiced_value'] = $receipt_item['received_value'];
  997. $item_data['invoiced_quantity'] = $receipt_item['received_quantity'];
  998. $item_data['invoice_id'] = $newInvId;
  999. $this->Purchase_invoice_item->insert($item_data);
  1000. log_message('debug','insert statement ='.$this->db->last_query());
  1001. $id = $this->db->insert_id();
  1002. /* end insert */
  1003. /* update reference number in quote item */
  1004. $where_clause = array('id'=>$id);
  1005. $this->Purchase_invoice_item->update($where_clause, array('reference' => 10000000 + $id));
  1006. // now prepare array to update order line items
  1007. if (array_key_exists($receipt_item['order_line_id'], $order_line_array)){
  1008. // already exists .. that means in separate invoice item some of the quantity
  1009. //already invoiced.. get the old value add with the this invoice line items
  1010. // invoiced_quantity. push iit back to array
  1011. $oldvalue = $order_line_array[$item_data['order_line_id']];
  1012. $order_line_array[$item_data['order_line_id']] = $oldvalue + $item_data['invoiced_quantity'];
  1013. }
  1014. else {
  1015. // first invoice item for this order line item
  1016. $order_line_array[$item_data['order_line_id']] = $item_data['invoiced_quantity'];
  1017. }
  1018. }
  1019. //grab order line array .. update order line items
  1020. foreach ($order_line_array as $key => $value){
  1021. $this->Purchase_order_item->update(array('id'=>$key),array('invoiced_quantity'=>$value));
  1022. }
  1023. //calcultae total invoice value by receipt id
  1024. $total_invoice_value +=$this->Receipt_item->totalAmount($receiptId);
  1025. // as of now this is all or none.
  1026. //later add invoiced quantity
  1027. $this->Receipt_master->update(array('id'=>$receiptId,'status'=>self::RECEIVED),array('invoice_id'=>$newInvId,'status'=>self::INVOICED));
  1028. $this->Receipt_item->update(array('receipt_id'=>$receiptId,'status'=>self::RECEIVED),array('status'=>self::INVOICED));
  1029. }
  1030. $this->Purchase_invoice_master->update(array('id'=>$newInvId),array('total_value'=>$total_invoice_value));
  1031. //validate by order if invoicing complete
  1032. //first find order lines are received. If all order lines are received then there are entries in
  1033. //receipt line item table with all order line items. Next Se if all receipt Items with receipt ids
  1034. //with the order id are invoiced. If Invoiced then mark all order lines and the order as invoiced
  1035. //(Revisit This Later)
  1036. // $noOfRows = $this->Receipt_master()->totalNoOfRows(array('order_id'=>$order_id,'status'=>self::RECEIVED));
  1037. $this->db->trans_complete();
  1038. echo $newInvId;
  1039. }
  1040. function createInvoice($invoiceData){
  1041. $this->Purchase_invoice_master->insert($invoiceData);
  1042. log_message('debug','insert statement ='.$this->db->last_query());
  1043. $id = $this->db->insert_id();
  1044. $where_clause = array('id'=>$id);
  1045. $this->Purchase_invoice_master->update($where_clause, array('reference' => 10000000 + $id));
  1046. log_message('debug','update statement ='.$this->db->last_query());
  1047. return $id;
  1048. }
  1049. function registerPayment(){
  1050. $total = $_REQUEST['total_value'] ;
  1051. $data['amount'] = $_REQUEST['amount'] ;
  1052. $data['invoice_id'] = $_REQUEST['invoice_id'] ;
  1053. $data['comments'] = $_REQUEST['comments'] ;
  1054. $oper = $_REQUEST['oper'] ;
  1055. $payment_id = $_REQUEST['payment_id'] ;
  1056. $data['payment_reference'] = $_REQUEST['payment_ref'] ;
  1057. $data['payment_type'] = $_REQUEST['payment_type'] ;
  1058. $total_invoiced = $_REQUEST['total_invoiced'];
  1059. $this->db->trans_start();
  1060. if ($oper == 'add'){
  1061. $this->Outgoing_payment->insert($data);
  1062. }
  1063. else if (oper == 'edit'){
  1064. $this->Outgoing_payment->update(array('id',$payment_id),$data);
  1065. }
  1066. if ($total_invoiced == $total){
  1067. $this->Purchase_invoice_master->update(array('id'=>$_REQUEST['invoice_id'] ),array('amount_paid'=>$total,'status'=>self::COMPLETE));
  1068. }
  1069. else {
  1070. $this->Purchase_invoice_master->update(array('id'=>$_REQUEST['invoice_id'] ),array('amount_paid'=>$total,'status'=>self::PARTIAL));
  1071. }
  1072. $this->db->trans_complete();
  1073. if ($this->db->trans_status()=== TRUE){
  1074. echo $total;
  1075. }
  1076. }
  1077. function printInvoice(){
  1078. define('FPDF_FONTPATH',$this->config->item('fonts_path'));
  1079. //$this->load->library('fpdf','','fpdf');
  1080. //$this->load->library('table_pdf','','pdf');
  1081. // $this->load->library('rotation');
  1082. // $this->load->library('pdf','','pdf');
  1083. // $this->pdf->AddPage();
  1084. // $this->pdf->SetFont('Arial','B',16);
  1085. // $this->pdf->Cell(40,10,'Hello World!');
  1086. $header = array('Type', 'Payment Ref', 'Amount');
  1087. $data = $this->Outgoing_payment->getColumnValues(false,null,array('payment_type','payment_reference','amount'));
  1088. $this->pdf->SetFont('Arial','',14);
  1089. // $this->pdf->AddPage();
  1090. // $this->pdf->BasicTable($header,$data);
  1091. // $this->pdf->AddPage();
  1092. // $this->pdf->ImprovedTable($header,$data);
  1093. $this->pdf->AddPage();
  1094. $this->pdf->FancyTable($header,$data);
  1095. //$this->pdf->Output('/tmp/test'.time().'.pdf', 'F');
  1096. $this->pdf->Output('/tmp/test.pdf', 'F');
  1097. }
  1098. function generatePdfPurchaseInvoice(){
  1099. define('FPDF_FONTPATH',$this->config->item('fonts_path'));
  1100. $this->load->library('pdf_invoice','','pdf');
  1101. $this->pdf->AddPage();
  1102. $invoice_details = $this->Purchase_invoice_master->getById($_REQUEST['invoice_id']);
  1103. $order_details = $this->Purchase_order_master->getGridById($invoice_details->order_id,false);
  1104. $supplier_details = $this->Supplier->getById($order_details->supplier_id);
  1105. $payments = $this->Outgoing_payment->getColumnValues(false,array('invoice_id'=>$invoice_details->id),array('payment_type','payment_reference','amount','comments'));
  1106. $receiptIds = $this->Receipt_master->getColumnValues(false,array('invoice_id'=>$invoice_details->id),array('id'));
  1107. $receiptItems = $this->Receipt_item->getColumnValues(false,array('invoice_id'=>$invoice_details->id),array('id'));
  1108. $payment_height = 20 + count($payments)*2;
  1109. //$supplier_details;
  1110. $this->pdf->addSociete("Shopifine Retail LLP",
  1111. "#440 5th Cross 8th Cross\n" .
  1112. "Bangalore 560094\n" .
  1113. "Karnataka\n"
  1114. );
  1115. $this->pdf->fact_dev( "Shopifine ", "Invoice" );
  1116. $this->pdf->temporaire( "Shopifine" );
  1117. //$this->pdf->addDate( $invoice_details['created_at']);
  1118. $this->pdf->addClient($supplier_details['supplier_name']);
  1119. $this->pdf->addPageNumber("1");
  1120. $this->pdf->addClientAdresse($supplier_details['address']." ".$supplier_details['city']
  1121. ." ".$supplier_details['state']);
  1122. // $this->pdf->addReglement("Chèque à réception de facture");
  1123. // $this->pdf->addEcheance("03/12/2003");
  1124. $this->pdf->addNumTVA($supplier_details['registration_number']);
  1125. $contact = $supplier_details['contact_person'];
  1126. //$this->pdf->addReference("$contact");
  1127. $cols=array( "PAYMENT TYPE " => 35,
  1128. "PAYMENT REFERENCE" => 50,
  1129. "AMOUNT" => 30,
  1130. "COMMENTS" => 70
  1131. );
  1132. $this->pdf->addCols( $cols,$payment_height);
  1133. $cols=array( "PAYMENT TYPE " => "C",
  1134. "PAYMENT REFERENCE" => "C",
  1135. "AMOUNT" => "R",
  1136. "COMMENTS" => "L"
  1137. );
  1138. $this->pdf->addLineFormat( $cols);
  1139. $this->pdf->addLineFormat($cols);
  1140. ////
  1141. $y = 109;
  1142. foreach ($payments as $payment){
  1143. $line = $cols=array( "PAYMENT TYPE " => $payment['payment_type'],
  1144. "PAYMENT REFERENCE" => $payment['payment_reference'],
  1145. "AMOUNT" => $payment['amount'],
  1146. "COMMENTS" => $payment['comments']
  1147. );
  1148. $size = $this->pdf->addLine( $y, $line );
  1149. $y += $size + 2;
  1150. }
  1151. //
  1152. //
  1153. $this->pdf->addCadreTVAs();
  1154. //
  1155. // invoice = array( "px_unit" => value,
  1156. // "qte" => qte,
  1157. // "tva" => code_tva );
  1158. // tab_tva = array( "1" => 19.6,
  1159. // "2" => 5.5, ... );
  1160. // params = array( "RemiseGlobale" => [0|1],
  1161. // "remise_tva" => [1|2...], // {la remise s'applique sur ce code TVA}
  1162. // "remise" => value, // {montant de la remise}
  1163. // "remise_percent" => percent, // {pourcentage de remise sur ce montant de TVA}
  1164. // "FraisPort" => [0|1],
  1165. // "portTTC" => value, // montant des frais de ports TTC
  1166. // // par defaut la TVA = 19.6 %
  1167. // "portHT" => value, // montant des frais de ports HT
  1168. // "portTVA" => tva_value, // valeur de la TVA a appliquer sur le montant HT
  1169. // "AccompteExige" => [0|1],
  1170. // "accompte" => value // montant de l'acompte (TTC)
  1171. // "accompte_percent" => percent // pourcentage d'acompte (TTC)
  1172. // "Remarque" => "texte" // texte
  1173. $tot_prods = array( array ( "px_unit" => 600, "qte" => 1, "tva" => 1 ),
  1174. array ( "px_unit" => 10, "qte" => 1, "tva" => 1 ));
  1175. $tab_tva = array( "1" => 19.6,
  1176. "2" => 5.5);
  1177. $params = array( "RemiseGlobale" => 1,
  1178. "remise_tva" => 1, // {la remise s'applique sur ce code TVA}
  1179. "remise" => 0, // {montant de la remise}
  1180. "remise_percent" => 10, // {pourcentage de remise sur ce montant de TVA}
  1181. "FraisPort" => 1,
  1182. "portTTC" => 10, // montant des frais de ports TTC
  1183. // par defaut la TVA = 19.6 %
  1184. "portHT" => 0, // montant des frais de ports HT
  1185. "portTVA" => 19.6, // valeur de la TVA a appliquer sur le montant HT
  1186. "AccompteExige" => 1,
  1187. "accompte" => 0, // montant de l'acompte (TTC)
  1188. "accompte_percent" => 15, // pourcentage d'acompte (TTC)
  1189. "Remarque" => "Avec un acompte, svp..." );
  1190. $this->pdf->addTVAs( $params, $tab_tva, $tot_prods);
  1191. //$this->pdf->addCadreEurosFrancs();
  1192. $this->pdf->Output();
  1193. //$this->pdf->Output('/tmp/test.pdf', 'F');
  1194. }
  1195. /* Invoice Grid Start */
  1196. function populateInvoicesToPay(){
  1197. $person_id = $this->user->person_id;
  1198. $in_where=array('field_name'=>'status','id_array'=>array(self::RECEIVED)) ;
  1199. $page = $_REQUEST['page'];
  1200. $limit = $_REQUEST['rows'];
  1201. $sidx = $_REQUEST['sidx'];
  1202. $sord = $_REQUEST['sord'];
  1203. $searchOn = $_REQUEST['_search'];
  1204. if (!empty($person_id)){
  1205. $where['owner_id'] = $person_id;
  1206. }
  1207. //standard response parameters
  1208. $quotedata = array();
  1209. $count = $this->Purchase_invoice_master->totalNoOfRows($where);
  1210. if( $count > 0 && $limit > 0) {
  1211. $total_pages = ceil($count/$limit);
  1212. } else {
  1213. $total_pages = 0;
  1214. }
  1215. if ($page > $total_pages) $page=$total_pages;
  1216. $start = $limit*$page - $limit;
  1217. // if for some reasons start position is negative set it to 0
  1218. // typical case is that the user type 0 for the requested page
  1219. if($start <0) $start = 0;
  1220. $clauses = array('orderBy'=>$sidx,'orderDir'=>$sord,'startLimit'=>$start,'limit'=>$limit);
  1221. $data['total'] = $total_pages;
  1222. $data['page'] = $page;
  1223. $data['records'] = $count;
  1224. if($searchOn=='true') {
  1225. $filters = json_decode($_REQUEST['filters'],true);
  1226. $groupOp = $filters['groupOp'];
  1227. $rules = $filters['rules'];
  1228. $like_condition = array();
  1229. foreach ($rules as $rule){
  1230. $field = $rule['field'];
  1231. $op= $rule['op'];
  1232. $input = $rule['data'];
  1233. $like_condition[$field] = trim($input);
  1234. }
  1235. $quotes = $this->Purchase_invoice_master->getAll(false,$where,$clauses,$like_condition);
  1236. }
  1237. else {
  1238. $quotes = $this->Purchase_invoice_master->getAll(false,$where);
  1239. }
  1240. foreach ($quotes as $dp){
  1241. $orderDetails = $this->Purchase_order_master->getGridById($dp['order_id']);
  1242. $userDetails = $this->User->getUserInfo($dp['invoiced_by'],true);
  1243. array_push($quotedata, array('id'=> $dp['id'],'dprow' => array($dp['reference'],$dp['total_value'],$dp['amount_paid'],$dp['status'],$userDetails['username'],$dp['order_id'],$orderDetails['reference'])));
  1244. }
  1245. $data['quotedata'] = $quotedata;
  1246. echo json_encode($data);
  1247. }
  1248. function populateInvoiceItems(){
  1249. $invoiceId = $_REQUEST['invoiceId'];
  1250. if (!empty($invoiceId)){
  1251. $page = $_REQUEST['page'];
  1252. $limit = $_REQUEST['rows'];
  1253. $sidx = $_REQUEST['sidx'];
  1254. $sord = $_REQUEST['sord'];
  1255. //standard response parameters
  1256. $quotedata = array();
  1257. $where = array('invoice_id' => $invoiceId );
  1258. $count = $this->Purchase_invoice_item->totalNoOfRows($where);
  1259. if( $count > 0 && $limit > 0) {
  1260. $total_pages = ceil($count/$limit);
  1261. } else {
  1262. $total_pages = 0;
  1263. }
  1264. if ($page > $total_pages) $page=$total_pages;
  1265. $start = $limit*$page - $limit;
  1266. // if for some reasons start position is negative set it to 0
  1267. // typical case is that the user type 0 for the requested page
  1268. if($start <0) $start = 0;
  1269. $clauses = array('orderBy'=>$sidx,'orderDir'=>$sord,'startLimit'=>$start,'limit'=>$limit);
  1270. $data['total'] = $total_pages;
  1271. $data['page'] = $page;
  1272. $data['records'] = $count;
  1273. $quotes = $this->Purchase_invoice_item->getAll(false,$where);
  1274. foreach ($quotes as $dp){
  1275. //$order_line = $this->Purchase_order_item->getById($dp['order_line_id']);
  1276. array_push($quotedata, array('id'=> $dp['id'],'dprow' => array($dp['product_id'],$dp['name'],$dp['invoiced_quantity'],$dp['total_invoiced_value'])));
  1277. }
  1278. $data['invoiceitemdata'] = $quotedata;
  1279. echo json_encode($data);
  1280. }
  1281. }
  1282. }
  1283. ?>