How to customize kanban viwe in Odoo14? - odoo

I am trying to add some dashboard values to kanban view of maintenance.team model. I used helpdesk dashboard for reference. But it didn't work as expected.
Here is my code:
***.js**
odoo.define('maintenance_dashboard.dashboard',function (require){
"use strict";
console.log('Am here in dashboard js');
var core = require('web.core');
var KanbanController = require('web.KanbanController');
var KanbanModel = require("web.KanbanModel");
var KanbanRenderer = require('web.KanbanRenderer');
var KanbanView = require('web.KanbanView');
var session = require("web.session");
var view_registry = require('web.view_registry');
var Qweb = core.qweb;
var _t = core._t;
var _lt = core._lt;
console.log('KanbanRenderer',KanbanRenderer);
var MaintenanceDashboardRenderer = KanbanRenderer.extend({
/**
* #override
* #private
* #returns {Promise}
*/
_render: function(){
console.log('inside render function');
var self = this;
return this._super.apply(this,arguments).then(function (){
var values = self.state.dashboardValues;
console.log('values',values);
var maintenance_dashboard1 = Qweb.render('maintenance_dashboard.MaintenanceDashboard', {
widget: self,
// show_demo: values.show_demo,
// rating_enable: values.rating_enable,
// success_rate_enable: values.success_rate_enable,
values: values,
});
self.$el.prepend(maintenance_dashboard1);
});
},
});
console.log('after first function');
var MaintenanceDashboardModel = KanbanModel.extend({
/**
* #override
*/
init: function () {
this.dashboardValues = {};
this._super.apply(this, arguments);
},
//--------------------------------------------------------------------------
// Public
//--------------------------------------------------------------------------
/**
* #override
*/
__get: function (localID) {
var result = this._super.apply(this, arguments);
if (_.isObject(result)) {
result.dashboardValues = this.dashboardValues[localID];
}
return result;
},
/**
* #œverride
* #returns {Promise}
*/
__load: function () {
return this._loadDashboard(this._super.apply(this, arguments));
},
/**
* #œverride
* #returns {Promise}
*/
__reload: function () {
return this._loadDashboard(this._super.apply(this, arguments));
},
//--------------------------------------------------------------------------
// Private
//--------------------------------------------------------------------------
/**
* #private
* #param {Promise} super_def a promise that resolves with a dataPoint id
* #returns {Promise -> string} resolves to the dataPoint id
*/
_loadDashboard: function (super_def) {
var self = this;
var dashboard_def = this._rpc({
model: 'maintenance.team',
method: 'retrieve_dashboard',
});
return Promise.all([super_def, dashboard_def]).then(function(results) {
var id = results[0];
var dashboardValues = results[1];
self.dashboardValues[id] = dashboardValues;
return id;
});
},
});
var MaintenanceDashboardView = KanbanView.extend({
config:_.extend({},KanbanView.prototype.config,{
Model: MaintenanceDashboardModel,
Renderer: MaintenanceDashboardRenderer,
}),
display_name:_lt('Dashboard'),
icon:'fa-dashboard',
searchview_hidden:true,
});
view_registry.add('maintenance_dashboard1', MaintenanceDashboardView);
return {
Model: MaintenanceDashboardModel,
Renderer: MaintenanceDashboardRenderer,
};
});
**xml_template.xml**
<?xml version="1.0" encoding="UTF-8"?>
<templates>
<t t-name="maintenance_dashboard.MaintenanceDashboard">
<div>
<span> Am here</span>
</div>
</t>
</templates>

Found the solution, I forget to add js_class attribute in kanaban tag.
<record id="maintenance_team_kanban_inherit" model="ir.ui.view">
<field name="name">maintenance.team.kanban.inherit</field>
<field name="model">maintenance.team</field>
<field name="inherit_id" ref="maintenance.maintenance_team_kanban"/>
<field name="arch" type="xml">
<xpath expr="//kanban" position="attributes">
<attribute name="js_class">maintenance_dashboard1</attribute>
</xpath>
</field>
</record>
Now its working fine.

