Implemented automatic price calculation of items from std. cost.
authorJoe Hunt <joe.hunt.consulting@gmail.com>
Mon, 29 Jun 2009 22:47:26 +0000 (22:47 +0000)
committerJoe Hunt <joe.hunt.consulting@gmail.com>
Mon, 29 Jun 2009 22:47:26 +0000 (22:47 +0000)
CHANGELOG.txt
admin/company_preferences.php
admin/db/company_db.inc
doc/calculate_price.txt [new file with mode: 0644]
sales/includes/sales_db.inc
sql/alter2.2.sql

index 7a11e3c777a4fb1584cbf93c652f617284fbdfaf..57f41d680e1b4aef4aebb4f019a5d727f3cb8e00 100644 (file)
@@ -19,6 +19,14 @@ Legend:
 ! -> Note
 $ -> Affected files
 
+30-Jun-2009 Joe Hunt
++ Implemented automatic price calculation of items from std. cost.
+$ /admin/company_preferences.php
+  /admin/db/company_db.inc
+  /doc/calculate_price.txt (new file)
+  /sales/includes/sales_db.inc
+  /sql/alter2.2.sql
+  
 29-Jun-2009 Joe Hunt
 ! Small layout improments in Customer Payments
 $ /sales/customer_payments.php
index 124d361a884a5912c3c8c0ce6574c1686a9b2aeb..3bd7d05e85487bc9d365697e93d3347d1d1dc351 100644 (file)
@@ -94,6 +94,8 @@ if (isset($_POST['update']) && $_POST['update'] != "")
                                $_POST['coy_logo'] = "";
                }
        }
+       if ($_POST['add_pct'] == "")
+               $_POST['add_pct'] = -1;
        if ($input_error != 1)
        {
                update_company_setup($_POST['coy_name'], $_POST['coy_no'], 
@@ -102,7 +104,7 @@ if (isset($_POST['update']) && $_POST['update'] != "")
                        $_POST['email'], $_POST['coy_logo'], $_POST['domicile'],
                        $_POST['use_dimension'], $_POST['curr_default'], $_POST['f_year'], 
                        check_value('no_item_list'), check_value('no_customer_list'), 
-                       check_value('no_supplier_list'), $_POST['base_sales'], check_value('time_zone'));
+                       check_value('no_supplier_list'), $_POST['base_sales'], check_value('time_zone'), $_POST['add_pct'], $_POST['round_to']);
 
                display_notification_centered(_("Company setup has been updated."));
        }
@@ -136,6 +138,10 @@ $_POST['curr_default']  = $myrow["curr_default"];
 $_POST['f_year']  = $myrow["f_year"];
 $_POST['time_zone']  = $myrow["time_zone"];
 $_POST['version_id']  = $myrow["version_id"];
+$_POST['add_pct'] = $myrow['add_pct'];
+if ($_POST['add_pct'] == -1)
+       $_POST['add_pct'] = "";
+$_POST['round_to'] = $myrow['round_to'];       
 $_POST['del_coy_logo']  = 0;
 
 start_outer_table($table_style2);
@@ -144,6 +150,7 @@ table_section(1);
 
 text_row_ex(_("Name (to appear on reports):"), 'coy_name', 42, 50);
 textarea_row(_("Address:"), 'postal_address', $_POST['postal_address'], 35, 6);
+text_row_ex(_("Domicile:"), 'domicile', 25, 55);
 
 text_row_ex(_("Phone Number:"), 'phone', 25, 55);
 text_row_ex(_("Fax Number:"), 'fax', 25);
