Merge branch 'develop' into invoiced_items_gross_margin_api_develop

This commit is contained in:
Saurabh 2019-05-09 12:06:12 +05:30 committed by GitHub
commit 2b6b504f30
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
24 changed files with 556 additions and 972 deletions

View File

@ -369,7 +369,9 @@ def make_purchase_receipt(source_name, target_doc=None):
"field_map": { "field_map": {
"name": "purchase_order_item", "name": "purchase_order_item",
"parent": "purchase_order", "parent": "purchase_order",
"bom": "bom" "bom": "bom",
"material_request": "material_request",
"material_request_item": "material_request_item"
}, },
"postprocess": update_item, "postprocess": update_item,
"condition": lambda doc: abs(doc.received_qty) < abs(doc.qty) and doc.delivered_by_supplier!=1 "condition": lambda doc: abs(doc.received_qty) < abs(doc.qty) and doc.delivered_by_supplier!=1

View File

@ -124,16 +124,8 @@ def find_variant(template, args, variant_item_code=None):
conditions = " or ".join(conditions) conditions = " or ".join(conditions)
# use approximate match and shortlist possible variant matches from erpnext.portal.product_configurator.utils import get_item_codes_by_attributes
# it is approximate because we are matching using OR condition possible_variants = [i for i in get_item_codes_by_attributes(args, template) if i != variant_item_code]
# and it need not be exact match at this stage
# this uses a simpler query instead of using multiple exists conditions
possible_variants = frappe.db.sql_list("""select name from `tabItem` item
where variant_of=%s and exists (
select name from `tabItem Variant Attribute` iv_attribute
where iv_attribute.parent=item.name
and ({conditions}) and parent != %s
)""".format(conditions=conditions), (template, cstr(variant_item_code)))
for variant in possible_variants: for variant in possible_variants:
variant = frappe.get_doc("Item", variant) variant = frappe.get_doc("Item", variant)
@ -317,7 +309,7 @@ def make_variant_item_code(template_item_code, template_item_name, variant):
}, as_dict=True) }, as_dict=True)
if not item_attribute: if not item_attribute:
return continue
# frappe.throw(_('Invalid attribute {0} {1}').format(frappe.bold(attr.attribute), # frappe.throw(_('Invalid attribute {0} {1}').format(frappe.bold(attr.attribute),
# frappe.bold(attr.attribute_value)), title=_('Invalid Attribute'), # frappe.bold(attr.attribute_value)), title=_('Invalid Attribute'),
# exc=InvalidItemAttributeValueError) # exc=InvalidItemAttributeValueError)

View File

@ -96,7 +96,9 @@ status_map = {
["Partially Ordered", "eval:self.status != 'Stopped' and self.per_ordered < 100 and self.per_ordered > 0 and self.docstatus == 1"], ["Partially Ordered", "eval:self.status != 'Stopped' and self.per_ordered < 100 and self.per_ordered > 0 and self.docstatus == 1"],
["Ordered", "eval:self.status != 'Stopped' and self.per_ordered == 100 and self.docstatus == 1 and self.material_request_type == 'Purchase'"], ["Ordered", "eval:self.status != 'Stopped' and self.per_ordered == 100 and self.docstatus == 1 and self.material_request_type == 'Purchase'"],
["Transferred", "eval:self.status != 'Stopped' and self.per_ordered == 100 and self.docstatus == 1 and self.material_request_type == 'Material Transfer'"], ["Transferred", "eval:self.status != 'Stopped' and self.per_ordered == 100 and self.docstatus == 1 and self.material_request_type == 'Material Transfer'"],
["Issued", "eval:self.status != 'Stopped' and self.per_ordered == 100 and self.docstatus == 1 and self.material_request_type == 'Material Issue'"] ["Issued", "eval:self.status != 'Stopped' and self.per_ordered == 100 and self.docstatus == 1 and self.material_request_type == 'Material Issue'"],
["Received", "eval:self.status != 'Stopped' and self.per_received == 100 and self.docstatus == 1 and self.material_request_type == 'Purchase'"],
["Partially Received", "eval:self.status != 'Stopped' and self.per_received > 0 and self.per_received < 100 and self.docstatus == 1 and self.material_request_type == 'Purchase'"]
] ]
} }

