mirror of
https://github.com/frappe/erpnext.git
synced 2026-05-24 23:49:19 +00:00
[fixed conflict]
This commit is contained in:
@@ -8,69 +8,82 @@
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
cur_frm.cscript.tname = "Installation Note Item";
|
||||
cur_frm.cscript.fname = "installed_item_details";
|
||||
|
||||
wn.provide("erpnext.selling");
|
||||
// TODO commonify this code
|
||||
erpnext.selling.InstallationNote = wn.ui.form.Controller.extend({
|
||||
customer: function() {
|
||||
var me = this;
|
||||
if(this.frm.doc.customer) {
|
||||
this.frm.call({
|
||||
doc: this.frm.doc,
|
||||
method: "set_customer_defaults",
|
||||
callback: function(r) {
|
||||
if(!r.exc) me.frm.refresh_fields();
|
||||
}
|
||||
});
|
||||
|
||||
// TODO shift this to depends_on
|
||||
unhide_field(['customer_address', 'contact_person', 'customer_name',
|
||||
'address_display', 'contact_display', 'contact_mobile', 'contact_email',
|
||||
'territory', 'customer_group']);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
$.extend(cur_frm.cscript, new erpnext.selling.InstallationNote({frm: cur_frm}));
|
||||
|
||||
cur_frm.cscript.onload = function(doc, dt, dn) {
|
||||
if(!doc.status) set_multiple(dt,dn,{status:'Draft'});
|
||||
if(doc.__islocal){
|
||||
set_multiple(dt,dn,{inst_date:get_today()});
|
||||
hide_field(['customer_address','contact_person','customer_name','address_display','contact_display','contact_mobile','contact_email','territory','customer_group']);
|
||||
}
|
||||
if (doc.customer) {
|
||||
unhide_field(['customer_address','contact_person','customer_name','address_display','contact_display','contact_mobile','contact_email','territory','customer_group']);
|
||||
}
|
||||
if(!doc.status) set_multiple(dt,dn,{status:'Draft'});
|
||||
if(doc.__islocal){
|
||||
set_multiple(dt,dn,{inst_date:get_today()});
|
||||
hide_field(['customer_address','contact_person','customer_name','address_display','contact_display','contact_mobile','contact_email','territory','customer_group']);
|
||||
}
|
||||
if (doc.customer) {
|
||||
unhide_field(['customer_address','contact_person','customer_name','address_display','contact_display','contact_mobile','contact_email','territory','customer_group']);
|
||||
}
|
||||
}
|
||||
|
||||
cur_frm.fields_dict['delivery_note_no'].get_query = function(doc) {
|
||||
doc = locals[this.doctype][this.docname];
|
||||
var cond = '';
|
||||
if(doc.customer) {
|
||||
cond = '`tabDelivery Note`.customer = "'+doc.customer+'" AND';
|
||||
}
|
||||
return repl('SELECT DISTINCT `tabDelivery Note`.name, `tabDelivery Note`.customer_name FROM `tabDelivery Note`, `tabDelivery Note Item` WHERE `tabDelivery Note`.company = "%(company)s" AND `tabDelivery Note`.docstatus = 1 AND ifnull(`tabDelivery Note`.per_installed,0) < 99.99 AND %(cond)s `tabDelivery Note`.name LIKE "%s" ORDER BY `tabDelivery Note`.name DESC LIMIT 50', {company:doc.company, cond:cond});
|
||||
doc = locals[this.doctype][this.docname];
|
||||
var cond = '';
|
||||
if(doc.customer) {
|
||||
cond = '`tabDelivery Note`.customer = "'+doc.customer+'" AND';
|
||||
}
|
||||
return repl('SELECT DISTINCT `tabDelivery Note`.name, `tabDelivery Note`.customer_name FROM `tabDelivery Note`, `tabDelivery Note Item` WHERE `tabDelivery Note`.company = "%(company)s" AND `tabDelivery Note`.docstatus = 1 AND ifnull(`tabDelivery Note`.per_installed,0) < 99.99 AND %(cond)s `tabDelivery Note`.name LIKE "%s" ORDER BY `tabDelivery Note`.name DESC LIMIT 50', {company:doc.company, cond:cond});
|
||||
}
|
||||
|
||||
|
||||
cur_frm.fields_dict['territory'].get_query = function(doc,cdt,cdn) {
|
||||
return 'SELECT `tabTerritory`.`name`,`tabTerritory`.`parent_territory` FROM `tabTerritory` WHERE `tabTerritory`.`is_group` = "No" AND `tabTerritory`.`docstatus`!= 2 AND `tabTerritory`.%(key)s LIKE "%s" ORDER BY `tabTerritory`.`name` ASC LIMIT 50';
|
||||
return 'SELECT `tabTerritory`.`name`,`tabTerritory`.`parent_territory` FROM `tabTerritory` WHERE `tabTerritory`.`is_group` = "No" AND `tabTerritory`.`docstatus`!= 2 AND `tabTerritory`.%(key)s LIKE "%s" ORDER BY `tabTerritory`.`name` ASC LIMIT 50';
|
||||
}
|
||||
|
||||
cur_frm.cscript.get_items = function(doc, dt, dn) {
|
||||
var callback = function(r,rt) {
|
||||
unhide_field(['customer_address','contact_person','customer_name','address_display','contact_display','contact_mobile','contact_email','territory','customer_group']);
|
||||
cur_frm.refresh();
|
||||
}
|
||||
get_server_fields('pull_delivery_note_details','','',doc, dt, dn,1,callback);
|
||||
var callback = function(r,rt) {
|
||||
unhide_field(['customer_address','contact_person','customer_name','address_display','contact_display','contact_mobile','contact_email','territory','customer_group']);
|
||||
cur_frm.refresh();
|
||||
}
|
||||
get_server_fields('pull_delivery_note_details','','',doc, dt, dn,1,callback);
|
||||
}
|
||||
|
||||
//customer
|
||||
cur_frm.cscript.customer = function(doc,dt,dn) {
|
||||
var callback = function(r,rt) {
|
||||
var doc = locals[cur_frm.doctype][cur_frm.docname];
|
||||
cur_frm.refresh();
|
||||
}
|
||||
|
||||
if(doc.customer) $c_obj(make_doclist(doc.doctype, doc.name), 'get_default_customer_address', '', callback);
|
||||
if(doc.customer) unhide_field(['customer_address','contact_person','customer_name','address_display','contact_display','contact_mobile','contact_email','territory','customer_group']);
|
||||
}
|
||||
|
||||
cur_frm.cscript.customer_address = cur_frm.cscript.contact_person = function(doc,dt,dn) {
|
||||
if(doc.customer) get_server_fields('get_customer_address', JSON.stringify({customer: doc.customer, address: doc.customer_address, contact: doc.contact_person}),'', doc, dt, dn, 1);
|
||||
cur_frm.cscript.customer_address = cur_frm.cscript.contact_person = function(doc,dt,dn) {
|
||||
if(doc.customer) get_server_fields('get_customer_address', JSON.stringify({customer: doc.customer, address: doc.customer_address, contact: doc.contact_person}),'', doc, dt, dn, 1);
|
||||
}
|
||||
|
||||
cur_frm.fields_dict['customer_address'].get_query = function(doc, cdt, cdn) {
|
||||
return 'SELECT name,address_line1,city FROM tabAddress WHERE customer = "'+ doc.customer +'" AND docstatus != 2 AND name LIKE "%s" ORDER BY name ASC LIMIT 50';
|
||||
return 'SELECT name,address_line1,city FROM tabAddress WHERE customer = "'+ doc.customer +'" AND docstatus != 2 AND name LIKE "%s" ORDER BY name ASC LIMIT 50';
|
||||
}
|
||||
|
||||
cur_frm.fields_dict['contact_person'].get_query = function(doc, cdt, cdn) {
|
||||
return 'SELECT name,CONCAT(first_name," ",ifnull(last_name,"")) As FullName,department,designation FROM tabContact WHERE customer = "'+ doc.customer +'" AND docstatus != 2 AND name LIKE "%s" ORDER BY name ASC LIMIT 50';
|
||||
return 'SELECT name,CONCAT(first_name," ",ifnull(last_name,"")) As FullName,department,designation FROM tabContact WHERE customer = "'+ doc.customer +'" AND docstatus != 2 AND name LIKE "%s" ORDER BY name ASC LIMIT 50';
|
||||
}
|
||||
|
||||
cur_frm.fields_dict.customer.get_query = erpnext.utils.customer_query;
|
||||
@@ -2,7 +2,7 @@
|
||||
{
|
||||
"creation": "2013-04-10 11:45:37",
|
||||
"docstatus": 0,
|
||||
"modified": "2013-07-03 10:22:31",
|
||||
"modified": "2013-07-03 10:24:00",
|
||||
"modified_by": "Administrator",
|
||||
"owner": "Administrator"
|
||||
},
|
||||
@@ -314,13 +314,6 @@
|
||||
"oldfieldtype": "Select",
|
||||
"options": "\nProduct Enquiry\nRequest for Information\nSuggestions\nOther"
|
||||
},
|
||||
{
|
||||
"doctype": "DocField",
|
||||
"fieldname": "default_price_list",
|
||||
"fieldtype": "Link",
|
||||
"label": "Default Price List",
|
||||
"options": "Price List"
|
||||
},
|
||||
{
|
||||
"doctype": "DocField",
|
||||
"fieldname": "fiscal_year",
|
||||
|
||||
@@ -16,6 +16,30 @@
|
||||
|
||||
wn.require('app/utilities/doctype/sms_control/sms_control.js');
|
||||
|
||||
wn.provide("erpnext.selling");
|
||||
// TODO commonify this code
|
||||
erpnext.selling.Opportunity = wn.ui.form.Controller.extend({
|
||||
customer: function() {
|
||||
var me = this;
|
||||
if(this.frm.doc.customer) {
|
||||
this.frm.call({
|
||||
doc: this.frm.doc,
|
||||
method: "set_customer_defaults",
|
||||
callback: function(r) {
|
||||
if(!r.exc) me.frm.refresh_fields();
|
||||
}
|
||||
});
|
||||
|
||||
// TODO shift this to depends_on
|
||||
unhide_field(['customer_address', 'contact_person', 'customer_name',
|
||||
'address_display', 'contact_display', 'contact_mobile', 'contact_email',
|
||||
'territory', 'customer_group']);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
$.extend(cur_frm.cscript, new erpnext.selling.Opportunity({frm: cur_frm}));
|
||||
|
||||
cur_frm.cscript.refresh = function(doc, cdt, cdn){
|
||||
erpnext.hide_naming_series();
|
||||
|
||||
@@ -117,28 +141,6 @@ cur_frm.cscript.lead_cust_show = function(doc,cdt,cdn){
|
||||
}
|
||||
}
|
||||
|
||||
// customer
|
||||
cur_frm.cscript.customer = function(doc,dt,dn) {
|
||||
cur_frm.toggle_display("contact_info", doc.customer || doc.lead);
|
||||
|
||||
if(doc.customer) {
|
||||
cur_frm.call({
|
||||
doc: cur_frm.doc,
|
||||
method: "get_default_customer_address",
|
||||
args: { customer: doc.customer },
|
||||
callback: function(r) {
|
||||
if(!r.exc) {
|
||||
cur_frm.refresh();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
unhide_field(["customer_name", "customer_address", "contact_person",
|
||||
"address_display", "contact_display", "contact_mobile", "contact_email",
|
||||
"territory", "customer_group"]);
|
||||
}
|
||||
}
|
||||
|
||||
cur_frm.cscript.customer_address = cur_frm.cscript.contact_person = function(doc,dt,dn) {
|
||||
if(doc.customer) get_server_fields('get_customer_address', JSON.stringify({customer: doc.customer, address: doc.customer_address, contact: doc.contact_person}),'', doc, dt, dn, 1);
|
||||
}
|
||||
@@ -167,7 +169,15 @@ cur_frm.cscript.lead = function(doc, cdt, cdn) {
|
||||
cur_frm.toggle_display("contact_info", doc.customer || doc.lead);
|
||||
|
||||
if(doc.lead) {
|
||||
get_server_fields('get_lead_details', doc.lead,'', doc, cdt, cdn, 1);
|
||||
cur_frm.call({
|
||||
doc: cur_frm.doc,
|
||||
method: "set_lead_defaults",
|
||||
callback: function(r) {
|
||||
if(!r.exc) {
|
||||
cur_frm.refresh_fields();
|
||||
}
|
||||
}
|
||||
});
|
||||
unhide_field(['customer_name', 'address_display','contact_mobile', 'contact_email',
|
||||
'territory']);
|
||||
}
|
||||
|
||||
@@ -24,9 +24,8 @@ from webnotes import msgprint
|
||||
sql = webnotes.conn.sql
|
||||
|
||||
from utilities.transaction_base import TransactionBase
|
||||
|
||||
class DocType(TransactionBase):
|
||||
def __init__(self,doc,doclist=[]):
|
||||
def __init__(self,doc,doclist):
|
||||
self.doc = doc
|
||||
self.doclist = doclist
|
||||
self.fname = 'enq_details'
|
||||
|
||||
@@ -99,7 +99,15 @@ cur_frm.fields_dict.lead.get_query = erpnext.utils.lead_query;
|
||||
|
||||
cur_frm.cscript.lead = function(doc, cdt, cdn) {
|
||||
if(doc.lead) {
|
||||
get_server_fields('get_lead_details', doc.lead,'', doc, cdt, cdn, 1);
|
||||
cur_frm.call({
|
||||
doc: cur_frm.doc,
|
||||
method: "set_lead_defaults",
|
||||
callback: function(r) {
|
||||
if(!r.exc) {
|
||||
cur_frm.refresh_fields();
|
||||
}
|
||||
}
|
||||
});
|
||||
unhide_field('territory');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,10 +26,78 @@ wn.require("app/js/transaction.js");
|
||||
|
||||
erpnext.selling.SellingController = erpnext.TransactionController.extend({
|
||||
setup: function() {
|
||||
var me = this;
|
||||
|
||||
this.frm.add_fetch("sales_partner", "commission_rate", "commission_rate");
|
||||
|
||||
if(this.frm.fields_dict.shipping_address_name && this.frm.fields_dict.customer_address)
|
||||
this.frm.fields_dict.shipping_address_name.get_query = this.frm.fields_dict['customer_address'].get_query;
|
||||
if(this.frm.fields_dict.shipping_address_name && this.frm.fields_dict.customer_address) {
|
||||
this.frm.fields_dict.shipping_address_name.get_query =
|
||||
this.frm.fields_dict['customer_address'].get_query;
|
||||
}
|
||||
|
||||
this.frm.set_query("customer_address", function() {
|
||||
return 'SELECT name, address_line1, city FROM tabAddress \
|
||||
WHERE customer = "'+ me.frm.doc.customer +'" AND docstatus != 2 AND \
|
||||
%(key)s LIKE "%s" ORDER BY name ASC LIMIT 50';
|
||||
});
|
||||
|
||||
this.frm.set_query("contact_person", function() {
|
||||
return 'SELECT name, CONCAT(first_name," ",ifnull(last_name,"")) As FullName, \
|
||||
department, designation FROM tabContact WHERE customer = "'+ me.frm.doc.customer +
|
||||
'" AND docstatus != 2 AND %(key)s LIKE "%s" ORDER BY name ASC LIMIT 50';
|
||||
});
|
||||
|
||||
if(this.frm.fields_dict.charge) {
|
||||
this.frm.set_query("charge", function() {
|
||||
return 'SELECT DISTINCT `tabSales Taxes and Charges Master`.name FROM \
|
||||
`tabSales Taxes and Charges Master` \
|
||||
WHERE `tabSales Taxes and Charges Master`.company = "' + me.frm.doc.company +
|
||||
'" AND `tabSales Taxes and Charges Master`.company is not NULL \
|
||||
AND `tabSales Taxes and Charges Master`.docstatus != 2 \
|
||||
AND `tabSales Taxes and Charges Master`.%(key)s LIKE "%s" \
|
||||
ORDER BY `tabSales Taxes and Charges Master`.name LIMIT 50';
|
||||
});
|
||||
}
|
||||
|
||||
this.frm.fields_dict.customer.get_query = erpnext.utils.customer_query;
|
||||
|
||||
this.frm.fields_dict.lead && this.frm.set_query("lead", erpnext.utils.lead_query);
|
||||
|
||||
if(!this.fname) {
|
||||
return;
|
||||
}
|
||||
|
||||
if(this.frm.fields_dict[this.fname].grid.get_field('item_code')) {
|
||||
this.frm.set_query("item_code", this.fname, function() {
|
||||
return me.frm.doc.order_type === "Maintenance" ?
|
||||
erpnext.queries.item({'ifnull(tabItem.is_service_item, "No")': "Yes"}) :
|
||||
erpnext.queries.item({'ifnull(tabItem.is_sales_item, "No")': "Yes"});
|
||||
});
|
||||
}
|
||||
|
||||
if(this.frm.fields_dict[this.fname].grid.get_field('batch_no')) {
|
||||
this.frm.set_query("batch_no", this.fname, function(doc, cdt, cdn) {
|
||||
var item = wn.model.get_doc(cdt, cdn);
|
||||
if(!item.item_code) {
|
||||
wn.throw("Please enter Item Code to get batch no");
|
||||
} else {
|
||||
if(item.warehouse) {
|
||||
return "select batch_no from `tabStock Ledger Entry` sle \
|
||||
where item_code = '" + item.item_code +
|
||||
"' and warehouse = '" + item.warehouse +
|
||||
"' and ifnull(is_cancelled, 'No') = 'No' and batch_no like '%s' \
|
||||
and exists(select * from `tabBatch` where \
|
||||
name = sle.batch_no and expiry_date >= '" + me.frm.doc.posting_date +
|
||||
"' and docstatus != 2) group by batch_no having sum(actual_qty) > 0 \
|
||||
order by batch_no desc limit 50";
|
||||
} else {
|
||||
return "SELECT name FROM tabBatch WHERE docstatus != 2 AND item = '" +
|
||||
item.item_code + "' and expiry_date >= '" + me.frm.doc.posting_date +
|
||||
"' AND name like '%s' ORDER BY name DESC LIMIT 50";
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
onload: function() {
|
||||
@@ -403,7 +471,7 @@ erpnext.selling.SellingController = erpnext.TransactionController.extend({
|
||||
|
||||
var setup_field_label_map = function(fields_list, currency) {
|
||||
$.each(fields_list, function(i, fname) {
|
||||
var docfield = wn.meta.get_docfield(me.frm.doc.doctype, fname);
|
||||
var docfield = wn.meta.docfield_map[me.frm.doc.doctype][fname];
|
||||
if(docfield) {
|
||||
var label = wn._(docfield.label || "").replace(/\([^\)]*\)/g, "");
|
||||
field_label_map[fname] = label.trim() + " (" + currency + ")";
|
||||
@@ -448,7 +516,7 @@ erpnext.selling.SellingController = erpnext.TransactionController.extend({
|
||||
var setup_field_label_map = function(fields_list, currency, parentfield) {
|
||||
var grid_doctype = me.frm.fields_dict[parentfield].grid.doctype;
|
||||
$.each(fields_list, function(i, fname) {
|
||||
var docfield = wn.meta.get_docfield(grid_doctype, fname);
|
||||
var docfield = wn.meta.docfield_map[grid_doctype][fname];
|
||||
if(docfield) {
|
||||
var label = wn._(docfield.label || "").replace(/\([^\)]*\)/g, "");
|
||||
field_label_map[grid_doctype + "-" + fname] =
|
||||
@@ -508,15 +576,6 @@ erpnext.selling.SellingController = erpnext.TransactionController.extend({
|
||||
}
|
||||
});
|
||||
|
||||
// to save previous state of cur_frm.cscript
|
||||
var prev_cscript = {};
|
||||
$.extend(prev_cscript, cur_frm.cscript);
|
||||
|
||||
cur_frm.cscript = new erpnext.selling.SellingController({frm: cur_frm});
|
||||
|
||||
// for backward compatibility: combine new and previous states
|
||||
$.extend(cur_frm.cscript, prev_cscript);
|
||||
|
||||
// Help for Sales BOM items
|
||||
var set_sales_bom_help = function(doc) {
|
||||
if(!cur_frm.fields_dict.packing_list) return;
|
||||
@@ -540,61 +599,3 @@ var set_sales_bom_help = function(doc) {
|
||||
}
|
||||
refresh_field('sales_bom_help');
|
||||
}
|
||||
|
||||
cur_frm.fields_dict[cur_frm.cscript.fname].grid.get_field("item_code").get_query = function(doc, cdt, cdn) {
|
||||
if (doc.order_type == "Maintenance") {
|
||||
return erpnext.queries.item({
|
||||
'ifnull(tabItem.is_service_item, "No")': 'Yes'
|
||||
});
|
||||
} else {
|
||||
return erpnext.queries.item({
|
||||
'ifnull(tabItem.is_sales_item, "No")': 'Yes'
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
cur_frm.fields_dict[cur_frm.cscript.fname].grid.get_field('batch_no').get_query =
|
||||
function(doc, cdt, cdn) {
|
||||
var d = locals[cdt][cdn];
|
||||
if(d.item_code) {
|
||||
if (d.warehouse) {
|
||||
return "select batch_no from `tabStock Ledger Entry` sle \
|
||||
where item_code = '" + d.item_code + "' and warehouse = '" + d.warehouse +
|
||||
"' and ifnull(is_cancelled, 'No') = 'No' and batch_no like '%s' \
|
||||
and exists(select * from `tabBatch` where \
|
||||
name = sle.batch_no and expiry_date >= '" + doc.posting_date +
|
||||
"' and docstatus != 2) group by batch_no having sum(actual_qty) > 0 \
|
||||
order by batch_no desc limit 50";
|
||||
} else {
|
||||
return "SELECT name FROM tabBatch WHERE docstatus != 2 AND item = '" +
|
||||
d.item_code + "' and expiry_date >= '" + doc.posting_date +
|
||||
"' AND name like '%s' ORDER BY name DESC LIMIT 50";
|
||||
}
|
||||
} else {
|
||||
msgprint("Please enter Item Code to get batch no");
|
||||
}
|
||||
}
|
||||
|
||||
cur_frm.fields_dict['customer_address'].get_query = function(doc, cdt, cdn) {
|
||||
return 'SELECT name, address_line1, city FROM tabAddress \
|
||||
WHERE customer = "'+ doc.customer +'" AND docstatus != 2 AND \
|
||||
%(key)s LIKE "%s" ORDER BY name ASC LIMIT 50';
|
||||
}
|
||||
|
||||
cur_frm.fields_dict['contact_person'].get_query = function(doc, cdt, cdn) {
|
||||
return 'SELECT name, CONCAT(first_name," ",ifnull(last_name,"")) As FullName, \
|
||||
department, designation FROM tabContact WHERE customer = "'+ doc.customer +
|
||||
'" AND docstatus != 2 AND %(key)s LIKE "%s" ORDER BY name ASC LIMIT 50';
|
||||
}
|
||||
|
||||
// ************* GET OTHER CHARGES BASED ON COMPANY *************
|
||||
cur_frm.fields_dict.charge.get_query = function(doc) {
|
||||
return 'SELECT DISTINCT `tabSales Taxes and Charges Master`.name FROM \
|
||||
`tabSales Taxes and Charges Master` WHERE `tabSales Taxes and Charges Master`.company = "'
|
||||
+doc.company+'" AND `tabSales Taxes and Charges Master`.company is not NULL \
|
||||
AND `tabSales Taxes and Charges Master`.docstatus != 2 \
|
||||
AND `tabSales Taxes and Charges Master`.%(key)s LIKE "%s" \
|
||||
ORDER BY `tabSales Taxes and Charges Master`.name LIMIT 50';
|
||||
}
|
||||
|
||||
cur_frm.fields_dict.customer.get_query = erpnext.utils.customer_query;
|
||||
Reference in New Issue
Block a user