i have two reports cout_materiel_facture_detail_report.xml (detailed report) and cout_materiel_facture_report.xml (simple report) and have a wizard where the user inputs some data and chooses whether he/she wants to print the simple report or the detailed one. Here is the wizard's class:
class CoutMaterielFactureWizard(models.TransientModel):
_name = 'gc.cout_materiel_facture_wizard'
directeur_parc_id = fields.Many2one('hr.employee', string='Directeur Parc')
procedure = fields.Char(string='Procedure')
version = fields.Char(string='Verion')
date_realisation = fields.Date(string='Date realisation')
# is_landscape = fields.Boolean(string='Mode paysage?')
is_detail = fields.Boolean(string='Version simplifiee?')
#api.multi
def do_toggle_print(self):
cout_materiel = self.env['gc.cout_materiel'].browse(self._context.get('active_id', False))
cout_materiel.write({
'directeur_parc_id': self.directeur_parc_id.id
})
# Print the simple report
if not self.is_detail:
return {
'type': 'ir.actions.report.xml',
'name': 'gestion_cout.cout_materiel_facture_report_template',
'report_name': 'gestion_cout.cout_materiel_facture_report_template',
}
# Print the detailed report
else:
sql = "SELECT SUM(h_sup)+SUM(h_exp),SUM(h_im),count(*),SUM(total), famille FROM gc_cout_materiel_line where " \
"cout_materiel_id =%s group by famille "
self.env.cr.execute(sql, (cout_materiel.id,))
results = self.env.cr.fetchall()
if len(results) > 0:
line_ids = []
for nbht, nbhim, qte, prix_total, famille in results:
line_ids.append((0, 0, {
'famille': famille,
'type': 'VA',
'qte': qte,
'nbr_heures': nbht,
'nbr_heures_im': nbhim,
'nbr_jours': 28,
'prix_unitaire': 'VA',
'prix_total': prix_total,
}))
self.env['gc.cout_materiel_facture_temp'].create({
'chantier_name': cout_materiel.chantier_id.name,
'mois_name': cout_materiel.mois_id.name,
'num_annexe': cout_materiel.num_annexe,
'expediteur': cout_materiel.expediteur,
'destinateur': cout_materiel.destinateur,
'application_date': cout_materiel.application_date,
'date_realisation': self.date_realisation,
'directeur_parc_name': self.directeur_parc_id.name,
'procedure': self.procedure,
'version': self.version,
'prix_total_global': cout_materiel.total_global,
'line_ids': line_ids,
})
return {
'type': 'ir.actions.report.xml',
'name': 'gestion_cout.gc_cout_materiel_facture_detail_report_template',
'report_name': 'gestion_cout.gc_cout_materiel_facture_detail_report_template',
}
But i get this error after i hit the print button
I checked out the database and found both reports are present there.
Any help? please!!
Finally i managed to solve my problem!!
Here is what i did:
I created a method in the wizard model which returns a list of objects that i whant to print and linked the wizard to the qweb report.
Then i called the method from the qweb report using object.my_mehtod() in a t-foreach loop, where object represents the wizard.
With this way i am able to create complex reports and print them easily. One can use this method to get data from several tables and organize the data and retur them as a list.
I hope that it will help someone.
Best regards!!
Related
I have a WTForm that submits its data in JSON format. Say the database is one recipe to many recipe steps.
{
"stepset-0": {
"recipe_step_id": "5",
"recipe_step_name": "step 1",
"recipe_step_temp": "666.0"
},
"stepset-1": {
"recipe_step_id": "6",
"recipe_step_name": "Step 2",
"recipe_step_temp": "57.0"
},
"stepset-2": {
"recipe_step_id": "7",
"recipe_step_name": "Step 3",
"recipe_step_temp": "68.0"
},
"stepset-3": {
"recipe_step_id": "8",
"recipe_step_name": "Step 4",
"recipe_step_temp": "73.0"
}
}
I'm using JS to remove elements from the table, but currently trying to get my head round how to update the data in the recipe_steps table.
The logic should be basically:
Find the steps in the step table that match the recipe.
See if those steps are in the JSON data (match using the id)
Delete anything that isn't in the submitted JSON.
So if I remove the row with recipe_step_id '8', this gets submitted to the route, and the route works out that it isn't in the data, removes it from the db, then processes the rest of the data as per the route.
My current route (showing add/update functions) is thus:
#app.route('/recipe/recipesteps/<int:recipe_id>/update', methods=['GET', 'POST'])
#login_required
def updaterecipesteps(recipe_id):
recipe = Recipe.query.get_or_404(recipe_id)
data = request.form
nested_data = nest_once(data)
for key, val in nested_data.items():
recipe_step_id = val['recipe_step_id']
recipe_step_temp = val['recipe_step_temp']
recipe_step_name = val['recipe_step_name']
recipe_id = recipe
if recipe_step_id:
recipe_step = ReciperecipeSteps.query.get_or_404(recipe_step_id)
recipe_step.name = recipe_step_name
recipe_step.step_temp = recipe_step_temp
db.session.commit()
else:
recipe_step = ReciperecipeSteps(name=recipe_step_name,
step_temp=recipe_step_temp,
recipe_id=recipe_step.recipe_id)
db.session.add(recipe_step)
db.session.commit()
return redirect(url_for('recipe', recipe_id=recipe.id))
The closest I've got to this is this query:
mash_steps = RecipeSteps.query.filter(RecipeSteps.id.not_in([nested_data.recipe_step_id for val in nested_data.items]), RecipeSteps.recipe_id == recipe_id).all()
...but Python won't iterate over the object.
Probably far from the best way of doing this (I'd imagine I could have parsed the JSON data in the query), but this is what I got working:
# Build a list from the step ids
step_id = []
for key, value in nested_data.items():
recipe_step_id = value['recipe_step_id']
step_id.append(recipe_step_id)
# Query matching items that aren't on the list
recipe_steps = RecipeSteps.query.filter(RecipeSteps.id.not_in(step_id), RecipeSteps.recipe_id == recipe.id).all()
# Loop through the results and delete
for m in recipe_steps:
db.session.delete(m)
db.session.commit()
I have this function that uses PrettyTables to gather information about the Virtual Machines owned by a user. Right now, it only shows information and it works well. I have a new idea where I want to add a button to a new column which allows the user to reboot the virutal machine. I already know how to restart the virtual machines but what I'm struggling to figure out is the best way to create a dataset which i can iterate through and then create a HTML table. I've done similar stuff with PHP/SQL in the past and it was straight forward. I don't think I can iterate through PrettyTables so I'm wondering what is my best option? Pretty tables does a very good job of making it simple to create the table (as you can see below). I'm hoping to use another method, but also keep it very simple. Basically, making it relational and easy to iterate through. Any other suggestions are welcome. Thanks!
Here is my current code:
x = PrettyTable()
x.field_names = ["VM Name", "OS", "IP", "Power State"]
for uuid in virtual_machines:
vm = search_index.FindByUuid(None, uuid, True, False)
if vm.summary.guest.ipAddress == None:
ip = "Unavailable"
else:
ip = vm.summary.guest.ipAddress
if vm.summary.runtime.powerState == "poweredOff":
power_state = "OFF"
else:
power_state = "ON"
if vm.summary.guest.guestFullName == None:
os = "Unavailable"
else:
os = vm.summary.guest.guestFullName
x.add_row([vm.summary.config.name, os, ip, power_state])
table = x.get_html_string(attributes = {"class":"table table-striped"})
return table
Here is a sample of what it looks like and also what I plan to do with the button. http://prntscr.com/nki3ci
Figured out how to query the prettytable. It was a minor addition without having to redo it all.
html = '<table class="table"><tr><th>VM Name</th><th>OS</th><th>IP</th><th>Power
State</th></tr>'
htmlend = '</tr></table>'
body = ''
for vmm in x:
vmm.border = False
vmm.header = False
vm_name = (vmm.get_string(fields=["VM Name"]))
operating_system = (vmm.get_string(fields=["OS"]))
ip_addr = ((vmm.get_string(fields=["IP"])))
body += '<tr><td>'+ vm_name + '</td><td>' + operating_system + '</td> <td>'+ ip_addr +'</td> <td>ON</td></tr>'
html += body
html += htmlend
print(html)
This is my function. I am able to create a new quatation on clicking a button in my indent form and also able to see the indent sequence in quatation. But I am not able to update product line in indent in purchase order line. Can any1 help me out here..?
#api.multi
def action_rfq(self):
rfq_obj = self.env['purchase.order']
for order in self.product_lines:
rfq_id = rfq_obj.create({
'series': self.name,
'order_line': ({
'product_id': order.product_id.id,
'name': order.name,
'product_qty': order.product_uom_qty,
'product_uom': order.product_uom.id,
'price_unit': order.price_unit,
'date_planned': datetime.now(),
'order_id': order.indent_id.id,
})
})
'product_id': order.product_id.id,
'name': order.name,
'product_qty': order.product_uom_qty,
'product_uom': order.product_uom.id,
'price_unit': order.price_unit,
'date_planned': datetime.now(),
'order_id': order.indent_id.id,
})
})
return rfq_id
Hello Gautam,
It would be late now ,but can be helpfull for others.You want to update product line in indent in purchase order line ...so for updating the order line you have to call the write function and pass the product value like this...
order_line_obj = self.env['purchase.order.line']
first create the obj of purchase .order.line
browse_obj=order_line_obj.browse(int(active_id))
After creating the object call browse object and pass the id of present record
order_line_id=browse_obj.write({'name':hotel_name})
After doing this call the write function with browse object.and doing so your record will be updated.
Now I'm developing a project about softlayer api. I wan't to get the os list by softlayer api. Just like the portal site. Is there certain method to get correct os list ? regards~
Is there a specific language example you are looking for? If you use the SoftLayer CLI you can do this with the following command
slcli vs create-options # For Virtual Guests
slcli server create-options # For Bare Metal Servers
Unfortunately, it's not possible to retrieve the same result than Control Portal making a single call, but it's possible using a programming language.
To see programming languages supported by SoftLayer:
SoftLayer Development Network
Take a look the following python script:
"""
List OSs for VSI similar than Portal
See below references for more details.
Important manual pages:
http://sldn.softlayer.com/reference/services/SoftLayer_Product_Package/getItemPrices
http://sldn.softlayer.com/article/object-filters
http://sldn.softlayer.com/article/object-Masks
#License: http://sldn.softlayer.com/article/License
#Author: SoftLayer Technologies, Inc. <sldn#softlayer.com>
"""
import SoftLayer
import datetime
import time
# Your SoftLayer's username and api Key
USERNAME = 'set me'
API_KEY = 'set me'
# Package id
packageId = 46
# Datacenter
datacenter = 'wdc04'
# Computing INstance
core = '1 x 2.0 GHz Core'
# Creating service
client = SoftLayer.Client(username=USERNAME, api_key=API_KEY)
packageService = client['SoftLayer_Product_Package']
# Declaring filters and mask to get additional information for items
filterDatacenter = {"itemPrices": {"pricingLocationGroup": {"locations": {"name": {"operation": datacenter}}}}}
objectMaskDatacenter = 'mask[pricingLocationGroup[locations]]'
objectMask = 'mask[pricingLocationGroup[locations],categories,item[id, description, capacity,softwareDescription[manufacturer],availabilityAttributeCount, availabilityAttributes[attributeType]]]'
filterInstance = {
'itemPrices': {
'categories': {
'categoryCode': {
'operation': 'os'
}
}
}
}
# Define a variable to get capacity
coreCapacity = 0
# To get item id information
itemId = 0
flag = False
# Define the manufacturers from which you like to get information
manufacturers = ["CentOS", "CloudLinux", "CoreOS", "Debian", "Microsoft", "Redhat", "Ubuntu"]
# Declare time to avoid list OS expired
now = time.strftime("%m/%d/%Y")
nowTime = time.mktime(datetime.datetime.strptime(now, "%m/%d/%Y").timetuple())
try:
conflicts = packageService.getItemConflicts(id=packageId)
itemPrices = packageService.getItemPrices(id=packageId, filter=filterDatacenter, mask=objectMask)
if len(itemPrices) == 0:
filterDatacenter = {"itemPrices":{"locationGroupId":{"operation":"is null"}}}
itemPrices = packageService.getItemPrices(id=packageId, filter=filterDatacenter, mask=objectMask)
for itemPrice in itemPrices:
if itemPrice['item']['description'] == core:
itemId = itemPrice['item']['id']
coreCapacity = itemPrice['item']['capacity']
result = packageService.getItemPrices(id=packageId, mask=objectMask, filter=filterInstance)
filtered_os = []
for item in result:
for attribute in item['item']['availabilityAttributes']:
expireTime = time.mktime(datetime.datetime.strptime(attribute['value'], "%m/%d/%Y").timetuple())
if ((attribute['attributeType']['keyName'] == 'UNAVAILABLE_AFTER_DATE_NEW_ORDERS') and (expireTime >= nowTime)):
filtered_os.append(item)
if item['item']['availabilityAttributeCount'] == 0:
filtered_os.append(item)
for manufacturer in manufacturers:
print(manufacturer)
for itemOs in filtered_os:
for conflict in conflicts:
if (((itemOs['item']['id'] == conflict['itemId']) and (itemId == conflict['resourceTableId'])) or ((itemId == conflict['itemId']) and (itemOs['item']['id'] == conflict['resourceTableId']))):
flag = False
break
else:
flag = True
if flag:
if itemOs['item']['softwareDescription']['manufacturer'] == manufacturer:
if 'capacityRestrictionMinimum' in itemOs:
if((itemOs['capacityRestrictionMinimum'] <= coreCapacity) and (coreCapacity <= itemOs['capacityRestrictionMaximum'])):
print("%s Price Id: %s Item Id: %s" % (itemOs['item']['description'], itemOs['id'], itemOs['item']['id']))
else:
print("%s Price Id: %s Item Id: %s" % (itemOs['item']['description'], itemOs['id'], itemOs['item']['id']))
print("---------------------------------------------------")
except SoftLayer.SoftLayerAPIError as e:
print('Unable to get Item Prices faultCode=%s, faultString=%s'
% (e.faultCode, e.faultString))
I added core variable, because the OSs have restriction for capacity of cores. Also I added datecenter to get the specific core item price for a specifc datacenter, perhaps it's something innecesary, but you can edit this script according your requirements.
The same idea could be applied for others programming languges.
I hope it helps, please let me know any doubt, comments or if you need further assistance.
Updated
I improved the script, I added the ability to check conflicts between items, in order to get the same result for each kind of Computing Instance
Following is the code which will try to fetch the fields for a given adset id.
The problem is I'm not able to get any fields that I've mentioned. Only id is being seen in the response.
Code :
FacebookAdsApi.init(account_id, "credentials", "access_token")
api = FacebookAdsApi.get_default_api()
api_batch = api.new_batch()
adset = AdSet(fbid=adset_id)
fields = [
AdSet.Field.name,
AdSet.Field.configured_status,
AdSet.Field.effective_status,
AdSet.Field.account_id,
AdSet.Field.campaign_id,
AdSet.Field.daily_budget,
AdSet.Field.start_time,
AdSet.Field.bid_amount,
AdSet.Field.billing_event,
AdSet.Field.optimization_goal,
AdSet.Field.targeting,
AdSet.Field.promoted_object
]
adset = AdSet(str(adset_id))
api = FacebookAdsApi.get_default_api()
api_batch = api.new_batch()
def get_response(success_adset=None):
print "Response is success"
print success_adset.json()
def get_failure(failure_adset=None):
print "Response is failure"
print failure_adset.json()
fn_success = partial(get_response)
fn_failure = partial(get_failure)
adset.remote_read(fields=[AdSet.Field.name], batch=api_batch, success=fn_success, failure=fn_failure)
api_batch.execute()
it doesn't look like you're passing the fields into the remote_read method. In the SDK examples we use the following:
adset.remote_read(fields=[
AdSet.Field.name,
AdSet.Field.configured_status,
AdSet.Field.effective_status,
AdSet.Field.account_id,
AdSet.Field.campaign_id,
AdSet.Field.daily_budget,
AdSet.Field.start_time,
AdSet.Field.bid_amount,
AdSet.Field.billing_event,
AdSet.Field.optimization_goal,
AdSet.Field.targeting,
AdSet.Field.promoted_object
], batch=api_batch, success=fn_success, failure=fn_failure)