how can i execute or not a line of a for-comprehension depending on a condition, with scala slickdb - slick-3.0

I have this code using slickdb:
val action: DBIOAction[Int, NoStream, Effect] =
for {
id <- sql"select id from product where name = $name".as[Int].head
_ <- sql"update product set description = ${description(id, name)}".asUpdate if id != 5
} yield id
db.run(action)
With this code, the action will not return the id if id != 5. This is not what I want. I want that the set description update is only executed if id != 5, and at the same time dbaction must return the id independenting or whether id != 5 or not.
How can I achieve this?

You might need something like this:
val action: DBIOAction[Int, NoStream, Effect] =
for {
id <- sql"select id from product where name = $name".as[Int].head
} yield {
if (id != 5) {sql"update product set description = ${description(id, name)}".asUpdate }
id
}

Related

Is there a way to find an element in a list and delete items after it that are of a specific type without using indicies?

I have a project that needs me to remove items if one of the properties of the item I'm trying to find within the list is true. Just so it's easier understand the project I am pasting all code needed to understand it below.
fun main() {
val acct1 = AccountId(72)
val calendars = mutableListOf<CalendarDrawerCalendarItem>()
val calendars2 = mutableListOf<CalendarDrawerCalendarItem>()
calendars.add(CalendarDrawerCalendarItem(CalendarDescriptor(acct1, CalendarId(acct1, 3),"toast", true)))
calendars.add(CalendarDrawerCalendarItem(CalendarDescriptor(acct1, CalendarId(acct1, 4), "chicken", false)))
calendars.add(CalendarDrawerCalendarItem(CalendarDescriptor(acct1, CalendarId(acct1, 5), "pizza", true)))
calendars2.add(CalendarDrawerCalendarItem(CalendarDescriptor(acct1, CalendarId(acct1, 1), "bagel", true)))
// These are example calls to collapse
collapse(calendars, CalendarDrawerGroupItem(true, CalendarGroupDescriptor( acct1, "My Calendars")))
collapse(calendars2, CalendarDrawerGroupItem(false, CalendarGroupDescriptor(acct1, "Group Calendars")))
}
fun collapse(calendars: List<CalendarDrawerListItem>, group: CalendarDrawerGroupItem): List<CalendarDrawerListItem> {
val collapsedResults = mutableListOf<CalendarDrawerListItem>()
val findGroupGiven = group
collapsedResults.addAll(calendars)
if (collapsedResults.contains(findGroupGiven)) {
group.collapsed = true
// logic for deleting items here
}
return collapsedResults
}
I'll also put the classes so you can see how they're defined
data class AccountId(
val accountId: Int
)
data class CalendarId(
val accountId: AccountId,
val calendarId: Int)
data class CalendarDescriptor(
val accountId: AccountId,
val calendarId: CalendarId,
val name: String,
val isGroupCalendar: Boolean
)
data class CalendarGroupDescriptor(
val accountId: AccountId,
val name: String,
)
sealed class CalendarDrawerListItem
data class CalendarDrawerGroupItem(var collapsed: Boolean, val groupDescriptor: CalendarGroupDescriptor) : CalendarDrawerListItem()
data class CalendarDrawerCalendarItem(val calendarDescriptor: CalendarDescriptor) : CalendarDrawerListItem()
The first step I have done is I must find the given group from the group variable, within calendars. (I did this with the contains() method). Next when I find the group I have to set its collapsed variable to true and any CalendarDrawerCalendarItems after it have to be deleted.
The input will look something like (the exact numbers and values are not the important part):
Input:
calendars:
CDGroupItem(collapsed = false, groupDescriptor = GroupDescriptor(accountId = 1, name = "My calendars"))
CDCalendarItem(calendarDescriptor = CalendarDescriptor(accountId = 1, calendarId = 1, isGroup = false))
CDCalendarItem(calendarDescriptor = CalendarDescriptor(accountId = 1, calendarId = 2, isGroup = false))
CDCalendarItem(calendarDescriptor = CalendarDescriptor(accountId = 1, calendarId = 3, isGroup = false))
CDGroupItem(collapsed = false, groupDescriptor = GroupDescriptor(accountId = 1, name = "Group calendars"))
CDCalendarItem(calendarDescriptor = CalendarDescriptor(accountId = 1, calendarId = 4, isGroup = true))
CDCalendarItem(calendarDescriptor = CalendarDescriptor(accountId = 1, calendarId = 5, isGroup = true))
group: CDGroupItem(collapsed = false, groupDescriptor = GroupDescriptor(accountId = 1, name = "My calendars"))
The output should look something like this:
Output:
CDGroupItem(collapsed = true, groupDescriptor = GroupDescriptor(accountId = 1, name = "My calendars"))
CDGroupItem(collapsed = false, groupDescriptor = GroupDescriptor(accountId = 1, name = "Group calendars"))
CDCalendarItem(calendarDescriptor = CalendarDescriptor(accountId = 1, calendarId = 4, isGroup = true))
CDCalendarItem(calendarDescriptor = CalendarDescriptor(accountId = 1, calendarId = 5, isGroup = true))
Any group item that has its collapsed boolean set to true should have all calendar items deleted after it since its collapsed is set to true. Again the names and numbers are not super important. The collapsed bool is. How can I do this without hardcoding or using indicies?
Your example code doesn't use that input and output as-is so I can only give you a general example, but you could use a fold:
val result = calendars.fold(mutableListOf<CalendarDrawerListItem>()) { items, current ->
// basically 'is there a last item stored, and is it a group item, and is it collapsed'
val lastStoredIsCollapsed =
(items.lastOrNull() as? CalendarDrawerGroupItem)?.collapsed == true
if (current is CalendarDrawerCalendarItem && lastStoredIsCollapsed) items
else items.apply { add(current) }
}
It basically pipes out each item into a list, but if the last one it stored is a CalendarDrawerGroupItem with collapsed set to true, it drops drawer items. If the last one is a non-collapsed group item, it can store a drawer item, and that means the next drawer item will be stored (since the last item isn't a collapsed group)
edit: here's the for loop equivalent if it helps, with the full logic for when a calendar is not dropped (the logic in my other example is for whether it should be dropped, which can be condensed a bit):
// assuming 'calendars' is your list of items with 'collapsed' set appropriately
val result = mutableListOf<CalendarDrawerListItem)
for (calendar in calendars) {
val lastStored = result.lastOrNull()
when {
lastStored == null ->
result.add(calendar)
lastStored is CalendarDrawerGroupItem && !lastStored.collapsed ->
result.add(calendar)
lastStored is CalendarDrawerCalendarItem ->
result.add(calendar)
}
}
return result
If you're asking how to actually mutate your list so a collapsed property is set to true, that would be easy if the property was a var in your data class. Since it's a val you'll have to do something like this:
val calendarInputWithCollapsedSet = calendars.map { calendar ->
if ((calendar as? CalendarDrawerGroupItem)?.groupDescriptor == group.groupDescriptor)
calendar.copy(collapsed = true) else calendar
}
So if you find a matching group (you'll have to work out how to match them, I'm guessing) you transform it into a copy with its collapsed property set
And then you can run the fold or whatever on that new list.

Problem in rendering Multiple Drilldown in fusioncharts

I am using Django. I want use the drilldown feature in fusioncharts. I am able to get the first drilldown correctly. But when I code for the second drilldown it is showing "No data to display". Also the following code renders all the charts in the same type. But I want to render the child charts in different types. I am sharing the snippet below.
def chart(request):
dataSource = {}
dataSource['chart'] = {
"caption": "Top 10 Most Populous Countries",
"showValues": "0",
"theme": "zune"
}
dataSource['data'] = []
dataSource['linkeddata'] = []
sbc = MTD.pdobjects.values('Vertical', 'Channel','Brand','Sales_Value')
sbc_df = sbc.to_dataframe().reset_index(drop=True)#Trying to use filtered model for dataframe
sbc_df['Sales_Value']=sbc_df['Sales_Value'].astype(float)
chn_gb=sbc_df.groupby('Channel')['Sales_Value'].sum().reset_index()
channel=list(chn_gb['Channel'])
channel_val=list(chn_gb['Sales_Value'])
sbc_gb=pandas.pivot_table(sbc_df,index=['Vertical','Channel'],values=['Sales_Value'],aggfunc='sum').reset_index()
brd_gb=pandas.pivot_table(sbc_df,index=['Vertical','Channel','Brand'],values=['Sales_Value'],aggfunc='sum').reset_index()
for i in range(len(channel)):
data = {}
data['label'] = channel[i]
data['value'] = channel_val[i]
data['link'] = 'newchart-json-'+ channel[i]
dataSource['data'].append(data)
linkData2 = {}
linkData2['id'] = channel[i]
linkedchart2 = {}
linkedchart2['chart'] = {
"caption" : "Top 10 Most Populous Cities - " + channel[i] ,
"showValues": "0",
"theme": "fusion",
}
linkedchart2['data'] = []
sbc_filtered=sbc_gb[sbc_gb.Channel == channel[i]]
vertical_list=list(sbc_filtered['Vertical'])
vertical_val=list(sbc_filtered['Sales_Value'])
for k in range(len(sbc_filtered)):
arrDara2 = {}
arrDara2['label'] = vertical_list[k]
arrDara2['value'] = vertical_val[k]
arrDara2['link'] = 'newchart-json-'+ vertical_list[k]
linkedchart2['data'].append(arrDara2)
linkData1 = {}
# Inititate the linkData for cities drilldown
linkData1['id'] = vertical_list[k]
linkedchart1 = {}
linkedchart1['chart'] = {
"caption" : "Top 10 Most Populous Cities - " + vertical_list[k] ,
"showValues": "0",
"theme": "fusion",
}
linkedchart1['data'] = []
brd_filtered=brd_gb[(brd_gb.Channel == channel[i]) & (brd_gb.Vertical== vertical_list[k])]
brd_list=list(brd_filtered['Brand'])
brd_val=list(brd_filtered['Sales_Value'])
for j in range(len(brd_filtered)):
arrDara1 = {}
arrDara1['label'] = brd_list[j]
arrDara1['value'] = brd_val[j]
linkedchart1['data'].append(arrDara1)
linkData1['linkedchart'] = linkedchart1
dataSource['linkeddata'].append(linkData1)
linkData2['linkedchart'] = linkedchart2
dataSource['linkeddata'].append(linkData2)
print(dataSource)
column2D = FusionCharts("column2D", "ex1" , "700", "400", "chart-1", "json", dataSource)
return render(request, 'table.html',{'output':column2D.render()})
Kindly help me to achieve the successive drilldown correctly.
Thanks
In order to change the chart type for the child chart you need to use configureLink API method to set the child chart type, you can also set different chart at a different level, provided the datastructure for each chart is correct, here is how you can do
myChart.configureLink([
{ type: 'bar2d' },
{ type: 'line' },
{ type: 'pie2d' }
]);
Here is a demo - http://jsfiddle.net/x0c2wo7k/
Please note the above sample is using plain javascript

Apex Interactive Grid how to retrieve a specific record

I am retrieving my grid data using:
var ig$ = apex.region("myGrid1").widget(),
view = ig$.interactiveGrid("getCurrentView");
Now I want to check for a specific record based on 2 columns: id1 and id2 where id1 = 1 and id2 = 7
How can I do that with javascript?
You can iterate for each record like this:
//"myGrid1" should be the static id of the IG region
var widget = apex.region('myGrid1').widget();
var grid = widget.interactiveGrid('getViews','grid');
var model = grid.model;
var results = [];
model.forEach(function(r) {
var record = r;
//the name of the columns should be ID1 and ID2, if not
//make the necessary changes using "_" to represent "space"
var value1 = model.getValue(record,'ID1');
var value2 = model.getValue(record,'ID2');
if(value1 == 1 && value2 == 7) {
results.push(record);
}
})
console.log(results);
To test this code, execute it on console.
To start the console on chrome just press F12
good luck.

Return value in sales.order.line from wizard in Odoov10

I have a Many2many type field in wizard('pack_ids') and also a Many2many('pack_id') type field in sale.order.line. And i want that the value of Many2many type field of wizard('pack_ids') return in sale.order.line field('pack_id').
For this my code is here:
class SalePackWizard(models.TransientModel):
_name = "sale.pack.wizard"
_description = "Sale Pack Wizard"
#api.onchange('product_id')
def _onchange_product_pack_name(self):
print"A:", self.product_id.product_pack
res = self.product_id.product_pack
a = {}
print "res:", res
if res:
domain = {'pack_ids': [('id', 'in', [v.id for v in res])]}
a= res
print "a:", a
return {'domain': domain}
product_id = fields.Many2one('product.product', string="Product Pack", required=True, domain="[('is_pack','=',True)]")
qty = fields.Float(string='Quantity', digits=dp.get_precision('Product Unit of Measure'), required=True, default=1.0)
pack_ids = fields.Many2many('product.pack', string='Pack Products', change_default=True,
default=_onchange_product_pack_name)
#api.multi
def action_salepack_add(self):
rec = self._context.get('active_ids', [])
print "REC", rec, self.product_id.categ_id #product_uom
if rec:
line_values = {'product_id': self.product_id.id,
#'design_id':self.design_id.id,
'pack_id': self.product_id.product_pack,
'category_id':self.product_id.categ_id.id,
'order_id':rec[0],
'product_uom_qty':self.qty,
}
sale_order_line = self.env['sale.order.line'].create(line_values)
you can update your code by that:
#api.multi
def action_salepack_add(self):
order_id = self._context.get('active_id',False)
if order_id:
line_values = {'product_id': self.product_id.id,
'pack_id': [ ( 6, 0, [self.product_id.product_pack.id] ) ],
'category_id':self.product_id.categ_id.id,
'order_id':order_id,
'product_uom_qty':self.qty,
}
sale_order_line = self.env['sale.order.line'].create(line_values)
You cant create values in a many2many field just giving it the id (this is only for many2one). If the field is a one2many or many2many:
(0, 0, { values }) link to a new record that needs to be created with the given values dictionary
(1, ID, { values }) update the linked record with id = ID (write values on it)
(2, ID) remove and delete the linked record with id = ID (calls unlink on ID, that will delete the object completely, and the link to it as well)
(3, ID) cut the link to the linked record with id = ID (delete the relationship between the two objects but does not delete the target object itself)
(4, ID) link to existing record with id = ID (adds a relationship)
(5) unlink all (like using (3,ID) for all linked records)
(6, 0, [IDs]) replace the list of linked IDs (like using (5) then (4,ID) for each ID in the list of IDs)
Error Fixed. Here is the solution for error:
#api.multi
def action_salepack_add(self):
rec = self._context.get('active_ids', [])
print "REC", rec, self.product_id.categ_id #product_uom
if rec:
line_values = {'product_id': self.product_id.id,
#'design_id':self.design_id.id,
'pack_id': [(6, 0, [v.id for v in self.product_id.product_pack])],
'category_id':self.product_id.categ_id.id,
'order_id':rec[0],
'product_uom_qty':self.qty,
}
sale_order_line = self.env['sale.order.line'].create(line_values)
Thanks,

