Odoo OpenERP 8 invoice number custom - numbers

I'm coding an invoice inherited from account.invoice, the class looks like
class my_invoice(models.Model):
_inherit = 'account.invoice'
my_number = fields.Char(store=True, compute='_compute_my_number')
my_sequence = fields.Many2One(comodel_name='my_sequence.model')
#api.one
#api.depends('state')
def _compute_my_number(self):
if self.state == 'draft':
self.my_number = 'DRAFT:' + self.my_sequence.number
elif self.state == 'open':
self.my_number = 'OPEN:' + self.my_sequence.number
elif self.state == 'paid':
self.my_number = 'PAID:' + self.my_sequence.number
Well, and I made a new view inherited from account.invoice_form including on it the field my_number
The problem is, everything works fine when the invoice is draft or open but when I make a payment, then my_number is empty.
Any ideas

Related

write a test class for apex class

I am new to apex, I'm interested in writing a test class for the following controller, but not sure where to begin. Here is my apex class code.
public class tree {
public Account acct{get;set;}
//private final Account acct;
public ApexPages.StandardController stdController {get;set;}
public tree(ApexPages.StandardController stdController) {
stdController.addFields(new String[]{'Id','Tete_de_groupe__c'});
this.acct = (Account)stdController.getRecord();
// this.stdController = stdController;
}
public List<Account> listOfAccount(){
List<Account> acctList;
if (acct.Tete_de_groupe__c == null){
acctList = [SELECT Name,Parent.Name,id,Code_NAF__c ,Industry ,RecordType.Name,Adresse_Agence__c, Tete_de_groupe__c,Statut__c
FROM Account
where id = :this.acct.id or Tete_de_groupe__c = :this.acct.id ];}
else {
acctList = [Select Name,Parent.Name,id,Tete_de_groupe__c,Statut__c
from Account
where id = :this.acct.Tete_de_groupe__c or Tete_de_groupe__c = :this.acct.Tete_de_groupe__c];}
return acctList;
}
Public String getaccountdata(){
String datastr1 = '';
String datastr2 = '';
String datastr = '';
List<Account> lstOfAcc =listOfAccount();
for (integer i=0;i<lstOfAcc.size();i++){
if (lstOfAcc[i].Parent.Name == null){
datastr1 = datastr1 + '{"name": "';
datastr1+= lstOfAcc[i].Name;
datastr1+= '","parent": ';
datastr1+= lstOfAcc[i].Parent.Name;
datastr1+= ',"accountid": "';
datastr1+= lstOfAcc[i].id;
datastr1+= '","Statut__c": "';
datastr1+= lstOfAcc[i].Statut__c;
datastr1+='" }';
}
else{
datastr2 = datastr2 + '{"name": "';
datastr2+= lstOfAcc[i].Name;
datastr2+= '","parent": "';
datastr2+= lstOfAcc[i].Parent.Name;
datastr2+= '","accountid": "';
datastr2+= lstOfAcc[i].id;
datastr2+= '","Statut__c": "';
datastr2+= lstOfAcc[i].Statut__c;
datastr2+='" },';
}
}
if(datastr2 == ''){datastr = '[' + datastr1 + ']';}
else {
datastr2 = datastr2.substring(0,datastr2.length()-1);
datastr = '[' + datastr1 +','+ datastr2 + ']'; }
return datastr;
}
}
I want to create test class. Guys need help if some one can tell me about test class of this apex class.
AParise pointed out the consideration. What you need to do in your test class, step by step:
Insert some account objects into the database (the test runs doesn't see any data by default, and that's OK)
Keep the ID from the first account and use it for Tete_de_groupe__c for the others.
Call the function, roughly like this:
Account mainAccount = populateTestAccounts(); // Helper function
Tree t = new Tree();
t.setAcct(mainAccount);
String result = t.getaccountdata();
assert(....);
That should do the trick!
For unit tests regarding classes like the one you posted, the easiest way is to think about expected results given a code path. For each test method, ask yourself: "Given this set of data, when I invoke this method, I expect this to occur".
Let's walk through your "getaccountdata" method.
"Given this set of data..." - What data does this method require for proper execution? Without diving too deep into your logic, this probably means inserting some Account sObjects.
"When I invoke this method..." - the "getaccountdata" method is being invoked.
"I expect this to occur..." - This is where your assertions come into play. You created the Account sObjects with specific values, so verify that these values propagated into your method return value.