View File

@ -4,5 +4,18 @@
frappe.ui.form.on('HR Settings', { frappe.ui.form.on('HR Settings', {
refresh: function(frm) { refresh: function(frm) {
},
encrypt_salary_slips_in_emails: function(frm) {
let encrypt_state = frm.doc.encrypt_salary_slips_in_emails;
frm.set_df_property('password_policy', 'reqd', encrypt_state);
},
validate: function(frm) {
let policy = frm.doc.password_policy;
if (policy.includes(' ') || policy.includes('--')) {
frappe.msgprint("Password policy cannot contain spaces or simultaneous hyphens. The format will be restructured automatically");
}
frm.set_value('password_policy', policy.split(new RegExp(" |-", 'g')).filter((token) => token).join('-'));
} }
}); });

View File

@ -1,5 +1,6 @@
{ {
"allow_copy": 0, "allow_copy": 0,
"allow_events_in_timeline": 0,
"allow_guest_to_view": 0, "allow_guest_to_view": 0,
"allow_import": 0, "allow_import": 0,
"allow_rename": 0, "allow_rename": 0,
@ -13,10 +14,12 @@
"fields": [ "fields": [
{ {
"allow_bulk_edit": 0, "allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0, "allow_on_submit": 0,
"bold": 0, "bold": 0,
"collapsible": 0, "collapsible": 0,
"columns": 0, "columns": 0,
"fetch_if_empty": 0,
"fieldname": "employee_settings", "fieldname": "employee_settings",
"fieldtype": "Section Break", "fieldtype": "Section Break",
"hidden": 0, "hidden": 0,
@ -43,12 +46,14 @@
}, },
{ {
"allow_bulk_edit": 0, "allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0, "allow_on_submit": 0,
"bold": 0, "bold": 0,
"collapsible": 0, "collapsible": 0,
"columns": 0, "columns": 0,
"default": "", "default": "",
"description": "Enter retirement age in years", "description": "Enter retirement age in years",
"fetch_if_empty": 0,
"fieldname": "retirement_age", "fieldname": "retirement_age",
"fieldtype": "Data", "fieldtype": "Data",
"hidden": 0, "hidden": 0,
@ -76,12 +81,14 @@
}, },
{ {
"allow_bulk_edit": 0, "allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0, "allow_on_submit": 0,
"bold": 0, "bold": 0,
"collapsible": 0, "collapsible": 0,
"columns": 0, "columns": 0,
"default": "Naming Series", "default": "Naming Series",
"description": "Employee record is created using selected field. ", "description": "Employee record is created using selected field. ",
"fetch_if_empty": 0,
"fieldname": "emp_created_by", "fieldname": "emp_created_by",
"fieldtype": "Select", "fieldtype": "Select",
"hidden": 0, "hidden": 0,
@ -109,11 +116,13 @@
}, },
{ {
"allow_bulk_edit": 0, "allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0, "allow_on_submit": 0,
"bold": 0, "bold": 0,
"collapsible": 0, "collapsible": 0,
"columns": 0, "columns": 0,
"default": "", "default": "",
"fetch_if_empty": 0,
"fieldname": "leave_approval_notification_template", "fieldname": "leave_approval_notification_template",
"fieldtype": "Link", "fieldtype": "Link",
"hidden": 0, "hidden": 0,
@ -142,10 +151,12 @@
}, },
{ {
"allow_bulk_edit": 0, "allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0, "allow_on_submit": 0,
"bold": 0, "bold": 0,
"collapsible": 0, "collapsible": 0,
"columns": 0, "columns": 0,
"fetch_if_empty": 0,
"fieldname": "leave_status_notification_template", "fieldname": "leave_status_notification_template",
"fieldtype": "Link", "fieldtype": "Link",
"hidden": 0, "hidden": 0,
@ -174,10 +185,12 @@
}, },
{ {
"allow_bulk_edit": 0, "allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0, "allow_on_submit": 0,
"bold": 0, "bold": 0,
"collapsible": 0, "collapsible": 0,
"columns": 0, "columns": 0,
"fetch_if_empty": 0,
"fieldname": "column_break_4", "fieldname": "column_break_4",
"fieldtype": "Column Break", "fieldtype": "Column Break",
"hidden": 0, "hidden": 0,
@ -204,11 +217,13 @@
}, },
{ {
"allow_bulk_edit": 0, "allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0, "allow_on_submit": 0,
"bold": 0, "bold": 0,
"collapsible": 0, "collapsible": 0,
"columns": 0, "columns": 0,
"description": "Don't send Employee Birthday Reminders", "description": "Don't send Employee Birthday Reminders",
"fetch_if_empty": 0,
"fieldname": "stop_birthday_reminders", "fieldname": "stop_birthday_reminders",
"fieldtype": "Check", "fieldtype": "Check",
"hidden": 0, "hidden": 0,
@ -235,10 +250,12 @@
}, },
{ {
"allow_bulk_edit": 0, "allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0, "allow_on_submit": 0,
"bold": 0, "bold": 0,
"collapsible": 0, "collapsible": 0,
"columns": 0, "columns": 0,
"fetch_if_empty": 0,
"fieldname": "maintain_bill_work_hours_same", "fieldname": "maintain_bill_work_hours_same",
"fieldtype": "Check", "fieldtype": "Check",
"hidden": 0, "hidden": 0,
@ -266,11 +283,13 @@
}, },
{ {
"allow_bulk_edit": 0, "allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0, "allow_on_submit": 0,
"bold": 0, "bold": 0,
"collapsible": 0, "collapsible": 0,
"columns": 0, "columns": 0,
"default": "1", "default": "1",
"fetch_if_empty": 0,
"fieldname": "leave_approver_mandatory_in_leave_application", "fieldname": "leave_approver_mandatory_in_leave_application",
"fieldtype": "Check", "fieldtype": "Check",
"hidden": 0, "hidden": 0,
@ -298,11 +317,13 @@
}, },
{ {
"allow_bulk_edit": 0, "allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0, "allow_on_submit": 0,
"bold": 0, "bold": 0,
"collapsible": 0, "collapsible": 0,
"columns": 0, "columns": 0,
"default": "1", "default": "1",
"fetch_if_empty": 0,
"fieldname": "expense_approver_mandatory_in_expense_claim", "fieldname": "expense_approver_mandatory_in_expense_claim",
"fieldtype": "Check", "fieldtype": "Check",
"hidden": 0, "hidden": 0,
@ -330,10 +351,13 @@
}, },
{ {
"allow_bulk_edit": 0, "allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0, "allow_on_submit": 0,
"bold": 0, "bold": 0,
"collapsible": 0, "collapsible": 0,
"columns": 0, "columns": 0,
"depends_on": "",
"fetch_if_empty": 0,
"fieldname": "payroll_settings", "fieldname": "payroll_settings",
"fieldtype": "Section Break", "fieldtype": "Section Break",
"hidden": 0, "hidden": 0,
@ -360,11 +384,13 @@
}, },
{ {
"allow_bulk_edit": 0, "allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0, "allow_on_submit": 0,
"bold": 0, "bold": 0,
"collapsible": 0, "collapsible": 0,
"columns": 0, "columns": 0,
"description": "If checked, Total no. of Working Days will include holidays, and this will reduce the value of Salary Per Day", "description": "If checked, Total no. of Working Days will include holidays, and this will reduce the value of Salary Per Day",
"fetch_if_empty": 0,
"fieldname": "include_holidays_in_total_working_days", "fieldname": "include_holidays_in_total_working_days",
"fieldtype": "Check", "fieldtype": "Check",
"hidden": 0, "hidden": 0,
@ -391,12 +417,14 @@
}, },
{ {
"allow_bulk_edit": 0, "allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0, "allow_on_submit": 0,
"bold": 0, "bold": 0,
"collapsible": 0, "collapsible": 0,
"columns": 0, "columns": 0,
"default": "1", "default": "1",
"description": "Emails salary slip to employee based on preferred email selected in Employee", "description": "Emails salary slip to employee based on preferred email selected in Employee",
"fetch_if_empty": 0,
"fieldname": "email_salary_slip_to_employee", "fieldname": "email_salary_slip_to_employee",
"fieldtype": "Check", "fieldtype": "Check",
"hidden": 0, "hidden": 0,
@ -424,10 +452,82 @@
}, },
{ {
"allow_bulk_edit": 0, "allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0, "allow_on_submit": 0,
"bold": 0, "bold": 0,
"collapsible": 0, "collapsible": 0,
"columns": 0, "columns": 0,
"depends_on": "eval: doc.email_salary_slip_to_employee == 1;",
"description": "The salary slip emailed to the employee will be password protected, the password will be generated based on the password policy.",
"fetch_if_empty": 0,
"fieldname": "encrypt_salary_slips_in_emails",
"fieldtype": "Check",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Encrypt Salary Slips in Emails",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"depends_on": "eval: doc.encrypt_salary_slips_in_emails == 1",
"description": "<b>Example:</b> SAL-{first_name}-{date_of_birth.year} <br>This will generate a password like SAL-Jane-1972",
"fetch_if_empty": 0,
"fieldname": "password_policy",
"fieldtype": "Data",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 1,
"in_standard_filter": 0,
"label": "Password Policy",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "max_working_hours_against_timesheet", "fieldname": "max_working_hours_against_timesheet",
"fieldtype": "Float", "fieldtype": "Float",
"hidden": 0, "hidden": 0,
@ -455,10 +555,12 @@
}, },
{ {
"allow_bulk_edit": 0, "allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0, "allow_on_submit": 0,
"bold": 0, "bold": 0,
"collapsible": 0, "collapsible": 0,
"columns": 0, "columns": 0,
"fetch_if_empty": 0,
"fieldname": "leave_settings", "fieldname": "leave_settings",
"fieldtype": "Section Break", "fieldtype": "Section Break",
"hidden": 0, "hidden": 0,
@ -481,14 +583,17 @@
"reqd": 0, "reqd": 0,
"search_index": 0, "search_index": 0,
"set_only_once": 0, "set_only_once": 0,
"translatable": 0,
"unique": 0 "unique": 0
}, },
{ {
"allow_bulk_edit": 0, "allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0, "allow_on_submit": 0,
"bold": 0, "bold": 0,
"collapsible": 0, "collapsible": 0,
"columns": 0, "columns": 0,
"fetch_if_empty": 0,
"fieldname": "show_leaves_of_all_department_members_in_calendar", "fieldname": "show_leaves_of_all_department_members_in_calendar",
"fieldtype": "Check", "fieldtype": "Check",
"hidden": 0, "hidden": 0,
@ -511,22 +616,21 @@
"reqd": 0, "reqd": 0,
"search_index": 0, "search_index": 0,
"set_only_once": 0, "set_only_once": 0,
"translatable": 0,
"unique": 0 "unique": 0
} }
], ],
"has_web_view": 0, "has_web_view": 0,
"hide_heading": 0,
"hide_toolbar": 0, "hide_toolbar": 0,
"icon": "fa fa-cog", "icon": "fa fa-cog",
"idx": 1, "idx": 1,
"image_view": 0,
"in_create": 0, "in_create": 0,
"is_submittable": 0, "is_submittable": 0,
"issingle": 1, "issingle": 1,
"istable": 0, "istable": 0,
"max_attachments": 0, "max_attachments": 0,
"modified": "2018-05-03 15:36:13.015466", "modified": "2019-04-25 15:08:12.983571",
"modified_by": "Administrator", "modified_by": "shivam@example.com",
"module": "HR", "module": "HR",
"name": "HR Settings", "name": "HR Settings",
"owner": "Administrator", "owner": "Administrator",
@ -553,9 +657,9 @@
], ],
"quick_entry": 0, "quick_entry": 0,
"read_only": 0, "read_only": 0,
"read_only_onload": 0,
"show_name_in_global_search": 0, "show_name_in_global_search": 0,
"sort_order": "ASC", "sort_order": "ASC",
"track_changes": 0, "track_changes": 0,
"track_seen": 0 "track_seen": 0,
"track_views": 0
} }

