diff --git a/application/controllers/config.php b/application/controllers/config.php
index b0a447a47..a4dd320cd 100644
--- a/application/controllers/config.php
+++ b/application/controllers/config.php
@@ -145,6 +145,7 @@ class Config extends Secure_area
'barcode_num_in_row'=>$this->input->post('barcode_num_in_row'),
'barcode_page_width'=>$this->input->post('barcode_page_width'),
'barcode_page_cellspacing'=>$this->input->post('barcode_page_cellspacing'),
+ 'barcode_generate_if_empty'=>$this->input->post('barcode_generate_if_empty'),
'barcode_content'=>$this->input->post('barcode_content')
);
diff --git a/application/controllers/items.php b/application/controllers/items.php
index 98424e4c3..4113db5c7 100644
--- a/application/controllers/items.php
+++ b/application/controllers/items.php
@@ -332,21 +332,17 @@ class Items extends Secure_area implements iData_controller
$result = $this->Item->get_multiple_info($item_ids)->result_array();
$config = $this->barcode_lib->get_barcode_config();
- $data['items'] = $result;
$data['barcode_config'] = $config;
- // display barcodes
- $this->load->view("barcode_sheet", $data);
-
// check the list of items to see if any item_number field is empty
- foreach($result as $item)
+ foreach($result as &$item)
{
// update the UPC/EAN/ISBN field if empty / null with the newly generated barcode
- if ($item['item_number'] == '' || $item['item_number'] == null)
+ if (empty($item['item_number']) && $this->Appconfig->get('barcode_generate_if_empty'))
{
// get the newly generated barcode
- $item['item_number'] = $this->barcode_lib->get_new_barcode($item, $config);
-
+ $barcode_instance = Barcode_lib::barcode_instance($item, $config);
+ $item['item_number'] = $barcode_instance->getData();
// remove from item any suppliers table info to avoid save failure because of unknown fields
// WARNING: if suppliers table is changed this list needs to be upgraded, which makes the matter a bit tricky to maintain
unset($item['person_id']);
@@ -358,6 +354,10 @@ class Items extends Secure_area implements iData_controller
$this->Item->save($item, $item['item_id']);
}
}
+ $data['items'] = $result;
+ // display barcodes
+ $this->load->view("barcode_sheet", $data);
+
}
function bulk_edit()
@@ -497,7 +497,6 @@ class Items extends Secure_area implements iData_controller
function check_item_number()
{
$exists = $this->Item->item_number_exists($this->input->post('item_number'),$this->input->post('item_id'));
-
echo json_encode(array('success'=>!$exists,'message'=>$this->lang->line('items_item_number_duplicate')));
}
diff --git a/application/language/en/config_lang.php b/application/language/en/config_lang.php
index 63b5c8238..2ea009519 100644
--- a/application/language/en/config_lang.php
+++ b/application/language/en/config_lang.php
@@ -24,6 +24,7 @@ $lang["config_barcode_second_row"] = "Row 2";
$lang["config_barcode_third_row"] = "Row 3";
$lang["config_barcode_type"] = "Barcode Type";
$lang["config_barcode_width"] = "Width (px)";
+$lang["config_barcode_generate_if_empty"] = "Generate if empty";
$lang["config_company"] = "Company Name";
$lang["config_company_logo"] = "Company Logo";
$lang["config_company_required"] = "Company name is a required field";
diff --git a/application/language/es/config_lang.php b/application/language/es/config_lang.php
index 61a1a468c..2e892f6bc 100644
--- a/application/language/es/config_lang.php
+++ b/application/language/es/config_lang.php
@@ -24,6 +24,7 @@ $lang["config_barcode_second_row"] = "Fila 1";
$lang["config_barcode_third_row"] = "Fila 2";
$lang["config_barcode_type"] = "Tipo de Código de Barra";
$lang["config_barcode_width"] = "Ancho (px)";
+$lang["config_barcode_generate_if_empty"] = "Generate if empty";
$lang["config_company"] = "Nombre del Comercio";
$lang["config_company_logo"] = "Logotipo del Comercio";
$lang["config_company_required"] = "Nombre del Comercio es requerido";
diff --git a/application/language/fr/config_lang.php b/application/language/fr/config_lang.php
index f8c9549f6..d62a1ad3a 100644
--- a/application/language/fr/config_lang.php
+++ b/application/language/fr/config_lang.php
@@ -24,6 +24,7 @@ $lang["config_barcode_second_row"] = "Row 3";
$lang["config_barcode_third_row"] = "Row 4";
$lang["config_barcode_type"] = "Barcode Type";
$lang["config_barcode_width"] = "Width (px)";
+$lang["config_barcode_generate_if_empty"] = "Generate if empty";
$lang["config_company"] = "Nome de l\'Entreprise";
$lang["config_company_logo"] = "Company Logo";
$lang["config_company_required"] = "Le nom d\'entreprise est requis";
diff --git a/application/language/id/config_lang.php b/application/language/id/config_lang.php
index 7809a905a..4cccf147d 100644
--- a/application/language/id/config_lang.php
+++ b/application/language/id/config_lang.php
@@ -24,6 +24,7 @@ $lang["config_barcode_second_row"] = "Row 8";
$lang["config_barcode_third_row"] = "Row 9";
$lang["config_barcode_type"] = "Barcode Type";
$lang["config_barcode_width"] = "Width (px)";
+$lang["config_barcode_generate_if_empty"] = "Generate if empty";
$lang["config_company"] = "Nama Perusahaan";
$lang["config_company_logo"] = "Company Logo";
$lang["config_company_required"] = "Nama Perusahaan wajib diisi";
diff --git a/application/language/nl-BE/config_lang.php b/application/language/nl-BE/config_lang.php
index 8ea68a158..ea7601940 100755
--- a/application/language/nl-BE/config_lang.php
+++ b/application/language/nl-BE/config_lang.php
@@ -24,6 +24,7 @@ $lang["config_barcode_second_row"] = "Rij 2";
$lang["config_barcode_third_row"] = "Rij 3";
$lang["config_barcode_type"] = "Barcode Type";
$lang["config_barcode_width"] = "Breedte (px)";
+$lang["config_barcode_generate_if_empty"] = "Genereer indien leeg";
$lang["config_company"] = "Bedrijfsnaam";
$lang["config_company_logo"] = "Logo";
$lang["config_company_required"] = "De bedrijfsnaam moet ingevuld worden";
diff --git a/application/language/ru/config_lang.php b/application/language/ru/config_lang.php
index a864ecddb..fcb9c2ef2 100644
--- a/application/language/ru/config_lang.php
+++ b/application/language/ru/config_lang.php
@@ -24,6 +24,7 @@ $lang["config_barcode_second_row"] = "Row 5";
$lang["config_barcode_third_row"] = "Row 6";
$lang["config_barcode_type"] = "Barcode Type";
$lang["config_barcode_width"] = "Width (px)";
+$lang["config_barcode_generate_if_empty"] = "Generate if empty";
$lang["config_company"] = "Название Компании";
$lang["config_company_logo"] = "Company Logo";
$lang["config_company_required"] = "Имя Компании обязательный пробел";
diff --git a/application/language/th/config_lang.php b/application/language/th/config_lang.php
index aacfc5e57..e858e3e27 100644
--- a/application/language/th/config_lang.php
+++ b/application/language/th/config_lang.php
@@ -24,6 +24,7 @@ $lang["config_barcode_second_row"] = "แถว 2";
$lang["config_barcode_third_row"] = "แถว 3";
$lang["config_barcode_type"] = "ประเภทบาร์โค้ด";
$lang["config_barcode_width"] = "กว้าง (px)";
+$lang["config_barcode_generate_if_empty"] = "Generate if empty";
$lang["config_company"] = "ชื่อร้านค้า";
$lang["config_company_logo"] = "ภาพโลโก้";
$lang["config_company_required"] = "ชื่อร้านค้าต้องกรอก";
diff --git a/application/language/tr/config_lang.php b/application/language/tr/config_lang.php
index 5461becb2..dcd1ce2ba 100644
--- a/application/language/tr/config_lang.php
+++ b/application/language/tr/config_lang.php
@@ -24,6 +24,7 @@ $lang["config_barcode_second_row"] = "Row 7";
$lang["config_barcode_third_row"] = "Row 8";
$lang["config_barcode_type"] = "Barcode Type";
$lang["config_barcode_width"] = "Width (px)";
+$lang["config_barcode_generate_if_empty"] = "Generate if empty";
$lang["config_company"] = "Şirket Adı";
$lang["config_company_logo"] = "Company Logo";
$lang["config_company_required"] = "Şirket Adı zorunlu alandır";
diff --git a/application/language/zh/config_lang.php b/application/language/zh/config_lang.php
index bf69c26b5..08fa0d31f 100755
--- a/application/language/zh/config_lang.php
+++ b/application/language/zh/config_lang.php
@@ -24,6 +24,7 @@ $lang["config_barcode_second_row"] = "Row 4";
$lang["config_barcode_third_row"] = "Row 5";
$lang["config_barcode_type"] = "Barcode Type";
$lang["config_barcode_width"] = "Width (px)";
+$lang["config_barcode_generate_if_empty"] = "Generate if empty";
$lang["config_company"] = "公司名稱";
$lang["config_company_logo"] = "Company Logo";
$lang["config_company_required"] = "公司名稱為必填";
diff --git a/application/libraries/Barcode_lib.php b/application/libraries/Barcode_lib.php
index e0e5dcacc..8f60e29f9 100644
--- a/application/libraries/Barcode_lib.php
+++ b/application/libraries/Barcode_lib.php
@@ -38,11 +38,35 @@ class Barcode_lib
$data['barcode_num_in_row'] = $this->CI->Appconfig->get('barcode_num_in_row');
$data['barcode_page_width'] = $this->CI->Appconfig->get('barcode_page_width');
$data['barcode_page_cellspacing'] = $this->CI->Appconfig->get('barcode_page_cellspacing');
+ $data['barcode_generate_if_empty'] = $this->CI->Appconfig->get('barcode_generate_if_empty');
return $data;
}
-
- private function get_barcode_instance($barcode_type='Code128')
+
+ public function validate_barcode($barcode)
+ {
+ $barcode_type = $this->CI->Appconfig->get('barcode_type');
+ $barcode_instance = $this->get_barcode_instance($barcode_type);
+ return $barcode_instance->validate($barcode);
+ }
+
+ public static function barcode_instance($item, $barcode_config)
+ {
+ $barcode_instance = Barcode_lib::get_barcode_instance($barcode_config['barcode_type']);
+ $is_valid = empty($item['item_number']) && $barcode_config['barcode_generate_if_empty'] || $barcode_instance->validate($item['item_number']);
+
+ // if barcode validation does not succeed,
+ if (!$is_valid)
+ {
+ $barcode_instance = Barcode_lib::get_barcode_instance();
+ }
+ $seed = Barcode_lib::barcode_seed($item, $barcode_instance, $barcode_config);
+ $barcode_instance->setData($seed);
+
+ return $barcode_instance;
+ }
+
+ private static function get_barcode_instance($barcode_type='Code128')
{
switch($barcode_type)
{
@@ -64,36 +88,41 @@ class Barcode_lib
break;
}
}
-
+
+ private static function barcode_seed($item, $barcode_instance, $barcode_config)
+ {
+ $seed = $barcode_config['barcode_content'] !== "id" && isset($item['item_number']) ? $item['item_number'] : $item['item_id'];
+
+ if( $barcode_config['barcode_content'] !== "id" && !empty($item['item_number']))
+ {
+ $seed = $item['item_number'];
+ }
+ else
+ {
+ if ($barcode_config['barcode_generate_if_empty'])
+ {
+ // generate barcode with the correct instance
+ $seed = $barcode_instance->generate($seed);
+ }
+ else
+ {
+ $seed = $item['item_id'];
+ }
+ }
+ return $seed;
+ }
+
private function generate_barcode($item, $barcode_config)
{
try
{
- $barcode = $this->get_barcode_instance($barcode_config['barcode_type']);
- $is_valid = $barcode->validate($item['item_number']);
+ $barcode_instance = Barcode_lib::barcode_instance($item, $barcode_config);
+ $barcode_instance->setQuality($barcode_config['barcode_quality']);
+ $barcode_instance->setDimensions($barcode_config['barcode_width'], $barcode_config['barcode_height']);
- // if barcdoe validation does not succeed, then fallback to the default, which should not require specific formatting
- if (!$is_valid)
- {
- $barcode = $this->get_barcode_instance();
- }
-
- $barcode_content = $barcode_config['barcode_content'] !== "id" && isset($item['item_number']) ? $item['item_number'] : $item['item_id'];
- $barcode->setData($barcode_content);
- if( $barcode_config['barcode_content'] !== "id" && isset($item['item_number']))
- {
- $barcode->setData($item['item_number']);
- }
- else
- {
- $barcode->setData($item['item_id']);
- }
- $barcode->setQuality($barcode_config['barcode_quality']);
- $barcode->setDimensions($barcode_config['barcode_width'], $barcode_config['barcode_height']);
-
- $barcode->draw();
+ $barcode_instance->draw();
- return $barcode->base64();
+ return $barcode_instance->base64();
}
catch(Exception $e)
{
@@ -128,42 +157,7 @@ class Barcode_lib
}
}
- public function get_new_barcode($item, $barcode_config)
- {
- try
- {
- $barcode = $this->get_barcode_instance($barcode_config['barcode_type']);
-
- // generate a barcode only if one is not already available and we use the item_id as seed.
- // This to avoid generating Barcodes out of existing Barcodes
- if( $barcode_config['barcode_content'] !== "id" && isset($item['item_number']) )
- {
- $barcode->setData($item['item_number'], false);
-
- return null;
- }
- else
- {
- $barcode->setData($item['item_id'], true);
-
- $code = $barcode->getData();
-
- // in case no new code is generated like in Code39 and Code128 return an empty string because we don't want to override it with a pure item_id
- if( $code == $item['item_id'] )
- {
- $code = null;
- }
-
- return $code;
- }
- }
- catch(Exception $e)
- {
- echo 'Caught exception: ', $e->getMessage(), "\n";
- }
- }
-
- public function create_display_barcode($item, $barcode_config)
+ public function display_barcode($item, $barcode_config)
{
$display_table = "
";
$display_table .= "| " . $this->manage_display_layout($barcode_config['barcode_first_row'], $item, $barcode_config) . " |
";
diff --git a/application/views/barcode_sheet.php b/application/views/barcode_sheet.php
index 7c636e627..6f4cb4cbc 100644
--- a/application/views/barcode_sheet.php
+++ b/application/views/barcode_sheet.php
@@ -16,7 +16,7 @@
barcode_lib->get_font_name($barcode_config['barcode_font']); ?>
style="font-size:px">
- width= >
+ width='' >
';
}
- echo "| " . $this->barcode_lib->create_display_barcode($item, $barcode_config) . " | ";
+ echo "" . $this->barcode_lib->display_barcode($item, $barcode_config) . " | ";
$count++;
}
?>
diff --git a/application/views/barcodes/BarcodeBase.php b/application/views/barcodes/BarcodeBase.php
index 93f7bbc21..b96b565aa 100644
--- a/application/views/barcodes/BarcodeBase.php
+++ b/application/views/barcodes/BarcodeBase.php
@@ -84,6 +84,18 @@ abstract class BarcodeBase
{
return TRUE;
}
+
+ /**
+ * Generate a barcode for this implementation using the given seed.
+ * Default implementation returns just the seed
+ * @param $number The seed to generate a barcode for
+ * @return mixed The generated barcode
+ */
+ public function generate($number)
+ {
+ return $number;
+ }
+
/*
* (Abstract) Draw the image
*
diff --git a/application/views/barcodes/Ean13.php b/application/views/barcodes/Ean13.php
index 9b30f8dd6..e2e52d5cb 100644
--- a/application/views/barcodes/Ean13.php
+++ b/application/views/barcodes/Ean13.php
@@ -127,6 +127,32 @@ class Ean13 extends BarcodeBase
$this->data = $data;
}
+ /*
+ * Generate EAN13 code out of a provided number
+ * Code taken from http://stackoverflow.com/questions/19890144/generate-valid-ean13-in-php (unknown copyright / license claims)
+ *
+ * @param number is the internal code you want to have EANed. The prefix, zero-padding and checksum are added by the function.
+ * @return string with complete EAN13 code
+ */
+ public function generate($number)
+ {
+ $number = '200' . str_pad($number, 9, '0');
+ $weightflag = true;
+ $sum = 0;
+
+ // Weight for a digit in the checksum is 3, 1, 3.. starting from the last digit.
+ // loop backwards to make the loop length-agnostic. The same basic functionality
+ // will work for codes of different lengths.
+ for ($i = strlen($number) - 1; $i >= 0; $i--)
+ {
+ $sum += (int)$number[$i] * ($weightflag?3:1);
+ $weightflag = !$weightflag;
+ }
+ $number .= (10 - ($sum % 10)) % 10;
+
+ return $number;
+ }
+
public function validate($barcode)
{
// check to see if barcode is 13 digits long
diff --git a/application/views/barcodes/Ean8.php b/application/views/barcodes/Ean8.php
index c3cdf542c..2f129d567 100644
--- a/application/views/barcodes/Ean8.php
+++ b/application/views/barcodes/Ean8.php
@@ -89,12 +89,76 @@ class Ean8 extends BarcodeBase
)
);
+ /*
+ * Calculate EAN8 or EAN13 automatically
+ * set $len = 8 for EAN8, $len = 13 for EAN13
+ *
+ * @param number is the internal code you want to have EANed. The prefix, zero-padding and checksum are added by the function.
+ * @return string with complete EAN code
+ */
+ public function generate($number, $len = 8)
+ {
+ $barcode = $number;
+
+ if($number > -1)
+ {
+ $data_len = $len - 1;
+
+ //Padding
+ $barcode = str_pad($barcode, $data_len, '0', STR_PAD_LEFT);
+ $barcode_len = strlen($barcode);
+
+ // calculate check digit
+ $sum_a = 0;
+ for ($i = 1; $i < $data_len; $i += 2)
+ {
+ $sum_a += $barcode{$i};
+ }
+
+ if ($len > 12)
+ {
+ $sum_a *= 3;
+ }
+
+ $sum_b = 0;
+ for ($i = 0; $i < $data_len; $i += 2)
+ {
+ $sum_b += ($barcode{$i});
+ }
+
+ if ($len < 13)
+ {
+ $sum_b *= 3;
+ }
+
+ $r = ($sum_a + $sum_b) % 10;
+
+ if($r > 0)
+ {
+ $r = (10 - $r);
+ }
+
+ if (strlen($barcode) == $data_len)
+ {
+ // add check digit
+ $barcode .= $r;
+ }
+ elseif ($r !== intval($barcode{$data_len}))
+ {
+ // wrong checkdigit
+ $barcode = null;
+ }
+ }
+
+ return $barcode;
+ }
+
public function validate($barcode)
{
$ean = str_replace(array("-","/"," ","\t","\n"), "", $barcode); // make a clean ean
$len = strlen($ean);
- if( !is_numeric($ean) )
+ if( !is_numeric($ean) || strlen($barcode) != 8 )
{
return false;
}
diff --git a/application/views/configs/barcode_config.php b/application/views/configs/barcode_config.php
index f80738966..a6337b8d6 100644
--- a/application/views/configs/barcode_config.php
+++ b/application/views/configs/barcode_config.php
@@ -86,6 +86,11 @@ echo form_open('config/save_barcode/',array('id'=>'barcode_config_form'));
'value'=>'number',
'checked'=>$this->config->item('barcode_content') === "number")); ?>
lang->line('config_barcode_number'); ?>
+ 'barcode_generate_if_empty',
+ 'value'=>'barcode_generate_if_empty',
+ 'checked'=>$this->config->item('barcode_generate_if_empty'))); ?>
+ lang->line('config_barcode_generate_if_empty'); ?>
diff --git a/database/2.3.2_to_2.3.3.sql b/database/2.3.2_to_2.3.3.sql
index 5d6fa1109..045f35359 100644
--- a/database/2.3.2_to_2.3.3.sql
+++ b/database/2.3.2_to_2.3.3.sql
@@ -3,7 +3,8 @@ ALTER TABLE `ospos_suppliers`
INSERT INTO `ospos_app_config` (`key`, `value`) VALUES
('dateformat', 'm/d/Y'),
- ('timeformat', 'H:i:s');
+ ('timeformat', 'H:i:s'),
+ ('barcode_generate_if_empty', '0');
ALTER TABLE `ospos_sales_suspended`
DROP KEY `invoice_number`;
diff --git a/database/database.sql b/database/database.sql
index 8b86e43e4..e528b2fca 100644
--- a/database/database.sql
+++ b/database/database.sql
@@ -55,6 +55,7 @@ INSERT INTO `ospos_app_config` (`key`, `value`) VALUES
('barcode_num_in_row', '2'),
('barcode_page_width', '100'),
('barcode_page_cellspacing', '20'),
+('barcode_generate_if_empty', '0'),
('receipt_show_taxes', '0'),
('use_invoice_template', '1'),
('invoice_email_message', 'Dear $CU, In attachment the receipt for sale $INV'),
diff --git a/translations/config_lang.csv b/translations/config_lang.csv
index fa82950a8..b712e53eb 100644
--- a/translations/config_lang.csv
+++ b/translations/config_lang.csv
@@ -23,6 +23,7 @@ config_barcode_second_row,Rij 2,Fila 1,Row 2,Row 3,Row 4,Row 5,แถว 2,Row 7
config_barcode_third_row,Rij 3,Fila 2,Row 3,Row 4,Row 5,Row 6,แถว 3,Row 8,Row 9
config_barcode_type,Barcode Type,Tipo de Código de Barra,Barcode Type,Barcode Type,Barcode Type,Barcode Type,ประเภทบาร์โค้ด,Barcode Type,Barcode Type
config_barcode_width,Breedte (px),Ancho (px),Width (px),Width (px),Width (px),Width (px),กว้าง (px),Width (px),Width (px)
+config_barcode_generate_if_empty,Genereer indien leeg,Generate if empty,Generate if empty,Generate if empty,Generate if empty,Generate if empty,Generate if empty,Generate if empty,Generate if empty
config_company,Bedrijfsnaam,Nombre del Comercio,Company Name,Nome de l\'Entreprise,公司名稱,Название Компании,ชื่อร้านค้า,Şirket Adı,Nama Perusahaan
config_company_logo,Logo,Logotipo del Comercio,Company Logo,Company Logo,Company Logo,Company Logo,ภาพโลโก้,Company Logo,Company Logo
config_company_required,De bedrijfsnaam moet ingevuld worden,Nombre del Comercio es requerido,Company name is a required field,Le nom d\'entreprise est requis,公司名稱為必填,Имя Компании обязательный пробел,ชื่อร้านค้าต้องกรอก,Şirket Adı zorunlu alandır,Nama Perusahaan wajib diisi