Apex class is called in a trigger based on some conditions.Test class passes the test but code coverage is stil 0%

When work order updates to Completed then a new water meter reading record needs to created with two field values from work order and two from another object att. Both work order and water meter reading have a look up(workorder) and master detail relation(water meter reading) with att.Sorry for so much code,but I am really stuck and need help.
trigger CreateWaterMeterReading on sm1e__smWork_Order__c (after update)
{
if (Trigger.new.size() == 1)
{
sm1e__smWork_Order__c wo = Trigger.new[0];
if(wo.sm1e__WO_Type__c == 'Meter Read Move In/Out ' && wo.sm1e__Status__c == 'Completed')
reateNewWaterMeterRead.createWMRforMoveInOrOut(wo.Id);
}
}
--Apex class
public class CreateNewWaterMeterRead {
public static void createWMRforMoveInOrOut(string workorderId)
{
Work_Order__c wo = [Select Equipment__r.Name,Completion_Date__c,Meter_Reading__c from Work_Order__c where Id = : workorderId ];
Equipment__c att = [Select Id,Last_Water_Meter_Reading_Date__c,Last_Water_Meter_Reading__c from Equipment__c where Name = : wo.Equipment__r.Name ];
List<Water_Meter_Readings__c> newwmr = new List<Water_Meter_Readings__c>();
Water_Meter_Readings__c wmr = new Water_Meter_Readings__c();
wmr.Meter__c = att.Id;
wmr.Current_Meter_Reading__c = wo.Meter_Reading__c;
wmr.Current_Read_Date__c = wo.sm1e__Completion_Date__c;
wmr.Prior_Meter_Reading__c = att.Last_Water_Meter_Reading__c;
wmr.Prior_Read_Date__c = att.Last_Water_Meter_Reading_Date__c;
wmr.Source__c = 'Manual Read';
newwmr.add(wmr);
if(newwmr.size() >0)
insert newwmr;
}
--Test Class
isTest(SeeAllData = true)
public class CreateNewWaterMeterReadTest
{
static testmethod void createWMRforMoveInOrOut()
{
Work_Order__c wo = [Select Id,Equipment__r.Name,Completion_Date__c,Meter_Reading__c from Work_Order__c where sm1e__Status__c != 'Completed' AND sm1e__WO_Type__c = 'Meter Read Move In/Out' LIMIT 1];
Equipment__c att = [Select Id,Last_Water_Meter_Reading_Date__c,Last_Water_Meter_Reading__c from Equipment__c where Name = : wo.Equipment__r.Name ];
test.startTest();
wo.Meter_Reading__c = 1317;
wo.sm1e__Status__c = 'Completed';
update wo;
test.stopTest();
System.debug('updated wo');
Water_Meter_Readings__c wmr = new Water_Meter_Readings__c();
System.debug('wmr for test');
wmr.Meter__c= att.Id;
wmr.Current_Meter_Reading__c = wo.Meter_Reading__c;
wmr.Current_Read_Date__c = wo.Completion_Date__c;
System.debug('in between wmr');
wmr.Prior_Meter_Reading__c = att.Last_Water_Meter_Reading__c;
wmr.Prior_Read_Date__c = att.Last_Water_Meter_Reading_Date__c;
wmr.Source__c = 'Manual';
insert wmr;
You've written trigger on after update. But in your test class you're inserting a record and not updating it. That is why your code coverage is 0%. Refer to this link
For executing trigger you must do dml operation for which you've written a trigger. Also you can invoke your class method from test class by creating its instance. Refer above link for the same.

How can you populate a WTForms FieldList after the validate_on_submit() block?

There is a real lack of documentation on how to work with WTForms' FieldList. So thanks to the internet I've been able to hack together the following:
Form:
class BranchForm(Form):
name = StringField('Name', validators = [Required()])
equipment = FieldList(SelectField('Equipment', validators=[Required()], coerce=int,
choices = [(x.id, x.name) for x in Equipment.query.all()]))
mod = FieldList(StringField('Method of Delivery', validators = [Optional()]))
View:
def edit_branch(id):
branch = Branch.query.filter_by(id=id).first()
#populate data_in to be used by BranchForm
data_in = []
for eq_obj in branch.equipment_assoc:
data_in.append(('equipment', eq_obj.equipment.id))
data_in.append(('mod', eq_obj.mod))
editform = BranchForm(data=MultiDict(data_in))
if editform.validate_on_submit():
branch.name = editform.name.data
db.session.add(branch)
db.session.commit()
return redirect('/admin/branches/' + str(branch.id))
editform.name.data = branch.name
return render_template("branch_edit.html",
title="Edit Branch",
branch = branch,
editform = editform)
What's throwing me off is that everywhere else that I've used a WTForm Form and populated the fields with data from my db (like for edit forms), I've had to populate these form fields after the form.validate_on_submit() block, because if not, then the form will never update as whatever is submitted is immediately overwritten.
See "editform.name.data = branch.name" (this is how I've always done it)
From every example I've found online about populating a FieldList, it apparently must be done during instantiation, but the form has to be instantiated before the validate_on_submit() as well because validate_on_submit() is a method of the form object.
See "editform = BranchForm(data=MultiDict(data_in))" (this is how I've seen FieldLists populated in all the examples I've seen.)
How can I go about populating my form with its field lists?
Alright, so a buddy helped me figure this one out. Here's what I ended up with:
Form:
class BranchForm(Form):
name = StringField('Name', validators = [Required()])
equipment = FieldList(SelectField('Equipment', validators=[Required()], coerce=int,
choices = [(x.id, x.name) for x in Equipment.query.all()]))
mod = FieldList(StringField('Method of Delivery', validators = [Optional()]))
def populate_assoc(self, branch_obj):
i = 0
branch_obj.name = self.name.data
for assoc_obj in branch_obj.equipment_assoc:
assoc_obj.equipment_id = self.equipment[i].data
assoc_obj.mod = self.mod[i].data
i += 1
View:
def edit_branch(id):
branch = Branch.query.filter_by(id=id).first()
if request.method == 'POST':
editform = BranchForm()
if editform.validate_on_submit():
editform.populate_assoc(branch)
db.session.add(branch)
db.session.commit()
return redirect('/admin/branches/' + str(branch.id))
#populate data_in to be used
data_in = []
for eq_obj in branch.equipment_assoc:
data_in.append(('equipment', eq_obj.equipment.id))
data_in.append(('mod', eq_obj.mod))
editform = BranchForm(data=MultiDict(data_in))
editform.name.data = branch.name
return render_template("branch_edit.html",
title="Edit Branch",
branch = branch,
editform = editform)
The trick was really to step away from using form.validate_on_submit() as my logic separator, since it relies on the form object. His idea was to use the if request.method == 'POST': for this purpose. This way I can instantiate my form in two different ways. One gets populated for display, the other is only instantiated if the request method is POST, thus retaining the information submitted in the form.
To finish the job I added the populate_assoc method to my form class so that I can easily place the information from the form into my association model.
WtForms has a populate_obj() method. Maybe that's what you're after?
def edit_branch(id):
branch = Branch.query.filter_by(id=id).first()
editform = BranchForm(obj=branch)
if editform.validate_on_submit():
editform.populate_obj(branch)
db.session.commit()
return redirect('/admin/branches/' + str(branch.id))
return render_template("branch_edit.html",
title="Edit Branch",
branch = branch,
editform = editform)

Getting a script to trigger when only a specific form is submitted - Google Script / Sheets / Forms

I feel like this should be so easy and obvious, but I cannot figure it out...
I am working with 2 forms and 2 spreadsheets. Form 1 submits to Sheet 1. On Sheet 1, for each record, there is a link that takes the user to Form 2, which is half pre-populated with data from Sheet 1. When the user submits Form 2, it populates Sheet 2.
I have a couple of scripts that are supposed to be triggered when Form 1 is submitted. I am using the "From Spreadsheet" "OnFormSubmit" trigger. The scripts, however, are also triggering when Form 2 is submitted.
How can I make it so the scripts only execute when Form 1 is submitted? Also, is there a way to ensure that scripts trigger in a specific order?
If it helps, the scripts are below. They all work properly as is, except for the triggering issue. I know that I can merge the 2nd and 3rd script, and I will, but I'd like to fix this triggering issue first, as I'm getting double the emails every time I test.
1st script:
function onFormSubmit(e) {
//Uses time in milleseconds to create unique ID #
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName("ComplaintLog");
var d = new Date();
var n = d.getTime();
var lastRow = sheet.getLastRow();
var cell = sheet.getRange("BA" + lastRow);
cell.setValue(n);
var cell = sheet.getRange("BB" + lastRow);
cell.setFormula("=right(BA"+lastRow+",6)");
sheet.getRange("BB"+lastRow).copyTo(sheet.getRange("BC"+lastRow), +
{contentsOnly:true});
}
2nd script:
function formSubmitReply(e) {
//Sends email to certain users when a new complaint has been entered
var emailAddresses = 'person#organzation.com';
MailApp.sendEmail(emailAddresses,
"person#organzation.com",
"New Guest Complaint",
"A new guest complaint has been entered into the database."
+ "\n\n To vew the database, click here: http://goo.gl/DI33EC");
}
3rd script:
function createResolutionForm() {
var ss = SpreadsheetApp.getActive()
var sheet = ss.getSheetByName("ComplaintLog")
var lastRow = sheet.getLastRow();
var data = ss.getSheetByName("ComplaintLog") +
.getRange("A"+lastRow+":Z"+lastRow).getValues();
var form = FormApp.openById('The form's ID goes here. that part works.');
var items = form.getItems();
for (var i = 0; i < data.length; i++) {
var formResponse = form.createResponse();
//ID
var formItem = items[1].asTextItem();
var response = formItem.createResponse(data[i][0]);
formResponse.withItemResponse(response);
//Guest Name
var formItem = items[2].asTextItem();
var response = formItem.createResponse(data[i][3]);
formResponse.withItemResponse(response);
//email
var formItem = items[3].asTextItem();
var response = formItem.createResponse(data[i][4]);
formResponse.withItemResponse(response);
// The pre-populated form is being created here. I didn't include every
// form item for brevity's sake.
}
//Create Link
var formUrl = formResponse.toPrefilledUrl();
//Enable Clickable ID
var idNum = sheet.getRange("BC"+lastRow).getValues();
sheet.getRange("A"+lastRow).setFormula +
('=HYPERLINK("' + formUrl + '","' + idNum + '")');
var sheetUrl = "The URL to the spreadsheet goes here - that part works.";
//Send Email to assigned managers
var j,tempname=[],name, subject, managername, message;
managername = sheet.getRange("P"+lastRow).getValue();
tempname=managername.split(" ");
Logger.log(managername)
if (tempname.length==2) {
name=tempname[0].slice(0,1) + tempname[1] + '#organization.com';
subject = 'Action Required';
var message = "<html><body>"
+ "<p> You have been assigned to follow-up on a complaint,"
+ "or your contact information has been given to a customer in"
+ "regards to a complaint."
+ "<p><p>The complaint ID number is " + idNum +"."
+ "<p>To go directly to this complaint,"
+ "<b>click here</b>."
+ "<p>To vew the database so that you can take action,"
+click here."
+ "</body></html>";
MailApp.sendEmail(name, subject,"",{htmlBody : message});
}
}
Setting up the triggers from within the script might be what you're looking for. You can create triggers that respond to form submission events on a per-form basis like so:
function setup () {
ScriptApp.newTrigger('onForm1ResponseHandler').forForm(form1).onFormSubmit().create();
ScriptApp.newTrigger('onForm2ResponseHandler').forForm(form2).onFormSubmit().create();
}
where form1 and form2 are Form objects and 'onForm1ResponseHandler' is the name of the handler function.
With a handler function set up like this:
function onForm1ResponseHandler (e) {
...
}
e will be an object with properties documented here (for the Form Submit event).

Is that possible to generate unique Id for list item across site collection?

Ex: I have 10 sites and every site have 5 list. From site 1 i have adding one item in listX now id will be like "1" and creating another item in listB of 4th sub site so now id will "2"... So it has to go on like this how to achieve this?
I need to update this with all list item added event ? also how to get the latest id?
I have tried this code with custom forms it's work's cool, but thinking this may give concurrency issue
public static void ID()
{
if ((field.InternalName.Equals("Field1")))
{
{
string template;
using (SPSite site = new SPSite(SPContext.Current.Site.Url))
{
using (SPWeb web = site.RootWeb)
{
template = web.Properties["eydtemplate"].ToString();
}
}
if ("eydadvisory" == template)
{
SPListItemCollection items = _currentList.Items;
if (_currentList.ItemCount == 0)
{
webControl.Field.DefaultValue = (1).ToString();
}
else
{
SPQuery query = new SPQuery();
query.RowLimit = 1;
query.Query = " <OrderBy><FieldRef Name='" + field.InternalName + "' Ascending='FALSE' /></OrderBy>";
webControl.Field.DefaultValue = (Convert.ToInt64(_currentList.GetItems(query).Cast<SPListItem>().FirstOrDefault()[field.InternalName]) + 1).ToString();
}
}
}