View File

@ -5,11 +5,21 @@
from __future__ import unicode_literals from __future__ import unicode_literals
import frappe import frappe
from frappe import _
from frappe.model.document import Document from frappe.model.document import Document
class HRSettings(Document): class HRSettings(Document):
def validate(self): def validate(self):
self.set_naming_series()
self.validate_password_policy()
def set_naming_series(self):
from erpnext.setup.doctype.naming_series.naming_series import set_by_naming_series from erpnext.setup.doctype.naming_series.naming_series import set_by_naming_series
set_by_naming_series("Employee", "employee_number", set_by_naming_series("Employee", "employee_number",
self.get("emp_created_by")=="Naming Series", hide_name_field=True) self.get("emp_created_by")=="Naming Series", hide_name_field=True)
def validate_password_policy(self):
if self.email_salary_slip_to_employee and self.encrypt_salary_slips_in_emails:
if not self.password_policy:
frappe.throw(_("Password policy for Salary Slips is not set"))

View File

@ -520,13 +520,20 @@ class SalarySlip(TransactionBase):
def email_salary_slip(self): def email_salary_slip(self):
receiver = frappe.db.get_value("Employee", self.employee, "prefered_email") receiver = frappe.db.get_value("Employee", self.employee, "prefered_email")
hr_settings = frappe.get_single("HR Settings")
message = "Please see attachment"
password = None
if hr_settings.encrypt_salary_slips_in_emails:
password = generate_password_for_pdf(hr_settings.password_policy, self.employee)
message += """<br>Note: Your salary slip is password protected,
the password to unlock the PDF is of the format {0}. """.format(hr_settings.password_policy)
if receiver: if receiver:
email_args = { email_args = {
"recipients": [receiver], "recipients": [receiver],
"message": _("Please see attachment"), "message": _(message),
"subject": 'Salary Slip - from {0} to {1}'.format(self.start_date, self.end_date), "subject": 'Salary Slip - from {0} to {1}'.format(self.start_date, self.end_date),
"attachments": [frappe.attach_print(self.doctype, self.name, file_name=self.name)], "attachments": [frappe.attach_print(self.doctype, self.name, file_name=self.name, password=password)],
"reference_doctype": self.doctype, "reference_doctype": self.doctype,
"reference_name": self.name "reference_name": self.name
} }
@ -843,3 +850,7 @@ def unlink_ref_doc_from_salary_slip(ref_no):
for ss in linked_ss: for ss in linked_ss:
ss_doc = frappe.get_doc("Salary Slip", ss) ss_doc = frappe.get_doc("Salary Slip", ss)
frappe.db.set_value("Salary Slip", ss_doc.name, "journal_entry", "") frappe.db.set_value("Salary Slip", ss_doc.name, "journal_entry", "")
def generate_password_for_pdf(policy_template, employee):
employee = frappe.get_doc("Employee", employee)
return policy_template.format(**employee.as_dict())

View File

@ -0,0 +1,29 @@
{
"attach_print": 0,
"channel": "Email",
"condition": "doc.status == \"Received\" or doc.status == \"Partially Received\"",
"creation": "2019-04-29 11:53:23.981418",
"days_in_advance": 0,
"docstatus": 0,
"doctype": "Notification",
"document_type": "Material Request",
"enabled": 1,
"event": "Value Change",
"idx": 0,
"is_standard": 1,
"message": "<b>Material Request Type</b>: {{ doc.material_request_type }}<br>\n<b>Company</b>: {{ doc.company }}\n\n<h3>Order Summary</h3>\n\n<table border=2 >\n <tr align=\"center\">\n <th>Item Name</th>\n <th>Received Quantity</th>\n </tr>\n {% for item in doc.items %}\n {% if frappe.utils.flt(item.received_qty, 2) > 0.0 %}\n <tr align=\"center\">\n <td>{{ item.item_code }}</td>\n <td>{{ frappe.utils.flt(item.received_qty, 2) }}</td>\n </tr>\n {% endif %}\n {% endfor %}\n</table>",
"method": "",
"modified": "2019-05-01 18:02:51.090037",
"modified_by": "Administrator",
"module": "Manufacturing",
"name": "Material Request Receipt Notification",
"owner": "Administrator",
"recipients": [
{
"email_by_document_field": "requested_by"
}
],
"sender_email": "",
"subject": "{{ doc.name }} has been received",
"value_changed": "status"
}