Related

Send back FullCalendar events to .NET with AJAX

I would like to sendback FullCalendar events to .NET with an AJAX request. I create a custom button for that :
#{
ViewData["Title"] = "Planning visites";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h1>#ViewData["Title"]</h1>
<div id='calendar'></div>
#section scripts
{
<script>
let date = new Date();
let month = String(date.getMonth() + 1).padStart(2, '0');
let day = String(date.getDate()).padStart(2, '0');
let year = date.getFullYear();
let dateDuJour = year + '-' + month + '-' + day;
let dateDuJourplusunan = (year + 1) + '-' + month + '-' + day;
document.addEventListener('DOMContentLoaded', function() {
var calendarEl = document.getElementById('calendar');
var calendar = new FullCalendar.Calendar(calendarEl, {
//themeSystem: 'bootstrap5',
//plugins: [ timeGridPlugin ],
initialView: 'timeGridWeek',
selectable: true,
selectOverlap: false,
//selectMirror: true,
validRange: {
start: dateDuJour,
end: dateDuJourplusunan
},
customButtons: {
enregistrermodifs: {
text: 'enregistrer',
click: function() {
var eventsobj = calendar.getEvents();
var data = JSON.stringify(eventsobj);
//var data = JSON.serialize(eventsobj);
alert(data);
$.ajax({
type: 'POST',
url: '#Url.Action("MAJAgenda","Agenda")',
//contentType: 'application/x-www-form-urlencoded; charset=UTF-8', // when we use .serialize() this generates the data in query string format. this needs the default contentType (default content type is: contentType: 'application/x-www-form-urlencoded; charset=UTF-8') so it is optional, you can remove it
contentType: 'application/json; charset=utf-8',
data: data,
success: function(result) {
alert('Successfully received Data ');
console.log(result);
},
error: function() {
alert('Erreur : enregistrement non effectué');
console.log('Failed');
}
});
}
}
},
headerToolbar: {
left: 'prev,next,today,enregistrermodifs',
center: 'title',
right: 'dayGridMonth,timeGridWeek,dayGridDay'
},
buttonText: {
today: 'Aujourdhui',
month: 'mois',
week: 'semaine',
timeGridWeek: 'jour',
day: 'jour',
list: 'liste'
},
initialDate: dateDuJour,
navLinks: true, // can click day/week names to navigate views
editable: true,
dayMaxEvents: true, // allow "more" link when too many events
events:'#Url.Action("RecupDonneesAgenda","Agenda")?annonceId=#ViewBag.AnnonceId',
select: function(info) {
calendar.addEvent({
//id: info.startStr,
title: 'Indisponibilité',
start: info.startStr,
end: info.endStr,
allDay: false
});
},
eventClick: function(info) {
var eventobj = info.event;
eventobj.remove();
}
});
calendar.render();
calendar.setOption('locale', 'fr');
});
</script>
}
Here's my model in .NET :
public class AgendaAJAX
{
public string? title { get; set; }
public DateTime? start { get; set; }
public DateTime? end { get; set; }
}
And here's my action method :
[HttpPost]
public async Task<IActionResult> MAJAgenda(AgendaAJAX? agenda)
{
string userID = User.FindFirstValue(ClaimTypes.NameIdentifier);
////List<Agenda> agenda = await _context.Agendas.Where(a => a.AnnonceID == annonceId && a.Personne1 == userID).ToListAsync();
//JsonResult result = new JsonResult(agenda);
return View("Agenda");
}
THE AJAX call works well : here's the JSON data :
[{"title":"Indisponibilité","start":"2022-06-09T07:30:00+02:00","end":"2022-06-09T12:30:00+02:00"},{"title":"Indisponibilité","start":"2022-06-10T10:00:00+02:00","end":"2022-06-10T15:00:00+02:00"},{"title":"Indisponibilité","start":"2022-06-11T07:00:00+02:00","end":"2022-06-11T09:30:00+02:00"}]
The problem is that I don't receive any data in the action method : agenda remains null.
I don't understand why.
If you can help me please.
Thanks.

sending notification in pusher private channel to selected users laravel8

I'm sending notifications using the public pusher channel in laravel8 .. How can I turn it to a private channel in order to send notifications just to the selected user.. which the admin selected from the dropdown menu?
here is my controller
public function notification(MessageRequest $request){
$data =[
'title' => $request->title,
'body' => $request->body,
// 'users' => $request->users,
];
event(new NewNotification($data));
return redirect()->back()->with(['success'=>'success']);
}
My event :
class NewNotification implements ShouldBroadcast
{
use Dispatchable, InteractsWithSockets, SerializesModels;
/**
* Create a new event instance.
*
* #return void
*/
public $title;
public $body;
// public $users;
public function __construct($data=[])
{
$this->title = $data['title'];
$this->body = $data['body'];
// $this->users = $data['users'];
}
/**
* Get the channels the event should broadcast on.
*
* #return Channel|array
*/
public function broadcastOn()
{
return new Channel('notification');
}
}
this is layout:
<script src="https://code.jquery.com/jquery-3.6.0.min.js" integrity="sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4=" crossorigin="anonymous"></script>
<script src="https://js.pusher.com/7.0/pusher.min.js"></script>
<script>
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
}
});
// Enable pusher logging - don't include this in production
Pusher.logToConsole = true;
var pusher = new Pusher('e7a414640973c420f866', {
// cluster: 'mt1'
});
</script>
<script src="{{asset('js/pusherNotifications.js')}}"></script>
and javascript file is :
var notificationsWrapper = $('.dropdown-notifications');
var notificationsToggle = notificationsWrapper.find('a[data-toggle]');
var notificationsCountElem = notificationsToggle.find('span[data-count]');
var notificationsCount = parseInt(notificationsCountElem.data('count'));
var notifications = notificationsWrapper.find('li.scrollable-container');
// Subscribe to the channel we specified in our Laravel Event
var channel = pusher.subscribe('notification');
// Bind a function to a Event (the full Laravel class)
channel.bind('App\\Events\\NewNotification', function (data) {
var existingNotifications = notifications.html();
var newNotificationHtml = `<a href="`+data.title+`">
<div class="media-body"><h6 class="media-heading text-right">` + data.title + `</h6>
<p class="notification-text font-small-3 text-muted text-right">` + data.body + `</p><small style="direction: ltr;">
</small></div></div></a>`;
notifications.html(newNotificationHtml + existingNotifications);
notificationsCount += 1;
notificationsCountElem.attr('data-count', notificationsCount);
notificationsWrapper.find('.notif-count').text(notificationsCount);
notificationsWrapper.show();
});
any help please,

Update Cascading Dropdown in Mvc5

