Fixed Test Cases
This commit is contained in:
parent
06a6bcce17
commit
ec5ec60764
@ -29,6 +29,7 @@ def _make_test_records(verbose):
|
||||
["_Test Account S&H Education Cess", "_Test Account Tax Assets", "Ledger", "Tax"],
|
||||
["_Test Account CST", "Direct Expenses", "Ledger", "Tax"],
|
||||
["_Test Account Discount", "Direct Expenses", "Ledger", None],
|
||||
["_Test Write Off", "Indirect Expenses", "Ledger", None],
|
||||
|
||||
# related to Account Inventory Integration
|
||||
["_Test Account Stock In Hand", "Current Assets", "Ledger", None],
|
||||
|
@ -2,25 +2,32 @@
|
||||
{
|
||||
"budgets": [
|
||||
{
|
||||
"account": "_Test Account Cost for Goods Sold - _TC",
|
||||
"budget_allocated": 100000,
|
||||
"doctype": "Budget Detail",
|
||||
"fiscal_year": "_Test Fiscal Year 2013",
|
||||
"account": "_Test Account Cost for Goods Sold - _TC",
|
||||
"budget_allocated": 100000,
|
||||
"doctype": "Budget Detail",
|
||||
"fiscal_year": "_Test Fiscal Year 2013",
|
||||
"parentfield": "budgets"
|
||||
}
|
||||
],
|
||||
"company": "_Test Company",
|
||||
"cost_center_name": "_Test Cost Center",
|
||||
"distribution_id": "_Test Distribution",
|
||||
"doctype": "Cost Center",
|
||||
"group_or_ledger": "Ledger",
|
||||
],
|
||||
"company": "_Test Company",
|
||||
"cost_center_name": "_Test Cost Center",
|
||||
"distribution_id": "_Test Distribution",
|
||||
"doctype": "Cost Center",
|
||||
"group_or_ledger": "Ledger",
|
||||
"parent_cost_center": "_Test Company - _TC"
|
||||
},
|
||||
{
|
||||
"company": "_Test Company",
|
||||
"cost_center_name": "_Test Cost Center 2",
|
||||
"cost_center_name": "_Test Cost Center 2",
|
||||
"doctype": "Cost Center",
|
||||
"group_or_ledger": "Ledger",
|
||||
"parent_cost_center": "_Test Company - _TC"
|
||||
},
|
||||
{
|
||||
"company": "_Test Company",
|
||||
"cost_center_name": "_Test Write Off Cost Center",
|
||||
"doctype": "Cost Center",
|
||||
"group_or_ledger": "Ledger",
|
||||
"parent_cost_center": "_Test Company - _TC"
|
||||
}
|
||||
]
|
||||
]
|
||||
|
@ -15,6 +15,7 @@ class TestPricingRule(unittest.TestCase):
|
||||
|
||||
test_record = {
|
||||
"doctype": "Pricing Rule",
|
||||
"title": "_Test Pricing Rule",
|
||||
"apply_on": "Item Code",
|
||||
"item_code": "_Test Item",
|
||||
"selling": 1,
|
||||
|
@ -53,7 +53,7 @@
|
||||
"description": "Shipping Charges",
|
||||
"doctype": "Purchase Taxes and Charges",
|
||||
"parentfield": "taxes",
|
||||
"rate": 100
|
||||
"tax_amount": 100
|
||||
},
|
||||
{
|
||||
"account_head": "_Test Account Customs Duty - _TC",
|
||||
@ -176,7 +176,7 @@
|
||||
"description": "Shipping Charges",
|
||||
"doctype": "Purchase Taxes and Charges",
|
||||
"parentfield": "taxes",
|
||||
"rate": 100.0
|
||||
"tax_amount": 100.0
|
||||
},
|
||||
{
|
||||
"account_head": "_Test Account VAT - _TC",
|
||||
@ -187,7 +187,7 @@
|
||||
"description": "VAT",
|
||||
"doctype": "Purchase Taxes and Charges",
|
||||
"parentfield": "taxes",
|
||||
"rate": 120.0
|
||||
"tax_amount": 120.0
|
||||
},
|
||||
{
|
||||
"account_head": "_Test Account Customs Duty - _TC",
|
||||
@ -198,7 +198,7 @@
|
||||
"description": "Customs Duty",
|
||||
"doctype": "Purchase Taxes and Charges",
|
||||
"parentfield": "taxes",
|
||||
"rate": 150.0
|
||||
"tax_amount": 150.0
|
||||
}
|
||||
],
|
||||
"posting_date": "2013-02-03",
|
||||
|
@ -174,7 +174,7 @@
|
||||
"description": "Shipping Charges",
|
||||
"doctype": "Sales Taxes and Charges",
|
||||
"parentfield": "taxes",
|
||||
"rate": 100
|
||||
"tax_amount": 100
|
||||
},
|
||||
{
|
||||
"account_head": "_Test Account Customs Duty - _TC",
|
||||
@ -367,7 +367,7 @@
|
||||
"doctype": "Sales Taxes and Charges",
|
||||
"idx": 7,
|
||||
"parentfield": "taxes",
|
||||
"rate": 100
|
||||
"tax_amount": 100
|
||||
},
|
||||
{
|
||||
"account_head": "_Test Account Discount - _TC",
|
||||
|
@ -254,9 +254,9 @@ class TestSalesInvoice(unittest.TestCase):
|
||||
|
||||
expected_values = {
|
||||
"keys": ["price_list_rate", "discount_percentage", "rate", "amount",
|
||||
"base_price_list_rate", "base_rate", "base_amount"],
|
||||
"_Test Item Home Desktop 100": [62.5, 0, 62.5, 625.0, 50, 50, 499.98],
|
||||
"_Test Item Home Desktop 200": [190.66, 0, 190.66, 953.3, 150, 150, 750],
|
||||
"base_price_list_rate", "base_rate", "base_amount", "net_rate", "net_amount"],
|
||||
"_Test Item Home Desktop 100": [62.5, 0, 62.5, 625.0, 62.5, 62.5, 625.0, 50, 499.98],
|
||||
"_Test Item Home Desktop 200": [190.66, 0, 190.66, 953.3, 190.66, 190.66, 953.3, 150, 750],
|
||||
}
|
||||
|
||||
# check if children are saved
|
||||
@ -500,7 +500,9 @@ class TestSalesInvoice(unittest.TestCase):
|
||||
"naming_series": "_T-POS Setting-",
|
||||
"selling_price_list": "_Test Price List",
|
||||
"territory": "_Test Territory",
|
||||
"warehouse": "_Test Warehouse - _TC"
|
||||
"warehouse": "_Test Warehouse - _TC",
|
||||
"write_off_account": "_Test Write Off - _TC",
|
||||
"write_off_cost_center": "_Test Write Off Cost Center - _TC"
|
||||
})
|
||||
|
||||
if not frappe.db.exists("POS Setting", "_Test POS Setting"):
|
||||
|
@ -1,157 +1,157 @@
|
||||
[
|
||||
{
|
||||
"company": "_Test Company",
|
||||
"doctype": "Sales Taxes and Charges Master",
|
||||
"company": "_Test Company",
|
||||
"doctype": "Sales Taxes and Charges Master",
|
||||
"taxes": [
|
||||
{
|
||||
"account_head": "_Test Account VAT - _TC",
|
||||
"charge_type": "On Net Total",
|
||||
"description": "VAT",
|
||||
"doctype": "Sales Taxes and Charges",
|
||||
"parentfield": "taxes",
|
||||
"account_head": "_Test Account VAT - _TC",
|
||||
"charge_type": "On Net Total",
|
||||
"description": "VAT",
|
||||
"doctype": "Sales Taxes and Charges",
|
||||
"parentfield": "taxes",
|
||||
"rate": 6
|
||||
},
|
||||
},
|
||||
{
|
||||
"account_head": "_Test Account Service Tax - _TC",
|
||||
"charge_type": "On Net Total",
|
||||
"description": "Service Tax",
|
||||
"doctype": "Sales Taxes and Charges",
|
||||
"parentfield": "taxes",
|
||||
"account_head": "_Test Account Service Tax - _TC",
|
||||
"charge_type": "On Net Total",
|
||||
"description": "Service Tax",
|
||||
"doctype": "Sales Taxes and Charges",
|
||||
"parentfield": "taxes",
|
||||
"rate": 6.36
|
||||
}
|
||||
],
|
||||
"title": "_Test Sales Taxes and Charges Master",
|
||||
],
|
||||
"title": "_Test Sales Taxes and Charges Master",
|
||||
"territories": [
|
||||
{
|
||||
"doctype": "Applicable Territory",
|
||||
"parentfield": "territories",
|
||||
"doctype": "Applicable Territory",
|
||||
"parentfield": "territories",
|
||||
"territory": "All Territories"
|
||||
},
|
||||
},
|
||||
{
|
||||
"doctype": "Applicable Territory",
|
||||
"parentfield": "territories",
|
||||
"doctype": "Applicable Territory",
|
||||
"parentfield": "territories",
|
||||
"territory": "_Test Territory Rest Of The World"
|
||||
}
|
||||
]
|
||||
},
|
||||
},
|
||||
{
|
||||
"company": "_Test Company",
|
||||
"doctype": "Sales Taxes and Charges Master",
|
||||
"company": "_Test Company",
|
||||
"doctype": "Sales Taxes and Charges Master",
|
||||
"taxes": [
|
||||
{
|
||||
"account_head": "_Test Account Shipping Charges - _TC",
|
||||
"charge_type": "Actual",
|
||||
"cost_center": "_Test Cost Center - _TC",
|
||||
"description": "Shipping Charges",
|
||||
"doctype": "Sales Taxes and Charges",
|
||||
"parentfield": "taxes",
|
||||
"rate": 100
|
||||
},
|
||||
"account_head": "_Test Account Shipping Charges - _TC",
|
||||
"charge_type": "Actual",
|
||||
"cost_center": "_Test Cost Center - _TC",
|
||||
"description": "Shipping Charges",
|
||||
"doctype": "Sales Taxes and Charges",
|
||||
"parentfield": "taxes",
|
||||
"tax_amount": 100
|
||||
},
|
||||
{
|
||||
"account_head": "_Test Account Customs Duty - _TC",
|
||||
"charge_type": "On Net Total",
|
||||
"cost_center": "_Test Cost Center - _TC",
|
||||
"description": "Customs Duty",
|
||||
"doctype": "Sales Taxes and Charges",
|
||||
"parentfield": "taxes",
|
||||
"account_head": "_Test Account Customs Duty - _TC",
|
||||
"charge_type": "On Net Total",
|
||||
"cost_center": "_Test Cost Center - _TC",
|
||||
"description": "Customs Duty",
|
||||
"doctype": "Sales Taxes and Charges",
|
||||
"parentfield": "taxes",
|
||||
"rate": 10
|
||||
},
|
||||
},
|
||||
{
|
||||
"account_head": "_Test Account Excise Duty - _TC",
|
||||
"charge_type": "On Net Total",
|
||||
"cost_center": "_Test Cost Center - _TC",
|
||||
"description": "Excise Duty",
|
||||
"doctype": "Sales Taxes and Charges",
|
||||
"parentfield": "taxes",
|
||||
"account_head": "_Test Account Excise Duty - _TC",
|
||||
"charge_type": "On Net Total",
|
||||
"cost_center": "_Test Cost Center - _TC",
|
||||
"description": "Excise Duty",
|
||||
"doctype": "Sales Taxes and Charges",
|
||||
"parentfield": "taxes",
|
||||
"rate": 12
|
||||
},
|
||||
},
|
||||
{
|
||||
"account_head": "_Test Account Education Cess - _TC",
|
||||
"charge_type": "On Previous Row Amount",
|
||||
"cost_center": "_Test Cost Center - _TC",
|
||||
"description": "Education Cess",
|
||||
"doctype": "Sales Taxes and Charges",
|
||||
"parentfield": "taxes",
|
||||
"rate": 2,
|
||||
"account_head": "_Test Account Education Cess - _TC",
|
||||
"charge_type": "On Previous Row Amount",
|
||||
"cost_center": "_Test Cost Center - _TC",
|
||||
"description": "Education Cess",
|
||||
"doctype": "Sales Taxes and Charges",
|
||||
"parentfield": "taxes",
|
||||
"rate": 2,
|
||||
"row_id": 3
|
||||
},
|
||||
},
|
||||
{
|
||||
"account_head": "_Test Account S&H Education Cess - _TC",
|
||||
"charge_type": "On Previous Row Amount",
|
||||
"cost_center": "_Test Cost Center - _TC",
|
||||
"description": "S&H Education Cess",
|
||||
"doctype": "Sales Taxes and Charges",
|
||||
"parentfield": "taxes",
|
||||
"rate": 1,
|
||||
"account_head": "_Test Account S&H Education Cess - _TC",
|
||||
"charge_type": "On Previous Row Amount",
|
||||
"cost_center": "_Test Cost Center - _TC",
|
||||
"description": "S&H Education Cess",
|
||||
"doctype": "Sales Taxes and Charges",
|
||||
"parentfield": "taxes",
|
||||
"rate": 1,
|
||||
"row_id": 3
|
||||
},
|
||||
},
|
||||
{
|
||||
"account_head": "_Test Account CST - _TC",
|
||||
"charge_type": "On Previous Row Total",
|
||||
"cost_center": "_Test Cost Center - _TC",
|
||||
"description": "CST",
|
||||
"doctype": "Sales Taxes and Charges",
|
||||
"parentfield": "taxes",
|
||||
"rate": 2,
|
||||
"account_head": "_Test Account CST - _TC",
|
||||
"charge_type": "On Previous Row Total",
|
||||
"cost_center": "_Test Cost Center - _TC",
|
||||
"description": "CST",
|
||||
"doctype": "Sales Taxes and Charges",
|
||||
"parentfield": "taxes",
|
||||
"rate": 2,
|
||||
"row_id": 5
|
||||
},
|
||||
},
|
||||
{
|
||||
"account_head": "_Test Account VAT - _TC",
|
||||
"charge_type": "On Net Total",
|
||||
"cost_center": "_Test Cost Center - _TC",
|
||||
"description": "VAT",
|
||||
"doctype": "Sales Taxes and Charges",
|
||||
"parentfield": "taxes",
|
||||
"account_head": "_Test Account VAT - _TC",
|
||||
"charge_type": "On Net Total",
|
||||
"cost_center": "_Test Cost Center - _TC",
|
||||
"description": "VAT",
|
||||
"doctype": "Sales Taxes and Charges",
|
||||
"parentfield": "taxes",
|
||||
"rate": 12.5
|
||||
},
|
||||
},
|
||||
{
|
||||
"account_head": "_Test Account Discount - _TC",
|
||||
"charge_type": "On Previous Row Total",
|
||||
"cost_center": "_Test Cost Center - _TC",
|
||||
"description": "Discount",
|
||||
"doctype": "Sales Taxes and Charges",
|
||||
"parentfield": "taxes",
|
||||
"rate": -10,
|
||||
"account_head": "_Test Account Discount - _TC",
|
||||
"charge_type": "On Previous Row Total",
|
||||
"cost_center": "_Test Cost Center - _TC",
|
||||
"description": "Discount",
|
||||
"doctype": "Sales Taxes and Charges",
|
||||
"parentfield": "taxes",
|
||||
"rate": -10,
|
||||
"row_id": 7
|
||||
}
|
||||
],
|
||||
"title": "_Test India Tax Master",
|
||||
],
|
||||
"title": "_Test India Tax Master",
|
||||
"territories": [
|
||||
{
|
||||
"doctype": "Applicable Territory",
|
||||
"parentfield": "territories",
|
||||
"doctype": "Applicable Territory",
|
||||
"parentfield": "territories",
|
||||
"territory": "_Test Territory India"
|
||||
}
|
||||
]
|
||||
},
|
||||
},
|
||||
{
|
||||
"company": "_Test Company",
|
||||
"doctype": "Sales Taxes and Charges Master",
|
||||
"company": "_Test Company",
|
||||
"doctype": "Sales Taxes and Charges Master",
|
||||
"taxes": [
|
||||
{
|
||||
"account_head": "_Test Account VAT - _TC",
|
||||
"charge_type": "On Net Total",
|
||||
"description": "VAT",
|
||||
"doctype": "Sales Taxes and Charges",
|
||||
"parentfield": "taxes",
|
||||
"account_head": "_Test Account VAT - _TC",
|
||||
"charge_type": "On Net Total",
|
||||
"description": "VAT",
|
||||
"doctype": "Sales Taxes and Charges",
|
||||
"parentfield": "taxes",
|
||||
"rate": 12
|
||||
},
|
||||
},
|
||||
{
|
||||
"account_head": "_Test Account Service Tax - _TC",
|
||||
"charge_type": "On Net Total",
|
||||
"description": "Service Tax",
|
||||
"doctype": "Sales Taxes and Charges",
|
||||
"parentfield": "taxes",
|
||||
"account_head": "_Test Account Service Tax - _TC",
|
||||
"charge_type": "On Net Total",
|
||||
"description": "Service Tax",
|
||||
"doctype": "Sales Taxes and Charges",
|
||||
"parentfield": "taxes",
|
||||
"rate": 4
|
||||
}
|
||||
],
|
||||
"title": "_Test Sales Taxes and Charges Master - Rest of the World",
|
||||
],
|
||||
"title": "_Test Sales Taxes and Charges Master - Rest of the World",
|
||||
"territories": [
|
||||
{
|
||||
"doctype": "Applicable Territory",
|
||||
"parentfield": "territories",
|
||||
"doctype": "Applicable Territory",
|
||||
"parentfield": "territories",
|
||||
"territory": "_Test Territory Rest Of The World"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
]
|
||||
|
@ -226,13 +226,13 @@ class calculate_taxes_and_totals(object):
|
||||
# set precision in the last item iteration
|
||||
if n == len(self.doc.get("items")) - 1:
|
||||
self.round_off_totals(tax)
|
||||
|
||||
|
||||
# adjust Discount Amount loss in last tax iteration
|
||||
if i == (len(self.doc.get("taxes")) - 1) and self.discount_amount_applied \
|
||||
and self.doc.discount_amount:
|
||||
self.adjust_discount_amount_loss(tax)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
def get_current_tax_amount(self, item, tax, item_tax_map):
|
||||
tax_rate = self._get_tax_rate(tax, item_tax_map)
|
||||
@ -279,18 +279,23 @@ class calculate_taxes_and_totals(object):
|
||||
tax.tax_amount_after_discount_amount = flt(tax.tax_amount_after_discount_amount +
|
||||
discount_amount_loss, tax.precision("tax_amount"))
|
||||
tax.total = flt(tax.total + discount_amount_loss, tax.precision("total"))
|
||||
|
||||
|
||||
self._set_in_company_currency(tax, ["total", "tax_amount_after_discount_amount"])
|
||||
|
||||
def calculate_totals(self):
|
||||
self.doc.grand_total = flt(self.doc.get("taxes")[-1].total
|
||||
if self.doc.get("taxes") else self.doc.net_total)
|
||||
|
||||
self.doc.total_taxes_and_charges = flt(self.doc.grand_total - self.doc.net_total,
|
||||
self.doc.precision("total_taxes_and_charges"))
|
||||
|
||||
self._set_in_company_currency(self.doc, ["total_taxes_and_charges"])
|
||||
|
||||
if self.doc.doctype in ["Quotation", "Sales Order", "Delivery Note", "Sales Invoice"]:
|
||||
self.doc.base_grand_total = flt(self.doc.grand_total * self.doc.conversion_rate) \
|
||||
if self.doc.total_taxes_and_charges else self.doc.base_net_total
|
||||
else:
|
||||
self.doc.taxes_and_charges_added, self.taxes_and_charges_deducted = 0.0, 0.0
|
||||
self.doc.taxes_and_charges_added = self.doc.taxes_and_charges_deducted = 0.0
|
||||
for tax in self.doc.get("taxes"):
|
||||
if tax.category in ["Valuation and Total", "Total"]:
|
||||
if tax.add_deduct_tax == "Add":
|
||||
@ -306,10 +311,6 @@ class calculate_taxes_and_totals(object):
|
||||
|
||||
self._set_in_company_currency(self.doc, ["taxes_and_charges_added", "taxes_and_charges_deducted"])
|
||||
|
||||
self.doc.total_taxes_and_charges = flt(self.doc.grand_total - self.doc.net_total,
|
||||
self.doc.precision("total_taxes_and_charges"))
|
||||
|
||||
self._set_in_company_currency(self.doc, ["total_taxes_and_charges"])
|
||||
self.doc.round_floats_in(self.doc, ["grand_total", "base_grand_total"])
|
||||
|
||||
if self.doc.meta.get_field("rounded_total"):
|
||||
@ -338,20 +339,20 @@ class calculate_taxes_and_totals(object):
|
||||
for i, item in enumerate(self.doc.get("items")):
|
||||
distributed_amount = flt(self.doc.discount_amount) * \
|
||||
item.net_amount / total_for_discount_amount
|
||||
|
||||
|
||||
item.net_amount = flt(item.net_amount - distributed_amount, item.precision("net_amount"))
|
||||
net_total += item.net_amount
|
||||
|
||||
|
||||
# discount amount rounding loss adjustment if no taxes
|
||||
if (not taxes or self.doc.apply_discount_on == "Net Total") \
|
||||
and i == len(self.doc.get("items")) - 1:
|
||||
discount_amount_loss = flt(self.doc.total - net_total - self.doc.discount_amount,
|
||||
discount_amount_loss = flt(self.doc.total - net_total - self.doc.discount_amount,
|
||||
self.doc.precision("net_total"))
|
||||
item.net_amount = flt(item.net_amount + discount_amount_loss,
|
||||
item.net_amount = flt(item.net_amount + discount_amount_loss,
|
||||
item.precision("net_amount"))
|
||||
|
||||
|
||||
item.net_rate = flt(item.net_amount / item.qty, item.precision("net_rate"))
|
||||
|
||||
|
||||
self._set_in_company_currency(item, ["net_rate", "net_amount"])
|
||||
|
||||
self.discount_amount_applied = True
|
||||
|
@ -124,6 +124,9 @@ class Opportunity(TransactionBase):
|
||||
item_fields = ("item_name", "description", "item_group", "brand")
|
||||
|
||||
for d in self.items:
|
||||
if not d.item_code:
|
||||
continue
|
||||
|
||||
item = frappe.db.get_value("Item", d.item_code, item_fields, as_dict=True)
|
||||
for key in item_fields:
|
||||
if not d.get(key): d.set(key, item.get(key))
|
||||
|
@ -4,7 +4,7 @@
|
||||
from __future__ import unicode_literals
|
||||
import frappe
|
||||
|
||||
from frappe.utils import getdate, validate_email_add, cint
|
||||
from frappe.utils import getdate, validate_email_add, cint, today
|
||||
from frappe.model.naming import make_autoname
|
||||
from frappe import throw, _, msgprint
|
||||
import frappe.permissions
|
||||
@ -205,6 +205,6 @@ def send_birthday_reminders():
|
||||
def get_employees_who_are_born_today():
|
||||
"""Get Employee properties whose birthday is today."""
|
||||
return frappe.db.sql("""select name, personal_email, company_email, employee_name
|
||||
from tabEmployee where day(date_of_birth) = day(curdate())
|
||||
and month(date_of_birth) = month(curdate())
|
||||
and status = 'Active'""", as_dict=True)
|
||||
from tabEmployee where day(date_of_birth) = day(%(date)s)
|
||||
and month(date_of_birth) = month(%(date)s)
|
||||
and status = 'Active'""", {"date": today()}, as_dict=True)
|
||||
|
@ -1,99 +1,99 @@
|
||||
{
|
||||
"allow_copy": 0,
|
||||
"allow_import": 0,
|
||||
"allow_rename": 0,
|
||||
"creation": "2014-11-27 14:12:07.542534",
|
||||
"custom": 0,
|
||||
"docstatus": 0,
|
||||
"doctype": "DocType",
|
||||
"document_type": "Master",
|
||||
"allow_copy": 0,
|
||||
"allow_import": 0,
|
||||
"allow_rename": 0,
|
||||
"creation": "2014-11-27 14:12:07.542534",
|
||||
"custom": 0,
|
||||
"docstatus": 0,
|
||||
"doctype": "DocType",
|
||||
"document_type": "Master",
|
||||
"fields": [
|
||||
{
|
||||
"fieldname": "capacity_planning",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "Capacity Planning",
|
||||
"permlevel": 0,
|
||||
"fieldname": "capacity_planning",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "Capacity Planning",
|
||||
"permlevel": 0,
|
||||
"precision": ""
|
||||
},
|
||||
},
|
||||
{
|
||||
"description": "Plan time logs outside Workstation Working Hours.",
|
||||
"fieldname": "allow_overtime",
|
||||
"fieldtype": "Check",
|
||||
"label": "Allow Overtime",
|
||||
"permlevel": 0,
|
||||
"description": "Plan time logs outside Workstation Working Hours.",
|
||||
"fieldname": "allow_overtime",
|
||||
"fieldtype": "Check",
|
||||
"label": "Allow Overtime",
|
||||
"permlevel": 0,
|
||||
"precision": ""
|
||||
},
|
||||
},
|
||||
{
|
||||
"default": "",
|
||||
"fieldname": "allow_production_on_holidays",
|
||||
"fieldtype": "Check",
|
||||
"in_list_view": 1,
|
||||
"label": "Allow Production on Holidays",
|
||||
"options": "",
|
||||
"permlevel": 0,
|
||||
"default": "",
|
||||
"fieldname": "allow_production_on_holidays",
|
||||
"fieldtype": "Check",
|
||||
"in_list_view": 1,
|
||||
"label": "Allow Production on Holidays",
|
||||
"options": "",
|
||||
"permlevel": 0,
|
||||
"precision": ""
|
||||
},
|
||||
},
|
||||
{
|
||||
"fieldname": "column_break_3",
|
||||
"fieldtype": "Column Break",
|
||||
"permlevel": 0,
|
||||
"fieldname": "column_break_3",
|
||||
"fieldtype": "Column Break",
|
||||
"permlevel": 0,
|
||||
"precision": ""
|
||||
},
|
||||
},
|
||||
{
|
||||
"default": "30",
|
||||
"description": "Try planning operations for X days in advance.",
|
||||
"fieldname": "capacity_planning_for_days",
|
||||
"fieldtype": "Data",
|
||||
"label": "Capacity Planning For (Days)",
|
||||
"permlevel": 0,
|
||||
"default": "30",
|
||||
"description": "Try planning operations for X days in advance.",
|
||||
"fieldname": "capacity_planning_for_days",
|
||||
"fieldtype": "Data",
|
||||
"label": "Capacity Planning For (Days)",
|
||||
"permlevel": 0,
|
||||
"precision": ""
|
||||
},
|
||||
},
|
||||
{
|
||||
"description": "Default 10 mins",
|
||||
"fieldname": "mins_between_operations",
|
||||
"fieldtype": "Data",
|
||||
"label": "Time Between Operations (in mins)",
|
||||
"permlevel": 0,
|
||||
"description": "Default 10 mins",
|
||||
"fieldname": "mins_between_operations",
|
||||
"fieldtype": "Data",
|
||||
"label": "Time Between Operations (in mins)",
|
||||
"permlevel": 0,
|
||||
"precision": ""
|
||||
}
|
||||
],
|
||||
"hide_heading": 0,
|
||||
"hide_toolbar": 0,
|
||||
"icon": "icon-wrench",
|
||||
"in_create": 0,
|
||||
"in_dialog": 0,
|
||||
"is_submittable": 0,
|
||||
"issingle": 1,
|
||||
"istable": 0,
|
||||
"modified": "2015-02-23 23:44:45.917027",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Manufacturing",
|
||||
"name": "Manufacturing Settings",
|
||||
"name_case": "",
|
||||
"owner": "Administrator",
|
||||
],
|
||||
"hide_heading": 0,
|
||||
"hide_toolbar": 0,
|
||||
"icon": "icon-wrench",
|
||||
"in_create": 0,
|
||||
"in_dialog": 0,
|
||||
"is_submittable": 0,
|
||||
"issingle": 1,
|
||||
"istable": 0,
|
||||
"modified": "2015-03-05 23:44:45.917027",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Manufacturing",
|
||||
"name": "Manufacturing Settings",
|
||||
"name_case": "",
|
||||
"owner": "Administrator",
|
||||
"permissions": [
|
||||
{
|
||||
"amend": 0,
|
||||
"apply_user_permissions": 0,
|
||||
"cancel": 0,
|
||||
"create": 1,
|
||||
"delete": 0,
|
||||
"email": 0,
|
||||
"export": 0,
|
||||
"import": 0,
|
||||
"permlevel": 0,
|
||||
"print": 0,
|
||||
"read": 1,
|
||||
"report": 0,
|
||||
"role": "Manufacturing Manager",
|
||||
"set_user_permissions": 0,
|
||||
"share": 1,
|
||||
"submit": 0,
|
||||
"amend": 0,
|
||||
"apply_user_permissions": 0,
|
||||
"cancel": 0,
|
||||
"create": 1,
|
||||
"delete": 0,
|
||||
"email": 0,
|
||||
"export": 0,
|
||||
"import": 0,
|
||||
"permlevel": 0,
|
||||
"print": 0,
|
||||
"read": 1,
|
||||
"report": 0,
|
||||
"role": "Manufacturing Manager",
|
||||
"set_user_permissions": 0,
|
||||
"share": 1,
|
||||
"submit": 0,
|
||||
"write": 1
|
||||
}
|
||||
],
|
||||
"read_only": 0,
|
||||
"read_only_onload": 0,
|
||||
"sort_field": "modified",
|
||||
],
|
||||
"read_only": 0,
|
||||
"read_only_onload": 0,
|
||||
"sort_field": "modified",
|
||||
"sort_order": "DESC"
|
||||
}
|
||||
}
|
||||
|
@ -200,7 +200,7 @@ $.extend(cur_frm.cscript, {
|
||||
},
|
||||
|
||||
show_time_logs: function(doc, doctype, name) {
|
||||
frappe.route_options = {"operation_id": name};
|
||||
frappe.route_options = {"operation": name};
|
||||
frappe.set_route("List", "Time Log");
|
||||
},
|
||||
|
||||
|
@ -1,385 +1,386 @@
|
||||
{
|
||||
"allow_import": 1,
|
||||
"autoname": "naming_series:",
|
||||
"creation": "2013-01-10 16:34:16",
|
||||
"docstatus": 0,
|
||||
"doctype": "DocType",
|
||||
"allow_import": 1,
|
||||
"autoname": "naming_series:",
|
||||
"creation": "2013-01-10 16:34:16",
|
||||
"docstatus": 0,
|
||||
"doctype": "DocType",
|
||||
"fields": [
|
||||
{
|
||||
"fieldname": "item",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "",
|
||||
"options": "icon-gift",
|
||||
"fieldname": "item",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "",
|
||||
"options": "icon-gift",
|
||||
"permlevel": 0
|
||||
},
|
||||
},
|
||||
{
|
||||
"default": "PRO-",
|
||||
"fieldname": "naming_series",
|
||||
"fieldtype": "Select",
|
||||
"label": "Series",
|
||||
"options": "PRO-",
|
||||
"permlevel": 0,
|
||||
"default": "PRO-",
|
||||
"fieldname": "naming_series",
|
||||
"fieldtype": "Select",
|
||||
"label": "Series",
|
||||
"options": "PRO-",
|
||||
"permlevel": 0,
|
||||
"reqd": 1
|
||||
},
|
||||
},
|
||||
{
|
||||
"default": "Draft",
|
||||
"depends_on": "eval:!doc.__islocal",
|
||||
"fieldname": "status",
|
||||
"fieldtype": "Select",
|
||||
"in_filter": 1,
|
||||
"in_list_view": 0,
|
||||
"label": "Status",
|
||||
"no_copy": 1,
|
||||
"oldfieldname": "status",
|
||||
"oldfieldtype": "Select",
|
||||
"options": "\nDraft\nSubmitted\nStopped\nIn Process\nCompleted\nCancelled",
|
||||
"permlevel": 0,
|
||||
"read_only": 1,
|
||||
"reqd": 1,
|
||||
"default": "Draft",
|
||||
"depends_on": "eval:!doc.__islocal",
|
||||
"fieldname": "status",
|
||||
"fieldtype": "Select",
|
||||
"in_filter": 1,
|
||||
"in_list_view": 0,
|
||||
"label": "Status",
|
||||
"no_copy": 1,
|
||||
"oldfieldname": "status",
|
||||
"oldfieldtype": "Select",
|
||||
"options": "\nDraft\nSubmitted\nStopped\nIn Process\nCompleted\nCancelled",
|
||||
"permlevel": 0,
|
||||
"read_only": 1,
|
||||
"reqd": 1,
|
||||
"search_index": 1
|
||||
},
|
||||
},
|
||||
{
|
||||
"fieldname": "production_item",
|
||||
"fieldtype": "Link",
|
||||
"in_filter": 1,
|
||||
"in_list_view": 1,
|
||||
"label": "Item To Manufacture",
|
||||
"oldfieldname": "production_item",
|
||||
"oldfieldtype": "Link",
|
||||
"options": "Item",
|
||||
"permlevel": 0,
|
||||
"read_only": 0,
|
||||
"fieldname": "production_item",
|
||||
"fieldtype": "Link",
|
||||
"in_filter": 1,
|
||||
"in_list_view": 1,
|
||||
"label": "Item To Manufacture",
|
||||
"oldfieldname": "production_item",
|
||||
"oldfieldtype": "Link",
|
||||
"options": "Item",
|
||||
"permlevel": 0,
|
||||
"read_only": 0,
|
||||
"reqd": 1
|
||||
},
|
||||
},
|
||||
{
|
||||
"depends_on": "",
|
||||
"description": "",
|
||||
"fieldname": "bom_no",
|
||||
"fieldtype": "Link",
|
||||
"in_list_view": 0,
|
||||
"label": "BOM No",
|
||||
"oldfieldname": "bom_no",
|
||||
"oldfieldtype": "Link",
|
||||
"options": "BOM",
|
||||
"permlevel": 0,
|
||||
"read_only": 0,
|
||||
"depends_on": "",
|
||||
"description": "",
|
||||
"fieldname": "bom_no",
|
||||
"fieldtype": "Link",
|
||||
"in_list_view": 0,
|
||||
"label": "BOM No",
|
||||
"oldfieldname": "bom_no",
|
||||
"oldfieldtype": "Link",
|
||||
"options": "BOM",
|
||||
"permlevel": 0,
|
||||
"read_only": 0,
|
||||
"reqd": 1
|
||||
},
|
||||
},
|
||||
{
|
||||
"default": "1",
|
||||
"description": "Plan material for sub-assemblies",
|
||||
"fieldname": "use_multi_level_bom",
|
||||
"fieldtype": "Check",
|
||||
"label": "Use Multi-Level BOM",
|
||||
"default": "1",
|
||||
"description": "Plan material for sub-assemblies",
|
||||
"fieldname": "use_multi_level_bom",
|
||||
"fieldtype": "Check",
|
||||
"label": "Use Multi-Level BOM",
|
||||
"permlevel": 0
|
||||
},
|
||||
},
|
||||
{
|
||||
"fieldname": "column_break1",
|
||||
"fieldtype": "Column Break",
|
||||
"oldfieldtype": "Column Break",
|
||||
"permlevel": 0,
|
||||
"read_only": 0,
|
||||
"fieldname": "column_break1",
|
||||
"fieldtype": "Column Break",
|
||||
"oldfieldtype": "Column Break",
|
||||
"permlevel": 0,
|
||||
"read_only": 0,
|
||||
"width": "50%"
|
||||
},
|
||||
},
|
||||
{
|
||||
"depends_on": "",
|
||||
"fieldname": "qty",
|
||||
"fieldtype": "Float",
|
||||
"in_list_view": 0,
|
||||
"label": "Qty To Manufacture",
|
||||
"oldfieldname": "qty",
|
||||
"oldfieldtype": "Currency",
|
||||
"permlevel": 0,
|
||||
"read_only": 0,
|
||||
"depends_on": "",
|
||||
"fieldname": "qty",
|
||||
"fieldtype": "Float",
|
||||
"in_list_view": 0,
|
||||
"label": "Qty To Manufacture",
|
||||
"oldfieldname": "qty",
|
||||
"oldfieldtype": "Currency",
|
||||
"permlevel": 0,
|
||||
"read_only": 0,
|
||||
"reqd": 1
|
||||
},
|
||||
},
|
||||
{
|
||||
"description": "",
|
||||
"fieldname": "material_transferred_for_qty",
|
||||
"fieldtype": "Int",
|
||||
"label": "Material Transferred for Qty",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"description": "",
|
||||
"fieldname": "material_transferred_for_qty",
|
||||
"fieldtype": "Int",
|
||||
"label": "Material Transferred for Qty",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"read_only": 1
|
||||
},
|
||||
},
|
||||
{
|
||||
"default": "0",
|
||||
"depends_on": "eval:doc.docstatus==1",
|
||||
"description": "",
|
||||
"fieldname": "produced_qty",
|
||||
"fieldtype": "Float",
|
||||
"label": "Manufactured Qty",
|
||||
"no_copy": 1,
|
||||
"oldfieldname": "produced_qty",
|
||||
"oldfieldtype": "Currency",
|
||||
"permlevel": 0,
|
||||
"default": "0",
|
||||
"depends_on": "eval:doc.docstatus==1",
|
||||
"description": "",
|
||||
"fieldname": "produced_qty",
|
||||
"fieldtype": "Float",
|
||||
"label": "Manufactured Qty",
|
||||
"no_copy": 1,
|
||||
"oldfieldname": "produced_qty",
|
||||
"oldfieldtype": "Currency",
|
||||
"permlevel": 0,
|
||||
"read_only": 1
|
||||
},
|
||||
},
|
||||
{
|
||||
"fieldname": "warehouses",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "Warehouses",
|
||||
"options": "icon-building",
|
||||
"fieldname": "warehouses",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "Warehouses",
|
||||
"options": "icon-building",
|
||||
"permlevel": 0
|
||||
},
|
||||
},
|
||||
{
|
||||
"fieldname": "wip_warehouse",
|
||||
"fieldtype": "Link",
|
||||
"label": "Work-in-Progress Warehouse",
|
||||
"options": "Warehouse",
|
||||
"permlevel": 0,
|
||||
"fieldname": "wip_warehouse",
|
||||
"fieldtype": "Link",
|
||||
"label": "Work-in-Progress Warehouse",
|
||||
"options": "Warehouse",
|
||||
"permlevel": 0,
|
||||
"reqd": 0
|
||||
},
|
||||
},
|
||||
{
|
||||
"fieldname": "column_break_12",
|
||||
"fieldtype": "Column Break",
|
||||
"fieldname": "column_break_12",
|
||||
"fieldtype": "Column Break",
|
||||
"permlevel": 0
|
||||
},
|
||||
},
|
||||
{
|
||||
"depends_on": "",
|
||||
"description": "",
|
||||
"fieldname": "fg_warehouse",
|
||||
"fieldtype": "Link",
|
||||
"in_list_view": 0,
|
||||
"label": "Target Warehouse",
|
||||
"options": "Warehouse",
|
||||
"permlevel": 0,
|
||||
"read_only": 0,
|
||||
"depends_on": "",
|
||||
"description": "",
|
||||
"fieldname": "fg_warehouse",
|
||||
"fieldtype": "Link",
|
||||
"in_list_view": 0,
|
||||
"label": "Target Warehouse",
|
||||
"options": "Warehouse",
|
||||
"permlevel": 0,
|
||||
"read_only": 0,
|
||||
"reqd": 0
|
||||
},
|
||||
},
|
||||
{
|
||||
"fieldname": "time",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "Time",
|
||||
"options": "icon-time",
|
||||
"permlevel": 0,
|
||||
"fieldname": "time",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "Time",
|
||||
"options": "icon-time",
|
||||
"permlevel": 0,
|
||||
"precision": ""
|
||||
},
|
||||
},
|
||||
{
|
||||
"depends_on": "",
|
||||
"fieldname": "expected_delivery_date",
|
||||
"fieldtype": "Date",
|
||||
"label": "Expected Delivery Date",
|
||||
"permlevel": 0,
|
||||
"depends_on": "",
|
||||
"fieldname": "expected_delivery_date",
|
||||
"fieldtype": "Date",
|
||||
"label": "Expected Delivery Date",
|
||||
"permlevel": 0,
|
||||
"read_only": 0
|
||||
},
|
||||
},
|
||||
{
|
||||
"fieldname": "planned_start_date",
|
||||
"fieldtype": "Datetime",
|
||||
"label": "Planned Start Date",
|
||||
"permlevel": 0,
|
||||
"default": "now",
|
||||
"fieldname": "planned_start_date",
|
||||
"fieldtype": "Datetime",
|
||||
"label": "Planned Start Date",
|
||||
"permlevel": 0,
|
||||
"precision": ""
|
||||
},
|
||||
},
|
||||
{
|
||||
"fieldname": "planned_end_date",
|
||||
"fieldtype": "Datetime",
|
||||
"label": "Planned End Date",
|
||||
"permlevel": 0,
|
||||
"fieldname": "planned_end_date",
|
||||
"fieldtype": "Datetime",
|
||||
"label": "Planned End Date",
|
||||
"permlevel": 0,
|
||||
"precision": ""
|
||||
},
|
||||
},
|
||||
{
|
||||
"fieldname": "column_break_13",
|
||||
"fieldtype": "Column Break",
|
||||
"permlevel": 0,
|
||||
"fieldname": "column_break_13",
|
||||
"fieldtype": "Column Break",
|
||||
"permlevel": 0,
|
||||
"precision": ""
|
||||
},
|
||||
},
|
||||
{
|
||||
"fieldname": "actual_start_date",
|
||||
"fieldtype": "Datetime",
|
||||
"label": "Actual Start Date",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"fieldname": "actual_start_date",
|
||||
"fieldtype": "Datetime",
|
||||
"label": "Actual Start Date",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"read_only": 1
|
||||
},
|
||||
},
|
||||
{
|
||||
"fieldname": "actual_end_date",
|
||||
"fieldtype": "Datetime",
|
||||
"label": "Actual End Date",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"fieldname": "actual_end_date",
|
||||
"fieldtype": "Datetime",
|
||||
"label": "Actual End Date",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"read_only": 1
|
||||
},
|
||||
},
|
||||
{
|
||||
"depends_on": "",
|
||||
"fieldname": "operations_section",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "Operations",
|
||||
"options": "icon-wrench",
|
||||
"permlevel": 0,
|
||||
"depends_on": "",
|
||||
"fieldname": "operations_section",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "Operations",
|
||||
"options": "icon-wrench",
|
||||
"permlevel": 0,
|
||||
"precision": ""
|
||||
},
|
||||
},
|
||||
{
|
||||
"fieldname": "operations",
|
||||
"fieldtype": "Table",
|
||||
"label": "Operations",
|
||||
"options": "Production Order Operation",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"fieldname": "operations",
|
||||
"fieldtype": "Table",
|
||||
"label": "Operations",
|
||||
"options": "Production Order Operation",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"read_only": 1
|
||||
},
|
||||
},
|
||||
{
|
||||
"fieldname": "section_break_22",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "Operation Cost",
|
||||
"options": "",
|
||||
"permlevel": 0,
|
||||
"fieldname": "section_break_22",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "Operation Cost",
|
||||
"options": "",
|
||||
"permlevel": 0,
|
||||
"precision": ""
|
||||
},
|
||||
},
|
||||
{
|
||||
"fieldname": "planned_operating_cost",
|
||||
"fieldtype": "Currency",
|
||||
"label": "Planned Operating Cost",
|
||||
"no_copy": 0,
|
||||
"options": "Company:company:default_currency",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"fieldname": "planned_operating_cost",
|
||||
"fieldtype": "Currency",
|
||||
"label": "Planned Operating Cost",
|
||||
"no_copy": 0,
|
||||
"options": "Company:company:default_currency",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"read_only": 1
|
||||
},
|
||||
},
|
||||
{
|
||||
"fieldname": "actual_operating_cost",
|
||||
"fieldtype": "Currency",
|
||||
"label": "Actual Operating Cost",
|
||||
"no_copy": 1,
|
||||
"options": "Company:company:default_currency",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"fieldname": "actual_operating_cost",
|
||||
"fieldtype": "Currency",
|
||||
"label": "Actual Operating Cost",
|
||||
"no_copy": 1,
|
||||
"options": "Company:company:default_currency",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"read_only": 1
|
||||
},
|
||||
},
|
||||
{
|
||||
"fieldname": "additional_operating_cost",
|
||||
"fieldtype": "Currency",
|
||||
"label": "Additional Operating Cost",
|
||||
"no_copy": 1,
|
||||
"options": "Company:company:default_currency",
|
||||
"permlevel": 0,
|
||||
"fieldname": "additional_operating_cost",
|
||||
"fieldtype": "Currency",
|
||||
"label": "Additional Operating Cost",
|
||||
"no_copy": 1,
|
||||
"options": "Company:company:default_currency",
|
||||
"permlevel": 0,
|
||||
"precision": ""
|
||||
},
|
||||
},
|
||||
{
|
||||
"fieldname": "column_break_24",
|
||||
"fieldtype": "Column Break",
|
||||
"permlevel": 0,
|
||||
"fieldname": "column_break_24",
|
||||
"fieldtype": "Column Break",
|
||||
"permlevel": 0,
|
||||
"precision": ""
|
||||
},
|
||||
},
|
||||
{
|
||||
"fieldname": "total_operating_cost",
|
||||
"fieldtype": "Currency",
|
||||
"label": "Total Operating Cost",
|
||||
"no_copy": 1,
|
||||
"options": "Company:company:default_currency",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"fieldname": "total_operating_cost",
|
||||
"fieldtype": "Currency",
|
||||
"label": "Total Operating Cost",
|
||||
"no_copy": 1,
|
||||
"options": "Company:company:default_currency",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"read_only": 1
|
||||
},
|
||||
},
|
||||
{
|
||||
"fieldname": "more_info",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "More Info",
|
||||
"options": "icon-file-text",
|
||||
"permlevel": 0,
|
||||
"fieldname": "more_info",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "More Info",
|
||||
"options": "icon-file-text",
|
||||
"permlevel": 0,
|
||||
"read_only": 0
|
||||
},
|
||||
},
|
||||
{
|
||||
"fieldname": "description",
|
||||
"fieldtype": "Small Text",
|
||||
"label": "Item Description",
|
||||
"permlevel": 0,
|
||||
"fieldname": "description",
|
||||
"fieldtype": "Small Text",
|
||||
"label": "Item Description",
|
||||
"permlevel": 0,
|
||||
"read_only": 1
|
||||
},
|
||||
},
|
||||
{
|
||||
"depends_on": "",
|
||||
"fieldname": "stock_uom",
|
||||
"fieldtype": "Link",
|
||||
"label": "Stock UOM",
|
||||
"oldfieldname": "stock_uom",
|
||||
"oldfieldtype": "Data",
|
||||
"options": "UOM",
|
||||
"permlevel": 0,
|
||||
"depends_on": "",
|
||||
"fieldname": "stock_uom",
|
||||
"fieldtype": "Link",
|
||||
"label": "Stock UOM",
|
||||
"oldfieldname": "stock_uom",
|
||||
"oldfieldtype": "Data",
|
||||
"options": "UOM",
|
||||
"permlevel": 0,
|
||||
"read_only": 1
|
||||
},
|
||||
},
|
||||
{
|
||||
"fieldname": "column_break2",
|
||||
"fieldtype": "Column Break",
|
||||
"permlevel": 0,
|
||||
"read_only": 0,
|
||||
"fieldname": "column_break2",
|
||||
"fieldtype": "Column Break",
|
||||
"permlevel": 0,
|
||||
"read_only": 0,
|
||||
"width": "50%"
|
||||
},
|
||||
},
|
||||
{
|
||||
"fieldname": "project_name",
|
||||
"fieldtype": "Link",
|
||||
"in_filter": 1,
|
||||
"label": "Project Name",
|
||||
"oldfieldname": "project_name",
|
||||
"oldfieldtype": "Link",
|
||||
"options": "Project",
|
||||
"permlevel": 0,
|
||||
"fieldname": "project_name",
|
||||
"fieldtype": "Link",
|
||||
"in_filter": 1,
|
||||
"label": "Project Name",
|
||||
"oldfieldname": "project_name",
|
||||
"oldfieldtype": "Link",
|
||||
"options": "Project",
|
||||
"permlevel": 0,
|
||||
"read_only": 0
|
||||
},
|
||||
},
|
||||
{
|
||||
"description": "Manufacture against Sales Order",
|
||||
"fieldname": "sales_order",
|
||||
"fieldtype": "Link",
|
||||
"label": "Sales Order",
|
||||
"options": "Sales Order",
|
||||
"permlevel": 0,
|
||||
"description": "Manufacture against Sales Order",
|
||||
"fieldname": "sales_order",
|
||||
"fieldtype": "Link",
|
||||
"label": "Sales Order",
|
||||
"options": "Sales Order",
|
||||
"permlevel": 0,
|
||||
"read_only": 0
|
||||
},
|
||||
},
|
||||
{
|
||||
"fieldname": "company",
|
||||
"fieldtype": "Link",
|
||||
"label": "Company",
|
||||
"oldfieldname": "company",
|
||||
"oldfieldtype": "Link",
|
||||
"options": "Company",
|
||||
"permlevel": 0,
|
||||
"read_only": 0,
|
||||
"fieldname": "company",
|
||||
"fieldtype": "Link",
|
||||
"label": "Company",
|
||||
"oldfieldname": "company",
|
||||
"oldfieldtype": "Link",
|
||||
"options": "Company",
|
||||
"permlevel": 0,
|
||||
"read_only": 0,
|
||||
"reqd": 1
|
||||
},
|
||||
},
|
||||
{
|
||||
"fieldname": "amended_from",
|
||||
"fieldtype": "Link",
|
||||
"ignore_user_permissions": 1,
|
||||
"label": "Amended From",
|
||||
"no_copy": 1,
|
||||
"oldfieldname": "amended_from",
|
||||
"oldfieldtype": "Data",
|
||||
"options": "Production Order",
|
||||
"permlevel": 0,
|
||||
"fieldname": "amended_from",
|
||||
"fieldtype": "Link",
|
||||
"ignore_user_permissions": 1,
|
||||
"label": "Amended From",
|
||||
"no_copy": 1,
|
||||
"oldfieldname": "amended_from",
|
||||
"oldfieldtype": "Data",
|
||||
"options": "Production Order",
|
||||
"permlevel": 0,
|
||||
"read_only": 1
|
||||
}
|
||||
],
|
||||
"icon": "icon-cogs",
|
||||
"idx": 1,
|
||||
"in_create": 0,
|
||||
"is_submittable": 1,
|
||||
"modified": "2015-02-26 04:03:28.164713",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Manufacturing",
|
||||
"name": "Production Order",
|
||||
"owner": "Administrator",
|
||||
],
|
||||
"icon": "icon-cogs",
|
||||
"idx": 1,
|
||||
"in_create": 0,
|
||||
"is_submittable": 1,
|
||||
"modified": "2015-03-05 13:03:28.164713",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Manufacturing",
|
||||
"name": "Production Order",
|
||||
"owner": "Administrator",
|
||||
"permissions": [
|
||||
{
|
||||
"amend": 1,
|
||||
"apply_user_permissions": 1,
|
||||
"cancel": 1,
|
||||
"create": 1,
|
||||
"delete": 1,
|
||||
"email": 1,
|
||||
"permlevel": 0,
|
||||
"print": 1,
|
||||
"read": 1,
|
||||
"report": 1,
|
||||
"role": "Manufacturing User",
|
||||
"share": 1,
|
||||
"submit": 1,
|
||||
"amend": 1,
|
||||
"apply_user_permissions": 1,
|
||||
"cancel": 1,
|
||||
"create": 1,
|
||||
"delete": 1,
|
||||
"email": 1,
|
||||
"permlevel": 0,
|
||||
"print": 1,
|
||||
"read": 1,
|
||||
"report": 1,
|
||||
"role": "Manufacturing User",
|
||||
"share": 1,
|
||||
"submit": 1,
|
||||
"write": 1
|
||||
},
|
||||
},
|
||||
{
|
||||
"apply_user_permissions": 1,
|
||||
"permlevel": 0,
|
||||
"read": 1,
|
||||
"report": 1,
|
||||
"apply_user_permissions": 1,
|
||||
"permlevel": 0,
|
||||
"read": 1,
|
||||
"report": 1,
|
||||
"role": "Material User"
|
||||
}
|
||||
],
|
||||
],
|
||||
"title_field": "production_item"
|
||||
}
|
||||
}
|
||||
|
@ -4,12 +4,11 @@
|
||||
from __future__ import unicode_literals
|
||||
import frappe, json
|
||||
|
||||
from frappe.utils import flt, nowdate, get_datetime, getdate, date_diff, time_diff_in_seconds
|
||||
from frappe.utils import flt, nowdate, get_datetime, getdate, date_diff
|
||||
from frappe import _
|
||||
from frappe.model.document import Document
|
||||
from erpnext.manufacturing.doctype.bom.bom import validate_bom_no
|
||||
from dateutil.relativedelta import relativedelta
|
||||
from dateutil.parser import parse
|
||||
|
||||
class OverProductionError(frappe.ValidationError): pass
|
||||
class StockOverProductionError(frappe.ValidationError): pass
|
||||
@ -64,7 +63,7 @@ class ProductionOrder(Document):
|
||||
def calculate_operating_cost(self):
|
||||
self.planned_operating_cost, self.actual_operating_cost = 0.0, 0.0
|
||||
for d in self.get("operations"):
|
||||
d.actual_operating_cost = flt(d.hour_rate) * flt(d.actual_operation_time) / 60
|
||||
d.actual_operating_cost = flt(d.hour_rate) * (flt(d.actual_operation_time) / 60.0)
|
||||
|
||||
self.planned_operating_cost += flt(d.planned_operating_cost)
|
||||
self.actual_operating_cost += flt(d.actual_operating_cost)
|
||||
@ -273,16 +272,8 @@ class ProductionOrder(Document):
|
||||
|
||||
def check_operation_fits_in_working_hours(self, d):
|
||||
"""Raises expection if operation is longer than working hours in the given workstation."""
|
||||
operation_length = time_diff_in_seconds(d.planned_end_time, d.planned_start_time)
|
||||
|
||||
workstation = frappe.get_doc("Workstation", d.workstation)
|
||||
for working_hour in workstation.working_hours:
|
||||
slot_length = (parse(working_hour.end_time) - parse(working_hour.start_time)).total_seconds()
|
||||
if slot_length >= operation_length:
|
||||
return
|
||||
|
||||
frappe.throw(_("Operation {0} longer than any available working hours in workstation {1}, break down the operation into multiple operations").format(d.operation, d.workstation),
|
||||
OperationTooLongError)
|
||||
from erpnext.manufacturing.doctype.workstation.workstation import check_if_within_operating_hours
|
||||
check_if_within_operating_hours(d.workstation, d.operation, d.planned_start_time, d.planned_end_time)
|
||||
|
||||
def update_operation_status(self):
|
||||
for d in self.get("operations"):
|
||||
@ -386,10 +377,11 @@ def make_time_log(name, operation, from_time, to_time, qty=None, project=None,
|
||||
time_log.production_order = name
|
||||
time_log.project = project
|
||||
time_log.operation_id = operation_id
|
||||
time_log.operation= operation
|
||||
time_log.operation = operation
|
||||
time_log.workstation= workstation
|
||||
time_log.activity_type= "Manufacturing"
|
||||
time_log.completed_qty = flt(qty)
|
||||
|
||||
if from_time and to_time :
|
||||
time_log.calculate_total_hours()
|
||||
return time_log
|
||||
|
@ -5,10 +5,11 @@
|
||||
from __future__ import unicode_literals
|
||||
import unittest
|
||||
import frappe
|
||||
from frappe.utils import flt, get_datetime
|
||||
from erpnext.stock.doctype.purchase_receipt.test_purchase_receipt import set_perpetual_inventory
|
||||
from erpnext.manufacturing.doctype.production_order.production_order import make_stock_entry
|
||||
from erpnext.stock.doctype.stock_entry import test_stock_entry
|
||||
from erpnext.projects.doctype.time_log.time_log import OverProductionError
|
||||
from erpnext.projects.doctype.time_log.time_log import OverProductionLoggedError
|
||||
|
||||
class TestProductionOrder(unittest.TestCase):
|
||||
def check_planned_qty(self):
|
||||
@ -27,7 +28,7 @@ class TestProductionOrder(unittest.TestCase):
|
||||
target="Stores - _TC", qty=100, incoming_rate=100)
|
||||
|
||||
# from stores to wip
|
||||
s = frappe.get_doc(make_stock_entry(pro_doc.name, "Material Transfer", 4))
|
||||
s = frappe.get_doc(make_stock_entry(pro_doc.name, "Material Transfer for Manufacture", 4))
|
||||
for d in s.get("items"):
|
||||
d.s_warehouse = "Stores - _TC"
|
||||
s.fiscal_year = "_Test Fiscal Year 2013"
|
||||
@ -45,6 +46,7 @@ class TestProductionOrder(unittest.TestCase):
|
||||
self.assertEqual(frappe.db.get_value("Production Order", pro_doc.name,
|
||||
"produced_qty"), 4)
|
||||
planned1 = frappe.db.get_value("Bin", {"item_code": "_Test FG Item", "warehouse": "_Test Warehouse 1 - _TC"}, "planned_qty")
|
||||
|
||||
self.assertEqual(planned1 - planned0, 6)
|
||||
|
||||
return pro_doc
|
||||
@ -66,38 +68,34 @@ class TestProductionOrder(unittest.TestCase):
|
||||
self.assertRaises(StockOverProductionError, s.submit)
|
||||
|
||||
def test_make_time_log(self):
|
||||
from erpnext.manufacturing.doctype.production_order.production_order import make_time_log
|
||||
from frappe.utils import cstr
|
||||
from frappe.utils import time_diff_in_hours
|
||||
|
||||
prod_order = frappe.get_doc({
|
||||
"doctype": "Production Order",
|
||||
"production_item": "_Test FG Item 2",
|
||||
"bom_no": "BOM/_Test FG Item 2/002",
|
||||
"qty": 1,
|
||||
"wip_warehouse": "_Test Warehouse - _TC",
|
||||
"fg_warehouse": "_Test Warehouse 1 - _TC"
|
||||
"fg_warehouse": "_Test Warehouse 1 - _TC",
|
||||
"company": "_Test Company",
|
||||
"planned_start_date": "2014-11-25 00:00:00"
|
||||
})
|
||||
|
||||
|
||||
prod_order.set_production_order_operations()
|
||||
prod_order.operations[0].update({
|
||||
"planned_start_time": "2014-11-25 00:00:00",
|
||||
"planned_end_time": "2014-11-25 10:00:00",
|
||||
"hour_rate": 10
|
||||
})
|
||||
|
||||
prod_order.insert()
|
||||
|
||||
prod_order.submit()
|
||||
d = prod_order.operations[0]
|
||||
|
||||
from erpnext.manufacturing.doctype.production_order.production_order import make_time_log
|
||||
from frappe.utils import cstr
|
||||
from frappe.utils import time_diff_in_hours
|
||||
d.completed_qty = flt(d.completed_qty)
|
||||
|
||||
prod_order.submit()
|
||||
|
||||
time_log = make_time_log( prod_order.name, cstr(d.idx) + ". " + d.operation, \
|
||||
d.planned_start_time, d.planned_end_time, prod_order.qty - d.qty_completed)
|
||||
time_log = make_time_log(prod_order.name, cstr(d.idx) + ". " + d.operation, \
|
||||
d.planned_start_time, d.planned_end_time, prod_order.qty - d.completed_qty,
|
||||
operation_id=d.name)
|
||||
|
||||
self.assertEqual(prod_order.name, time_log.production_order)
|
||||
self.assertEqual((prod_order.qty - d.qty_completed), time_log.qty)
|
||||
self.assertEqual((prod_order.qty - d.completed_qty), time_log.completed_qty)
|
||||
self.assertEqual(time_diff_in_hours(d.planned_end_time, d.planned_start_time),time_log.hours)
|
||||
|
||||
time_log.save()
|
||||
@ -105,7 +103,6 @@ class TestProductionOrder(unittest.TestCase):
|
||||
|
||||
manufacturing_settings = frappe.get_doc({
|
||||
"doctype": "Manufacturing Settings",
|
||||
"maximum_overtime": 30,
|
||||
"allow_production_on_holidays": 0
|
||||
})
|
||||
|
||||
@ -113,30 +110,30 @@ class TestProductionOrder(unittest.TestCase):
|
||||
|
||||
prod_order.load_from_db()
|
||||
self.assertEqual(prod_order.operations[0].status, "Completed")
|
||||
self.assertEqual(prod_order.operations[0].qty_completed, prod_order.qty)
|
||||
self.assertEqual(prod_order.operations[0].completed_qty, prod_order.qty)
|
||||
|
||||
self.assertEqual(prod_order.operations[0].actual_start_time, time_log.from_time)
|
||||
self.assertEqual(prod_order.operations[0].actual_end_time, time_log.to_time)
|
||||
self.assertEqual(get_datetime(prod_order.operations[0].actual_start_time), get_datetime(time_log.from_time))
|
||||
self.assertEqual(get_datetime(prod_order.operations[0].actual_end_time), get_datetime(time_log.to_time))
|
||||
|
||||
self.assertEqual(prod_order.operations[0].actual_operation_time, 600)
|
||||
self.assertEqual(prod_order.operations[0].actual_operating_cost, 6000)
|
||||
self.assertEqual(prod_order.operations[0].actual_operation_time, 60)
|
||||
self.assertEqual(prod_order.operations[0].actual_operating_cost, 100)
|
||||
|
||||
time_log.cancel()
|
||||
|
||||
prod_order.load_from_db()
|
||||
self.assertEqual(prod_order.operations[0].status, "Pending")
|
||||
self.assertEqual(prod_order.operations[0].qty_completed, 0)
|
||||
self.assertEqual(flt(prod_order.operations[0].completed_qty), 0)
|
||||
|
||||
self.assertEqual(prod_order.operations[0].actual_operation_time, 0)
|
||||
self.assertEqual(prod_order.operations[0].actual_operating_cost, 0)
|
||||
self.assertEqual(flt(prod_order.operations[0].actual_operation_time), 0)
|
||||
self.assertEqual(flt(prod_order.operations[0].actual_operating_cost), 0)
|
||||
|
||||
time_log2 = frappe.copy_doc(time_log)
|
||||
time_log2.update({
|
||||
"qty": 10,
|
||||
"completed_qty": 10,
|
||||
"from_time": "2014-11-26 00:00:00",
|
||||
"to_time": "2014-11-26 00:00:00",
|
||||
"docstatus": 0
|
||||
})
|
||||
self.assertRaises(OverProductionError, time_log2.save)
|
||||
self.assertRaises(OverProductionLoggedError, time_log2.save)
|
||||
|
||||
test_records = frappe.get_test_records('Production Order')
|
||||
|
@ -4,7 +4,10 @@
|
||||
"name": "_Test Workstation 1",
|
||||
"workstation_name": "_Test Workstation 1",
|
||||
"warehouse": "_Test warehouse - _TC",
|
||||
"hour_rate":100,
|
||||
"hour_rate_labour": 25,
|
||||
"hour_rate_electricity": 25,
|
||||
"hour_rate_consumable": 25,
|
||||
"hour_rate_rent": 25,
|
||||
"holiday_list": "_Test Holiday List",
|
||||
"working_hours": [
|
||||
{
|
||||
|
@ -4,6 +4,7 @@ from __future__ import unicode_literals
|
||||
|
||||
import frappe
|
||||
import unittest
|
||||
from .workstation import check_if_within_operating_hours, NotInWorkingHoursError, WorkstationHolidayError
|
||||
|
||||
test_dependencies = ["Warehouse"]
|
||||
test_records = frappe.get_test_records('Workstation')
|
||||
@ -11,6 +12,11 @@ test_records = frappe.get_test_records('Workstation')
|
||||
class TestWorkstation(unittest.TestCase):
|
||||
|
||||
def test_validate_timings(self):
|
||||
wks = frappe.get_doc("Workstation", "_Test Workstation 1")
|
||||
self.assertEqual(1,wks.check_workstation_for_operation_time("2013-02-01 05:00:00", "2013-02-02 20:00:00"))
|
||||
self.assertEqual(None,wks.check_workstation_for_operation_time("2013-02-03 10:00:00", "2013-02-03 20:00:00"))
|
||||
check_if_within_operating_hours("_Test Workstation 1", "Operation 1", "2013-02-02 11:00:00", "2013-02-02 19:00:00")
|
||||
check_if_within_operating_hours("_Test Workstation 1", "Operation 1", "2013-02-02 10:00:00", "2013-02-02 20:00:00")
|
||||
self.assertRaises(NotInWorkingHoursError, check_if_within_operating_hours,
|
||||
"_Test Workstation 1", "Operation 1", "2013-02-02 05:00:00", "2013-02-02 20:00:00")
|
||||
self.assertRaises(NotInWorkingHoursError, check_if_within_operating_hours,
|
||||
"_Test Workstation 1", "Operation 1", "2013-02-02 05:00:00", "2013-02-02 20:00:00")
|
||||
self.assertRaises(WorkstationHolidayError, check_if_within_operating_hours,
|
||||
"_Test Workstation 1", "Operation 1", "2013-02-01 10:00:00", "2013-02-02 20:00:00")
|
||||
|
@ -4,29 +4,21 @@
|
||||
from __future__ import unicode_literals
|
||||
import frappe
|
||||
from frappe import _
|
||||
from frappe.utils import flt, cint, getdate, formatdate, comma_and, get_datetime
|
||||
|
||||
from frappe.utils import flt, cint, getdate, formatdate, comma_and, time_diff_in_seconds
|
||||
from frappe.model.document import Document
|
||||
from dateutil.parser import parse
|
||||
|
||||
class WorkstationHolidayError(frappe.ValidationError): pass
|
||||
class NotInWorkingHoursError(frappe.ValidationError): pass
|
||||
class OverlapError(frappe.ValidationError): pass
|
||||
|
||||
class Workstation(Document):
|
||||
def update_bom_operation(self):
|
||||
bom_list = frappe.db.sql("""select DISTINCT parent from `tabBOM Operation`
|
||||
where workstation = %s""", self.name)
|
||||
for bom_no in bom_list:
|
||||
frappe.db.sql("""update `tabBOM Operation` set hour_rate = %s
|
||||
where parent = %s and workstation = %s""",
|
||||
(self.hour_rate, bom_no[0], self.name))
|
||||
def validate(self):
|
||||
self.hour_rate = (flt(self.hour_rate_labour) + flt(self.hour_rate_electricity) +
|
||||
flt(self.hour_rate_consumable) + flt(self.hour_rate_rent))
|
||||
|
||||
def on_update(self):
|
||||
self.validate_overlap_for_operation_timings()
|
||||
|
||||
frappe.db.set(self, 'hour_rate', flt(self.hour_rate_labour) + flt(self.hour_rate_electricity) +
|
||||
flt(self.hour_rate_consumable) + flt(self.hour_rate_rent))
|
||||
|
||||
self.update_bom_operation()
|
||||
|
||||
def validate_overlap_for_operation_timings(self):
|
||||
@ -43,32 +35,35 @@ class Workstation(Document):
|
||||
if existing:
|
||||
frappe.throw(_("Row #{0}: Timings conflicts with row {1}").format(d.idx, comma_and(existing)), OverlapError)
|
||||
|
||||
def update_bom_operation(self):
|
||||
bom_list = frappe.db.sql("""select DISTINCT parent from `tabBOM Operation`
|
||||
where workstation = %s""", self.name)
|
||||
for bom_no in bom_list:
|
||||
frappe.db.sql("""update `tabBOM Operation` set hour_rate = %s
|
||||
where parent = %s and workstation = %s""",
|
||||
(self.hour_rate, bom_no[0], self.name))
|
||||
|
||||
@frappe.whitelist()
|
||||
def get_default_holiday_list():
|
||||
return frappe.db.get_value("Company", frappe.defaults.get_user_default("company"), "default_holiday_list")
|
||||
|
||||
def check_if_within_operating_hours(workstation, from_datetime, to_datetime):
|
||||
if not cint(frappe.db.get_value("Manufacturing Settings", None, "allow_overtime")):
|
||||
is_within_operating_hours(workstation, from_datetime, to_datetime)
|
||||
|
||||
def check_if_within_operating_hours(workstation, operation, from_datetime, to_datetime):
|
||||
if not cint(frappe.db.get_value("Manufacturing Settings", "None", "allow_production_on_holidays")):
|
||||
check_workstation_for_holiday(workstation, from_datetime, to_datetime)
|
||||
|
||||
def is_within_operating_hours(workstation, from_datetime, to_datetime):
|
||||
start_time = get_datetime(from_datetime).time()
|
||||
end_time = get_datetime(to_datetime).time()
|
||||
if not cint(frappe.db.get_value("Manufacturing Settings", None, "allow_overtime")):
|
||||
is_within_operating_hours(workstation, operation, from_datetime, to_datetime)
|
||||
|
||||
working_hours = frappe.db.sql_list("""select idx from `tabWorkstation Working Hour`
|
||||
where parent = %s
|
||||
and (
|
||||
(start_time between %s and %s) or
|
||||
(end_time between %s and %s) or
|
||||
(%s between start_time and end_time))
|
||||
""", (workstation, start_time, end_time, start_time, end_time, start_time))
|
||||
def is_within_operating_hours(workstation, operation, from_datetime, to_datetime):
|
||||
operation_length = time_diff_in_seconds(to_datetime, from_datetime)
|
||||
workstation = frappe.get_doc("Workstation", workstation)
|
||||
|
||||
if not working_hours:
|
||||
frappe.throw(_("Time Log timings outside workstation operating hours"), NotInWorkingHoursError)
|
||||
for working_hour in workstation.working_hours:
|
||||
slot_length = (parse(working_hour.end_time) - parse(working_hour.start_time)).total_seconds()
|
||||
if slot_length >= operation_length:
|
||||
return
|
||||
|
||||
frappe.throw(_("Operation {0} longer than any available working hours in workstation {1}, break down the operation into multiple operations").format(operation, workstation.name), NotInWorkingHoursError)
|
||||
|
||||
def check_workstation_for_holiday(workstation, from_datetime, to_datetime):
|
||||
holiday_list = frappe.db.get_value("Workstation", workstation, "holiday_list")
|
||||
|
@ -1,129 +1,129 @@
|
||||
{
|
||||
"allow_copy": 0,
|
||||
"allow_import": 0,
|
||||
"allow_rename": 0,
|
||||
"creation": "2014-12-24 14:46:40.678236",
|
||||
"custom": 0,
|
||||
"docstatus": 0,
|
||||
"doctype": "DocType",
|
||||
"document_type": "",
|
||||
"allow_copy": 0,
|
||||
"allow_import": 0,
|
||||
"allow_rename": 0,
|
||||
"creation": "2014-12-24 14:46:40.678236",
|
||||
"custom": 0,
|
||||
"docstatus": 0,
|
||||
"doctype": "DocType",
|
||||
"document_type": "",
|
||||
"fields": [
|
||||
{
|
||||
"allow_on_submit": 0,
|
||||
"fieldname": "start_time",
|
||||
"fieldtype": "Time",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"in_filter": 0,
|
||||
"in_list_view": 1,
|
||||
"label": "Start Time",
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"read_only": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"allow_on_submit": 0,
|
||||
"fieldname": "start_time",
|
||||
"fieldtype": "Time",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"in_filter": 0,
|
||||
"in_list_view": 1,
|
||||
"label": "Start Time",
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"read_only": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 1,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
},
|
||||
{
|
||||
"allow_on_submit": 0,
|
||||
"fieldname": "column_break_2",
|
||||
"fieldtype": "Column Break",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"in_filter": 0,
|
||||
"in_list_view": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"read_only": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"allow_on_submit": 0,
|
||||
"fieldname": "column_break_2",
|
||||
"fieldtype": "Column Break",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"in_filter": 0,
|
||||
"in_list_view": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"read_only": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
},
|
||||
{
|
||||
"allow_on_submit": 0,
|
||||
"fieldname": "end_time",
|
||||
"fieldtype": "Time",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"in_filter": 0,
|
||||
"in_list_view": 1,
|
||||
"label": "End Time",
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"read_only": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"allow_on_submit": 0,
|
||||
"fieldname": "end_time",
|
||||
"fieldtype": "Time",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"in_filter": 0,
|
||||
"in_list_view": 1,
|
||||
"label": "End Time",
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"read_only": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 1,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
},
|
||||
{
|
||||
"allow_on_submit": 0,
|
||||
"fieldname": "section_break_2",
|
||||
"fieldtype": "Column Break",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"in_filter": 0,
|
||||
"in_list_view": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"read_only": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"allow_on_submit": 0,
|
||||
"fieldname": "section_break_2",
|
||||
"fieldtype": "Column Break",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"in_filter": 0,
|
||||
"in_list_view": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"read_only": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
},
|
||||
{
|
||||
"allow_on_submit": 0,
|
||||
"default": "1",
|
||||
"fieldname": "enabled",
|
||||
"fieldtype": "Check",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"in_filter": 0,
|
||||
"in_list_view": 1,
|
||||
"label": "Enabled",
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"read_only": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"allow_on_submit": 0,
|
||||
"default": "1",
|
||||
"fieldname": "enabled",
|
||||
"fieldtype": "Check",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"in_filter": 0,
|
||||
"in_list_view": 1,
|
||||
"label": "Enabled",
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"read_only": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
}
|
||||
],
|
||||
"hide_heading": 0,
|
||||
"hide_toolbar": 0,
|
||||
"in_create": 0,
|
||||
"in_dialog": 0,
|
||||
"is_submittable": 0,
|
||||
"issingle": 0,
|
||||
"istable": 1,
|
||||
"modified": "2015-02-11 14:55:55.650726",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Manufacturing",
|
||||
"name": "Workstation Working Hour",
|
||||
"name_case": "",
|
||||
"owner": "Administrator",
|
||||
"permissions": [],
|
||||
"read_only": 0,
|
||||
"read_only_onload": 0,
|
||||
"sort_field": "modified",
|
||||
],
|
||||
"hide_heading": 0,
|
||||
"hide_toolbar": 0,
|
||||
"in_create": 0,
|
||||
"in_dialog": 0,
|
||||
"is_submittable": 0,
|
||||
"issingle": 0,
|
||||
"istable": 1,
|
||||
"modified": "2015-03-05 14:55:55.650726",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Manufacturing",
|
||||
"name": "Workstation Working Hour",
|
||||
"name_case": "",
|
||||
"owner": "Administrator",
|
||||
"permissions": [],
|
||||
"read_only": 0,
|
||||
"read_only_onload": 0,
|
||||
"sort_field": "modified",
|
||||
"sort_order": "DESC"
|
||||
}
|
||||
}
|
||||
|
@ -4,4 +4,5 @@ from __future__ import unicode_literals
|
||||
|
||||
|
||||
import frappe
|
||||
test_records = frappe.get_test_records('Project')
|
||||
test_records = frappe.get_test_records('Project')
|
||||
test_ignore = ["Task"]
|
||||
|
@ -5,5 +5,5 @@ from __future__ import unicode_literals
|
||||
|
||||
import frappe
|
||||
test_records = frappe.get_test_records('Task')
|
||||
|
||||
test_ignore = ["Customer"]
|
||||
test_dependencies = ["Project"]
|
||||
test_ignore = ["Customer"]
|
||||
|
@ -1,10 +1,12 @@
|
||||
[
|
||||
{
|
||||
"activity_type": "_Test Activity Type",
|
||||
"docstatus": 1,
|
||||
"doctype": "Time Log",
|
||||
"from_time": "2013-01-01 10:00:00.000000",
|
||||
"note": "_Test Note",
|
||||
"to_time": "2013-01-01 11:00:00.000000"
|
||||
"activity_type": "_Test Activity Type",
|
||||
"docstatus": 1,
|
||||
"doctype": "Time Log",
|
||||
"from_time": "2013-01-01 10:00:00.000000",
|
||||
"note": "_Test Note",
|
||||
"to_time": "2013-01-01 11:00:00.000000",
|
||||
"time_log_for": "Project",
|
||||
"project": "_Test Project"
|
||||
}
|
||||
]
|
||||
]
|
||||
|
@ -10,17 +10,22 @@ from erpnext.projects.doctype.time_log.time_log import OverlapError
|
||||
from erpnext.projects.doctype.time_log.time_log import NotSubmittedError
|
||||
|
||||
from erpnext.manufacturing.doctype.workstation.workstation import WorkstationHolidayError
|
||||
from erpnext.manufacturing.doctype.workstation.workstation import WorkstationIsClosedError
|
||||
from erpnext.manufacturing.doctype.workstation.workstation import NotInWorkingHoursError
|
||||
|
||||
from erpnext.projects.doctype.time_log_batch.test_time_log_batch import *
|
||||
|
||||
class TestTimeLog(unittest.TestCase):
|
||||
def test_duplication(self):
|
||||
frappe.db.sql("delete from `tabTime Log`")
|
||||
frappe.get_doc(frappe.copy_doc(test_records[0])).insert()
|
||||
|
||||
ts = frappe.get_doc(frappe.copy_doc(test_records[0]))
|
||||
self.assertRaises(OverlapError, ts.insert)
|
||||
tl1 = frappe.get_doc(frappe.copy_doc(test_records[0]))
|
||||
tl1.user = "test@example.com"
|
||||
tl1.insert()
|
||||
|
||||
tl2 = frappe.get_doc(frappe.copy_doc(test_records[0]))
|
||||
tl2.user = "test@example.com"
|
||||
|
||||
self.assertRaises(OverlapError, tl2.insert)
|
||||
|
||||
frappe.db.sql("delete from `tabTime Log`")
|
||||
|
||||
@ -42,7 +47,7 @@ class TestTimeLog(unittest.TestCase):
|
||||
|
||||
def test_time_log_on_holiday(self):
|
||||
prod_order = make_prod_order(self)
|
||||
|
||||
prod_order.set_production_order_operations()
|
||||
prod_order.save()
|
||||
prod_order.submit()
|
||||
|
||||
@ -50,7 +55,10 @@ class TestTimeLog(unittest.TestCase):
|
||||
"doctype": "Time Log",
|
||||
"time_log_for": "Manufacturing",
|
||||
"production_order": prod_order.name,
|
||||
"operation": prod_order.operations[0].operation,
|
||||
"operation_id": prod_order.operations[0].name,
|
||||
"qty": 1,
|
||||
"activity_type": "_Test Activity Type",
|
||||
"from_time": "2013-02-01 10:00:00",
|
||||
"to_time": "2013-02-01 20:00:00",
|
||||
"workstation": "_Test Workstation 1"
|
||||
@ -61,9 +69,9 @@ class TestTimeLog(unittest.TestCase):
|
||||
"from_time": "2013-02-02 09:00:00",
|
||||
"to_time": "2013-02-02 20:00:00"
|
||||
})
|
||||
self.assertRaises(WorkstationIsClosedError , time_log.save)
|
||||
self.assertRaises(NotInWorkingHoursError , time_log.save)
|
||||
|
||||
time_log.from_time= "2013-02-02 09:30:00"
|
||||
time_log.from_time= "2013-02-02 10:30:00"
|
||||
time_log.save()
|
||||
time_log.submit()
|
||||
time_log.cancel()
|
||||
@ -84,7 +92,7 @@ def make_prod_order(self):
|
||||
"bom_no": "BOM/_Test FG Item 2/002",
|
||||
"qty": 1,
|
||||
"wip_warehouse": "_Test Warehouse - _TC",
|
||||
"fg_warehouse": "_Test Warehouse 1 - _TC"
|
||||
"fg_warehouse": "_Test Warehouse 1 - _TC",
|
||||
})
|
||||
|
||||
test_records = frappe.get_test_records('Time Log')
|
||||
|
@ -1,283 +1,283 @@
|
||||
{
|
||||
"allow_import": 1,
|
||||
"autoname": "naming_series:",
|
||||
"creation": "2013-04-03 16:38:41",
|
||||
"description": "Log of Activities performed by users against Tasks that can be used for tracking time, billing.",
|
||||
"docstatus": 0,
|
||||
"doctype": "DocType",
|
||||
"document_type": "Master",
|
||||
"allow_import": 1,
|
||||
"autoname": "naming_series:",
|
||||
"creation": "2013-04-03 16:38:41",
|
||||
"description": "Log of Activities performed by users against Tasks that can be used for tracking time, billing.",
|
||||
"docstatus": 0,
|
||||
"doctype": "DocType",
|
||||
"document_type": "Master",
|
||||
"fields": [
|
||||
{
|
||||
"fieldname": "naming_series",
|
||||
"fieldtype": "Select",
|
||||
"label": "Series",
|
||||
"options": "TL-",
|
||||
"permlevel": 0,
|
||||
"read_only": 0,
|
||||
"fieldname": "naming_series",
|
||||
"fieldtype": "Select",
|
||||
"label": "Series",
|
||||
"options": "TL-",
|
||||
"permlevel": 0,
|
||||
"read_only": 0,
|
||||
"reqd": 1
|
||||
},
|
||||
},
|
||||
{
|
||||
"fieldname": "from_time",
|
||||
"fieldtype": "Datetime",
|
||||
"in_list_view": 0,
|
||||
"label": "From Time",
|
||||
"permlevel": 0,
|
||||
"read_only": 0,
|
||||
"fieldname": "from_time",
|
||||
"fieldtype": "Datetime",
|
||||
"in_list_view": 0,
|
||||
"label": "From Time",
|
||||
"permlevel": 0,
|
||||
"read_only": 0,
|
||||
"reqd": 1
|
||||
},
|
||||
},
|
||||
{
|
||||
"fieldname": "to_time",
|
||||
"fieldtype": "Datetime",
|
||||
"in_list_view": 0,
|
||||
"label": "To Time",
|
||||
"permlevel": 0,
|
||||
"read_only": 0,
|
||||
"fieldname": "to_time",
|
||||
"fieldtype": "Datetime",
|
||||
"in_list_view": 0,
|
||||
"label": "To Time",
|
||||
"permlevel": 0,
|
||||
"read_only": 0,
|
||||
"reqd": 1
|
||||
},
|
||||
},
|
||||
{
|
||||
"fieldname": "hours",
|
||||
"fieldtype": "Float",
|
||||
"in_list_view": 1,
|
||||
"label": "Hours",
|
||||
"permlevel": 0,
|
||||
"fieldname": "hours",
|
||||
"fieldtype": "Float",
|
||||
"in_list_view": 1,
|
||||
"label": "Hours",
|
||||
"permlevel": 0,
|
||||
"read_only": 0
|
||||
},
|
||||
},
|
||||
{
|
||||
"fieldname": "billable",
|
||||
"fieldtype": "Check",
|
||||
"in_list_view": 0,
|
||||
"label": "Billable",
|
||||
"permlevel": 0,
|
||||
"fieldname": "billable",
|
||||
"fieldtype": "Check",
|
||||
"in_list_view": 0,
|
||||
"label": "Billable",
|
||||
"permlevel": 0,
|
||||
"read_only": 0
|
||||
},
|
||||
},
|
||||
{
|
||||
"fieldname": "user",
|
||||
"fieldtype": "Link",
|
||||
"label": "User",
|
||||
"options": "User",
|
||||
"permlevel": 0,
|
||||
"fieldname": "user",
|
||||
"fieldtype": "Link",
|
||||
"label": "User",
|
||||
"options": "User",
|
||||
"permlevel": 0,
|
||||
"precision": ""
|
||||
},
|
||||
},
|
||||
{
|
||||
"fieldname": "column_break_3",
|
||||
"fieldtype": "Column Break",
|
||||
"permlevel": 0,
|
||||
"fieldname": "column_break_3",
|
||||
"fieldtype": "Column Break",
|
||||
"permlevel": 0,
|
||||
"read_only": 0
|
||||
},
|
||||
},
|
||||
{
|
||||
"fieldname": "status",
|
||||
"fieldtype": "Select",
|
||||
"in_list_view": 0,
|
||||
"label": "Status",
|
||||
"options": "Draft\nSubmitted\nBatched for Billing\nBilled\nCancelled",
|
||||
"permlevel": 0,
|
||||
"read_only": 1,
|
||||
"fieldname": "status",
|
||||
"fieldtype": "Select",
|
||||
"in_list_view": 0,
|
||||
"label": "Status",
|
||||
"options": "Draft\nSubmitted\nBatched for Billing\nBilled\nCancelled",
|
||||
"permlevel": 0,
|
||||
"read_only": 1,
|
||||
"reqd": 0
|
||||
},
|
||||
},
|
||||
{
|
||||
"default": "Project",
|
||||
"fieldname": "time_log_for",
|
||||
"fieldtype": "Select",
|
||||
"label": "Time Log For",
|
||||
"options": "\nProject\nManufacturing",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"read_only": 1,
|
||||
"default": "Project",
|
||||
"fieldname": "time_log_for",
|
||||
"fieldtype": "Select",
|
||||
"label": "Time Log For",
|
||||
"options": "Project\nManufacturing",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"read_only": 1,
|
||||
"reqd": 0
|
||||
},
|
||||
},
|
||||
{
|
||||
"depends_on": "",
|
||||
"fieldname": "activity_type",
|
||||
"fieldtype": "Link",
|
||||
"in_list_view": 0,
|
||||
"label": "Activity Type",
|
||||
"options": "Activity Type",
|
||||
"permlevel": 0,
|
||||
"read_only": 0,
|
||||
"depends_on": "",
|
||||
"fieldname": "activity_type",
|
||||
"fieldtype": "Link",
|
||||
"in_list_view": 0,
|
||||
"label": "Activity Type",
|
||||
"options": "Activity Type",
|
||||
"permlevel": 0,
|
||||
"read_only": 0,
|
||||
"reqd": 1
|
||||
},
|
||||
},
|
||||
{
|
||||
"depends_on": "eval:doc.time_log_for != 'Manufacturing'",
|
||||
"fieldname": "task",
|
||||
"fieldtype": "Link",
|
||||
"label": "Task",
|
||||
"options": "Task",
|
||||
"permlevel": 0,
|
||||
"depends_on": "eval:doc.time_log_for != 'Manufacturing'",
|
||||
"fieldname": "task",
|
||||
"fieldtype": "Link",
|
||||
"label": "Task",
|
||||
"options": "Task",
|
||||
"permlevel": 0,
|
||||
"read_only": 0
|
||||
},
|
||||
},
|
||||
{
|
||||
"depends_on": "eval:doc.time_log_for == 'Manufacturing'",
|
||||
"fieldname": "section_break_11",
|
||||
"fieldtype": "Section Break",
|
||||
"permlevel": 0,
|
||||
"depends_on": "eval:doc.time_log_for == 'Manufacturing'",
|
||||
"fieldname": "section_break_11",
|
||||
"fieldtype": "Section Break",
|
||||
"permlevel": 0,
|
||||
"precision": ""
|
||||
},
|
||||
},
|
||||
{
|
||||
"depends_on": "eval:doc.time_log_for == 'Manufacturing'",
|
||||
"fieldname": "production_order",
|
||||
"fieldtype": "Link",
|
||||
"label": "Production Order",
|
||||
"options": "Production Order",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"depends_on": "eval:doc.time_log_for == 'Manufacturing'",
|
||||
"fieldname": "production_order",
|
||||
"fieldtype": "Link",
|
||||
"label": "Production Order",
|
||||
"options": "Production Order",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"read_only": 1
|
||||
},
|
||||
},
|
||||
{
|
||||
"depends_on": "eval:doc.time_log_for == 'Manufacturing'",
|
||||
"fieldname": "operation",
|
||||
"fieldtype": "Select",
|
||||
"label": "Operation",
|
||||
"options": "",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"depends_on": "eval:doc.time_log_for == 'Manufacturing'",
|
||||
"fieldname": "operation",
|
||||
"fieldtype": "Select",
|
||||
"label": "Operation",
|
||||
"options": "",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"read_only": 1
|
||||
},
|
||||
},
|
||||
{
|
||||
"fieldname": "operation_id",
|
||||
"fieldtype": "Data",
|
||||
"label": "Operation ID",
|
||||
"options": "",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"fieldname": "operation_id",
|
||||
"fieldtype": "Data",
|
||||
"label": "Operation ID",
|
||||
"options": "",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"read_only": 1
|
||||
},
|
||||
},
|
||||
{
|
||||
"fieldname": "column_break_14",
|
||||
"fieldtype": "Column Break",
|
||||
"permlevel": 0,
|
||||
"fieldname": "column_break_14",
|
||||
"fieldtype": "Column Break",
|
||||
"permlevel": 0,
|
||||
"precision": ""
|
||||
},
|
||||
},
|
||||
{
|
||||
"depends_on": "eval:doc.time_log_for == 'Manufacturing'",
|
||||
"fieldname": "workstation",
|
||||
"fieldtype": "Link",
|
||||
"label": "Workstation",
|
||||
"options": "Workstation",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"depends_on": "eval:doc.time_log_for == 'Manufacturing'",
|
||||
"fieldname": "workstation",
|
||||
"fieldtype": "Link",
|
||||
"label": "Workstation",
|
||||
"options": "Workstation",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"read_only": 1
|
||||
},
|
||||
},
|
||||
{
|
||||
"depends_on": "eval:doc.time_log_for == 'Manufacturing'",
|
||||
"description": "Operation completed for how many finished goods?",
|
||||
"fieldname": "completed_qty",
|
||||
"fieldtype": "Float",
|
||||
"label": "Completed Qty",
|
||||
"permlevel": 0,
|
||||
"depends_on": "eval:doc.time_log_for == 'Manufacturing'",
|
||||
"description": "Operation completed for how many finished goods?",
|
||||
"fieldname": "completed_qty",
|
||||
"fieldtype": "Float",
|
||||
"label": "Completed Qty",
|
||||
"permlevel": 0,
|
||||
"precision": ""
|
||||
},
|
||||
},
|
||||
{
|
||||
"fieldname": "section_break_7",
|
||||
"fieldtype": "Section Break",
|
||||
"permlevel": 0,
|
||||
"fieldname": "section_break_7",
|
||||
"fieldtype": "Section Break",
|
||||
"permlevel": 0,
|
||||
"read_only": 0
|
||||
},
|
||||
},
|
||||
{
|
||||
"fieldname": "note",
|
||||
"fieldtype": "Text Editor",
|
||||
"label": "Note",
|
||||
"permlevel": 0,
|
||||
"fieldname": "note",
|
||||
"fieldtype": "Text Editor",
|
||||
"label": "Note",
|
||||
"permlevel": 0,
|
||||
"read_only": 0
|
||||
},
|
||||
},
|
||||
{
|
||||
"fieldname": "section_break_9",
|
||||
"fieldtype": "Section Break",
|
||||
"permlevel": 0,
|
||||
"fieldname": "section_break_9",
|
||||
"fieldtype": "Section Break",
|
||||
"permlevel": 0,
|
||||
"read_only": 0
|
||||
},
|
||||
},
|
||||
{
|
||||
"depends_on": "eval:doc.time_log_for",
|
||||
"fieldname": "project",
|
||||
"fieldtype": "Link",
|
||||
"in_list_view": 1,
|
||||
"label": "Project",
|
||||
"options": "Project",
|
||||
"permlevel": 0,
|
||||
"depends_on": "eval:doc.time_log_for",
|
||||
"fieldname": "project",
|
||||
"fieldtype": "Link",
|
||||
"in_list_view": 1,
|
||||
"label": "Project",
|
||||
"options": "Project",
|
||||
"permlevel": 0,
|
||||
"read_only": 0
|
||||
},
|
||||
},
|
||||
{
|
||||
"description": "Will be updated when batched.",
|
||||
"fieldname": "time_log_batch",
|
||||
"fieldtype": "Link",
|
||||
"label": "Time Log Batch",
|
||||
"options": "Time Log Batch",
|
||||
"permlevel": 0,
|
||||
"description": "Will be updated when batched.",
|
||||
"fieldname": "time_log_batch",
|
||||
"fieldtype": "Link",
|
||||
"label": "Time Log Batch",
|
||||
"options": "Time Log Batch",
|
||||
"permlevel": 0,
|
||||
"read_only": 1
|
||||
},
|
||||
},
|
||||
{
|
||||
"description": "Will be updated when billed.",
|
||||
"fieldname": "sales_invoice",
|
||||
"fieldtype": "Link",
|
||||
"label": "Sales Invoice",
|
||||
"options": "Sales Invoice",
|
||||
"permlevel": 0,
|
||||
"description": "Will be updated when billed.",
|
||||
"fieldname": "sales_invoice",
|
||||
"fieldtype": "Link",
|
||||
"label": "Sales Invoice",
|
||||
"options": "Sales Invoice",
|
||||
"permlevel": 0,
|
||||
"read_only": 1
|
||||
},
|
||||
},
|
||||
{
|
||||
"fieldname": "column_break_16",
|
||||
"fieldtype": "Column Break",
|
||||
"permlevel": 0,
|
||||
"fieldname": "column_break_16",
|
||||
"fieldtype": "Column Break",
|
||||
"permlevel": 0,
|
||||
"read_only": 0
|
||||
},
|
||||
},
|
||||
{
|
||||
"fieldname": "amended_from",
|
||||
"fieldtype": "Link",
|
||||
"ignore_user_permissions": 1,
|
||||
"label": "Amended From",
|
||||
"no_copy": 1,
|
||||
"options": "Time Log",
|
||||
"permlevel": 1,
|
||||
"print_hide": 1,
|
||||
"fieldname": "amended_from",
|
||||
"fieldtype": "Link",
|
||||
"ignore_user_permissions": 1,
|
||||
"label": "Amended From",
|
||||
"no_copy": 1,
|
||||
"options": "Time Log",
|
||||
"permlevel": 1,
|
||||
"print_hide": 1,
|
||||
"read_only": 0
|
||||
},
|
||||
},
|
||||
{
|
||||
"fieldname": "title",
|
||||
"fieldtype": "Data",
|
||||
"hidden": 1,
|
||||
"label": "Title",
|
||||
"permlevel": 0,
|
||||
"fieldname": "title",
|
||||
"fieldtype": "Data",
|
||||
"hidden": 1,
|
||||
"label": "Title",
|
||||
"permlevel": 0,
|
||||
"precision": ""
|
||||
}
|
||||
],
|
||||
"icon": "icon-time",
|
||||
"idx": 1,
|
||||
"is_submittable": 1,
|
||||
"modified": "2015-02-26 02:22:10.312376",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Projects",
|
||||
"name": "Time Log",
|
||||
"owner": "Administrator",
|
||||
],
|
||||
"icon": "icon-time",
|
||||
"idx": 1,
|
||||
"is_submittable": 1,
|
||||
"modified": "2015-02-26 02:22:10.312376",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Projects",
|
||||
"name": "Time Log",
|
||||
"owner": "Administrator",
|
||||
"permissions": [
|
||||
{
|
||||
"amend": 1,
|
||||
"apply_user_permissions": 1,
|
||||
"cancel": 1,
|
||||
"create": 1,
|
||||
"delete": 1,
|
||||
"email": 1,
|
||||
"permlevel": 0,
|
||||
"print": 1,
|
||||
"read": 1,
|
||||
"report": 1,
|
||||
"role": "Projects User",
|
||||
"share": 1,
|
||||
"submit": 1,
|
||||
"amend": 1,
|
||||
"apply_user_permissions": 1,
|
||||
"cancel": 1,
|
||||
"create": 1,
|
||||
"delete": 1,
|
||||
"email": 1,
|
||||
"permlevel": 0,
|
||||
"print": 1,
|
||||
"read": 1,
|
||||
"report": 1,
|
||||
"role": "Projects User",
|
||||
"share": 1,
|
||||
"submit": 1,
|
||||
"write": 1
|
||||
},
|
||||
},
|
||||
{
|
||||
"amend": 1,
|
||||
"cancel": 1,
|
||||
"delete": 1,
|
||||
"email": 1,
|
||||
"permlevel": 0,
|
||||
"print": 1,
|
||||
"read": 1,
|
||||
"report": 1,
|
||||
"role": "Projects Manager",
|
||||
"share": 1,
|
||||
"submit": 1,
|
||||
"amend": 1,
|
||||
"cancel": 1,
|
||||
"delete": 1,
|
||||
"email": 1,
|
||||
"permlevel": 0,
|
||||
"print": 1,
|
||||
"read": 1,
|
||||
"report": 1,
|
||||
"role": "Projects Manager",
|
||||
"share": 1,
|
||||
"submit": 1,
|
||||
"write": 1
|
||||
}
|
||||
],
|
||||
],
|
||||
"title_field": "title"
|
||||
}
|
||||
}
|
||||
|
@ -9,7 +9,7 @@ from dateutil.relativedelta import relativedelta
|
||||
from dateutil.parser import parse
|
||||
|
||||
class OverlapError(frappe.ValidationError): pass
|
||||
class OverProductionError(frappe.ValidationError): pass
|
||||
class OverProductionLoggedError(frappe.ValidationError): pass
|
||||
class NotSubmittedError(frappe.ValidationError): pass
|
||||
|
||||
from frappe.model.document import Document
|
||||
@ -76,17 +76,22 @@ class TimeLog(Document):
|
||||
def get_overlap_for(self, fieldname):
|
||||
if not self.get(fieldname):
|
||||
return
|
||||
existing = frappe.db.sql("""select name, from_time, to_time from `tabTime Log` where `{0}`=%s and
|
||||
|
||||
existing = frappe.db.sql("""select name, from_time, to_time from `tabTime Log` where `{0}`=%(val)s and
|
||||
(
|
||||
(from_time between %s and %s) or
|
||||
(to_time between %s and %s) or
|
||||
(%s between from_time and to_time))
|
||||
and name!=%s
|
||||
and ifnull(task, "")=%s
|
||||
(from_time between %(from_time)s and %(to_time)s) or
|
||||
(to_time between %(from_time)s and %(to_time)s) or
|
||||
(%(from_time)s between from_time and to_time))
|
||||
and name!=%(name)s
|
||||
and ifnull(task, "")=%(task)s
|
||||
and docstatus < 2""".format(fieldname),
|
||||
(self.get(fieldname), self.from_time, self.to_time, self.from_time,
|
||||
self.to_time, self.from_time, self.name or "No Name",
|
||||
cstr(self.task)), as_dict=True)
|
||||
{
|
||||
"val": self.get(fieldname),
|
||||
"from_time": self.from_time,
|
||||
"to_time": self.to_time,
|
||||
"name": self.name or "No Name",
|
||||
"task": cstr(self.task)
|
||||
}, as_dict=True)
|
||||
|
||||
return existing[0] if existing else None
|
||||
|
||||
@ -107,7 +112,7 @@ class TimeLog(Document):
|
||||
"""Checks if **Time Log** is between operating hours of the **Workstation**."""
|
||||
if self.workstation:
|
||||
from erpnext.manufacturing.doctype.workstation.workstation import check_if_within_operating_hours
|
||||
check_if_within_operating_hours(self.workstation, self.from_time, self.to_time)
|
||||
check_if_within_operating_hours(self.workstation, self.operation, self.from_time, self.to_time)
|
||||
|
||||
def validate_production_order(self):
|
||||
"""Throws 'NotSubmittedError' if **production order** is not submitted. """
|
||||
@ -194,7 +199,14 @@ class TimeLog(Document):
|
||||
if not self.operation:
|
||||
frappe.throw(_("Operation is Mandatory"))
|
||||
if not self.completed_qty:
|
||||
self.completed_qty=0
|
||||
self.completed_qty = 0
|
||||
|
||||
production_order = frappe.get_doc("Production Order", self.production_order)
|
||||
pending_qty = flt(production_order.qty) - flt(production_order.produced_qty)
|
||||
if flt(self.completed_qty) > pending_qty:
|
||||
frappe.throw(_("Completed Qty cannot be more than {0} for operation {1}").format(pending_qty, self.operation),
|
||||
OverProductionLoggedError)
|
||||
|
||||
else:
|
||||
self.production_order = None
|
||||
self.operation = None
|
||||
|
@ -34,7 +34,8 @@ def create_time_log():
|
||||
time_log.update({
|
||||
"from_time": "2013-01-02 10:00:00.000000",
|
||||
"to_time": "2013-01-02 11:00:00.000000",
|
||||
"docstatus": 0
|
||||
"docstatus": 0,
|
||||
"time_log_for": "Project"
|
||||
})
|
||||
time_log.insert()
|
||||
time_log.submit()
|
||||
|
@ -469,7 +469,7 @@ class StockEntry(StockController):
|
||||
pro_doc = frappe.get_doc("Production Order", self.production_order)
|
||||
_validate_production_order(pro_doc)
|
||||
pro_doc.run_method("update_status")
|
||||
if self.purpose in ("Manufacture", "Material Transfer for Manufacture"):
|
||||
if self.purpose in "Manufacture":
|
||||
pro_doc.run_method("update_production_order_qty")
|
||||
self.update_planned_qty(pro_doc)
|
||||
|
||||
@ -543,7 +543,7 @@ class StockEntry(StockController):
|
||||
def get_items(self):
|
||||
if not self.fg_completed_qty or not self.bom_no:
|
||||
frappe.throw(_("BOM and Manufacturing Quantity are required"))
|
||||
|
||||
|
||||
self.set('items', [])
|
||||
self.validate_production_order()
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user