View File

@ -0,0 +1,19 @@
<b>Material Request Type</b>: {{ doc.material_request_type }}<br>
<b>Company</b>: {{ doc.company }}
<h3>Order Summary</h3>
<table border=2 >
<tr align="center">
<th>Item Name</th>
<th>Received Quantity</th>
</tr>
{% for item in doc.items %}
{% if frappe.utils.flt(item.received_qty, 2) > 0.0 %}
<tr align="center">
<td>{{ item.item_code }}</td>
<td>{{ frappe.utils.flt(item.received_qty, 2) }}</td>
</tr>
{% endif %}
{% endfor %}
</table>

View File

@ -0,0 +1,7 @@
from __future__ import unicode_literals
import frappe
def get_context(context):
# do your magic here
pass

View File

@ -512,6 +512,7 @@ erpnext.patches.v11_0.rename_employee_loan_to_loan
erpnext.patches.v11_0.move_leave_approvers_from_employee #13-06-2018 erpnext.patches.v11_0.move_leave_approvers_from_employee #13-06-2018
erpnext.patches.v11_0.update_department_lft_rgt erpnext.patches.v11_0.update_department_lft_rgt
erpnext.patches.v11_0.add_default_email_template_for_leave erpnext.patches.v11_0.add_default_email_template_for_leave
execute:frappe.reload_doc("HR", "doctype", "HR Settings")
erpnext.patches.v11_0.set_default_email_template_in_hr #08-06-2018 erpnext.patches.v11_0.set_default_email_template_in_hr #08-06-2018
erpnext.patches.v11_0.uom_conversion_data #30-06-2018 erpnext.patches.v11_0.uom_conversion_data #30-06-2018
erpnext.patches.v10_0.taxes_issue_with_pos erpnext.patches.v10_0.taxes_issue_with_pos

