Merge branch 'master' of github.com:webnotes/erpnext

This commit is contained in:
Anand Doshi 2013-08-12 17:33:23 +05:30
commit 3eb8c38efb
18 changed files with 290 additions and 137 deletions

View File

@ -47,18 +47,20 @@ def get_columns(filters):
msgprint(_("Please specify") + ": " + label,
raise_exception=True)
columns = ["Cost Center:Link/Cost Center:100", "Account:Link/Account:100"]
columns = ["Cost Center:Link/Cost Center:120", "Account:Link/Account:120"]
group_months = False if filters["period"] == "Monthly" else True
for from_date, to_date in get_period_date_ranges(filters["period"], filters["fiscal_year"]):
for label in ["Target (%s)", "Actual (%s)", "Variance (%s)"]:
if group_months:
columns.append(label % (from_date.strftime("%b") + " - " + to_date.strftime("%b")))
label = label % (from_date.strftime("%b") + " - " + to_date.strftime("%b"))
else:
columns.append(label % from_date.strftime("%b"))
label = label % from_date.strftime("%b")
columns.append(label+":Float:120")
return columns + ["Total Target::80", "Total Actual::80", "Total Variance::80"]
return columns + ["Total Target::120", "Total Actual::120", "Total Variance::120"]
#Get cost center & target details
def get_costcenter_target_details(filters):
@ -66,19 +68,17 @@ def get_costcenter_target_details(filters):
cc.parent_cost_center, bd.account, bd.budget_allocated
from `tabCost Center` cc, `tabBudget Detail` bd
where bd.parent=cc.name and bd.fiscal_year=%s and
cc.company=%s and ifnull(cc.distribution_id, '')!=''
order by cc.name""" % ('%s', '%s'),
cc.company=%s order by cc.name""" % ('%s', '%s'),
(filters.get("fiscal_year"), filters.get("company")), as_dict=1)
#Get target distribution details of accounts of cost center
def get_target_distribution_details(filters):
target_details = {}
for d in webnotes.conn.sql("""select bdd.month, bdd.percentage_allocation \
from `tabBudget Distribution Detail` bdd, `tabBudget Distribution` bd, \
`tabCost Center` cc where bdd.parent=bd.name and cc.distribution_id=bd.name and \
bd.fiscal_year=%s""", (filters["fiscal_year"]), as_dict=1):
target_details.setdefault(d.month, d)
for d in webnotes.conn.sql("""select bd.name, bdd.month, bdd.percentage_allocation \
from `tabBudget Distribution Detail` bdd, `tabBudget Distribution` bd
where bdd.parent=bd.name and bd.fiscal_year=%s""", (filters["fiscal_year"]), as_dict=1):
target_details.setdefault(d.name, {}).setdefault(d.month, d.percentage_allocation)
return target_details
@ -99,15 +99,19 @@ def get_costcenter_account_month_map(filters):
cam_map = {}
for ccd in costcenter_target_details:
for month in tdd:
for month_id in range(1, 13):
month = datetime.date(2013, month_id, 1).strftime('%B')
cam_map.setdefault(ccd.name, {}).setdefault(ccd.account, {})\
.setdefault(month, webnotes._dict({
"target": 0.0, "actual": 0.0
}))
.setdefault(month, webnotes._dict({
"target": 0.0, "actual": 0.0
}))
tav_dict = cam_map[ccd.name][ccd.account][month]
tav_dict.target = flt(ccd.budget_allocated) * \
(tdd[month]["percentage_allocation"]/100)
month_percentage = ccd.distribution_id and \
tdd.get(ccd.distribution_id, {}).get(month, 0) or 100.0/12
tav_dict.target = flt(flt(ccd.budget_allocated) * month_percentage /100)
for ad in actual_details:
if ad.month_name == month and ad.account == ccd.account \

View File

@ -115,7 +115,8 @@ class DocType(DocListController):
self.doc.leave_balance = get_leave_balance(self.doc.employee,
self.doc.leave_type, self.doc.fiscal_year)["leave_balance"]
if self.doc.leave_balance - self.doc.total_leave_days < 0:
if self.doc.status != "Rejected" \
and self.doc.leave_balance - self.doc.total_leave_days < 0:
#check if this leave type allow the remaining balance to be in negative. If yes then warn the user and continue to save else warn the user and don't save.
msgprint("There is not enough leave balance for Leave Type: %s" % \
(self.doc.leave_type,),

View File

@ -61,30 +61,25 @@ cur_frm.cscript['Unstop Production Order'] = function() {
}
cur_frm.cscript['Transfer Raw Materials'] = function() {
var doc = cur_frm.doc;
cur_frm.cscript.make_se(doc, 'Material Transfer');
cur_frm.cscript.make_se('Material Transfer');
}
cur_frm.cscript['Update Finished Goods'] = function() {
var doc = cur_frm.doc;
cur_frm.cscript.make_se(doc, 'Manufacture/Repack');
cur_frm.cscript.make_se('Manufacture/Repack');
}
cur_frm.cscript.make_se = function(doc, purpose) {
var se = wn.model.get_new_doc("Stock Entry");
se.purpose = purpose;
se.production_order = doc.name;
if(purpose==="Material Transfer") {
se.to_warehouse = doc.wip_warehouse;
} else {
se.from_warehouse = doc.wip_warehouse;
se.to_warehouse = doc.fg_warehouse;
}
se.company = doc.company;
se.fg_completed_qty = doc.qty - doc.produced_qty;
se.bom_no = doc.bom_no;
se.use_multi_level_bom = doc.use_multi_level_bom;
loaddoc('Stock Entry', se.name);
cur_frm.cscript.make_se = function(purpose) {
wn.call({
method:"manufacturing.doctype.production_order.production_order.make_stock_entry",
args: {
"production_order_id": cur_frm.doc.name,
"purpose": purpose
},
callback: function(r) {
var doclist = wn.model.sync(r.message);
wn.set_route("Form", doclist[0].doctype, doclist[0].name);
}
})
}
cur_frm.fields_dict['production_item'].get_query = function(doc) {

View File

@ -137,4 +137,23 @@ def get_item_details(item):
if bom:
res.bom_no = bom[0][0]
return res
return res
@webnotes.whitelist()
def make_stock_entry(production_order_id, purpose):
production_order = webnotes.bean("Production Order", production_order_id)
stock_entry = webnotes.new_bean("Stock Entry")
stock_entry.doc.purpose = purpose
stock_entry.doc.production_order = production_order_id
stock_entry.doc.company = production_order.doc.company
stock_entry.doc.bom_no = production_order.doc.bom_no
stock_entry.doc.fg_completed_qty = flt(production_order.doc.qty) - flt(production_order.doc.produced_qty)
if purpose=="Material Transfer":
stock_entry.doc.to_warehouse = production_order.doc.wip_warehouse
else:
stock_entry.doc.from_warehouse = production_order.doc.wip_warehouse
stock_entry.doc.to_warehouse = production_order.doc.fg_warehouse
return [d.fields for d in stock_entry.doclist]

View File

@ -64,11 +64,26 @@ wn.module_page["Manufacturing"] = [
right: true,
icon: "icon-list",
items: [
{
"label":wn._("Open Production Orders"),
route: "query-report/Open Production Orders",
doctype:"Production Order"
},
{
"label":wn._("Production Orders in Progress"),
route: "query-report/Production Orders in Progress",
doctype:"Production Order"
},
{
"label":wn._("Issued Items Against Production Order"),
route: "query-report/Issued Items Against Production Order",
doctype:"Production Order"
},
{
"label":wn._("Completed Production Orders"),
route: "query-report/Completed Production Orders",
doctype:"Production Order"
},
]
}
]

View File

@ -0,0 +1,22 @@
[
{
"creation": "2013-08-12 12:44:27",
"docstatus": 0,
"modified": "2013-08-12 12:44:27",
"modified_by": "Administrator",
"owner": "Administrator"
},
{
"doctype": "Report",
"is_standard": "Yes",
"name": "__common__",
"query": "SELECT\n `tabProduction Order`.name as \"Production Order:Link/Production Order:200\",\n `tabProduction Order`.creation as \"Date:Date:120\",\n `tabProduction Order`.production_item as \"Item:Link/Item:150\",\n `tabProduction Order`.qty as \"To Produce:Int:100\",\n `tabProduction Order`.produced_qty as \"Produced:Int:100\"\nFROM\n `tabProduction Order`\nWHERE\n `tabProduction Order`.docstatus=1\n AND ifnull(`tabProduction Order`.produced_qty,0) = `tabProduction Order`.qty",
"ref_doctype": "Production Order",
"report_name": "Completed Production Orders",
"report_type": "Query Report"
},
{
"doctype": "Report",
"name": "Completed Production Orders"
}
]

View File

@ -0,0 +1,22 @@
[
{
"creation": "2013-08-12 12:32:30",
"docstatus": 0,
"modified": "2013-08-12 12:42:29",
"modified_by": "Administrator",
"owner": "Administrator"
},
{
"doctype": "Report",
"is_standard": "Yes",
"name": "__common__",
"query": "SELECT\n `tabProduction Order`.name as \"Production Order:Link/Production Order:200\",\n `tabProduction Order`.creation as \"Date:Date:120\",\n `tabProduction Order`.production_item as \"Item:Link/Item:150\",\n `tabProduction Order`.qty as \"To Produce:Int:100\",\n `tabProduction Order`.produced_qty as \"Produced:Int:100\"\nFROM\n `tabProduction Order`\nWHERE\n `tabProduction Order`.docstatus=1\n AND ifnull(`tabProduction Order`.produced_qty,0) < `tabProduction Order`.qty\n AND NOT EXISTS (SELECT name from `tabStock Entry` where production_order =`tabProduction Order`.name) ",
"ref_doctype": "Production Order",
"report_name": "Open Production Orders",
"report_type": "Query Report"
},
{
"doctype": "Report",
"name": "Open Production Orders"
}
]

View File

@ -0,0 +1,22 @@
[
{
"creation": "2013-08-12 12:43:47",
"docstatus": 0,
"modified": "2013-08-12 12:43:47",
"modified_by": "Administrator",
"owner": "Administrator"
},
{
"doctype": "Report",
"is_standard": "Yes",
"name": "__common__",
"query": "SELECT\n `tabProduction Order`.name as \"Production Order:Link/Production Order:200\",\n `tabProduction Order`.creation as \"Date:Date:120\",\n `tabProduction Order`.production_item as \"Item:Link/Item:150\",\n `tabProduction Order`.qty as \"To Produce:Int:100\",\n `tabProduction Order`.produced_qty as \"Produced:Int:100\"\nFROM\n `tabProduction Order`\nWHERE\n `tabProduction Order`.docstatus=1\n AND ifnull(`tabProduction Order`.produced_qty,0) < `tabProduction Order`.qty\n AND EXISTS (SELECT name from `tabStock Entry` where production_order =`tabProduction Order`.name) ",
"ref_doctype": "Production Order",
"report_name": "Production Orders in Progress",
"report_type": "Query Report"
},
{
"doctype": "Report",
"name": "Production Orders in Progress"
}
]

View File

@ -8,6 +8,7 @@ from webnotes.utils import flt
import time
from accounts.utils import get_fiscal_year
from controllers.trends import get_period_date_ranges, get_period_month_ranges
from webnotes.model.meta import get_field_precision
def execute(filters=None):
if not filters: filters = {}
@ -16,10 +17,7 @@ def execute(filters=None):
period_month_ranges = get_period_month_ranges(filters["period"], filters["fiscal_year"])
sim_map = get_salesperson_item_month_map(filters)
precision = webnotes.conn.get_value("Global Defaults", None, "float_precision") or 2
data = []
for salesperson, salesperson_items in sim_map.items():
for item_group, monthwise_data in salesperson_items.items():
row = [salesperson, item_group]
@ -29,7 +27,7 @@ def execute(filters=None):
for month in relevant_months:
month_data = monthwise_data.get(month, {})
for i, fieldname in enumerate(["target", "achieved", "variance"]):
value = flt(month_data.get(fieldname), precision)
value = flt(month_data.get(fieldname))
period_data[i] += value
totals[i] += value
period_data[2] = period_data[0] - period_data[1]
@ -47,37 +45,37 @@ def get_columns(filters):
msgprint(_("Please specify") + ": " + label,
raise_exception=True)
columns = ["Sales Person:Link/Sales Person:80", "Item Group:Link/Item Group:80"]
columns = ["Sales Person:Link/Sales Person:120", "Item Group:Link/Item Group:120"]
group_months = False if filters["period"] == "Monthly" else True
for from_date, to_date in get_period_date_ranges(filters["period"], filters["fiscal_year"]):
for label in ["Target (%s)", "Achieved (%s)", "Variance (%s)"]:
if group_months:
columns.append(label % (from_date.strftime("%b") + " - " + to_date.strftime("%b")))
label = label % (from_date.strftime("%b") + " - " + to_date.strftime("%b"))
else:
columns.append(label % from_date.strftime("%b"))
label = label % from_date.strftime("%b")
columns.append(label+":Float:120")
return columns + ["Total Target::80", "Total Achieved::80", "Total Variance::80"]
return columns + ["Total Target::120", "Total Achieved::120", "Total Variance::120"]
#Get sales person & item group details
def get_salesperson_details(filters):
return webnotes.conn.sql("""select sp.name, td.item_group, td.target_qty,
td.target_amount, sp.distribution_id
from `tabSales Person` sp, `tabTarget Detail` td
where td.parent=sp.name and td.fiscal_year=%s and
ifnull(sp.distribution_id, '')!='' order by sp.name""",
where td.parent=sp.name and td.fiscal_year=%s order by sp.name""",
(filters["fiscal_year"]), as_dict=1)
#Get target distribution details of item group
def get_target_distribution_details(filters):
target_details = {}
for d in webnotes.conn.sql("""select bdd.month, bdd.percentage_allocation \
from `tabBudget Distribution Detail` bdd, `tabBudget Distribution` bd, \
`tabTerritory` t where bdd.parent=bd.name and t.distribution_id=bd.name and \
bd.fiscal_year=%s""", (filters["fiscal_year"]), as_dict=1):
target_details.setdefault(d.month, d)
for d in webnotes.conn.sql("""select bd.name, bdd.month, bdd.percentage_allocation
from `tabBudget Distribution Detail` bdd, `tabBudget Distribution` bd
where bdd.parent=bd.name and bd.fiscal_year=%s""", (filters["fiscal_year"]), as_dict=1):
target_details.setdefault(d.name, {}).setdefault(d.month, d.percentage_allocation)
return target_details
@ -94,32 +92,33 @@ def get_achieved_details(filters):
(start_date, end_date), as_dict=1)
def get_salesperson_item_month_map(filters):
import datetime
salesperson_details = get_salesperson_details(filters)
tdd = get_target_distribution_details(filters)
achieved_details = get_achieved_details(filters)
sim_map = {}
for sd in salesperson_details:
for month in tdd:
for month_id in range(1, 13):
month = datetime.date(2013, month_id, 1).strftime('%B')
sim_map.setdefault(sd.name, {}).setdefault(sd.item_group, {})\
.setdefault(month, webnotes._dict({
"target": 0.0, "achieved": 0.0
}))
.setdefault(month, webnotes._dict({
"target": 0.0, "achieved": 0.0
}))
tav_dict = sim_map[sd.name][sd.item_group][month]
month_percentage = sd.distribution_id and \
tdd.get(sd.distribution_id, {}).get(month, 0) or 100.0/12
for ad in achieved_details:
if (filters["target_on"] == "Quantity"):
tav_dict.target = flt(sd.target_qty) * \
(tdd[month]["percentage_allocation"]/100)
tav_dict.target = flt(flt(sd.target_qty) * month_percentage/100, 2)
if ad.month_name == month and get_item_group(ad.item_code) == sd.item_group \
and ad.sales_person == sd.name:
tav_dict.achieved += ad.qty
if (filters["target_on"] == "Amount"):
tav_dict.target = flt(sd.target_amount) * \
(tdd[month]["percentage_allocation"]/100)
tav_dict.target = flt(flt(sd.target_amount) * month_percentage/100, 2)
if ad.month_name == month and get_item_group(ad.item_code) == sd.item_group \
and ad.sales_person == sd.name:
tav_dict.achieved += ad.amount

View File

@ -46,37 +46,36 @@ def get_columns(filters):
label = (" ".join(fieldname.split("_"))).title()
msgprint(_("Please specify") + ": " + label, raise_exception=True)
columns = ["Territory:Link/Territory:80", "Item Group:Link/Item Group:80"]
columns = ["Territory:Link/Territory:120", "Item Group:Link/Item Group:120"]
group_months = False if filters["period"] == "Monthly" else True
for from_date, to_date in get_period_date_ranges(filters["period"], filters["fiscal_year"]):
for label in ["Target (%s)", "Achieved (%s)", "Variance (%s)"]:
if group_months:
columns.append(label % (from_date.strftime("%b") + " - " + to_date.strftime("%b")))
label = label % (from_date.strftime("%b") + " - " + to_date.strftime("%b"))
else:
columns.append(label % from_date.strftime("%b"))
label = label % from_date.strftime("%b")
columns.append(label+":Float:120")
return columns + ["Total Target::80", "Total Achieved::80", "Total Variance::80"]
return columns + ["Total Target::120", "Total Achieved::120", "Total Variance::120"]
#Get territory & item group details
def get_territory_details(filters):
return webnotes.conn.sql("""select t.name, td.item_group, td.target_qty,
td.target_amount, t.distribution_id
from `tabTerritory` t, `tabTarget Detail` td
where td.parent=t.name and td.fiscal_year=%s and
ifnull(t.distribution_id, '')!='' order by t.name""",
where td.parent=t.name and td.fiscal_year=%s order by t.name""",
(filters["fiscal_year"]), as_dict=1)
#Get target distribution details of item group
def get_target_distribution_details(filters):
target_details = {}
for d in webnotes.conn.sql("""select bdd.month, bdd.percentage_allocation \
from `tabBudget Distribution Detail` bdd, `tabBudget Distribution` bd, \
`tabTerritory` t where bdd.parent=bd.name and t.distribution_id=bd.name and \
bd.fiscal_year=%s""", (filters["fiscal_year"]), as_dict=1):
target_details.setdefault(d.month, d)
for d in webnotes.conn.sql("""select bd.name, bdd.month, bdd.percentage_allocation
from `tabBudget Distribution Detail` bdd, `tabBudget Distribution` bd
where bdd.parent=bd.name and bd.fiscal_year=%s""", (filters["fiscal_year"]), as_dict=1):
target_details.setdefault(d.name, {}).setdefault(d.month, d.percentage_allocation)
return target_details
@ -99,25 +98,27 @@ def get_territory_item_month_map(filters):
tim_map = {}
for td in territory_details:
for month in tdd:
for month_id in range(1, 13):
month = datetime.date(2013, month_id, 1).strftime('%B')
tim_map.setdefault(td.name, {}).setdefault(td.item_group, {})\
.setdefault(month, webnotes._dict({
"target": 0.0, "achieved": 0.0
}))
.setdefault(month, webnotes._dict({
"target": 0.0, "achieved": 0.0
}))
tav_dict = tim_map[td.name][td.item_group][month]
month_percentage = td.distribution_id and \
tdd.get(td.distribution_id, {}).get(month, 0) or 100.0/12
for ad in achieved_details:
if (filters["target_on"] == "Quantity"):
tav_dict.target = flt(td.target_qty) * \
(tdd[month]["percentage_allocation"]/100)
tav_dict.target = flt(flt(td.target_qty) * month_percentage /100)
if ad.month_name == month and get_item_group(ad.item_code) == td.item_group \
and ad.territory == td.name:
tav_dict.achieved += ad.qty
if (filters["target_on"] == "Amount"):
tav_dict.target = flt(td.target_amount) * \
(tdd[month]["percentage_allocation"]/100)
tav_dict.target = flt(flt(td.target_amount) * month_percentage / 100)
if ad.month_name == month and get_item_group(ad.item_code) == td.item_group \
and ad.territory == td.name:
tav_dict.achieved += ad.amount

View File

@ -4,34 +4,7 @@
wn.require("public/app/js/controllers/stock_controller.js");
wn.provide("erpnext.stock");
erpnext.stock.StockEntry = erpnext.stock.StockController.extend({
onload: function() {
this.set_default_account();
},
set_default_account: function() {
var me = this;
if (cint(wn.defaults.get_default("auto_inventory_accounting")) && !this.frm.doc.expense_adjustment_account) {
if (this.frm.doc.purpose == "Sales Return")
account_for = "stock_in_hand_account";
else if (this.frm.doc.purpose == "Purchase Return")
account_for = "stock_received_but_not_billed";
else account_for = "stock_adjustment_account";
return this.frm.call({
method: "accounts.utils.get_company_default",
args: {
"fieldname": account_for,
"company": this.frm.doc.company
},
callback: function(r) {
if (!r.exc) me.frm.set_value("expense_adjustment_account", r.message);
}
});
}
},
erpnext.stock.StockEntry = erpnext.stock.StockController.extend({
setup: function() {
var me = this;
@ -80,11 +53,7 @@ erpnext.stock.StockEntry = erpnext.stock.StockController.extend({
},
onload_post_render: function() {
if(this.frm.doc.__islocal && (this.frm.doc.production_order || this.frm.doc.bom_no)
&& !getchildren('Stock Entry Detail', this.frm.doc.name, 'mtn_details').length) {
// if production order / bom is mentioned, get items
this.get_items();
}
this.set_default_account();
},
refresh: function() {
@ -115,6 +84,33 @@ erpnext.stock.StockEntry = erpnext.stock.StockController.extend({
after_cancel: function() {
this.clean_up();
},
set_default_account: function() {
var me = this;
if (cint(wn.defaults.get_default("auto_inventory_accounting")) && !this.frm.doc.expense_adjustment_account) {
var account_for = "stock_adjustment_account";
if (this.frm.doc.purpose == "Sales Return")
account_for = "stock_in_hand_account";
else if (this.frm.doc.purpose == "Purchase Return")
account_for = "stock_received_but_not_billed";
return this.frm.call({
method: "accounts.utils.get_company_default",
args: {
"fieldname": account_for,
"company": this.frm.doc.company
},
callback: function(r) {
if (!r.exc) me.frm.set_value("expense_adjustment_account", r.message);
me.get_items();
}
});
} else {
me.get_items();
}
},
clean_up: function() {
// Clear Production Order record from locals, because it is updated via Stock Entry
@ -126,13 +122,17 @@ erpnext.stock.StockEntry = erpnext.stock.StockController.extend({
},
get_items: function() {
return this.frm.call({
doc: this.frm.doc,
method: "get_items",
callback: function(r) {
if(!r.exc) refresh_field("mtn_details");
}
});
if(this.frm.doc.__islocal && (this.frm.doc.production_order || this.frm.doc.bom_no)
&& !getchildren('Stock Entry Detail', this.frm.doc.name, 'mtn_details').length) {
// if production order / bom is mentioned, get items
return this.frm.call({
doc: this.frm.doc,
method: "get_items",
callback: function(r) {
if(!r.exc) refresh_field("mtn_details");
}
});
}
},
qty: function(doc, cdt, cdn) {
@ -212,7 +212,6 @@ erpnext.stock.StockEntry = erpnext.stock.StockController.extend({
});
loaddoc("Journal Voucher", jv_name);
}
}
});
}

View File

@ -19,6 +19,7 @@ sql = webnotes.conn.sql
class NotUpdateStockError(webnotes.ValidationError): pass
class StockOverReturnError(webnotes.ValidationError): pass
class IncorrectValuationRateError(webnotes.ValidationError): pass
from controllers.stock_controller import StockController
@ -245,7 +246,7 @@ class DocType(StockController):
def validate_incoming_rate(self):
for d in getlist(self.doclist, 'mtn_details'):
if d.t_warehouse:
self.validate_value("incoming_rate", ">", 0, d)
self.validate_value("incoming_rate", ">", 0, d, raise_exception=IncorrectValuationRateError)
def validate_bom(self):
for d in getlist(self.doclist, 'mtn_details'):

View File

@ -8,6 +8,7 @@ from stock.utils import get_valuation_method
import json
# future reposting
class NegativeStockError(webnotes.ValidationError): pass
_exceptions = []
def update_entries_after(args, verbose=1):
@ -253,9 +254,9 @@ def _raise_exceptions(args, verbose=1):
_exceptions[0]["voucher_type"], _exceptions[0]["voucher_no"],
abs(deficiency))
if verbose:
msgprint(msg, raise_exception=1)
msgprint(msg, raise_exception=NegativeStockError)
else:
raise webnotes.ValidationError, msg
raise NegativeStockError, msg
def get_previous_sle(args, for_update=False):
"""

View File

@ -69,7 +69,7 @@ def get_incoming_rate(args):
if valuation_method == 'FIFO':
if not previous_sle:
return 0.0
previous_stock_queue = json.loads(previous_sle.get('stock_queue', '[]'))
previous_stock_queue = json.loads(previous_sle.get('stock_queue', '[]') or '[]')
in_rate = previous_stock_queue and \
get_fifo_rate(previous_stock_queue, args.get("qty") or 0) or 0
elif valuation_method == 'Moving Average':
@ -184,8 +184,8 @@ def _get_buying_amount(voucher_type, voucher_no, item_row, stock_ledger_entries)
def reorder_item():
""" Reorder item if stock reaches reorder level"""
if not hasattr(webnotes, "auto_indent"):
webnotes.auto_indent = webnotes.conn.get_value('Stock Settings', None, 'auto_indent')
webnotes.auto_indent = cint(webnotes.conn.get_value('Stock Settings', None, 'auto_indent'))
if webnotes.auto_indent:
material_requests = {}
bin_list = webnotes.conn.sql("""select item_code, warehouse, projected_qty
@ -280,8 +280,8 @@ def create_material_request(material_requests):
if mr_list:
if not hasattr(webnotes, "reorder_email_notify"):
webnotes.reorder_email_notify = webnotes.conn.get_value('Stock Settings', None,
'reorder_email_notify')
webnotes.reorder_email_notify = cint(webnotes.conn.get_value('Stock Settings', None,
'reorder_email_notify'))
if(webnotes.reorder_email_notify):
send_email_notification(mr_list)
@ -307,7 +307,6 @@ def send_email_notification(mr_list):
msg += "<tr><td>" + item.item_code + "</td><td>" + item.warehouse + "</td><td>" + \
cstr(item.qty) + "</td><td>" + cstr(item.uom) + "</td></tr>"
msg += "</table>"
sendmail(email_list, subject='Auto Material Request Generation Notification', msg = msg)
def notify_errors(exceptions_list):

View File

@ -19,15 +19,18 @@ runs_for = 20
prob = {
"Quotation": { "make": 0.5, "qty": (1,5) },
"Sales Order": { "make": 0.5, "qty": (1,4) },
"Purchase Order": { "make": 0.7, "qty": (1,4) },
"Purchase Receipt": { "make": 0.7, "qty": (1,4) },
"Supplier Quotation": { "make": 0.5, "qty": (1, 3) }
}
def make():
def make(reset=False):
webnotes.connect()
webnotes.print_messages = True
webnotes.mute_emails = True
#setup()
if reset:
setup()
simulate()
def setup():
@ -68,13 +71,29 @@ def run_sales(current_date):
make_sales_order(current_date)
def run_stock(current_date):
pass
# make purchase requests
if can_make("Purchase Receipt"):
from buying.doctype.purchase_order.purchase_order import make_purchase_receipt
report = "Purchase Order Items To Be Received"
for po in list(set([r[0] for r in query_report.run(report)["result"] if r[0]!="Total"]))[:how_many("Purchase Receipt")]:
pr = webnotes.bean(make_purchase_receipt(po))
pr.doc.posting_date = current_date
pr.doc.fiscal_year = "2010"
pr.insert()
pr.submit()
# make delivery notes (if possible)
if can_make("Delivery Note"):
from selling.doctype.sales_order.sales_order import make_delivery_note
report = "Ordered Items To Be Delivered"
for so in list(set([r[0] for r in query_report.run(report)["result"] if r[0]!="Total"]))[:how_many("Delivery Note")]:
dn = webnotes.bean(make_delivery_note(so))
dn.doc.posting_date = current_date
dn.doc.fiscal_year = "2010"
dn.insert()
dn.submit()
# make stock entry (from production order)
def run_purchase(current_date):
# make supplier quotations
if can_make("Supplier Quotation"):
@ -121,6 +140,40 @@ def run_manufacturing(current_date):
b = webnotes.bean("Material Request", pro[0])
b.submit()
# stores -> wip
if can_make("Stock Entry for WIP"):
for pro in query_report.run("Open Production Orders")["result"][:how_many("Stock Entry for WIP")]:
make_stock_entry_from_pro(pro[0], "Material Transfer", current_date)
# wip -> fg
if can_make("Stock Entry for FG"):
for pro in query_report.run("Production Orders in Progress")["result"][:how_many("Stock Entry for FG")]:
make_stock_entry_from_pro(pro[0], "Manufacture/Repack", current_date)
# try posting older drafts (if exists)
for st in webnotes.conn.get_values("Stock Entry", {"docstatus":0}):
try:
webnotes.bean("Stock Entry", st[0]).submit()
except NegativeStockError: pass
except IncorrectValuationRateError: pass
def make_stock_entry_from_pro(pro_id, purpose, current_date):
from manufacturing.doctype.production_order.production_order import make_stock_entry
from stock.stock_ledger import NegativeStockError
from stock.doctype.stock_entry.stock_entry import IncorrectValuationRateError
st = webnotes.bean(make_stock_entry(pro_id, purpose))
st.run_method("get_items")
st.doc.posting_date = current_date
st.doc.fiscal_year = "2010"
st.doc.expense_adjustment_account = "Stock in Hand - WP"
try:
st.insert()
st.submit()
except NegativeStockError: pass
except IncorrectValuationRateError: pass
def make_quotation(current_date):
b = webnotes.bean([{
"creation": current_date,