Skip to content

Instantly share code, notes, and snippets.

@monroy95
Created April 12, 2018 17:31
Show Gist options
  • Save monroy95/f6c192ad19541d80db5c9ab966bb724e to your computer and use it in GitHub Desktop.
Save monroy95/f6c192ad19541d80db5c9ab966bb724e to your computer and use it in GitHub Desktop.
// Cuando carga, carga la pagina sales-analitycs-2 que a su vez recibe una funcion con parametro
// wrapper, esto quiere decri que podra hacer varias cosas al mismo tiempo
frappe.pages['sales-analytics-2'].on_page_load = function (wrapper) {
var page = frappe.ui.make_app_page({
parent: wrapper,
title: 'Sales Analytics 2.0',
single_column: true
});
// wrapper permite llamar multiples funciones
new erpnext.SalesAnalytics2(wrapper);
frappe.breadcrumbs.add("Revelare");
}
// La vista para Sales Analitycs2 hereda de TreeGridReport : TODO
erpnext.SalesAnalytics2 = frappe.views.TreeGridReport.extend({
init: function (wrapper) {
// Super Constructor: Aca se asignan las propiedades iniciales.
this._super({
title: __("Sales Analytics 2.0"),
parent: $(wrapper).find('.layout-main'),
page: wrapper.page,
doctypes: ["Item", "Item Group", "Customer", "Customer Group", "Company", "Territory",
"Fiscal Year", "Sales Invoice", "Sales Invoice Item",
"Sales Order", "Sales Order Item[Sales Analytics]",
"Delivery Note", "Delivery Note Item[Sales Analytics]"
],
tree_grid: {
show: true
}
});
this.tree_grids = {
"Customer Group": {
label: __("Customer Group / Customer"),
show: true,
item_key: "customer",
parent_field: "parent_customer_group",
formatter: function (item) {
return item.customer_name ? item.customer_name + " (" + item.name + ")" : item.name;
}
},
"Customer": {
label: __("Customer"),
show: false,
item_key: "customer",
formatter: function (item) {
return item.customer_name ? item.customer_name + " (" + item.name + ")" : item.name;
}
},
"Item Group": {
label: __("Item"),
show: true,
parent_field: "parent_item_group",
item_key: "item_code",
formatter: function (item) {
return item.name;
}
},
"Item": {
label: __("Item"),
show: true,
item_key: "item_code",
formatter: function (item) {
return item.name;
// return item.stock_uom // Muestra la unidad de medida default
}
},
"Territory": {
label: __("Territory / Customer"),
show: true,
item_key: "customer",
parent_field: "parent_territory",
formatter: function (item) {
return item.customer_name ? item.customer_name + " (" + item.name + ")" : item.name;
}
}
}
},
// Configuracion Columnas
setup_columns: function () {
this.tree_grid = this.tree_grids[this.tree_type];
var std_columns = [{
id: "check",
name: "Plot",
field: "check",
width: 30,
formatter: this.check_formatter
},
{
id: "name",
name: this.tree_grid.label,
field: "name",
width: 300,
formatter: this.tree_formatter
},
{
id: "total",
name: "Total",
field: "total",
plot: false,
formatter: this.currency_formatter
},
// Agregando columna de UOM:
// Name: El nombre a mostrar en la columna del informe
// ? ID: Asumimos que es el identificador del objeto FIXME
// Field: El campo que se desea mostrar
// Plot: Si se muestra o no en la gráfica
// Width: El ancho en pixelas de la columna.
// Formatter: Formater es el formato a mostrarse en la pantalla.
{
id: "UOM2",
name: "UOM",
field: "stock_uom",
width: 100,
plot: false,
formatter: this.select // formatters.js public/js // muestra la unidad de medida default para cada item
}
];
this.make_date_range_columns();
this.columns = std_columns.concat(this.columns);
},
// Especificacion de filtros
filters: [{
fieldtype: "Select",
fieldname: "tree_type",
label: __("Tree Type"),
//options: ["Customer Group", "Customer",
// "Item Group", "Item", "Territory"
//],
options: ["Item Group", "Item", "Customer Group", "Customer", "Territory"],
filter: function (val, item, opts, me) {
return me.apply_zero_filter(val, item, opts, me);
}
},
{
fieldtype: "Select",
fieldname: "based_on",
label: __("Based On"),
options: ["Sales Invoice",
"Sales Order", "Delivery Note"
]
},
{
fieldtype: "Select",
fieldname: "value_or_qty",
label: __("Value or Qty"),
options: [{
label: __("Value"),
value: "Value"
}, {
label: __("Quantity"),
value: "Quantity"
}]
},
{
fieldtype: "Date",
fieldname: "from_date",
label: __("From Date")
},
{
fieldtype: "Label",
fieldname: "to",
label: __("To")
},
{
fieldtype: "Date",
fieldname: "to_date",
label: __("To Date")
},
{
fieldtype: "Select",
fieldname: "company",
label: __("Company"),
link: "Company",
default_value: __("Select Company...")
},
{
fieldtype: "Select",
label: __("Range"),
fieldname: "range",
options: [{
label: __("Daily"),
value: "Daily"
}, {
label: __("Weekly"),
value: "Weekly"
},
{
label: __("Monthly"),
value: "Monthly"
}, {
label: __("Quarterly"),
value: "Quarterly"
},
{
label: __("Yearly"),
value: "Yearly"
}
]
}
],
// Configurando Filtros
setup_filters: function () {
var me = this; // Forma clasica para hacer refencia al contexto del scope actual
this._super(); // SuperConstructor
// Actualiza los datos cuando ocurren los trigger dentro del array
this.trigger_refresh_on_change(["value_or_qty", "tree_type", "based_on", "company"]);
// Mostrar los ceros
this.show_zero_check();
// Configurar check grafica
this.setup_chart_check();
},
// inicializando Filtros
init_filter_values: function () {
this._super();
this.filter_inputs.range.val('Monthly');
},
// Preparando Data
// TODO:
prepare_data: function () {
var me = this;
if (!this.tl) {
// add 'Not Set' Customer & Item
// (Customer / Item are not mandatory!!)
// TODO: Que hace report_dump?
frappe.report_dump.data["Customer"].push({
name: "Not Set",
parent_customer_group: "All Customer Groups",
parent_territory: "All Territories",
id: "Not Set",
});
frappe.report_dump.data["Item"].push({
name: "Not Set",
parent_item_group: "All Item Groups",
id: "Not Set",
});
}
if (!this.tl || !this.tl[this.based_on]) {
this.make_transaction_list(this.based_on, this.based_on + " Item");
}
if (!this.data || me.item_type != me.tree_type) {
if (me.tree_type == 'Customer') {
var items = frappe.report_dump.data["Customer"];
}
if (me.tree_type == 'Customer Group') {
var items = this.prepare_tree("Customer", "Customer Group");
} else if (me.tree_type == "Item Group") {
var items = this.prepare_tree("Item", "Item Group");
} else if (me.tree_type == "Item") {
var items = frappe.report_dump.data["Item"];
} else if (me.tree_type == "Territory") {
var items = this.prepare_tree("Customer", "Territory");
}
me.item_type = me.tree_type
me.parent_map = {};
me.item_by_name = {};
me.data = [];
$.each(items, function (i, v) {
var d = copy_dict(v);
me.data.push(d);
me.item_by_name[d.name] = d;
if (d[me.tree_grid.parent_field]) {
me.parent_map[d.name] = d[me.tree_grid.parent_field];
}
me.reset_item_values(d);
});
this.set_indent();
} else {
// otherwise, only reset values
$.each(this.data, function (i, d) {
me.reset_item_values(d);
});
}
this.prepare_balances();
if (me.tree_grid.show) { // TODO: probar llamar funcion
this.set_totals(false);
this.update_groups();
} else {
this.set_totals(true);
}
},
// Preparar Balances
// TODO:
prepare_balances: function () {
var me = this; // Hace referencia a this en el contexto actual (scope)
// Tomando los datos de fecha inicial
var from_date = frappe.datetime.str_to_obj(this.from_date);
// Tomando los datos de fecha final
var to_date = frappe.datetime.str_to_obj(this.to_date);
// Aca se guarda el estado si es valor o cantidad, pero como default se le asigna como "value" ¿?
var is_val = this.value_or_qty == 'Value';
// Recorriendo los campos y realizando operaciones. Se ejecuta cada vez que se utiliza el trigger/evento
// based_on
// tl = layout ¿?
$.each(this.tl[this.based_on], function (i, tl) { // TODO: LLAMAR FUNCIONES AQUI, PROBAR?
// Debe ser la compañia default
if (me.is_default('company') ? true : tl.company === me.company) {
// Agrega las columnas por fechas
var posting_date = frappe.datetime.str_to_obj(tl.posting_date);
// Permite estar en el rango de las fechas seleccionadas
if (posting_date >= from_date && posting_date <= to_date) {
var item = me.item_by_name[tl[me.tree_grid.item_key]] || me.item_by_name['Not Set'];
if (item) {
// FIXME: REALIZAR AQUI OPERACIONES MATEMATICAS
item[me.column_map[tl.posting_date].field] += (is_val ? tl.base_net_amount : tl.qty * 10); // FIXME: OPERACIONES DE PRUEBA
}
}
}
});
},
// Actualizar Grupos
// TODO:
update_groups: function () {
var me = this;
$.each(this.data, function (i, item) {
var parent = me.parent_map[item.name];
while (parent) {
var parent_group = me.item_by_name[parent];
$.each(me.columns, function (c, col) {
if (col.formatter == me.currency_formatter) {
parent_group[col.field] =
flt(parent_group[col.field]) + flt(item[col.field]);
}
});
parent = me.parent_map[parent];
}
});
},
// Totalizar
// TODO:
set_totals: function (sort) {
var me = this;
var checked = false;
$.each(this.data, function (i, d) {
d.total = 0.0;
$.each(me.columns, function (i, col) {
if (col.formatter == me.currency_formatter && !col.hidden && col.field != "total")
d.total += d[col.field];
if (d.checked) checked = true;
})
});
if (sort) this.data = this.data.sort(function (a, b) {
return a.total < b.total;
});
if (!this.checked) {
this.data[0].checked = true;
}
}
});
// ES6 METHODS NO FUNCIONAN :(
// let clicke = document.getElementsByClassName("btn btn-primary btn-sm primary-action");
// clicke.addEventListener("click", () => console.log('MARIO'));
// $(".btn btn-primary btn-sm primary-action").change(function () {
// alert("Handler for .change() called.");
// });
// $("#btn").click(function () {
// console.log('Mario')
// });
// TODO: FEATURES REPORT BUILDER!!
// ENCONTRAR UN TRIGGER QUE PARA CUANDO CARGUE EL REPORT, PARA ASI BUSCAR Y LLAMAR LA UNIDAD DE MEDIDA
// DEFAULT: CUANDO EL BOTON ACTUALIZAR SE ACCIONE,
// refresh: No funciona!!
// on_load: No Funciona!!
// ¿?
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment