[mapper] purchase cycle

This commit is contained in:
Nabin Hait
2013-07-05 15:23:47 +05:30
parent 44935e4608
commit eb883ee7a3
21 changed files with 390 additions and 823 deletions

View File

@@ -37,15 +37,15 @@ erpnext.buying.MaterialRequestController = erpnext.buying.BuyingController.exten
if(doc.docstatus == 1 && doc.status != 'Stopped'){
if(doc.material_request_type === "Purchase")
cur_frm.add_custom_button("Make Supplier Quotation",
cur_frm.cscript.make_supplier_quotation);
this.make_supplier_quotation);
if(doc.material_request_type === "Transfer" && doc.status === "Submitted")
cur_frm.add_custom_button("Transfer Material", cur_frm.cscript.make_stock_entry);
cur_frm.add_custom_button("Transfer Material", this.make_stock_entry);
if(flt(doc.per_ordered, 2) < 100) {
if(doc.material_request_type === "Purchase")
cur_frm.add_custom_button('Make Purchase Order',
cur_frm.cscript.make_purchase_order);
this.make_purchase_order);
cur_frm.add_custom_button('Stop Material Request',
cur_frm.cscript['Stop Material Request']);

View File

@@ -241,19 +241,17 @@ def _update_requested_qty(controller, mr_obj, mr_items):
"posting_date": controller.doc.posting_date,
})
def set_missing_values(source, target):
po = webnotes.bean(target)
po.run_method("set_missing_values")
@webnotes.whitelist()
def make_purchase_order(source_name, target_doclist=None):
from webnotes.model.mapper import get_mapped_doclist
def update_item(obj, target):
def update_item(obj, target, source_parent):
target.conversion_factor = 1
target.qty = flt(obj.qty) - flt(obj.ordered_qty)
def set_missing_values(source, target):
po = webnotes.bean(target)
po.run_method("set_missing_values")
doclist = get_mapped_doclist("Material Request", source_name, {
"Material Request": {
@@ -281,10 +279,6 @@ def make_purchase_order(source_name, target_doclist=None):
def make_supplier_quotation(source_name, target_doclist=None):
from webnotes.model.mapper import get_mapped_doclist
def set_missing_values(source, target):
sq = webnotes.bean(target)
sq.run_method("set_missing_values")
doclist = get_mapped_doclist("Material Request", source_name, {
"Material Request": {
"doctype": "Supplier Quotation",
@@ -309,7 +303,7 @@ def make_supplier_quotation(source_name, target_doclist=None):
def make_stock_entry(source_name, target_doclist=None):
from webnotes.model.mapper import get_mapped_doclist
def set_purpose(source, target):
def set_purpose(source, target, source_parent):
target[0].purpose = "Material Transfer"
def update_item(source, target):

View File

@@ -30,7 +30,7 @@ erpnext.stock.PurchaseReceiptController = erpnext.buying.BuyingController.extend
if(this.frm.doc.docstatus == 1) {
if(flt(this.frm.doc.per_billed, 2) < 100) {
cur_frm.add_custom_button('Make Purchase Invoice',
cur_frm.cscript['Make Purchase Invoice']);
this.make_purchase_invoice);
}
cur_frm.add_custom_button('Send SMS', cur_frm.cscript['Send SMS']);
}
@@ -68,7 +68,8 @@ erpnext.stock.PurchaseReceiptController = erpnext.buying.BuyingController.extend
wn.model.round_floats_in(item, ["received_qty", "rejected_qty"]);
if(item.rejected_qty > item.received_qty) {
msgprint(wn._("Error") + ": " + wn._(wn.meta.get_label(item.doctype, "rejected_qty", item.name))
msgprint(wn._("Error") + ": " +
wn._(wn.meta.get_label(item.doctype, "rejected_qty", item.name))
+ " > " + wn._(wn.meta.get_label(item.doctype, "received_qty", item.name)));
item.qty = item.rejected_qty = 0.0;
} else {
@@ -77,6 +78,21 @@ erpnext.stock.PurchaseReceiptController = erpnext.buying.BuyingController.extend
this.qty(doc, cdt, cdn);
},
make_purchase_invoice: function() {
wn.model.open_mapped_doc({
method: "stock.doctype.purchase_receipt.purchase_receipt.make_purchase_invoice",
source_name: cur_frm.doc.name
})
},
pull_purchase_order_details: function() {
wn.model.map_current_doc({
method: "buying.doctype.purchase_order.purchase_order.make_purchase_receipt",
source_name: cur_frm.doc.purchase_order_no,
})
}
});
// for backward compatibility: combine new and previous states
@@ -94,17 +110,6 @@ 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 supplier = "'+ doc.supplier +'" AND docstatus != 2 AND name LIKE "%s" ORDER BY name ASC LIMIT 50';
}
// Get Purchase Order Button
// -----------------
cur_frm.cscript.pull_purchase_order_details = function(doc, dt, dn) {
$c_obj(make_doclist(dt,dn),'get_po_details','',function(r,rt) {
cur_frm.refresh_fields();
});
}
//================ create new contact ============================================================================
cur_frm.cscript.new_contact = function(){
tn = wn.model.make_new_doc_and_get_name('Contact');
locals['Contact'][tn].is_supplier = 1;
@@ -112,15 +117,12 @@ cur_frm.cscript.new_contact = function(){
loaddoc('Contact', tn);
}
// ***************** Get project name *****************
cur_frm.fields_dict['purchase_receipt_details'].grid.get_field('project_name').get_query = function(doc, cdt, cdn) {
return 'SELECT `tabProject`.name FROM `tabProject` \
WHERE `tabProject`.status not in ("Completed", "Cancelled") \
AND `tabProject`.name LIKE "%s" ORDER BY `tabProject`.name ASC LIMIT 50';
}
//========================= Overloaded query for link batch_no =============================================================
cur_frm.fields_dict['purchase_receipt_details'].grid.get_field('batch_no').get_query= function(doc, cdt, cdn) {
var d = locals[cdt][cdn];
if(d.item_code){
@@ -139,12 +141,11 @@ cur_frm.cscript.select_print_heading = function(doc,cdt,cdn){
else
cur_frm.pformat.print_heading = "Purchase Receipt";
}
// ***************** Get Print Heading *****************
cur_frm.fields_dict['select_print_heading'].get_query = function(doc, cdt, cdn) {
return 'SELECT `tabPrint Heading`.name FROM `tabPrint Heading` WHERE `tabPrint Heading`.docstatus !=2 AND `tabPrint Heading`.name LIKE "%s" ORDER BY `tabPrint Heading`.name ASC LIMIT 50';
}
//================================= Purchase Order No Get Query ====================================
cur_frm.fields_dict['purchase_order_no'].get_query = function(doc) {
if (doc.supplier)
return 'SELECT DISTINCT `tabPurchase Order`.`name` FROM `tabPurchase Order` WHERE `tabPurchase Order`.`supplier` = "' +doc.supplier + '" and`tabPurchase Order`.`docstatus` = 1 and `tabPurchase Order`.`status` != "Stopped" and ifnull(`tabPurchase Order`.`per_received`, 0) < 99.99 and `tabPurchase Order`.`currency` = ifnull("' +doc.currency+ '","") and `tabPurchase Order`.company = "'+ doc.company +'" and `tabPurchase Order`.%(key)s LIKE "%s" ORDER BY `tabPurchase Order`.`name` DESC LIMIT 50';
@@ -152,36 +153,10 @@ cur_frm.fields_dict['purchase_order_no'].get_query = function(doc) {
return 'SELECT DISTINCT `tabPurchase Order`.`name` FROM `tabPurchase Order` WHERE `tabPurchase Order`.`docstatus` = 1 and `tabPurchase Order`.`company` = "'+ doc.company +'" and `tabPurchase Order`.`status` != "Stopped" and ifnull(`tabPurchase Order`.`per_received`, 0) < 99.99 and `tabPurchase Order`.%(key)s LIKE "%s" ORDER BY `tabPurchase Order`.`name` DESC LIMIT 50';
}
// QA INspection report get_query
//---------------------------------
cur_frm.fields_dict.purchase_receipt_details.grid.get_field("qa_no").get_query = function(doc) {
return 'SELECT `tabQuality Inspection`.name FROM `tabQuality Inspection` WHERE `tabQuality Inspection`.docstatus = 1 AND `tabQuality Inspection`.%(key)s LIKE "%s"';
}
// On Button Click Functions
// ------------------------------------------------------------------------------
// ================================ Make Purchase Invoice ==========================================
cur_frm.cscript['Make Purchase Invoice'] = function() {
n = wn.model.make_new_doc_and_get_name('Purchase Invoice');
$c('dt_map', args={
'docs':wn.model.compress([locals['Purchase Invoice'][n]]),
'from_doctype': cur_frm.doc.doctype,
'to_doctype':'Purchase Invoice',
'from_docname': cur_frm.doc.name,
'from_to_list':"[['Purchase Receipt','Purchase Invoice'],['Purchase Receipt Item','Purchase Invoice Item'],['Purchase Taxes and Charges','Purchase Taxes and Charges']]"
}, function(r,rt) {
loaddoc('Purchase Invoice', n);
}
);
}
//****************** For print sales order no and date*************************
cur_frm.pformat.purchase_order_no = function(doc, cdt, cdn){
//function to make row of table

View File

@@ -52,11 +52,6 @@ class DocType(BuyingController):
def get_bin_details(self, arg = ''):
return get_obj(dt='Purchase Common').get_bin_details(arg)
# Pull Purchase Order
def get_po_details(self):
self.validate_prev_docname()
get_obj('DocType Mapper', 'Purchase Order-Purchase Receipt').dt_map('Purchase Order', 'Purchase Receipt', self.doc.purchase_order_no, self.doc, self.doclist, "[['Purchase Order','Purchase Receipt'],['Purchase Order Item', 'Purchase Receipt Item'],['Purchase Taxes and Charges','Purchase Taxes and Charges']]")
# validate if PO has been pulled twice
def validate_prev_docname(self):
for d in getlist(self.doclist, 'purchase_receipt_details'):
@@ -64,9 +59,6 @@ class DocType(BuyingController):
msgprint(cstr(self.doc.purchase_order_no) + " Purchase Order details have already been pulled. ")
raise Exception
# validation
#-------------------------------------------------------------------------------------------------------------
# validate accepted and rejected qty
def validate_accepted_rejected_qty(self):
for d in getlist(self.doclist, "purchase_receipt_details"):
@@ -333,4 +325,47 @@ class DocType(BuyingController):
total_valuation_amount += flt(item.valuation_rate) * \
flt(item.qty) * flt(item.conversion_factor)
return total_valuation_amount
return total_valuation_amount
@webnotes.whitelist()
def make_purchase_invoice(source_name, target_doclist=None):
from webnotes.model.mapper import get_mapped_doclist
def set_missing_values(source, target):
bean = webnotes.bean(target)
bean.run_method("set_missing_values")
bean.run_method("set_supplier_defaults")
def update_item(obj, target, source_parent):
target.conversion_factor = 1
target.qty = (flt(obj.amount) - flt(obj.billed_amt)) / flt(obj.purchase_rate)
target.import_amount = (flt(obj.amount) - flt(obj.billed_amt)) / \
flt(source_parent.conversion_rate)
target.amount = flt(obj.amount) - flt(obj.billed_amt)
doclist = get_mapped_doclist("Purchase Receipt", source_name, {
"Purchase Receipt": {
"doctype": "Purchase Invoice",
"validation": {
"docstatus": ["=", 1],
}
},
"Purchase Receipt Item": {
"doctype": "Purchase Invoice Item",
"field_map": {
"name": "pr_detail",
"parent": "purchase_receipt",
"prevdoc_detail_docname": "po_detail",
"prevdoc_docname": "purchase_order",
"purchase_rate": "rate"
},
"postprocess": update_item,
"condition": lambda doc: doc.amount==0 or doc.billed_amt < doc.amount
},
"Purchase Taxes and Charges": {
"doctype": "Purchase Taxes and Charges",
}
}, target_doclist, set_missing_values)
return [d.fields for d in doclist]

View File

@@ -2,7 +2,7 @@
{
"creation": "2013-05-21 16:16:39",
"docstatus": 0,
"modified": "2013-06-11 16:16:40",
"modified": "2013-07-05 14:38:03",
"modified_by": "Administrator",
"owner": "Administrator"
},
@@ -31,7 +31,6 @@
"parent": "Purchase Receipt",
"parentfield": "permissions",
"parenttype": "DocType",
"permlevel": 0,
"read": 1,
"report": 1
},
@@ -262,7 +261,6 @@
"fieldtype": "Button",
"label": "Pull Purchase Order Details",
"oldfieldtype": "Button",
"options": "get_po_details",
"print_hide": 1
},
{
@@ -869,19 +867,41 @@
"read_only": 1
},
{
"amend": 1,
"cancel": 1,
"create": 1,
"amend": 0,
"cancel": 0,
"create": 0,
"doctype": "DocPerm",
"permlevel": 1,
"role": "Material Manager",
"submit": 1,
"write": 1
"submit": 0,
"write": 0
},
{
"amend": 1,
"cancel": 1,
"create": 1,
"doctype": "DocPerm",
"permlevel": 0,
"role": "Material Manager",
"submit": 1,
"write": 1
},
{
"amend": 0,
"cancel": 0,
"create": 0,
"doctype": "DocPerm",
"permlevel": 1,
"role": "Material User",
"submit": 0,
"write": 0
},
{
"amend": 1,
"cancel": 1,
"create": 1,
"doctype": "DocPerm",
"permlevel": 0,
"role": "Material User",
"submit": 1,
"write": 1
@@ -891,13 +911,24 @@
"cancel": 1,
"create": 1,
"doctype": "DocPerm",
"permlevel": 0,
"role": "Purchase User",
"submit": 1,
"write": 1
},
{
"amend": 0,
"cancel": 0,
"create": 0,
"doctype": "DocPerm",
"permlevel": 1,
"role": "Purchase User",
"submit": 0
},
{
"doctype": "DocPerm",
"match": "supplier",
"permlevel": 0,
"role": "Supplier"
}
]

View File

@@ -22,6 +22,21 @@ import webnotes.defaults
from webnotes.utils import cint
class TestPurchaseReceipt(unittest.TestCase):
def test_make_purchase_invocie(self):
from stock.doctype.purchase_receipt.purchase_receipt import make_purchase_invoice
pr = webnotes.bean(copy=test_records[0]).insert()
self.assertRaises(webnotes.ValidationError, make_purchase_invoice,
pr.doc.name)
pr = webnotes.bean("Purchase Receipt", pr.doc.name)
pr.submit()
pi = make_purchase_invoice(pr.doc.name)
self.assertEquals(pi[0]["doctype"], "Purchase Invoice")
self.assertEquals(len(pi), len(pr.doclist))
def test_purchase_receipt_no_gl_entry(self):
pr = webnotes.bean(copy=test_records[0])
pr.run_method("calculate_taxes_and_totals")