blob: d46e9da2a1ba38977f0013851c583b1a15121863 [file] [log] [blame]
Rushabh Mehtaf0b45622017-03-31 12:53:05 +05301// Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
2// License: GNU General Public License v3. See license.txt
3
4frappe.provide("erpnext.buying");
5
6cur_frm.cscript.tax_table = "Purchase Taxes and Charges";
7
8{% include 'erpnext/accounts/doctype/purchase_taxes_and_charges_template/purchase_taxes_and_charges_template.js' %}
9
10cur_frm.email_field = "contact_email";
11
12erpnext.buying.BuyingController = erpnext.TransactionController.extend({
13 setup: function() {
14 this._super();
15 },
16
17 onload: function() {
18 this.setup_queries();
19 this._super();
20
Faris Ansariab74ca72017-05-30 12:54:42 +053021 /* eslint-disable */
22 // no idea where me is coming from
Rushabh Mehtaf0b45622017-03-31 12:53:05 +053023 if(this.frm.get_field('shipping_address')) {
Faris Ansariab74ca72017-05-30 12:54:42 +053024 this.frm.set_query("shipping_address", function() {
25 if(me.frm.doc.customer) {
Rushabh Mehtaf0b45622017-03-31 12:53:05 +053026 return {
KanchanChauhan1dc26b12017-06-13 15:26:35 +053027 query: 'frappe.contacts.doctype.address.address.address_query',
Rushabh Mehtaf0b45622017-03-31 12:53:05 +053028 filters: { link_doctype: 'Customer', link_name: me.frm.doc.customer }
29 };
30 } else
31 return erpnext.queries.company_address_query(me.frm.doc)
32 });
33 }
Faris Ansariab74ca72017-05-30 12:54:42 +053034 /* eslint-enable */
Rushabh Mehtaf0b45622017-03-31 12:53:05 +053035 },
36
37 setup_queries: function() {
38 var me = this;
39
40 if(this.frm.fields_dict.buying_price_list) {
41 this.frm.set_query("buying_price_list", function() {
42 return{
43 filters: { 'buying': 1 }
44 }
45 });
46 }
47
48 me.frm.set_query('supplier', erpnext.queries.supplier);
49 me.frm.set_query('contact_person', erpnext.queries.contact_query);
50 me.frm.set_query('supplier_address', erpnext.queries.address_query);
51
52 if(this.frm.fields_dict.supplier) {
53 this.frm.set_query("supplier", function() {
54 return{ query: "erpnext.controllers.queries.supplier_query" }});
55 }
56
57 this.frm.set_query("item_code", "items", function() {
58 if(me.frm.doc.is_subcontracted == "Yes") {
59 return{
60 query: "erpnext.controllers.queries.item_query",
61 filters:{ 'is_sub_contracted_item': 1 }
62 }
63 } else {
64 return{
65 query: "erpnext.controllers.queries.item_query",
66 filters: {'is_purchase_item': 1}
67 }
68 }
69 });
70 },
71
72 refresh: function(doc) {
73 frappe.dynamic_link = {doc: this.frm.doc, fieldname: 'supplier', doctype: 'Supplier'};
74
75 this.frm.toggle_display("supplier_name",
76 (this.frm.doc.supplier_name && this.frm.doc.supplier_name!==this.frm.doc.supplier));
77
78 if(this.frm.doc.docstatus==0 &&
79 (this.frm.doctype==="Purchase Order" || this.frm.doctype==="Material Request")) {
80 this.set_from_product_bundle();
81 }
82
83 this._super();
84 },
85
86 supplier: function() {
87 var me = this;
88 erpnext.utils.get_party_details(this.frm, null, null, function(){me.apply_pricing_rule()});
89 },
90
91 supplier_address: function() {
92 erpnext.utils.get_address_display(this.frm);
93 },
94
95 buying_price_list: function() {
96 this.apply_price_list();
97 },
98
99 price_list_rate: function(doc, cdt, cdn) {
100 var item = frappe.get_doc(cdt, cdn);
101 frappe.model.round_floats_in(item, ["price_list_rate", "discount_percentage"]);
102
103 item.rate = flt(item.price_list_rate * (1 - item.discount_percentage / 100.0),
104 precision("rate", item));
105
106 this.calculate_taxes_and_totals();
107 },
108
109 discount_percentage: function(doc, cdt, cdn) {
110 this.price_list_rate(doc, cdt, cdn);
111 },
112
113 qty: function(doc, cdt, cdn) {
114 var item = frappe.get_doc(cdt, cdn);
115 if ((doc.doctype == "Purchase Receipt") || (doc.doctype == "Purchase Invoice" && (doc.update_stock || doc.is_return))) {
116 frappe.model.round_floats_in(item, ["qty", "received_qty"]);
117
118 if(!doc.is_return && this.validate_negative_quantity(cdt, cdn, item, ["qty", "received_qty"])){ return }
119
120 if(!item.rejected_qty && item.qty) {
121 item.received_qty = item.qty;
122 }
123
124 frappe.model.round_floats_in(item, ["qty", "received_qty"]);
125 item.rejected_qty = flt(item.received_qty - item.qty, precision("rejected_qty", item));
126 }
127
128 this._super(doc, cdt, cdn);
129 },
130
131 received_qty: function(doc, cdt, cdn) {
132 this.calculate_accepted_qty(doc, cdt, cdn)
133 },
134
135 rejected_qty: function(doc, cdt, cdn) {
136 this.calculate_accepted_qty(doc, cdt, cdn)
137 },
138
139 calculate_accepted_qty: function(doc, cdt, cdn){
140 var item = frappe.get_doc(cdt, cdn);
141 frappe.model.round_floats_in(item, ["received_qty", "rejected_qty"]);
142
143 if(!doc.is_return && this.validate_negative_quantity(cdt, cdn, item, ["received_qty", "rejected_qty"])){ return }
144
145 item.qty = flt(item.received_qty - item.rejected_qty, precision("qty", item));
146 this.qty(doc, cdt, cdn);
147 },
148
149 validate_negative_quantity: function(cdt, cdn, item, fieldnames){
150 if(!item || !fieldnames) { return }
151
152 var is_negative_qty = false;
153 for(var i = 0; i<fieldnames.length; i++) {
154 if(item[fieldnames[i]] < 0){
155 frappe.msgprint(__("Row #{0}: {1} can not be negative for item {2}",
156 [item.idx,__(frappe.meta.get_label(cdt, fieldnames[i], cdn)), item.item_code]));
157 is_negative_qty = true;
158 break;
159 }
160 }
161
162 return is_negative_qty
163 },
164
165 warehouse: function(doc, cdt, cdn) {
166 var item = frappe.get_doc(cdt, cdn);
167 if(item.item_code && item.warehouse) {
168 return this.frm.call({
169 method: "erpnext.stock.get_item_details.get_bin_details",
170 child: item,
171 args: {
172 item_code: item.item_code,
173 warehouse: item.warehouse
174 }
175 });
176 }
177 },
178
179 project: function(doc, cdt, cdn) {
180 var item = frappe.get_doc(cdt, cdn);
181 if(item.project) {
182 $.each(this.frm.doc["items"] || [],
183 function(i, other_item) {
184 if(!other_item.project) {
185 other_item.project = item.project;
186 refresh_field("project", other_item.name, other_item.parentfield);
187 }
188 });
189 }
190 },
191
192 category: function(doc, cdt, cdn) {
193 // should be the category field of tax table
194 if(cdt != doc.doctype) {
195 this.calculate_taxes_and_totals();
196 }
197 },
198 add_deduct_tax: function(doc, cdt, cdn) {
199 this.calculate_taxes_and_totals();
200 },
201
202 set_from_product_bundle: function() {
203 var me = this;
204 this.frm.add_custom_button(__("Product Bundle"), function() {
205 erpnext.buying.get_items_from_product_bundle(me.frm);
206 }, __("Get items from"));
207 },
208
209 shipping_address: function(){
210 var me = this;
211 erpnext.utils.get_address_display(this.frm, "shipping_address",
Faris Ansariab74ca72017-05-30 12:54:42 +0530212 "shipping_address_display", true);
Rushabh Mehtaf0b45622017-03-31 12:53:05 +0530213 },
214
215 tc_name: function() {
216 this.get_terms();
217 },
218 link_to_mrs: function() {
Faris Ansariab74ca72017-05-30 12:54:42 +0530219 var my_items = [];
220 for (var i in cur_frm.doc.items) {
221 if(!cur_frm.doc.items[i].material_request){
222 my_items.push(cur_frm.doc.items[i].item_code);
223 }
224 }
225 frappe.call({
226 method: "erpnext.buying.utils.get_linked_material_requests",
227 args:{
228 items: my_items
229 },
230 callback: function(r) {
231 var i = 0;
232 var item_length = cur_frm.doc.items.length;
233 while (i < item_length) {
234 var qty = cur_frm.doc.items[i].qty;
235 (r.message[0] || []).forEach(function(d) {
236 if (d.qty > 0 && qty > 0 && cur_frm.doc.items[i].item_code == d.item_code && !cur_frm.doc.items[i].material_request_item)
237 {
238 cur_frm.doc.items[i].material_request = d.mr_name;
239 cur_frm.doc.items[i].material_request_item = d.mr_item;
240 var my_qty = Math.min(qty, d.qty);
241 qty = qty - my_qty;
242 d.qty = d.qty - my_qty;
243 cur_frm.doc.items[i].stock_qty = my_qty*cur_frm.doc.items[i].conversion_factor;
244 cur_frm.doc.items[i].qty = my_qty;
245
246 frappe.msgprint("Assigning " + d.mr_name + " to " + d.item_code + " (row " + cur_frm.doc.items[i].idx + ")");
247 if (qty > 0)
248 {
249 frappe.msgprint("Splitting " + qty + " units of " + d.item_code);
250 var newrow = frappe.model.add_child(cur_frm.doc, cur_frm.doc.items[i].doctype, "items");
251 item_length++;
252
253 for (var key in cur_frm.doc.items[i])
Rushabh Mehtaf0b45622017-03-31 12:53:05 +0530254 {
Faris Ansariab74ca72017-05-30 12:54:42 +0530255 newrow[key] = cur_frm.doc.items[i][key];
Rushabh Mehtaf0b45622017-03-31 12:53:05 +0530256 }
257
Faris Ansariab74ca72017-05-30 12:54:42 +0530258 newrow.idx = item_length;
259 newrow["stock_qty"] = newrow.conversion_factor*qty;
260 newrow["qty"] = qty;
261
262 newrow["material_request"] = "";
263 newrow["material_request_item"] = "";
264
265 }
266
267
268
Rushabh Mehtaf0b45622017-03-31 12:53:05 +0530269 }
Faris Ansariab74ca72017-05-30 12:54:42 +0530270
271 });
272 i++;
273 }
274 refresh_field("items");
275 //cur_frm.save();
Rushabh Mehtaf0b45622017-03-31 12:53:05 +0530276 }
Faris Ansariab74ca72017-05-30 12:54:42 +0530277 });
278 }
Rushabh Mehtaf0b45622017-03-31 12:53:05 +0530279});
280
281cur_frm.add_fetch('project', 'cost_center', 'cost_center');
282
283erpnext.buying.get_default_bom = function(frm) {
284 $.each(frm.doc["items"] || [], function(i, d) {
285 if (d.item_code && d.bom === "") {
286 return frappe.call({
287 type: "GET",
288 method: "erpnext.stock.get_item_details.get_default_bom",
289 args: {
290 "item_code": d.item_code,
291 },
292 callback: function(r) {
293 if(r) {
294 frappe.model.set_value(d.doctype, d.name, "bom", r.message);
295 }
296 }
297 })
298 }
299 });
300}
301
302erpnext.buying.get_items_from_product_bundle = function(frm) {
303 var dialog = new frappe.ui.Dialog({
304 title: __("Get Items from Product Bundle"),
305 fields: [
306 {
307 "fieldtype": "Link",
308 "label": __("Product Bundle"),
309 "fieldname": "product_bundle",
310 "options":"Product Bundle",
311 "reqd": 1
312 },
313 {
314 "fieldtype": "Currency",
315 "label": __("Quantity"),
316 "fieldname": "quantity",
317 "reqd": 1,
318 "default": 1
319 },
320 {
321 "fieldtype": "Button",
322 "label": __("Get Items"),
323 "fieldname": "get_items",
324 "cssClass": "btn-primary"
325 }
326 ]
327 });
328
329 dialog.fields_dict.get_items.$input.click(function() {
Faris Ansariab74ca72017-05-30 12:54:42 +0530330 var args = dialog.get_values();
Rushabh Mehtaf0b45622017-03-31 12:53:05 +0530331 if(!args) return;
332 dialog.hide();
333 return frappe.call({
334 type: "GET",
335 method: "erpnext.stock.doctype.packed_item.packed_item.get_items_from_product_bundle",
336 args: {
337 args: {
338 item_code: args.product_bundle,
339 quantity: args.quantity,
340 parenttype: frm.doc.doctype,
341 parent: frm.doc.name,
342 supplier: frm.doc.supplier,
343 currency: frm.doc.currency,
344 conversion_rate: frm.doc.conversion_rate,
345 price_list: frm.doc.buying_price_list,
346 price_list_currency: frm.doc.price_list_currency,
347 plc_conversion_rate: frm.doc.plc_conversion_rate,
348 company: frm.doc.company,
349 is_subcontracted: frm.doc.is_subcontracted,
350 transaction_date: frm.doc.transaction_date || frm.doc.posting_date,
351 ignore_pricing_rule: frm.doc.ignore_pricing_rule
352 }
353 },
354 freeze: true,
355 callback: function(r) {
356 if(!r.exc && r.message) {
357 for ( var i=0; i< r.message.length; i++ ) {
358 var d = frm.add_child("items");
359 var item = r.message[i];
360 for ( var key in item) {
361 if ( !is_null(item[key]) ) {
362 d[key] = item[key];
363 }
364 }
365 if(frappe.meta.get_docfield(d.doctype, "price_list_rate", d.name)) {
366 frm.script_manager.trigger("price_list_rate", d.doctype, d.name);
367 }
368 }
369 frm.refresh_field("items");
370 }
371 }
372 })
373 });
374 dialog.show();
375}