Hi i want to know how to update or edit cascading dropdown like (Country,state,City)in mvc5.I have created 3 cascading dropdowns Country State city.If i select Country State will append in state dropdownn like wise city. Now i save these 3 dropdown values in table successfully. But now i stuck with edit option. I donno how to bind the saved value to these dropdowns in edit from.
My model
public class UCustomerManagementViewModel
{
public string UCountry { get; set; }
public string UState { get; set; }
public string UCity { get; set; }
}
My Controller code
public JsonResult GetCountries()
{
var Countries = db.Countries.ToList();
return Json(Countries, JsonRequestBehavior.AllowGet);
}
public JsonResult GetStatesByCountryID(string countryId)
{
int id = Convert.ToInt32(countryId);
var states = db.States.Where(d => d.CountryID == id).Select(e => new { e.UID, e.StateName }).ToList();
return Json(states, JsonRequestBehavior.AllowGet);
}
public JsonResult GetCityByStateID(string stateId)
{
int id = Convert.ToInt32(stateId);
var Cities = db.Cities.Where(d => d.StateID == id).Select(e => new { e.UID, e.CityName }).ToList();
return Json(Cities, JsonRequestBehavior.AllowGet);
}
public ActionResult Update(int id)
{
CustomerManagement cc = db.CustomerManagements.Find(id);
ViewBag.CountryID = new SelectList(db.Countries.Where(d => d.CountryID.ToString() == cc.Country.ToString()), "CountryID", "CountryName",cc.CountryID);
var ucusmanvm = new UCustomerManagementViewModel();
ucusmanvm.UCountry = cc.Country;(here i get value 1)
ucusmanvm.UState = cc.State;(here i get value 2)
ucusmanvm.UCity = cc.City;(here iget value 2)
return View(ucusmanvm);
}
here i pass all the value to view form
My View Code
$(document).ready(function () {
debugger;
$.ajax({
type: "GET",
url: '#Url.Action("GetCountries", "FrmCustomerManagement")',
datatype: "Json",
success: function (data) {
$.each(data, function (index, value) {
$('#dropdownCountry').append('<option value="' + value.CountryID + '">' + value.CountryName + '</option>');
});
}
});
$('#dropdownCountry').change(function () {
debugger;
$('#dropdownState').empty();
var cval = $('#dropdownCountry').val()
$.ajax({
type: "POST",
url: '#Url.Action("GetStatesByCountryID", "FrmCustomerManagement")',
datatype: "Json",
data: { countryId: cval },
success: function (data) {
$.each(data, function (index, value) {
$('#dropdownState').append('<option value="' + value.UID + '">' + value.StateName + '</option>');
});
}
})
});
$('#dropdownState').change(function () {
debugger;
$('#dropdownCity').empty();
var sval = $('#dropdownState').val()
$.ajax({
type: "POST",
url: '#Url.Action("GetCityByStateID", "FrmCustomerManagement")',
datatype: "Json",
data: { stateId: sval },
success: function (data) {
$.each(data, function (index, value) {
$('#dropdownCity').append('<option value="' + value.UID + '">' + value.CityName + '</option>');
});
}
})
});
#Html.DropDownList("dropdownCountry", new SelectList(string.Empty, "Value", "Text"), "Please select a country", new { #class = "form-control", #width = "80%", #value=Model.UCountry})
<div class="col-sm-8">
<label>State</label>
#Html.DropDownList("dropdownState", new SelectList(string.Empty, "Value", "Text"), "Please select a State", new { #class = "form-control", #width = "80%" , #value=Model.UState})
</div>
<div class="col-sm-8">
<label>City</label>
#Html.DropDownList("dropdownCity", new SelectList(string.Empty, "Value", "Text"), "Please select a City", new { #class = "form-control", #width = "80%" , #value=Model.Ucity})
</div>
Here in update from also i acheive Cascading dropdown using ajax. but in update form i donno how to bring the save value to drop downs(Country city, state) from controller to view (eg i saved UAE in Country Dropdown but in edit mode i donno how to bring UAE value in Country dropdown ).I passed value from controller but i donno how to bind that value in view.please any one help me to resolve this issue .

How to update values in QWeb template in odoo dynamically?

I'm trying to develop barcode scanning module to make inventory transfers using barcode scanner.
I made QWeb template and render it with this.$el.html method and I can see that view rendered appropriately. The problem is that values I pass to the template is not updating with client actions. How do I make them dynamically changed when I change them in js script? Code goes here:
barcode-scanner.js
odoo.define('stock.barcode_scanner', function(require) {
'use sctrict';
var AbstractAction = require('web.AbstractAction');
var core = require('web.core');
var QWeb = core.qweb;
var _t = core._t;
var BarcodeAction = AbstractAction.extend({
start: function() {
var self = this;
self.$el.html(QWeb.render("BarcodeHandlerView", {widget: self}));
core.bus.on('barcode_scanned', this, this._onBarcodeScanned);
return this._super();
},
destroy: function () {
core.bus.off('barcode_scanned', this, this._onBarcodeScanned);
this._super();
},
_onBarcodeScanned: function(barcode) {
var self = this;
this._rpc({
model: 'stock.barcode.handler',
method: 'product_scan',
args: [barcode, ],
})
.then(function (result) {
if (result.action) {
var action = result.action;
if (action.type === 'source_location_set') {
self.sourceLocation = action.value;
} else if (action.type === 'product_added') {
if (self.productsList === undefined) {
self.productsList = [];
}
self.productsList.push(action.value);
} else if (action.type === 'destination_location_set') {
self.destionationLocation = action.value;
} else if (action.type === 'validation') {
self.sourceLocation = undefined;
self.productsList = undefined;
self.destinationLocation = undefined;
}
}
if (result.warning) {
self.do_warn(result.warning);
}
});
},
});
core.action_registry.add('stock_barcode_scanner', BarcodeAction);
return {
BarcodeAction: BarcodeAction,
};
});
transfers.xml
<?xml version="1.0" encoding="utf-8"?>
<template id="theme.tp_remove_button">
<t t-name="BarcodeHandlerView">
<div>Source Location: <t t-esc="widget.sourceLocation"/></div>
<div>Destination Location: <t t-esc="widget.destinationLocation"/></div>
</t>
</template>
I am sure that everything is set properly at __manifest__.py - I can see the view, but client action doesn't trigger page update - and client actions are running when I trigger them - I can see my warnings I return from python function. What am I doing wrong? Should I use some other approach to achieve that?
You must to create an action to catch the event when your element change.
odoo.define('stock.barcode_scanner', function(require) {
'use sctrict';
var AbstractAction = require('web.AbstractAction');
var core = require('web.core');
var QWeb = core.qweb;
var _t = core._t;
var BarcodeAction = AbstractAction.extend({
// ***** Add this to catch events on your template
events: {
'change #destination-location': '_onBarcodeScanned',
},
start: function() {
var self = this;
self.$el.html(QWeb.render("BarcodeHandlerView", {widget: self}));
core.bus.on('barcode_scanned', this, this._onBarcodeScanned);
return this._super();
},
destroy: function () {
core.bus.off('barcode_scanned', this, this._onBarcodeScanned);
this._super();
},
action_change_destination: function (newLocation = null) {
if(newLocation === null){
return null;
}else{
let self = this;
console.log("My new awesome destination changing....");
self.destinationLocation = newLocation;
$("#detination-location").html(self.destinationLocation);
}
},
_onBarcodeScanned: function(barcode) {
var self = this;
this._rpc({
model: 'stock.barcode.handler',
method: 'product_scan',
args: [barcode, ],
})
.then(function (result) {
if (result.action) {
var action = result.action;
if (action.type === 'source_location_set') {
self.sourceLocation = action.value;
} else if (action.type === 'product_added') {
if (self.productsList === undefined) {
self.productsList = [];
}
self.productsList.push(action.value);
} else if (action.type === 'destination_location_set') {
self.destionationLocation = action.value;
// ****** GO AND CHANGE YOUR DESTINATION *****
self.action_change_destination(self.destionationLocation);
} else if (action.type === 'validation') {
self.sourceLocation = undefined;
self.productsList = undefined;
self.destinationLocation = undefined;
}
}
if (result.warning) {
self.do_warn(result.warning);
}
});
},
});
core.action_registry.add('stock_barcode_scanner', BarcodeAction);
return {
BarcodeAction: BarcodeAction,
};
});
And in your view should be like this:
<?xml version="1.0" encoding="utf-8"?>
<template id="theme.tp_remove_button">
<t t-name="BarcodeHandlerView">
<div>Source Location: <t t-esc="widget.sourceLocation"/></div>
<div>Destination Location: <span id="destination-location" /></div>
</t>
</template>

Get dropdown value and text in controller mvc4 razor

I am working on MVC4 project. I have form where dropdownlist is populated with text and value field.
#Html.DropDownList("SourceDropDownList", new SelectList(""), "-Select-", new { #class = "validate[required]" })
This dropdown is populated from other dropdown change event
here is that code
function OnSourceFacilityDropDownChange(source, e) {
$("#SourceDropDownList").empty();
var curOpt = new Option('-Select-', "");
$("#SourceDropDownList").get(0).options[$("#SourceDropDownList").get(0).options.length] = curOpt;
if (source.value != '') {
var url = getUrl() + '/AdminPanel/GetIns/?id=' + Math.random();
$.ajax({
url: url,
data: { clientid: $("#SourceDropDown").val(), strFacility: source.value }, //parameters go here in object literal form
type: 'GET',
datatype: 'json',
success: function (data) {
$.each(data, function (index, item) {
var curOpt = new Option(item.T, item.T);
curOpt.setAttribute("title", item.T);
$("#SourceDropDownList").get(0).options[$("#SourceDropDownList").get(0).options.length] = curOpt;
});
},
error: function (request, status, error) { alert("Status: " + status + "\n Exception Handling : \n" + request.responseText); },
complete: function () {
$("#divLoading").hide();
}
});
}
else {
}
}
and code in AdminPanel/GetIns controller is
public JsonResult GetInspection(int clientid, string strFacility)
{
var objlist = (from d in Context.tbl_insp
orderby d.str_insp ascending
where d.clientid.Equals(ClientId))
select new { T= d.str_inspname, V= d.dte_start.Value.ToShortDateString()}).ToArray();
Array InspectionList = objlist;
return Json(InspectionList, JsonRequestBehavior.AllowGet);
}
And in model class i have initialized the property of dropdown
public string SourceDropDownList{ get; set; }
now i am getting only text values of what i select in SourceDropDownList dropdown..
How do i get the value also ??
Try with this,Just Example
View
#Html.DropDownList("CustomerId", (SelectList)ViewBag.CustomerNameID, "--Select--")
#Html.DropDownList("CustomerNameId", new SelectList(Enumerable.Empty<SelectListItem>(), "Value", "Text"), "-- Select --")
Script
<script type="text/javascript">
$(document).ready(function () {
$("#CustomerId").change(function () {
var Id = $("#CustomerId").val();
$.ajax({
url: '#Url.Action("GetCustomerNameWithId", "Test")',
type: "Post",
data: { CustomerNameId: Id },
success: function (listItems) {
var STSelectBox = jQuery('#CustomerNameId');
STSelectBox.empty();
if (listItems.length > 0) {
for (var i = 0; i < listItems.length; i++) {
if (i == 0) {
STSelectBox.append('<option value="' + i + '">--Select--</option>');
}
STSelectBox.append('<option value="' + listItems[i].Value + '">' + listItems[i].Text + '</option>');
}
}
else {
for (var i = 0; i < listItems.length; i++) {
STSelectBox.append('<option value="' + listItems[i].Value + '">' + listItems[i].Text + '</option>');
}
}
}
});
});
});
</script>
Controller
public JsonResult GetCustomerNameWithId(string CustomerNameId)
{
int _CustomerNameId = 0;
int.TryParse(CustomerNameId, out _CustomerNameId);
var listItems = GetCustomerNameId(_CustomerNameId).Select(s => new SelectListItem { Value = s.CID.ToString(), Text = s.CustomerName }).ToList<SelectListItem>();
return Json(listItems, JsonRequestBehavior.AllowGet);
}
Model
public class CustomerModel
{
public int CustomerId { get; set; }
public int CustomerNameId { get; set; }
}