File: //proc/self/cwd/pm/plugins/Manufacturing/Models/Manufacturing_model.php
<?php
namespace Manufacturing\Models;
use App\Models\Crud_model;
class Manufacturing_model extends Crud_model {
function __construct() {
parent::__construct();
}
/*general functions start*/
/**
* prefixed table fields wildcard
* @param [type] $table
* @param [type] $alias
* @param [type] $field
* @return [type]
*/
public function prefixed_table_fields_wildcard($table, $alias, $field)
{
$columns = $this->db->query("SHOW COLUMNS FROM $table")->getResultArray();
$field_names = [];
foreach ($columns as $column) {
$field_names[] = $column['Field'];
}
$prefixed = [];
foreach ($field_names as $field_name) {
if ($field == $field_name) {
$prefixed[] = "`{$alias}`.`{$field_name}` AS `{$alias}.{$field_name}`";
}
}
return implode(', ', $prefixed);
}
/**
* hr profile run query
* @param [type] $query_string
* @return [type]
*/
public function manufacturing_run_query($query_string)
{
return $this->db->query("$query_string")->getResultArray();
}
/**
* count items
* @return [type]
*/
public function count_all_items($where = '')
{
$items = $this->db->table(get_db_prefix().'items');
$items->where('deleted', 0);
if(strlen($where) > 0){
$items->groupStart();
$items->where($where);
$items->groupEnd();
}
$list_item = $items->get()->getResultArray();
return count($list_item);
}
/**
* Function that will parse table data from the tables folder for amin area
* @param string $table table filename
* @param array $params additional params
* @return void
*/
public function get_table_data($table, $dataPost, $params = [])
{
$params = app_hooks()->apply_filters('table_params', $params, $table);
foreach ($params as $key => $val) {
$key = $val;
}
$customFieldsColumns = [];
$path = MANUFACTURING_VIEWPATH . 'admin/tables/' . $table . EXT;
if (!file_exists($path)) {
$path = $table;
if (!endsWith($path, EXT)) {
$path .= EXT;
}
} else {
$myPrefixedPath = MANUFACTURING_VIEWPATH . 'admin/tables/my_' . $table . EXT;
if (file_exists($myPrefixedPath)) {
$path = $myPrefixedPath;
}
}
include_once($path);
echo json_encode($output);
die;
}
/**
* plugin get access info
* @param integer $user_id
* @return [type]
*/
function plugin_get_access_info($user_id = 0) {
$users_table = $this->db->prefixTable('users');
$roles_table = $this->db->prefixTable('roles');
$team_table = $this->db->prefixTable('team');
if (!$user_id) {
$user_id = 0;
}
$sql = "SELECT $users_table.id, $users_table.user_type, $users_table.is_admin, $users_table.role_id, $users_table.email,
$users_table.first_name, $users_table.last_name, $users_table.image, $users_table.message_checked_at, $users_table.notification_checked_at, $users_table.client_id, $users_table.enable_web_notification,
$users_table.is_primary_contact, $users_table.sticky_note,
$roles_table.title as role_title, $roles_table.plugins_permissions1 as permissions,
(SELECT GROUP_CONCAT(id) team_ids FROM $team_table WHERE FIND_IN_SET('$user_id', `members`)) as team_ids
FROM $users_table
LEFT JOIN $roles_table ON $roles_table.id = $users_table.role_id AND $roles_table.deleted = 0
WHERE $users_table.deleted=0 AND $users_table.id=$user_id";
return $this->db->query($sql)->getRow();
}
/**
* add attachment to database
* @param [type] $rel_id
* @param [type] $rel_type
* @param [type] $attachment
* @param boolean $external
*/
public function add_attachment_to_database($rel_id, $rel_type, $attachment, $external = false)
{
$data['dateadded'] = get_current_utc_time();
$data['rel_id'] = $rel_id;
if (!isset($attachment[0]['staffid'])) {
$data['staffid'] = get_staff_user_id1();
} else {
$data['staffid'] = $attachment[0]['staffid'];
}
if (isset($attachment[0]['task_comment_id'])) {
$data['task_comment_id'] = $attachment[0]['task_comment_id'];
}
$data['rel_type'] = $rel_type;
if (isset($attachment[0]['contact_id'])) {
$data['contact_id'] = $attachment[0]['contact_id'];
$data['visible_to_customer'] = 1;
if (isset($data['staffid'])) {
unset($data['staffid']);
}
}
$data['attachment_key'] = app_generate_hash();
if ($external == false) {
$data['file_name'] = $attachment[0]['file_name'];
$data['filetype'] = $attachment[0]['filetype'];
} else {
$path_parts = pathinfo($attachment[0]['name']);
$data['file_name'] = $attachment[0]['name'];
$data['external_link'] = $attachment[0]['link'];
$data['filetype'] = !isset($attachment[0]['mime']) ? get_mime_by_extension('.' . $path_parts['extension']) : $attachment[0]['mime'];
$data['external'] = $external;
if (isset($attachment[0]['thumbnailLink'])) {
$data['thumbnail_link'] = $attachment[0]['thumbnailLink'];
}
}
$builder = $this->db->table(db_prefix().'files');
$builder->insert($data);
$insert_id = $this->db->insertID();
return $insert_id;
}
/*general functions end*/
/**
* get routings
* @param boolean $id
* @return [type]
*/
public function get_routings($id = false)
{
if (is_numeric($id)) {
$builder = $this->db->table(get_db_prefix().'mrp_routings');
$builder->where('id', $id);
return $builder->get()->getRow();
}
if ($id == false) {
return $this->db->query('select * from ' . get_db_prefix() . 'mrp_routings')->getResultArray();
}
}
/**
* get work centers
* @param boolean $id
* @return [type]
*/
public function get_work_centers($id = false)
{
if (is_numeric($id)) {
$builder = $this->db->table(get_db_prefix().'mrp_work_centers');
$builder->where('id', $id);
return $builder->get()->getRow();
}
if ($id == false) {
return $this->db->query('select * from ' . get_db_prefix() . 'mrp_work_centers')->getResultArray();
}
}
/**
* add work center
* @param [type] $data
*/
public function add_work_center($data)
{
$builder = $this->db->table(get_db_prefix().'mrp_work_centers');
$builder->insert($data);
$insert_id = $this->db->insertID();
if ($insert_id) {
return $insert_id;
}
return false;
}
/**
* update work center
* @param [type] $data
* @param [type] $id
* @return [type]
*/
public function update_work_center($data, $id)
{
$affected_rows=0;
$builder = $this->db->table(get_db_prefix().'mrp_work_centers');
$builder->where('id', $id);
$affected_rows = $builder->update($data);
if ($affected_rows > 0) {
$affected_rows++;
}
if($affected_rows > 0){
return true;
}
return false;
}
/**
* delete work center
* @param [type] $id
* @return [type]
*/
public function delete_work_center($id)
{
$builder = $this->db->table(get_db_prefix().'mrp_work_centers');
$builder->where('id', $id);
$affected_rows = $builder->delete();
if ($affected_rows > 0) {
return true;
}
return false;
}
/**
* get working hour
* @param [type] $id
* @return [type]
*/
public function get_working_hour($id = fasle)
{
if (is_numeric($id)) {
$builder = $this->db->table(get_db_prefix().'mrp_working_hours');
$builder->where('id', $id);
$working_hour = $builder->get()->getRow();
//get working detail
$builder = $this->db->table(get_db_prefix().'mrp_working_hour_times');
$builder->select('id, working_hour_id, working_hour_name, day_of_week, day_period, date_format(work_from, "%H:%i") as work_from , date_format(work_to, "%H:%i") as work_to, starting_date, end_date');
$builder->where('working_hour_id', $id);
$working_hour_details = $builder->get()->getResultArray();
//get time off
$builder = $this->db->table(get_db_prefix().'mrp_working_hour_time_off');
$builder->where('working_hour_id', $id);
$time_off = $builder->get()->getResultArray();
$result=[];
$result['working_hour'] = $working_hour;
$result['working_hour_details'] = $working_hour_details;
$result['time_off'] = $time_off;
return $result;
}
if ($id == false) {
return $this->db->query('select * from ' . get_db_prefix() . 'mrp_working_hours')->getResultArray();
}
}
/**
* get working hours
* @return [type]
*/
public function get_working_hours()
{
return $this->db->query('select * from ' . get_db_prefix() . 'mrp_working_hours')->getResultArray();
}
/**
* delete working hour
* @param [type] $id
* @return [type]
*/
public function delete_working_hour($id)
{
$affected_rows=0;
$builder = $this->db->table(get_db_prefix().'mrp_working_hour_time_off');
$builder->where('working_hour_id', $id);
$affected_rows = $builder->delete();
if ($affected_rows > 0) {
$affected_rows++;
}
$builder = $this->db->table(get_db_prefix().'mrp_working_hour_times');
$builder->where('working_hour_id', $id);
$affected_rows = $builder->delete();
if ($affected_rows > 0) {
$affected_rows++;
}
$builder = $this->db->table(get_db_prefix().'mrp_working_hours');
$builder->where('id', $id);
$affected_rows = $builder->delete();
if ($affected_rows > 0) {
$affected_rows++;
}
if($affected_rows > 0){
return true;
}
return false;
}
/**
* add working hour
* @param [type] $data
*/
public function add_working_hour($data)
{
$affected_rows=0;
if (isset($data['working_hour_hs'])) {
$working_hour_hs = $data['working_hour_hs'];
unset($data['working_hour_hs']);
}
if (isset($data['global_time_off_hs'])) {
$global_time_off_hs = $data['global_time_off_hs'];
unset($data['global_time_off_hs']);
}
$builder = $this->db->table(get_db_prefix().'mrp_working_hours');
$builder->insert( $data);
$insert_id = $this->db->insertID();
//create working hours data
if(isset($working_hour_hs)){
$working_hour_detail = json_decode($working_hour_hs);
$es_detail = [];
$row = [];
$header = [];
$header[] = 'id';
$header[] = 'working_hour_id';
$header[] = 'working_hour_name';
$header[] = 'day_of_week';
$header[] = 'day_period';
$header[] = 'work_from';
$header[] = 'work_to';
$header[] = 'starting_date';
$header[] = 'end_date';
foreach ($working_hour_detail as $key => $value) {
if($value[2] != ''){
$es_detail[] = array_combine($header, $value);
}
}
}
//create global time off
if(isset($global_time_off_hs)){
$global_time_off_detail = json_decode($global_time_off_hs);
$time_off_detail = [];
$row = [];
$header = [];
$header[] = 'id';
$header[] = 'working_hour_id';
$header[] = 'reason';
$header[] = 'starting_date';
$header[] = 'end_date';
foreach ($global_time_off_detail as $key => $value) {
if($value[2] != ''){
$time_off_detail[] = array_combine($header, $value);
}
}
}
if (isset($insert_id)) {
$affected_rows++;
/*insert working_hour_id*/
foreach($es_detail as $key => $rqd){
$es_detail[$key]['working_hour_id'] = $insert_id;
}
foreach($time_off_detail as $key => $time_off){
$time_off_detail[$key]['working_hour_id'] = $insert_id;
}
if(count($es_detail) > 0){
$builder = $this->db->table(get_db_prefix().'mrp_working_hour_times');
$insert_working_hour = $builder->insertBatch($es_detail);
if($insert_working_hour > 0){
$affected_rows++;
}
}
if(count($time_off_detail) > 0){
$builder = $this->db->table(get_db_prefix().'mrp_working_hour_time_off');
$insert_time_off = $builder->insertBatch($time_off_detail);
if($insert_time_off > 0){
$affected_rows++;
}
}
}
if ($affected_rows > 0) {
return $insert_id;
}
return false;
}
/**
* update working hour
* @param [type] $data
* @param [type] $id
* @return [type]
*/
public function update_working_hour($data, $id)
{
$affected_rows=0;
if (isset($data['working_hour_hs'])) {
$working_hour_hs = $data['working_hour_hs'];
unset($data['working_hour_hs']);
}
if (isset($data['global_time_off_hs'])) {
$global_time_off_hs = $data['global_time_off_hs'];
unset($data['global_time_off_hs']);
}
$builder = $this->db->table(get_db_prefix().'mrp_working_hours');
$builder->where('id', $id);
$affected_row = $builder->update($data);
if ($affected_row > 0) {
$affected_rows++;
}
//create working hours data
if(isset($working_hour_hs)){
$working_hour_detail = json_decode($working_hour_hs);
$es_detail = [];
$row = [];
$header = [];
$header[] = 'id';
$header[] = 'working_hour_id';
$header[] = 'working_hour_name';
$header[] = 'day_of_week';
$header[] = 'day_period';
$header[] = 'work_from';
$header[] = 'work_to';
$header[] = 'starting_date';
$header[] = 'end_date';
foreach ($working_hour_detail as $key => $value) {
if($value[2] != ''){
$es_detail[] = array_combine($header, $value);
}
}
}
//create global time off
if(isset($global_time_off_hs)){
$global_time_off_detail = json_decode($global_time_off_hs);
$time_off_detail = [];
$row = [];
$header = [];
$header[] = 'id';
$header[] = 'working_hour_id';
$header[] = 'reason';
$header[] = 'starting_date';
$header[] = 'end_date';
foreach ($global_time_off_detail as $key => $value) {
if($value[2] != ''){
$time_off_detail[] = array_combine($header, $value);
}
}
}
//handle working hours
$row_working_hour_detail = [];
$row_working_hour_detail['update'] = [];
$row_working_hour_detail['insert'] = [];
$row_working_hour_detail['delete'] = [];
$total = [];
foreach ($es_detail as $key => $value) {
if($value['id'] != ''){
$row_working_hour_detail['delete'][] = $value['id'];
$row_working_hour_detail['update'][] = $value;
}else{
unset($value['id']);
$value['working_hour_id'] = $id;
$row_working_hour_detail['insert'][] = $value;
}
}
if(empty($row_working_hour_detail['delete'])){
$row_working_hour_detail['delete'] = ['0'];
}
$row_working_hour_detail['delete'] = implode(",",$row_working_hour_detail['delete']);
$builder = $this->db->table(get_db_prefix().'mrp_working_hour_times');
$builder->where('id NOT IN ('.$row_working_hour_detail['delete'] .') and working_hour_id ='.$id);
$affected_row = $builder->delete();
if($affected_row > 0){
$affected_rows++;
}
if(count($row_working_hour_detail['insert']) != 0){
$builder = $this->db->table(get_db_prefix().'mrp_working_hour_times');
$affected_row = $builder->insertBatch($row_working_hour_detail['insert']);
if($affected_row > 0){
$affected_rows++;
}
}
if(count($row_working_hour_detail['update']) != 0){
$builder = $this->db->table(get_db_prefix().'mrp_working_hour_times');
$affected_row = $builder->updateBatch($row_working_hour_detail['update'], 'id');
if($affected_row > 0){
$affected_rows++;
}
}
//handle time off
$row_time_off_detail = [];
$row_time_off_detail['update'] = [];
$row_time_off_detail['insert'] = [];
$row_time_off_detail['delete'] = [];
$total = [];
foreach ($time_off_detail as $key => $value) {
if($value['id'] != ''){
$row_time_off_detail['delete'][] = $value['id'];
$row_time_off_detail['update'][] = $value;
}else{
unset($value['id']);
$value['working_hour_id'] = $id;
$row_time_off_detail['insert'][] = $value;
}
}
if(empty($row_time_off_detail['delete'])){
$row_time_off_detail['delete'] = ['0'];
}
$row_time_off_detail['delete'] = implode(",",$row_time_off_detail['delete']);
$builder = $this->db->table(get_db_prefix().'mrp_working_hour_time_off');
$builder->where('id NOT IN ('.$row_time_off_detail['delete'] .') and working_hour_id ='.$id);
$affected_row = $builder->delete();
if($affected_row > 0){
$affected_rows++;
}
if(count($row_time_off_detail['insert']) != 0){
$builder = $this->db->table(get_db_prefix().'mrp_working_hour_time_off');
$affected_row = $builder->insertBatch($row_time_off_detail['insert']);
if($affected_row > 0){
$affected_rows++;
}
}
if(count($row_time_off_detail['update']) != 0){
$builder = $this->db->table(get_db_prefix().'mrp_working_hour_time_off');
$affected_row = $builder->updateBatch($row_time_off_detail['update'], 'id');
if($affected_row > 0){
$affected_rows++;
}
}
if ($affected_rows > 0) {
return true;
}
return false;
}
/**
* create code
* @param [type] $rel_type
* @return [type]
*/
public function create_code($rel_type) {
//rel_type: position_code, staff_contract, ...
$str_result ='';
$prefix_str ='';
switch ($rel_type) {
case 'bom_code':
$prefix_str .= get_setting('bom_prefix');
$next_number = (int) get_setting('bom_number');
$str_result .= $prefix_str.str_pad($next_number,5,'0',STR_PAD_LEFT);
break;
case 'routing_code':
$prefix_str .= get_setting('routing_prefix');
$next_number = (int) get_setting('routing_number');
$str_result .= $prefix_str.str_pad($next_number,5,'0',STR_PAD_LEFT);
break;
case 'mo_code':
$prefix_str .= get_setting('mo_prefix');
$next_number = (int) get_setting('mo_number');
$str_result .= $prefix_str.str_pad($next_number,5,'0',STR_PAD_LEFT);
break;
default:
# code...
break;
}
return $str_result;
}
/**
* add routing
* @param [type] $data
*/
public function add_routing($data)
{
if(isset($data['files'])){
unset($data['files']);
}
$builder = $this->db->table(get_db_prefix().'mrp_routings');
$builder->insert($data);
$insert_id = $this->db->insertID();
if ($insert_id) {
/*update next number setting*/
$this->update_prefix_number(['routing_number' => get_setting('routing_number')+1]);
return $insert_id;
}
return false;
}
/**
* update routing
* @param [type] $data
* @param [type] $id
* @return [type]
*/
public function update_routing($data, $id)
{
if(isset($data['files'])){
unset($data['files']);
}
$builder = $this->db->table(get_db_prefix().'mrp_routings');
$builder->where('id', $id);
$affected_row = $builder->update($data);
if ($affected_row > 0) {
return true;
}
return false;
}
/**
* delete routing
* @param [type] $id
* @return [type]
*/
public function delete_routing($id)
{
$affected_rows = 0;
//get operations by routing id
$operations = $this->get_operation('', $id);
foreach ($operations as $value) {
$delete_result = $this->delete_operation($value['id']);
if($delete_result){
$affected_rows++;
}
}
//delete data
$builder = $this->db->table(get_db_prefix().'mrp_routings');
$builder->where('id', $id);
$affected_row = $builder->delete();
if ($affected_row > 0) {
$affected_rows++;
}
if($affected_rows > 0){
return true;
}
return false;
}
/**
* get routing detail
* @param boolean $id
* @return [type]
*/
public function get_operation($id=false, $routing_id = false)
{
if (is_numeric($id)) {
$builder = $this->db->table(get_db_prefix().'mrp_routing_details');
$builder->where('id', $id);
return $builder->get()->getRow();
}
if($routing_id != false){
$builder = $this->db->table(get_db_prefix().'mrp_routing_details');
$builder->where('routing_id', $routing_id);
$builder->orderBy('display_order', 'asc');
return $builder->get()->getResultArray();
}
if ($id == false) {
return $this->db->query('select * from ' . get_db_prefix() . 'mrp_routing_details')->getResultArray();
}
}
/**
* add operation
* @param [type] $data
*/
public function add_operation($data)
{
if($data['duration_computation'] == 'compute_based_on_real_time'){
$data['default_duration'] = 0;
}elseif($data['duration_computation'] == 'set_duration_manually'){
$data['based_on'] = 0;
}
if($data['start_next_operation'] == 'once_all_products_are_processed'){
$data['quantity_process'] = 0;
}
if(isset($data['file'])){
unset($data['file']);
}
$builder = $this->db->table(get_db_prefix().'mrp_routing_details');
$builder->insert($data);
$insert_id = $this->db->insertID();
if ($insert_id) {
return $insert_id;
}
return false;
}
/**
* update operation
* @param [type] $data
* @param [type] $id
* @return [type]
*/
public function update_operation($data, $id)
{
$affected_rows=0;
if($data['duration_computation'] == 'compute_based_on_real_time'){
$data['default_duration'] = 0;
}elseif($data['duration_computation'] == 'set_duration_manually'){
$data['based_on'] = 0;
}
if($data['start_next_operation'] == 'once_all_products_are_processed'){
$data['quantity_process'] = 0;
}
if(isset($data['file'])){
unset($data['file']);
}
$builder = $this->db->table(get_db_prefix().'mrp_routing_details');
$builder->where('id', $id);
$affected_row = $builder->update($data);
if ($affected_row > 0) {
$affected_rows++;
}
if($affected_rows > 0){
return true;
}
return false;
}
/**
* delete operation
* @param [type] $id
* @return [type]
*/
public function delete_operation($id)
{
//delete attachment file
$files = $this->mrp_get_attachments_file($id, 'mrp_operation');
foreach ($files as $file_key => $file_value) {
$this->delete_mrp_attachment_file($file_value['id'], MANUFACTURING_OPERATION_ATTACHMENTS_UPLOAD_FOLDER);
}
//delete data
$builder = $this->db->table(get_db_prefix().'mrp_routing_details');
$builder->where('id', $id);
$affected_row = $builder->delete();
if ($affected_row > 0) {
return true;
}
return false;
}
/**
* mrp get attachments file
* @param [type] $rel_id
* @param [type] $rel_type
* @return [type]
*/
public function mrp_get_attachments_file($rel_id, $rel_type)
{
//rel_id = id, rel_type = 'mrp_operation'
$builder = $this->db->table(get_db_prefix().'files');
$builder->orderBy('dateadded', 'desc');
$builder->where('rel_id', $rel_id);
$builder->where('rel_type', $rel_type);
return $builder->get()->getResultArray();
}
/**
* delete mrp attachment file
* @param [type] $attachment_id
* @param [type] $folder_name
* @return [type]
*/
public function delete_mrp_attachment_file($attachment_id, $folder_name)
{
$deleted = false;
$attachment = $this->get_file($attachment_id);
if ($attachment) {
if (empty($attachment->external)) {
unlink($folder_name .$attachment->rel_id.'/'.$attachment->file_name);
}
$builder = $this->db->table(get_db_prefix().'files');
$builder->where('id', $attachment->id);
$affected_row = $builder->delete();
if ($affected_row > 0) {
$deleted = true;
}
if (is_dir($folder_name .$attachment->rel_id)) {
// Check if no attachments left, so we can delete the folder also
$other_attachments = list_files($folder_name .$attachment->rel_id);
if (count($other_attachments) == 0) {
// okey only index.html so we can delete the folder also
delete_dir($folder_name .$attachment->rel_id);
}
}
}
return $deleted;
}
/**
* get unit categories
* @param boolean $id
* @return [type]
*/
public function get_unit_categories($id = false)
{
if (is_numeric($id)) {
$builder = $this->db->table(get_db_prefix().'mrp_unit_measure_categories');
$builder->where('id', $id);
return $builder->get()->getRow();
}
if ($id == false) {
return $this->db->query('select * from ' . get_db_prefix() . 'mrp_unit_measure_categories')->getResultArray();
}
}
/**
* add unit categories
* @param [type] $data
*/
public function add_unit_categories($data)
{
$builder = $this->db->table(get_db_prefix().'mrp_unit_measure_categories');
$builder->insert($data);
$insert_id = $this->db->insertID();
if ($insert_id) {
return $insert_id;
}
return false;
}
/**
* update unit categories
* @param [type] $data
* @param [type] $id
* @return [type]
*/
public function update_unit_categories($data, $id)
{
$affected_rows=0;
$builder = $this->db->table(get_db_prefix().'mrp_unit_measure_categories');
$builder->where('id', $id);
$affected_row = $builder->update($data);
if ($affected_row > 0) {
return true;
}
return false;
}
/**
* delete unit categories
* @param [type] $id
* @return [type]
*/
public function delete_unit_categories($id)
{
$builder = $this->db->table(get_db_prefix().'mrp_unit_measure_categories');
$builder->where('id', $id);
$affected_row = $builder->delete();
if ($affected_row > 0) {
return true;
}
return false;
}
/**
* get unit of measure
* @param boolean $id
* @return [type]
*/
public function get_unit_of_measure($id = false)
{
if (is_numeric($id)) {
$builder = $this->db->table(get_db_prefix().'ware_unit_type');
$builder->where('unit_type_id', $id);
return $builder->get()->getRow();
}
if ($id == false) {
return $this->db->query('select * from ' . get_db_prefix() . 'ware_unit_type')->getResultArray();
}
}
/**
* add unit of measure
* @param [type] $data
*/
public function add_unit_of_measure($data)
{
$data['unit_code'] = strtoupper(str_replace(" ", "_", mrp_convert_accented_characters($data['unit_name'])));
$data['order'] = 1;
if(!isset($data['display'])){
$data['display'] = 0;
}
if($data['unit_measure_type'] == 'bigger'){
$data['smaller_ratio'] = 0;
}elseif($data['unit_measure_type'] == 'smaller'){
$data['bigger_ratio'] = 0;
}else{
$data['smaller_ratio'] = 0;
$data['bigger_ratio'] = 0;
}
$builder = $this->db->table(get_db_prefix().'ware_unit_type');
$builder->insert($data);
$insert_id = $this->db->insertID();
if ($insert_id) {
return $insert_id;
}
return false;
}
/**
* update unit of measure
* @param [type] $data
* @param [type] $id
* @return [type]
*/
public function update_unit_of_measure($data, $id)
{
$builder = $this->db->table(get_db_prefix().'ware_unit_type');
$builder->where('unit_type_id', $id);
$affected_row = $builder->update($data);
if ($affected_row > 0) {
return true;
}
return false;
}
/**
* delete unit of measure
* @param [type] $id
* @return [type]
*/
public function delete_unit_of_measure($id)
{
$builder = $this->db->table(get_db_prefix().'ware_unit_type');
$builder->where('unit_type_id', $id);
$affected_row = $builder->delete();
if ($affected_row > 0) {
return true;
}
return false;
}
/**
* get commodity
* @param boolean $id
* @return array or object
*/
public function get_product($id = false)
{
if (is_numeric($id)) {
$builder = $this->db->table(get_db_prefix().'items');
$builder->where('id', $id);
return $builder->get()->getRow();
}
if ($id == false) {
$builder = $this->db->table(get_db_prefix().'items');
$sql_where = db_prefix().'items.id not in ( SELECT distinct parent_id from '.db_prefix().'items WHERE parent_id is not null AND parent_id != "0" )';
$builder->select('*, CONCAT(commodity_code, "_", title) as description');
$builder->where($sql_where);
return $builder->get()->getResultArray();
}
}
/**
* get product by parent id
* @param [type] $parent_id
* @return [type]
*/
public function get_product_by_parent_id($parent_id)
{
$builder = $this->db->table(get_db_prefix().'items');
$builder->where('parent_id', $parent_id);
$items = $builder->get()->getResultArray();
return $items;
}
/**
* mrp get item group
* @return [type]
*/
public function mrp_get_item_group()
{
return $this->db->query('select * from '.db_prefix().'item_categories where display = 1 AND deleted = 0 order by '.db_prefix().'item_categories.order asc ')->getResultArray();
}
/**
* mrp get unit
* @return [type]
*/
public function mrp_get_unit()
{
return $this->db->query('select * from '.db_prefix().'ware_unit_type where display = 1 order by '.db_prefix().'ware_unit_type.order asc ')->getResultArray();
}
/**
* check sku duplicate
* @param [type] $data
* @return [type]
*/
public function check_sku_duplicate($data)
{
if(isset($data['item_id']) && $data['item_id'] != ''){
//check update
$builder = $this->db->table(get_db_prefix().'items');
$builder->where('sku_code', $data['sku_code']);
$builder->where('id != ', $data['item_id']);
$items = $builder->get()->getResultArray();
if(count($items) > 0){
return false;
}
return true;
}elseif(isset($data['sku_code']) && $data['sku_code'] != ''){
//check insert
$builder = $this->db->table(get_db_prefix().'items');
$builder->where('sku_code', $data['sku_code']);
$items = $builder->get()->getRow();
if($items){
return false;
}
return true;
}
return true;
}
/**
* add product
* @param [type] $data
*/
public function add_product($data, $rel_type)
{
$arr_insert_cf=[];
$arr_variation=[];
$arr_attributes=[];
$arr_custom_fields=[];
$arr_variation_temp=[];
$variation_name_temp='';
$variation_option_temp='';
if(isset($data['name'])){
foreach ($data['name'] as $key => $data_name) {
//get variation (parent attribute)
$variation_name_temp = $data_name;
if(isset($data['options'][$key])){
$variation_option_temp = $data['options'][$key];
}
array_push($arr_variation, [
'name' => $variation_name_temp,
'options' => explode(',', $variation_option_temp),
]);
$variation_name_temp='';
$variation_option_temp='';
}
}
//get attribute
foreach ($data as $key => $value) {
if(preg_match("/^variation_names_/", $key)){
array_push($arr_attributes, [
'name' => str_replace('variation_names_', '', $key),
'option' => $value,
]);
unset($data[$key]);
}
}
if(isset($data['supplier_taxes_id'])){
$data['supplier_taxes_id'] = implode(",", $data['supplier_taxes_id']);
}
$arr_insert_cf['items_pr'] = $arr_custom_fields;
//get attribute
if(count($arr_attributes) > 0){
$data['attributes'] = json_encode($arr_attributes);
}else{
$data['attributes'] = null;
}
if(count($arr_variation) > 0){
$data['parent_attributes'] = json_encode($arr_variation);
}else{
$data['parent_attributes'] = null;
}
//generate sku_code
if($data['sku_code'] == ''){
$sql_where = 'SELECT * FROM ' . get_db_prefix() . 'items order by id desc limit 1';
$res = $this->db->query($sql_where)->getRow();
$last_commodity_id = 0;
if (isset($res)) {
$last_commodity_id = $this->db->query($sql_where)->getRow()->id;
}
$next_commodity_id = (int) $last_commodity_id + 1;
$sku_code = str_pad($next_commodity_id,5,'0',STR_PAD_LEFT);
$data['commodity_code'] = $sku_code;
$data['sku_code'] = $sku_code;
}else{
$data['commodity_code'] = $data['sku_code'];
}
if(isset($data['name'])){
unset($data['name']);
}
if(isset($data['options'])){
unset($data['options']);
}
if(isset($data['file_names'])){
unset($data['file_names']);
}
if(isset($data['file_sizes'])){
unset($data['file_sizes']);
}
$builder = $this->db->table(get_db_prefix().'items');
$builder->insert($data);
$insert_id = $this->db->insertID();
if ($insert_id) {
//create variant
$add_variant=false;
if($rel_type == 'product'){
if(count($arr_variation) > 0 && strlen(json_encode($arr_variation)) > 28){
$response_create_variant = $this->create_variant_product($insert_id, $data, $arr_variation);
if($response_create_variant){
$add_variant = true;
}
}
}
app_hooks()->do_action('item_created', $insert_id);
return ['insert_id' => $insert_id, 'add_variant' => $add_variant];
}
return false;
}
/**
* update product
* @param [type] $data
* @param [type] $id
* @return [type]
*/
public function update_product($data, $id, $rel_type)
{
$affected_rows = 0;
$arr_insert_cf=[];
$arr_variation=[];
$arr_attributes=[];
$arr_custom_fields=[];
$arr_variation_temp=[];
$variation_name_temp='';
$variation_option_temp='';
if(isset($data['name'])){
foreach ($data['name'] as $key => $data_name) {
//get variation (parent attribute)
$variation_name_temp = $data_name;
if(isset($data['options'][$key])){
$variation_option_temp = $data['options'][$key];
}
array_push($arr_variation, [
'name' => $variation_name_temp,
'options' => explode(',', $variation_option_temp),
]);
$variation_name_temp='';
$variation_option_temp='';
}
}
//get attribute
foreach ($data as $key => $value) {
if(preg_match("/^variation_names_/", $key)){
array_push($arr_attributes, [
'name' => str_replace('variation_names_', '', $key),
'option' => $value,
]);
unset($data[$key]);
}
}
if(isset($data['supplier_taxes_id'])){
$data['supplier_taxes_id'] = implode(",", $data['supplier_taxes_id']);
}
$arr_insert_cf['items_pr'] = $arr_custom_fields;
//get attribute
if(count($arr_attributes) > 0){
$data['attributes'] = json_encode($arr_attributes);
}else{
$data['attributes'] = null;
}
if(count($arr_variation) > 0){
$data['parent_attributes'] = json_encode($arr_variation);
}else{
$data['parent_attributes'] = null;
}
if(isset($data['name'])){
unset($data['name']);
}
if(isset($data['options'])){
unset($data['options']);
}
if(isset($data['file_names'])){
unset($data['file_names']);
}
if(isset($data['file_sizes'])){
unset($data['file_sizes']);
}
$builder = $this->db->table(get_db_prefix().'items');
$builder->where('id', $id);
$affected_row = $builder->update($data);
if ($affected_row > 0) {
$affected_rows++;
}
//create, inactive variant product when update
if($rel_type == 'product'){
if(count($arr_variation) > 0 && strlen(json_encode($arr_variation)) > 28){
$response_create_variant = $this->update_variant_product($id, $arr_variation);
if($response_create_variant){
$affected_rows++;
}
}else{
//update all product to inactive
$builder = $this->db->table(get_db_prefix().'items');
$builder->where('parent_id', $id);
$affected_row = $builder->update(['deleted' => 1]);
if ($affected_row > 0) {
$affected_rows++;
}
}
}
if($affected_rows > 0){
return true;
}
return false;
}
/**
* delete product
* @param [type] $id
* @return [type]
*/
public function delete_product($id, $rel_type)
{
app_hooks()->do_action('delete_item_on_woocommerce', $id);
/*delete file attachment*/
$array_file= $this->mrp_get_attachments_file($id, 'commodity_item_file');
if(count($array_file) > 0 ){
foreach ($array_file as $key => $file_value) {
$this->delete_mrp_attachment_file($file_value['id'], MANUFACTURING_PRODUCT_UPLOAD);
}
}
$builder = $this->db->table(get_db_prefix().'items');
$builder->where('id', $id);
$affected_row = $builder->delete();
if ($affected_row > 0) {
return true;
}
return false;
}
/**
* create variant product
* @param [type] $parent_id
* @param [type] $data
* @return [type]
*/
public function create_variant_product($parent_id, $data, $variant)
{
//get last product id
$sql_where = 'SELECT * FROM ' . get_db_prefix() . 'items order by id desc limit 1';
$res = $this->db->query($sql_where)->getRow();
$last_commodity_id = 0;
if (isset($res)) {
$last_commodity_id = $this->db->query($sql_where)->getRow()->id;
}
$next_commodity_id = (int) $last_commodity_id + 1;
$generate_variants = $this->variant_generator($variant);
$varirant_data=[];
$description = $data['title'];
foreach ($generate_variants as $_variant) {
$str_variant='';
if(count($variant) > 1){
foreach ($_variant as $value) {
if(strlen($str_variant) == 0){
$str_variant .= $value['option'];
}else{
$str_variant .= '-'.$value['option'];
}
}
}else{
if(strlen($str_variant) == 0){
$str_variant .= $_variant['option'];
}else{
$str_variant .= '-'.$_variant['option'];
}
}
$str_variant = str_replace(' ', '_', $str_variant);
$barcode_gen = mrp_generate_commodity_barcode();
//create sku code
$sku_code = str_pad($next_commodity_id,5,'0',STR_PAD_LEFT);
$next_commodity_id++;
$data['commodity_code'] = $sku_code;
$data['sku_code'] = $sku_code;
$data['commodity_barcode'] = $barcode_gen;
$data['commodity_code'] = $sku_code;
$data['sku_code'] = $sku_code;
$data['parent_id'] = $parent_id;
$data['parent_attributes'] = null;
if(count($variant) > 1){
$data['attributes'] = json_encode($_variant);
}else{
$data['attributes'] = json_encode(array($_variant));
}
$data['title'] = $description.' '. $str_variant;
$varirant_data[] = $data;
}
if(count($varirant_data) != 0){
$builder = $this->db->table(get_db_prefix().'items');
$affected_rows = $builder->insertBatch($varirant_data);
if($affected_rows > 0){
return true;
}
return false;
}
return false;
}
/**
* variant generator
* @param [type] $variants
* @param integer $i
* @return [type]
*/
public function variant_generator($variants, $i = 0)
{
if (!isset($variants[$i]['options'])) {
return array();
}
if ($i == count($variants) - 1) {
$last_arr=[];
foreach ($variants[$i]['options'] as $value) {
$last_arr[]=[
'name' => $variants[$i]['name'],
'option' => $value,
];
}
return $last_arr;
}
// get combinations from subsequent variants
$tmp = $this->variant_generator($variants, $i + 1);
$result = array();
// concat each array from tmp with each element from $variants[$i]
foreach ($variants[$i]['options'] as $v) { //pre end
foreach ($tmp as $t) { //end
$tem=[];
$tem=[
'name' => $variants[$i]['name'],
'option' => $v,
];
if($i <= (count($variants) - 3)){
$result[] = array_merge( array($tem), array_values($t));
}else{
$result[] = array_merge( array($tem), array($t));
}
}
}
return $result;
}
/**
* copy product image
* @param [type] $id
* @return [type]
*/
public function copy_product_image($id, $arr_variant = [])
{
if(count($arr_variant) == 0){
$arr_variant = $this->get_product_by_parent_id($id);
}
$attachments = $this->mrp_get_attachments_file($id, 'commodity_item_file');
foreach ($arr_variant as $variant_id) {
if (is_dir(MANUFACTURING_PRODUCT_UPLOAD . $id)) {
xcopy(MANUFACTURING_PRODUCT_UPLOAD . $id, MANUFACTURING_PRODUCT_UPLOAD . $variant_id['id']);
}
foreach ($attachments as $at) {
$_at = [];
$_at[] = $at;
$external = false;
if (!empty($at['external'])) {
$external = $at['external'];
$_at[0]['name'] = $at['file_name'];
$_at[0]['link'] = $at['external_link'];
if (!empty($at['thumbnail_link'])) {
$_at[0]['thumbnailLink'] = $at['thumbnail_link'];
}
}
$this->misc_model->add_attachment_to_database($variant_id['id'],'commodity_item_file', $_at, $external);
}
}
return true;
}
/**
* get parent product
* @return [type]
*/
public function get_parent_product()
{
$sql_where = ' (' .db_prefix().'items.parent_id is null OR '.db_prefix().'items.parent_id = 0 OR '.db_prefix().'items.parent_id = "" ) ';
$builder = $this->db->table(get_db_prefix().'items');
$builder->where($sql_where);
$products = $builder->get()->getResultArray();
return $products;
}
/**
* get product variant
* @return [type]
*/
public function get_product_variant()
{
$sql_where = db_prefix().'items.deleted = 0 AND '.db_prefix().'items.parent_id is not null AND '.db_prefix().'items.parent_id != 0 AND '.db_prefix().'items.attributes is not null ';
$builder = $this->db->table(get_db_prefix().'items');
$builder->select('*, CONCAT(commodity_code, "_", description) as description');
$builder->where($sql_where);
$products = $builder->get()->getResultArray();
return $products;
}
/**
* get bill of material
* @param boolean $id
* @return [type]
*/
public function get_bill_of_materials($id = false)
{
if (is_numeric($id)) {
$builder = $this->db->table(get_db_prefix().'mrp_bill_of_materials');
$builder->where('id', $id);
return $builder->get()->getRow();
}
if ($id == false) {
return $this->db->query('select * from ' . get_db_prefix() . 'mrp_bill_of_materials')->getResultArray();
}
}
/**
* add bill of material
* @param [type] $data
*/
public function add_bill_of_material($data)
{
$builder = $this->db->table(get_db_prefix().'mrp_bill_of_materials');
$builder->insert($data);
$insert_id = $this->db->insertID();
if ($insert_id) {
/*update next number setting*/
$this->update_prefix_number(['bom_number' => get_setting('bom_number')+1]);
return $insert_id;
}
return false;
}
/**
* update bill of material
* @param [type] $data
* @param [type] $id
* @return [type]
*/
public function update_bill_of_material($data, $id)
{
$builder = $this->db->table(get_db_prefix().'mrp_bill_of_materials');
$builder->where('id', $id);
$affected_row = $builder->update($data);
if ($affected_row > 0) {
return true;
}
return false;
}
/**
* delete bill of material
* @param [type] $id
* @return [type]
*/
public function delete_bill_of_material($id)
{
$affected_rows = 0;
//delete bill of material details
$builder = $this->db->table(get_db_prefix().'mrp_bill_of_material_details');
$builder->where('bill_of_material_id', $id);
$affected_row = $builder->delete();
if ($affected_row > 0) {
$affected_rows++;
}
//delete data
$builder = $this->db->table(get_db_prefix().'mrp_bill_of_materials');
$builder->where('id', $id);
$affected_row = $builder->delete();
if ($affected_row > 0) {
$affected_rows++;
}
if($affected_rows > 0){
return true;
}
return false;
}
/**
* get bill of material details
* @param boolean $id
* @param boolean $bill_of_material_id
* @return [type]
*/
public function get_bill_of_material_details($id=false, $bill_of_material_id = false)
{
if (is_numeric($id)) {
$builder = $this->db->table(get_db_prefix().'mrp_bill_of_material_details');
$builder->where('id', $id);
return $builder->get()->getRow();
}
if($bill_of_material_id != false){
$builder = $this->db->table(get_db_prefix().'mrp_bill_of_material_details');
$builder->where('bill_of_material_id', $bill_of_material_id);
return $builder->get()->getResultArray();
}
if ($id == false) {
return $this->db->query('select * from ' . get_db_prefix() . 'mrp_bill_of_material_details')->getResultArray();
}
}
/**
* add bill of material detail
* @param [type] $data
*/
public function add_bill_of_material_detail($data)
{
if(isset($data['apply_on_variants'])){
$data['apply_on_variants'] = implode(',', $data['apply_on_variants']);
}
$builder = $this->db->table(get_db_prefix().'mrp_bill_of_material_details');
$builder->insert($data);
$insert_id = $this->db->insertID();
if ($insert_id) {
return $insert_id;
}
return false;
}
/**
* update bill of material detail
* @param [type] $data
* @param [type] $id
* @return [type]
*/
public function update_bill_of_material_detail($data, $id)
{
$affected_rows=0;
if(isset($data['apply_on_variants'])){
$data['apply_on_variants'] = implode(',', $data['apply_on_variants']);
}else{
$data['apply_on_variants'] = null;
}
$builder = $this->db->table(get_db_prefix().'mrp_bill_of_material_details');
$builder->where('id', $id);
$affected_row = $builder->update($data);
if ($affected_row > 0) {
$affected_rows++;
}
if($affected_rows > 0){
return true;
}
return false;
}
/**
* delete bill of material detail
* @param [type] $id
* @return [type]
*/
public function delete_bill_of_material_detail($id)
{
//delete data
$builder = $this->db->table(get_db_prefix().'mrp_bill_of_material_details');
$builder->where('id', $id);
$affected_row = $builder->delete();
if ($affected_row > 0) {
return true;
}
return false;
}
/**
* get variant attribute
* @param [type] $product_id
* @return [type]
*/
public function get_variant_attribute($product_id)
{
$arr_variant=[];
$product = $this->get_product($product_id);
if($product){
if( $product->parent_attributes != null && $product->parent_attributes != '' && strlen($product->parent_attributes) > 28){
$parent_attributes = json_decode($product->parent_attributes);
foreach ($parent_attributes as $parent_attribute) {
foreach ($parent_attribute->options as $option) {
array_push($arr_variant, [
'name' => $parent_attribute->name.':'.$option,
'label' => $parent_attribute->name.' : '.$option,
]);
}
}
}
}
return $arr_variant;
}
/**
* get product variants
* @param [type] $id
* @return [type]
*/
public function get_product_variants($id)
{
$options = '';
$product_by_parent_id = $this->get_product_by_parent_id($id);
if(count($product_by_parent_id) > 0){
$options .= '<option value="">- '.app_lang('product_variant').'</option>';
foreach ($product_by_parent_id as $key => $value) {
$options .= '<option value="' . $value['id'] . '">' . $value['commodity_code'].' '. $value['title'] . '</option>';
}
}
return $options;
}
/**
* get data create manufacturing order
* @param [type] $product_id
* @return [type]
*/
public function get_data_create_manufacturing_order($product_id)
{
$bill_of_material_option ='';
$routing_option ='';
$bill_of_material_arr=[];
$component_arr=[];
$component_row=0;
$unit_id='';
//get list bills of material with BOM type is "manufacture this product"
$bill_of_materials = $this->get_list_bill_of_material_by_product($product_id);
if(count($bill_of_materials) > 0){
foreach ($bill_of_materials as $bom_key => $bom_value) {
$selected = '';
if($bom_key == 0){
$selected = ' selected';
}
$bill_of_material_option .= '<option value="' . $bom_value['id'] . '" '.$selected.'>' .$bom_value['description'] . '</option>';
$bill_of_material_arr[] = $bom_value['id'];
if(strlen($routing_option) == 0){
$routing_option = $bom_value['routing_id'];
}
}
}
//get bill_of_material detail value
if(count($bill_of_material_arr) > 0){
$bill_of_material_details = $this->get_bill_of_material_details('', $bill_of_material_arr[0]);
$product = $this->get_product($product_id);
if(isset($product)){
$component_arr = $this->get_bill_of_material_details_by_product($bill_of_material_arr[0], $product->attributes);
$unit_id = $product->unit_id;
}
}
$result=[];
$result['bill_of_material_option'] =$bill_of_material_option;
$result['routing_option'] =$routing_option;
$result['component_arr'] =$component_arr;
$result['component_row'] = count($component_arr);
$result['unit_id'] = $unit_id;
return $result;
}
/**
* get product for hansometable
* @return [type]
*/
public function get_product_for_hansometable()
{
$sql_where = get_db_prefix().'items.id not in ( SELECT distinct parent_id from '.get_db_prefix().'items WHERE parent_id is not null AND parent_id != "0" )';
$builder = $this->db->table(get_db_prefix().'items');
$builder->select('id, CONCAT(commodity_code,"_",title) as label');
$builder->where($sql_where);
return $builder->get()->getResultArray();
}
/**
* get unit for hansometable
* @return [type]
*/
public function get_unit_for_hansometable()
{
return $this->db->query('select unit_type_id as id, unit_name as label from ' . get_db_prefix() . 'ware_unit_type')->getResultArray();
}
/**
* get bill of material detail with product name
* @return [type]
*/
public function get_bill_of_material_detail_with_product_name()
{
$builder = $this->db->table(get_db_prefix().'mrp_bill_of_materials');
$builder->select(get_db_prefix().'mrp_bill_of_materials.id, CONCAT('.db_prefix().'mrp_bill_of_materials.bom_code," ", '.db_prefix().'items.title) as description');
$builder->join(get_db_prefix() . 'items', db_prefix() . 'mrp_bill_of_materials.product_id = ' . get_db_prefix() . 'items.id', 'left');
$bill_of_materials = $builder->get()->getResultArray();
return $bill_of_materials;
}
/**
* get bill of material details by product
* @param [type] $bill_of_material_id
* @param [type] $product_attribute
* @return [type]
*/
public function get_bill_of_material_details_by_product($bill_of_material_id, $product_attributes, $product_qty='')
{
$component_arr = [];
$bom_qty=1;
$bom = $this->get_bill_of_materials($bill_of_material_id);
if($bom){
$bom_qty = $bom->product_qty;
}
if($product_attributes != null){
$str_where = '';
$arr_attributes = json_decode($product_attributes);
foreach ($arr_attributes as $key => $attributes) {
if(strlen($str_where) > 0){
$str_where .= 'OR find_in_set( "'.$attributes->name.':'.$attributes->option.'", apply_on_variants)';
}else{
$str_where .= ' find_in_set( "'.$attributes->name.':'.$attributes->option.'", apply_on_variants)';
}
}
if(strlen($str_where) > 0){
$str_where .= 'OR apply_on_variants is null';
}else{
$str_where .= 'apply_on_variants is null';
}
$builder = $this->db->table(get_db_prefix().'mrp_bill_of_material_details');
$builder->where('bill_of_material_id = '.$bill_of_material_id.' AND ('.$str_where.')');
$bill_of_material_details = $builder->get()->getResultArray();
}else{
$builder = $this->db->table(get_db_prefix().'mrp_bill_of_material_details');
$builder->where('bill_of_material_id = '.$bill_of_material_id.' AND apply_on_variants is null ');
$bill_of_material_details = $builder->get()->getResultArray();
}
foreach ($bill_of_material_details as $bom_detail_key => $bom_detail_value) {
if($product_qty != ''){
$qty_to_consume = (float)$bom_detail_value['product_qty']*(float)$product_qty/$bom_qty;
}else{
//default mo for 1 product
$qty_to_consume = $bom_detail_value['product_qty']*1/$bom_qty;
}
$last_bill_of_material = $this->get_last_bill_of_material_by_product($bom_detail_value['product_id'], $qty_to_consume, '');
if(count($last_bill_of_material) > 0){
$component_arr = array_merge($component_arr, $last_bill_of_material);
}else{
array_push($component_arr, [
'id' => 0,
'product_id' => $bom_detail_value['product_id'],
'unit_id' => $bom_detail_value['unit_id'],
'qty_to_consume' => $qty_to_consume,
'qty_reserved' => 0,
'qty_done' => 0,
'check_inventory_qty' => true,
]);
}
}
return $component_arr;
}
/**
* add manufacturing order
* @param [type] $data
*/
public function add_manufacturing_order($data)
{
$affected_rows=0;
if (isset($data['product_tab_hs'])) {
$product_tab_hs = $data['product_tab_hs'];
unset($data['product_tab_hs']);
}
$data['manufacturing_order_code'] = $this->create_code('mo_code');
$data['date_deadline'] = to_sql_date1($data['date_deadline'], true);
$data['date_plan_from'] = to_sql_date1($data['date_plan_from'], true);
$builder = $this->db->table(get_db_prefix().'mrp_manufacturing_orders');
$builder->insert($data);
$insert_id = $this->db->insertID();
//create working hours data
if(isset($product_tab_hs)){
$working_hour_detail = json_decode($product_tab_hs);
$es_detail = [];
$row = [];
$header = [];
$header[] = 'id';
$header[] = 'product_id';
$header[] = 'unit_id';
$header[] = 'qty_to_consume';
$header[] = 'qty_reserved';
$header[] = 'qty_done';
foreach ($working_hour_detail as $key => $value) {
if($value[1] != ''){
$es_detail[] = array_combine($header, $value);
}
}
}
if(count($es_detail) > 0){
if (isset($insert_id)) {
$affected_rows++;
/*insert manufacturing_order_id*/
foreach($es_detail as $key => $rqd){
$es_detail[$key]['manufacturing_order_id'] = $insert_id;
}
$builder = $this->db->table(get_db_prefix().'mrp_manufacturing_order_details');
$insert_working_hour = $builder->insertBatch($es_detail);
if($insert_working_hour > 0){
$affected_rows++;
}
}
}
if($insert_id){
/*update next number setting*/
$this->update_prefix_number(['mo_number' => get_setting('mo_number')+1]);
}
if ($affected_rows > 0) {
return $insert_id;
}
return false;
}
/**
* update manufacturing order
* @param [type] $id
* @param [type] $data
* @return [type]
*/
public function update_manufacturing_order($data, $id)
{
$affected_rows=0;
if (isset($data['product_tab_hs'])) {
$product_tab_hs = $data['product_tab_hs'];
unset($data['product_tab_hs']);
}
$data['date_deadline'] = to_sql_date1($data['date_deadline'], true);
$data['date_plan_from'] = to_sql_date1($data['date_plan_from'], true);
$builder = $this->db->table(get_db_prefix().'mrp_manufacturing_orders');
$builder->where('id', $id);
$ffected_row = $builder->update($data);
if ($ffected_row > 0) {
$affected_rows++;
}
//create working hours data
if(isset($product_tab_hs)){
$working_hour_detail = json_decode($product_tab_hs);
$es_detail = [];
$row = [];
$header = [];
$header[] = 'id';
$header[] = 'product_id';
$header[] = 'unit_id';
$header[] = 'qty_to_consume';
$header[] = 'qty_reserved';
$header[] = 'qty_done';
foreach ($working_hour_detail as $key => $value) {
if($value[1] != ''){
$es_detail[] = array_combine($header, $value);
}
}
}
//handle manufacturing_orders detail
$manufacturing_order_details = [];
$manufacturing_order_details['update'] = [];
$manufacturing_order_details['insert'] = [];
$manufacturing_order_details['delete'] = [];
$total = [];
foreach ($es_detail as $key => $value) {
if($value['id'] != ''){
$manufacturing_order_details['delete'][] = $value['id'];
$manufacturing_order_details['update'][] = $value;
}else{
unset($value['id']);
$value['manufacturing_order_id'] = $id;
$manufacturing_order_details['insert'][] = $value;
}
}
if(empty($manufacturing_order_details['delete'])){
$manufacturing_order_details['delete'] = ['0'];
}
$manufacturing_order_details['delete'] = implode(",",$manufacturing_order_details['delete']);
$builder = $this->db->table(get_db_prefix().'mrp_manufacturing_order_details');
$builder->where('id NOT IN ('.$manufacturing_order_details['delete'] .') and manufacturing_order_id ='.$id);
$affected_row = $builder->delete();
if($affected_row > 0){
$affected_rows++;
}
if(count($manufacturing_order_details['insert']) != 0){
$builder = $this->db->table(get_db_prefix().'mrp_manufacturing_order_details');
$affected_row = $builder->insertBatch(get_db_prefix().'mrp_manufacturing_order_details', $manufacturing_order_details['insert']);
if($affected_row > 0){
$affected_rows++;
}
}
if(count($manufacturing_order_details['update']) != 0){
$builder = $this->db->table(get_db_prefix().'mrp_manufacturing_order_details');
$affected_row = $builder->updateBatch($manufacturing_order_details['update'], 'id');
if($affected_row > 0){
$affected_rows++;
}
}
if ($affected_rows > 0) {
return true;
}
return false;
}
/**
* delete manufacturing order
* @param [type] $id
* @return [type]
*/
public function delete_manufacturing_order($id)
{
$affected_rows = 0;
//delete data
$builder = $this->db->table(get_db_prefix().'mrp_manufacturing_order_details');
$builder->where('manufacturing_order_id', $id);
$affected_row = $builder->delete();
if ($affected_row > 0) {
$affected_rows++;
}
$builder = $this->db->table(get_db_prefix().'mrp_manufacturing_orders');
$builder->where('id', $id);
$affected_row = $builder->delete();
if ($affected_row > 0) {
$affected_rows++;
}
if($affected_rows > 0){
app_hooks()->do_action('after_manufacturing_order_deleted', $id);
return true;
}
return false;
}
/**
* get list manufacturing order
* @return [type]
*/
public function get_list_manufacturing_order()
{
return $this->db->query('select * from ' . get_db_prefix() . 'mrp_manufacturing_orders')->getResultArray();
}
/**
* get manufacturing order
* @param [type] $id
* @return [type]
*/
public function get_manufacturing_order($id)
{
$builder = $this->db->table(get_db_prefix().'mrp_manufacturing_order_details');
$builder->where('manufacturing_order_id', $id);
$manufacturing_order_details = $builder->get()->getResultArray();
$builder = $this->db->table(get_db_prefix().'mrp_manufacturing_orders');
$builder->where('id', $id);
$manufacturing_order = $builder->get()->getRow();
$result=[];
$result['manufacturing_order_detail'] = $manufacturing_order_details;
$result['manufacturing_order'] = $manufacturing_order;
return $result;
}
/**
* get list bill of material by product
* @param [type] $product_id
* @return [type]
*/
public function get_list_bill_of_material_by_product($product_id)
{
//get list bills of material with BOM type is "manufacture this product"
$product = $this->get_product($product_id);
if($product){
$parent_id = $product->parent_id;
$attributes = $product->attributes;
}
if(isset($parent_id) && (int)$parent_id != 0){
$sql_where = "( (product_id = ".$parent_id." AND product_variant_id = ".$product_id.") OR( product_id = ".$parent_id." AND (product_variant_id = 0 OR product_variant_id is null))) AND bom_type = 'manufacture_this_product'";
}else{
//14/05/2021 change bom_type "Kit" TO "manufacture_this_product"
$sql_where = "product_id = ".$product_id." AND bom_type = 'manufacture_this_product'";
}
$builder = $this->db->table(get_db_prefix().'mrp_bill_of_materials');
$builder->select(get_db_prefix().'mrp_bill_of_materials.id,CONCAT('.db_prefix().'mrp_bill_of_materials.bom_code," ", '.db_prefix().'items.title) as description, '.db_prefix().'mrp_bill_of_materials.bom_code, routing_id');
$builder->join(get_db_prefix() . 'items', db_prefix() . 'mrp_bill_of_materials.product_id = ' . get_db_prefix() . 'items.id', 'left');
$builder->where($sql_where);
$bill_of_materials = $builder->get()->getResultArray();
return $bill_of_materials;
}
/**
* update manufacturing order status
* @param [type] $id
* @param [type] $status
* @return [type]
*/
public function update_manufacturing_order_status($id, $data)
{
$builder = $this->db->table(get_db_prefix().'mrp_manufacturing_orders');
$builder->where('id', $id);
$affected_row = $builder->update($data);
if($affected_row > 0){
app_hooks()->do_action('manufacturing_order_status_changed', ['id' => $id, 'data' => $data]);
return true;
}
return false;
}
/**
* mo mark as todo
* @param [type] $id
* @return [type]
* Check component avalability
*/
public function mo_mark_as_todo($id, $type)
{
$Warehouse_model = model("Warehouse\Models\Warehouse_model");
$result=[];
$affected_rows=0;
$flag = 0;
//get MO
$mo_detail_update=[];
$mo_detail_update_check_availability=[];
$check_availability='';
$check_availability_message='';
$warehouse_id='';
$mo = $this->get_manufacturing_order($id);
if($mo['manufacturing_order']){
$warehouse_id = $mo['manufacturing_order']->components_warehouse_id;
}
if($mo['manufacturing_order_detail']){
foreach ($mo['manufacturing_order_detail'] as $mo_detail) {
$flag_inventory = 0;
$commodity_name='';
$item_value = $this->get_product($mo_detail['product_id']);
if($item_value){
$commodity_name .= $item_value->description;
}
if(strlen($warehouse_id) > 0){
$sql = 'SELECT sum(inventory_number) as inventory_number from ' . get_db_prefix() . 'inventory_manage where warehouse_id = ' . $warehouse_id . ' AND commodity_id = ' . $mo_detail['product_id'];
}else{
$sql = 'SELECT sum(inventory_number) as inventory_number from ' . get_db_prefix() . 'inventory_manage where commodity_id = ' . $mo_detail['product_id'];
}
$value = $this->db->query($sql)->getRow();
if ($value) {
$inventory_number = $value->inventory_number;
if ((float)$value->inventory_number < (float) $mo_detail['qty_to_consume']) {
$flag = 1;
$flag_inventory = 1;
$check_availability_message .= $commodity_name.' '._l('not_enough_inventory').', '._l('available_quantity').': '.(float) $value->inventory_number.'<br/>';
}
} else {
$flag = 1;
$flag_inventory = 1;
$check_availability_message .=$commodity_name.' '. _l('Product_does_not_exist_in_stock').'<br/>';
}
if($type == 'mark_as_todo'){
//mark_as_todo
if($flag_inventory == 0){
$qty_reserved = $mo_detail['qty_to_consume'];
}else{
if(isset($inventory_number) && (float)$inventory_number != 0){
$qty_reserved = (float)$inventory_number;
}else{
$qty_reserved = 0;
}
}
array_push($mo_detail_update, [
'id' =>$mo_detail['id'],
'manufacturing_order_id' =>$mo_detail['manufacturing_order_id'],
'product_id' =>$mo_detail['product_id'],
'unit_id' =>$mo_detail['unit_id'],
'qty_to_consume' =>$mo_detail['qty_to_consume'],
'qty_reserved' =>$qty_reserved,
]);
}else{
//check availability
if($mo_detail['qty_reserved'] < $mo_detail['qty_to_consume']){
if(isset($inventory_number) && (float)$inventory_number != 0){
if(($mo_detail['qty_to_consume']-$mo_detail['qty_reserved']) <= (float)$inventory_number){
$qty_reserved = $mo_detail['qty_to_consume']-$mo_detail['qty_reserved'];
}else{
$qty_reserved = $inventory_number;
}
array_push($mo_detail_update, [
'id' =>$mo_detail['id'],
'manufacturing_order_id' =>$mo_detail['manufacturing_order_id'],
'product_id' =>$mo_detail['product_id'],
'unit_id' =>$mo_detail['unit_id'],
'qty_to_consume' =>$mo_detail['qty_to_consume'],
'qty_reserved' =>$mo_detail['qty_reserved']+$qty_reserved,
]);
array_push($mo_detail_update_check_availability, [
'id' =>$mo_detail['id'],
'manufacturing_order_id' =>$mo_detail['manufacturing_order_id'],
'product_id' =>$mo_detail['product_id'],
'unit_id' =>$mo_detail['unit_id'],
'qty_to_consume' =>$mo_detail['qty_to_consume'],
'qty_reserved' =>$qty_reserved,
]);
}
}
}
}
}
if($flag == 1){
$result['status'] = false;
$result['message'] = _l('component').'<br>'.$check_availability_message;
}
if(count($mo_detail_update) > 0){
//update mo detail, reserved quantity
$builder = $this->db->table(get_db_prefix().'mrp_manufacturing_order_details');
$affected_row = $builder->updateBatch($mo_detail_update, 'id');
if($affected_row > 0){
$affected_rows++;
}
//update inventory quantity (warehouse module)
//remove item have qty_reserved == 0
foreach ($mo_detail_update as $mo_d_key => $mo_value) {
if($mo_value['qty_reserved'] == 0){
unset($mo_detail_update[$mo_d_key]);
}
}
if(count($mo_detail_update) > 0){
if($type == 'mark_as_todo'){
//mark_as_todo
$add_inventory_quantity = $this->mrp_add_inventory_quantity($mo_detail_update, 2, $warehouse_id);
}else{
//check availability
$add_inventory_quantity = $this->mrp_add_inventory_quantity($mo_detail_update, 2, $warehouse_id);
}
if($add_inventory_quantity){
$affected_rows++;
}
}
}
if($type == 'mark_as_todo'){
//update MO status to "confirmed"
$update_mo_status = $this->update_manufacturing_order_status($id, [
'status' => 'confirmed',
]);
if($update_mo_status){
$affected_rows++;
}
}
if(!isset($result['status'])){
if($affected_rows > 0){
$result['status'] = true;
}else{
$result['status'] = false;
}
}
if(!isset($result['message'])){
$result['message'] = '';
}
return $result;
}
/**
* mo mark as todo
* @param [type] $id
* @return [type]
*/
public function mo_mark_as_planned($id)
{
$affected_rows=0;
//insert data to work order table
$operation_of_bom = $this->get_operation_of_bom($id);
if(count($operation_of_bom['work_orders']) > 0){
$builder = $this->db->table(get_db_prefix().'mrp_work_orders');
$affected_row = $builder->insertBatch($operation_of_bom['work_orders']);
if($affected_row > 0){
$affected_rows++;
}
}
//update MO status to "planned"
$update_mo_status = $this->update_manufacturing_order_status($id, [
'status' => 'planned',
'date_planned_start' => to_sql_date1($operation_of_bom['date_planned_start'], true),
'date_planned_finished' => to_sql_date1($operation_of_bom['date_planned_finished'], true),
]);
if($update_mo_status){
$affected_rows++;
}
if($affected_rows > 0){
return true;
}
return false;
}
/**
* get operation of bom
* @param [type] $bom_id
* @return [type]
*/
public function get_operation_of_bom($mo_id)
{
//1.get operation of main Bom
//2.get operation of components in Bom (recursive).
$work_orders=[];
//1.get operation of main Bom
$manufacturing_order = $this->get_manufacturing_order($mo_id);
$work_center_id=[];
if($manufacturing_order['manufacturing_order']){
$date_plan_from = $manufacturing_order['manufacturing_order']->date_plan_from;
$mo_product_id = $manufacturing_order['manufacturing_order']->product_id;
$product_quantity = $manufacturing_order['manufacturing_order']->product_qty;
$product_unit = $manufacturing_order['manufacturing_order']->unit_id;
//get operation from routing id
$operations = $this->get_operation('', $manufacturing_order['manufacturing_order']->routing_id);
foreach ($operations as $operation) {
array_push($work_orders, [
'manufacturing_order_id' => $mo_id,
'product_id' => $mo_product_id,
'qty_produced' => 0,
'qty_production' => $product_quantity,
'qty_producing' => $product_quantity,
'unit_id' => $product_unit,
'date_planned_start' => to_sql_date1('', true),
'date_planned_finished' => to_sql_date1('', true),
'routing_detail_id' => $operation['id'],
'duration_expected' => $operation['default_duration'],
'operation_name' => $operation['operation'],
'work_center_id' => $operation['work_center_id'],
]);
if(!in_array($operation['work_center_id'], $work_center_id)){
$work_center_id[] = $operation['work_center_id'];
}
}
}
//get working hours
//get working hours by day
$working_hours=[];
if(count($work_center_id) > 0){
$working_hours = $this->get_working_time_by_ids($work_center_id);
}
//2.get operation of components in Bom (recursive).
if(count($manufacturing_order['manufacturing_order_detail']) > 0){
$bill_of_material_details = $this->get_bill_of_material_details('', $manufacturing_order['manufacturing_order']->bom_id);
$operation_recursive = $this->get_operation_recursive($bill_of_material_details, $mo_id);
$work_orders = array_merge($work_orders, $operation_recursive);
}
if(isset($date_plan_from)){
$date_planned_start_temp=$date_plan_from;
$date_planned_finished_temp='';
$flag_next_day = false;
foreach ($work_orders as $key => $work_order) {
$flag_hour_key=0;
if(count($working_hours) > 0 && isset($working_hours['wcenter'.$work_order['work_center_id']])){
$wh_by_wcenter = $working_hours['wcenter'.$work_order['work_center_id']];
$duration_expected_temp = $work_order['duration_expected'];
while ( (float)$duration_expected_temp != 0) {
while (!isset($wh_by_wcenter[date('N', strtotime($date_planned_start_temp))])){
$date_planned_start_temp = date('Y-m-d', strtotime($date_planned_start_temp.'+'.'1 days')).' 00:00:01';
}
foreach ($wh_by_wcenter[date('N', strtotime($date_planned_start_temp))] as $hour_key => $hours) {
if((strtotime($date_planned_start_temp) >= strtotime(date('Y-m-d', strtotime($date_planned_start_temp)).' '.$hours['work_from'] )) && (strtotime($date_planned_start_temp) <= strtotime(date('Y-m-d', strtotime($date_planned_start_temp)).' '.$hours['work_to'] ))){
// <= date_planned_start_temp <=
if(!isset($work_orders[$key]['date_planned_start']) || $work_orders[$key]['date_planned_start'] == null){
$work_orders[$key]['date_planned_start'] = to_sql_date1($date_planned_start_temp, true);
}
if($flag_next_day == true){
$hours_time = (strtotime(date('Y-m-d', strtotime($date_planned_start_temp.'+'.'1 days')).' '.$hours['work_to'])-strtotime($date_planned_start_temp))/60;
}else{
$hours_time = (strtotime($hours['work_to'])-strtotime(date('H:i:s', strtotime($date_planned_start_temp))))/60;
}
if((float)$duration_expected_temp > (float)$hours_time){
$duration_expected_temp = (float)$duration_expected_temp - (float)$hours_time;
$date_planned_start_temp = date('Y-m-d H:i:s', strtotime($date_planned_start_temp.'+'.$hours_time.' minute'));
}else{
$date_planned_start_temp = date('Y-m-d H:i:s', strtotime($date_planned_start_temp.'+'.(float)$duration_expected_temp.' minute'));
$duration_expected_temp = 0;
}
$work_orders[$key]['date_planned_finished'] = to_sql_date1($date_planned_start_temp, true);
if($duration_expected_temp == 0){
$flag_next_day=false;
break;
}
if($duration_expected_temp != 0 && count($wh_by_wcenter[date('N', strtotime($date_planned_start_temp))]) == $hour_key+1){
$date_planned_start_temp = date('Y-m-d', strtotime($date_planned_start_temp.'+'.'1 days')).' 00:00:01';
$flag_next_day=true;
}
}elseif(strtotime($date_planned_start_temp) <= strtotime(date('Y-m-d', strtotime($date_planned_start_temp)).' '.$hours['work_from'] )){
if(!isset($work_orders[$key]['date_planned_start']) && $work_orders[$key]['date_planned_start'] == null){
$work_orders[$key]['date_planned_start'] = date('Y-m-d H:i:s', strtotime(date('Y-m-d', strtotime($date_planned_start_temp)).' '.$hours['work_from'] ));
$work_order['date_planned_start'] = date('Y-m-d H:i:s', strtotime(date('Y-m-d', strtotime($date_planned_start_temp)).' '.$hours['work_from'] ));
}
$date_planned_start_temp = date('Y-m-d', strtotime($date_planned_start_temp)).' '.$hours['work_from'] ;
if($flag_next_day == true){
$hours_time = (strtotime(date('Y-m-d', strtotime($date_planned_start_temp)).' '.$hours['work_to'])-strtotime($date_planned_start_temp))/60;
}else{
$hours_time = (strtotime($hours['work_to'])-strtotime($hours['work_from']))/60;
}
if((float)$duration_expected_temp > (float)$hours_time){
$duration_expected_temp = (float)$duration_expected_temp - (float)$hours_time;
$date_planned_start_temp = date('Y-m-d H:i:s', strtotime($date_planned_start_temp.'+'.$hours_time.' minute'));
}else{
$date_planned_start_temp = date('Y-m-d H:i:s', strtotime($date_planned_start_temp.'+'.(float)$duration_expected_temp.' minute'));
$duration_expected_temp = 0;
}
$work_orders[$key]['date_planned_finished'] = $date_planned_start_temp;
if($duration_expected_temp == 0){
$flag_next_day=false;
break;
}
if($duration_expected_temp != 0 && count($wh_by_wcenter[date('N', strtotime($date_planned_start_temp))]) == $hour_key+1){
$date_planned_start_temp = date('Y-m-d', strtotime($date_planned_start_temp.'+'.'1 days')).' 00:00:01';
$flag_next_day=true;
}
}elseif(strtotime($date_planned_start_temp) >= strtotime(date('Y-m-d', strtotime($date_planned_start_temp)).' '.$hours['work_to'] )){
if(count($wh_by_wcenter[date('N', strtotime($date_planned_start_temp))]) == $hour_key+1){
$date_planned_start_temp = date('Y-m-d', strtotime($date_planned_start_temp.'+'.'1 days')).' 00:00:01';
$flag_next_day=true;
}
}else{
$date_planned_start_temp = date('Y-m-d', strtotime($date_planned_start_temp.'+'.'1 days')).' 00:00:01';
$flag_next_day=true;
}
}
}
if(!isset($work_order['status'])){
if($key == 0 ){
$work_orders[$key]['status'] = 'ready';
}else{
$work_orders[$key]['status'] = 'waiting_for_another_wo';
}
}
}else{
$newtimestamp = strtotime($date_planned_start_temp.' + '.(int)$work_order['duration_expected'].' minute');
$planned_finished = date('Y-m-d H:i:s', $newtimestamp);
$work_orders[$key]['date_planned_start'] = to_sql_date1($date_planned_start_temp, true);
$work_orders[$key]['date_planned_finished'] = to_sql_date1($planned_finished, true);
if(!isset($work_order['status'])){
if($key == 0 ){
$work_orders[$key]['status'] = 'ready';
}else{
$work_orders[$key]['status'] = 'waiting_for_another_wo';
}
}
$date_planned_start_temp = $planned_finished;
}
}
}
$work_orders = array_reverse($work_orders);
$data=[];
$data['work_orders'] = $work_orders;
$data['date_planned_start'] = $date_plan_from;
$data['date_planned_finished'] = $date_planned_start_temp;
return $data;
}
/**
* get_plan_start_finished
* @param [type] $work_orders
* @param [type] $work_order
* @param [type] $key
* @param [type] $wh_by_wcenter
* @param [type] $date_planned_start_temp
* @param [type] $duration_expected_temp
* @param [type] $flag_next_day
* @return [type]
*/
public function get_plan_start_finished($work_orders, $work_order, $key, $wh_by_wcenter, $date_planned_start_temp, $duration_expected_temp, $flag_next_day)
{
if(isset($wh_by_wcenter[date('N', strtotime($date_planned_start_temp))])){
foreach ($wh_by_wcenter[date('N', strtotime($date_planned_start_temp))] as $hour_key => $hours) {
if((strtotime($date_planned_start_temp) >= strtotime(date('Y-m-d', strtotime($date_planned_start_temp)).' '.$hours['work_from'] )) && (strtotime($date_planned_start_temp) <= strtotime(date('Y-m-d', strtotime($date_planned_start_temp)).' '.$hours['work_to'] ))){
// <= date_planned_start_temp <=
if(!isset($work_orders[$key]['date_planned_start']) || $work_orders[$key]['date_planned_start'] == null){
$work_orders[$key]['date_planned_start'] = to_sql_date1($date_planned_start_temp, true);
$work_order['date_planned_start'] = to_sql_date1($date_planned_start_temp, true);
}
if($flag_next_day == true){
$hours_time = (strtotime(date('Y-m-d', strtotime($date_planned_start_temp.'+'.'1 days')).' '.$hours['work_to'])-strtotime($date_planned_start_temp))/60;
}else{
$hours_time = (strtotime($hours['work_to'])-strtotime(date('H:i:s', strtotime($date_planned_start_temp))))/60;
}
if($hours_time == 0 && $hour_key+1 == count($wh_by_wcenter[date('N', strtotime($date_planned_start_temp))])){
$next_date = date('Y-m-d', strtotime($date_planned_start_temp.'+'.'1 days')).' 00:00:00';
$hour_diff = round(abs(strtotime($next_date) - strtotime($date_planned_start_temp))/60, 2);
$date_planned_start_temp = date('Y-m-d H:i:s', strtotime($date_planned_start_temp.'+'.$hour_diff.' minute'));
$flag_next_day = true;
$this->get_plan_start_finished($work_orders, $work_order, $key, $wh_by_wcenter, $date_planned_start_temp, $duration_expected_temp, true);
}
if((float)$duration_expected_temp > (float)$hours_time){
$duration_expected_temp = (float)$duration_expected_temp - (float)$hours_time;
$date_planned_start_temp = date('Y-m-d H:i:s', strtotime($date_planned_start_temp.'+'.$hours_time.' minute'));
}else{
$date_planned_start_temp = date('Y-m-d H:i:s', strtotime($date_planned_start_temp.'+'.(float)$duration_expected_temp.' minute'));
$duration_expected_temp = 0;
}
$work_orders[$key]['date_planned_finished'] = to_sql_date1($date_planned_start_temp, true);
$work_order['date_planned_finished'] = to_sql_date1($date_planned_start_temp, true);
if($duration_expected_temp != 0 && $hour_key+1 == count($wh_by_wcenter[date('N', strtotime($date_planned_start_temp))])){
$next_date = date('Y-m-d', strtotime($date_planned_start_temp.'+'.'1 days')).' 00:00:00';
$hour_diff = round(abs(strtotime($next_date) - strtotime($date_planned_start_temp))/60, 2);
$date_planned_start_temp = date('Y-m-d H:i:s', strtotime($date_planned_start_temp.'+'.$hour_diff.' minute'));
$flag_next_day = true;
$this->get_plan_start_finished($work_orders, $work_order, $key, $wh_by_wcenter, $date_planned_start_temp, $duration_expected_temp, true);
}
}elseif(strtotime($date_planned_start_temp) < strtotime(date('Y-m-d', strtotime($date_planned_start_temp)).' '.$hours['work_from'] )){
// date_planned_start_temp <
if(!isset($work_orders[$key]['date_planned_start']) && $work_orders[$key]['date_planned_start'] == null){
$work_orders[$key]['date_planned_start'] = date('Y-m-d H:i:s', strtotime(date('Y-m-d', strtotime($date_planned_start_temp)).' '.$hours['work_from'] ));
$work_order['date_planned_start'] = date('Y-m-d H:i:s', strtotime(date('Y-m-d', strtotime($date_planned_start_temp)).' '.$hours['work_from'] ));
}
$date_planned_start_temp = date('Y-m-d', strtotime($date_planned_start_temp)).' '.$hours['work_from'] ;
if($flag_next_day == true){
$hours_time = (strtotime(date('Y-m-d', strtotime($date_planned_start_temp)).' '.$hours['work_to'])-strtotime($date_planned_start_temp))/60;
}else{
$hours_time = (strtotime($hours['work_to'])-strtotime($hours['work_from']))/60;
}
if((float)$duration_expected_temp > (float)$hours_time){
$duration_expected_temp = (float)$duration_expected_temp - (float)$hours_time;
$date_planned_start_temp = date('Y-m-d H:i:s', strtotime($date_planned_start_temp.'+'.$hours_time.' minute'));
}else{
$date_planned_start_temp = date('Y-m-d H:i:s', strtotime($date_planned_start_temp.'+'.(float)$duration_expected_temp.' minute'));
$duration_expected_temp = 0;
}
$work_orders[$key]['date_planned_finished'] = $date_planned_start_temp;
$work_order['date_planned_finished'] = $date_planned_start_temp;
if($duration_expected_temp != 0 && $hour_key+1 == count($wh_by_wcenter[date('N', strtotime($date_planned_start_temp))])){
$next_date = date('Y-m-d', strtotime($date_planned_start_temp.'+'.'1 days')).' 00:00:00';
$hour_diff = round(abs(strtotime($next_date) - strtotime($date_planned_start_temp))/60, 2);
$date_planned_start_temp = date('Y-m-d H:i:s', strtotime($date_planned_start_temp.'+'.$hour_diff.' minute'));
$flag_next_day = true;
$this->get_plan_start_finished($work_orders, $work_order, $key, $wh_by_wcenter, $date_planned_start_temp, $duration_expected_temp, true);
}
}elseif(strtotime($date_planned_start_temp) > strtotime(date('Y-m-d', strtotime($date_planned_start_temp)).' '.$hours['work_to'] ) && $hour_key+1 == count($wh_by_wcenter[date('N', strtotime($date_planned_start_temp))])){
$next_date = date('Y-m-d', strtotime($date_planned_start_temp.'+'.'1 days')).' 00:00:00';
$hour_diff = round(abs(strtotime($next_date) - strtotime($date_planned_start_temp))/60, 2);
$date_planned_start_temp = date('Y-m-d H:i:s', strtotime($date_planned_start_temp.'+'.$hour_diff.' minute'));
$flag_next_day = true;
$this->get_plan_start_finished($work_orders, $work_order, $key, $wh_by_wcenter, $date_planned_start_temp, $duration_expected_temp, true);
}
}
return ['work_orders' => $work_orders, 'date_planned_start_temp' => $date_planned_start_temp, 'flag_next_day' => $flag_next_day];
}else{
$next_date = date('Y-m-d', strtotime($date_planned_start_temp.'+'.'1 days')).' 00:00:00';
$hour_diff = round(abs(strtotime($next_date) - strtotime($date_planned_start_temp))/60, 2);
$date_planned_start_temp = date('Y-m-d H:i:s', strtotime($date_planned_start_temp.'+'.$hour_diff.' minute'));
$flag_next_day = true;
$this->get_plan_start_finished($work_orders, $work_order, $key, $wh_by_wcenter, $date_planned_start_temp, $duration_expected_temp, true);
}
}
/**
* get operation recursive
* @param [type] $data
* @param [type] $mo_id
* @return [type]
*/
public function get_operation_recursive($data, $mo_id)
{
$work_orders=[];
foreach ($data as $value) {
//get list bills of material with BOM type is "manufacture this product"
$product = $this->get_product($value['product_id']);
if($product){
$parent_id = $product->parent_id;
$attributes = $product->attributes;
}
if(isset($parent_id)){
$sql_where = "( (product_id = ".$parent_id." AND product_variant_id = ".$value['product_id'].") OR( product_id = ".$parent_id." AND (product_variant_id = 0 OR product_variant_id is null))) AND bom_type = 'kit'";
}else{
$sql_where = "product_id = ".$value['product_id']." ";
}
$builder = $this->db->table(get_db_prefix().'mrp_bill_of_materials');
$builder->select('*');
$builder->where($sql_where);
$builder->orderBy('id', 'desc');
$bill_of_material = $builder->get()->getRow();
//get bom detail
if($bill_of_material){
$mo_product_id = $bill_of_material->product_id;
$product_quantity = $bill_of_material->product_qty;
$product_unit = $bill_of_material->unit_id;
//get operation from routing id
$operations = $this->get_operation('', $bill_of_material->routing_id);
foreach ($operations as $key => $operation) {
if($key == 0 ){
$status = 'ready';
}else{
$status = 'waiting_for_another_wo';
}
array_push($work_orders, [
'manufacturing_order_id' => $mo_id,
'product_id' => $mo_product_id,
'qty_produced' => 0,
'qty_production' => $product_quantity,
'qty_producing' => $product_quantity,
'unit_id' => $product_unit,
'date_planned_start' => to_sql_date1('', true),
'date_planned_finished' => to_sql_date1('', true),
'routing_detail_id' => $operation['id'],
'duration_expected' => $operation['default_duration'],
'operation_name' => $operation['operation'],
'work_center_id' => $operation['work_center_id'],
'status' => $status,
]);
}
$bill_of_material_details = $this->get_bill_of_material_details('', $bill_of_material->id);
}
}
return $work_orders;
}
/**
* get last bill of material by product
* @param [type] $product_id
* @return [type]
*/
public function get_last_bill_of_material_by_product($product_id, $bom_detail_to_consume, $mo_id)
{
$component_arr=[];
//get list bills of material with BOM type is "manufacture this product"
$product = $this->get_product($product_id);
if($product){
$parent_id = $product->parent_id;
$attributes = $product->attributes;
}
if(isset($parent_id) && (int)$parent_id != 0){
$sql_where = "( (product_id = ".$parent_id." AND product_variant_id = ".$product_id.") OR( product_id = ".$parent_id." AND (product_variant_id = 0 OR product_variant_id is null))) AND bom_type = 'kit'";
}else{
$sql_where = "product_id = ".$product_id." ";
}
$builder = $this->db->table(get_db_prefix().'mrp_bill_of_materials');
$builder->select('*');
$builder->where($sql_where);
$builder->orderBy('id', 'desc');
$bill_of_material = $builder->get()->getRow();
//get bom detail
if($bill_of_material){
$bom_qty = $bill_of_material->product_qty;
$bill_of_material_details = $this->get_bill_of_material_details('', $bill_of_material->id);
foreach ($bill_of_material_details as $bom_detail_value) {
if($bom_detail_to_consume != ''){
$qty_to_consume = (float)$bom_detail_value['product_qty']*(float)$bom_detail_to_consume/$bom_qty;
}else{
//default mo for 1 product
$qty_to_consume = $bom_detail_value['product_qty']*1/$bom_qty;
}
array_push($component_arr, [
'id' => 0,
'product_id' => $bom_detail_value['product_id'],
'unit_id' => $bom_detail_value['unit_id'],
'qty_to_consume' => $qty_to_consume,
'qty_reserved' => 0,
'qty_done' => 0,
'check_inventory_qty' => false,
]);
}
}
return $component_arr;
}
/**
* get work order
* @param boolean $id
* @return [type]
*/
public function get_work_order($id = false)
{
if (is_numeric($id)) {
$builder = $this->db->table(get_db_prefix().'mrp_work_orders');
$builder->where('id', $id);
return $builder->get()->getRow();
}
if ($id == false) {
return $this->db->query('select * from ' . get_db_prefix() . 'mrp_work_orders')->getResultArray();
}
}
/**
* get working tim by ids
* @param [type] $ids
* @return [type]
*/
public function get_working_time_by_ids($ids)
{
$day_of_week=[];
$day_of_week['monday'] = '1';
$day_of_week['tuesday'] = '2';
$day_of_week['wednesday'] = '3';
$day_of_week['thursday'] = '4';
$day_of_week['friday'] = '5';
$day_of_week['saturday'] = '6';
$day_of_week['sunday'] = '7';
//TODO: get working hours by day
$working_hour_data=[];
$builder = $this->db->table(get_db_prefix().'mrp_working_hours');
$builder->select(get_db_prefix().'mrp_work_centers.id as work_center_id, working_hour_id, day_of_week,day_period, hours_per_day, work_from, work_to ');
$builder->join(get_db_prefix() . 'mrp_working_hour_times', db_prefix() . 'mrp_working_hours.id = ' . get_db_prefix() . 'mrp_working_hour_times.working_hour_id', 'left');
$builder->join(get_db_prefix() . 'mrp_work_centers', db_prefix() . 'mrp_working_hours.id = ' . get_db_prefix() . 'mrp_work_centers.working_hours', 'left');
$builder->where(get_db_prefix().'mrp_work_centers.id IN ('.implode(",",$ids).')');
$working_hours = $builder->get()->getResultArray();
$working_hour_data=[];
foreach ($working_hours as $key => $value) {
$working_hour_data['wcenter'.$value['work_center_id']][$day_of_week[$value['day_of_week']]][] = ['work_from' => $value['work_from'], 'work_to' => $value['work_to']];
}
return $working_hour_data;
}
/**
* get work order previous next
* @param [type] $work_order_id
* @return [type]
*/
public function get_work_order_previous_next($work_order_id, $manufacturing_order_id)
{
$prev_id='';
$next_id='';
$pager_value=0;
$pager_limit=0;
$work_orders=[];
$builder = $this->db->table(get_db_prefix().'mrp_work_orders');
$builder->where('manufacturing_order_id', $manufacturing_order_id);
$builder->orderBy('id', 'desc');
$get_work_orders= $builder->get()->getResultArray();
foreach ($get_work_orders as $key => $value) {
$value['index'] = $key+1;
$work_orders[$value['id']] = $value;
}
$pager_value = $work_orders[(int)$work_order_id]['index'];
$pager_limit = count($get_work_orders);
//prev_id
if(count($work_orders) > 0){
if(isset($work_orders[(int)$work_order_id+1])){
$prev_id = (int)$work_order_id+1;
}else{
$prev_id = $get_work_orders[count($work_orders)-1]['id'];
}
}else{
$prev_id = (int)$work_order_id;
}
//next_id
if(count($work_orders) > 0){
if(isset($work_orders[(int)$work_order_id-1])){
$next_id = (int)$work_order_id-1;
}else{
$next_id = $get_work_orders[0]['id'];
}
}else{
$next_id = (int)$work_order_id;
}
$data=[];
$data['pager_value']= $pager_value;
$data['pager_limit']= $pager_limit;
$data['prev_id']= $prev_id;
$data['next_id']= $next_id;
return $data;
}
/**
* update work order status
* @param [type] $id
* @param [type] $data
* @return [type]
*/
public function update_work_order_status($id, $data)
{
$builder = $this->db->table(get_db_prefix().'mrp_work_orders');
$builder->where('id', $id);
$affected_row = $builder->update($data);
if($affected_row > 0){
return true;
}
return false;
}
/**
* add time tracking
* @param [type] $id
* @param [type] $data
*/
public function add_time_tracking($data)
{
$builder = $this->db->table(get_db_prefix().'mrp_work_order_time_trackings');
$insert_id = $builder->insert($data);
if($insert_id ){
return true;
}
return false;
}
/**
* update time tracking
* @param [type] $id
* @param [type] $data
* @return [type]
*/
public function update_time_tracking($work_order_id, $data)
{
$builder = $this->db->table(get_db_prefix().'mrp_work_order_time_trackings');
$builder->where('work_order_id', $work_order_id);
$builder->orderBy('id', 'desc');
$time_tracking = $builder->get()->getRow();
if($time_tracking){
$start_date = strtotime($time_tracking->from_date);
$to_date = strtotime($data['to_date']);
$duration = abs($to_date - $start_date)/(60);
$data['duration'] = $duration;
$builder = $this->db->table(get_db_prefix().'mrp_work_order_time_trackings');
$builder->where('id', $time_tracking->id);
$affected_row = $builder->update( $data);
if($affected_row > 0){
return true;
}
}
return false;
}
/**
* get time tracking details
* @param [type] $id
* @return [type]
*/
public function get_time_tracking_details($id)
{
$builder = $this->db->table(get_db_prefix().'mrp_work_order_time_trackings');
$builder->select(get_db_prefix().'mrp_work_order_time_trackings.id , mrp_work_order_time_trackings.work_order_id, from_date, to_date, duration, CONCAT(first_name," ",last_name) as full_name');
$builder->join(get_db_prefix() . 'users', db_prefix() . 'mrp_work_order_time_trackings.staff_id = ' . get_db_prefix() . 'users.id', 'left');
$builder->where('work_order_id', $id);
$time_trackings = $builder->get()->getResultArray();
$row = count($time_trackings);
$data=[];
$data['rows'] = $row;
$data['time_trackings'] = $time_trackings;
return $data;
}
/**
* get total duration
* @param [type] $work_order_id
* @return [type]
*/
public function get_total_duration($work_order_id)
{
$duration = 0;
$builder = $this->db->table(get_db_prefix().'mrp_work_order_time_trackings');
$builder->select('sum(duration) as duration');
$builder->where('work_order_id', $work_order_id);
$time_tracking = $builder->get()->getRow();
if($time_tracking){
$duration = $time_tracking->duration;
}
return $duration;
}
/**
* mo mark as done
* @return [type]
*/
public function wo_mark_as_done($work_order_id, $manufacturing_order_id)
{
$affected_rows=0;
$current_time=date('Y-m-d H:i:s');
//Update time tracking
$data_update=[
'work_order_id' => $work_order_id,
'to_date' => $current_time,
'staff_id' => get_staff_user_id1(),
];
$update_time_tracking = $this->update_time_tracking($work_order_id, $data_update);
if($update_time_tracking){
$affected_rows++;
}
//update consumed quantity
$duration = $this->get_total_duration($work_order_id);
$work_order = $this->get_work_order($work_order_id);
$qty_produced = 0;
if($work_order){
$qty_produced = $work_order->qty_producing;
}
$update_work_order=[];
$update_work_order['status'] = 'finished';
$update_work_order['date_finished'] = to_sql_date1($current_time, true);
$update_work_order['real_duration'] = $duration;
$update_work_order['qty_produced'] = $qty_produced;
$update_work_order['qty_producing'] = 0;
$update_work_order = $this->update_work_order_status($work_order_id, $update_work_order);
if($update_work_order){
$affected_rows++;
}
//update next work order status
$get_work_order_previous_next = $this->get_work_order_previous_next($work_order_id, $manufacturing_order_id);
if($get_work_order_previous_next['next_id']){
$next_work_order = $this->get_work_order($get_work_order_previous_next['next_id']);
if($next_work_order && $next_work_order->status == 'waiting_for_another_wo'){
$update_next_work_order = $this->update_work_order_status($get_work_order_previous_next['next_id'], ['status' => 'ready']);
if($update_next_work_order){
$affected_rows++;
}
}
}
if($affected_rows > 0){
return true;
}
return false;
}
/**
* get work order timeline
* @param string $manufacturing_order_id
* @return [type]
*/
public function get_work_order_timeline($manufacturing_order_id='')
{
$data=[];
//get manufacturing order
$mo_ids=[];
if($manufacturing_order_id != ''){
$builder = $this->db->table(get_db_prefix().'mrp_manufacturing_orders');
$builder->where('id', $manufacturing_order_id);
$manufacturing_order = $builder->get()->getResultArray();
$mo_ids[] = $manufacturing_order_id;
}else{
$builder = $this->db->table(get_db_prefix().'mrp_manufacturing_orders');
$builder->where('status !=', 'draft');
$manufacturing_order = $builder->get()->getResultArray();
foreach ($manufacturing_order as $value) {
$mo_ids[] = $value['id'];
}
}
$builder = $this->db->table(get_db_prefix().'mrp_work_orders');
$builder->where('manufacturing_order_id IN ('.implode(",",$mo_ids) .') ');
$builder->orderBy('id', 'desc');
$work_order_data = $builder->get()->getResultArray();
$work_orders=[];
foreach ($work_order_data as $key => $work_order) {
$work_orders[$work_order['manufacturing_order_id']][] = $work_order;
}
foreach ($manufacturing_order as $value) {
$row = [];
$row['id'] = 'mo_' . $value['id'];
$row['start'] = $value['date_planned_start'];
$row['end'] = $value['date_planned_finished'];
$row['name'] = $value['manufacturing_order_code'].' - '.mrp_get_product_name($value['product_id']);
$data[] = $row;
if(isset($work_orders[$value['id']])){
foreach ($work_orders[$value['id']] as $wo_key => $wo_value) {
$note = [];
$note['start'] = $wo_value['date_planned_start'];
$note['progress'] = 100;
$note['name'] = mrp_get_product_name($wo_value['product_id']).' - '.$wo_value['operation_name'] .' - '._l($wo_value['status']);
$note['id'] = $wo_value['id'];
$note['dependencies'] = 'mo_' . $wo_value['manufacturing_order_id'];
$note['end'] = $wo_value['date_planned_finished'];
$note['duration_expected'] = round($wo_value['duration_expected'], 2);
$note['real_duration'] = round($wo_value['real_duration'], 2);
$note['quantity_produced'] = $wo_value['qty_produced'].'/'.$wo_value['qty_production'];
switch ($wo_value['status']) {
case 'waiting_for_another_wo':
$note['custom_class'] = 'br_waiting_for_another_wo';
break;
case 'ready':
$note['custom_class'] = 'br_ready';
break;
case 'in_progress':
$note['custom_class'] = 'br_in_progress';
break;
case 'finished':
$note['custom_class'] = 'br_finished';
break;
case 'pause':
$note['custom_class'] = 'br_pause';
break;
}
$data[] = $note;
}
}
}
if ($data == []) {
$data[][] = [];
}
return $data;
}
/**
* check manufacturing order done
* @param [type] $mo_id
* @return [type]
*/
public function check_manufacturing_order_type($mo_id)
{
//get mo
$manufacturing_order = $this->get_manufacturing_order($mo_id);
$check_mo_done='';
$check_create_purchase_request='';
$check_availability='';
$check_planned = false;
$bom_ready_to_produce = 'all_available';
$data_color=[];
if($manufacturing_order['manufacturing_order']){
$bom = $this->get_bill_of_materials($manufacturing_order['manufacturing_order']->bom_id);
if($bom){
$bom_ready_to_produce = $bom->ready_to_produce;
}
if($manufacturing_order['manufacturing_order']->status != 'draft' ){
$builder = $this->db->table(get_db_prefix().'mrp_work_orders');
$builder->where('manufacturing_order_id', $mo_id);
$builder->where('status != ', 'finished');
$work_orders = $builder->get()->getResultArray();
if(count($work_orders) > 0){
$check_mo_done = false;
}else{
$check_mo_done = true;
}
}else{
$check_mo_done = false;
}
}else{
$check_mo_done = false;
}
//check_create_purchase_request
if($manufacturing_order['manufacturing_order']){
if($manufacturing_order['manufacturing_order']->purchase_request_id == null && $manufacturing_order['manufacturing_order']->status != 'done' && $manufacturing_order['manufacturing_order']->status != 'cancelled'){
foreach ($manufacturing_order['manufacturing_order_detail'] as $mo_detail) {
if($mo_detail['qty_reserved'] < $mo_detail['qty_to_consume']){
$check_create_purchase_request = true;
}
}
if(!$check_create_purchase_request){
$check_create_purchase_request = false;
}
}else{
$check_create_purchase_request = false;
}
}else{
$check_create_purchase_request = false;
}
//check availability
if($manufacturing_order['manufacturing_order_detail']){
$check_planned_temp = true;
foreach ($manufacturing_order['manufacturing_order_detail'] as $mo_key => $mo_detail) {
if($bom_ready_to_produce == 'all_available'){
if($mo_detail['qty_reserved'] < $mo_detail['qty_to_consume']){
$check_planned_temp = false;
}
}else{
// components_for_1st
if($mo_key == 0 && $mo_detail['qty_reserved'] >= $mo_detail['qty_to_consume']){
$check_planned = true;
}
}
if($mo_detail['qty_reserved'] < $mo_detail['qty_to_consume']){
$check_availability = true;
$data_color[$mo_key] = '#d8341b';
}else{
$data_color[$mo_key] = '#4caf50';
}
}
if(!$check_availability){
$check_availability = false;
}
if($bom_ready_to_produce == 'all_available'){
if($check_planned_temp){
$check_planned = true;
}
}
}else{
$check_availability = false;
}
$result=[];
$result['check_mo_done'] = $check_mo_done;
$result['check_create_purchase_request'] = $check_create_purchase_request;
$result['check_availability'] = $check_availability;
$result['data_color'] = $data_color;
$result['check_planned'] = $check_planned;
return $result;
}
/**
* mo mark as done
* @param [type] $id
* @return [type]
*/
public function mo_mark_as_done($id)
{
$Warehouse_model = model("Warehouse\Models\Warehouse_model");
$affected_rows=0;
$available_quantity = true;
//update inventory quantity related Inventory Module
$mo = $this->get_manufacturing_order($id);
//check available quantity before mark as done
foreach ($mo['manufacturing_order_detail'] as $key => $mo_value) {
if($mo_value['qty_reserved'] == 0){
$available_quantity = false;
}
}
if($available_quantity){
if($mo['manufacturing_order']){
$add_receipt_voucher = $this->mrp_add_good_receipt_voucher($mo['manufacturing_order']);
if($add_receipt_voucher){
$affected_rows++;
}
}else{
return false;
}
$manufacturing_order_costing = $this->get_manufacturing_order_costing($mo['manufacturing_order']->id);
$total_manufaturing_order_costing = (float)$manufacturing_order_costing['total_material_cost'] + (float)$manufacturing_order_costing['total_labour_cost'];
$purchase_price = $total_manufaturing_order_costing/(float)$mo['manufacturing_order']->product_qty;
$get_product = $this->get_product($mo['manufacturing_order']->product_id);
if($get_product){
if((float)$get_product->purchase_price == 0){
$builder = $this->db->table(get_db_prefix().'items');
$builder->where('id', $mo['manufacturing_order']->product_id);
$builder->update(['purchase_price' => $purchase_price]);
}
}
//create inventory delivery voucher for component use in Mo, write log, don't change inventory quantity
if($mo){
$insert_id = $this->mo_add_goods_delivery($mo);
if($insert_id){
$goods_delivery_detail = $Warehouse_model->get_goods_delivery_detail($insert_id);
foreach ($goods_delivery_detail as $goods_delivery_detail_value) {
$goods_delivery_detail_value['purchase_price'] = $purchase_price;
$Warehouse_model->add_goods_transaction_detail($goods_delivery_detail_value, 2);
}
}
}
//update manufacturing order status to Finished
$update_mo_status = $this->update_manufacturing_order_status($id, ['status' => 'done']);
if($update_mo_status){
$affected_rows++;
}
if($affected_rows > 0){
return true;
}
return false;
}else{
return false;
}
}
/**
* mo create purchase request
* @param [type] $id
* @return [type]
*/
public function mo_create_purchase_request($id)
{
$Purchase_model = model("Purchase\Models\Purchase_model");
$Taxes_model = model("Models\Taxes_model");
$currency = 0;
$currency = get_base_currency();
$mo = $this->get_manufacturing_order($id);
if(isset($mo['manufacturing_order_detail'])){
$mo_detail=[];
$arr_product_id=[];
foreach ($mo['manufacturing_order_detail'] as $key => $mo_value) {
$arr_product_id[] = $mo_value['product_id'];
}
$builder = $this->db->table(get_db_prefix().'items');
$builder->where('id IN ('.implode(",",$arr_product_id) .')');
$products = $builder->get()->getResultArray();
$arr_products=[];
foreach ($products as $product) {
$arr_products[$product['id']] = $product;
}
$pu_subtotal=0;
$pu_total_tax=0;
$pu_total=0;
foreach ($mo['manufacturing_order_detail'] as $key => $mo_value) {
if($mo_value['qty_reserved'] != $mo_value['qty_to_consume']){
$tax_select = [];
$pu_qty = $mo_value['qty_to_consume'] - $mo_value['qty_reserved'];
$unit_price = isset($arr_products[$mo_value['product_id']]) ? (float)$arr_products[$mo_value['product_id']]['purchase_price'] : 0;
$list_taxrate = isset($arr_products[$mo_value['product_id']]) ? $arr_products[$mo_value['product_id']]['supplier_taxes_id'] : '';
$taxrate= 0 ;
$tax_id='';
if(strlen($list_taxrate) > 0){
$array_taxrate = explode(',', $list_taxrate);
foreach ($array_taxrate as $taxrate_id) {
$tax = $this->taxes_model->get($taxrate_id);
if($tax){
$taxrate += (float)$tax->taxrate;
$tax_select[] = $tax->name.'|'.$tax->taxrate;
}
}
}
$tax_value = (float)$unit_price*$pu_qty*$taxrate/100;
$into_money = (float)$unit_price*$pu_qty;
$total = (float)$unit_price*$pu_qty+$tax_value;
$pu_total_tax += $tax_value;
$pu_subtotal += $into_money;
$pu_total += $total;
array_push($mo_detail, [
'item_code' => $mo_value['product_id'],
'unit_id' => $mo_value['unit_id'],
'unit_price' => $unit_price,
'quantity' => $pu_qty,
'into_money' => $into_money,
'tax' => $tax_id,
'tax_value' => $tax_value,
'total' => $total,
'inventory_quantity' => 0,
'item_text' => mo_get_commodity_name($mo_value['product_id']),
'tax_select' => $tax_select,
]);
}
}
$prefix = get_setting('pur_request_prefix');
$data['department'] = 0;
$purchase_data=[];
$purchase_data['number'] = (int)get_setting('next_pr_number');
$purchase_data['pur_rq_code'] = $prefix.'-'.str_pad($purchase_data['number'],5,'0',STR_PAD_LEFT).'-'.date('M-Y');
$purchase_data['pur_rq_name'] = 'PUR create from Manufacturing '.$mo['manufacturing_order']->manufacturing_order_code;
$purchase_data['project'] = '';
$purchase_data['type'] = '';
$purchase_data['sale_invoice'] = '';
$purchase_data['requester'] = get_staff_user_id1();
$purchase_data['from_items'] = '1';
$purchase_data['rq_description'] = app_lang('this_puchase_request_create_from_MO_module').$mo['manufacturing_order']->manufacturing_order_code;
$purchase_data['subtotal'] = $pu_subtotal;
$purchase_data['total_mn'] = $pu_total;
$purchase_data['department'] = $data['department'];
$purchase_data['currency'] = $currency;
$purchase_data['from_currency'] = $currency;
$purchase_data['currency_rate'] = 1;
$request_detail_temp=[];
foreach ($mo_detail as $mo_detail_value) {
$request_detail_temp[] = [
'item_code' => $mo_detail_value['item_code'],
'unit_id' => $mo_detail_value['unit_id'],
'unit_price' => $mo_detail_value['unit_price'],
'into_money' => $mo_detail_value['into_money'],
'total' => $mo_detail_value['total'],
'tax_value' => $mo_detail_value['tax_value'],
'item_text' => $mo_detail_value['item_text'],
'quantity' => $mo_detail_value['quantity'],
'tax_select' => $mo_detail_value['tax_select'],
];
}
$purchase_data['newitems'] = $request_detail_temp;
//add purchase request
$pur_request_id = $Purchase_model->add_pur_request($purchase_data);
return $pur_request_id;
}
}
/**
* mo add pur request
* @param [type] $data
* @return [type]
*/
public function mo_add_pur_request($data)
{
$data['request_date'] = date('Y-m-d H:i:s');
$data['status'] = 2;
$data['from_items'] = 1;
$data['subtotal'] = reformat_currency_pur($data['subtotal']);
if(isset($data['total_mn'])){
$data['total'] = reformat_currency_pur($data['total_mn']);
unset($data['total_mn']);
}
$data['total_tax'] = $data['total'] - $data['subtotal'];
$dpm_name = department_pur_request_name($data['department']);
if(mrp_get_status_modules('Purchase')){
$prefix = get_setting('pur_order_prefix');
}else{
$prefix = '#PO';
}
$builder = $this->db->table(get_db_prefix().'pur_request');
$builder->where('pur_rq_code',$data['pur_rq_code']);
$check_exist_number = $builder->get()->getRow();
while($check_exist_number) {
$data['number'] = $data['number'] + 1;
$data['pur_rq_code'] = $prefix.'-'.str_pad($data['number'],5,'0',STR_PAD_LEFT).'-'.date('M-Y').'-'.$dpm_name;
$builder->where('pur_rq_code',$data['pur_rq_code']);
$check_exist_number = $builder->get(get_db_prefix().'pur_request')->getRow();
}
$data['hash'] = app_generate_hash();
$rq_detail = [];
if(isset($data['request_detail'])){
$request_detail = json_decode($data['request_detail']);
unset($data['request_detail']);
$row = [];
$rq_val = [];
$header = [];
$header[] = 'item_code';
$header[] = 'unit_id';
$header[] = 'unit_price';
$header[] = 'quantity';
$header[] = 'into_money';
$header[] = 'tax';
$header[] = 'tax_value';
$header[] = 'total';
$header[] = 'inventory_quantity';
foreach ($request_detail as $key => $value) {
if($value[0] != '' && $value[0] != null){
$rq_detail[] = array_combine($header, $value);
}
}
}
$builder = $this->db->table(get_db_prefix().'pur_request');
$builder->insert($data);
$insert_id = $this->db->insertID();
if($insert_id){
// Update next purchase order number in settings
$builder = $this->db->table(get_db_prefix().'purchase_option');
$next_number = $data['number']+1;
$builder->where('option_name', 'next_pr_number');
$builder->update(['option_val' => $next_number,]);
if(count($rq_detail) > 0){
foreach($rq_detail as $key => $rqd){
$rq_detail[$key]['pur_request'] = $insert_id;
$rq_detail[$key]['tax_rate'] = $this->get_tax_rate_by_id($rqd['tax']);
$rq_detail[$key]['quantity'] = ($rqd['quantity'] != ''&& $rqd['quantity'] != null) ? $rqd['quantity'] : 0;
if($data['status'] == 2 && $data['from_items'] != 1){
$item_data['description'] = $rqd['item_text'];
$item_data['purchase_price'] = $rqd['unit_price'];
$item_data['unit_id'] = $rqd['unit_id'];
$item_data['rate'] = '';
$item_data['sku_code'] = '';
$item_data['commodity_barcode'] = $this->generate_commodity_barcode();
$item_data['commodity_code'] = $this->generate_commodity_barcode();
$item_id = $this->add_commodity_one_item($item_data);
if($item_id){
$rq_detail[$key]['item_code'] = $item_id;
}
}
}
$builder = $this->db->table(get_db_prefix().'pur_request_detail');
$builder->insertBatch($rq_detail);
}
return $insert_id;
}
return false;
}
/**
* mrp add good receipt voucher
* @param [type] $mo_data
* @return [type]
*/
public function mrp_add_good_receipt_voucher($mo_data)
{
$affected_rows=0;
$Warehouse_model = model("Warehouse\Models\Warehouse_model");
//get product data
$product = $this->get_product($mo_data->product_id);
$manufacturing_order_costing = $this->get_manufacturing_order_costing($mo_data->id);
$total_manufaturing_order_costing = (float)$manufacturing_order_costing['total_material_cost'] + (float)$manufacturing_order_costing['total_labour_cost'];
if(!$product){
return false;
}
$good_receipt=[];
$good_receipt_detail=[];
$purchase_price = $total_manufaturing_order_costing/(float)$mo_data->product_qty;
$tax_value = 0;
$tax = $Warehouse_model->get_taxe_value($product->tax);
if($tax){
$tax_value = $tax->taxrate;
}
$good_receipt['approval'] = 1;
$good_receipt['goods_receipt_code'] = $Warehouse_model->create_goods_code();
$good_receipt['date_c'] = date('Y-m-d');
$good_receipt['date_add'] = date('Y-m-d');
$good_receipt['addedfrom'] = get_staff_user_id1();
$good_receipt['total_tax_money'] = 0;
$good_receipt['total_goods_money'] = (float)($purchase_price)*(float)($mo_data->product_qty);
$good_receipt['value_of_inventory'] = (float)($purchase_price)*(float)($mo_data->product_qty);
$good_receipt['total_money'] = (float)$good_receipt['total_tax_money']+(float)$good_receipt['total_goods_money'];
$good_receipt['description'] = _l('this_receipt_voucher_for_the_product_after_it_has_been_manufactured_from_the_manufacturing_module').$mo_data->manufacturing_order_code;
$good_receipt_detail['commodity_code'] = $product->id;
$good_receipt_detail['warehouse_id'] = $mo_data->finished_products_warehouse_id;
$good_receipt_detail['unit_id'] = $product->unit_id;
$good_receipt_detail['quantities'] = $mo_data->product_qty;
$good_receipt_detail['unit_price'] = $purchase_price;
$good_receipt_detail['goods_money'] = $good_receipt['total_goods_money'];
//insert good receipt
$builder = $this->db->table(get_db_prefix().'goods_receipt');
$builder->insert($good_receipt);
$insert_id = $this->db->insertID();
if($insert_id){
$affected_rows++;
$good_receipt_detail['goods_receipt_id'] = $insert_id;
$builder = $this->db->table(get_db_prefix().'goods_receipt_detail');
$builder->insert($good_receipt_detail);
$insert_detail = $this->db->insertID();
if($insert_detail){
$affected_rows++;
}
}
if(isset($insert_id)){
/*update next number setting*/
$Warehouse_model->update_inventory_setting(['next_inventory_received_mumber' => get_setting('next_inventory_received_mumber')+1]);
}
//update inventory quantity
if (isset($insert_id)) {
if ($good_receipt['approval'] == 1) {
$this->mrp_update_inventory_quantity($insert_id, 1, 1);
}
}
if($affected_rows > 0){
return true;
}
return false;
}
/**
* mrp update inventory quantity
* @param [type] $rel_id
* @param [type] $rel_type
* @param [type] $status
* @return [type]
*/
public function mrp_update_inventory_quantity($rel_id, $rel_type, $status)
{
$Warehouse_model = model("Warehouse\Models\Warehouse_model");
$data_update = [];
switch ($rel_type) {
//case 1: stock_import
case '1':
$data_update['approval'] = $status;
$builder = $this->db->table(get_db_prefix().'goods_receipt');
$builder->where('id', $rel_id);
$builder->update($data_update);
// //update history stock, inventoty manage after staff approved
$goods_receipt_detail = $Warehouse_model->get_goods_receipt_detail($rel_id);
foreach ($goods_receipt_detail as $goods_receipt_detail_value) {
$Warehouse_model->add_goods_transaction_detail($goods_receipt_detail_value, 1);
$Warehouse_model->add_inventory_manage($goods_receipt_detail_value, 1);
}
return true;
break;
case '2':
$data_update['approval'] = $status;
$builder = $this->db->table(get_db_prefix().'goods_delivery');
$builder->where('id', $rel_id);
$builder->update($data_update);
//update history stock, inventoty manage after staff approved
$goods_delivery_detail = $Warehouse_model->get_goods_delivery_detail($rel_id);
foreach ($goods_delivery_detail as $goods_delivery_detail_value) {
// add goods transaction detail (log) after update invetory number
$Warehouse_model->add_inventory_manage($goods_delivery_detail_value, 2);
}
return true;
break;
default:
return false;
break;
}
}
/**
* mrp revert inventory quantity child
* @param [type] $warehouse_id
* @param [type] $commodity_id
* @param [type] $inventory_number
* @return [type]
*/
public function mrp_revert_inventory_quantity_child($warehouse_id, $commodity_id, $inventory_number)
{
$affected_rows=0;
$builder = $this->db->table(get_db_prefix().'inventory_manage');
$builder->where('warehouse_id', $warehouse_id);
$builder->where('commodity_id', $commodity_id);
$total_rows = $builder->get()->getResultArray();
if(count($total_rows) > 0){
//update
$inventory_number_update = (float) $total_rows[0]['inventory_number'] + (float) $inventory_number;
$builder = $this->db->table(get_db_prefix().'inventory_manage');
$builder->where('id', $total_rows[0]['id']);
$affected_row = $builder->update([
'inventory_number' => $inventory_number_update,
]);
if($affected_row > 0){
$affected_rows++;
}
}else{
//insert
$builder = $this->db->table(get_db_prefix().'inventory_manage');
$builder->insert([
'warehouse_id' => $warehouse_id,
'commodity_id' => $commodity_id,
'inventory_number' => $inventory_number,
]);
$insert_id = $this->db->insertID();
if($insert_id > 0){
$affected_rows++;
}
}
return $affected_rows;
}
/**
* mrp add inventory quantity
* @param [type] $data
* @param [type] $status
* @return [type]
*/
public function mrp_add_inventory_quantity($data, $status, $warehouse_id)
{
$affected_rows=0;
// status '1:Goods receipt note 2:Goods delivery note',
if ($status == 1) {
foreach ($data as $key => $value) {
if(strlen($warehouse_id) > 0){
$revert_inventory_quantity_child = $this->mrp_revert_inventory_quantity_child($warehouse_id, $value['product_id'], $value['qty_reserved']);
$affected_rows += (float)$revert_inventory_quantity_child;
}else{
if(strlen($value['warehouse_id']) > 0){
$warehouse_id = explode(",", $value['warehouse_id'])[0];
$revert_inventory_quantity_child = $this->mrp_revert_inventory_quantity_child($warehouse_id, $value['product_id'], $value['qty_reserved']);
$affected_rows += (float)$revert_inventory_quantity_child;
}else{
$Warehouse_model = model("Warehouse\Models\Warehouse_model");
$list_warehouse = $Warehouse_model->get_warehouse();
if(count($list_warehouse) > 0){
$revert_inventory_quantity_child = $this->mrp_revert_inventory_quantity_child($list_warehouse[0]['warehouse_id'], $value['product_id'], $value['qty_reserved']);
$affected_rows += (float)$revert_inventory_quantity_child;
}
}
}
}
} else {
//status == 2 export
//update
$data_update=[];
foreach ($data as $key => $value) {
$available_quantity_n =0;
$data_warehouse_id ='';
$builder = $this->db->table(get_db_prefix().'inventory_manage');
if(strlen($warehouse_id) > 0){
$builder->where('warehouse_id', $warehouse_id);
}
$builder->where('commodity_id', $value['product_id']);
$builder->orderBy('id', 'ASC');
$result = $builder->get()->getResultArray();
//get available qty
foreach ($result as $r_key => $r_value) {
$available_quantity_n += (float)$r_value['inventory_number'];
}
$temp_quantities = $value['qty_reserved'];
$expiry_date = '';
$lot_number = '';
foreach ($result as $result_value) {
if (($result_value['inventory_number'] != 0) && ($temp_quantities != 0)) {
if ($temp_quantities >= $result_value['inventory_number']) {
$temp_quantities = (float) $temp_quantities - (float) $result_value['inventory_number'];
//update inventory
$builder = $this->db->table(get_db_prefix().'inventory_manage');
$builder->where('id', $result_value['id']);
$affected_row = $builder->update([
'inventory_number' => 0,
]);
if($affected_row > 0){
$affected_rows++;
}
//log lot number
if(($result_value['lot_number'] != null) && ($result_value['lot_number'] != '') ){
if(strlen($lot_number) != 0){
$lot_number .=','.$result_value['lot_number'].','.$result_value['inventory_number'];
}else{
$lot_number .= $result_value['lot_number'].','.$result_value['inventory_number'];
}
}
//log expiry date
if(($result_value['expiry_date'] != null) && ($result_value['expiry_date'] != '') ){
if(strlen($expiry_date) != 0){
$expiry_date .=','.$result_value['expiry_date'].','.$result_value['inventory_number'];
}else{
$expiry_date .= $result_value['expiry_date'].','.$result_value['inventory_number'];
}
}
//add warehouse id get from inventory manage
if(strlen($data_warehouse_id) != 0){
$data_warehouse_id .= ','.$result_value['warehouse_id'];
}else{
$data_warehouse_id .= $result_value['warehouse_id'];
}
} else {
//update inventory
$builder = $this->db->table(get_db_prefix().'inventory_manage');
$builder->where('id', $result_value['id']);
$affected_row = $builder->update([
'inventory_number' => (float) $result_value['inventory_number'] - (float) $temp_quantities,
]);
if($affected_row > 0){
$affected_rows++;
}
//log lot number
if(($result_value['lot_number'] != null) && ($result_value['lot_number'] != '') ){
if(strlen($lot_number) != 0){
$lot_number .=','.$result_value['lot_number'].','.$temp_quantities;
}else{
$lot_number .= $result_value['lot_number'].','.$temp_quantities;
}
}
//log expiry date
if(($result_value['expiry_date'] != null) && ($result_value['expiry_date'] != '') ){
if(strlen($expiry_date) != 0){
$expiry_date .=','.$result_value['expiry_date'].','.$temp_quantities;
}else{
$expiry_date .= $result_value['expiry_date'].','.$temp_quantities;
}
}
//add warehouse id get from inventory manage
if(strlen($data_warehouse_id) != 0){
$data_warehouse_id .= ','.$result_value['warehouse_id'];
}else{
$data_warehouse_id .= $result_value['warehouse_id'];
}
$temp_quantities = 0;
}
}
}
array_push($data_update, [
'id' => $value['id'],
'warehouse_id' => $data_warehouse_id,
'lot_number' => $lot_number,
'expiry_date' => $expiry_date,
'available_quantity' => $available_quantity_n,
]);
}
//update warehouse_id, lot_number, expiry date into table mrp_manufacturing_order_details. So when mark as done mo => write log good delivery voucher
if(count($data) != 0){
$builder = $this->db->table(get_db_prefix().'mrp_manufacturing_order_details');
$builder->updateBatch($data_update, 'id');
if($affected_row > 0){
$affected_rows++;
}
}
}
if($affected_rows > 0){
return true;
}
return false;
}
/**
* mo mark as unreserved
* @param [type] $id
* @return [type]
*/
public function mo_mark_as_unreserved($id)
{
$Warehouse_model = model("Warehouse\Models\Warehouse_model");
$result=[];
$affected_rows=0;
//get MO
$mo_detail_update=[];
$mo_detail_revert=[];
$check_availability='';
$check_availability_message='';
$warehouse_id='';
$mo = $this->get_manufacturing_order($id);
if($mo['manufacturing_order']){
$warehouse_id = $mo['manufacturing_order']->components_warehouse_id;
}
if($mo['manufacturing_order_detail']){
foreach ($mo['manufacturing_order_detail'] as $mo_detail) {
array_push($mo_detail_update, [
'id' =>$mo_detail['id'],
'manufacturing_order_id' =>$mo_detail['manufacturing_order_id'],
'product_id' =>$mo_detail['product_id'],
'unit_id' =>$mo_detail['unit_id'],
'qty_to_consume' =>$mo_detail['qty_to_consume'],
'qty_reserved' =>0,
]);
if($mo_detail['qty_reserved'] != 0){
array_push($mo_detail_revert, [
'id' =>$mo_detail['id'],
'manufacturing_order_id' =>$mo_detail['manufacturing_order_id'],
'product_id' =>$mo_detail['product_id'],
'unit_id' =>$mo_detail['unit_id'],
'qty_to_consume' =>$mo_detail['qty_to_consume'],
'qty_reserved' =>$mo_detail['qty_reserved'],
'warehouse_id' =>$mo_detail['warehouse_id'],
]);
}
}
}
if(count($mo_detail_update) > 0){
//update mo detail, reserved quantity
$builder = $this->db->table(get_db_prefix().'mrp_manufacturing_order_details');
$affected_row = $builder->updateBatch($mo_detail_update, 'id');
if($affected_row > 0){
$affected_rows++;
}
//revert inventory quantity (warehouse module)
$add_inventory_quantity = $this->mrp_add_inventory_quantity($mo_detail_revert, 1, $warehouse_id);
if($add_inventory_quantity){
$affected_rows++;
}
}
//revert MO status to "draft"
$update_mo_status = $this->update_manufacturing_order_status($id, [
'status' => 'draft',
]);
if($update_mo_status){
$affected_rows++;
}
if($affected_rows > 0){
return true;
}
return false;
}
/**
* mo add goods delivery
* @param [type] $data
* @param boolean $id
* @return [type]
*/
public function mo_add_goods_delivery($mo_data)
{
$Warehouse_model = model("Warehouse\Models\Warehouse_model");
$mo= $mo_data['manufacturing_order'];
$mo_detail = $mo_data['manufacturing_order_detail'];
$data_detail=[];
$total_money=0;
foreach ($mo_detail as $key => $value) {
$get_product =$this->get_product($value['product_id']);
if($get_product){
/*get item from name*/
$arr_item_insert[$key]['warehouse_id'] = $value['warehouse_id'];
$arr_item_insert[$key]['expiry_date'] = $value['expiry_date'];
$arr_item_insert[$key]['lot_number'] = $value['lot_number'];
$arr_item_insert[$key]['available_quantity'] = $value['available_quantity'];
$arr_item_insert[$key]['commodity_code'] = $value['product_id'];
$arr_item_insert[$key]['quantities'] = $value['qty_reserved'];
$arr_item_insert[$key]['unit_price'] = $get_product->rate;
$arr_item_insert[$key]['tax_id'] = '';
$arr_item_insert[$key]['unit_id'] = $get_product->unit_id;
$arr_item_insert[$key]['total_money'] = (float)$value['qty_reserved']*(float)$get_product->rate;
$arr_item_insert[$key]['total_after_discount'] = (float)$value['qty_reserved']*(float)$get_product->rate;
$total_money += (float)$value['qty_reserved']*(float)$get_product->rate;
}
}
$data['approval'] = 1;
$data['goods_delivery_code'] = $Warehouse_model->create_goods_delivery_code();
$data['date_c'] = date('Y-m-d');
$data['date_add'] = date('Y-m-d');
$data['description'] = _l('this_delivery_voucher_for_the_product_used_in_the_production_module').$mo->manufacturing_order_code;
$data['total_money'] = $total_money;
$data['after_discount'] = $total_money;
$data['addedfrom'] = get_staff_user_id1();
//insert goods delivery
$builder = $this->db->table(get_db_prefix().'goods_delivery');
$builder->insert($data);
$insert_id = $this->db->insertID();
/*update next number setting*/
$Warehouse_model->update_inventory_setting(['next_inventory_delivery_mumber' => get_setting('next_inventory_delivery_mumber')+1]);
//insert goods delivery detail
if (isset($insert_id)) {
foreach ($arr_item_insert as $key => $value) {
$arr_item_insert[$key]['goods_delivery_id'] = $insert_id;
}
$builder = $this->db->table(get_db_prefix().'goods_delivery_detail');
$goods_delivery_detail = $builder->insertBatch($arr_item_insert);
return $insert_id;
}
return false;
}
/**
* mo add delivery log
* @param [type] $data
* @param [type] $status
* @return [type]
*/
public function mo_add_delivery_log($data)
{
$Warehouse_model = model("Warehouse\Models\Warehouse_model");
$available_quantity_n =0;
$available_quantity = $Warehouse_model->get_inventory_by_commodity($data['commodity_code']);
if($available_quantity){
$available_quantity_n = $available_quantity->inventory_number;
}
$data['warehouse_id']='';
//status == 2 export
//update
$builder = $this->db->table(get_db_prefix().'inventory_manage');
$builder->where('commodity_id', $data['commodity_code']);
$builder->orderBy('id', 'ASC');
$result = $builder->get()->getResultArray();
$temp_quantities = $data['quantities'];
$expiry_date = '';
$lot_number = '';
foreach ($result as $result_value) {
if (($result_value['inventory_number'] != 0) && ($temp_quantities != 0)) {
if ($temp_quantities >= $result_value['inventory_number']) {
$temp_quantities = (float) $temp_quantities - (float) $result_value['inventory_number'];
//log lot number
if(($result_value['lot_number'] != null) && ($result_value['lot_number'] != '') ){
if(strlen($lot_number) != 0){
$lot_number .=','.$result_value['lot_number'].','.$result_value['inventory_number'];
}else{
$lot_number .= $result_value['lot_number'].','.$result_value['inventory_number'];
}
}
//log expiry date
if(($result_value['expiry_date'] != null) && ($result_value['expiry_date'] != '') ){
if(strlen($expiry_date) != 0){
$expiry_date .=','.$result_value['expiry_date'].','.$result_value['inventory_number'];
}else{
$expiry_date .= $result_value['expiry_date'].','.$result_value['inventory_number'];
}
}
//add warehouse id get from inventory manage
if(strlen($data['warehouse_id']) != 0){
$data['warehouse_id'] .= ','.$result_value['warehouse_id'];
}else{
$data['warehouse_id'] .= $result_value['warehouse_id'];
}
} else {
//log lot number
if(($result_value['lot_number'] != null) && ($result_value['lot_number'] != '') ){
if(strlen($lot_number) != 0){
$lot_number .=','.$result_value['lot_number'].','.$temp_quantities;
}else{
$lot_number .= $result_value['lot_number'].','.$temp_quantities;
}
}
//log expiry date
if(($result_value['expiry_date'] != null) && ($result_value['expiry_date'] != '') ){
if(strlen($expiry_date) != 0){
$expiry_date .=','.$result_value['expiry_date'].','.$temp_quantities;
}else{
$expiry_date .= $result_value['expiry_date'].','.$temp_quantities;
}
}
//add warehouse id get from inventory manage
if(strlen($data['warehouse_id']) != 0){
$data['warehouse_id'] .= ','.$result_value['warehouse_id'];
}else{
$data['warehouse_id'] .= $result_value['warehouse_id'];
}
$temp_quantities = 0;
}
}
}
//update good delivery detail
$builder = $this->db->table(get_db_prefix().'goods_delivery_detail');
$builder->where('id', $data['id']);
$builder->update([
'expiry_date' => $expiry_date,
'lot_number' => $lot_number,
'warehouse_id' => $data['warehouse_id'],
'available_quantity' => $available_quantity_n,
]);
//goods transaction detail log
$data['expiry_date'] = $expiry_date;
$data['lot_number'] = $lot_number;
$Warehouse_model->add_goods_transaction_detail($data, 2);
return true;
}
/**
* mo mark as cancel
* @param [type] $id
* @return [type]
*/
public function mo_mark_as_cancel($id)
{
$affected_rows=0;
//revert MO status to "cancelled"
$update_mo_status = $this->update_manufacturing_order_status($id, [
'status' => 'cancelled',
]);
if($update_mo_status){
$affected_rows++;
}
if($affected_rows > 0){
return true;
}
return false;
}
/**
* print barcode pdf
* @param [type] $print_barcode
* @return [type]
*/
public function print_barcode_pdf($print_barcode)
{
return app_pdf('print_barcode', module_dir_path(MANUFACTURING_MODULE_NAME, 'libraries/pdf/Print_barcode_pdf.php'), $print_barcode);
}
/**
* get stock internal delivery pdf_html
* @param [type] $internal_delivery_id
* @return [type]
*/
public function get_print_barcode_pdf_html($data)
{
$display_product_name = get_setting('display_product_name_when_print_barcode');
$get_base_currency = get_base_currency();
$current_id='';
if($get_base_currency){
$current_id= $get_base_currency->id;
}
$html ='';
$html .= '<table class="table">
<tbody>';
if($data['select_item'] == 0){
//select all
$array_commodity = $this->get_product();
$html_child='';
$br_tem=1;
foreach ($array_commodity as $key => $value) {
if($value['commodity_barcode'] != ''){
if(!file_exists(MANUFACTURING_PRINT_ITEM. md5($value['commodity_barcode']).'.svg')){
$this->getBarcode($value['commodity_barcode']);
}
}
/*get frist 25 character */
if(strlen($value['description']) > 30){
$pos=strpos($value['description'], ' ', 30);
$description = substr($value['description'],0,$pos );
}else{
$description = $value['description'];
}
/*get frist 100 character */
if(strlen($value['long_description']) > 30){
$pos=strpos($value['long_description'], ' ', 30);
$description_sub = substr($value['long_description'],0,$pos );
}else{
$description_sub = $value['long_description'];
}
//final price: price*Vat
$tax_value=0;
if($value['tax'] != 0 && $value['tax'] != ''){
$tax_rate = get_tax_rate($value['tax']);
if(!is_array($tax_rate) && isset($tax_rate)){
$tax_value = $tax_rate->taxrate;
}
}
$rate_after_tax = (float)$value['rate'] + (float)$value['rate']*$tax_value/100;
if($value['commodity_barcode'] != ''){
if($display_product_name == 1){
$html_child .= '<td class="print-barcode-td-height"><span class="print-item-code print-item-name">'.$description.'</span><br><span class="print-item-code print-item-name">'.$description_sub.'</span><br><span class=" print-item-price">'._l('print_barcode_sale_price').': '.app_format_money($rate_after_tax,$current_id).'</span><span class="print-item"><img class="images_w_table" src="' . site_url('modules/manufacturing/uploads/print_item/' . md5($value['commodity_barcode']).'.svg') . '" alt="' . $value['commodity_barcode'] . '" ></span><span class="print-item-code">'.$value['commodity_barcode'].'</span></td>';
}else{
$html_child .= '<td class="print-barcode-td-height"><span class="print-item-code print-item-name"></span><br><span class="print-item-code print-item-name">'.$description.'</span><br><span class=" print-item-price">'._l('print_barcode_sale_price').': '.app_format_money($rate_after_tax,$current_id).'</span><span class="print-item"><img class="images_w_table" src="' . site_url('modules/manufacturing/uploads/print_item/' . md5($value['commodity_barcode']).'.svg') . '" alt="' . $value['commodity_barcode'] . '" ></span><span class="print-item-code">'.$value['commodity_barcode'].'</span></td>';
}
}else{
if($display_product_name == 1){
$html_child .= '<td class="print-barcode-td-height"><span class="print-item-code print-item-name">'.$description.'</span><br><span class="print-item-code print-item-name">'.$description_sub.'</span><br><span class=" print-item-price">'._l('print_barcode_sale_price').': '.app_format_money($rate_after_tax,$current_id).'</span><span class="print-item"><img class="images_w_table" src="" alt="' . $value['commodity_barcode'] . '" ></span><span class="print-item-code">'._l('the_product_has_no_barcode').'</span></td>';
}else{
$html_child .= '<td class="print-barcode-td-height"><span class="print-item-code print-item-name"></span><br><span class="print-item-code print-item-name">'.$description.'</span><br><span class=" print-item-price">'._l('print_barcode_sale_price').': '.app_format_money($rate_after_tax,$current_id).'</span><span class="print-item"><img class="images_w_table" src="" alt="' . $value['commodity_barcode'] . '" ></span><span class="print-item-code">'._l('the_product_has_no_barcode').'</span></td>';
}
}
if(($key+1)%4 == 0 ){
$html .= '<tr>'.$html_child.'</tr>';
if($br_tem%36 == 0){
$html .= '<br>';
}
$html_child='';
}elseif(($key+1)%4 != 0 && ($key+1 == count($array_commodity))){
$html .= '<tr>'.$html_child.'</tr>';
if($br_tem%36 == 0){
$html .= '<br>';
}
$html_child='';
}
$br_tem++;
}
}else{
//select item check
if(isset($data['item_select_print_barcode'])){
$sql_where ='select * from '.db_prefix().'items where id IN ('.implode(", ", $data['item_select_print_barcode']).') order by id desc';
$array_commodity = $this->db->query($sql_where)->getResultArray();
$html_child='';
$br_tem=1;
foreach ($array_commodity as $key => $value) {
if($value['commodity_barcode'] != ''){
if(!file_exists(MANUFACTURING_PRINT_ITEM. md5($value['commodity_barcode']).'.svg')){
$this->getBarcode($value['commodity_barcode']);
}
}
/*get frist 100 character */
if(strlen($value['description']) > 30){
$pos=strpos($value['description'], ' ', 30);
$description = substr($value['description'],0,$pos );
}else{
$description = $value['description'];
}
/*get frist 100 character */
if(strlen($value['long_description']) > 30){
$pos=strpos($value['long_description'], ' ', 30);
$description_sub = substr($value['long_description'],0,$pos );
}else{
$description_sub = $value['long_description'];
}
//final price: price*Vat
$tax_value=0;
if($value['tax'] != 0 && $value['tax'] != ''){
$tax_rate = get_tax_rate($value['tax']);
if(!is_array($tax_rate) && isset($tax_rate)){
$tax_value = $tax_rate->taxrate;
}
}
$rate_after_tax = (float)$value['rate'] + (float)$value['rate']*$tax_value/100;
if($value['commodity_barcode'] != ''){
if($display_product_name == 1){
$html_child .= '<td><span class="print-item-code print-item-name">'.$description.'</span><br><span class="print-item-code print-item-name ">'.$description_sub.'</span><br><span class=" print-item-price">'._l('print_barcode_sale_price').': '.app_format_money($rate_after_tax,$current_id).'</span><span class="print-item"><img class="images_w_table" src="' . site_url('modules/manufacturing/uploads/print_item/' . md5($value['commodity_barcode']).'.svg') . '" alt="' . $value['commodity_barcode'] . '" ></span><span class="print-item-code">'.$value['commodity_barcode'].'</span></td>';
}else{
$html_child .= '<td><span class="print-item-code print-item-name "></span><br><span class="print-item-code print-item-name">'.$description.'</span><br><span class=" print-item-price">'._l('print_barcode_sale_price').': '.app_format_money($rate_after_tax,$current_id).'</span><span class="print-item"><img class="images_w_table" src="' . site_url('modules/manufacturing/uploads/print_item/' . md5($value['commodity_barcode']).'.svg') . '" alt="' . $value['commodity_barcode'] . '" ></span><span class="print-item-code">'.$value['commodity_barcode'].'</span></td>';
}
}else{
if($display_product_name == 1){
$html_child .= '<td><span class="print-item-code print-item-name">'.$description.'</span><br><span class="print-item-code print-item-name ">'.$description_sub.'</span><br><span class=" print-item-price">'._l('print_barcode_sale_price').': '.app_format_money($rate_after_tax,$current_id).'</span><span class="print-item"><img class="images_w_table" src="" alt="' . $value['commodity_barcode'] . '" ></span><span class="print-item-code">'._l('the_product_has_no_barcode').'</span></td>';
}else{
$html_child .= '<td><span class="print-item-code print-item-name "></span><br><span class="print-item-code print-item-name">'.$description.'</span><br><span class=" print-item-price">'._l('print_barcode_sale_price').': '.app_format_money($rate_after_tax,$current_id).'</span><span class="print-item"><img class="images_w_table" src="" alt="' . $value['commodity_barcode'] . '" ></span><span class="print-item-code">'._l('the_product_has_no_barcode').'</span></td>';
}
}
if(($key+1)%4 == 0 ){
$html .= '<tr>'.$html_child.'</tr>';
if($br_tem%36 == 0){
$html .= '<br>';
}
$html_child='';
}elseif(($key+1)%4 != 0 && ($key+1 == count($array_commodity))){
$html .= '<tr>'.$html_child.'</tr>';
if($br_tem%36 == 0){
$html .= '<br>';
}
$html_child='';
}
$br_tem++;
}
}
}
$html .= '</tbody>
</table>
<br><br><br>
';
$html .= '<link href="' . module_dir_url(MANUFACTURING_MODULE_NAME, 'assets/css/pdf_style.css') . '" rel="stylesheet" type="text/css" />';
return $html;
}
/**
* getBarcode
* @param [type] $sample
* @return [type]
*/
function getBarcode($sample)
{
if (!$sample) {
echo "";
} else {
$barcodeobj = new TCPDFBarcode($sample, 'EAN13');
$code = $barcodeobj->getBarcodeSVGcode(4, 70, 'black');
file_put_contents(MANUFACTURING_PRINT_ITEM.md5($sample).'.svg', $code);
return true;
}
}
/**
* bom get product filter
* @param [type] $ids
* @return [type]
*/
public function bom_get_product_filter($ids)
{
$builder = $this->db->table(get_db_prefix().'items');
$builder->where('id IN ('.implode(",",$ids) .')');
$products = $builder->get()->getResultArray();
return $products;
}
/**
* get mo report data
* @param [type] $mo_measures
* @param [type] $from_date
* @param [type] $to_date
* @return [type]
*/
public function get_mo_report_data($mo_measures, $from_date, $to_date)
{
$chart=[];
switch ($mo_measures) {
case 'count':
$sql_where="SELECT date_format(date_deadline, '%m') as mo_month, count(id) as total, status FROM ".db_prefix()."mrp_manufacturing_orders
where date_format(date_deadline, '%Y-%m-%d') >= '".$from_date."' AND date_format(date_deadline, '%Y-%m-%d') <= '".$to_date."'
group by date_format(date_deadline, '%m'), status
";
break;
case 'total_qty':
$sql_where="SELECT date_format(date_deadline, '%m') as mo_month, sum(product_qty) as total, status FROM ".db_prefix()."mrp_manufacturing_orders
where date_format(date_deadline, '%Y-%m-%d') >= '".$from_date."' AND date_format(date_deadline, '%Y-%m-%d') <= '".$to_date."'
group by date_format(date_deadline, '%m'), status
";
break;
}
$mo = $this->db->query($sql_where)->getResultArray();
$mo_by_month=[];
foreach ($mo as $key => $mo_value) {
$mo_by_month[(int)$mo_value['mo_month']][$mo_value['status']] = $mo_value;
}
for($_month = 1 ; $_month <= 12; $_month++){
if(isset($mo_by_month[$_month])){
$chart['draft'][] = isset($mo_by_month[$_month]['draft']) ? (float)$mo_by_month[$_month]['draft']['total'] : 0;
$chart['planned'][] = isset($mo_by_month[$_month]['planned']) ? (float)$mo_by_month[$_month]['planned']['total'] : 0;
$chart['cancelled'][] = isset($mo_by_month[$_month]['cancelled']) ? (float)$mo_by_month[$_month]['cancelled']['total'] : 0;
$chart['confirmed'][] = isset($mo_by_month[$_month]['confirmed']) ? (float)$mo_by_month[$_month]['confirmed']['total'] : 0;
$chart['done'][] = isset($mo_by_month[$_month]['done']) ? (float)$mo_by_month[$_month]['done']['total'] : 0;
$chart['in_progress'][] = isset($mo_by_month[$_month]['in_progress']) ? (float)$mo_by_month[$_month]['in_progress']['total'] : 0;
}else{
$chart['draft'][] = 0;
$chart['planned'][] = 0;
$chart['cancelled'][] = 0;
$chart['confirmed'][] = 0;
$chart['done'][] = 0;
$chart['in_progress'][] = 0;
}
if($_month == 5){
$chart['categories'][] = _l('month_05');
}else{
$chart['categories'][] = _l('month_'.$_month);
}
}
return $chart;
}
/**
* get wo report data
* @param [type] $mo_measures
* @param [type] $from_date
* @param [type] $to_date
* @return [type]
*/
public function get_wo_report_data($mo_measures, $from_date, $to_date)
{
$chart=[];
$chart['categories']=[];
$chart['mo_data']=[];
$arr_mo_id=[];
$mo_where = "SELECT * FROM ".db_prefix()."mrp_manufacturing_orders where status = 'done' AND date_format(date_deadline, '%Y-%m-%d') >= '".$from_date."' AND date_format(date_deadline, '%Y-%m-%d') <= '".$to_date."'";
$mo_done = $this->db->query($mo_where)->getResultArray();
foreach ($mo_done as $mo) {
$arr_mo_id[] = $mo['id'];
}
if(count($arr_mo_id) > 0){
//get manufacturing order name
$get_mo_where = "SELECT * FROM ".db_prefix()."mrp_manufacturing_orders where manufacturing_order_id IN (". implode(",",$arr_mo_id).")";
$get_mo = $this->db->query($mo_where)->getResultArray();
$manufacturing_order=[];
foreach ($get_mo as $key => $value) {
$manufacturing_order[$value['id']] = $value;
}
switch ($mo_measures) {
case 'count':
$sql_where="SELECT count(id) as dashboard_re, manufacturing_order_id FROM ".db_prefix()."mrp_work_orders
where manufacturing_order_id IN (". implode(",",$arr_mo_id).")
group by manufacturing_order_id
";
$work_orders = $this->db->query($sql_where)->getResultArray();
break;
case 'duration_per_unit':
$sql_where="SELECT sum(real_duration)/sum(qty_producing) as dashboard_re, manufacturing_order_id FROM ".db_prefix()."mrp_work_orders
where manufacturing_order_id IN (". implode(",",$arr_mo_id).")
group by manufacturing_order_id
";
$work_orders = $this->db->query($sql_where)->getResultArray();
break;
case 'expected_duration':
$sql_where="SELECT sum(duration_expected) as dashboard_re, manufacturing_order_id FROM ".db_prefix()."mrp_work_orders
where manufacturing_order_id IN (". implode(",",$arr_mo_id).")
group by manufacturing_order_id
";
$work_orders = $this->db->query($sql_where)->getResultArray();
break;
case 'quantity':
$sql_where="SELECT sum(qty_producing) as dashboard_re, manufacturing_order_id FROM ".db_prefix()."mrp_work_orders
where manufacturing_order_id IN (". implode(",",$arr_mo_id).")
group by manufacturing_order_id
";
$work_orders = $this->db->query($sql_where)->getResultArray();
break;
case 'real_duration':
$sql_where="SELECT sum(real_duration) as dashboard_re, manufacturing_order_id FROM ".db_prefix()."mrp_work_orders
where manufacturing_order_id IN (". implode(",",$arr_mo_id).")
group by manufacturing_order_id
";
$work_orders = $this->db->query($sql_where)->getResultArray();
break;
}
foreach ($work_orders as $wo_key => $wo_value) {
$chart['categories'][] = isset($manufacturing_order[$wo_value['manufacturing_order_id']]) ? $manufacturing_order[$wo_value['manufacturing_order_id']]['manufacturing_order_code'] : '';
$chart['mo_data'][] = (float)$wo_value['dashboard_re'];
}
}
return $chart;
}
/**
* dasboard get work center
* @return [type]
*/
public function dasboard_get_work_center()
{
$work_center_data=[];
$work_order_data=[];
//get_work_centers
$work_centers = $this->get_work_centers();
//get list work order
$work_orders = $this->get_work_order();
foreach ($work_orders as $key => $value) {
if(strtotime($value['date_finished']) > strtotime($value['date_planned_finished'])){
if(isset($work_order_data[$value['work_center_id']]['late'])){
$work_order_data[$value['work_center_id']]['late'] += 1;
}else{
$work_order_data[$value['work_center_id']]['late'] = 1;
}
}
}
$get_wcenter_where = "SELECT count(id) as total, work_center_id, status FROM ".db_prefix()."mrp_work_orders
group by work_center_id, status
;";
$work_center_by_status = $this->db->query($get_wcenter_where)->getResultArray();
foreach ($work_center_by_status as $wo_c_key => $wo_c_value) {
switch ($wo_c_value['status']) {
case 'ready':
$work_order_data[$value['work_center_id']]['ready'] = $wo_c_value['total'];
break;
case 'in_progress':
$work_order_data[$value['work_center_id']]['in_progress'] = $wo_c_value['total'];
break;
}
}
foreach ($work_centers as $wo_key => $wo_value) {
if(isset($work_order_data[$wo_value['id']])){
$id = $wo_value['id'];
$work_center_code = $wo_value['work_center_code'];
$work_center_name = $wo_value['work_center_name'];
$ready = isset($work_order_data[$wo_value['id']]['ready']) ? $work_order_data[$wo_value['id']]['ready'] : 0;
$in_progress = isset($work_order_data[$wo_value['id']]['in_progress']) ? $work_order_data[$wo_value['id']]['in_progress'] : 0;
$late = isset($work_order_data[$wo_value['id']]['late']) ? $work_order_data[$wo_value['id']]['late'] : 0;
array_push($work_center_data, [
'ready' => $ready,
'in_progress' => $in_progress,
'late' => $late,
'work_center_code' => $work_center_code,
'work_center_name' => $work_center_name,
'id' => $id,
]);
}else{
$ready = 0;
$in_progress = 0;
$late = 0;
$work_center_code = $wo_value['work_center_code'];
$work_center_name = $wo_value['work_center_name'];
$id = $wo_value['id'];
array_push($work_center_data, [
'ready' => $ready,
'in_progress' => $in_progress,
'late' => $late,
'work_center_code' => $work_center_code,
'work_center_name' => $work_center_name,
'id' => $id,
]);
}
}
return $work_center_data;
}
/**
* update prefix number
* @param [type] $data
* @return [type]
*/
public function update_prefix_number($data)
{
$affected_rows=0;
foreach ($data as $key => $value) {
$builder = $this->db->table(get_db_prefix().'settings');
$builder->where('setting_name',$key);
$affected_row = $builder->update([
'setting_value' => $value,
]);
if ($affected_row > 0) {
$affected_rows++;
}
}
if($affected_rows > 0){
return true;
}else{
return false;
}
}
/**
* update variant product
* @param [type] $parent_id
* @param [type] $data
* @param [type] $variant
* @return [type]
*/
public function update_variant_product($parent_id, $variant)
{
$arr_item_active = [];
$arr_item_active[] = $parent_id;
//parent information
$data = (array)$this->get_product($parent_id);
unset($data['id']);
//get last product id
$sql_where = 'SELECT * FROM ' . get_db_prefix() . 'items order by id desc limit 1';
$res = $this->db->query($sql_where)->getRow();
$last_commodity_id = 0;
if (isset($res)) {
$last_commodity_id = $this->db->query($sql_where)->getRow()->id;
}
$next_commodity_id = (int) $last_commodity_id + 1;
$generate_variants = $this->variant_generator($variant);
$varirant_data=[];
$description = $data['title'];
foreach ($generate_variants as $_variant) {
$str_variant='';
if(count($variant) > 1){
foreach ($_variant as $value) {
if(strlen($str_variant) == 0){
$str_variant .= $value['option'];
}else{
$str_variant .= '-'.$value['option'];
}
}
}else{
if(strlen($str_variant) == 0){
$str_variant .= $_variant['option'];
}else{
$str_variant .= '-'.$_variant['option'];
}
}
$str_variant = str_replace(' ', '_', $str_variant);
$barcode_gen = mrp_generate_commodity_barcode();
//create sku code
$sku_code = str_pad($next_commodity_id,5,'0',STR_PAD_LEFT);
$next_commodity_id++;
$data['commodity_code'] = $sku_code;
$data['sku_code'] = $sku_code;
$data['commodity_barcode'] = $barcode_gen;
$data['commodity_code'] = $sku_code;
$data['sku_code'] = $sku_code;
$data['parent_id'] = $parent_id;
$data['parent_attributes'] = null;
if(count($variant) > 1){
$data['attributes'] = json_encode($_variant);
}else{
$data['attributes'] = json_encode(array($_variant));
}
$data['title'] = $description.' '. $str_variant;
//check if product exist, don't add
$builder = $this->db->table(get_db_prefix().'items');
$builder->where('parent_id', $parent_id);
$builder->where('attributes', $data['attributes']);
$child_product = $builder->get()->getRow();
if($child_product){
$arr_item_active[] = $child_product->id;
continue;
}
$varirant_data[] = $data;
}
//update inactive product
$builder = $this->db->table(get_db_prefix().'items');
$builder->where('parent_id', $parent_id);
$builder->where('id NOT IN ('.implode(",",$arr_item_active).')');
$builder->update(['deleted' => 1]);
//update active product, if exist old product current is inactive
$builder = $this->db->table(get_db_prefix().'items');
$builder->where('parent_id', $parent_id);
$builder->where('id IN ('.implode(",",$arr_item_active).')');
$builder->update(['deleted' => 0]);
//add new variant product
if(count($varirant_data) > 0){
$builder = $this->db->table(get_db_prefix().'items');
$affected_rows = $builder->insertBatch($varirant_data);
if($affected_rows > 0){
//copy_product_image
// get new product id
$arr_variant = [];
$builder = $this->db->table(get_db_prefix().'items');
$builder->where('parent_id', $parent_id);
$builder->where('id NOT IN ('.implode(",",$arr_item_active).')');
$new_product_variants = $builder->get()->getResultArray();
foreach ($new_product_variants as $product_variant) {
$arr_variant[] = ['id' => $product_variant['id']];
}
if(count($arr_variant) > 0){
$this->copy_product_image($parent_id, $arr_variant);
}
return true;
}
return false;
}
return false;
}
/**
* get manufacturing order costing
* @param [type] $id
* @return [type]
*/
public function get_manufacturing_order_costing($id)
{
$builder = $this->db->table(get_db_prefix().'mrp_manufacturing_order_details');
$builder->where('manufacturing_order_id', $id);
$manufacturing_order_details = $builder->get()->getResultArray();
$builder = $this->db->table(get_db_prefix().'mrp_manufacturing_orders');
$builder->where('id', $id);
$manufacturing_order = $builder->get()->getRow();
$arr_work_centers = [];
$get_work_centers = $this->get_work_centers();
foreach ($get_work_centers as $work_center) {
$arr_work_centers[$work_center['id']] = $work_center['costs_hour'];
}
$total_material_cost = 0;
$total_labour_cost = 0;
$total_work_center_cost = 0;
$total_employee_working_cost = 0;
foreach ($manufacturing_order_details as $key => $value) {
$item = $this->get_product($value['product_id']);
if($item){
$rate = $item->purchase_price*$value['qty_to_consume'];
$total_material_cost += $rate;
}
}
$builder = $this->db->table(get_db_prefix().'mrp_work_orders');
$builder->where('manufacturing_order_id', $id);
$work_orders = $builder->get()->getResultArray();
$total_hour = 0;
foreach ($work_orders as $key => $value) {
$total_hour += $value['real_duration'];
if(isset($arr_work_centers[$value['work_center_id']])){
$total_work_center_cost += ($value['real_duration']/60) * $arr_work_centers[$value['work_center_id']];
}
}
$costs_hour = get_setting('cost_hour');
if($costs_hour != ''){
$total_employee_working_cost = ($total_hour/60) * $costs_hour;
}
$total_labour_cost = $total_work_center_cost + $total_employee_working_cost;
return ['total_material_cost' => round($total_material_cost, 2),'total_labour_cost' => round($total_labour_cost, 2), 'total_work_center_cost' => round($total_work_center_cost, 2), 'total_employee_working_cost' => round($total_employee_working_cost, 2)];
}
/**
* check planned
* @param [type] $manufacturing_order_id
* @return [type]
*/
public function check_planned($manufacturing_order_id)
{
$check_planned = false;
$manufacturing_order = $this->get_manufacturing_order($manufacturing_order_id);
if($manufacturing_order){
}
return $check_planned;
}
/**
* get_file
* @param [type] $id
* @param boolean $rel_id
* @return [type]
*/
public function get_file($id, $rel_id = false) {
$builder = $this->db->table(get_db_prefix().'files');
$builder->where('id', $id);
$file = $builder->get()->getRow();
if ($file && $rel_id) {
if ($file->rel_id != $rel_id) {
return false;
}
}
return $file;
}
//end file
}