فهرست منبع

Added more functionality and fixes.

mingodad 13 سال پیش
والد
کامیت
8bd9ab4e7b

+ 14 - 9
SquiLu-ourbiz/db-updater.nut

@@ -16,6 +16,10 @@ class DBTableUpdateBase {
 	useMultiPart = null;
 	useSLE = null;
 	static boundary = "----OurbizZ1X2c3LkUw";
+	static e_none = edbAction.e_none;
+	static e_insert = edbAction.e_insert;
+	static e_update = edbAction.e_update;
+	static e_delete = edbAction.e_delete;
 
 	constructor() {
 		table_name = "no_table_name";
@@ -84,8 +88,9 @@ class DBTableUpdateBase {
 	function afterDbActionHttpConn(request_result){}
     
 	function doDbActionHttpConn(){
-		local my_result;
+		local my_result = blob(0, 8192);
 		local httpRequest = HTTPConn(my_result);
+		local appServer = AppServer.getAppServer();
 		appServer.httpcon_setup(httpRequest);
 
 		local httpBody = blob(0, 8192);
@@ -95,20 +100,20 @@ class DBTableUpdateBase {
 		local body_str = null;
 		local nchanges = _field_changes.size();
 		if(useSLE){
-			httpBodyMemBuf = blob(0, 8192);
+			local httpBodyMemBuf = blob(0, 8192);
 			httpBodyMemBuf.write("[[");
 			for(local i=0; i<nchanges; ++i)
 			{
 				//printf("%s : %s\n", _field_changes[i].key,  _field_changes[i].val);
 				add2sle(httpBodyMemBuf, _field_changes[i][0]);
 			}
-			httpBodyMemBuf.write(SLEEND);
+			httpBodyMemBuf.writen(SLE_SLEEND, 'c');
 			httpBodyMemBuf.write("][");
 			for(local i=0; i<nchanges; ++i)
 			{
 				add2sle(httpBodyMemBuf, _field_changes[i][1]);
 			}
-			httpBodyMemBuf.write(SLEEND);
+			httpBodyMemBuf.writen(SLE_SLEEND, 'c');
 			httpBodyMemBuf.write("]]");
 
 			body_str = httpBodyMemBuf.tostring();
@@ -143,8 +148,8 @@ class DBTableUpdateBase {
 		{
 			version = 0;
 			local rec = {};
-			sle2map(my_result, rec);
-			local new_id = rec.get("id", 0);
+			appServer.asle2map(my_result, rec);
+			local new_id = rec.get("id", 0).tointeger();
 			if(new_id == 0) throw("Could not update this record !");
 			edit_id = new_id;
 		}
@@ -153,10 +158,10 @@ class DBTableUpdateBase {
 		case edbAction.e_delete:
 		{
 			local rec = {};
-			sle2map(my_result, rec);
-			local changes = rec.get("changes", 0);
+			appServer.sle2map(my_result, rec);
+			local changes = rec.get("changes", 0).tointeger();
 			if(changes == 0) {
-				if(dbAction == e_update) throw("Could not update this record !");
+				if(dbAction == edbAction.e_update) throw("Could not update this record !");
 				else throw("Could not delete this record !");
 			}
 			if(dbAction == edbAction.e_update) ++version;

+ 23 - 8
SquiLu-ourbiz/fluid2SquiLu.nut

@@ -76,7 +76,7 @@ function BuildGrammar(){
 		"i18n_type", "i18n_include", "i18n_function", "i18n_file", "i18n_set" ];
 	local str_methods = [ "tooltip", "type", "box", "down_box", "xclass", "labeltype" ];
 	local str_ext_methods = [ "label", "callback", "after", "image", "user_data", "class",
-		"code0", "code1", "code2", "code3", ":", "macro_name" ];
+		"code0", "code1", "code2", "code3", ":", "macro_name", "dirty_name" ];
 	local number_methods = [ "labelsize", "align", "value", "textcolor", "selection_color",
 		"labelcolor", "color", "labelfont", "textfont", "when", "textsize", "step", 
 		"maximum", "minimum", "shortcut" ];
@@ -137,7 +137,7 @@ function GetItem(pos, type, parent=null){
 	source_file.find_lua("^%s*(%b{})%s+", function(start, end, match){
 		p1 = start; p2 = end; item = match;
 	}, pos);
-	print("pos",pos, source_file.slice(pos, pos+30))
+	//print("pos",pos, source_file.slice(pos, pos+30))
 	assert(p1);
 
 	local content = item.slice(1,-1);
@@ -287,10 +287,24 @@ Write.widget <- function(t, ind){
 	//print(t.key, name, klass)
 	Output(ind, "{\n"); 
 	++ind;
-	Output(ind, "local %s = %s%s(%s%s%d, %s%d, %d, %d", name, 
-		klass, newMethodCallStr, firstParamStr, t.xoffset, x, t.yoffset, y, w, h);
-	if (! isClearLabel && t.attr.get("label", false)) Output(0, ", %s(%q)", configuration.textfilter, t.attr.label);
-	Output(0, ");\n");
+	local dirty_name =  t.attr.get("dirty_name", false);
+	local need_var_assign = true;
+	if(dirty_name && dirty_name[0] == '@'){
+		need_var_assign = false;
+		dirty_name = dirty_name.slice(1);
+		Output(ind, "local o = %s;\n", dirty_name);
+		Output(ind, "Fl_Group.current()->add(o);\n", dirty_name);
+		Output(ind, "o->resize(%s%s%d, %s%d, %d, %d);\n",  firstParamStr, t.xoffset, x, t.yoffset, y, w, h);
+		if (! isClearLabel && t.attr.get("label", false)) 
+			Output(ind, "o->lable(%s(%q));\n", configuration.textfilter, t.attr.label);
+	}
+	else
+	{
+		Output(ind, "local %s = %s%s(%s%s%d, %s%d, %d, %d", name, 
+			klass, newMethodCallStr, firstParamStr, t.xoffset, x, t.yoffset, y, w, h);
+		if (! isClearLabel && t.attr.get("label", false)) Output(0, ", %s(%q)", configuration.textfilter, t.attr.label);
+		Output(0, ");\n");
+	}	
 
 	t.varname <- name;
 	if (t.name.len() > 0){ 
@@ -315,7 +329,7 @@ Write.widget <- function(t, ind){
 		}
 		else obj_name = t.name;
 
-		Output(ind, "%s = %s;\n", obj_name, name);
+		if(need_var_assign) Output(ind, "%s = %s;\n", obj_name, name);
 		t.varname = t.name;
 	}
 	
@@ -677,4 +691,5 @@ if (vargv.len() > 0){
 	local config = rc[0], infile = rc[1], outfile = rc.get(2, "-"); 
 	Fluid2SquiLu(infile, outfile, config);
 }
-Fluid2SquiLu("entity-edit-gui.fl", "-", {});
+//Fluid2SquiLu("entity-edit-gui.fl", "-", {});
+Fluid2SquiLu("orders-edit-gui.fl", "-", {});

+ 3 - 4
SquiLu-ourbiz/happyhttp.nut

@@ -143,6 +143,7 @@ class HappyHttpConnection {
 		switch(rc[1]){
 			case socket.IO_DONE:
 			case socket.IO_TIMEOUT:
+			//case socket.IO_CLOSED:
 				break;
 			default:
 				if(rc[0].len() == 0) throw(format("socket io error %d", rc[1]));
@@ -262,7 +263,7 @@ class HappyHttpConnection {
 	}
 
 	// return true if socket has data waiting to be read
-	static function datawaiting( sock , milisec=0)
+	static function datawaiting( sock , milisec)
 	{
 		try {
 			local rc = socket.select( [sock], [], milisec ? milisec / 1000.0 : 0);
@@ -414,7 +415,7 @@ class HappyHttpResponse {
 					bytesused = ProcessDataChunked( data, data_idx, count );
 				else
 					bytesused = ProcessDataNonChunked( data, data_idx, count );
-				data += bytesused;
+				data_idx += bytesused;
 				count -= bytesused;
 			}
 		}
@@ -543,7 +544,6 @@ class HappyHttpResponse {
 		// invoke callback to pass out the data
 		m_Connection.response_data( this, data, data_idx, n );
 		m_BytesRead += n;
-
 		// Finish if we know we're done. Else we're waiting for connection close.
 		if( m_Length != -1 && m_BytesRead == m_Length ) Finish();
 		return n;
@@ -583,7 +583,6 @@ class HappyHttpResponse {
 			m_Length = 0;
 		}
 
-
 		// if we're not using chunked mode, and no length has been specified,
 		// assume connection will close at end.
 		if( !m_WillClose && !m_Chunked && m_Length == -1 ) m_WillClose = true;

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

@@ -182,6 +182,7 @@ class HTTPConn extends HTTPConnAuthBase
 
     constructor(aresult_out)
     {
+	assert(aresult_out instanceof stream)
 	base.constructor();
 	result_out = aresult_out;
     }
@@ -237,6 +238,9 @@ class AppServer
     _port = null;
     _conn_type = null;
     _db = null;
+    static e_conn_none = conn_type_e.e_conn_none;
+    static e_conn_http = conn_type_e.e_conn_http;
+    static e_conn_dbfile = conn_type_e.e_conn_dbfile;
     
     constructor()
     {
@@ -457,7 +461,7 @@ class AppServer
             {
                 add2sle(httpBody, k);
             }
-            httpBody.write(SLEEND);
+            httpBody.writen(SLE_SLEEND, 'c');
             httpBody.write("][");
 
             add2sle(httpBody, table);
@@ -468,7 +472,7 @@ class AppServer
             {
                 add2sle(httpBody, v);
             }
-            httpBody.write(SLEEND);
+            httpBody.writen(SLE_SLEEND, 'c');
             httpBody.write("]]");
 
             //printf("%d : %s\n", rec.size(), httpBody.c_str());

+ 165 - 116
SquiLu-ourbiz/ourbiz-fltk.nut

@@ -184,25 +184,32 @@ enum DbAction_Enum {
 		};
 
 class Fl_Choice_dbAction extends Fl_Choice {
+	_options = null;
 	constructor(px, py, pw, ph, pl=null){
 		base.constructor(px, py, pw, ph, pl);
 		tooltip(_tr("Select an operation to perform on this record"));
+		_options = [];
 		add_tr("Insert", DbAction_Enum.e_insert);
 		add_tr("Update", DbAction_Enum.e_update);
 		add_tr("Delete", DbAction_Enum.e_delete);
 	}
 
-	function action(){return mvalue()->user_data();}
-	function action(act){
-		local m = menu();
-		for(local i=0, count = m->size(); i<count; ++i){
-			if(m[i].user_data() == act){
-				value(i);
+	function action(act=null){
+		if(!act) return _options[value()][1];
+		local x = 0;
+		foreach(opt in _options){
+			if(opt[1] == act){
+				value(x);
 				break;
 			}
+			++x;
 		}
 	}
-	function add_tr(label, act){return add(_tr(label), 0, 0, act, 0);}
+	function add_tr(label, act){
+		local opt = [_tr(label), act];
+		_options.push(opt);
+		return add(opt[0], 0, 0, opt[1], 0);
+	}
 
 	function insert_export_import(){
 		add_tr("Export", DbAction_Enum.e_export);
@@ -344,6 +351,68 @@ class MyBaseWindow extends Fl_Window {
 	}
 }
 
+class Widget_Fill_By_Map {
+	_map = null;
+	_setChanged = null;
+
+	constructor(map, setChanged=false){
+		_setChanged = setChanged;
+		_map = map;
+	};
+
+	function set_widget_value_by_map(inputs){
+		foreach(fld_name, wdg in inputs){
+			set_widget_value(wdg, fld_name);
+		}
+	}
+
+	function setValue(fld_name, value){
+		_map[fld_name] <- value ? value : "";
+	}
+
+	function getValue(fld_name){
+		return _map.get(fld_name, "");
+	}
+	
+	function getValueInteger(fld_name){
+		local value = _map.get(fld_name, "");
+		return value.len() ? value.tointeger() : 0;
+	}
+
+	function set_widget_value(wdg, fld_name, asBlank=false, dflt=null){
+		if(wdg instanceof Fl_Text_Editor){
+			wdg->buffer()->text((asBlank) ? "" : getValue(fld_name));
+		}
+		else if(wdg instanceof Fl_Check_Button){
+			wdg->value((asBlank) ? (dflt ? 1 : 0) : getValueInteger(fld_name));
+		}
+		else if(wdg instanceof Fl_Choice_Str){
+			 wdg->my_set_value((asBlank) ? "" : getValue(fld_name));
+		}
+		else if(wdg instanceof Fl_Choice_Int){
+			 wdg->my_set_value((asBlank) ? (dflt ? dflt : -1) : getValueInteger(fld_name));
+		}
+		else if(wdg instanceof Flu_Combo_Box){
+			wdg->select_by_data((asBlank) ? (dflt ? dflt : 0) : getValueInteger(fld_name));
+		}
+		else if(wdg instanceof Flu_Tree_Browser){
+			local value = (asBlank) ? (dflt ? dflt : 0) : getValueInteger(fld_name);
+			wdg->unselect_all();
+			local item = wdg->find_by_user_data(value);
+			if(item){
+				wdg->set_hilighted(item);
+				wdg->select(item, true);
+				//clear changed because Flu_Tree_Browser will set it when select
+				wdg->clear_changed_all();
+			}
+		}
+		else if(wdg instanceof Fl_Input_){
+			wdg->value((asBlank) ? (dflt ? dflt : "") : getValue(fld_name));
+		}
+		if(_setChanged) wdg->set_changed2();
+	}
+}
+
 class DBUpdateByWidget extends DBTableUpdate
 {
 	constructor(){
@@ -354,34 +423,33 @@ class DBUpdateByWidget extends DBTableUpdate
 		foreach(fld_name, wdg in inputs){
 			//printf("%s : %s : %s\n", fld_name, wdg->classId(), Fl_Check_Button.className());
 			if(wdg instanceof Fl_Text_Editor){
-				get_widget_value(wdg, fld_name);
-				if((dbAction == e_insert) || wgt->changed2())
+				if((dbAction == e_insert) || wdg->changed2())
 				{
-					_field_changes.push([fld_name, wgt->buffer()->text()]);
+					_field_changes.push([fld_name, wdg->buffer()->text()]);
 				}
 			}
 			else if(wdg instanceof Fl_Check_Button){
-				if((dbAction == e_insert) || wgt->changed2())
+				if((dbAction == e_insert) || wdg->changed2())
 				{
-					_field_changes.push([fld_name, wgt->value() ? "1" : "0"]);
+					_field_changes.push([fld_name, wdg->value() ? "1" : "0"]);
 				}
 			}
 			else if(wdg instanceof Fl_Choice_Str){
-				if((dbAction == e_insert) || wgt->changed2())
+				if((dbAction == e_insert) || wdg->changed2())
 				{
-					_field_changes.push([fld_name, wgt->my_get_value()]);
+					_field_changes.push([fld_name, wdg->my_get_value()]);
 				}
 			}
 			else if(wdg instanceof Fl_Choice_Int){
-				if((dbAction == e_insert) || wgt->changed2())
+				if((dbAction == e_insert) || wdg->changed2())
 				{
-					_field_changes.push([fld_name, wgt->my_get_value_str()]);
+					_field_changes.push([fld_name, wdg->my_get_value_str()]);
 				}
 			}
 			else if(wdg instanceof Flu_Combo_Box){
-				if((dbAction == e_insert) || wgt->input.changed2())
+				if((dbAction == e_insert) || wdg->input.changed2())
 				{
-					_field_changes.push([fld_name, wgt->get_data_at().tostring()]);
+					_field_changes.push([fld_name, wdg->get_data_at().tostring()]);
 				}
 			}
 			else if(wdg instanceof Flu_Tree_Browser){
@@ -397,9 +465,9 @@ class DBUpdateByWidget extends DBTableUpdate
 				}
 			}
 			else if(wdg instanceof Fl_Input_){
-				if((dbAction == e_insert) || wgt->changed2())
+				if((dbAction == e_insert) || wdg->changed2())
 				{
-					_field_changes.push([fld_name, wgt->value()]);
+					_field_changes.push([fld_name, wdg->value()]);
 				}
 			}
 		}
@@ -416,65 +484,20 @@ class DBUpdateByWidget extends DBTableUpdate
 
 class EditWindow extends MyBaseWindow {
 	_record = null;
-	_id = null;
-	_main_table = null;
-	_version_ = null;
 	_dbUpdater = null;
-
+	_choiceDbAction = null;
+	_btnDbAction = null;
+	_formGroup = null;
+	
 	constructor(px, py, pw, ph, pl){
 		base.constructor(px, py, pw, ph, pl);
 		_record = {};
 	}
-	function get_record(id){
-		appServer.get_record(_record, _main_table, 0, id);
-	}
-	function show_id(id){
-		get_record(id);
-		_id = id;
-		local tbl_map = _db_map.get(_main_table, false);
-		if(tbl_map){
-			foreach(k, wdg in tbl_map){
-				if(_record.rawin(k)){
-					local value =  _record[k];
-					local classId = wdg->classId();
-					if(classId == Fl_Text_Editor.className()){
-						//set_widget_value((Fl_Text_Editor*)wdg, fld_name);
-					}
-					else if(classId == Fl_Check_Button.className()){
-						//set_widget_value((Fl_Check_Button*)wdg, fld_name);
-						wdg->value(value == "1" ? 1 : 0);
-					}
-					else if(classId == Fl_Choice.className()){
-						if(wdg instanceof Fl_Choice_Str){
-							if(value && value.len()) wdg->my_set_value(value);
-							else wdg->my_clear();
-						}
-						else if(wdg instanceof Fl_Choice_Int){
-							if(value && value.len()) wdg->my_set_value(value.tointeger());
-							else wdg->my_clear();
-						}
-					}
-					/*
-					else if(classId == Fl_Choice_Str.className()){
-						//set_widget_value((Fl_Choice_Str*)wdg, fld_name);
-					}
-					else if(classId == Fl_Choice_Int.className()){
-						//set_widget_value((Fl_Choice_Int*)wdg, fld_name);
-					}
-					else if(classId == Flu_Combo_Box.className()){
-						//set_widget_value((Flu_Combo_Box*)wdg, fld_name);
-					}
-					else if(classId == Flu_Tree_Browser.className()){
-						//set_widget_value((Flu_Tree_Browser*)wdg, fld_name);
-					}
-					*/
-					else if(wdg->inherits_from(Fl_Input_.cheap_rtti_info())){
-						//set_widget_value((Fl_Input_*)wdg, fld_name);
-						wdg->value(value);
-					}
-				}
-			}
-		}
+	function setDbActionControls(choice, btn){
+		_choiceDbAction = choice;
+		_choiceDbAction.callback(on_Change_dbAction);
+		_btnDbAction = btn;
+		_btnDbAction.callback(on_btnDbAction);
 	}
 	function fill_choice_by_data (choice, data)
 	{
@@ -486,56 +509,70 @@ class EditWindow extends MyBaseWindow {
 		}
 	}
 	
-	function on_Change_dbAction()
+	function on_Change_dbAction(sender=null, udata=null)
 	{
+		if(sender) this = sender->window();
 		local colors = [255, 95, 79, 90, 238, 238, 238, 238];
-		local idx = dbAction->action();
-		btnDbAction->label(dbAction->text());
-		btnDbAction->color(colors[idx]);
+		local idx = _choiceDbAction->action();
+		_btnDbAction->label(_choiceDbAction->text());
+		_btnDbAction->color(colors[idx]);
 	}
-	function on_btnDbAction()
+	function on_btnDbAction(sender, udata)
 	{
+		this = sender->window();
+		
 		local cursor_wait = fl_cursor_wait();
-		switch(dbAction->action())
-		{
-		case DbAction_Enum.e_insert:
-		    do_insert();
-		    break;
-		case DbAction_Enum.e_update:
-		    do_update();
-		    break;
-		case DbAction_Enum.e_delete:
-		    do_delete();
-		    break;
-		case DbAction_Enum.e_export:
-		    do_export();
-		    break;
-		case DbAction_Enum.e_import:
-		    do_import();
-		    break;
-		case DbAction_Enum.e_refresh:
-		    do_refresh();
-		    break;
-		case DbAction_Enum.e_copy:
-		    do_copy();
-		    break;
+		try {
+			switch(_choiceDbAction->action())
+			{
+			case DbAction_Enum.e_insert:
+			    do_insert();
+			    break;
+			case DbAction_Enum.e_update:
+			    do_update();
+			    break;
+			case DbAction_Enum.e_delete:
+			    do_delete();
+			    break;
+			case DbAction_Enum.e_export:
+			    do_export();
+			    break;
+			case DbAction_Enum.e_import:
+			    do_import();
+			    break;
+			case DbAction_Enum.e_refresh:
+			    do_refresh();
+			    break;
+			case DbAction_Enum.e_copy:
+			    do_copy();
+			    break;
+			}
 		}
+		catch(e){ fl_alert(e);}
+	}
+	function get_record_by_id(id){
+		appServer.get_record(_record, dbUpdater()->table_name, 0, dbUpdater()->edit_id);
 	}
 	function do_edit(aid){
 		local dbu = dbUpdater();
 		dbu->edit_id = aid;
 		dbu->version = 0;
-		dbAction->action(aid ? DbAction_Enum.e_update : Fl_Choice_dbAction::e_insert);
+		dbAction->action(aid ? DbAction_Enum.e_update : DbAction_Enum.e_insert);
 		on_Change_dbAction();
 		delayed_method_call(this, this.do_edit_delayed, aid);
 	}
-	function do_edit_delayed(udata){}
+	function do_edit_delayed(udata)
+	{
+		local cursor_wait = fl_cursor_wait();
+		get_record_by_id(udata);
+		fill_edit_form(dbUpdater()->edit_id == 0);
+	}
 	function fill_edit_form(asBlank=false){
 		if(asBlank) _record.clear();
-		local  wfq = WidgetFillByMap(_record);
+		local  wfq = Widget_Fill_By_Map(_record);
 		local input_fld_map = get_input_fields(dbUpdater()->get_fields_map_name());
-		wfq.set_widget_value(input_fld_map);
-		wfq.get("_version_", dbUpdater()->version);
+		wfq.set_widget_value_by_map(input_fld_map);
+		dbUpdater()->version = wfq.getValueInteger("_version_");
 	}
 	function get_widget_changed(uw){
 		local input_fld_map = get_input_fields(dbUpdater()->get_fields_map_name());
@@ -544,7 +581,7 @@ class EditWindow extends MyBaseWindow {
 	function do_insert(){
 		//fl_alert("do_insert");
 		local dbu = dbUpdater();
-		dbu->dbAction = edbAction.e_insert;
+		dbu->dbAction = dbu.e_insert;
 		dbu->clear();
 		get_widget_changed(dbu);
 		dbu->insert_table();
@@ -555,7 +592,7 @@ class EditWindow extends MyBaseWindow {
 	function do_update(){
 		//fl_alert("do_update");
 		local dbu = dbUpdater();
-		dbu->dbAction = edbAction.e_update;
+		dbu->dbAction = dbu.e_update;
 		dbu->clear();
 		get_widget_changed(dbu);
 		dbu->update_table();
@@ -564,7 +601,7 @@ class EditWindow extends MyBaseWindow {
 	function do_delete()	{
 		//fl_alert("do_delete");
 		local dbu = dbUpdater();
-		dbu->dbAction = edbAction.e_delete;
+		dbu->dbAction = dbu.e_delete;
 		dbu->clear();
 		dbu->delete_record();
 		dbAction->action(DbAction_Enum.e_insert);
@@ -895,7 +932,7 @@ class MyListSearchWindow extends ListSearch {
 		local edit_window = get_edit_window();
 		if(edit_window){
 			edit_window.show();
-			edit_window.show_id(grid->get_row_id());
+			edit_window.do_edit(grid->get_row_id());
 			switch(ev){
 				case Fl_Data_Table_Events.e_select:
 				break;
@@ -1069,9 +1106,17 @@ function print_entities_list_contact_report()
 }
 
 class MyEditEntityWindow extends EditEntityWindow {
+	_sab = null;
 	constructor(){
 		base.constructor();
-		_main_table = "entities";
+		dbUpdater()->table_name = "entities";
+		_sab = 'A';
+		setDbActionControls(dbAction, btnDbAction);
+	}
+	function do_edit_delayed(udata)
+	{
+		base.do_edit_delayed(udata);
+		delayed_focus(db_entities_name);
 	}
 }
 
@@ -1200,13 +1245,18 @@ function print_products_list()
 }
 
 class MyEditProductWindow extends EditProductWindow {
+	_sab = null;
 	constructor(){
 		base.constructor();
-		_main_table = "products";
+		dbUpdater()->table_name = "products";
+		_sab = 'A';
+		setDbActionControls(dbAction, btnDbAction);
 		load_aux_data();
 	}
-	function show_id(id){
-		base.show_id(id);
+	function do_edit_delayed(udata)
+	{
+		base.do_edit_delayed(udata);
+		delayed_focus(db_products_sell_description);
 		local image_id = _record.get("image_id", false);
 		if(image_id) button_show_db_image(btnImage, image_id.tointeger(), null, false, false);
 		else {
@@ -1389,7 +1439,6 @@ class MyEditOrderWindow extends EditOrderWindow {
 		btnCalcDelivery.callback(cb_btnCalcDelivery);
 		btnShowCalendar.callback(cb_btnShowCalendar);
 		btnSearchEntity.callback(cb_btnSearchEntity);
-		delayed_method_call(this, this.do_edit_delayed, null);
 	}
 	function on_first_time_show(){
 		local data = [];

+ 32 - 24
SquiLu-ourbiz/ourbiz.nut

@@ -33,9 +33,9 @@ function escape_sql_like_search_str(str){
 }
 
 function mkEmptyWhenZero(tbl, key){
-	if (type(key) == "table"){
-		foreach( k,v in key ) {
-			if (tbl[v] == "0") tbl[v] = "";
+	if (type(key) == "array"){
+		foreach( v in key ) {
+			if (tbl.get(v, false) == "0") tbl[v] = "";
 		}
 	}
 	else if (tbl[key] == 0) tbl[key] = "";
@@ -211,8 +211,8 @@ class DB_Manager {
 		}
 		local result = stmt.step();
 		stmt.finalize()
-		if (result == sqlite3.DONE) return db.last_insert_rowid();
-		throw db.error_message();
+		if (result == SQLite3Stmt.DONE) return db.last_insert_rowid();
+		throw db.errmsg();
 	}
 
 	function db_update(db, data){
@@ -230,8 +230,7 @@ class DB_Manager {
 		if (has_version) mf.write(", _version_=_version_+1 ");
 
 		mf.write(" where id=? ");
-		if (self.has_version) mf.write(" and _version_=?");
-
+		if (has_version) mf.write(" and _version_=?");
 		local stmt = db.prepare(mf.tostring());
 		local x = 0;
 		foreach( k,v in editable_fields) {
@@ -244,8 +243,8 @@ class DB_Manager {
 
 		local result = stmt.step();
 		stmt.finalize();
-		if (result == sqlite3.SQLITE_DONE) return db.changes();
-		throw db.error_message();
+		if (result == SQLite3Stmt.SQLITE_DONE) return db.changes();
+		throw db.errmsg();
 	}
 
 	function db_delete(db, data){
@@ -259,8 +258,8 @@ class DB_Manager {
 
 		local result = stmt.step();
 		stmt.finalize();
-		if (result == sqlite3.DONE) return db.changes();
-		throw db.error_message();
+		if (result == SQLite3Stmt.DONE) return db.changes();
+		throw db.errmsg();
 	}
 
 	function sql_get_one(req) {
@@ -831,10 +830,10 @@ class  CalcOrderTotals
 	{
 		out_result.write("[[");
 		dumpSLEFieldNames(out_result);
-		out_result.write(SLEEND);
+		out_result.writen(SLE_SLEEND, 'c');
 		out_result.write("][");
 		dumpSLEFieldValues(out_result);
-		out_result.write(SLEEND);
+		out_result.writen(SLE_SLEEND, 'c');
 		out_result.write("]");
 	}
 
@@ -1453,8 +1452,6 @@ from product_kits as pk left join products as p on pk.product_id = p.id
 where pk.kit_id = %d]==], kit_id);
 }
 
-constants.SLE <- "\xff";
-
 function add2sle(out_result, str){
 	str = str.tostring();
 	out_result.write(get_sle_size(str.len()), str);
@@ -1473,7 +1470,8 @@ function dump_group_tree_childs(parent, out_result, parent_map, data_map){
 				add2sle(out_result, id);
 				add2sle(out_result, myparent);
 				add2sle(out_result, data_map[id]);
-				out_result.write(SLE, "]");
+				out_result.writen(SLE_SLEEND, 'c');
+				out_result.write("]");
 				dump_group_tree_childs(id, out_result, parent_map, data_map);
 			}
 			break;
@@ -1500,7 +1498,8 @@ function group_dump_data(db, out_result, tbl){
 	add2sle(out_result, "id");
 	add2sle(out_result, "parent_id");
 	add2sle(out_result, "description");
-	out_result.write(SLE, "]");
+	out_result.writen(SLE_SLEEND, 'c');
+	out_result.write("]");
 	dump_group_tree_childs(0, out_result, parent_map, group_map);
 	out_result.write("]");
 }
@@ -1571,7 +1570,7 @@ Content-Length: %d
 
 		if (sql){
 			local stmt = db.prepare(sql);
-			//debug_print(sql, "\n", db.error_message(), "\n")
+			//debug_print(sql, "\n", db.errmsg(), "\n")
 			data = stmt.asSleArray();
 			stmt.finalize();
 		}
@@ -1716,7 +1715,7 @@ function ourbizDbGetBin(request){
 function ourbizDbAction(request){
 	local isPost = request.info.request_method == "POST";
 	if (isPost){
-		local data = get_post_fields(10*1024);
+		local data = get_post_fields(request, 10*1024);
 		local db = getOurbizDB();
 		local tbl = data.get("__table__", null);
 		local action = data.get("__action__", null);
@@ -1729,20 +1728,29 @@ function ourbizDbAction(request){
 				result = db_manager.db_action(db, data);
 			} catch(e){
 				err_msg = e;
+				if(AT_DEV_DBG) foreach(k,v in get_last_stackinfo()) debug_print("\n", k, ":", v)
 			}
 		}
-		if (result){
+		if (result != null){
 			gmFile.clear();
 			gmFile.write("[[");
 			if (action == "insert") add2sle(gmFile, "id");
 			else add2sle(gmFile, "changes");
 
-			gmFile.write(SLE, "][");
-			add2sle(gmFile, result);
-			gmFile.write(SLE, "]]");
+			gmFile.writen(SLE_SLEEND, 'c');
+			gmFile.write("][");
+			add2sle(gmFile, result.tostring());
+			gmFile.writen(SLE_SLEEND, 'c');
+			gmFile.write("]]");
 			data = gmFile.tostring();
 		}
-		else if (err_msg) data = err_msg;
+		else if (err_msg) {
+			gmFile.clear();
+			gmFile.write("HTTP/1.1 500 Internal Server Error\r\nContent-Type: text/plain; charset=utf-8\r\nContent-Length: ", err_msg.len(), "\r\n\r\n", err_msg);
+			//debug_print(tostring(gmFile), "\n")
+			request.write_blob(gmFile);
+			return true;
+		}
 		else data = null;
 
 		//debug_print(data, "\n")

+ 4 - 3
SquiLu-ourbiz/sq-server-plugin.nut

@@ -245,12 +245,13 @@ function parse_post_data(input_type, data, tab = null){
 	if (input_type.find("x-www-form-urlencoded") >= 0) parse_qs(data, tab);
 	else if (input_type.find("multipart/form-data") >= 0) parse_multipart_data(data, input_type, tab);
 	else if (input_type.find("SLE") >= 0) {
-		local vv = sle2vecOfvec(data);
+		local vv = [];
+		sle2vecOfvec(data, vv);
 		if (vv.len() > 0) {
 			local names = vv[0];
 			local values = vv[1];
 			for (local i=0, len = names.len(); i < len; ++i){
-				tab[names[i]] = values[i];
+				tab[names[i]] <- values[i];
 			}
 		}
 	}
@@ -814,7 +815,7 @@ function getExtraCompanyData(cid, cnum){
 		stmt2.bind(1, cid);
 		stmt2.bind(2, data);
 		stmt2.step();
-		//debug_print("company_extra_data", checkCompaniesUkDB():error_message())
+		//debug_print("company_extra_data", checkCompaniesUkDB():errmsg())
 		stmt2.reset();
 		return data;
 	} catch(e){