I want to pick the balance (flowfield)record from customer table to the Bill Table. I have a Customer table and a BillPros table.
The balance in the customer table is a flowfield.
//Customer on Variable Band Billing
Customers.RESET;
Customers.SETCURRENTKEY(Customers."No.");
Customers.SETFILTER(Customers."No.",'%1',MeterR."Customer Number");
Customers.SETFILTER(Customers."Customer Posting
Group",'%1',Surcharge."Customer Posting Group");
Customers.CALCFIELDS("Balance (LCY)");
Bal := Customers."Balance (LCY)";
IF Customers.FIND('-')THEN
//Post Metre Reading;
PostReading.RESET;
PostReading.Date := MeterR.Period;
PostReading.MetreID :=MeterR."Metre ID";
PostReading."Last Reading" := MeterR."Metre Reading";
PostReading.INSERT;
//Bill Info Process
TotalAmount:=0;
BillPros.INIT;
BillPros."Customer No." := MeterR."Customer Number";
BillPros.Consumption := TotalReading;
BillPros.Rate := Bands."Rate Amount";
BillPros."Invoice No." := MeterR."Invoice Number";
BillPros.Amount := TotalReading*Bands."Rate Amount";
BillPros.Balance := Bal;
Your code is wrong. You should call the CALCFIELDS after the FIND('-'). Before that you "don't have" the actual Customer Record. And you don't need the Bal variable. You can write BillPros.Balance := Customer."Balance (LCY)";
Use findset then inside the findset function do the calcfield instead
IF Customers.FIND THEN
Customers.CALCFIELDS("Balance (LCY)");
Bal := Customers."Balance (LCY)";
Related
I'm trying to mock a method written with sqlboiler but I'm having massive trouble building the mock-query.
The model I'm trying to mock looks like this:
type Course struct {
ID int, Name string, Description null.String, EnrollKey string, ForumID int,
CreatedAt null.Time, UpdatedAt null.Time, DeletedAt null.Time,
R *courseR, L courseL
}
For simplicity I want to test the GetCourse-method
func (p *PublicController) GetCourse(id int) (*models.Course, error) {
c, err := models.FindCourse(context.Background(), p.Database, id)
if err != nil {
return nil, err
}
return c, nil
}
with this test
func TestGetCourse(t *testing.T) {
db, mock, err := sqlmock.New()
if err != nil {
t.Fatalf("an error '%s' was not expected", err)
}
oldDB := boil.GetDB()
defer func() {
db.Close()
boil.SetDB(oldDB)
}()
boil.SetDB(db)
ctrl := &PublicController{db}
rows := sqlmock.NewRows([]string{"ID", "Name", "Description", "EnrollKey", "ForumID"}).AddRow(42, "Testkurs", "12345", 33)
query := regexp.QuoteMeta("SELECT ID, Name, Description, EnrollKey, ForumID FROM courses WHERE ID = ?")
//mockQuery := regexp.QuoteMeta("SELECT * FROM `courses` WHERE (`course AND (`courses`.deleted_at is null) LIMIT 1;")
mock.ExpectQuery(query).WithArgs(42).WillReturnRows(rows)
course, err := ctrl.GetCourse(42)
assert.NotNil(t, course)
assert.NoError(t, err)
}
But running this test only returns
Query: could not match actual sql: "select * from course where id=? and deleted_at is null" with expected regexp "SELECT ID, Name, Description, EnrollKey, ForumID FROM courses WHERE ID = ?"
bind failed to execute query
And I can't really find out how to construct it correctly.
How do I correctly mock the sqlboiler-query for running unit tests?
UPDATE
I managed to solve this by using different parameters in AddRow()
.AddRow(c.ID, c.Name, null.String{}, c.EnrollKey, c.ForumID)
and building the query differently
query := regexp.QuoteMeta("select * from `course` where `id`=? and `deleted_at` is null")
Now my issue is that in contrast to this method the others have a very large complexity in comparison with a large amount of complex queries (mainly insert-operations). From my understanding, sqlboiler-tests needs to mimic every single interaction made with the database.
How do I extract the necessary queries for the large amount of database interactions? I solved my problem by just using the "actual sql-query" instead of the previously used one but I'm afraid this procedure is the opposite of efficient testing.
I tried searching, but can't find how to do this.
I want to take instances of my struct and store them in a list, then iterate over them and call a function on them.
type comicBook struct {
Title string
Writer string
Artist string
Publisher string
Year int
Pages int
Grade float32
}
func (c comicBook) PrintInfo() {
fmt.Println(c.Title, "written by", c.Writer, "drawn by", c.Artist, "published by", c.Publisher, "in", c.Year)
fmt.Println("Pages:", c.Pages)
fmt.Println("Grade:", c.Grade)
}
This works fine.
c := comicBook.NewComicBook(
"Mr. GoToSleep",
"Tracey Hatchet",
"Jewel Tampson",
"DizzyBooks Publishing Inc.",
1997,
14,
6.5,
)
c.PrintInfo()
c2 := comicBook.NewComicBook("Epic Vol. 1",
"Ryan N. Shawn",
"Phoebe Paperclips",
"DizzyBooks Publishing Inc.",
2013, 160, 9.0)
c2.PrintInfo()
Storing them in a list does not.
comicBookList := list.New()
comicBookList.PushBack(c)
comicBookList.PushBack(c2)
fmt.Println("\nNow from a list!\n")
for comic := comicBookList.Front(); comic != nil; comic = comic.Next() {
comic.Value.PrintInfo()
}
This fails with comic.Value.PrintInfo undefined (type interface {} is interface with no methods)
container/list is not "generic" and operates on interface{} values. To get "typed" values out of it, you have to use type assertion:
for comic := comicBookList.Front(); comic != nil; comic = comic.Next() {
comic.Value.(comicBook).PrintInfo()
}
Try it on the Go Playground.
But you shouldn't use container/list in the first place.
Instead use a slice. Slices are generic (with the help of the compiler):
var books []comicBook
To add a value to the slice, use the builtin append():
b := comicBook.NewComicBook(...)
books = append(books, b)
To iterate over the slice, use for range:
for _, b := range books {
b.PrintInfo()
}
Try it on the Go Playground.
#icza's answer is the best approach. That said, you can use type assertion.
for comic := comicBookList.Front(); comic != nil; comic = comic.Next() {
realComic, ok := comic.Value.(comicBook)
if !ok {
panic("this would error anyway, but good for visibility")
}
realComic.PrintInfo()
}
Does anyone have code that replaces a value in selected document of a view using a customized icon on the toolbar. I remember this was done using Formulas but cannot find anymore on the web.
Thanks,
Tim
Create a custom icon in the toolbar preferences and put this code in the formula window. Show the icon in all views. While in a view, it will prompt you for the field, its type and its value. Then it will replace that value in the field without ever opening the document.
Found this in one of the public Lotus Notes forums a long time ago. If anyone knows the original creator, please name them here for credit they deserve.
REM {Get a listing of all the fields on the current document};
List := #DocFields;
REM {Possible data types to choose from.};
REM {I called Number Integer because use keyboard to select what you want with keyboard quicker.};
DataTypes := "Text" : "Date" : "Integer" : "Password" : "Name" : "Common Name" : "**** Remove Field ****" : "Text Multi Value" : "Date Multi Value" : "Integer Multi Value" : "Name Multi Value";
REM {Prompt for which field needs to be updated.};
EditField := #Prompt([OkCancelList]; "Select Field To Update"; "Select the field you wish to update:"; ""; List : "**** ADD A NEW FIELD ****");
REM {If adding a new field, prompt for the field name};
NewFieldName := #If(EditField = "**** ADD A NEW FIELD ****"; #Prompt([OkCancelEdit]; "Enter Field Name"; "Enter the name of the new field:"; ""); "");
CheckFieldName := #If(#IsMember(NewFieldName; List) & NewFieldName != ""; #Return(#Prompt([Ok]; "Already In List"; "The field " + NewFieldName + " already exists on the document.")); "");
UpdateVariable := #If(NewFieldName = ""; ""; EditField := NewFieldName);
REM {Prompt for which data type you would like the data to be};
REM {This needs to be done before value prompt to determine if the};
REM { Picklist or any prompting needs to be used.};
DataType := #Prompt([OkCancelList] : [NoSort]; "Choose Data Type"; "Please Select the correct data type or action for field: " + EditField; "Text"; DataTypes);
REM {For multi-valued fields, let the user choose the separator to use};
Separator := #If(#Contains(DataType; "Multi Value"); #Prompt([OkCancelList] : [NoSort]; "Choose Separator"; "Choose the separator to split out your multiple values"; ":"; (":" : ";" : "+" : "-" : "*")); "");
REM {Pull out the current value of the field};
CurrValue1 := #Eval(#Text(EditField));
CurrValue2 := #Abstract([TextOnly]; 254; ""; #Text(EditField));
CurrValue := #If(#IsNumber(CurrValue1) | #IsTime(CurrValue1); #Implode(#Text(CurrValue1); Separator); CurrValue2 != ""; CurrValue2; #Implode(#Text(CurrValue1); Separator));
REM {Based on what type of data is being entered different prompts will happen if any at all.};
RawValue := #If(
#Contains(DataType; "Name Multi Value"); #PickList([Name]);
#Contains(DataType; "Name"); #PickList([Name] : [Single]);
DataType = "**** Remove Field ****"; "";
#Contains(DataType; "Multi Value"); #Prompt([OkCancelEdit]; "New Value"; "Please enter the new desired value for: " + EditField + " seperated with " + Separator + " for each value."; CurrValue);
#Prompt([OkCancelEdit]; "New Value"; "Please enter the new desired value for: " + EditField + "."; CurrValue)
);
REM {If data conversion doesn't work then don't set field.};
#If(
DataType = "Date"; #If(#SetField(EditField; #TextToTime(RawValue)));
DataType = "Integer"; #If(#IsError(#TextToNumber(RawValue)); ""; #SetField(EditField; #TextToNumber(RawValue)));
DataType = "Password"; #SetField(EditField; #Password(RawValue));
DataType = "**** Remove Field ****"; #SetField(EditField; #DeleteField);
DataType = "Text Multi Value"; #SetField(EditField; #Explode(RawValue; Separator));
DataType = "Date Multi Value"; #SetField(EditField; #TextToTime(#Explode(RawValue; Separator)));
DataType = "Integer Multi Value"; #If(#IsError(#TextToNumber(#Explode(RawValue; Separator))); ""; #SetField(EditField; #TextToNumber(#Explode(RawValue; Separator))));
DataType = "Name Multi Value"; #SetField(EditField; #Explode(#Name([Canonicalize]; RawValue); Separator));
#SetField(EditField; RawValue)
);
""
Trying to update table by user specified values. But the values are not getting updated.
cout<<"\nEnter Ac No"<<endl;
cin>>ac;
cout<<"\nEnter Amount"<<endl;
cin>>amt;
/* Create merged SQL statement */
sql = "UPDATE RECORDS set BAL = '%d' where ACCOUNT_NO = '%d'",amt, ac;
/* Execute SQL statement */
rc = sqlite3_exec(db, sql, callback, (void*)data, &zErrMsg);
If I replace BAL and ACCOUNT_NO by some integer value instead of place holder then it is working fine.
Your sql string is not being created properly.
If you expect this code
sql = "UPDATE RECORDS set BAL = '%d' where ACCOUNT_NO = '%d'",amt, ac;
to result in
"UPDATE RECORDS set BAL = '1' where ACCOUNT_NO = '2'"
where
amt= 1 and ac = 2 then you need to use a string formatting call like this.
// the buffer where your sql statement will live
char sql[1024];
// write the SQL statment with values into the buffer
_snprintf(sql,sizeof(sql)-1, "UPDATE RECORDS set BAL = '%d' where ACCOUNT_NO = '%d'",amt, ac);
buff[sizeof(sql)-1]='\0';
On your particular platform _snprintf(...) might be snprintf(..) or another similarly named function. Also your compiler may warn about buffer manipulation security vulnerabilities. Choose the appropriate substitute for your needs
I'm trying to represent money in a go template.
{{.cash}}
But right now, cash comes as 1000000
Would it be possible to make it output 1,000,000 ?
Is there some sort of {{.cash | Currency}} formatter?
If not, how do I go about getting the desired output?
Thanks.
You can leverage github.com/dustin/go-humanize to do this.
funcMap := template.FuncMap{
"comma": humanize.Comma,
}
t := template.New("").Funcs(templateFuncs).Parse(`A million: {{comma .}}`)
err := tmpl.Execute(os.Stdout, 1000000)
if err != nil {
log.Fatalf("execution: %s", err)
}
// A million: 1,000,000