View File

@ -2,7 +2,6 @@ from __future__ import unicode_literals
import frappe import frappe
def execute(): def execute():
hr_settings = frappe.get_single("HR Settings") hr_settings = frappe.get_single("HR Settings")
hr_settings.leave_approval_notification_template = "Leave Approval Notification" hr_settings.leave_approval_notification_template = "Leave Approval Notification"
hr_settings.leave_status_notification_template = "Leave Status Notification" hr_settings.leave_status_notification_template = "Leave Status Notification"

View File

@ -102,6 +102,9 @@ def get_item_codes_by_attributes(attribute_filters, template_item_code=None):
for attribute, values in attribute_filters.items(): for attribute, values in attribute_filters.items():
attribute_values = values attribute_values = values
if not isinstance(attribute_values, list):
attribute_values = [attribute_values]
if not attribute_values: continue if not attribute_values: continue
wheres = [] wheres = []

View File

@ -390,15 +390,6 @@ frappe.ui.form.ItemQuickEntryForm = frappe.ui.form.QuickEntryForm.extend({
} }
}) })
if (mandatory.length) {
frappe.msgprint({
title: __('Missing Values Required'),
message: __('Following fields have missing values:') + '<br><br><ul><li>' + mandatory.join('<li>') + '</ul>',
indicator: 'orange'
});
return {};
}
if (this.is_manufacturer) { if (this.is_manufacturer) {
$.each(this.manufacturer_fields, function(index, field) { $.each(this.manufacturer_fields, function(index, field) {
attribute[field.fieldname] = me.dialog.fields_dict[field.fieldname].input.value; attribute[field.fieldname] = me.dialog.fields_dict[field.fieldname].input.value;

View File

@ -585,7 +585,7 @@ $.extend(erpnext.item, {
"label": row.attribute, "label": row.attribute,
"fieldname": row.attribute, "fieldname": row.attribute,
"fieldtype": fieldtype, "fieldtype": fieldtype,
"reqd": 1, "reqd": 0,
"description": desc "description": desc
}) })
} }
@ -600,6 +600,7 @@ $.extend(erpnext.item, {
if(!args) return; if(!args) return;
frappe.call({ frappe.call({
method:"erpnext.controllers.item_variant.get_variant", method:"erpnext.controllers.item_variant.get_variant",
btn: d.get_primary_btn(),
args: { args: {
"template": frm.doc.name, "template": frm.doc.name,
"args": d.get_values() "args": d.get_values()

View File

@ -800,10 +800,12 @@ class Item(WebsiteGenerator):
def validate_variant_attributes(self): def validate_variant_attributes(self):
if self.is_new() and self.variant_of and self.variant_based_on == 'Item Attribute': if self.is_new() and self.variant_of and self.variant_based_on == 'Item Attribute':
# remove attributes with no attribute_value set
self.attributes = [d for d in self.attributes if cstr(d.attribute_value).strip()]
args = {} args = {}
for d in self.attributes: for i, d in enumerate(self.attributes):
if cstr(d.attribute_value).strip() == '': d.idx = i + 1
frappe.throw(_("Please specify Attribute Value for attribute {0}").format(d.attribute))
args[d.attribute] = d.attribute_value args[d.attribute] = d.attribute_value
variant = get_variant(self.variant_of, args, self.name) variant = get_variant(self.variant_of, args, self.name)

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +1,5 @@
frappe.listview_settings['Material Request'] = { frappe.listview_settings['Material Request'] = {
add_fields: ["material_request_type", "status", "per_ordered"], add_fields: ["material_request_type", "status", "per_ordered", "per_received"],
get_indicator: function(doc) { get_indicator: function(doc) {
if(doc.status=="Stopped") { if(doc.status=="Stopped") {
return [__("Stopped"), "red", "status,=,Stopped"]; return [__("Stopped"), "red", "status,=,Stopped"];
@ -8,7 +8,11 @@ frappe.listview_settings['Material Request'] = {
} else if(doc.docstatus==1 && flt(doc.per_ordered, 2) < 100) { } else if(doc.docstatus==1 && flt(doc.per_ordered, 2) < 100) {
return [__("Partially ordered"), "yellow", "per_ordered,<,100"]; return [__("Partially ordered"), "yellow", "per_ordered,<,100"];
} else if(doc.docstatus==1 && flt(doc.per_ordered, 2) == 100) { } else if(doc.docstatus==1 && flt(doc.per_ordered, 2) == 100) {
if (doc.material_request_type == "Purchase") { if (doc.material_request_type == "Purchase" && flt(doc.per_received, 2) < 100 && flt(doc.per_received, 2) > 0) {
return [__("Partially Received"), "yellow", "per_received,<,100"];
} else if (doc.material_request_type == "Purchase" && flt(doc.per_received, 2) == 100) {
return [__("Received"), "green", "per_received,=,100"];
} else if (doc.material_request_type == "Purchase") {
return [__("Ordered"), "green", "per_ordered,=,100"]; return [__("Ordered"), "green", "per_ordered,=,100"];
} else if (doc.material_request_type == "Material Transfer") { } else if (doc.material_request_type == "Material Transfer") {
return [__("Transfered"), "green", "per_ordered,=,100"]; return [__("Transfered"), "green", "per_ordered,=,100"];

View File

@ -38,6 +38,7 @@
"projected_qty", "projected_qty",
"actual_qty", "actual_qty",
"ordered_qty", "ordered_qty",
"received_qty",
"accounting_details", "accounting_details",
"expense_account", "expense_account",
"column_break_35", "column_break_35",
@ -364,11 +365,16 @@
{ {
"fieldname": "section_break_37", "fieldname": "section_break_37",
"fieldtype": "Section Break" "fieldtype": "Section Break"
},
{
"fieldname": "received_qty",
"fieldtype": "Data",
"label": "Received Quantity"
} }
], ],
"idx": 1, "idx": 1,
"istable": 1, "istable": 1,
"modified": "2019-05-01 17:48:12.361976", "modified": "2019-05-08 10:27:25.008801",
"modified_by": "Administrator", "modified_by": "Administrator",
"module": "Stock", "module": "Stock",
"name": "Material Request Item", "name": "Material Request Item",

View File

@ -35,6 +35,17 @@ class PurchaseReceipt(BuyingController):
'percent_join_field': 'purchase_order', 'percent_join_field': 'purchase_order',
'overflow_type': 'receipt' 'overflow_type': 'receipt'
}, },
{
'source_dt': 'Purchase Receipt Item',
'target_dt': 'Material Request Item',
'join_field': 'material_request_item',
'target_field': 'received_qty',
'target_parent_dt': 'Material Request',
'target_parent_field': 'per_received',
'target_ref_field': 'qty',
'source_field': 'qty',
'percent_join_field': 'material_request'
},
{ {
'source_dt': 'Purchase Receipt Item', 'source_dt': 'Purchase Receipt Item',
'target_dt': 'Purchase Order Item', 'target_dt': 'Purchase Order Item',

View File

@ -64,7 +64,9 @@
"rejected_warehouse", "rejected_warehouse",
"quality_inspection", "quality_inspection",
"purchase_order", "purchase_order",
"material_request",
"purchase_order_item", "purchase_order_item",
"material_request_item",
"column_break_40", "column_break_40",
"is_fixed_asset", "is_fixed_asset",
"asset", "asset",
@ -753,11 +755,22 @@
"fieldname": "image_section", "fieldname": "image_section",
"fieldtype": "Section Break", "fieldtype": "Section Break",
"label": "Image" "label": "Image"
},
{
"fieldname": "material_request",
"fieldtype": "Link",
"label": "Material Request",
"options": "Material Request"
},
{
"fieldname": "material_request_item",
"fieldtype": "Data",
"label": "Material Request Item"
} }
], ],
"idx": 1, "idx": 1,
"istable": 1, "istable": 1,
"modified": "2019-05-01 17:45:17.447900", "modified": "2019-05-08 10:25:27.157675",
"modified_by": "Administrator", "modified_by": "Administrator",
"module": "Stock", "module": "Stock",
"name": "Purchase Receipt Item", "name": "Purchase Receipt Item",

View File

@ -129,6 +129,10 @@ class StockEntry(StockController):
if self.purpose not in valid_purposes: if self.purpose not in valid_purposes:
frappe.throw(_("Purpose must be one of {0}").format(comma_or(valid_purposes))) frappe.throw(_("Purpose must be one of {0}").format(comma_or(valid_purposes)))
if self.job_card and self.purpose != 'Material Transfer for Manufacture':
frappe.throw(_("For job card {0}, you can only make the 'Material Transfer for Manufacture' type stock entry")
.format(self.job_card))
def set_transfer_qty(self): def set_transfer_qty(self):
for item in self.get("items"): for item in self.get("items"):
if not flt(item.qty): if not flt(item.qty):