merge conflict fixed

This commit is contained in:
Akhilesh Darjee 2014-01-30 14:44:35 +05:30
commit e0a1039756
20 changed files with 500 additions and 403 deletions

View File

@ -32,6 +32,9 @@ class DocType(BuyingController):
}] }]
def validate(self): def validate(self):
if not self.doc.is_opening:
self.doc.is_opening = 'No'
super(DocType, self).validate() super(DocType, self).validate()
self.po_required() self.po_required()
@ -45,15 +48,8 @@ class DocType(BuyingController):
self.check_for_stopped_status() self.check_for_stopped_status()
self.validate_with_previous_doc() self.validate_with_previous_doc()
self.validate_uom_is_integer("uom", "qty") self.validate_uom_is_integer("uom", "qty")
if not self.doc.is_opening:
self.doc.is_opening = 'No'
self.set_aging_date() self.set_aging_date()
#set against account for credit to
self.set_against_expense_account() self.set_against_expense_account()
self.validate_write_off_account() self.validate_write_off_account()
self.update_raw_material_cost() self.update_raw_material_cost()
self.update_valuation_rate("entries") self.update_valuation_rate("entries")
@ -215,7 +211,8 @@ class DocType(BuyingController):
against_accounts = [] against_accounts = []
stock_items = self.get_stock_items() stock_items = self.get_stock_items()
for item in self.doclist.get({"parentfield": "entries"}): for item in self.doclist.get({"parentfield": "entries"}):
if auto_accounting_for_stock and item.item_code in stock_items: if auto_accounting_for_stock and item.item_code in stock_items \
and self.doc.is_opening == 'No':
# in case of auto inventory accounting, against expense account is always # in case of auto inventory accounting, against expense account is always
# Stock Received But Not Billed for a stock item # Stock Received But Not Billed for a stock item
item.expense_head = stock_not_billed_account item.expense_head = stock_not_billed_account

View File

