Sfoglia il codice sorgente

Fixes to work with the latest changes to SquiLu

mingodad 9 anni fa
parent
commit
c748e45f48

+ 6 - 1
SquiLu-ourbiz/calendar-utils.nut

@@ -151,7 +151,7 @@ class CalendarBase {
 					}
 				break;
 				case 3:
-					if (nums[1] > 31){
+					if (nums[0] > 31){
 						//year and month and day
 						setYear(0);
 						setMonth(1);
@@ -220,10 +220,12 @@ class CalendarBase {
 		return (tzh + tzm) * 3600;
 	}
 
+	//month 0 - 11
 	function makemonth(y,m){
 		local month_array = [];
  		local atime = os.time({year=y,month=m,day=1});
 		local adate = os.date("*t", atime);
+		//print("makemonth", y, m, adate.year, adate.month, adate.day);
 		// get back to the nearest monday
 		atime -= _seconds_in_day * adate.wday;
 		adate = os.date("*t", atime);
@@ -232,6 +234,8 @@ class CalendarBase {
 			atime -=  _seconds_in_week;
 			adate = os.date("*t", atime);
 		}
+		local count_weeks = 0;
+		//print("makemonth", adate.year, adate.month, adate.day);
 		do
 		{
 			local week_array = [];
@@ -239,6 +243,7 @@ class CalendarBase {
 			do
 			{
 				// insert the week days
+				//print(adate.day);
 				week_array.push(adate.day);
 				atime += _seconds_in_day;
 				adate = os.date("*t", atime);

+ 12 - 0
SquiLu-ourbiz/companies-uk.nut

@@ -78,6 +78,7 @@ local function getCiaUkSearchList(search_str, search_post_code, search_sic_code,
 		local sic_codes_sql = "";
 		local sic_code = null;
 		local cached_stmt_name = "";
+		local name_sql_base = "";
 		local radius_sql_base = [==[
 %s, post_codes pc, post_codes ref
 where  ref.post_code = :post_code
@@ -88,6 +89,17 @@ and c.post_code = pc.post_code
 %s
 limit :limit offset :offset
 ]==];
+/*
+		base_sql = base_sql.replace(" from ", [==[
+, round(distance(ref.easting, ref.northing, pc.easting, pc.northing)) as distance,
+	ifnull(round(bearing(ref.easting, ref.northing, pc.easting, pc.northing)), 0) as bearing
+from 
+]==]);
+		if(strHasContent(search_str))
+		{
+			name_sql_base = ""
+		}
+*/
 		if (strHasContent(search_sic_code)){
 
 			if (search_sic_code.find_lua("%d+") == 0){

+ 8 - 4
SquiLu-ourbiz/db-updater.nut

@@ -14,7 +14,7 @@ class DBTableUpdateBase {
 	table_name = null;
 	_field_changes = null;
 	edit_id = null;
-	version = null;
+	version = 0;
 	_dbChanges = null;
 	dbAction = null;
 	hasVersion = null;
@@ -98,7 +98,6 @@ class DBTableUpdateBase {
 		local httpRequest = HTTPConn(my_result);
 		local appServer = AppServer.getAppServer();
 		appServer.httpcon_setup(httpRequest);
-
 		local httpBody = blob(0, 8192);
 		local url = "/DB/Action";
 		get_http_params(httpBody);
@@ -154,7 +153,7 @@ class DBTableUpdateBase {
 		{
 			version = 0;
 			local rec = {};
-			appServer.asle2map(my_result, rec);
+			appServer.sle2map(my_result, rec);
 			local new_id = table_rawget(rec, "id", 0).tointeger();
 			if(new_id == 0) throw("Could not update this record !");
 			edit_id = new_id;
@@ -198,7 +197,11 @@ class DBTableUpdateBase {
 		return lastParam;
 	}
 
-	function get_db(){return null;}
+	function get_db()
+	{
+		throw("DBTableUpdateBase:get_db no override for get_db");
+		return null;
+	}
 
 	function bind_field(stmt, pos, field, value){
 		local val = value.tostring();
@@ -229,6 +232,7 @@ class DBTableUpdateBase {
 		    sql += sql2;
 
 		    //printf("%s\n", sql.c_str());
+		    fl_alert(sql);
 
 		    local stmt = db.preapre(sql);
 		    for(local i=0; i<nchanges; ++i)

+ 75 - 75
SquiLu-ourbiz/help.txt

@@ -1,76 +1,76 @@
-Ourbiz 
-===
-Ourbiz is an excelent application to manage a small business, yet simple and powerfull !
-
-[Help](db:/help)
----
-Help: using this screen you can consult any existing help topic and edit then to help you make a better use of this application.
-
-Terminology
----
-Some terminology used on this application that will help you understand and use it better:
-
-- Entity : we call an entity any person/company that we have a commercial relation with.
-
-Tips
------
-On any tabular list you can use the keys CTRL+numeric(+) and CTRL+numeric(-) to increse or decrease the font size.
-
-Sales Products List/Search
----
-On this screen we can navigate through all existing sales products with an easy to use search capability.
-
-Edit Products
----
-When we need to edit an existing product or add a new one this form is the place to do it.
-
-Sales Entities List/Search
----
-On this screen we can navigate through all existing sales entities with an easy to use search capability.
-
-Edit Entity
----
-When we need to edit an existing entity or add a new one this form is the place to do it.
-
-Sales Orders List/Search
----
-Here is where we register the sales transactions we do with entities and our products/services.
-
-Buys Orders List/Search
----
-This is the same for the sales transactions but only applied to buy transactions.
-
-Edit Order / Sales Order Edit / Buy Order Edit
----
-All transactions are registered on this screen.
-
-Delivery Calc
----
-This is a complement to help calc delivery costs for an order.
-
-Calendar
----
-To make easy to enter dates we use this screen.
-
-Auxiliar information
-====
-
-V.A.T. Rates List / Edit
----
-The information about sales tax are here.
-
-Order Types List / Edit
----
-All transactions availlable are described here with option to add new ones as needed.
-
-Images List / Edit
----
-Images used though the application are centrally managed here.
-
-Product Groups List/Edit
----
-To group our products for any purpose we create the groups here.
-
-Entity Groups List/Edit
----
+Ourbiz 
+===
+Ourbiz is an excelent application to manage a small business, yet simple and powerfull !
+
+[Help](db:/help)
+---
+Help: using this screen you can consult any existing help topic and edit then to help you make a better use of this application.
+
+Terminology
+---
+Some terminology used on this application that will help you understand and use it better:
+
+- Entity : we call an entity any person/company that we have a commercial relation with.
+
+Tips
+-----
+On any tabular list you can use the keys CTRL+numeric(+) and CTRL+numeric(-) to increse or decrease the font size.
+
+Sales Products List/Search
+---
+On this screen we can navigate through all existing sales products with an easy to use search capability.
+
+Edit Products
+---
+When we need to edit an existing product or add a new one this form is the place to do it.
+
+Sales Entities List/Search
+---
+On this screen we can navigate through all existing sales entities with an easy to use search capability.
+
+Edit Entity
+---
+When we need to edit an existing entity or add a new one this form is the place to do it.
+
+Sales Orders List/Search
+---
+Here is where we register the sales transactions we do with entities and our products/services.
+
+Buys Orders List/Search
+---
+This is the same for the sales transactions but only applied to buy transactions.
+
+Edit Order / Sales Order Edit / Buy Order Edit
+---
+All transactions are registered on this screen.
+
+Delivery Calc
+---
+This is a complement to help calc delivery costs for an order.
+
+Calendar
+---
+To make easy to enter dates we use this screen.
+
+Auxiliar information
+====
+
+V.A.T. Rates List / Edit
+---
+The information about sales tax are here.
+
+Order Types List / Edit
+---
+All transactions availlable are described here with option to add new ones as needed.
+
+Images List / Edit
+---
+Images used though the application are centrally managed here.
+
+Product Groups List/Edit
+---
+To group our products for any purpose we create the groups here.
+
+Entity Groups List/Edit
+---
 Also to group our entities we create the groups here.

+ 2 - 2
SquiLu-ourbiz/ourbiz-client.nut

@@ -372,7 +372,7 @@ class AppServer
 
     function get_binary_data_from_url(get_url, rec, content_type, throwNotFound=true)
     {
-        table_clear(rec);
+        rec.clear();
 
         if(get_conn_type() == conn_type_e.e_conn_http)
         {
@@ -391,7 +391,7 @@ class AppServer
 
     function get_binary_data(rec, binary_type, table, aid, extra_url=0, throwNotFound=true)
     {
-        table_clear(rec);
+        rec.clear();
         if(get_conn_type() == conn_type_e.e_conn_http)
         {
             local url = format("/DB/GetBin?%s=%d", table, aid);

+ 706 - 21
SquiLu-ourbiz/ourbiz-fltk.nut

@@ -8,6 +8,8 @@
 Check if we are on windows os.
 */
 
+local table_rawget = table_rawget;
+
 local WIN32 = os.getenv("WINDIR") != null;
 socket.open();
 
@@ -27,8 +29,11 @@ Command line parameters.
 -user	user to authenticate
 -password	password to authenticate
 */
+
 local appServer_host = table_get(app_cmd_parameters, "-host", "localhost");
-local appServer_port = table_get(app_cmd_parameters, "-port", 8855).tointeger() ;
+//local appServer_host = table_get(app_cmd_parameters, "-host", "192.168.1.8");
+//local appServer_port = table_get(app_cmd_parameters, "-port", 8855).tointeger() ;
+local appServer_port = table_get(app_cmd_parameters, "-port", 8084).tointeger() ;
 //local appServer_host = table_get(app_cmd_parameters, "-host", "ourbiz.dadbiz.es");
 //local appServer_port = table_get(app_cmd_parameters, "-port", 80).tointeger() ;
 local appServer_user = table_get(app_cmd_parameters, "-user", "mingote");
@@ -352,6 +357,7 @@ local app_help_window = null;
 
 class Base_Window extends Fl_Window {
 	_child_windows=null;
+	_owner_window=null;
 	_db_map = null;
 	_sab = null;
 
@@ -368,10 +374,26 @@ class Base_Window extends Fl_Window {
 			if(!sender.as_window()) throw(_tr("Only windows can use this callback !"));
 			foreach(k, win in sender->_child_windows)
 			{
-				if(win) win->on_close_delete_cb(win, udata);
+				if(win) 
+				{
+					win->_owner_window = null; //prevents calling us to remove
+					win->on_close_delete_cb(win, udata);
+				}
 			}
 			sender->hide();
 			Fl.delete_widget(sender);
+			if(sender._owner_window)
+			{
+				local winName;
+				foreach(k,v in sender._owner_window._child_windows)
+				{
+					if(v == sender)
+					{
+						winName = k;
+					}
+				}
+				if(winName) table_rawdelete(sender._owner_window._child_windows, winName);
+			}
 		}
 	}
 
@@ -421,6 +443,7 @@ class Base_Window extends Fl_Window {
 			win = new WindowClass();
 			//win.label(winName);
 			_child_windows[winName] <- win; //.weakref();
+			win._owner_window = this.weakref();
 		}
 		return win;
 	}
@@ -700,17 +723,19 @@ class Edit_Base_Window extends Base_Window {
 	}
 
 	function setDbActionControls(choice, btn){
+		//print("setDbActionControls", __LINE__);
+		//fl_alert("setDbActionControls");
 		_choiceDbAction = choice;
 		_choiceDbAction.callback(on_Change_dbAction);
 		_btnDbAction = btn;
 		_btnDbAction.callback(on_btnDbAction);
 	}
-	function fill_choice_by_data (choice, data)
+	function fill_choice_by_data (choice, data, description_idx=1)
 	{
 		for(local i=0, max_count = data.size(); i<max_count; ++i)
 		{
 			local rec = data[i];
-			choice->my_add(rec[0].tointeger(), rec[1]);
+			choice->my_add(rec[0].tointeger(), rec[description_idx]);
 			//choice->add(rec[1]);
 		}
 	}
@@ -726,7 +751,7 @@ class Edit_Base_Window extends Base_Window {
 	function on_btnDbAction(sender : Fl_Widget, udata : any)
 	{
 		this = sender->window();
-
+		//fl_alert("on_btnDbAction");
 		local cursor_wait = fl_cursor_wait();
 		try {
 			switch(_choiceDbAction->action())
@@ -790,7 +815,7 @@ class Edit_Base_Window extends Base_Window {
 		uw.get_widget_value(input_fld_map);
 	}
 	function do_insert(){
-		//fl_alert("do_insert");
+		//fl_alert("do_insert:" + __LINE__);
 		local dbu = dbUpdater();
 		dbu->dbAction = dbu.e_insert;
 		dbu->clear();
@@ -975,6 +1000,11 @@ class Fl_Data_Table extends Flv_Data_Table {
 		}
 	}
 
+	function has_calee_on_select()
+	{
+		return _call_this && (row() >= 0);
+	}
+	
 	function handle(event){
 		switch(event){
 			case FL_RELEASE:{
@@ -1005,8 +1035,11 @@ class Fl_Data_Table extends Flv_Data_Table {
 					case FL_KP_Enter:
 					case FL_Enter:
 					case FL_Key_Space:
-						if(!Fl.event_ctrl()){
-							row_selected(Fl_Data_Table_Events.e_update);
+						if(Fl.event_ctrl()){
+							sender->mark_row(true, true);
+						} else {
+							if(has_calee_on_select()) row_selected(Fl_Data_Table_Events.e_select);
+							else row_selected(Fl_Data_Table.e_update);
 						}
 					break;
 				}
@@ -1148,9 +1181,15 @@ class  List_Edit_Base_Window extends Edit_Base_Window {
 	constructor(px, py, pw, ph, pl){
 		base.constructor(px, py, pw, ph, pl);
 	}
+	function setDbActionControls(choice, btn)
+	{
+		base.setDbActionControls(choice, btn);
+		dbAction->action(DbAction_Enum.e_insert);
+	}
 	function on_btnDbAction(sender : Fl_Widget, udata : any)
 	{
 		this = sender->window();
+		//print("on_btnDbAction", __LINE__);
 		local rc = base.on_btnDbAction(sender, udata);
 		if(!rc) return rc;
 		local saved_row = grid->row();
@@ -1264,6 +1303,7 @@ class MyListSearchWindow extends ListSearchWindow {
 		search_str->value(search_for_str);
 		show();
 		do_search();
+		grid->take_focus();
 	}
 
 	function hasSelectRequestCall(){
@@ -1532,6 +1572,7 @@ class OurDynamicQuery extends DynamicQueryWindow
 
 class OurImages extends ImagesListEditWindow {
 	_search_options = null;
+	_search_by_image_id = 0;
 
 	constructor(){
 		base.constructor();
@@ -1552,10 +1593,12 @@ class OurImages extends ImagesListEditWindow {
 	function do_search(){
 		_search_options.query_limit = query_limit->value();
 		_search_options.search_str = db_images_name->value();
+		_search_options.image_id = _search_by_image_id;
 		local cursor_wait = fl_cursor_wait();
 		grid->clear_data_rows();
 		appServer.images_get_list(grid->_data, _search_options);
 		grid->recalc_data();
+		_search_by_image_id = 0;
 	}
 
 	function do_edit(aid){
@@ -2356,6 +2399,16 @@ class OurProductKit extends ProductKitGroup
 
 	function on_search_product_cb(sender : Fl_Widget, udata : any)
 	{
+		this = sender->window();
+		/*
+		local swin = getEntitiesListSearchWindow();
+		local cb = function(entity_id) {
+				show();
+				validate_enity_id(entity_id);
+			}
+		cb.setenv(this);
+		swin->search_for_me(db_orders_entity_name->value(), cb);
+		*/
 		show_create_owned(_products_list_window);
 		local search_str = db_product_kits_sell_description->value();
 		local doSearchLast = (search_str.len() == 1) && (search_str[0] == ' ');
@@ -2377,6 +2430,9 @@ class MyEditProductWindow extends EditProductWindow {
 	_ourHistory = null;
 	_ourProductKit = null;
 	_ourProductPrices = null;
+	_image_id = 0;
+	_image_changed = false;
+	
 	static _history_options = [
 		"--- Select one",
 		"Sales by date",
@@ -2422,6 +2478,8 @@ class MyEditProductWindow extends EditProductWindow {
 		db_products_sell_price.callback(on_change_prices);
 		db_products_sell_price2.callback(on_change_prices);
 		db_products_price_decimals.callback(on_change_prices);
+		
+		btnImage.callback(on_change_image);
 
 		load_aux_data();
 	}
@@ -2442,8 +2500,8 @@ class MyEditProductWindow extends EditProductWindow {
 	{
 		base.do_edit_delayed(udata);
 		delayed_focus(db_products_sell_description);
-		local image_id = table_get(_record, "image_id", false);
-		if(image_id && image_id.len()) button_show_db_image(btnImage, image_id.tointeger(), null, false, false);
+		_image_id = table_get(_record, "image_id", false);
+		if(_image_id && _image_id.len()) button_show_db_image(btnImage, _image_id.tointeger(), null, false, false);
 		else {
 			btnImage->hide();
 			//btnImage->image(&jpegNophoto);
@@ -2516,6 +2574,31 @@ class MyEditProductWindow extends EditProductWindow {
 			this["db_products_" + k].value(prices_rec[k]);
 		}
 	}
+	
+	function refresh_product_image()
+	{
+		if(_image_id) button_show_db_image(btnImage, _image_id, 0, false, false);
+		else 
+		{
+			btnImage->hide();
+			//btnImage->image(jpegNophoto);
+			btnImage->show();
+		}
+	}
+	
+	function validate_image_id(wdg, aid){
+		_image_id = aid.tointeger();
+		_image_changed = true;
+		refresh_product_image();
+	}
+	function on_change_image(sender, udata)
+	{
+		this = sender->window();
+		local win = showChildWindow("Images List/Edit", OurImages, true);
+		win->_search_by_image_id = _image_id;
+		win->search_for_me( "" , validate_image_id);
+	}
+	
 }
 
 class MyEditProductSalesWindow extends MyEditProductWindow {
@@ -2678,6 +2761,8 @@ class MyCalendarWindow extends CalendarWindow {
 	_last_row = null;
 	_last_col = null;
 	static _week_days_abbr = ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"];
+	_dest_widget = null;
+	_header = null;
 
 	constructor(){
 		base.constructor();
@@ -2694,13 +2779,189 @@ class MyCalendarWindow extends CalendarWindow {
 		}
 		grid->set_cols(cols_info, true);
 		makemonth();
+		
+		grid.callback(on_grid_cb);
+		grid.callback_when(FLVEcb_SELECTION_CHANGED | FLVEcb_CLICKED);
+		btnToday.callback(today_cb);
+		btnNextMonth.callback(next_month_cb);
+		btnPrevMonth.callback(prev_month_cb);
+		btnNextYear.callback(next_year_cb);
+		btnPrevYear.callback(prev_year_cb);
+		btnSelect.callback(date_selected_cb);
+		for(int i=0; i < 12; i++)
+		{
+			month_buttons.child(i).callback(goto_month_cb);
+		}		
 	}
-	function makemonth(){
-		local tm = CalendarBase.makemonth(2013, 1);
+	function makemonth(dt=null){
+		if(!dt)
+		{
+			dt = os.date("*t");
+		}
+		local tm = CalendarBase.makemonth(dt.year, dt.month);
 		grid->set_data(tm);
+		_date = dt;
+		refresh();
 	}
-	function cb_gui_destination_zone(sender : Fl_Widget, udata : any){
+	function refresh()
+	{
+		_header = format("%d - %d - %d", _date.year, _date.month+1, _date.day);
+		this.label_month.label(_header);
+		select_curr_day();
+		grid->redraw();
+	}
+
+	function addDays(n)
+	{
+		local jd = CalendarBase.get_julian_day(_date.year, _date.month, _date.day);
+		jd += n;
+		local ut = CalendarBase.julian_to_unix(jd);
+		_date = os.date("*t", ut);
+	}
+
+	function addMonths(n)
+	{
+		local cm = _date.month;
+		cm += n;
+		local years = cm / 12;
+		local month = cm % 12;
+		//print(_date.month, cm, years, month);
+		_date.year += month < 0 ? (years - 1) : years;
+		_date.month = month < 0 ? 11 : month;
+	}
+
+	function set_selected_date()
+	{
+		local gc = grid.col();
+		local gr = grid.row();
+		if((gr != _last_row) || (gc != _last_col))
+		{
+		    local jump = (gr*7+gc) - (_last_row*7+_last_col);
+		    addDays(jump);
+		    _last_col = gc;
+		    _last_row = gr;
+		    refresh();
+		}
+	}
+
+	function select_curr_day()
+	{
+		local day = _date.day;
+		if(day == grid->_data[grid.row()][grid.col()]) return;
+		for(int row=0; row < 6; row++)
+		{
+			local row_data = grid->_data[row];
+			for(int col=0; col < 7; col++)
+			{
+				if (row_data[col] == day)
+				{
+					//prevent days 25..31 of prev month
+					if(row == 0 && day > 7) continue;
+					grid.row(row);
+					grid.col(col);
+					_last_col = col;
+					_last_row = row;
+					return;
+				}
+			}
+		}
+	}
+
+	function on_grid_cb(sender : Fl_Widget, udata : any)
+	{
+		this = sender->window();
+		if(Fl.event_clicks() > 0)
+		{
+			//print("on_grid_cb", __LINE__);
+			Fl.event_clicks(0);
+			//select_curr_date();
+			if(Fl.focus() == grid){
+				btnSelect.do_callback();
+			}
+		}
+		else
+		{
+			//print("on_grid_cb", __LINE__);
+			//prevent changes based on grid position from outside
+			//if(Fl::focus() == &gui_grid)
+			if(Fl.focus() != grid) grid.take_focus();
+			set_selected_date();
+		}
+	}
+
+	function today_cb(sender : Fl_Widget, udata : any)
+	{
+		this = sender->window();
+		makemonth();
+		select_curr_day();
+	}
+	
+	function next_month_cb(sender : Fl_Widget, udata : any)
+	{
+		this = sender->window();
+		addMonths(1);
+		makemonth(_date);
+	}
+
+	function prev_month_cb(sender : Fl_Widget, udata : any)
+	{
 		this = sender->window();
+		addMonths(-1);
+		makemonth(_date);
+	}
+
+	function next_year_cb(sender : Fl_Widget, udata : any)
+	{
+		this = sender->window();
+		++_date.year;
+		makemonth(_date);
+	}
+
+	function prev_year_cb(sender : Fl_Widget, udata : any)
+	{
+		this = sender->window();
+		--_date.year;
+		makemonth(_date);
+	}
+	
+	function goto_month_cb(sender : Fl_Widget, udata : any)
+	{
+		this = sender->window();
+		local month = 0;
+		for(local i=0; i < 12; i++)
+		{
+		    if(sender == month_buttons.child(i))
+		    {
+			month = i;
+			break;
+		    }
+		}
+		_date.month = month;
+		makemonth(_date);
+	}
+
+	function date_selected_cb(sender : Fl_Widget, udata : any)
+	{
+		this = sender->window();
+		local win = grid.window();
+		if(win) win->hide();
+		if(_dest_widget)
+		{
+			local dt = format("%d-%0.2d-%0.2d", _date.year, _date.month+1, _date.day);
+			_dest_widget->value(dt);
+		}
+	}
+	
+	function cb_gui_destination_zone(sender, udata)
+	{
+		this = sender->window();
+	}
+	
+	function show_date_for_me(wdg, fmt)
+	{
+		_dest_widget = wdg.weakref();
+		local dt = CalendarBase.parse_date(_dest_widget->value());
+		makemonth(dt);
 	}
 }
 
@@ -2760,8 +3021,20 @@ class MyEditOrderWindow extends EditOrderWindow {
 
 		btnCalcDelivery.callback(cb_btnCalcDelivery);
 		btnShowCalendar.callback(cb_btnShowCalendar);
+		
 		btnSearchEntity.callback(cb_btnSearchEntity);
+		db_orders_entity_name.callback(cb_btnSearchEntity);
+
 		btnSearchProduct.callback(cb_btnSearchProduct);
+		db_orders_lines_description.callback(cb_btnSearchProduct);
+		
+		db_orders_lines_quantity.callback(on_calc_line_cb);
+		db_orders_lines_weight.callback(on_calc_line_cb);
+		db_orders_lines_price.callback(on_calc_line_cb);
+		db_orders_lines_price_decimals.callback(on_calc_line_cb);
+		db_orders_lines_discount_pct.callback(on_calc_line_cb);
+		db_orders_lines_sales_tax1_pct.callback(on_calc_line_cb);
+		db_orders_lines_sales_tax2_pct.callback(on_calc_line_cb);
 	}
 	function on_first_time_show(){
 		local data = [];
@@ -2864,10 +3137,16 @@ class MyEditOrderWindow extends EditOrderWindow {
 
 	function fill_edit_lines_form(asBlank=false, doFocus=true, doCalc=true){
 		local  wfq = Widget_Fill_By_Map(_line_record);
-		if(asBlank) set_decimal_places(2);
-		else set_decimal_places(_line_record.price_decimals.tointeger());
 		local input_fld_map = get_input_fields("orders_lines");
 		wfq.set_widget_value_by_map(input_fld_map);
+		if(asBlank)
+		{
+			local dp = 2;
+			set_decimal_places(dp);
+			db_orders_lines_price_decimals->value(dp.tostring());
+			db_orders_lines_quantity->value("1");
+		}	
+		else set_decimal_places(_line_record.price_decimals.tointeger());
 
 		if(doFocus) {
 			linesTab->value(group_lines);
@@ -2883,6 +3162,7 @@ class MyEditOrderWindow extends EditOrderWindow {
 	function cb_btnShowCalendar(sender : Fl_Widget, udata : any){
 		this = sender->window();
 		local dc = getChildWindow("Calendar", MyCalendarWindow);
+		dc.show_date_for_me(db_orders_order_date, "YMD");
 		dc.show();
 	}
 
@@ -2899,7 +3179,8 @@ class MyEditOrderWindow extends EditOrderWindow {
 	}
 	function cb_btnSearchEntity(sender : Fl_Widget, udata : any){
 		this = sender->window();
-		if(sender == db_orders_entity_name && db_orders_entity_id->value())
+		local entity_id = db_orders_entity_id->value();
+		if(sender == db_orders_entity_name && (entity_id && entity_id.size()))
 		{
 			//if we have a valid entity id we accept direct changes to entity name
 			linesTab->value(group_lines);
@@ -2926,11 +3207,14 @@ class MyEditOrderWindow extends EditOrderWindow {
 	function validate_product_id(product_id){
 		db_orders_lines_product_id->value(product_id.tostring());
 	}
-	function cb_btnSearchProduct(sender : Fl_Widget, udata : any){
+
+	function cb_btnSearchProduct(sender : Fl_Widget, udata : any)
+	{
 		this = sender->window();
 		if(sender == db_orders_lines_description)
 		{
-			if(db_orders_lines_product_id->value())
+			local product_id = db_orders_lines_product_id->value();
+			if(product_id && product_id.len())
 			{
 				//if we have a valid product id we accept direct changes to product description
 				return;
@@ -2950,6 +3234,61 @@ class MyEditOrderWindow extends EditOrderWindow {
 		cb.setenv(this);
 		swin->search_for_me(db_orders_lines_description->value(), cb);
 	}
+	
+	function on_calc_line_cb(sender : Fl_Widget, udata : any)
+	{
+		this = sender->window();
+
+		local calc_fields = [
+			"product_id",
+			"quantity",
+			"weight",
+			"price",
+			"first_total",
+			"discount_pct",
+			"discount_amt",
+			"line_subtotal",
+			"sales_tax1_pct",
+			"sales_tax1_amt",
+			"sales_tax2_pct",
+			"line_total",
+			"price_decimals",
+			];
+		local calc_fields_dbnames;
+		if(!calc_fields_dbnames)
+		{
+			calc_fields_dbnames = {};
+		}
+		
+		foreach(str in calc_fields)
+		{
+			local fldn =  table_rawget(calc_fields_dbnames, str, false); 
+			if(!fldn)
+			{
+				fldn = "db_orders_lines_" + str;
+				calc_fields_dbnames[str] <- fldn;
+			}
+			local fld = this[fldn];
+			if(fld == sender) _line_record["trigger"] <- str;
+			_line_record[str] <- fld->value();
+		}
+
+		if(udata == -1)
+		{
+		    _line_record.clear();
+		}
+		else
+		{
+			appServer.do_dbaction(_line_record, "calc_line", "orders", _line_edit_id, 0);
+		}
+
+		foreach(str in calc_fields)
+		{
+			local fldn =  table_rawget(calc_fields_dbnames, str, false); 
+			local fld = this[fldn];
+			fld->value(_line_record[str] || "");
+		}
+	}
 
 	function on_show_chart_cb(sender : Fl_Widget, udata : any){
 		this = sender->window();
@@ -3237,6 +3576,9 @@ class PaymentsListSearch extends MyListSearchWindow {
 		btnInsert->hide();
 		if(doInitialSearch) delayed_method_call(this, this.do_search, null);
 	}
+	function fill_search_options(){
+		pack_search_options.add(Fl_Radio_Button());
+	}
 	function get_search_options(){
 		_search_options.search_str = search_str.value();
 		_search_options.entities = _search_by_entities.value() == 1;
@@ -3269,6 +3611,340 @@ class PaymentsBuysListSearch extends PaymentsListSearch {
 	function get_edit_window(){return getChildWindow("Payment/Buys Edit", MyPaymentsBuysWindow);}
 }
 
+//General Ledger
+class OurGlGroups extends GLGroupsListEditWindow {
+	constructor(){
+		base.constructor();
+		dbUpdater()->table_name = "gl_groups";
+		setup_grid(grid, this);
+		setDbActionControls(dbAction, btnDbAction);
+		local cols_info = [
+			"id|ID|0",
+			"code|Code|8",
+			"description|Description|-1",
+			"debit_op|Dbt|8|C",
+			"credit_op|Cdt|8|C",
+		];
+		grid->set_cols(cols_info);
+		do_search();
+	}
+	function do_search(){
+		local cursor_wait = fl_cursor_wait();
+		grid->clear_data_rows();
+		appServer.gl_groups_get_list(grid->_data);
+		grid->recalc_data();
+	}
+
+	function get_widget_changed(uw)
+	{
+		//if(!uw.validate_regex(db_order_types_with_credit, "[+-]", true))
+		//    throw TWidgetValidateException(db_order_types_with_credit,
+		//				   _tr("Valid options are +- !"));
+		base.get_widget_changed(uw);
+	}
+}
+
+class MyGLChartEditWindow extends GLChartEditWindow {
+
+	constructor(){
+		base.constructor();
+		dbUpdater()->table_name = "gl_chart";
+		db_gl_chart_notes->wrap_mode(1, 0);
+		setDbActionControls(dbAction, btnDbAction);
+	}
+	function on_first_time_show(){
+		local data = [];
+		appServer.gl_groups_get_short_list(data);
+		fill_choice_by_data(db_gl_chart_gl_group_id, data, 2);
+	}
+	
+	function do_edit_delayed(udata)
+	{
+		base.do_edit_delayed(udata);
+		delayed_focus(db_gl_chart_group_code);
+	}
+}
+
+class GlChartOfAccountsListSearch extends MyListSearchWindow {
+	_search_by_description = null;
+	_search_by_notes = null;
+	_search_by_code = null;
+	_search_by_active = null;
+	_search_by_headers = null;
+	_search_by_accounts = null;
+
+	constructor(doInitialSearch=false){
+		base.constructor(doInitialSearch);
+		label(_tr("GL Chart of Accounts List/Search"));
+		local cols_info = [
+			"id|ID|0|R",
+			"group_code|Grp.|3|C",
+			"code|Code|8",
+			"description|Description|-1",
+			"is_header|Hdr.|3|C|B",
+		];
+		grid->set_cols(cols_info);
+		_search_by_description = create_search_by("Description");
+		_search_by_notes = create_search_by("Notes");
+		_search_by_code = create_search_by("Code");
+		_search_by_description->setonly();
+		_search_by_active = create_search_by2("Active");
+		_search_by_headers = create_search_by2("Headers");
+		_search_by_accounts = create_search_by2("Accounts");
+		_search_by_active->value(1);
+		if(doInitialSearch) delayed_method_call(this, this.do_search, null);
+	}
+	function get_search_options(){
+		_search_options.search_str = search_str.value();
+		_search_options.description = _search_by_description.value() == 1;
+		_search_options.notes = _search_by_notes.value() == 1;
+		_search_options.code = _search_by_code.value() == 1;
+		_search_options.active = _search_by_active.value() == 1;
+		_search_options.headers = _search_by_headers.value() == 1;
+		_search_options.accounts = _search_by_accounts.value() == 1;
+		return _search_options;
+	}
+
+	function get_search_data(data, so){
+		appServer.gl_chart_get_list(grid->_data, so);
+	}
+	function get_edit_window(){return getChildWindow("GL Chart of Account Edit", MyGLChartEditWindow);}
+}
+
+class MyGLTransactionEditWindow extends GLTransactionEditWindow {
+	
+	_line_edit_id = 0;
+	_account_id = 0;
+	_lined_edit_credit_op = null;
+	_lined_edit_debit_op = null;
+	_line_record = null;
+	
+	constructor(){
+		base.constructor();
+		dbUpdater()->table_name = "gl_transactions";
+		local cols_info = [
+			"id|ID|0",
+			"code|Code|8",
+			"description|Account|-1",
+			"account_op|Op.|5",
+			"debit|Debit|9|R|D",
+			"credit|Credit|9|R|D",
+		];
+		grid_lines->set_cols(cols_info);
+		setup_grid(grid_lines, this);
+		_line_record = {};
+		_line_edit_id = 0;
+    
+		setDbActionControls(dbAction, btnDbAction);
+
+		_line_edit_id = _account_id = 0;
+		_lined_edit_credit_op = _lined_edit_debit_op = "";
+		
+		db_gl_transactions_transaction_date.callback(on_change_date);
+		btnShowCalendar.callback(calendar_for_transaction_date);
+		db_gl_transactions_lines_due_date.callback(on_change_date);
+		btnDueDateCalendar.callback(calendar_for_due_date);
+
+		db_gl_transactions_lines_debit.callback(on_change_cebit_credit_cb);
+		db_gl_transactions_lines_credit.callback(on_change_cebit_credit_cb);
+
+		db_gl_transactions_lines_group_code.callback(on_search_account_cb);
+		db_gl_transactions_lines_description.callback(on_search_account_cb);
+		
+		btnSearchAccount.callback(on_search_account_cb);
+		btnSaveLine.callback(on_save_line_cb);
+		btnClearLine.callback(on_clear_line_cb);
+		btnBalanceLine.callback(on_balance_line_cb);		
+	}
+	
+	function do_edit(aid)
+	{
+		base.do_edit(aid);
+		/*
+		appServer().get_record(_line_record, "gl_transactions", 0, aid, "&line=1");
+		//dbg_dump_map(_line_record);
+		fill_edit_lines_form(aid == 0, false);
+		_line_edit_id = aid;
+		if(aid) delayed_focus(db_gl_transactions_lines_debit);
+		*/
+	}
+	
+	function do_edit_delayed(udata)
+	{
+		base.do_edit_delayed(udata);
+		delayed_focus(db_gl_transactions_description);
+	}
+	
+	function set_debit_credit_label(debit_op, credit_op){
+		local oneStr = "%s        ";
+		local twoStr = "%s (%s)   ";
+		local ftm_debit = debit_op ? twoStr : oneStr;
+		local ftm_credit = credit_op ? twoStr : oneStr;
+		local buf = format(ftm_debit, _tr("Debit"), debit_op);
+		db_gl_transactions_lines_debit->copy_label(buf);
+		buf = format(ftm_credit, _tr("Credit"), credit_op);
+		db_gl_transactions_lines_credit->copy_label(buf);
+	}
+	
+	function fill_edit_form(asBlank=false){
+		base.fill_edit_form(asBlank);
+		fill_edit_lines_form(true, false); //clear lines entries
+	}
+	
+	function fill_edit_lines_form(asBlank=false, doFocus=true, doCalc=true)
+	{
+		//if(asBlank) set_decimal_places(2);
+		//else set_decimal_places(_line_record.price_decimals.tointeger());
+		local rec = _line_record;
+		if(!rec) rec = {};
+		db_gl_transactions_lines_group_code->value(table_rawget(rec, "group_code", ""));
+		db_gl_transactions_lines_gl_code->value(table_rawget(rec, "gl_code", ""));
+		db_gl_transactions_lines_description->value(table_rawget(rec, "description", ""));
+		set_debit_credit_label(table_rawget(rec, "debit_op", false), table_rawget(rec, "credit_op", false));
+		if(doFocus) {
+			delayed_focus(db_gl_transactions_lines_debit);
+		}
+	}
+
+	function on_change_date(wdg, udata)
+	{
+		local vdate = wdg->value();
+		/*
+		tm tmTime;
+		if(ParseDateString(vdate, &tmTime))
+		{
+		    char buf[64];
+		    strftime(buf, sizeof(buf), "%Y-%m-%d", &tmTime);
+		    db_gl_transactions_transaction_date->value(buf);
+		}
+		else
+		{
+		    fl_alert(_tr("Invalid date !"));
+		    delayed_focus(wdg);
+		}
+		*/
+	}
+
+	function showCalendarFor(wdg)
+	{
+		local dc = getChildWindow("Calendar", MyCalendarWindow);
+		dc.show_date_for_me(wdg, "YMD");
+		dc.show();
+	}
+
+	function calendar_for_transaction_date(sender : Fl_Widget, udata : any)
+	{
+		this = sender->window();
+		showCalendarFor(db_gl_transactions_transaction_date);
+	}
+
+	function calendar_for_due_date(sender : Fl_Widget, udata : any)
+	{
+		this = sender->window();
+		showCalendarFor(db_gl_transactions_lines_due_date);
+	}
+	
+	function on_change_account_code(sender : Fl_Widget, udata : any)
+	{
+		this = sender->window();
+	}
+
+	function validate_account_id(account_id)
+	{
+		appServer.get_record(_line_record, "gl_chart", 0, account_id, "&for_transaction=1");
+		_line_edit_id = account_id;
+		fill_edit_lines_form();
+	}
+
+	function on_search_account_cb(sender : Fl_Widget, udata : any)
+	{
+		this = sender->window();
+		local swin = getChildWindow("Chart of Accounts", GlChartOfAccountsListSearch);
+		local cb = function(account_id) {
+				show();
+				validate_account_id(account_id);
+			}
+		cb.setenv(this);
+		local search_str;
+		if(sender == db_gl_transactions_lines_group_code){
+		    search_str = db_gl_transactions_lines_group_code->value();
+		    //if(search_str.size()) search_str = " " + search_str;
+		    swin->_search_by_code->setonly();
+		}
+		else
+		{
+		    search_str = db_gl_transactions_lines_description->value();
+		    swin->_search_by_description->setonly();
+		}
+		swin->search_for_me(search_str, cb);
+	}
+	
+	function on_change_cebit_credit_cb(sender : Fl_Widget, udata : any)
+	{
+		this = sender->window();
+	}
+	
+	function on_clear_line_cb(sender : Fl_Widget, udata : any)
+	{
+		this = sender->window();
+	}
+	
+	function on_save_line_cb(sender : Fl_Widget, udata : any)
+	{
+		this = sender->window();
+	}
+	
+	function on_balance_line_cb(sender : Fl_Widget, udata : any)
+	{
+		this = sender->window();
+	}
+}
+
+class GlTransactionsListSearch extends MyListSearchWindow {
+	_search_by_description = null;
+	_search_by_date = null;
+
+	constructor(doInitialSearch=false){
+		base.constructor(doInitialSearch);
+		label(_tr("GL Transactions List/Search"));
+		local cols_info = [
+			"id|ID|6",
+			"transaction_date|Date|9",
+			"descriptio|Description|-1",
+			"amount|Amount|12|R|M",
+		];
+		grid->set_cols(cols_info);
+		fill_search_options();
+		if(doInitialSearch) delayed_method_call(this, this.do_search, null);
+	}
+	
+	function fill_search_options()
+	{
+		_search_by_description = create_search_by("Description");
+		_search_by_date = create_search_by("Date");
+		_search_by_description->setonly();
+	}
+	
+	function get_search_options()
+	{
+		_search_options.search_str = search_str.value();
+		_search_options.description = _search_by_description.value() == 1;
+		_search_options.date = _search_by_date.value() == 1;
+		return _search_options;
+	}
+
+	function get_data_group_filter(data)
+	{
+		appServer.gl_chart_get_short_list(data);
+	}
+	
+	function get_search_data(data, so){
+		appServer.gl_transactions_get_list(grid->_data, so);
+	}
+	function get_edit_window(){return getChildWindow("GL Transaction Edit", MyGLTransactionEditWindow);}
+}
+
+
 class MyMainWindow extends MainWindow {
 	constructor() {
 		base.constructor();
@@ -3359,9 +4035,18 @@ class MyMainWindow extends MainWindow {
 		this = sender.window();
 		local win = showSearchChildWindow("Products List/Search", ProductsListSearch);
 	}
-	function cb_btnGLGroups(sender : Fl_Widget, udata : any){print(__LINE__);}
-	function cb_btnGLChart(sender : Fl_Widget, udata : any){print(__LINE__);}
-	function cb_btnGLTransactions(sender : Fl_Widget, udata : any){print(__LINE__);}
+	function cb_btnGLGroups(sender : Fl_Widget, udata : any){
+		this = sender.window();
+		local win = showChildWindow("GL Groups List/Edit", OurGlGroups, true);
+	}
+	function cb_btnGLChart(sender : Fl_Widget, udata : any){
+		this = sender.window();
+		local win = showSearchChildWindow("GL Chart of Accounts List/Edit", GlChartOfAccountsListSearch);
+	}
+	function cb_btnGLTransactions(sender : Fl_Widget, udata : any){
+		this = sender.window();
+		local win = showSearchChildWindow("GL Transactions List/Edit", GlTransactionsListSearch);
+	}
 	function cb_btnOrdersSum(sender : Fl_Widget, udata : any){print(__LINE__);}
 	function cb_btnSalesTaxRates(sender : Fl_Widget, udata : any){
 		this = sender.window();

+ 51 - 54
SquiLu-ourbiz/ourbiz-gui.fl

@@ -1,5 +1,5 @@
 # data file for the Fltk User Interface Designer (fluid)
-version 1.0302 
+version 1.0303 
 i18n_type 1 
 i18n_include i18n_function.h 
 i18n_function _tr 
@@ -91,63 +91,64 @@ widget_class CalendarWindow {
     label Calendar
     xywh {5 5 340 25} box ENGRAVED_BOX color 7 labelsize 16
   }
-  Fl_Group {} {open
-    xywh {6 35 340 25} labelsize 16
+  Fl_Browser grid {
+    dirty_name grid
+    xywh {5 35 340 202} labeltype NO_LABEL labelsize 16
+    class Fl_Data_Table
+  }
+  Fl_Group month_buttons {
+    dirty_name month_buttons open
+    xywh {6 241 340 25} labelsize 16
   } {
     Fl_Button btnMonth1 {
       label 1
-      xywh {6 35 25 25}
+      xywh {6 241 25 25}
     }
     Fl_Button btnMonth2 {
       label 2
-      xywh {34 35 25 25}
+      xywh {34 241 25 25}
     }
     Fl_Button btnMonth3 {
       label 3
-      xywh {63 35 25 25}
+      xywh {63 241 25 25}
     }
     Fl_Button btnMonth4 {
       label 4
-      xywh {91 35 25 25}
+      xywh {91 241 25 25}
     }
     Fl_Button btnMonth5 {
       label 5
-      xywh {120 35 25 25}
+      xywh {120 241 25 25}
     }
     Fl_Button btnMonth6 {
       label 6
-      xywh {148 35 25 25}
+      xywh {148 241 25 25}
     }
     Fl_Button btnMonth7 {
       label 7
-      xywh {177 35 25 25}
+      xywh {177 241 25 25}
     }
     Fl_Button btnMonth8 {
       label 8
-      xywh {205 35 25 25}
+      xywh {205 241 25 25}
     }
     Fl_Button btnMonth9 {
       label 9
-      xywh {234 35 25 25}
+      xywh {234 241 25 25}
     }
     Fl_Button btnMonth10 {
       label 10
-      xywh {262 35 25 25}
+      xywh {262 241 25 25}
     }
     Fl_Button btnMonth11 {
       label 11
-      xywh {291 35 25 25}
+      xywh {291 241 25 25}
     }
     Fl_Button btnMonth12 {
       label 12
-      xywh {320 35 25 25}
+      xywh {320 241 25 25}
     }
   }
-  Fl_Browser grid {
-    dirty_name grid
-    xywh {5 65 340 202} labeltype NO_LABEL labelsize 16
-    class Fl_Data_Table
-  }
   Fl_Group {} {open
     xywh {5 275 340 25} labelsize 16
   } {
@@ -376,7 +377,6 @@ widget_class BarChartGroup {
   Fl_Box bar_chart {
     dirty_name bar_chart
     xywh {0 30 760 430} color 7 labeltype NO_LABEL labelsize 16 align 5 resizable
-    code0 {\#include "Fl_Bar_Chart.h"}
     class Fl_Bar_Chart
   }
 } 
@@ -2043,8 +2043,8 @@ widget_class PaymentEditWindow {
 
 widget_class GLGroupsListEditWindow {
   label {GL Groups List / Edit}
-  xywh {480 215 500 352} type Double labelsize 16 hide resizable
-  class Edit_Base_Window
+  xywh {480 215 500 350} type Double labelsize 16 hide resizable
+  class List_Edit_Base_Window
 } {
   Fl_Browser grid {
     xywh {5 5 490 200} type Multi labeltype NO_LABEL labelsize 16 textsize 16 resizable
@@ -2179,9 +2179,9 @@ widget_class GLChartEditWindow {
 } 
 
 widget_class GLTransactionEditWindow {
-  label {GL Transaction Edit}
-  xywh {80 133 720 410} type Double labelsize 16 hide resizable
-  class Edit_Base_Window
+  label {GL Transaction Edit} open
+  xywh {80 133 720 410} type Double labelsize 16 resizable
+  class Edit_Base_Window visible
 } {
   Fl_Input db_gl_transactions_description {
     label Description
@@ -2206,88 +2206,88 @@ widget_class GLTransactionEditWindow {
   }
   Fl_Group group_lines {
     dirty_name group_lines open
-    xywh {10 55 705 309} box THIN_UP_BOX color 246 labeltype NO_LABEL labelsize 16
+    xywh {10 55 705 310} box THIN_UP_BOX color 246 labeltype NO_LABEL labelsize 16
   } {
     Fl_Browser grid_lines {
-      dirty_name {@grid_lines}
-      xywh {15 55 695 150} type Hold labeltype NO_LABEL labelsize 16 align 5 textsize 16 resizable
+      dirty_name grid_lines selected
+      xywh {15 60 695 150} type Hold labeltype NO_LABEL labelsize 16 align 5 textsize 16 resizable
       class Fl_Data_Table
     }
     Fl_Group group_edit_line {
-      dirty_name group_edit_line open
-      xywh {15 230 695 130} labeltype NO_LABEL
+      dirty_name group_edit_line open selected
+      xywh {15 235 695 130} labeltype NO_LABEL
     } {
       Fl_Input db_gl_transactions_lines_description {
         label Account
         macro_name {db gl_transactions_lines description}
-        xywh {190 230 480 25} labelsize 16 align 5 textsize 16
+        xywh {190 235 480 25} labelsize 16 align 5 textsize 16
         code0 {=add_input_field_to_map("$(1)", "$(2)", $(name));}
       }
       Fl_Input db_gl_transactions_lines_group_code {
         label Code
         macro_name {db gl_transactions_lines group_code}
-        xywh {20 230 110 25} labelsize 16 align 5 textsize 16
+        xywh {20 235 110 25} labelsize 16 align 5 textsize 16
         code0 {=add_input_field_to_map("$(1)", "$(2)", $(name));}
       }
       Fl_Button btnSearchAccount {
         label {@<->}
         dirty_name btnSearchAccount
-        tooltip {Show calendar} xywh {680 230 30 25} labelsize 18 labelcolor 22
+        tooltip {Show calendar} xywh {680 235 30 25} labelsize 18 labelcolor 22
       }
       Fl_Input db_gl_transactions_lines_debit {
         label Debit
         macro_name {db gl_transactions_lines debit}
-        xywh {485 280 110 25} type Float labelsize 16 align 5 textsize 16
+        xywh {485 285 110 25} type Float labelsize 16 align 5 textsize 16
         code0 {=add_input_field_to_map("$(1)", "$(2)", $(name));}
       }
       Fl_Input db_gl_transactions_lines_credit {
         label Credit
         macro_name {db gl_transactions_lines credit}
-        xywh {600 280 110 25} type Float labelsize 16 align 5 textsize 16
+        xywh {600 285 110 25} type Float labelsize 16 align 5 textsize 16
         code0 {=add_input_field_to_map("$(1)", "$(2)", $(name));}
       }
       Fl_Button btnSaveLine {
         label {Save Line}
         dirty_name btnSaveLine
-        xywh {365 330 110 25} labelsize 16
+        xywh {365 335 110 25} labelsize 16
       }
       Fl_Button btnBalanceLine {
         label Balance
         dirty_name btnBalanceLine
-        xywh {485 330 110 25} labelsize 16
+        xywh {485 335 110 25} labelsize 16
       }
       Fl_Button btnClearLine {
         label {Clear Line}
         dirty_name btnClearLine
-        xywh {600 330 110 25} labelsize 16
+        xywh {600 335 110 25} labelsize 16
       }
       Fl_Output db_gl_transactions_lines_gl_code {
         label {Grp.}
         macro_name {db gl_transactions_lines gl_code}
-        xywh {140 230 40 25} labelsize 16 align 5 textsize 16
+        xywh {140 235 40 25} labelsize 16 align 5 textsize 16
         code0 {=add_input_field_to_map("$(1)", "$(2)", $(name));}
       }
       Fl_Input db_gl_transactions_lines_doc {
         label Document
         macro_name {db gl_transactions_lines doc}
-        xywh {20 280 455 25} labelsize 16 align 5 textsize 16
+        xywh {20 285 455 25} labelsize 16 align 5 textsize 16
         code0 {=add_input_field_to_map("$(1)", "$(2)", $(name));}
       }
       Fl_Input db_gl_transactions_lines_due_date {
         label {Due Date}
         macro_name {db gl_transactions_lines due_date}
-        xywh {20 330 125 25} labelsize 16 align 5 textsize 16
+        xywh {20 335 125 25} labelsize 16 align 5 textsize 16
         code0 {=add_input_field_to_map("$(1)", "$(2)", $(name));}
       }
       Fl_Button btnDueDateCalendar {
         label {@<->}
         dirty_name btnDueDateCalendar
-        tooltip {Show calendar} xywh {155 330 30 25} labelsize 18 labelcolor 22
+        tooltip {Show calendar} xywh {155 335 30 25} labelsize 18 labelcolor 22
       }
       Fl_Input db_gl_transactions_lines_checked_date {
         label {Checked Date}
         macro_name {db gl_transactions_lines checked_date}
-        xywh {195 330 125 25} labelsize 16 align 5 textsize 16
+        xywh {195 335 125 25} labelsize 16 align 5 textsize 16
         code0 {=add_input_field_to_map("$(1)", "$(2)", $(name));}
       }
     }
@@ -2681,9 +2681,9 @@ widget_class EditEntityWindow {
 } 
 
 widget_class EditProductWindow {
-  label {Edit Products} open
-  xywh {34 28 800 560} type Double resizable
-  class Edit_Base_Window visible
+  label {Edit Products}
+  xywh {34 28 800 560} type Double hide resizable
+  class Edit_Base_Window
 } {
   Fl_Output db_products_id {
     macro_name {db products id}
@@ -2710,7 +2710,7 @@ widget_class EditProductWindow {
     xywh {5 35 790 520} selection_color 4 labelsize 16 labelcolor 7 resizable
   } {
     Fl_Group tabMain {
-      label Main selected
+      label Main
       xywh {5 60 790 495} color 246 labelsize 16 resizable
     } {
       Fl_Input db_products_reference_code {
@@ -3277,7 +3277,7 @@ widget_class EditOrderWindow {
     xywh {5 68 790 487} selection_color 4 labelsize 16 labelcolor 7 resizable
   } {
     Fl_Group tabMain {
-      label Main open
+      label Main
       xywh {5 95 790 460} color 246 labelfont 2 labelsize 16 resizable
     } {
       Fl_Pack pack_line3 {open
@@ -3684,7 +3684,7 @@ widget_class EditOrderWindow {
       }
     }
     Fl_Group tabDelivery {
-      label Delivery
+      label Delivery open
       xywh {5 95 790 460} color 246 labelfont 2 labelsize 16 hide
     } {
       Fl_Input db_orders_entity_address {
@@ -3766,7 +3766,6 @@ widget_class EditOrderWindow {
         macro_name {db orders notes}
         dirty_name db_orders_notes
         xywh {15 395 770 150} labelsize 16 align 5 textsize 16 resizable
-        code0 {\#include <FL/Fl_Text_Editor.H>}
         code1 {=add_input_field_to_map("$(1)", "$(2)", $(name));}
         class Fl_Text_Editor_Buffered
       }
@@ -3785,7 +3784,7 @@ widget_class EditOrderWindow {
     }
     Fl_Group tabOptions {
       label Options
-      dirty_name tabOptions
+      dirty_name tabOptions open
       xywh {5 95 790 460} color 246 labelfont 2 labelsize 16 hide
     } {
       Fl_Check_Button opt_ask_for_printer {
@@ -3832,7 +3831,6 @@ widget_class EditOrderWindow {
         label {Company Info}
         dirty_name opt_print_order_company_info
         xywh {20 350 375 200} labelsize 16 align 5 textsize 16
-        code0 {\#include <FL/Fl_Text_Editor.H>}
         class Fl_Text_Editor_Buffered
       }
       Fl_Check_Button {} {
@@ -3844,7 +3842,6 @@ widget_class EditOrderWindow {
         label {Company Info}
         dirty_name opt_print_order_bottom_info
         xywh {405 350 375 200} labelsize 16 align 5 textsize 16 resizable
-        code0 {\#include <FL/Fl_Text_Editor.H>}
         class Fl_Text_Editor_Buffered
       }
       Fl_Check_Button {} {

+ 47 - 46
SquiLu-ourbiz/ourbiz-gui.nut

@@ -112,6 +112,8 @@ class CalendarWindow extends Base_Window {
   
   // Declaration of class members
   label_month : Fl_Box;
+  grid : Fl_Data_Table;
+  month_buttons : Fl_Group;
   btnMonth1 : Fl_Button;
   btnMonth2 : Fl_Button;
   btnMonth3 : Fl_Button;
@@ -124,7 +126,6 @@ class CalendarWindow extends Base_Window {
   btnMonth10 : Fl_Button;
   btnMonth11 : Fl_Button;
   btnMonth12 : Fl_Button;
-  grid : Fl_Data_Table;
   btnPrevYear : Fl_Repeat_Button;
   btnPrevMonth : Fl_Repeat_Button;
   btnToday : Fl_Button;
@@ -143,67 +144,68 @@ class CalendarWindow extends Base_Window {
       o.color(7);
     }
     {
-      local o = Fl_Group(6, 35, 340, 25);
+      local o = Fl_Data_Table(5, 35, 340, 202);
+      grid = o;
+      o.labeltype(FL_NO_LABEL);
+      o.labelsize(16);
+      o.end();
+    }
+    {
+      local o = Fl_Group(6, 241, 340, 25);
+      month_buttons = o;
       o.labelsize(16);
       {
         {
-          local o = Fl_Button(6, 35, 25, 25, _tr("1"));
+          local o = Fl_Button(6, 241, 25, 25, _tr("1"));
           btnMonth1 = o;
         }
         {
-          local o = Fl_Button(34, 35, 25, 25, _tr("2"));
+          local o = Fl_Button(34, 241, 25, 25, _tr("2"));
           btnMonth2 = o;
         }
         {
-          local o = Fl_Button(63, 35, 25, 25, _tr("3"));
+          local o = Fl_Button(63, 241, 25, 25, _tr("3"));
           btnMonth3 = o;
         }
         {
-          local o = Fl_Button(91, 35, 25, 25, _tr("4"));
+          local o = Fl_Button(91, 241, 25, 25, _tr("4"));
           btnMonth4 = o;
         }
         {
-          local o = Fl_Button(120, 35, 25, 25, _tr("5"));
+          local o = Fl_Button(120, 241, 25, 25, _tr("5"));
           btnMonth5 = o;
         }
         {
-          local o = Fl_Button(148, 35, 25, 25, _tr("6"));
+          local o = Fl_Button(148, 241, 25, 25, _tr("6"));
           btnMonth6 = o;
         }
         {
-          local o = Fl_Button(177, 35, 25, 25, _tr("7"));
+          local o = Fl_Button(177, 241, 25, 25, _tr("7"));
           btnMonth7 = o;
         }
         {
-          local o = Fl_Button(205, 35, 25, 25, _tr("8"));
+          local o = Fl_Button(205, 241, 25, 25, _tr("8"));
           btnMonth8 = o;
         }
         {
-          local o = Fl_Button(234, 35, 25, 25, _tr("9"));
+          local o = Fl_Button(234, 241, 25, 25, _tr("9"));
           btnMonth9 = o;
         }
         {
-          local o = Fl_Button(262, 35, 25, 25, _tr("10"));
+          local o = Fl_Button(262, 241, 25, 25, _tr("10"));
           btnMonth10 = o;
         }
         {
-          local o = Fl_Button(291, 35, 25, 25, _tr("11"));
+          local o = Fl_Button(291, 241, 25, 25, _tr("11"));
           btnMonth11 = o;
         }
         {
-          local o = Fl_Button(320, 35, 25, 25, _tr("12"));
+          local o = Fl_Button(320, 241, 25, 25, _tr("12"));
           btnMonth12 = o;
         }
       }
       o.end();
     }
-    {
-      local o = Fl_Data_Table(5, 65, 340, 202);
-      grid = o;
-      o.labeltype(FL_NO_LABEL);
-      o.labelsize(16);
-      o.end();
-    }
     {
       local o = Fl_Group(5, 275, 340, 25);
       o.labelsize(16);
@@ -3392,7 +3394,7 @@ class PaymentEditWindow extends Edit_Base_Window {
   }
 }
 
-class GLGroupsListEditWindow extends Edit_Base_Window {
+class GLGroupsListEditWindow extends List_Edit_Base_Window {
   
   // Declaration of class members
   grid : Fl_Data_Table;
@@ -3405,7 +3407,7 @@ class GLGroupsListEditWindow extends Edit_Base_Window {
   dbAction : Fl_Choice_dbAction;
   btnDbAction : Fl_Button;
   
-  constructor(px=480, py=215, pw=500, ph=352, pl=_tr("GL Groups List / Edit")){
+  constructor(px=480, py=215, pw=500, ph=350, pl=_tr("GL Groups List / Edit")){
     base.constructor(px, py, pw, ph, pl);
     // Create member functions and widgets
     {
@@ -3677,7 +3679,7 @@ class GLTransactionEditWindow extends Edit_Base_Window {
       o.tooltip(_tr("Show calendar"));
     }
     {
-      local o = Fl_Group(10, 55, 705, 309);
+      local o = Fl_Group(10, 55, 705, 310);
       group_lines = o;
       o.box(FL_THIN_UP_BOX);
       o.labelsize(16);
@@ -3685,9 +3687,8 @@ class GLTransactionEditWindow extends Edit_Base_Window {
       o.labeltype(FL_NO_LABEL);
       {
         {
-          local o = grid_lines;
-          Fl_Group.current()->add(o);
-          o->resize(15, 55, 695, 150);
+          local o = Fl_Data_Table(15, 60, 695, 150);
+          grid_lines = o;
           o.textsize(16);
           o.align(5);
           o.labeltype(FL_NO_LABEL);
@@ -3696,12 +3697,12 @@ class GLTransactionEditWindow extends Edit_Base_Window {
           Fl_Group.current().resizable(o);
         }
         {
-          local o = Fl_Group(15, 230, 695, 130);
+          local o = Fl_Group(15, 235, 695, 130);
           group_edit_line = o;
           o.labeltype(FL_NO_LABEL);
           {
             {
-              local o = Fl_Input(190, 230, 480, 25, _tr("Account"));
+              local o = Fl_Input(190, 235, 480, 25, _tr("Account"));
               db_gl_transactions_lines_description = o;
               o.textsize(16);
               o.align(5);
@@ -3709,7 +3710,7 @@ class GLTransactionEditWindow extends Edit_Base_Window {
               add_input_field_to_map("gl_transactions_lines", "description", db_gl_transactions_lines_description);
             }
             {
-              local o = Fl_Input(20, 230, 110, 25, _tr("Code"));
+              local o = Fl_Input(20, 235, 110, 25, _tr("Code"));
               db_gl_transactions_lines_group_code = o;
               o.textsize(16);
               o.align(5);
@@ -3717,14 +3718,14 @@ class GLTransactionEditWindow extends Edit_Base_Window {
               add_input_field_to_map("gl_transactions_lines", "group_code", db_gl_transactions_lines_group_code);
             }
             {
-              local o = Fl_Button(680, 230, 30, 25, _tr("@<->"));
+              local o = Fl_Button(680, 235, 30, 25, _tr("@<->"));
               btnSearchAccount = o;
               o.labelcolor(22);
               o.labelsize(18);
               o.tooltip(_tr("Show calendar"));
             }
             {
-              local o = Fl_Float_Input(485, 280, 110, 25, _tr("Debit"));
+              local o = Fl_Float_Input(485, 285, 110, 25, _tr("Debit"));
               db_gl_transactions_lines_debit = o;
               o.textsize(16);
               o.align(5);
@@ -3732,7 +3733,7 @@ class GLTransactionEditWindow extends Edit_Base_Window {
               add_input_field_to_map("gl_transactions_lines", "debit", db_gl_transactions_lines_debit);
             }
             {
-              local o = Fl_Float_Input(600, 280, 110, 25, _tr("Credit"));
+              local o = Fl_Float_Input(600, 285, 110, 25, _tr("Credit"));
               db_gl_transactions_lines_credit = o;
               o.textsize(16);
               o.align(5);
@@ -3740,22 +3741,22 @@ class GLTransactionEditWindow extends Edit_Base_Window {
               add_input_field_to_map("gl_transactions_lines", "credit", db_gl_transactions_lines_credit);
             }
             {
-              local o = Fl_Button(365, 330, 110, 25, _tr("Save Line"));
+              local o = Fl_Button(365, 335, 110, 25, _tr("Save Line"));
               btnSaveLine = o;
               o.labelsize(16);
             }
             {
-              local o = Fl_Button(485, 330, 110, 25, _tr("Balance"));
+              local o = Fl_Button(485, 335, 110, 25, _tr("Balance"));
               btnBalanceLine = o;
               o.labelsize(16);
             }
             {
-              local o = Fl_Button(600, 330, 110, 25, _tr("Clear Line"));
+              local o = Fl_Button(600, 335, 110, 25, _tr("Clear Line"));
               btnClearLine = o;
               o.labelsize(16);
             }
             {
-              local o = Fl_Output(140, 230, 40, 25, _tr("Grp."));
+              local o = Fl_Output(140, 235, 40, 25, _tr("Grp."));
               db_gl_transactions_lines_gl_code = o;
               o.textsize(16);
               o.align(5);
@@ -3763,7 +3764,7 @@ class GLTransactionEditWindow extends Edit_Base_Window {
               add_input_field_to_map("gl_transactions_lines", "gl_code", db_gl_transactions_lines_gl_code);
             }
             {
-              local o = Fl_Input(20, 280, 455, 25, _tr("Document"));
+              local o = Fl_Input(20, 285, 455, 25, _tr("Document"));
               db_gl_transactions_lines_doc = o;
               o.textsize(16);
               o.align(5);
@@ -3771,7 +3772,7 @@ class GLTransactionEditWindow extends Edit_Base_Window {
               add_input_field_to_map("gl_transactions_lines", "doc", db_gl_transactions_lines_doc);
             }
             {
-              local o = Fl_Input(20, 330, 125, 25, _tr("Due Date"));
+              local o = Fl_Input(20, 335, 125, 25, _tr("Due Date"));
               db_gl_transactions_lines_due_date = o;
               o.textsize(16);
               o.align(5);
@@ -3779,14 +3780,14 @@ class GLTransactionEditWindow extends Edit_Base_Window {
               add_input_field_to_map("gl_transactions_lines", "due_date", db_gl_transactions_lines_due_date);
             }
             {
-              local o = Fl_Button(155, 330, 30, 25, _tr("@<->"));
+              local o = Fl_Button(155, 335, 30, 25, _tr("@<->"));
               btnDueDateCalendar = o;
               o.labelcolor(22);
               o.labelsize(18);
               o.tooltip(_tr("Show calendar"));
             }
             {
-              local o = Fl_Input(195, 330, 125, 25, _tr("Checked Date"));
+              local o = Fl_Input(195, 335, 125, 25, _tr("Checked Date"));
               db_gl_transactions_lines_checked_date = o;
               o.textsize(16);
               o.align(5);
@@ -4438,8 +4439,8 @@ class EditProductWindow extends Edit_Base_Window {
         {
           local o = Fl_Group(5, 60, 790, 495, _tr("Main"));
           tabMain = o;
-          o.labelsize(16);
           o.color(246);
+          o.labelsize(16);
           {
             {
               local o = Fl_Input(115, 70, 165, 25, _tr("Reference"));
@@ -4687,8 +4688,8 @@ class EditProductWindow extends Edit_Base_Window {
               o.value(1);
               o.down_box(FL_DOWN_BOX);
               o.callback(function(sender, udata){
-                db_products_sell_notes->wrap_mode(o->value(), 0);
-                db_products_buy_notes->wrap_mode(o->value(), 0);
+                db_products_sell_notes->wrap_mode(o->value(), 0);
+                db_products_buy_notes->wrap_mode(o->value(), 0);
                 db_products_tags->wrap_mode(o->value(), 0);
               });
             }
@@ -5270,8 +5271,8 @@ class EditOrderWindow extends Edit_Base_Window {
         {
           local o = Fl_Group(5, 95, 790, 460, _tr("Main"));
           tabMain = o;
-          o.labelsize(16);
           o.labelfont(2);
+          o.labelsize(16);
           o.color(246);
           {
             {
@@ -5809,8 +5810,8 @@ class EditOrderWindow extends Edit_Base_Window {
         {
           local o = Fl_Group(5, 95, 790, 460, _tr("Delivery"));
           tabDelivery = o;
-          o.labelfont(2);
           o.labelsize(16);
+          o.labelfont(2);
           o.color(246);
           {
             {

+ 182 - 3
SquiLu-ourbiz/ourbiz.nut

@@ -199,9 +199,20 @@ local function getOurbizDBFileName(){
 	//return "file:ourbiz_db?mode=memory&cache=shared";
 }
 
+local function sqliteTrace(udata, sql)
+{
+	if(sql == "-- TRIGGER ") return;
+	debug_print(udata, ":", sql, "\n");
+}
+
 local ourbizDB = null;
 local function getOurbizDB(){
-	if(!ourbizDB) ourbizDB = SQLite3(getOurbizDBFileName());
+	if(!ourbizDB)
+	{
+		
+		ourbizDB = SQLite3(getOurbizDBFileName());
+		if(AT_DEV_DBG) ourbizDB.trace(sqliteTrace, "SQL", false);
+	}
 	return ourbizDB;
 	//return checkCachedDB(APP_CODE_FOLDER + "/ourbiz.db");
 }
@@ -459,7 +470,7 @@ local DB_Manager = class {
 		}
 		local result = stmt.step();
 		stmt.finalize()
-		if (result == SQLite3Stmt.DONE) return db.last_row_id();
+		if (result == SQLite3Stmt.SQLITE_DONE) return db.last_row_id();
 		throw db.errmsg();
 	}
 
@@ -506,7 +517,7 @@ local DB_Manager = class {
 
 		local result = stmt.step();
 		stmt.finalize();
-		if (result == SQLite3Stmt.DONE) return db.changes();
+		if (result == SQLite3Stmt.SQLITE_DONE) return db.changes();
 		throw db.errmsg();
 	}
 
@@ -3019,6 +3030,174 @@ db_ourbiz_tables.sales_tax_rates <- new DB_sales_tax_rates();
 
 db_ourbiz_tables.warranty_types <- new DB_Manager("warranty_types")
 
+local DB_gl_groups = class extends DB_Manager {
+	constructor(){
+		base.constructor("gl_groups", ["code", "description", "debit_op", "credit_op"]);
+	}
+
+	function sql_list(qs_tbl=null, post_tbl=null) {
+		return "select id, code, description, debit_op, credit_op from gl_groups order by code";
+	}
+
+	function sql_short_list(req) {
+		return "select id, description from gl_groups order by code";
+	}
+}
+
+db_ourbiz_tables.gl_groups <- new DB_gl_groups();
+
+local DB_gl_charts = class extends DB_Manager {
+	constructor(){
+		base.constructor("gl_chart", ["is_active", "group_code", "gl_group_id", "is_header",
+			"budget", "description", "notes"]);
+	}
+
+	function sql_list(qs_tbl, post_tbl){
+		local so = get_search_options(post_tbl);
+		checkQueryStringSAB(qs_tbl, so);
+		local mf = blob();
+		
+		mf.write("select c.id, g.code, c.group_code, c.description, c.is_header ",
+			"from gl_chart as c left join gl_groups as g on c.gl_group_id = g.id ",
+			"where 1=1 ");
+
+		local with_headers, with_accounts, cdate, group_id, active;
+		
+		if( so.with_headers ){
+			if( !(with_accounts = table_rawget(qs_tbl, "with_accounts", 0)) ) mf.write(" and c.is_header = 1 ");
+		}
+		if(so.with_accounts){
+			if(!with_headers) mf.write(" and c.is_header = 0 ");
+		}
+
+		if( so.cdate ) {
+			mf.write(" order by c.id desc ");
+			return mf.tostring();
+		}
+
+		if( so.group_id )
+		{
+			mf.write(" and c.gl_group_id =", so.group_id);
+		}
+
+		if( so.active ) mf.write(" and c.is_active=1 ");
+
+		local search_str = escape_sql_like_search_str(so.search_str);
+		//std::string lo_search_str = self.db:escape_sql_like_search_str(search_str)
+		if(so.account_id)
+		{
+			mf.write(" and c.id", so.account_id);
+		}
+		else if(search_str && search_str.size())
+		{
+			if(so.id) mf.write(" and c.id = ", so.search_str.tointeger().tostring());
+			else
+			{
+				mf.write(" and ");
+				if(so.code) mf.write(" c.group_code ");
+				else if(so.notes) mf.write(" c.notes ");
+				else mf.write(" c.description ");
+				mf.write(" like '", search_str, "' ");
+			}
+		}
+
+		mf.write(" order by c.group_code ");
+
+		if(so.query_limit != 0) mf.write(" limit ", so.query_limit);
+		
+		return mf.tostring();
+	}
+
+	function sql_get_one(tbl_qs) {
+		local id = table_rawget(tbl_qs, table_name, 0).tointeger().tostring();
+		if(table_rawget(tbl_qs, "for_transaction", false)){
+			local sql = [==[
+				select c.id as account_id, c.group_code, c.description, g.code as gl_code, g.debit_op, g.credit_op
+				from gl_chart as c join gl_groups as g on c.gl_group_id = g.id
+				where c.id=? and c.is_active=1]==];
+			return sql;
+		}
+		return base.sql_get_one(tbl_qs);
+	}
+	
+	function sql_short_list(req) {
+		return format("select id, description from gl_chart where is_active=1 order by 2;", table_name);
+	}
+}
+
+db_ourbiz_tables.gl_chart <- new DB_gl_charts();
+
+db_ourbiz_tables.gl_groups <- new DB_gl_groups();
+
+local DB_gl_transactions = class extends DB_Manager {
+	_sql_get_line = null;
+	
+	constructor(){
+		base.constructor("gl_transactions", ["description", "transaction_date"]);
+		_sql_get_line = [==[
+			select tl.*, gc.description, gc.group_code, g.code as gl_code, g.debit_op, g.credit_op,
+				case when amount < 0 then amount * -1 else 0 end as debit,
+				case when amount > 0 then amount else 0 end as credit
+			from gl_transactions_lines as tl join gl_chart as gc
+				on tl.account_id = gc.id
+			join gl_groups as g on gc.gl_group_id = g.id
+		]==];
+	}
+
+	function sql_list(qs_tbl, post_tbl){
+		local so = get_search_options(post_tbl);
+		checkQueryStringSAB(qs_tbl, so);
+		local mf = blob();
+		
+		mf.write([==[
+			select id, transaction_date, description,
+				case when totals.balanced <> 0 then -totals.balanced else totals.amount end
+			from gl_transactions left join (
+				select transaction_id as gl_tr_id,
+					sum(case when amount < 0 then 0 else amount end) as amount,
+					abs(sum(amount)
+				) as balanced
+				from gl_transactions_lines group by transaction_id) as totals on id=gl_tr_id where 1=1
+			]==]);
+
+		local with_headers, with_accounts, cdate, group_id, active;
+		
+		if( so.cdate ) {
+			mf.write(" order by c.id desc ");
+			return mf.tostring();
+		}
+
+		if(so.group_id) so.account_id = so.group_id;
+
+		local search_str = escape_sql_like_search_str(so.search_str);
+		//std::string lo_search_str = self.db:escape_sql_like_search_str(search_str)
+		if(so.account_id)
+		{
+			mf.write(" and id in(select transaction_id from gl_transactions_lines where account_id=", so.account_id);
+			if(so.query_limit != 0) mf.write(" limit ", so.query_limit);
+			mf.write(")");
+		}
+		else if(search_str.size())
+		{
+			if(so.id) mf.write(" and c.id = ", so.search_str.tointeger().tostring());
+			else
+			{
+				mf.write(" and description like '", search_str, "'");
+			}
+		}
+
+		if(so.query_limit != 0) mf.write(" limit ", so.query_limit);
+		
+		return mf.tostring();
+	}
+
+	function sql_short_list(req) {
+		return format("select id, description from gl_chart where is_active=1 order by 2;", table_name);
+	}
+}
+
+db_ourbiz_tables.gl_transactions <- new DB_gl_transactions();
+
 local DB_groups_tree = class extends DB_Manager
 {
 	constructor(){

+ 2 - 0
SquiLu-ourbiz/search-options.nut

@@ -41,6 +41,8 @@ class OurBizSearchOptions
     with_headers = null;
     with_accounts = null;
     code = null;
+    headers = null;
+    accounts = null;
 
     constructor()
     {

+ 2 - 1
SquiLu-ourbiz/sq-server-plugin.nut

@@ -809,11 +809,12 @@ function isExtensionAllowed(fname){
 
 function getFilesInPath(path, files=null, prefix=""){
 	if(!files) files = [];
+	local prefix_len = prefix.len();
 	foreach( file in sqfs.dir(path) ){
 		if(file != "." && file != ".." ){
 			local f = path + "/" + file;
 			local pf
-			if (prefix.len() > 0) pf = prefix + "/" + file;
+			if (prefix_len > 0) pf = prefix + "/" + file;
 			else pf = file;
 
 			try {

+ 8 - 1
SquiLu-ourbiz/sq-server.nut

@@ -65,11 +65,18 @@ local mongoose_start_params = {
 	ssl_certificate = "axTLS.x509_512.pem",
         //"ssl_certificate", "axTLS.x509_1024.pem",
         ssl_chain_file = "axTLS_x509_512.cer",
-	extra_mime_types = ".xsl=application/xml",
+	extra_mime_types = ".xsl=application/xml,.json=application/json; charset=utf-8",
 	master_plugin = function(){
+		//companies_uk_db_mem_global <- SQLite3("file:companies_uk_db?mode=memory&cache=shared");
+		//companies_uk_db_mem_global.restore("./companies-uk/companies-uk-2014-07.db");
+		//ourbiz_db_mem_global <- SQLite3("file:ourbiz_db?mode=memory&cache=shared");
+		//ourbiz_db_mem_global.restore("/home/mingo/dev/FrontAccountLua/ourbiz.db");
+
 		debug_print("done master_plugin\n");
 	},
 	master_plugin_exit = function(){
+		//companies_uk_db_mem_global.close();
+		//ourbiz_db_mem_global.close();
 		debug_print("done master_plugin_exit\n");
 	},
 	//functions to be used by each independent lua vm