How to do a MaxBy in RavenDb MapReduce

Using the Northwind database from RavenDB tutorial I'm trying to group orders by employee and get the most resent order for every employee.
Map:
from order in docs.Orders
select new {
Employee = order.Employee,
Count = 1,
MostRecent = order.OrderedAt,
MostRecentOrderId = order.Id
}
Reduce with nonexisting MaxBy:
from result in results
group result by result.Employee into grp
select new {
Employee = grp.Key,
Count = grp.Sum(result => result.Count),
MostRecent = grp.Max(result => result.MostRecent),
MostRecentOrderId = grp.MaxBy(result => result.MostRecent).MostRecentOrderId,
}
Reduce attempt:
from result in results
group result by result.Employee into grp
let TempMostRecent = grp.Max(result => result.MostRecent)
select new {
Employee = grp.Key,
Count = grp.Sum(result => result.Count),
MostRecent = TempMostRecent,
MostRecentOrderId = grp.First(result => result.MostRecent == TempMostRecent).MostRecentOrderId
}
However my reduce attempt returns 0 results.
Also: will RavenDB treat the Order.OrderetAt as a proper DateTime value and order them correctly?
You need to do it like
from order in docs.Orders
select new {
Employee = order.Employee,
Count = 1,
MostRecent = order.OrderedAt,
MostRecentOrderId = order.Id
}
from result in results
group result by result.Employee into grp
let maxOrder = grp.OrderByDescending(x=>x.MostRecent).First()
select new {
Employee = grp.Key,
Count = grp.Sum(result => result.Count),
MostRecent = maxOrder.MostRecent,
MostRecentOrderId = maxOrder.MostRecentOrderId,
}