@ -8,6 +8,7 @@
}, },
{ {
"allow_import": 1, "allow_import": 1,
"allow_rename": 1,
"autoname": "field:title", "autoname": "field:title",
"description": "Standard tax template that can be applied to all Purchase Transactions. This template can contain list of tax heads and also other expense heads like \"Shipping\", \"Insurance\", \"Handling\" etc.\n\n#### Note\n\nThe tax rate you define here will be the standard tax rate for all **Items**. If there are **Items** that have different rates, they must be added in the **Item Tax** table in the **Item** master.\n\n#### Description of Columns\n\n1. Calculation Type: \n - This can be on **Net Total** (that is the sum of basic amount).\n - **On Previous Row Total / Amount** (for cumulative taxes or charges). If you select this option, the tax will be applied as a percentage of the previous row (in the tax table) amount or total.\n - **Actual** (as mentioned).\n2. Account Head: The Account ledger under which this tax will be booked\n3. Cost Center: If the tax / charge is an income (like shipping) or expense it needs to be booked against a Cost Center.\n4. Description: Description of the tax (that will be printed in invoices / quotes).\n5. Rate: Tax rate.\n6. Amount: Tax amount.\n7. Total: Cumulative total to this point.\n8. Enter Row: If based on \"Previous Row Total\" you can select the row number which will be taken as a base for this calculation (default is the previous row).\n9. Consider Tax or Charge for: In this section you can specify if the tax / charge is only for valuation (not a part of total) or only for total (does not add value to the item) or for both.\n10. Add or Deduct: Whether you want to add or deduct the tax.", "description": "Standard tax template that can be applied to all Purchase Transactions. This template can contain list of tax heads and also other expense heads like \"Shipping\", \"Insurance\", \"Handling\" etc.\n\n#### Note\n\nThe tax rate you define here will be the standard tax rate for all **Items**. If there are **Items** that have different rates, they must be added in the **Item Tax** table in the **Item** master.\n\n#### Description of Columns\n\n1. Calculation Type: \n - This can be on **Net Total** (that is the sum of basic amount).\n - **On Previous Row Total / Amount** (for cumulative taxes or charges). If you select this option, the tax will be applied as a percentage of the previous row (in the tax table) amount or total.\n - **Actual** (as mentioned).\n2. Account Head: The Account ledger under which this tax will be booked\n3. Cost Center: If the tax / charge is an income (like shipping) or expense it needs to be booked against a Cost Center.\n4. Description: Description of the tax (that will be printed in invoices / quotes).\n5. Rate: Tax rate.\n6. Amount: Tax amount.\n7. Total: Cumulative total to this point.\n8. Enter Row: If based on \"Previous Row Total\" you can select the row number which will be taken as a base for this calculation (default is the previous row).\n9. Consider Tax or Charge for: In this section you can specify if the tax / charge is only for valuation (not a part of total) or only for total (does not add value to the item) or for both.\n10. Add or Deduct: Whether you want to add or deduct the tax.",
"doctype": "DocType", "doctype": "DocType",

View File

@ -2,12 +2,13 @@
{ {
"creation": "2013-01-10 16:34:09", "creation": "2013-01-10 16:34:09",
"docstatus": 0, "docstatus": 0,
"modified": "2014-01-20 17:49:25", "modified": "2014-01-28 12:28:27",
"modified_by": "Administrator", "modified_by": "Administrator",
"owner": "Administrator" "owner": "Administrator"
}, },
{ {
"allow_import": 1, "allow_import": 1,
"allow_rename": 1,
"autoname": "field:title", "autoname": "field:title",
"description": "Standard tax template that can be applied to all Sales Transactions. This template can contain list of tax heads and also other expense / income heads like \"Shipping\", \"Insurance\", \"Handling\" etc.\n\n#### Note\n\nThe tax rate you define here will be the standard tax rate for all **Items**. If there are **Items** that have different rates, they must be added in the **Item Tax** table in the **Item** master.\n\n#### Description of Columns\n\n1. Calculation Type: \n - This can be on **Net Total** (that is the sum of basic amount).\n - **On Previous Row Total / Amount** (for cumulative taxes or charges). If you select this option, the tax will be applied as a percentage of the previous row (in the tax table) amount or total.\n - **Actual** (as mentioned).\n2. Account Head: The Account ledger under which this tax will be booked\n3. Cost Center: If the tax / charge is an income (like shipping) or expense it needs to be booked against a Cost Center.\n4. Description: Description of the tax (that will be printed in invoices / quotes).\n5. Rate: Tax rate.\n6. Amount: Tax amount.\n7. Total: Cumulative total to this point.\n8. Enter Row: If based on \"Previous Row Total\" you can select the row number which will be taken as a base for this calculation (default is the previous row).\n9. Is this Tax included in Basic Rate?: If you check this, it means that this tax will not be shown below the item table, but will be included in the Basic Rate in your main item table. This is useful where you want give a flat price (inclusive of all taxes) price to customers.", "description": "Standard tax template that can be applied to all Sales Transactions. This template can contain list of tax heads and also other expense / income heads like \"Shipping\", \"Insurance\", \"Handling\" etc.\n\n#### Note\n\nThe tax rate you define here will be the standard tax rate for all **Items**. If there are **Items** that have different rates, they must be added in the **Item Tax** table in the **Item** master.\n\n#### Description of Columns\n\n1. Calculation Type: \n - This can be on **Net Total** (that is the sum of basic amount).\n - **On Previous Row Total / Amount** (for cumulative taxes or charges). If you select this option, the tax will be applied as a percentage of the previous row (in the tax table) amount or total.\n - **Actual** (as mentioned).\n2. Account Head: The Account ledger under which this tax will be booked\n3. Cost Center: If the tax / charge is an income (like shipping) or expense it needs to be booked against a Cost Center.\n4. Description: Description of the tax (that will be printed in invoices / quotes).\n5. Rate: Tax rate.\n6. Amount: Tax amount.\n7. Total: Cumulative total to this point.\n8. Enter Row: If based on \"Previous Row Total\" you can select the row number which will be taken as a base for this calculation (default is the previous row).\n9. Is this Tax included in Basic Rate?: If you check this, it means that this tax will not be shown below the item table, but will be included in the Basic Rate in your main item table. This is useful where you want give a flat price (inclusive of all taxes) price to customers.",
"doctype": "DocType", "doctype": "DocType",

View File

@ -132,7 +132,7 @@ class AccountsReceivableReport(object):
if not hasattr(self, "gl_entries"): if not hasattr(self, "gl_entries"):
conditions, values = self.prepare_conditions() conditions, values = self.prepare_conditions()
self.gl_entries = webnotes.conn.sql("""select * from `tabGL Entry` self.gl_entries = webnotes.conn.sql("""select * from `tabGL Entry`
where docstatus < 2 {} order by posting_date, account""".format(conditions), where docstatus < 2 {0} order by posting_date, account""".format(conditions),
values, as_dict=True) values, as_dict=True)
return self.gl_entries return self.gl_entries
@ -153,8 +153,8 @@ class AccountsReceivableReport(object):
if not account_map: if not account_map:
webnotes.throw(_("No Customer Accounts found.")) webnotes.throw(_("No Customer Accounts found."))
else: else:
accounts_list = ['"{}"'.format(ac) for ac in account_map] accounts_list = ['"{0}"'.format(ac) for ac in account_map]
conditions.append("account in ({})".format(", ".join(accounts_list))) conditions.append("account in ({0})".format(", ".join(accounts_list)))
return " and ".join(conditions), values return " and ".join(conditions), values

View File

@ -271,4 +271,6 @@ patch_list = [
"execute:webnotes.reload_doc('selling', 'doctype', 'quotation') # 2013-12-26", "execute:webnotes.reload_doc('selling', 'doctype', 'quotation') # 2013-12-26",
"execute:webnotes.reload_doc('stock', 'doctype', 'delivery_note') # 2013-12-26", "execute:webnotes.reload_doc('stock', 'doctype', 'delivery_note') # 2013-12-26",
"patches.1401.enable_all_price_list", "patches.1401.enable_all_price_list",
"patches.1401.fix_serial_no_status_and_warehouse",
"patches.1401.fix_planned_qty",
] ]

View File

@ -7,35 +7,35 @@ $.extend(erpnext.queries, {
profile: function() { profile: function() {
return { query: "webnotes.core.doctype.profile.profile.profile_query" }; return { query: "webnotes.core.doctype.profile.profile.profile_query" };
}, },
lead: function() { lead: function() {
return { query: "erpnext.controllers.queries.lead_query" }; return { query: "erpnext.controllers.queries.lead_query" };
}, },
customer: function() { customer: function() {
return { query: "erpnext.controllers.queries.customer_query" }; return { query: "erpnext.controllers.queries.customer_query" };
}, },
supplier: function() { supplier: function() {
return { query: "erpnext.controllers.queries.supplier_query" }; return { query: "erpnext.controllers.queries.supplier_query" };
}, },
account: function() { account: function() {
return { query: "erpnext.controllers.queries.account_query" }; return { query: "erpnext.controllers.queries.account_query" };
}, },
item: function() { item: function() {
return { query: "erpnext.controllers.queries.item_query" }; return { query: "erpnext.controllers.queries.item_query" };
}, },
bom: function() { bom: function() {
return { query: "erpnext.controllers.queries.bom" }; return { query: "erpnext.controllers.queries.bom" };
}, },
task: function() { task: function() {
return { query: "erpnext.projects.utils.query_task" }; return { query: "erpnext.projects.utils.query_task" };
}, },
customer_filter: function(doc) { customer_filter: function(doc) {
if(!doc.customer) { if(!doc.customer) {
wn.throw(wn._("Please specify a") + " " + wn.throw(wn._("Please specify a") + " " +
@ -44,7 +44,7 @@ $.extend(erpnext.queries, {
return { filters: { customer: doc.customer } }; return { filters: { customer: doc.customer } };
}, },
supplier_filter: function(doc) { supplier_filter: function(doc) {
if(!doc.supplier) { if(!doc.supplier) {
wn.throw(wn._("Please specify a") + " " + wn.throw(wn._("Please specify a") + " " +
@ -53,9 +53,17 @@ $.extend(erpnext.queries, {
return { filters: { supplier: doc.supplier } }; return { filters: { supplier: doc.supplier } };
}, },
lead_filter: function(doc) {
if(!doc.lead) {
wn.throw(wn._("Please specify a") + " " +
wn._(wn.meta.get_label(doc.doctype, "lead", doc.name)));
}
return { filters: { lead: doc.lead } };
},
not_a_group_filter: function() { not_a_group_filter: function() {
return { filters: { is_group: "No" } }; return { filters: { is_group: "No" } };
}, },
}); });

View File

@ -15,13 +15,13 @@ erpnext.selling.Opportunity = wn.ui.form.Controller.extend({
if(!this.frm.doc.enquiry_from) if(!this.frm.doc.enquiry_from)
hide_field(['customer', 'customer_address', 'contact_person', 'customer_name','lead', 'address_display', 'contact_display', 'contact_mobile', 'contact_email', 'territory', 'customer_group']); hide_field(['customer', 'customer_address', 'contact_person', 'customer_name','lead', 'address_display', 'contact_display', 'contact_mobile', 'contact_email', 'territory', 'customer_group']);
if(!this.frm.doc.status) if(!this.frm.doc.status)
set_multiple(cdt,cdn,{status:'Draft'}); set_multiple(cdt, cdn, { status:'Draft' });
if(!this.frm.doc.date) if(!this.frm.doc.date)
this.frm.doc.transaction_date = date.obj_to_str(new Date()); this.frm.doc.transaction_date = date.obj_to_str(new Date());
if(!this.frm.doc.company && wn.defaults.get_default("company")) if(!this.frm.doc.company && wn.defaults.get_default("company"))
set_multiple(cdt,cdn,{company:wn.defaults.get_default("company")}); set_multiple(cdt, cdn, { company:wn.defaults.get_default("company") });
if(!this.frm.doc.fiscal_year && sys_defaults.fiscal_year) if(!this.frm.doc.fiscal_year && sys_defaults.fiscal_year)
set_multiple(cdt,cdn,{fiscal_year:sys_defaults.fiscal_year}); set_multiple(cdt, cdn, { fiscal_year:sys_defaults.fiscal_year });
if(this.frm.doc.enquiry_from) { if(this.frm.doc.enquiry_from) {
if(this.frm.doc.enquiry_from == 'Customer') { if(this.frm.doc.enquiry_from == 'Customer') {
@ -99,15 +99,15 @@ erpnext.selling.Opportunity = wn.ui.form.Controller.extend({
$.extend(cur_frm.cscript, new erpnext.selling.Opportunity({frm: cur_frm})); $.extend(cur_frm.cscript, new erpnext.selling.Opportunity({frm: cur_frm}));
cur_frm.cscript.refresh = function(doc, cdt, cdn){ cur_frm.cscript.refresh = function(doc, cdt, cdn) {
erpnext.hide_naming_series(); erpnext.hide_naming_series();
cur_frm.clear_custom_buttons(); cur_frm.clear_custom_buttons();
if(doc.docstatus === 1 && doc.status!=="Lost") { if(doc.docstatus === 1 && doc.status!=="Lost") {
cur_frm.add_custom_button(wn._('Create Quotation'), cur_frm.cscript.create_quotation); cur_frm.add_custom_button(wn._('Create Quotation'), cur_frm.cscript.create_quotation);
if(doc.status!=="Quotation") { if(doc.status!=="Quotation")
cur_frm.add_custom_button(wn._('Opportunity Lost'), cur_frm.cscript['Declare Opportunity Lost']); cur_frm.add_custom_button(wn._('Opportunity Lost'), cur_frm.cscript['Declare Opportunity Lost']);
}
cur_frm.add_custom_button(wn._('Send SMS'), cur_frm.cscript.send_sms, "icon-mobile-phone"); cur_frm.add_custom_button(wn._('Send SMS'), cur_frm.cscript.send_sms, "icon-mobile-phone");
} }
@ -116,31 +116,29 @@ cur_frm.cscript.refresh = function(doc, cdt, cdn){
} }
cur_frm.cscript.onload_post_render = function(doc, cdt, cdn) { cur_frm.cscript.onload_post_render = function(doc, cdt, cdn) {
if(doc.enquiry_from == 'Lead' && doc.lead) { if(doc.enquiry_from == 'Lead' && doc.lead)
cur_frm.cscript.lead(doc,cdt,cdn); cur_frm.cscript.lead(doc, cdt, cdn);
}
} }
cur_frm.cscript.item_code = function(doc, cdt, cdn) { cur_frm.cscript.item_code = function(doc, cdt, cdn) {
var d = locals[cdt][cdn]; var d = locals[cdt][cdn];
if (d.item_code) { if (d.item_code)
return get_server_fields('get_item_details',d.item_code, 'enquiry_details',doc, cdt,cdn,1); return get_server_fields('get_item_details', d.item_code, 'enquiry_details', doc, cdt, cdn, 1);
}
} }
// hide - unhide fields on basis of enquiry_from lead or customer // hide - unhide fields on basis of enquiry_from lead or customer
cur_frm.cscript.enquiry_from = function(doc,cdt,cdn){ cur_frm.cscript.enquiry_from = function(doc, cdt, cdn) {
cur_frm.cscript.lead_cust_show(doc,cdt,cdn); cur_frm.cscript.lead_cust_show(doc, cdt, cdn);
} }
// hide - unhide fields based on lead or customer // hide - unhide fields based on lead or customer
cur_frm.cscript.lead_cust_show = function(doc,cdt,cdn){ cur_frm.cscript.lead_cust_show = function(doc, cdt, cdn) {
if(doc.enquiry_from == 'Lead'){ if(doc.enquiry_from == 'Lead') {
unhide_field(['lead']); unhide_field(['lead']);
hide_field(['customer','customer_address','contact_person','customer_name','address_display','contact_display','contact_mobile','contact_email','territory','customer_group']); hide_field(['customer','customer_address','contact_person','customer_name','address_display','contact_display','contact_mobile','contact_email','territory','customer_group']);
doc.lead = doc.customer = doc.customer_address = doc.contact_person = doc.address_display = doc.contact_display = doc.contact_mobile = doc.contact_email = doc.territory = doc.customer_group = ""; doc.lead = doc.customer = doc.customer_address = doc.contact_person = doc.address_display = doc.contact_display = doc.contact_mobile = doc.contact_email = doc.territory = doc.customer_group = "";
} }
else if(doc.enquiry_from == 'Customer'){ else if(doc.enquiry_from == 'Customer') {
unhide_field(['customer']); unhide_field(['customer']);
hide_field(['lead', 'address_display', 'contact_display', 'contact_mobile', hide_field(['lead', 'address_display', 'contact_display', 'contact_mobile',
'contact_email', 'territory', 'customer_group']); 'contact_email', 'territory', 'customer_group']);
@ -164,15 +162,13 @@ cur_frm.cscript.lead = function(doc, cdt, cdn) {
wn.model.map_current_doc({ wn.model.map_current_doc({
method: "erpnext.selling.doctype.lead.lead.make_opportunity", method: "erpnext.selling.doctype.lead.lead.make_opportunity",
source_name: cur_frm.doc.lead source_name: cur_frm.doc.lead
}) });
unhide_field(['customer_name', 'address_display','contact_mobile', 'customer_address', unhide_field(['customer_name', 'address_display','contact_mobile', 'customer_address',
'contact_email', 'territory']); 'contact_email', 'territory']);
} }
cur_frm.cscript['Declare Opportunity Lost'] = function() {
cur_frm.cscript['Declare Opportunity Lost'] = function(){
var dialog = new wn.ui.Dialog({ var dialog = new wn.ui.Dialog({
title: wn._("Set as Lost"), title: wn._("Set as Lost"),
fields: [ fields: [
@ -200,5 +196,4 @@ cur_frm.cscript['Declare Opportunity Lost'] = function(){
}) })
}); });
dialog.show(); dialog.show();
} }

View File

@ -15,12 +15,21 @@ cur_frm.cscript.sales_team_fname = "sales_team";
erpnext.selling.QuotationController = erpnext.selling.SellingController.extend({ erpnext.selling.QuotationController = erpnext.selling.SellingController.extend({
onload: function(doc, dt, dn) { onload: function(doc, dt, dn) {
var me = this;
this._super(doc, dt, dn); this._super(doc, dt, dn);
if(doc.customer && !doc.quotation_to) if(doc.customer && !doc.quotation_to)
doc.quotation_to = "Customer"; doc.quotation_to = "Customer";
else if(doc.lead && !doc.quotation_to) else if(doc.lead && !doc.quotation_to)
doc.quotation_to = "Lead"; doc.quotation_to = "Lead";
// to overwrite the customer_filter trigger from queries.js
if (doc.lead) {
$.each(["customer_address", "shipping_address_name"],
function(i, opts) {
me.frm.set_query(opts, erpnext.queries["lead_filter"]);
}
);
}
}, },
refresh: function(doc, dt, dn) { refresh: function(doc, dt, dn) {
this._super(doc, dt, dn); this._super(doc, dt, dn);
@ -68,6 +77,12 @@ erpnext.selling.QuotationController = erpnext.selling.SellingController.extend({
quotation_to: function() { quotation_to: function() {
this.frm.toggle_reqd("lead", this.frm.doc.quotation_to == "Lead"); this.frm.toggle_reqd("lead", this.frm.doc.quotation_to == "Lead");
this.frm.toggle_reqd("customer", this.frm.doc.quotation_to == "Customer"); this.frm.toggle_reqd("customer", this.frm.doc.quotation_to == "Customer");
if (this.frm.doc.quotation_to == "Lead") {
this.frm.set_value("customer", null);
this.frm.set_value("contact_person", null);
}
else if (this.frm.doc.quotation_to == "Customer")
this.frm.set_value("lead", null);
}, },
tc_name: function() { tc_name: function() {
@ -90,7 +105,8 @@ erpnext.selling.QuotationController = erpnext.selling.SellingController.extend({
cur_frm.script_manager.make(erpnext.selling.QuotationController); cur_frm.script_manager.make(erpnext.selling.QuotationController);
cur_frm.fields_dict.lead.get_query = function(doc,cdt,cdn) { cur_frm.fields_dict.lead.get_query = function(doc,cdt,cdn) {
return{ query: "erpnext.controllers.queries.lead_query" } } return{ query: "erpnext.controllers.queries.lead_query" }
}
cur_frm.cscript.lead = function(doc, cdt, cdn) { cur_frm.cscript.lead = function(doc, cdt, cdn) {
if(doc.lead) { if(doc.lead) {
@ -152,7 +168,6 @@ cur_frm.cscript['Declare Order Lost'] = function(){
} }
cur_frm.cscript.on_submit = function(doc, cdt, cdn) { cur_frm.cscript.on_submit = function(doc, cdt, cdn) {
if(cint(wn.boot.notification_settings.quotation)) { if(cint(wn.boot.notification_settings.quotation))
cur_frm.email_doc(wn.boot.notification_settings.quotation_message); cur_frm.email_doc(wn.boot.notification_settings.quotation_message);
}
} }

View File

@ -3,14 +3,11 @@
from __future__ import unicode_literals from __future__ import unicode_literals
import webnotes import webnotes
from webnotes.utils import cstr from webnotes.utils import cstr
from webnotes.model.bean import getlist from webnotes.model.bean import getlist
from webnotes.model.code import get_obj from webnotes.model.code import get_obj
from webnotes import _, msgprint from webnotes import _, msgprint
from erpnext.controllers.selling_controller import SellingController from erpnext.controllers.selling_controller import SellingController
class DocType(SellingController): class DocType(SellingController):

View File

@ -2,7 +2,7 @@
{ {
"creation": "2013-05-24 19:29:08", "creation": "2013-05-24 19:29:08",
"docstatus": 0, "docstatus": 0,
"modified": "2014-01-28 18:50:17", "modified": "2014-01-29 19:42:32",
"modified_by": "Administrator", "modified_by": "Administrator",
"owner": "Administrator" "owner": "Administrator"
}, },
@ -674,6 +674,7 @@
"read_only": 0 "read_only": 0
}, },
{ {
"depends_on": "eval:doc.customer",
"doctype": "DocField", "doctype": "DocField",
"fieldname": "contact_person", "fieldname": "contact_person",
"fieldtype": "Link", "fieldtype": "Link",

View File

@ -2,7 +2,7 @@
{ {
"creation": "2013-01-25 11:35:09", "creation": "2013-01-25 11:35:09",
"docstatus": 0, "docstatus": 0,
"modified": "2014-01-20 17:50:00", "modified": "2014-01-27 11:11:08",
"modified_by": "Administrator", "modified_by": "Administrator",
"owner": "Administrator" "owner": "Administrator"
}, },
@ -10,6 +10,9 @@
"allow_attach": 0, "allow_attach": 0,
"allow_copy": 0, "allow_copy": 0,
"allow_import": 1, "allow_import": 1,
"allow_email": 1,
"allow_print": 1,
"allow_rename": 1,
"autoname": "field:price_list_name", "autoname": "field:price_list_name",
"description": "Price List Master", "description": "Price List Master",
"doctype": "DocType", "doctype": "DocType",

View File

@ -87,6 +87,8 @@ class DocType(StockController):
self.doc.status = "Sales Returned" self.doc.status = "Sales Returned"
else: else:
self.doc.status = "Available" self.doc.status = "Available"
if not self.doc.warehouse:
self.doc.warehouse = last_sle.warehouse
else: else:
if document_type == "Purchase Return": if document_type == "Purchase Return":
self.doc.status = "Purchase Returned" self.doc.status = "Purchase Returned"
@ -94,6 +96,8 @@ class DocType(StockController):
self.doc.status = "Delivered" self.doc.status = "Delivered"
else: else:
self.doc.status = "Not Available" self.doc.status = "Not Available"
else:
self.doc.status = "Not Available"
def set_purchase_details(self, purchase_sle): def set_purchase_details(self, purchase_sle):
if purchase_sle: if purchase_sle:
@ -185,10 +189,9 @@ class DocType(StockController):
def on_stock_ledger_entry(self): def on_stock_ledger_entry(self):
if self.via_stock_ledger and not self.doc.fields.get("__islocal"): if self.via_stock_ledger and not self.doc.fields.get("__islocal"):
last_sle = self.get_last_sle() last_sle = self.get_last_sle()
if last_sle: self.set_status(last_sle.get("last_sle"))
self.set_status(last_sle.get("last_sle")) self.set_purchase_details(last_sle.get("purchase_sle"))
self.set_purchase_details(last_sle.get("purchase_sle")) self.set_sales_details(last_sle.get("delivery_sle"))
self.set_sales_details(last_sle.get("delivery_sle"))
def on_communication(self): def on_communication(self):
return return

View File

@ -344,7 +344,8 @@ class DocType(StockController):
pro_bean = webnotes.bean("Production Order", self.doc.production_order) pro_bean = webnotes.bean("Production Order", self.doc.production_order)
_validate_production_order(pro_bean) _validate_production_order(pro_bean)
self.update_produced_qty(pro_bean) self.update_produced_qty(pro_bean)
self.update_planned_qty(pro_bean) if self.doc.purpose == "Manufacture/Repack":
self.update_planned_qty(pro_bean)
def update_produced_qty(self, pro_bean): def update_produced_qty(self, pro_bean):
if self.doc.purpose == "Manufacture/Repack": if self.doc.purpose == "Manufacture/Repack":

File diff suppressed because it is too large Load Diff

View File

@ -1,11 +1,15 @@
# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors # Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors
# License: GNU General Public License v3. See license.txt # License: GNU General Public License v3. See license.txt
from __future__ import unicode_literals from __future__ import unicode_literals
import webnotes import webnotes
from webnotes import msgprint from webnotes import msgprint
from webnotes.utils import flt, getdate from webnotes.utils import flt, getdate, add_days
from webnotes.model.controller import DocListController from webnotes.model.controller import DocListController
from datetime import date
class StockFreezeError(webnotes.ValidationError): pass
class DocType(DocListController): class DocType(DocListController):
def __init__(self, doc, doclist=[]): def __init__(self, doc, doclist=[]):
@ -20,28 +24,29 @@ class DocType(DocListController):
self.scrub_posting_time() self.scrub_posting_time()
from erpnext.accounts.utils import validate_fiscal_year from erpnext.accounts.utils import validate_fiscal_year
validate_fiscal_year(self.doc.posting_date, self.doc.fiscal_year, self.meta.get_label("posting_date")) validate_fiscal_year(self.doc.posting_date, self.doc.fiscal_year,
self.meta.get_label("posting_date"))
def on_submit(self): def on_submit(self):
self.check_stock_frozen_date() self.check_stock_frozen_date()
self.actual_amt_check() self.actual_amt_check()
from erpnext.stock.doctype.serial_no.serial_no import process_serial_no from erpnext.stock.doctype.serial_no.serial_no import process_serial_no
process_serial_no(self.doc) process_serial_no(self.doc)
#check for item quantity available in stock #check for item quantity available in stock
def actual_amt_check(self): def actual_amt_check(self):
if self.doc.batch_no: if self.doc.batch_no:
batch_bal_after_transaction = flt(webnotes.conn.sql("""select sum(actual_qty) batch_bal_after_transaction = flt(webnotes.conn.sql("""select sum(actual_qty)
from `tabStock Ledger Entry` from `tabStock Ledger Entry`
where warehouse=%s and item_code=%s and batch_no=%s""", where warehouse=%s and item_code=%s and batch_no=%s""",
(self.doc.warehouse, self.doc.item_code, self.doc.batch_no))[0][0]) (self.doc.warehouse, self.doc.item_code, self.doc.batch_no))[0][0])
if batch_bal_after_transaction < 0: if batch_bal_after_transaction < 0:
self.doc.fields.update({ self.doc.fields.update({
'batch_bal': batch_bal_after_transaction - self.doc.actual_qty 'batch_bal': batch_bal_after_transaction - self.doc.actual_qty
}) })
webnotes.throw("""Not enough quantity (requested: %(actual_qty)s, \ webnotes.throw("""Not enough quantity (requested: %(actual_qty)s, \
current: %(batch_bal)s in Batch <b>%(batch_no)s</b> for Item \ current: %(batch_bal)s in Batch <b>%(batch_no)s</b> for Item \
<b>%(item_code)s</b> at Warehouse <b>%(warehouse)s</b> \ <b>%(item_code)s</b> at Warehouse <b>%(warehouse)s</b> \
@ -59,41 +64,49 @@ class DocType(DocListController):
msgprint("Warehouse: '%s' does not exist in the system. Please check." % self.doc.fields.get(k), raise_exception = 1) msgprint("Warehouse: '%s' does not exist in the system. Please check." % self.doc.fields.get(k), raise_exception = 1)
def validate_item(self): def validate_item(self):
item_det = webnotes.conn.sql("""select name, has_batch_no, docstatus, item_det = webnotes.conn.sql("""select name, has_batch_no, docstatus,
is_stock_item, has_serial_no, serial_no_series is_stock_item, has_serial_no, serial_no_series
from tabItem where name=%s""", from tabItem where name=%s""",
self.doc.item_code, as_dict=True)[0] self.doc.item_code, as_dict=True)[0]
if item_det.is_stock_item != 'Yes': if item_det.is_stock_item != 'Yes':
webnotes.throw("""Item: "%s" is not a Stock Item.""" % self.doc.item_code) webnotes.throw("""Item: "%s" is not a Stock Item.""" % self.doc.item_code)
# check if batch number is required # check if batch number is required
if item_det.has_batch_no =='Yes' and self.doc.voucher_type != 'Stock Reconciliation': if item_det.has_batch_no =='Yes' and self.doc.voucher_type != 'Stock Reconciliation':
if not self.doc.batch_no: if not self.doc.batch_no:
webnotes.throw("Batch number is mandatory for Item '%s'" % self.doc.item_code) webnotes.throw("Batch number is mandatory for Item '%s'" % self.doc.item_code)
# check if batch belongs to item # check if batch belongs to item
if not webnotes.conn.sql("""select name from `tabBatch` if not webnotes.conn.sql("""select name from `tabBatch`
where item='%s' and name ='%s' and docstatus != 2""" % (self.doc.item_code, self.doc.batch_no)): where item='%s' and name ='%s' and docstatus != 2""" % (self.doc.item_code, self.doc.batch_no)):
webnotes.throw("'%s' is not a valid Batch Number for Item '%s'" % (self.doc.batch_no, self.doc.item_code)) webnotes.throw("'%s' is not a valid Batch Number for Item '%s'" % (self.doc.batch_no, self.doc.item_code))
if not self.doc.stock_uom: if not self.doc.stock_uom:
self.doc.stock_uom = item_det.stock_uom self.doc.stock_uom = item_det.stock_uom
def check_stock_frozen_date(self): def check_stock_frozen_date(self):
stock_frozen_upto = webnotes.conn.get_value('Stock Settings', None, 'stock_frozen_upto') or '' stock_frozen_upto = webnotes.conn.get_value('Stock Settings', None, 'stock_frozen_upto') or ''
if stock_frozen_upto: if stock_frozen_upto:
stock_auth_role = webnotes.conn.get_value('Stock Settings', None,'stock_auth_role') stock_auth_role = webnotes.conn.get_value('Stock Settings', None,'stock_auth_role')
if getdate(self.doc.posting_date) <= getdate(stock_frozen_upto) and not stock_auth_role in webnotes.user.get_roles(): if getdate(self.doc.posting_date) <= getdate(stock_frozen_upto) and not stock_auth_role in webnotes.user.get_roles():
msgprint("You are not authorized to do / modify back dated stock entries before %s" % getdate(stock_frozen_upto).strftime('%d-%m-%Y'), raise_exception=1) msgprint("You are not authorized to do / modify back dated stock entries before %s" % getdate(stock_frozen_upto).strftime('%d-%m-%Y'), raise_exception=StockFreezeError)
stock_frozen_upto_days = int(webnotes.conn.get_value('Stock Settings', None, 'stock_frozen_upto_days') or 0)
if stock_frozen_upto_days:
stock_auth_role = webnotes.conn.get_value('Stock Settings', None,'stock_auth_role')
older_than_x_days_ago = (add_days(getdate(self.doc.posting_date), stock_frozen_upto_days) <= date.today())
if older_than_x_days_ago and not stock_auth_role in webnotes.user.get_roles():
msgprint("You are not authorized to do / modify back dated stock entries older than %d days ago" %stock_frozen_upto_days, raise_exception=StockFreezeError)
def scrub_posting_time(self): def scrub_posting_time(self):
if not self.doc.posting_time or self.doc.posting_time == '00:0': if not self.doc.posting_time or self.doc.posting_time == '00:0':
self.doc.posting_time = '00:00' self.doc.posting_time = '00:00'
def on_doctype_update(): def on_doctype_update():
if not webnotes.conn.sql("""show index from `tabStock Ledger Entry` if not webnotes.conn.sql("""show index from `tabStock Ledger Entry`
where Key_name="posting_sort_index" """): where Key_name="posting_sort_index" """):
webnotes.conn.commit() webnotes.conn.commit()
webnotes.conn.sql("""alter table `tabStock Ledger Entry` webnotes.conn.sql("""alter table `tabStock Ledger Entry`
add index posting_sort_index(posting_date, posting_time, name)""") add index posting_sort_index(posting_date, posting_time, name)""")

View File

@ -5,18 +5,23 @@
from __future__ import unicode_literals from __future__ import unicode_literals
import webnotes import webnotes
from webnotes import _
class DocType: class DocType:
def __init__(self, d, dl): def __init__(self, d, dl):
self.doc, self.doclist = d, dl self.doc, self.doclist = d, dl
def validate(self): def validate(self):
for key in ["item_naming_by", "item_group", "stock_uom", for key in ["item_naming_by", "item_group", "stock_uom",
"allow_negative_stock"]: "allow_negative_stock"]:
webnotes.conn.set_default(key, self.doc.fields.get(key, "")) webnotes.conn.set_default(key, self.doc.fields.get(key, ""))
from erpnext.setup.doctype.naming_series.naming_series import set_by_naming_series from erpnext.setup.doctype.naming_series.naming_series import set_by_naming_series
set_by_naming_series("Item", "item_code", set_by_naming_series("Item", "item_code",
self.doc.get("item_naming_by")=="Naming Series", hide_name_field=True) self.doc.get("item_naming_by")=="Naming Series", hide_name_field=True)
stock_frozen_limit = 356
submitted_stock_frozen = self.doc.stock_frozen_upto_days
if submitted_stock_frozen > stock_frozen_limit:
self.doc.stock_frozen_upto_days = stock_frozen_limit
webnotes.msgprint (_("`Freeze Stocks Older Than` should be smaller than %d days.") %stock_frozen_limit)

View File

@ -1,25 +1,25 @@
[ [
{ {
"creation": "2013-06-24 16:37:54", "creation": "2013-06-24 16:37:54",
"docstatus": 0, "docstatus": 0,
"modified": "2013-12-20 19:21:48", "modified": "2014-01-27 20:00:56",
"modified_by": "Administrator", "modified_by": "Administrator",
"owner": "Administrator" "owner": "Administrator"
}, },
{ {
"description": "Settings", "description": "Settings",
"doctype": "DocType", "doctype": "DocType",
"icon": "icon-cog", "icon": "icon-cog",
"issingle": 1, "issingle": 1,
"module": "Stock", "module": "Stock",
"name": "__common__" "name": "__common__"
}, },
{ {
"doctype": "DocField", "doctype": "DocField",
"name": "__common__", "name": "__common__",
"parent": "Stock Settings", "parent": "Stock Settings",
"parentfield": "fields", "parentfield": "fields",
"parenttype": "DocType", "parenttype": "DocType",
"permlevel": 0 "permlevel": 0
}, },
{ {
@ -35,96 +35,102 @@
"read": 1, "read": 1,
"role": "Material Manager", "role": "Material Manager",
"write": 1 "write": 1
}, },
{ {
"doctype": "DocType", "doctype": "DocType",
"name": "Stock Settings" "name": "Stock Settings"
}, },
{ {
"doctype": "DocField", "doctype": "DocField",
"fieldname": "item_naming_by", "fieldname": "item_naming_by",
"fieldtype": "Select", "fieldtype": "Select",
"label": "Item Naming By", "label": "Item Naming By",
"options": "Item Code\nNaming Series" "options": "Item Code\nNaming Series"
}, },
{ {
"description": "<a href=\"#Sales Browser/Item Group\">Add / Edit</a>", "description": "<a href=\"#Sales Browser/Item Group\">Add / Edit</a>",
"doctype": "DocField", "doctype": "DocField",
"fieldname": "item_group", "fieldname": "item_group",
"fieldtype": "Link", "fieldtype": "Link",
"label": "Default Item Group", "label": "Default Item Group",
"options": "Item Group" "options": "Item Group"
}, },
{ {
"doctype": "DocField", "doctype": "DocField",
"fieldname": "stock_uom", "fieldname": "stock_uom",
"fieldtype": "Link", "fieldtype": "Link",
"label": "Default Stock UOM", "label": "Default Stock UOM",
"options": "UOM" "options": "UOM"
}, },
{ {
"doctype": "DocField", "doctype": "DocField",
"fieldname": "column_break_4", "fieldname": "column_break_4",
"fieldtype": "Column Break" "fieldtype": "Column Break"
}, },
{ {
"doctype": "DocField", "doctype": "DocField",
"fieldname": "allow_negative_stock", "fieldname": "allow_negative_stock",
"fieldtype": "Check", "fieldtype": "Check",
"label": "Allow Negative Stock" "label": "Allow Negative Stock"
}, },
{ {
"doctype": "DocField", "doctype": "DocField",
"fieldname": "valuation_method", "fieldname": "valuation_method",
"fieldtype": "Select", "fieldtype": "Select",
"label": "Default Valuation Method", "label": "Default Valuation Method",
"options": "FIFO\nMoving Average" "options": "FIFO\nMoving Average"
}, },
{ {
"description": "Percentage you are allowed to receive or deliver more against the quantity ordered. For example: If you have ordered 100 units. and your Allowance is 10% then you are allowed to receive 110 units.", "description": "Percentage you are allowed to receive or deliver more against the quantity ordered. For example: If you have ordered 100 units. and your Allowance is 10% then you are allowed to receive 110 units.",
"doctype": "DocField", "doctype": "DocField",
"fieldname": "tolerance", "fieldname": "tolerance",
"fieldtype": "Float", "fieldtype": "Float",
"label": "Allowance Percent" "label": "Allowance Percent"
}, },
{ {
"doctype": "DocField", "doctype": "DocField",
"fieldname": "auto_material_request", "fieldname": "auto_material_request",
"fieldtype": "Section Break", "fieldtype": "Section Break",
"label": "Auto Material Request" "label": "Auto Material Request"
}, },
{ {
"doctype": "DocField", "doctype": "DocField",
"fieldname": "auto_indent", "fieldname": "auto_indent",
"fieldtype": "Check", "fieldtype": "Check",
"label": "Raise Material Request when stock reaches re-order level" "label": "Raise Material Request when stock reaches re-order level"
}, },
{ {
"doctype": "DocField", "doctype": "DocField",
"fieldname": "reorder_email_notify", "fieldname": "reorder_email_notify",
"fieldtype": "Check", "fieldtype": "Check",
"label": "Notify by Email on creation of automatic Material Request" "label": "Notify by Email on creation of automatic Material Request"
}, },
{ {
"doctype": "DocField", "doctype": "DocField",
"fieldname": "freeze_stock_entries", "fieldname": "freeze_stock_entries",
"fieldtype": "Section Break", "fieldtype": "Section Break",
"label": "Freeze Stock Entries" "label": "Freeze Stock Entries"
}, },
{ {
"doctype": "DocField", "doctype": "DocField",
"fieldname": "stock_frozen_upto", "fieldname": "stock_frozen_upto",
"fieldtype": "Date", "fieldtype": "Date",
"label": "Stock Frozen Upto" "label": "Stock Frozen Upto"
}, },
{ {
"doctype": "DocField", "doctype": "DocField",
"fieldname": "stock_auth_role", "fieldname": "stock_frozen_upto_days",
"fieldtype": "Link", "fieldtype": "Int",
"label": "Role Allowed to edit frozen stock", "label": "Freeze Stocks Older Than [Days]"
},
{
"doctype": "DocField",
"fieldname": "stock_auth_role",
"fieldtype": "Link",
"label": "Role Allowed to edit frozen stock",
"options": "Role" "options": "Role"
}, },
{ {
"doctype": "DocPerm" "doctype": "DocPerm"
} }
] ]

View File

@ -4,7 +4,7 @@
from __future__ import unicode_literals from __future__ import unicode_literals
import webnotes import webnotes
from webnotes import msgprint from webnotes import msgprint, throw, _
from webnotes.utils import cstr, cint from webnotes.utils import cstr, cint
class DocType: class DocType:
@ -16,11 +16,11 @@ class DocType:
if not self.doc.address_title: if not self.doc.address_title:
self.doc.address_title = self.doc.customer \ self.doc.address_title = self.doc.customer \
or self.doc.supplier or self.doc.sales_partner or self.doc.lead or self.doc.supplier or self.doc.sales_partner or self.doc.lead
if self.doc.address_title: if self.doc.address_title:
self.doc.name = cstr(self.doc.address_title).strip() + "-" + cstr(self.doc.address_type).strip() self.doc.name = cstr(self.doc.address_title).strip() + "-" + cstr(self.doc.address_type).strip()
else: else:
webnotes.msgprint("""Address Title is mandatory.""" + self.doc.customer, raise_exception=True) throw(_("Address Title is mandatory."))
def validate(self): def validate(self):
self.validate_primary_address() self.validate_primary_address()

View File

@ -0,0 +1,13 @@
# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors
# License: GNU General Public License v3. See license.txt
import webnotes
def execute():
webnotes.conn.auto_commit_on_many_writes = 1
from utilities.repost_stock import repost_stock
for d in webnotes.conn.sql("""select distinct production_item, fg_warehouse
from `tabProduction Order` where docstatus>0""", as_dict=1):
repost_stock(d.production_item, d.fg_warehouse)
webnotes.conn.auto_commit_on_many_writes = 0

View File

@ -0,0 +1,17 @@
# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors
# License: GNU General Public License v3. See license.txt
from __future__ import unicode_literals
import webnotes
def execute():
serial_nos = webnotes.conn.sql("""select name from `tabSerial No` where docstatus=0
and status in ('Available', 'Sales Returned') and ifnull(warehouse, '') = ''""")
for sr in serial_nos:
try:
sr_bean = webnotes.bean("Serial No", sr[0])
sr_bean.make_controller().via_stock_ledger = True
sr_bean.save()
webnotes.conn.commit()
except:
pass