@@ -163,11 +170,13 @@ text_row_ex(_("Tax Last Period:"), 'tax_last', 10, 10, '', null, null, _('Months
 label_row(_("Company Logo:"), $_POST['coy_logo']);
 label_row(_("New Company Logo (.jpg)") . ":", "<input type='file' id='pic' name='pic'>");
 check_row(_("Delete Company Logo:"), 'del_coy_logo', $_POST['del_coy_logo']);
-text_row_ex(_("Domicile:"), 'domicile', 25, 55);
 
 number_list_row(_("Use Dimensions:"), 'use_dimension', null, 0, 2);
 sales_types_list_row(_("Base for auto price calculations:"), 'base_sales', $_POST['base_sales'], false,
     _('No base price list') );
+text_row_ex(_("Add Price from Std Cost:"), 'add_pct', 10, 10, '', null, null, "%");
+$curr = get_currency($_POST['curr_default']);
+text_row_ex(_("Round to nearest:"), 'round_to', 10, 10, '', null, null, $curr['hundreds_name']);
 
 check_row(_("Search Item List"), 'no_item_list', null);
 check_row(_("Search Customer List"), 'no_customer_list', null);
index 1bb58326d8bacbdefedb7afb4ff14af08bc25b2d..ed2b18f1356ae1653d1e319a7bf21d89160bbc04 100644 (file)
@@ -66,7 +66,7 @@ function update_company_gl_setup($retained_act, $profit_loss_act, $debtors_act,
 function update_company_setup($coy_name, $coy_no, $gst_no, $tax_prd, $tax_last, 
        $postal_address, $phone, $fax, $email, $coy_logo, $domicile, $Dimension, 
        $curr_default, $f_year, $no_item_list, $no_customer_list, $no_supplier_list, 
-       $base_sales, $time_zone)
+       $base_sales, $time_zone, $add_pct, $round_to)
 {
        if ($f_year == null)
                $f_year = 0;
@@ -87,7 +87,9 @@ function update_company_setup($coy_name, $coy_no, $gst_no, $tax_prd, $tax_last,
                curr_default=".db_escape($curr_default).",
                f_year=$f_year,
                base_sales=$base_sales,
-               time_zone=$time_zone
+               time_zone=$time_zone,
+               add_pct=$add_pct,
+               round_to=$round_to
                WHERE coy_code=1";
 
        db_query($sql, "The company setup could not be updated ");
diff --git a/doc/calculate_price.txt b/doc/calculate_price.txt
new file mode 100644 (file)
index 0000000..dd1c8e3
--- /dev/null
@@ -0,0 +1,46 @@
+Calculate sales price from standard cost
+----------------------------------------
+
+You can have automatic sales price calculation from items that do not have any prices in Sales Prices entered. This works
+independently from Base Price factor, but if Base Price is set it works together with it.
+
+Preparing and operation
+-----------------------
+
+Go into Setup tab - Company Setup.
+
+In the field, Add Price from Std cost, enter the % that you want to increase from the average standard costs for the items not.
+listed in the Item Price List. If this value is empty there are no automatic price calculations. BE aware that an increase value of 0 will 
+calculate the price to be the same as the Std cost. So to remove the calculation, just empty the field. It will then get an internal value of -1.
+If the average standard costs is 0, the calculation would result in 0 as well.
+
+The field, Round to nearest xxx Cents, will round the calculated result to the nearest Cent entered. If you have 2 decimals in the amounts
+the value 100 would be divided by the xxx value. If you have 3 dicimans in the amounts the value 1000 will be divided by the xxx value.
+If there is no fraction, the value will be rounded up to the nearest xxx value. If there is a fraction, the value xxx will be subtracted from
+the value (100-xxx) or (1000-xxx).
+
+Let us take an example:
+----------------------
+
+Item standard cost = 20.77
+Decimals = 2
+Value to increase the items with = 70 (%)
+Round to nearest value = 5
+
+the pow(10, 2) = 100. 100 divided by 5 = 20 and no fraction. Price after increase = 20.77 * (1 + 70 / 100) = 35.309.
+Rounded to nearest 5 cent value = 35.35;
+
+Let us set the Round to nearest value = 95.
+
+The value 100 / 95 = 1 and a fraction of 95. The Price will still be calculated to 35.309. Now the value will be rounded to 36.00 
+and subtracted by (100 - 95) = 35.95.
+
+So you see it is very flexible. If you have larger prices you can even round up to nearest 10, 100 by setting the rounding to 
+nearest value = 1000 or 10000. But take care if you have different prices, large prices and small prices. It might not be a good idea to 
+round a value of 10.77 to 100.
+
+If there is a base price list set and for instance a factor 0.7 the price list in foreign currencies are calculated as well.
+And again, if a 'Round to nearest' value is set to other than 1 the foreign prices are rounded in the same way as explained above.
+
+This new price calculaton should work with sales kits too.
+
index 1eb5e9060371c40d786d7897e9e09acab4e8c173..638fa83fea2deaff61aaadc31e4f02a2efb3018b 100644 (file)
@@ -57,6 +57,31 @@ function add_gl_trans_customer($type, $type_no, $date_, $account, $dimension, $d
 
 //----------------------------------------------------------------------------------------
 
+function get_calculated_price($stock_id, $add_pct)
+{
+       $avg = get_standard_cost($stock_id);
+       if ($avg == 0)
+               return 0;
+       return round2($avg * (1 + $add_pct / 100), user_price_dec());
+}
+
+function round_to_nearest($price, $round_to)
+{
+       if ($price == 0)
+               return 0;
+       $pow = pow(10, user_price_dec());
+       if ($pow >= $round_to)
+               $mod = ($pow % $round_to);
+       else
+               $mod = ($round_to % $pow);
+       if ($mod != 0)
+               $price = ceil($price) - ($pow - $round_to) / $pow;
+       else    
+       $price = ceil($price * ($pow / $round_to)) / ($pow / $round_to);
+    return $price;
+
+}
+
 function get_price ($stock_id, $currency, $sales_type_id, $factor=null, $date=null)
 {
        if ($date == null)
@@ -77,18 +102,26 @@ function get_price ($stock_id, $currency, $sales_type_id, $factor=null, $date=nu
        $msg = "There was a problem retrieving the pricing information for the part $stock_id for customer";
        $result = db_query($sql, $msg);
 
+       $add_pct = get_company_pref('add_pct');
+       $round_to = get_company_pref('round_to');
+    $home_curr = get_company_currency();
+
        if (db_num_rows($result) != 0) 
        {
                $myrow = db_fetch_row($result);
                return $myrow[0];
        }
+       elseif ($add_pct != -1)
+       {
+               $price = get_calculated_price($stock_id, $add_pct);
+               if ($currency == $home_curr)
+                       return round_to_nearest($price, $round_to);
+       }               
        if ($factor == 0) return false; // auto price calculations off
 
        $base_id = get_base_sales_type();
        if ($base_id <= 0) return 0; // auto price calculations off
        
-    $home_curr = get_company_currency();
-
     // get all prices which we can use to guess the price.
     // alternative is make up to 2 additional sql queries
        $sql = "SELECT price, curr_abrev, sales_type_id
@@ -106,11 +139,18 @@ function get_price ($stock_id, $currency, $sales_type_id, $factor=null, $date=nu
        {
            $prices[$myrow['sales_type_id']][$myrow['curr_abrev']] = $myrow['price'];
        }
-       
        $rate = round(get_exchange_rate_from_home_currency($currency, $date),
            user_exrate_dec());
-       $price = false;
+       if (db_num_rows($result) == 0 && $add_pct != -1)
+       {
+               if ($factor != 0)
+               $price = $price * $factor / $rate;
+           else
+               $price /= $rate;
+               return round_to_nearest($price, $round_to);
+       }
        
+       $price = false;
        if (isset($prices[$sales_type_id][$home_curr])) 
        {
            $price = $prices[$sales_type_id][$home_curr] / $rate;
@@ -123,8 +163,12 @@ function get_price ($stock_id, $currency, $sales_type_id, $factor=null, $date=nu
        {
            $price = $prices[$base_id][$home_curr] * $factor / $rate;
        }
-       
-       return $price === false ? false : round($price, user_price_dec());
+       if ($price === false)
+               return false;
+       else if ($round_to != 1)        
+               return round_to_nearest($price, $round_to);
+       else
+               return round2($price, user_price_dec());
 }
 //----------------------------------------------------------------------------------------
 //
index ff6a0ad1b4717719b2c02fe2e900d2c78bffc5cf..f99abc0bc42ab979372937077b99c5d701c4a7f4 100644 (file)
@@ -10,6 +10,8 @@ ALTER TABLE `0_company` ADD COLUMN `version_id` VARCHAR(11) NOT NULL DEFAULT '';
 ALTER TABLE `0_company` DROP COLUMN `purch_exchange_diff_act`;
 ALTER TABLE `0_company` ADD COLUMN`profit_loss_year_act` VARCHAR(11) NOT NULL DEFAULT '' AFTER `exchange_diff_act`;
 ALTER TABLE `0_company` ADD COLUMN `time_zone` TINYINT(1) NOT NULL DEFAULT '0';
+ALTER TABLE `0_company` ADD COLUMN `add_pct` INT(5) NOT NULL DEFAULT '-1';
+ALTER TABLE `0_company` ADD COLUMN `round_to` INT(5) NOT NULL DEFAULT '1';
 ALTER TABLE `0_company` CHANGE `grn_act` `bank_charge_act` VARCHAR(11) NOT NULL DEFAULT '';
 #INSERT INTO `0_chart_master` VALUES ('9990', '', 'Profit and Loss this year', '52', '0');
 UPDATE `0_company` SET `profit_loss_year_act`='9990', `version_id`='2.2' WHERE `coy_code`=1;