Merge branch 'staging-fixes' into staging
This commit is contained in:
commit
961b7dee9d
@ -5,7 +5,7 @@ import frappe
|
|||||||
from erpnext.hooks import regional_overrides
|
from erpnext.hooks import regional_overrides
|
||||||
from frappe.utils import getdate
|
from frappe.utils import getdate
|
||||||
|
|
||||||
__version__ = '10.1.59'
|
__version__ = '10.1.60'
|
||||||
|
|
||||||
def get_default_company(user=None):
|
def get_default_company(user=None):
|
||||||
'''Get default company for user'''
|
'''Get default company for user'''
|
||||||
|
@ -123,7 +123,7 @@ class PaymentRequest(Document):
|
|||||||
"reference_doctype": "Payment Request",
|
"reference_doctype": "Payment Request",
|
||||||
"reference_docname": self.name,
|
"reference_docname": self.name,
|
||||||
"payer_email": self.email_to or frappe.session.user,
|
"payer_email": self.email_to or frappe.session.user,
|
||||||
"payer_name": data.customer_name,
|
"payer_name": frappe.safe_decode(data.customer_name),
|
||||||
"order_id": self.name,
|
"order_id": self.name,
|
||||||
"currency": self.currency
|
"currency": self.currency
|
||||||
})
|
})
|
||||||
|
@ -1,2 +0,0 @@
|
|||||||
// Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors
|
|
||||||
// For license information, please see license.txt
|
|
@ -1,129 +0,0 @@
|
|||||||
{
|
|
||||||
"allow_copy": 0,
|
|
||||||
"allow_guest_to_view": 0,
|
|
||||||
"allow_import": 0,
|
|
||||||
"allow_rename": 0,
|
|
||||||
"autoname": "field:subscriber_name",
|
|
||||||
"beta": 0,
|
|
||||||
"creation": "2018-02-24 11:17:46.809140",
|
|
||||||
"custom": 0,
|
|
||||||
"docstatus": 0,
|
|
||||||
"doctype": "DocType",
|
|
||||||
"document_type": "",
|
|
||||||
"editable_grid": 1,
|
|
||||||
"engine": "InnoDB",
|
|
||||||
"fields": [
|
|
||||||
{
|
|
||||||
"allow_bulk_edit": 0,
|
|
||||||
"allow_in_quick_entry": 0,
|
|
||||||
"allow_on_submit": 0,
|
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"fieldname": "customer",
|
|
||||||
"fieldtype": "Link",
|
|
||||||
"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": "Customer",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"options": "Customer",
|
|
||||||
"permlevel": 0,
|
|
||||||
"precision": "",
|
|
||||||
"print_hide": 0,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 0,
|
|
||||||
"remember_last_selected_value": 0,
|
|
||||||
"report_hide": 0,
|
|
||||||
"reqd": 1,
|
|
||||||
"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_from": "customer.customer_name",
|
|
||||||
"fieldname": "subscriber_name",
|
|
||||||
"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": "Subscriber Name",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"options": "",
|
|
||||||
"permlevel": 0,
|
|
||||||
"precision": "",
|
|
||||||
"print_hide": 0,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 0,
|
|
||||||
"remember_last_selected_value": 0,
|
|
||||||
"report_hide": 0,
|
|
||||||
"reqd": 1,
|
|
||||||
"search_index": 0,
|
|
||||||
"set_only_once": 0,
|
|
||||||
"translatable": 0,
|
|
||||||
"unique": 1
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"has_web_view": 0,
|
|
||||||
"hide_heading": 0,
|
|
||||||
"hide_toolbar": 0,
|
|
||||||
"idx": 0,
|
|
||||||
"image_view": 0,
|
|
||||||
"in_create": 0,
|
|
||||||
"is_submittable": 0,
|
|
||||||
"issingle": 0,
|
|
||||||
"istable": 0,
|
|
||||||
"max_attachments": 0,
|
|
||||||
"modified": "2018-07-11 15:13:30.056470",
|
|
||||||
"modified_by": "Administrator",
|
|
||||||
"module": "Accounts",
|
|
||||||
"name": "Subscriber",
|
|
||||||
"name_case": "",
|
|
||||||
"owner": "Administrator",
|
|
||||||
"permissions": [
|
|
||||||
{
|
|
||||||
"amend": 0,
|
|
||||||
"cancel": 0,
|
|
||||||
"create": 1,
|
|
||||||
"delete": 1,
|
|
||||||
"email": 1,
|
|
||||||
"export": 1,
|
|
||||||
"if_owner": 0,
|
|
||||||
"import": 0,
|
|
||||||
"permlevel": 0,
|
|
||||||
"print": 1,
|
|
||||||
"read": 1,
|
|
||||||
"report": 1,
|
|
||||||
"role": "System Manager",
|
|
||||||
"set_user_permissions": 0,
|
|
||||||
"share": 1,
|
|
||||||
"submit": 0,
|
|
||||||
"write": 1
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"quick_entry": 1,
|
|
||||||
"read_only": 0,
|
|
||||||
"read_only_onload": 0,
|
|
||||||
"show_name_in_global_search": 0,
|
|
||||||
"sort_field": "modified",
|
|
||||||
"sort_order": "DESC",
|
|
||||||
"track_changes": 1,
|
|
||||||
"track_seen": 0
|
|
||||||
}
|
|
@ -1,9 +0,0 @@
|
|||||||
# -*- coding: utf-8 -*-
|
|
||||||
# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors
|
|
||||||
# For license information, please see license.txt
|
|
||||||
|
|
||||||
from __future__ import unicode_literals
|
|
||||||
from frappe.model.document import Document
|
|
||||||
|
|
||||||
class Subscriber(Document):
|
|
||||||
pass
|
|
@ -1,14 +0,0 @@
|
|||||||
from frappe import _
|
|
||||||
|
|
||||||
def get_data():
|
|
||||||
return {
|
|
||||||
'heatmap': True,
|
|
||||||
'heatmap_message': _('This is based on transactions against this Subscriber. See timeline below for details'),
|
|
||||||
'fieldname': 'subscriber',
|
|
||||||
'transactions': [
|
|
||||||
{
|
|
||||||
'label': _('Subscriptions'),
|
|
||||||
'items': ['Subscription']
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
@ -1,23 +0,0 @@
|
|||||||
/* eslint-disable */
|
|
||||||
// rename this file from _test_[name] to test_[name] to activate
|
|
||||||
// and remove above this line
|
|
||||||
|
|
||||||
QUnit.test("test: Subscriber", function (assert) {
|
|
||||||
let done = assert.async();
|
|
||||||
|
|
||||||
// number of asserts
|
|
||||||
assert.expect(1);
|
|
||||||
|
|
||||||
frappe.run_serially([
|
|
||||||
// insert a new Subscriber
|
|
||||||
() => frappe.tests.make('Subscriber', [
|
|
||||||
// values to be set
|
|
||||||
{key: 'value'}
|
|
||||||
]),
|
|
||||||
() => {
|
|
||||||
assert.equal(cur_frm.doc.key, 'value');
|
|
||||||
},
|
|
||||||
() => done()
|
|
||||||
]);
|
|
||||||
|
|
||||||
});
|
|
@ -1,9 +0,0 @@
|
|||||||
# -*- coding: utf-8 -*-
|
|
||||||
# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and Contributors
|
|
||||||
# See license.txt
|
|
||||||
from __future__ import unicode_literals
|
|
||||||
|
|
||||||
import unittest
|
|
||||||
|
|
||||||
class TestSubscriber(unittest.TestCase):
|
|
||||||
pass
|
|
@ -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,
|
||||||
@ -20,7 +21,7 @@
|
|||||||
"bold": 0,
|
"bold": 0,
|
||||||
"collapsible": 0,
|
"collapsible": 0,
|
||||||
"columns": 0,
|
"columns": 0,
|
||||||
"fieldname": "subscriber",
|
"fieldname": "customer",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"hidden": 0,
|
"hidden": 0,
|
||||||
"ignore_user_permissions": 0,
|
"ignore_user_permissions": 0,
|
||||||
@ -29,10 +30,10 @@
|
|||||||
"in_global_search": 0,
|
"in_global_search": 0,
|
||||||
"in_list_view": 1,
|
"in_list_view": 1,
|
||||||
"in_standard_filter": 0,
|
"in_standard_filter": 0,
|
||||||
"label": "Subscriber",
|
"label": "Customer",
|
||||||
"length": 0,
|
"length": 0,
|
||||||
"no_copy": 0,
|
"no_copy": 0,
|
||||||
"options": "Subscriber",
|
"options": "Customer",
|
||||||
"permlevel": 0,
|
"permlevel": 0,
|
||||||
"precision": "",
|
"precision": "",
|
||||||
"print_hide": 0,
|
"print_hide": 0,
|
||||||
@ -437,6 +438,38 @@
|
|||||||
"translatable": 0,
|
"translatable": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"allow_bulk_edit": 0,
|
||||||
|
"allow_in_quick_entry": 0,
|
||||||
|
"allow_on_submit": 0,
|
||||||
|
"bold": 0,
|
||||||
|
"collapsible": 0,
|
||||||
|
"columns": 0,
|
||||||
|
"fieldname": "generate_invoice_at_period_start",
|
||||||
|
"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": "Generate Invoice At Beginning Of Period",
|
||||||
|
"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_bulk_edit": 0,
|
||||||
"allow_in_quick_entry": 0,
|
"allow_in_quick_entry": 0,
|
||||||
@ -814,7 +847,7 @@
|
|||||||
"issingle": 0,
|
"issingle": 0,
|
||||||
"istable": 0,
|
"istable": 0,
|
||||||
"max_attachments": 0,
|
"max_attachments": 0,
|
||||||
"modified": "2018-08-21 16:15:44.533482",
|
"modified": "2018-10-14 10:38:55.545540",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Accounts",
|
"module": "Accounts",
|
||||||
"name": "Subscription",
|
"name": "Subscription",
|
||||||
|
@ -239,7 +239,7 @@ class Subscription(Document):
|
|||||||
invoice = frappe.new_doc('Sales Invoice')
|
invoice = frappe.new_doc('Sales Invoice')
|
||||||
invoice.set_posting_time = 1
|
invoice.set_posting_time = 1
|
||||||
invoice.posting_date = self.current_invoice_start
|
invoice.posting_date = self.current_invoice_start
|
||||||
invoice.customer = self.get_customer(self.subscriber)
|
invoice.customer = self.customer
|
||||||
|
|
||||||
# Subscription is better suited for service items. I won't update `update_stock`
|
# Subscription is better suited for service items. I won't update `update_stock`
|
||||||
# for that reason
|
# for that reason
|
||||||
@ -282,13 +282,6 @@ class Subscription(Document):
|
|||||||
|
|
||||||
return invoice
|
return invoice
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def get_customer(subscriber_name):
|
|
||||||
"""
|
|
||||||
Returns the `Customer` linked to the `Subscriber`
|
|
||||||
"""
|
|
||||||
return frappe.db.get_value('Subscriber', subscriber_name, 'customer')
|
|
||||||
|
|
||||||
def get_items_from_plans(self, plans, prorate=0):
|
def get_items_from_plans(self, plans, prorate=0):
|
||||||
"""
|
"""
|
||||||
Returns the `Item`s linked to `Subscription Plan`
|
Returns the `Item`s linked to `Subscription Plan`
|
||||||
@ -297,7 +290,7 @@ class Subscription(Document):
|
|||||||
prorate_factor = get_prorata_factor(self.current_invoice_end, self.current_invoice_start)
|
prorate_factor = get_prorata_factor(self.current_invoice_end, self.current_invoice_start)
|
||||||
|
|
||||||
items = []
|
items = []
|
||||||
customer = self.get_customer(self.subscriber)
|
customer = self.customer
|
||||||
for plan in plans:
|
for plan in plans:
|
||||||
item_code = frappe.db.get_value("Subscription Plan", plan.plan, "item")
|
item_code = frappe.db.get_value("Subscription Plan", plan.plan, "item")
|
||||||
if not prorate:
|
if not prorate:
|
||||||
@ -321,6 +314,23 @@ class Subscription(Document):
|
|||||||
|
|
||||||
self.save()
|
self.save()
|
||||||
|
|
||||||
|
@property
|
||||||
|
def is_postpaid_to_invoice(self):
|
||||||
|
return getdate(nowdate()) > getdate(self.current_invoice_end) or \
|
||||||
|
(getdate(nowdate()) >= getdate(self.current_invoice_end) and getdate(self.current_invoice_end) == getdate(self.current_invoice_start)) and \
|
||||||
|
not self.has_outstanding_invoice()
|
||||||
|
|
||||||
|
@property
|
||||||
|
def is_prepaid_to_invoice(self):
|
||||||
|
if not self.generate_invoice_at_period_start:
|
||||||
|
return False
|
||||||
|
|
||||||
|
if self.is_new_subscription():
|
||||||
|
return True
|
||||||
|
|
||||||
|
# Check invoice dates and make sure it doesn't have outstanding invoices
|
||||||
|
return getdate(nowdate()) >= getdate(self.current_invoice_start) and not self.has_outstanding_invoice()
|
||||||
|
|
||||||
def process_for_active(self):
|
def process_for_active(self):
|
||||||
"""
|
"""
|
||||||
Called by `process` if the status of the `Subscription` is 'Active'.
|
Called by `process` if the status of the `Subscription` is 'Active'.
|
||||||
@ -330,7 +340,7 @@ class Subscription(Document):
|
|||||||
2. Change the `Subscription` status to 'Past Due Date'
|
2. Change the `Subscription` status to 'Past Due Date'
|
||||||
3. Change the `Subscription` status to 'Cancelled'
|
3. Change the `Subscription` status to 'Cancelled'
|
||||||
"""
|
"""
|
||||||
if getdate(nowdate()) > getdate(self.current_invoice_end) or (getdate(nowdate()) >= getdate(self.current_invoice_end) and getdate(self.current_invoice_end) == getdate(self.current_invoice_start)) and not self.has_outstanding_invoice():
|
if self.is_postpaid_to_invoice or self.is_prepaid_to_invoice:
|
||||||
self.generate_invoice()
|
self.generate_invoice()
|
||||||
if self.current_invoice_is_past_due():
|
if self.current_invoice_is_past_due():
|
||||||
self.status = 'Past Due Date'
|
self.status = 'Past Due Date'
|
||||||
@ -338,7 +348,7 @@ class Subscription(Document):
|
|||||||
if self.current_invoice_is_past_due() and getdate(nowdate()) > getdate(self.current_invoice_end):
|
if self.current_invoice_is_past_due() and getdate(nowdate()) > getdate(self.current_invoice_end):
|
||||||
self.status = 'Past Due Date'
|
self.status = 'Past Due Date'
|
||||||
|
|
||||||
if self.cancel_at_period_end and getdate(nowdate()) > self.current_invoice_end:
|
if self.cancel_at_period_end and getdate(nowdate()) > getdate(self.current_invoice_end):
|
||||||
self.cancel_subscription_at_period_end()
|
self.cancel_subscription_at_period_end()
|
||||||
|
|
||||||
def cancel_subscription_at_period_end(self):
|
def cancel_subscription_at_period_end(self):
|
||||||
|
@ -500,3 +500,51 @@ class TestSubscription(unittest.TestCase):
|
|||||||
self.assertEqual(invoice.apply_discount_on, 'Grand Total')
|
self.assertEqual(invoice.apply_discount_on, 'Grand Total')
|
||||||
|
|
||||||
subscription.delete()
|
subscription.delete()
|
||||||
|
|
||||||
|
def test_prepaid_subscriptions(self):
|
||||||
|
# Create a non pre-billed subscription, processing should not create
|
||||||
|
# invoices.
|
||||||
|
subscription = frappe.new_doc('Subscription')
|
||||||
|
subscription.subscriber = '_Test Customer'
|
||||||
|
subscription.append('plans', {'plan': '_Test Plan Name', 'qty': 1})
|
||||||
|
subscription.save()
|
||||||
|
subscription.process()
|
||||||
|
|
||||||
|
self.assertEqual(len(subscription.invoices), 0)
|
||||||
|
|
||||||
|
# Change the subscription type to prebilled and process it.
|
||||||
|
# Prepaid invoice should be generated
|
||||||
|
subscription.generate_invoice_at_period_start = True
|
||||||
|
subscription.save()
|
||||||
|
subscription.process()
|
||||||
|
|
||||||
|
self.assertEqual(len(subscription.invoices), 1)
|
||||||
|
|
||||||
|
def test_prepaid_subscriptions_with_prorate_true(self):
|
||||||
|
settings = frappe.get_single('Subscription Settings')
|
||||||
|
to_prorate = settings.prorate
|
||||||
|
settings.prorate = 1
|
||||||
|
settings.save()
|
||||||
|
|
||||||
|
subscription = frappe.new_doc('Subscription')
|
||||||
|
subscription.subscriber = '_Test Customer'
|
||||||
|
subscription.generate_invoice_at_period_start = True
|
||||||
|
subscription.append('plans', {'plan': '_Test Plan Name', 'qty': 1})
|
||||||
|
subscription.save()
|
||||||
|
subscription.cancel_subscription()
|
||||||
|
|
||||||
|
self.assertEqual(len(subscription.invoices), 1)
|
||||||
|
|
||||||
|
current_inv = subscription.get_current_invoice()
|
||||||
|
self.assertEqual(current_inv.status, "Unpaid")
|
||||||
|
|
||||||
|
diff = flt(date_diff(nowdate(), subscription.current_invoice_start) + 1)
|
||||||
|
plan_days = flt(date_diff(subscription.current_invoice_end, subscription.current_invoice_start) + 1)
|
||||||
|
prorate_factor = flt(diff / plan_days)
|
||||||
|
|
||||||
|
self.assertEqual(flt(current_inv.grand_total, 2), flt(prorate_factor * 900, 2))
|
||||||
|
|
||||||
|
settings.prorate = to_prorate
|
||||||
|
settings.save()
|
||||||
|
|
||||||
|
subscription.delete()
|
||||||
|
@ -189,15 +189,15 @@
|
|||||||
{% } %}
|
{% } %}
|
||||||
<td><b>{%= __("Total") %}</b></td>
|
<td><b>{%= __("Total") %}</b></td>
|
||||||
<td style="text-align: right">
|
<td style="text-align: right">
|
||||||
{%= format_currency(data[i]["Invoiced Amount"], data[i]["currency"] ) %}</td>
|
{%= format_currency(data[i]["invoiced_amount"], data[i]["currency"] ) %}</td>
|
||||||
|
|
||||||
{% if(!filters.show_pdc_in_print) { %}
|
{% if(!filters.show_pdc_in_print) { %}
|
||||||
<td style="text-align: right">
|
<td style="text-align: right">
|
||||||
{%= format_currency(data[i]["Paid Amount"], data[i]["currency"]) %}</td>
|
{%= format_currency(data[i]["paid_amount"], data[i]["currency"]) %}</td>
|
||||||
<td style="text-align: right">{%= report.report_name === "Accounts Receivable" ? format_currency(data[i]["Credit Note"], data[i]["currency"]) : format_currency(data[i]["Debit Note"], data[i]["currency"]) %} </td>
|
<td style="text-align: right">{%= report.report_name === "Accounts Receivable" ? format_currency(data[i]["credit_note"], data[i]["currency"]) : format_currency(data[i]["Debit Note"], data[i]["currency"]) %} </td>
|
||||||
{% } %}
|
{% } %}
|
||||||
<td style="text-align: right">
|
<td style="text-align: right">
|
||||||
{%= format_currency(data[i]["Outstanding Amount"], data[i]["currency"]) %}</td>
|
{%= format_currency(data[i]["outstanding_amount"], data[i]["currency"]) %}</td>
|
||||||
|
|
||||||
{% if(filters.show_pdc_in_print) { %}
|
{% if(filters.show_pdc_in_print) { %}
|
||||||
{% if(report.report_name === "Accounts Receivable") { %}
|
{% if(report.report_name === "Accounts Receivable") { %}
|
||||||
|
@ -1,72 +1,92 @@
|
|||||||
[
|
[
|
||||||
{
|
{
|
||||||
"date_of_birth": "1982-01-03",
|
"date_of_birth": "1982-01-03",
|
||||||
"date_of_joining": "2001-10-10",
|
"date_of_joining": "2001-10-10",
|
||||||
"employee_name": "Dikman Shervashidze Shervashidze",
|
"employee_name": "Diana Prince",
|
||||||
"gender": "Female",
|
"first_name": "Diana",
|
||||||
"user_id": "DikmanShervashidze@example.com"
|
"last_name": "Prince",
|
||||||
},
|
"gender": "Female",
|
||||||
{
|
"user_id": "DianaPrince@example.com"
|
||||||
"date_of_birth": "1959-02-03",
|
},
|
||||||
"date_of_joining": "1976-09-16",
|
{
|
||||||
"employee_name": "Zukutakitoteka",
|
"date_of_birth": "1959-02-03",
|
||||||
"gender": "Female",
|
"date_of_joining": "1976-09-16",
|
||||||
"user_id": "Zukutakitoteka@example.com"
|
"employee_name": "Zatanna Zatara",
|
||||||
},
|
"gender": "Female",
|
||||||
{
|
"user_id": "ZatannaZatara@example.com",
|
||||||
"date_of_birth": "1982-03-03",
|
"first_name": "Zatanna",
|
||||||
"date_of_joining": "2000-06-16",
|
"last_name": "Zatara"
|
||||||
"employee_name": "Hatsue Kashiwagi",
|
},
|
||||||
"gender": "Female",
|
{
|
||||||
"user_id": "HatsueKashiwagi@example.com"
|
"date_of_birth": "1982-03-03",
|
||||||
},
|
"date_of_joining": "2000-06-16",
|
||||||
{
|
"employee_name": "Holly Granger",
|
||||||
"date_of_birth": "1945-04-04",
|
"gender": "Female",
|
||||||
"date_of_joining": "1969-07-01",
|
"user_id": "HollyGranger@example.com",
|
||||||
"employee_name": "Nuran Verkleij",
|
"first_name": "Holly",
|
||||||
"gender": "Female",
|
"last_name": "Granger"
|
||||||
"user_id": "NuranVerkleij@example.com"
|
},
|
||||||
},
|
{
|
||||||
{
|
"date_of_birth": "1945-04-04",
|
||||||
"date_of_birth": "1978-05-03",
|
"date_of_joining": "1969-07-01",
|
||||||
"date_of_joining": "1999-12-24",
|
"employee_name": "Neptunia Aquaria",
|
||||||
"employee_name": "\u0414\u043c\u0438\u0442\u0440\u0438\u0439 \u041f\u0438\u0440\u043e\u0433\u043e\u0432",
|
"gender": "Female",
|
||||||
"gender": "Male",
|
"user_id": "NeptuniaAquaria@example.com",
|
||||||
"user_id": "aromn@example.com"
|
"first_name": "Neptunia",
|
||||||
},
|
"last_name": "Aquaria"
|
||||||
{
|
},
|
||||||
"date_of_birth": "1964-06-03",
|
{
|
||||||
"date_of_joining": "1981-08-05",
|
"date_of_birth": "1978-05-03",
|
||||||
"employee_name": "Tilde Lindqvist",
|
"date_of_joining": "1999-12-24",
|
||||||
"gender": "Female",
|
"employee_name": "Arthur Curry",
|
||||||
"user_id": "TildeLindqvist@example.com"
|
"gender": "Male",
|
||||||
},
|
"user_id": "ArthurCurry@example.com",
|
||||||
{
|
"first_name": "Arthur",
|
||||||
"date_of_birth": "1982-07-03",
|
"last_name": "Curry"
|
||||||
"date_of_joining": "2006-06-10",
|
},
|
||||||
"employee_name": "Micha\u0142 Sobczak",
|
{
|
||||||
"gender": "Male",
|
"date_of_birth": "1964-06-03",
|
||||||
"user_id": "MichalSobczak@example.com"
|
"date_of_joining": "1981-08-05",
|
||||||
},
|
"employee_name": "Thalia Al Ghul",
|
||||||
{
|
"gender": "Female",
|
||||||
"date_of_birth": "1969-08-03",
|
"user_id": "ThaliaAlGhul@example.com",
|
||||||
"date_of_joining": "1993-10-21",
|
"first_name": "Thalia",
|
||||||
"employee_name": "Gabrielle Loftus",
|
"last_name": "Al Ghul"
|
||||||
"gender": "Female",
|
},
|
||||||
"user_id": "GabrielleLoftus@example.com"
|
{
|
||||||
},
|
"date_of_birth": "1982-07-03",
|
||||||
{
|
"date_of_joining": "2006-06-10",
|
||||||
"date_of_birth": "1982-09-03",
|
"employee_name": "Maxwell Lord",
|
||||||
"date_of_joining": "2005-09-06",
|
"gender": "Male",
|
||||||
"employee_name": "Vakhita Ryzaev",
|
"user_id": "MaxwellLord@example.com",
|
||||||
"gender": "Male",
|
"first_name": "Maxwell",
|
||||||
"user_id": "VakhitaRyzaev@example.com"
|
"last_name": "Lord"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"date_of_birth": "1985-10-03",
|
"date_of_birth": "1969-08-03",
|
||||||
"date_of_joining": "2007-12-25",
|
"date_of_joining": "1993-10-21",
|
||||||
"employee_name": "Charmaine Gaudreau",
|
"employee_name": "Grace Choi",
|
||||||
"gender": "Female",
|
"gender": "Female",
|
||||||
"user_id": "CharmaineGaudreau@example.com"
|
"user_id": "GraceChoi@example.com",
|
||||||
}
|
"first_name": "Grace",
|
||||||
|
"last_name": "Choi"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"date_of_birth": "1982-09-03",
|
||||||
|
"date_of_joining": "2005-09-06",
|
||||||
|
"employee_name": "Vandal Savage",
|
||||||
|
"gender": "Male",
|
||||||
|
"user_id": "VandalSavage@example.com",
|
||||||
|
"first_name": "Vandal",
|
||||||
|
"last_name": "Savage"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"date_of_birth": "1985-10-03",
|
||||||
|
"date_of_joining": "2007-12-25",
|
||||||
|
"employee_name": "Caitlin Snow",
|
||||||
|
"gender": "Female",
|
||||||
|
"user_id": "CaitlinSnow@example.com",
|
||||||
|
"first_name": "Caitlin",
|
||||||
|
"last_name": "Snow"
|
||||||
|
}
|
||||||
]
|
]
|
@ -1,337 +1,493 @@
|
|||||||
[
|
[
|
||||||
{
|
{
|
||||||
"default_supplier": "Asiatic Solutions",
|
"item_defaults": [
|
||||||
"item_defaults": [{
|
{
|
||||||
"default_warehouse": "Stores"
|
"default_supplier": "Asiatic Solutions",
|
||||||
}],
|
"default_warehouse": "Stores"
|
||||||
"description": "For Upper Bearing",
|
}
|
||||||
"image": "/assets/erpnext_demo/images/disc.png",
|
],
|
||||||
"item_code": "Disc Collars",
|
"description": "For Upper Bearing",
|
||||||
"item_group": "Raw Material",
|
"image": "/assets/erpnext_demo/images/disc.png",
|
||||||
"item_name": "Disc Collars"
|
"item_code": "Disc Collars",
|
||||||
},
|
"item_group": "Raw Material",
|
||||||
{
|
"item_name": "Disc Collars"
|
||||||
"default_supplier": "Nan Duskin",
|
},
|
||||||
"item_defaults": [{
|
{
|
||||||
"default_warehouse": "Stores"
|
"item_defaults": [
|
||||||
}],
|
{
|
||||||
"description": "CAST IRON, MCMASTER PART NO. 3710T13",
|
"default_supplier": "Nan Duskin",
|
||||||
"image": "/assets/erpnext_demo/images/bearing.jpg",
|
"default_warehouse": "Stores"
|
||||||
"item_code": "Bearing Block",
|
}
|
||||||
"item_group": "Raw Material",
|
],
|
||||||
"item_name": "Bearing Block"
|
"description": "CAST IRON, MCMASTER PART NO. 3710T13",
|
||||||
},
|
"image": "/assets/erpnext_demo/images/bearing.jpg",
|
||||||
{
|
"item_code": "Bearing Block",
|
||||||
"default_supplier": null,
|
"item_group": "Raw Material",
|
||||||
"item_defaults": [{
|
"item_name": "Bearing Block"
|
||||||
"default_warehouse": "Finished Goods"
|
},
|
||||||
}],
|
{
|
||||||
"description": "Wind Mill C Series for Commercial Use 18ft",
|
"item_defaults": [
|
||||||
"image": "/assets/erpnext_demo/images/wind-turbine-2.png",
|
{
|
||||||
"item_code": "Wind MIll C Series",
|
"default_supplier": null,
|
||||||
"item_group": "Products",
|
"default_warehouse": "Finished Goods"
|
||||||
"item_name": "Wind MIll C Series"
|
}
|
||||||
},
|
],
|
||||||
{
|
"description": "Wind Mill C Series for Commercial Use 18ft",
|
||||||
"default_supplier": null,
|
"image": "/assets/erpnext_demo/images/wind-turbine-2.png",
|
||||||
"item_defaults": [{
|
"item_code": "Wind MIll C Series",
|
||||||
"default_warehouse": "Finished Goods"
|
"item_group": "Products",
|
||||||
}],
|
"item_name": "Wind MIll C Series"
|
||||||
"description": "Wind Mill A Series for Home Use 9ft",
|
},
|
||||||
"image": "/assets/erpnext_demo/images/wind-turbine.png",
|
{
|
||||||
"item_code": "Wind Mill A Series",
|
"item_defaults": [
|
||||||
"item_group": "Products",
|
{
|
||||||
"item_name": "Wind Mill A Series"
|
"default_supplier": null,
|
||||||
},
|
"default_warehouse": "Finished Goods"
|
||||||
{
|
}
|
||||||
"default_supplier": null,
|
],
|
||||||
"item_defaults": [{
|
"description": "Wind Mill A Series for Home Use 9ft",
|
||||||
"default_warehouse": "Finished Goods"
|
"image": "/assets/erpnext_demo/images/wind-turbine.png",
|
||||||
}],
|
"item_code": "Wind Mill A Series",
|
||||||
"description": "Small Wind Turbine for Home Use\n\n\n<!-- html -->",
|
"item_group": "Products",
|
||||||
"image": "/assets/erpnext_demo/images/wind-turbine-1.jpg",
|
"item_name": "Wind Mill A Series"
|
||||||
"item_code": "Wind Turbine",
|
},
|
||||||
"item_group": "Products",
|
{
|
||||||
"item_name": "Wind Turbine",
|
"item_defaults": [
|
||||||
"has_variants": 1,
|
{
|
||||||
"has_serial_no": 1,
|
"default_supplier": null,
|
||||||
"attributes":[
|
"default_warehouse": "Finished Goods"
|
||||||
{ "attribute": "Size" }
|
}
|
||||||
]
|
],
|
||||||
},
|
"description": "Small Wind Turbine for Home Use\n\n\n<!-- html -->",
|
||||||
{
|
"image": "/assets/erpnext_demo/images/wind-turbine-1.jpg",
|
||||||
"default_supplier": "HomeBase",
|
"item_code": "Wind Turbine",
|
||||||
"item_defaults": [{
|
"item_group": "Products",
|
||||||
"default_warehouse": "Stores"
|
"item_name": "Wind Turbine",
|
||||||
}],
|
"has_variants": 1,
|
||||||
"description": "1.5 in. Diameter x 36 in. Mild Steel Tubing",
|
"has_serial_no": 1,
|
||||||
"image": null,
|
"attributes": [
|
||||||
"item_code": "Bearing Pipe",
|
{
|
||||||
"item_group": "Raw Material",
|
"attribute": "Size"
|
||||||
"item_name": "Bearing Pipe"
|
}
|
||||||
},
|
]
|
||||||
{
|
},
|
||||||
"default_supplier": "New World Realty",
|
{
|
||||||
"item_defaults": [{
|
"item_defaults": [
|
||||||
"default_warehouse": "Stores"
|
{
|
||||||
}],
|
"default_supplier": "HomeBase",
|
||||||
"description": "1/32 in. x 24 in. x 47 in. HDPE Opaque Sheet",
|
"default_warehouse": "Stores"
|
||||||
"image": null,
|
}
|
||||||
"item_code": "Wing Sheet",
|
],
|
||||||
"item_group": "Raw Material",
|
"description": "1.5 in. Diameter x 36 in. Mild Steel Tubing",
|
||||||
"item_name": "Wing Sheet"
|
"image": null,
|
||||||
},
|
"item_code": "Bearing Pipe",
|
||||||
{
|
"item_group": "Raw Material",
|
||||||
"default_supplier": "Eagle Hardware",
|
"item_name": "Bearing Pipe"
|
||||||
"item_defaults": [{
|
},
|
||||||
"default_warehouse": "Stores"
|
{
|
||||||
}],
|
"item_defaults": [
|
||||||
"description": "3/16 in. x 6 in. x 6 in. Low Carbon Steel Plate",
|
{
|
||||||
"image": null,
|
"default_supplier": "New World Realty",
|
||||||
"item_code": "Upper Bearing Plate",
|
"default_warehouse": "Stores"
|
||||||
"item_group": "Raw Material",
|
}
|
||||||
"item_name": "Upper Bearing Plate"
|
],
|
||||||
},
|
"description": "1/32 in. x 24 in. x 47 in. HDPE Opaque Sheet",
|
||||||
{
|
"image": null,
|
||||||
"default_supplier": "Asiatic Solutions",
|
"item_code": "Wing Sheet",
|
||||||
"item_defaults": [{
|
"item_group": "Raw Material",
|
||||||
"default_warehouse": "Stores"
|
"item_name": "Wing Sheet"
|
||||||
}],
|
},
|
||||||
"description": "Bearing Assembly",
|
{
|
||||||
"image": null,
|
"item_defaults": [
|
||||||
"item_code": "Bearing Assembly",
|
{
|
||||||
"item_group": "Sub Assemblies",
|
"default_supplier": "Eagle Hardware",
|
||||||
"item_name": "Bearing Assembly"
|
"default_warehouse": "Stores"
|
||||||
},
|
}
|
||||||
{
|
],
|
||||||
"default_supplier": "HomeBase",
|
"description": "3/16 in. x 6 in. x 6 in. Low Carbon Steel Plate",
|
||||||
"item_defaults": [{
|
"image": null,
|
||||||
"default_warehouse": "Stores"
|
"item_code": "Upper Bearing Plate",
|
||||||
}],
|
"item_group": "Raw Material",
|
||||||
"description": "3/4 in. x 2 ft. x 4 ft. Pine Plywood",
|
"item_name": "Upper Bearing Plate"
|
||||||
"image": null,
|
},
|
||||||
"item_code": "Base Plate",
|
{
|
||||||
"item_group": "Raw Material",
|
"item_defaults": [
|
||||||
"item_name": "Base Plate",
|
{
|
||||||
"is_sub_contracted_item": 1
|
"default_supplier": "Asiatic Solutions",
|
||||||
},
|
"default_warehouse": "Stores"
|
||||||
{
|
}
|
||||||
"default_supplier": "Scott Ties",
|
],
|
||||||
"item_defaults": [{
|
"description": "Bearing Assembly",
|
||||||
"default_warehouse": "Stores"
|
"image": null,
|
||||||
}],
|
"item_code": "Bearing Assembly",
|
||||||
"description": "N/A",
|
"item_group": "Sub Assemblies",
|
||||||
"image": null,
|
"item_name": "Bearing Assembly"
|
||||||
"item_code": "Stand",
|
},
|
||||||
"item_group": "Raw Material",
|
{
|
||||||
"item_name": "Stand"
|
"item_defaults": [
|
||||||
},
|
{
|
||||||
{
|
"default_supplier": "HomeBase",
|
||||||
"default_supplier": "Eagle Hardware",
|
"default_warehouse": "Stores"
|
||||||
"item_defaults": [{
|
}
|
||||||
"default_warehouse": "Stores"
|
],
|
||||||
}],
|
"description": "3/4 in. x 2 ft. x 4 ft. Pine Plywood",
|
||||||
"description": "1 in. x 3 in. x 1 ft. Multipurpose Al Alloy Bar",
|
"image": null,
|
||||||
"image": null,
|
"item_code": "Base Plate",
|
||||||
"item_code": "Bearing Collar",
|
"item_group": "Raw Material",
|
||||||
"item_group": "Raw Material",
|
"item_name": "Base Plate",
|
||||||
"item_name": "Bearing Collar"
|
"is_sub_contracted_item": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"default_supplier": "Eagle Hardware",
|
"item_defaults": [
|
||||||
"item_defaults": [{
|
{
|
||||||
"default_warehouse": "Stores"
|
"default_supplier": "Scott Ties",
|
||||||
}],
|
"default_warehouse": "Stores"
|
||||||
"description": "1/4 in. x 6 in. x 6 in. Mild Steel Plate",
|
}
|
||||||
"image": null,
|
],
|
||||||
"item_code": "Base Bearing Plate",
|
"description": "N/A",
|
||||||
"item_group": "Raw Material",
|
"image": null,
|
||||||
"item_name": "Base Bearing Plate"
|
"item_code": "Stand",
|
||||||
},
|
"item_group": "Raw Material",
|
||||||
{
|
"item_name": "Stand"
|
||||||
"default_supplier": "HomeBase",
|
},
|
||||||
"item_defaults": [{
|
{
|
||||||
"default_warehouse": "Stores"
|
"item_defaults": [
|
||||||
}],
|
{
|
||||||
"description": "15/32 in. x 4 ft. x 8 ft. 3-Ply Rtd Sheathing",
|
"default_supplier": "Eagle Hardware",
|
||||||
"image": null,
|
"default_warehouse": "Stores"
|
||||||
"item_code": "External Disc",
|
}
|
||||||
"item_group": "Raw Material",
|
],
|
||||||
"item_name": "External Disc"
|
"description": "1 in. x 3 in. x 1 ft. Multipurpose Al Alloy Bar",
|
||||||
},
|
"image": null,
|
||||||
{
|
"item_code": "Bearing Collar",
|
||||||
"default_supplier": "Eagle Hardware",
|
"item_group": "Raw Material",
|
||||||
"item_defaults": [{
|
"item_name": "Bearing Collar"
|
||||||
"default_warehouse": "Stores"
|
},
|
||||||
}],
|
{
|
||||||
"description": "1.25 in. Diameter x 6 ft. Mild Steel Tubing",
|
"item_defaults": [
|
||||||
"image": null,
|
{
|
||||||
"item_code": "Shaft",
|
"default_supplier": "Eagle Hardware",
|
||||||
"item_group": "Raw Material",
|
"default_warehouse": "Stores"
|
||||||
"item_name": "Shaft"
|
}
|
||||||
},
|
],
|
||||||
{
|
"description": "1/4 in. x 6 in. x 6 in. Mild Steel Plate",
|
||||||
"default_supplier": "Ks Merchandise",
|
"image": null,
|
||||||
"item_defaults": [{
|
"item_code": "Base Bearing Plate",
|
||||||
"default_warehouse": "Stores"
|
"item_group": "Raw Material",
|
||||||
}],
|
"item_name": "Base Bearing Plate"
|
||||||
"description": "1/2 in. x 2 ft. x 4 ft. Pine Plywood",
|
},
|
||||||
"image": null,
|
{
|
||||||
"item_code": "Blade Rib",
|
"item_defaults": [
|
||||||
"item_group": "Raw Material",
|
{
|
||||||
"item_name": "Blade Rib"
|
"default_supplier": "HomeBase",
|
||||||
},
|
"default_warehouse": "Stores"
|
||||||
{
|
}
|
||||||
"default_supplier": "HomeBase",
|
],
|
||||||
"item_defaults": [{
|
"description": "15/32 in. x 4 ft. x 8 ft. 3-Ply Rtd Sheathing",
|
||||||
"default_warehouse": "Stores"
|
"image": null,
|
||||||
}],
|
"item_code": "External Disc",
|
||||||
"description": "For Bearing Collar",
|
"item_group": "Raw Material",
|
||||||
"image": null,
|
"item_name": "External Disc"
|
||||||
"item_code": "Internal Disc",
|
},
|
||||||
"item_group": "Raw Material",
|
{
|
||||||
"item_name": "Internal Disc"
|
"item_defaults": [
|
||||||
},
|
{
|
||||||
{
|
"default_supplier": "Eagle Hardware",
|
||||||
"default_supplier": null,
|
"default_warehouse": "Stores"
|
||||||
"item_defaults": [{
|
}
|
||||||
"default_warehouse": "Finished Goods"
|
],
|
||||||
}],
|
"description": "1.25 in. Diameter x 6 ft. Mild Steel Tubing",
|
||||||
"description": "Small Wind Turbine for Home Use\n\n\n<!-- html -->\n<p>Size: Small</p>",
|
"image": null,
|
||||||
"image": "/assets/erpnext_demo/images/wind-turbine-1.jpg",
|
"item_code": "Shaft",
|
||||||
"item_code": "Wind Turbine-S",
|
"item_group": "Raw Material",
|
||||||
"item_group": "Products",
|
"item_name": "Shaft"
|
||||||
"item_name": "Wind Turbine-S",
|
},
|
||||||
"variant_of": "Wind Turbine",
|
{
|
||||||
"valuation_rate": 300,
|
"item_defaults": [
|
||||||
"attributes":[
|
{
|
||||||
{
|
"default_supplier": "Ks Merchandise",
|
||||||
"attribute": "Size",
|
"default_warehouse": "Stores"
|
||||||
"attribute_value": "Small"
|
}
|
||||||
}
|
],
|
||||||
]
|
"description": "1/2 in. x 2 ft. x 4 ft. Pine Plywood",
|
||||||
},
|
"image": null,
|
||||||
{
|
"item_code": "Blade Rib",
|
||||||
"default_supplier": null,
|
"item_group": "Raw Material",
|
||||||
"item_defaults": [{
|
"item_name": "Blade Rib"
|
||||||
"default_warehouse": "Finished Goods"
|
},
|
||||||
}],
|
{
|
||||||
"description": "Small Wind Turbine for Home Use\n\n\n<!-- html -->\n<p>Size: Medium</p>",
|
"item_defaults": [
|
||||||
"image": "/assets/erpnext_demo/images/wind-turbine-1.jpg",
|
{
|
||||||
"item_code": "Wind Turbine-M",
|
"default_supplier": "HomeBase",
|
||||||
"item_group": "Products",
|
"default_warehouse": "Stores"
|
||||||
"item_name": "Wind Turbine-M",
|
}
|
||||||
"variant_of": "Wind Turbine",
|
],
|
||||||
"valuation_rate": 300,
|
"description": "For Bearing Collar",
|
||||||
"attributes":[
|
"image": null,
|
||||||
{
|
"item_code": "Internal Disc",
|
||||||
"attribute": "Size",
|
"item_group": "Raw Material",
|
||||||
"attribute_value": "Medium"
|
"item_name": "Internal Disc"
|
||||||
}
|
},
|
||||||
]
|
{
|
||||||
},
|
"item_defaults": [
|
||||||
{
|
{
|
||||||
"default_supplier": null,
|
"default_supplier": null,
|
||||||
"item_defaults": [{
|
"default_warehouse": "Finished Goods"
|
||||||
"default_warehouse": "Finished Goods"
|
}
|
||||||
}],
|
],
|
||||||
"description": "Small Wind Turbine for Home Use\n\n\n<!-- html -->\n<p>Size: Large</p>",
|
"description": "Small Wind Turbine for Home Use\n\n\n<!-- html -->\n<p>Size: Small</p>",
|
||||||
"image": "/assets/erpnext_demo/images/wind-turbine-1.jpg",
|
"image": "/assets/erpnext_demo/images/wind-turbine-1.jpg",
|
||||||
"item_code": "Wind Turbine-L",
|
"item_code": "Wind Turbine-S",
|
||||||
"item_group": "Products",
|
"item_group": "Products",
|
||||||
"item_name": "Wind Turbine-L",
|
"item_name": "Wind Turbine-S",
|
||||||
"variant_of": "Wind Turbine",
|
"variant_of": "Wind Turbine",
|
||||||
"valuation_rate": 300,
|
"valuation_rate": 300,
|
||||||
"attributes":[
|
"attributes": [
|
||||||
{
|
{
|
||||||
"attribute": "Size",
|
"attribute": "Size",
|
||||||
"attribute_value": "Large"
|
"attribute_value": "Small"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"is_stock_item": 0,
|
"item_defaults": [
|
||||||
"description": "Wind Mill A Series with Spare Bearing",
|
{
|
||||||
"item_code": "Wind Mill A Series with Spare Bearing",
|
"default_supplier": null,
|
||||||
"item_group": "Products",
|
"default_warehouse": "Finished Goods"
|
||||||
"item_name": "Wind Mill A Series with Spare Bearing"
|
}
|
||||||
},
|
],
|
||||||
{
|
"description": "Small Wind Turbine for Home Use\n\n\n<!-- html -->\n<p>Size: Medium</p>",
|
||||||
"default_supplier": "HomeBase",
|
"image": "/assets/erpnext_demo/images/wind-turbine-1.jpg",
|
||||||
"item_defaults": [{
|
"item_code": "Wind Turbine-M",
|
||||||
"default_warehouse": "Stores"
|
"item_group": "Products",
|
||||||
}],
|
"item_name": "Wind Turbine-M",
|
||||||
"description": "3/4 in. x 2 ft. x 4 ft. Pine Plywood",
|
"variant_of": "Wind Turbine",
|
||||||
"image": null,
|
"valuation_rate": 300,
|
||||||
"item_code": "Base Plate Un Painted",
|
"attributes": [
|
||||||
"item_group": "Raw Material",
|
{
|
||||||
"item_name": "Base Plate Un Painted"
|
"attribute": "Size",
|
||||||
},
|
"attribute_value": "Medium"
|
||||||
{
|
}
|
||||||
"is_fixed_asset": 1,
|
]
|
||||||
"asset_category": "Furnitures",
|
},
|
||||||
"is_stock_item": 0,
|
{
|
||||||
"description": "Table",
|
"item_defaults": [
|
||||||
"item_code": "Table",
|
{
|
||||||
"item_name": "Table",
|
"default_supplier": null,
|
||||||
"item_group": "Products"
|
"default_warehouse": "Finished Goods"
|
||||||
},
|
}
|
||||||
{
|
],
|
||||||
"is_fixed_asset": 1,
|
"description": "Small Wind Turbine for Home Use\n\n\n<!-- html -->\n<p>Size: Large</p>",
|
||||||
"asset_category": "Furnitures",
|
"image": "/assets/erpnext_demo/images/wind-turbine-1.jpg",
|
||||||
"is_stock_item": 0,
|
"item_code": "Wind Turbine-L",
|
||||||
"description": "Chair",
|
"item_group": "Products",
|
||||||
"item_code": "Chair",
|
"item_name": "Wind Turbine-L",
|
||||||
"item_name": "Chair",
|
"variant_of": "Wind Turbine",
|
||||||
"item_group": "Products"
|
"valuation_rate": 300,
|
||||||
},
|
"attributes": [
|
||||||
{
|
{
|
||||||
"is_fixed_asset": 1,
|
"attribute": "Size",
|
||||||
"asset_category": "Electronic Equipments",
|
"attribute_value": "Large"
|
||||||
"is_stock_item": 0,
|
}
|
||||||
"description": "Computer",
|
]
|
||||||
"item_code": "Computer",
|
},
|
||||||
"item_name": "Computer",
|
{
|
||||||
"item_group": "Products"
|
"is_stock_item": 0,
|
||||||
},
|
"description": "Wind Mill A Series with Spare Bearing",
|
||||||
{
|
"item_code": "Wind Mill A Series with Spare Bearing",
|
||||||
"is_fixed_asset": 1,
|
"item_group": "Products",
|
||||||
"asset_category": "Electronic Equipments",
|
"item_name": "Wind Mill A Series with Spare Bearing"
|
||||||
"is_stock_item": 0,
|
},
|
||||||
"description": "Mobile",
|
{
|
||||||
"item_code": "Mobile",
|
"item_defaults": [
|
||||||
"item_name": "Mobile",
|
{
|
||||||
"item_group": "Products"
|
"default_supplier": "HomeBase",
|
||||||
},
|
"default_warehouse": "Stores"
|
||||||
{
|
}
|
||||||
"is_fixed_asset": 1,
|
],
|
||||||
"asset_category": "Softwares",
|
"description": "3/4 in. x 2 ft. x 4 ft. Pine Plywood",
|
||||||
"is_stock_item": 0,
|
"image": null,
|
||||||
"description": "ERP",
|
"item_code": "Base Plate Un Painted",
|
||||||
"item_code": "ERP",
|
"item_group": "Raw Material",
|
||||||
"item_name": "ERP",
|
"item_name": "Base Plate Un Painted"
|
||||||
"item_group": "All Item Groups"
|
},
|
||||||
},
|
{
|
||||||
{
|
"is_fixed_asset": 1,
|
||||||
"is_fixed_asset": 1,
|
"asset_category": "Furnitures",
|
||||||
"asset_category": "Softwares",
|
"is_stock_item": 0,
|
||||||
"is_stock_item": 0,
|
"description": "Table",
|
||||||
"description": "Autocad",
|
"item_code": "Table",
|
||||||
"item_code": "Autocad",
|
"item_name": "Table",
|
||||||
"item_name": "Autocad",
|
"item_group": "Products"
|
||||||
"item_group": "All Item Groups"
|
},
|
||||||
},
|
{
|
||||||
{
|
"is_fixed_asset": 1,
|
||||||
"is_stock_item": 1,
|
"asset_category": "Furnitures",
|
||||||
"has_batch_no": 1,
|
"is_stock_item": 0,
|
||||||
"create_new_batch": 1,
|
"description": "Chair",
|
||||||
"valuation_rate": 200,
|
"item_code": "Chair",
|
||||||
"item_defaults": [{
|
"item_name": "Chair",
|
||||||
"default_warehouse": "Stores"
|
"item_group": "Products"
|
||||||
}],
|
},
|
||||||
"description": "Corrugated Box",
|
{
|
||||||
"item_code": "Corrugated Box",
|
"is_fixed_asset": 1,
|
||||||
"item_name": "Corrugated Box",
|
"asset_category": "Electronic Equipments",
|
||||||
"item_group": "All Item Groups"
|
"is_stock_item": 0,
|
||||||
}
|
"description": "Computer",
|
||||||
|
"item_code": "Computer",
|
||||||
|
"item_name": "Computer",
|
||||||
|
"item_group": "Products"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"is_fixed_asset": 1,
|
||||||
|
"asset_category": "Electronic Equipments",
|
||||||
|
"is_stock_item": 0,
|
||||||
|
"description": "Mobile",
|
||||||
|
"item_code": "Mobile",
|
||||||
|
"item_name": "Mobile",
|
||||||
|
"item_group": "Products"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"is_fixed_asset": 1,
|
||||||
|
"asset_category": "Softwares",
|
||||||
|
"is_stock_item": 0,
|
||||||
|
"description": "ERP",
|
||||||
|
"item_code": "ERP",
|
||||||
|
"item_name": "ERP",
|
||||||
|
"item_group": "All Item Groups"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"is_fixed_asset": 1,
|
||||||
|
"asset_category": "Softwares",
|
||||||
|
"is_stock_item": 0,
|
||||||
|
"description": "Autocad",
|
||||||
|
"item_code": "Autocad",
|
||||||
|
"item_name": "Autocad",
|
||||||
|
"item_group": "All Item Groups"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"is_stock_item": 1,
|
||||||
|
"has_batch_no": 1,
|
||||||
|
"create_new_batch": 1,
|
||||||
|
"valuation_rate": 200,
|
||||||
|
"item_defaults": [
|
||||||
|
{
|
||||||
|
"default_warehouse": "Stores"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "Corrugated Box",
|
||||||
|
"item_code": "Corrugated Box",
|
||||||
|
"item_name": "Corrugated Box",
|
||||||
|
"item_group": "All Item Groups"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"item_defaults": [
|
||||||
|
{
|
||||||
|
"default_warehouse": "Finished Goods"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"is_stock_item": 1,
|
||||||
|
"description": "OnePlus 6",
|
||||||
|
"item_code": "OnePlus 6",
|
||||||
|
"item_name": "OnePlus 6",
|
||||||
|
"item_group": "Products",
|
||||||
|
"domain": "Retail"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"item_defaults": [
|
||||||
|
{
|
||||||
|
"default_warehouse": "Finished Goods"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"is_stock_item": 1,
|
||||||
|
"description": "OnePlus 6T",
|
||||||
|
"item_code": "OnePlus 6T",
|
||||||
|
"item_name": "OnePlus 6T",
|
||||||
|
"item_group": "Products",
|
||||||
|
"domain": "Retail"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"item_defaults": [
|
||||||
|
{
|
||||||
|
"default_warehouse": "Finished Goods"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"is_stock_item": 1,
|
||||||
|
"description": "Xiaomi Poco F1",
|
||||||
|
"item_code": "Xiaomi Poco F1",
|
||||||
|
"item_name": "Xiaomi Poco F1",
|
||||||
|
"item_group": "Products",
|
||||||
|
"domain": "Retail"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"item_defaults": [
|
||||||
|
{
|
||||||
|
"default_warehouse": "Finished Goods"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"is_stock_item": 1,
|
||||||
|
"description": "Iphone XS",
|
||||||
|
"item_code": "Iphone XS",
|
||||||
|
"item_name": "Iphone XS",
|
||||||
|
"item_group": "Products",
|
||||||
|
"domain": "Retail"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"item_defaults": [
|
||||||
|
{
|
||||||
|
"default_warehouse": "Finished Goods"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"is_stock_item": 1,
|
||||||
|
"description": "Samsung Galaxy S9",
|
||||||
|
"item_code": "Samsung Galaxy S9",
|
||||||
|
"item_name": "Samsung Galaxy S9",
|
||||||
|
"item_group": "Products",
|
||||||
|
"domain": "Retail"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"item_defaults": [
|
||||||
|
{
|
||||||
|
"default_warehouse": "Finished Goods"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"is_stock_item": 1,
|
||||||
|
"description": "Sony Bluetooth Headphone",
|
||||||
|
"item_code": "Sony Bluetooth Headphone",
|
||||||
|
"item_name": "Sony Bluetooth Headphone",
|
||||||
|
"item_group": "Products",
|
||||||
|
"domain": "Retail"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"is_stock_item": 0,
|
||||||
|
"description": "Samsung Phone Repair",
|
||||||
|
"item_code": "Samsung Phone Repair",
|
||||||
|
"item_name": "Samsung Phone Repair",
|
||||||
|
"item_group": "Services",
|
||||||
|
"domain": "Retail"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"is_stock_item": 0,
|
||||||
|
"description": "OnePlus Phone Repair",
|
||||||
|
"item_code": "OnePlus Phone Repair",
|
||||||
|
"item_name": "OnePlus Phone Repair",
|
||||||
|
"item_group": "Services",
|
||||||
|
"domain": "Retail"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"is_stock_item": 0,
|
||||||
|
"description": "Xiaomi Phone Repair",
|
||||||
|
"item_code": "Xiaomi Phone Repair",
|
||||||
|
"item_name": "Xiaomi Phone Repair",
|
||||||
|
"item_group": "Services",
|
||||||
|
"domain": "Retail"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"is_stock_item": 0,
|
||||||
|
"description": "Apple Phone Repair",
|
||||||
|
"item_code": "Apple Phone Repair",
|
||||||
|
"item_name": "Apple Phone Repair",
|
||||||
|
"item_group": "Services",
|
||||||
|
"domain": "Retail"
|
||||||
|
}
|
||||||
]
|
]
|
@ -5,104 +5,104 @@
|
|||||||
"last_name": "User"
|
"last_name": "User"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"email": "DikmanShervashidze@example.com",
|
"email": "DianaPrince@example.com",
|
||||||
"first_name": "Dikman",
|
"first_name": "Diana",
|
||||||
"last_name": "Shervashidze"
|
"last_name": "Prince"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"email": "Zukutakitoteka@example.com",
|
"email": "ZatannaZatara@example.com",
|
||||||
"first_name": "Zukutakitoteka",
|
"first_name": "Zatanna",
|
||||||
"last_name": null
|
"last_name": "Zatara"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"email": "HatsueKashiwagi@example.com",
|
"email": "HollyGranger@example.com",
|
||||||
"first_name": "Hatsue",
|
"first_name": "Holly",
|
||||||
"last_name": "Kashiwagi"
|
"last_name": "Granger"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"email": "NuranVerkleij@example.com",
|
"email": "NeptuniaAquaria@example.com",
|
||||||
"first_name": "Nuran",
|
"first_name": "Neptunia",
|
||||||
"last_name": "Verkleij"
|
"last_name": "Aquaria"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"email": "aromn@example.com",
|
"email": "ArthurCurry@example.com",
|
||||||
"first_name": "Arom",
|
"first_name": "Arthur",
|
||||||
"last_name": "Nolan"
|
"last_name": "Curry"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"email": "TildeLindqvist@example.com",
|
"email": "ThaliaAlGhul@example.com",
|
||||||
"first_name": "Tilde",
|
"first_name": "Thalia",
|
||||||
"last_name": "Lindqvist"
|
"last_name": "Al Ghul"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"email": "MichalSobczak@example.com",
|
"email": "MaxwellLord@example.com",
|
||||||
"first_name": "Micha\u0142",
|
"first_name": "Maxwell",
|
||||||
"last_name": "Sobczak"
|
"last_name": "Lord"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"email": "GabrielleLoftus@example.com",
|
"email": "GraceChoi@example.com",
|
||||||
"first_name": "Gabrielle",
|
"first_name": "Grace",
|
||||||
"last_name": "Loftus"
|
"last_name": "Choi"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"email": "VakhitaRyzaev@example.com",
|
"email": "VandalSavage@example.com",
|
||||||
"first_name": "Vakhita",
|
"first_name": "Vandal",
|
||||||
"last_name": "Ryzaev"
|
"last_name": "Savage"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"email": "CharmaineGaudreau@example.com",
|
"email": "CaitlinSnow@example.com",
|
||||||
"first_name": "Charmaine",
|
"first_name": "Caitlin",
|
||||||
"last_name": "Gaudreau"
|
"last_name": "Snow"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"email": "RafaelaMaartens@example.com",
|
"email": "RipHunter@example.com",
|
||||||
"first_name": "Rafa\u00ebla",
|
"first_name": "Rip",
|
||||||
"last_name": "Maartens"
|
"last_name": "Hunter"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"email": "NuguseYohannes@example.com",
|
"email": "NicholasFury@example.com",
|
||||||
"first_name": "Nuguse",
|
"first_name": "Nicholas",
|
||||||
"last_name": "Yohannes"
|
"last_name": "Fury"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"email": "panca@example.com",
|
"email": "PeterParker@example.com",
|
||||||
"first_name": "\u0420\u0430\u0438\u0441\u0430",
|
"first_name": "Peter",
|
||||||
"last_name": "\u0411\u0435\u043b\u044f\u043a\u043e\u0432\u0430"
|
"last_name": "Parker"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"email": "CaYinLong@example.com",
|
"email": "JohnConstantine@example.com",
|
||||||
"first_name": "\u80e4\u9686",
|
"first_name": "John",
|
||||||
"last_name": "\u8521"
|
"last_name": "Constantine"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"email": "FreddieScott@example.com",
|
"email": "HalJordan@example.com",
|
||||||
"first_name": "Freddie",
|
"first_name": "Hal",
|
||||||
"last_name": "Scott"
|
"last_name": "Jordan"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"email": "BergoraVigfusdottir@example.com",
|
"email": "VictorStone@example.com",
|
||||||
"first_name": "Berg\u00fe\u00f3ra",
|
"first_name": "Victor",
|
||||||
"last_name": "Vigf\u00fasd\u00f3ttir"
|
"last_name": "Stone"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"email": "WardNajmalDinKalb@example.com",
|
"email": "BruceWayne@example.com",
|
||||||
"first_name": "Ward",
|
"first_name": "Bruce",
|
||||||
"last_name": "Kalb"
|
"last_name": "Wayne"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"email": "WanMai@example.com",
|
"email": "ClarkKent@example.com",
|
||||||
"first_name": "Wan",
|
"first_name": "Clark",
|
||||||
"last_name": "Mai"
|
"last_name": "Kent"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"email": "LeonAbdulov@example.com",
|
"email": "BarryAllen@example.com",
|
||||||
"first_name": "Leon",
|
"first_name": "Barry",
|
||||||
"last_name": "Abdulov"
|
"last_name": "Allen"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"email": "SabinaNovotna@example.com",
|
"email": "KaraZorEl@example.com",
|
||||||
"first_name": "Sabina",
|
"first_name": "Kara",
|
||||||
"last_name": "Novotn\u00e1"
|
"last_name": "Zor El"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"email": "demo@erpnext.com",
|
"email": "demo@erpnext.com",
|
||||||
|
@ -3,8 +3,9 @@ from __future__ import unicode_literals
|
|||||||
import frappe, sys
|
import frappe, sys
|
||||||
import erpnext
|
import erpnext
|
||||||
import frappe.utils
|
import frappe.utils
|
||||||
from erpnext.demo.user import hr, sales, purchase, manufacturing, stock, accounts, projects, fixed_asset, education
|
from erpnext.demo.user import hr, sales, purchase, manufacturing, stock, accounts, projects, fixed_asset
|
||||||
from erpnext.demo.setup import education, manufacture, setup_data, healthcare
|
from erpnext.demo.user import education as edu
|
||||||
|
from erpnext.demo.setup import education, manufacture, setup_data, healthcare, retail
|
||||||
"""
|
"""
|
||||||
Make a demo
|
Make a demo
|
||||||
|
|
||||||
@ -28,6 +29,8 @@ def make(domain='Manufacturing', days=100):
|
|||||||
setup_data.setup(domain)
|
setup_data.setup(domain)
|
||||||
if domain== 'Manufacturing':
|
if domain== 'Manufacturing':
|
||||||
manufacture.setup_data()
|
manufacture.setup_data()
|
||||||
|
elif domain == "Retail":
|
||||||
|
retail.setup_data()
|
||||||
elif domain== 'Education':
|
elif domain== 'Education':
|
||||||
education.setup_data()
|
education.setup_data()
|
||||||
elif domain== 'Healthcare':
|
elif domain== 'Healthcare':
|
||||||
@ -77,13 +80,13 @@ def simulate(domain='Manufacturing', days=100):
|
|||||||
stock.work()
|
stock.work()
|
||||||
accounts.work()
|
accounts.work()
|
||||||
projects.run_projects(current_date)
|
projects.run_projects(current_date)
|
||||||
|
sales.work(domain)
|
||||||
# run_messages()
|
# run_messages()
|
||||||
|
|
||||||
if domain=='Manufacturing':
|
if domain=='Manufacturing':
|
||||||
sales.work()
|
|
||||||
manufacturing.work()
|
manufacturing.work()
|
||||||
elif domain=='Education':
|
elif domain=='Education':
|
||||||
education.work()
|
edu.work()
|
||||||
|
|
||||||
except:
|
except:
|
||||||
frappe.db.set_global('demo_last_date', current_date)
|
frappe.db.set_global('demo_last_date', current_date)
|
||||||
|
@ -5,7 +5,7 @@ data = {
|
|||||||
'company_name': 'Wind Power LLC'
|
'company_name': 'Wind Power LLC'
|
||||||
},
|
},
|
||||||
'Retail': {
|
'Retail': {
|
||||||
'company_name': 'Annapurna Dairy Shop',
|
'company_name': 'Mobile Next',
|
||||||
},
|
},
|
||||||
'Distribution': {
|
'Distribution': {
|
||||||
'company_name': 'Soltice Hardware',
|
'company_name': 'Soltice Hardware',
|
||||||
|
65
erpnext/demo/setup/retail.py
Normal file
65
erpnext/demo/setup/retail.py
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
import random, json
|
||||||
|
import frappe
|
||||||
|
from frappe.utils import nowdate, add_days
|
||||||
|
from erpnext.demo.setup.setup_data import import_json
|
||||||
|
from erpnext.demo.domains import data
|
||||||
|
|
||||||
|
from six import iteritems
|
||||||
|
|
||||||
|
def setup_data():
|
||||||
|
setup_item()
|
||||||
|
setup_item_price()
|
||||||
|
frappe.db.commit()
|
||||||
|
frappe.clear_cache()
|
||||||
|
|
||||||
|
def setup_item():
|
||||||
|
items = json.loads(open(frappe.get_app_path('erpnext', 'demo', 'data', 'item.json')).read())
|
||||||
|
for i in items:
|
||||||
|
if not i.get("domain") == "Retail": continue
|
||||||
|
item = frappe.new_doc('Item')
|
||||||
|
item.update(i)
|
||||||
|
if hasattr(item, 'item_defaults') and item.item_defaults[0].default_warehouse:
|
||||||
|
item.item_defaults[0].company = data.get("Retail").get('company_name')
|
||||||
|
warehouse = frappe.get_all('Warehouse', filters={'warehouse_name': item.item_defaults[0].default_warehouse}, limit=1)
|
||||||
|
if warehouse:
|
||||||
|
item.item_defaults[0].default_warehouse = warehouse[0].name
|
||||||
|
item.insert()
|
||||||
|
|
||||||
|
def setup_item_price():
|
||||||
|
frappe.db.sql("delete from `tabItem Price`")
|
||||||
|
|
||||||
|
standard_selling = {
|
||||||
|
"OnePlus 6": 579,
|
||||||
|
"OnePlus 6T": 600,
|
||||||
|
"Xiaomi Poco F1": 300,
|
||||||
|
"Iphone XS": 999,
|
||||||
|
"Samsung Galaxy S9": 720,
|
||||||
|
"Sony Bluetooth Headphone": 99,
|
||||||
|
"Xiaomi Phone Repair": 10,
|
||||||
|
"Samsung Phone Repair": 20,
|
||||||
|
"OnePlus Phone Repair": 15,
|
||||||
|
"Apple Phone Repair": 30,
|
||||||
|
}
|
||||||
|
|
||||||
|
standard_buying = {
|
||||||
|
"OnePlus 6": 300,
|
||||||
|
"OnePlus 6T": 350,
|
||||||
|
"Xiaomi Poco F1": 200,
|
||||||
|
"Iphone XS": 600,
|
||||||
|
"Samsung Galaxy S9": 500,
|
||||||
|
"Sony Bluetooth Headphone": 69
|
||||||
|
}
|
||||||
|
|
||||||
|
for price_list in ("standard_buying", "standard_selling"):
|
||||||
|
for item, rate in iteritems(locals().get(price_list)):
|
||||||
|
frappe.get_doc({
|
||||||
|
"doctype": "Item Price",
|
||||||
|
"price_list": price_list.replace("_", " ").title(),
|
||||||
|
"item_code": item,
|
||||||
|
"selling": 1 if price_list=="standard_selling" else 0,
|
||||||
|
"buying": 1 if price_list=="standard_buying" else 0,
|
||||||
|
"price_list_rate": rate,
|
||||||
|
"currency": "USD"
|
||||||
|
}).insert()
|
@ -5,6 +5,7 @@ import frappe, erpnext
|
|||||||
from frappe.utils.nestedset import get_root_of
|
from frappe.utils.nestedset import get_root_of
|
||||||
from frappe.utils import flt, now_datetime, cstr, random_string
|
from frappe.utils import flt, now_datetime, cstr, random_string
|
||||||
from frappe.utils.make_random import add_random_children, get_random
|
from frappe.utils.make_random import add_random_children, get_random
|
||||||
|
from frappe.custom.doctype.custom_field.custom_field import create_custom_fields
|
||||||
from erpnext.demo.domains import data
|
from erpnext.demo.domains import data
|
||||||
from frappe import _
|
from frappe import _
|
||||||
|
|
||||||
@ -14,9 +15,10 @@ def setup(domain):
|
|||||||
setup_fiscal_year()
|
setup_fiscal_year()
|
||||||
setup_holiday_list()
|
setup_holiday_list()
|
||||||
setup_user()
|
setup_user()
|
||||||
#setup_employee()
|
setup_employee()
|
||||||
setup_user_roles()
|
setup_user_roles()
|
||||||
setup_role_permissions()
|
setup_role_permissions()
|
||||||
|
setup_custom_field_for_domain()
|
||||||
|
|
||||||
employees = frappe.get_all('Employee', fields=['name', 'date_of_joining'])
|
employees = frappe.get_all('Employee', fields=['name', 'date_of_joining'])
|
||||||
|
|
||||||
@ -120,7 +122,7 @@ def setup_user():
|
|||||||
user = frappe.new_doc("User")
|
user = frappe.new_doc("User")
|
||||||
user.update(u)
|
user.update(u)
|
||||||
user.flags.no_welcome_mail = True
|
user.flags.no_welcome_mail = True
|
||||||
user.new_password = 'demo'
|
user.new_password = 'Demo1234567!!!'
|
||||||
user.insert()
|
user.insert()
|
||||||
|
|
||||||
def setup_employee():
|
def setup_employee():
|
||||||
@ -136,6 +138,8 @@ def setup_employee():
|
|||||||
salary_component.save()
|
salary_component.save()
|
||||||
|
|
||||||
import_json('Employee')
|
import_json('Employee')
|
||||||
|
holiday_list = frappe.db.get_value("Holiday List", {"holiday_list_name": str(now_datetime().year)}, 'name')
|
||||||
|
frappe.db.sql('''update tabEmployee set holiday_list={0}'''.format(holiday_list))
|
||||||
|
|
||||||
def setup_salary_structure(employees, salary_slip_based_on_timesheet=0):
|
def setup_salary_structure(employees, salary_slip_based_on_timesheet=0):
|
||||||
ss = frappe.new_doc('Salary Structure')
|
ss = frappe.new_doc('Salary Structure')
|
||||||
@ -166,12 +170,16 @@ def setup_salary_structure(employees, salary_slip_based_on_timesheet=0):
|
|||||||
"idx": 1
|
"idx": 1
|
||||||
})
|
})
|
||||||
ss.insert()
|
ss.insert()
|
||||||
|
ss.submit()
|
||||||
|
|
||||||
for e in employees:
|
for e in employees:
|
||||||
sa = frappe.new_doc("Salary Structure Assignment")
|
sa = frappe.new_doc("Salary Structure Assignment")
|
||||||
sa.employee = e.name
|
sa.employee = e.name
|
||||||
|
sa.salary_structure = ss.name
|
||||||
sa.from_date = "2015-01-01"
|
sa.from_date = "2015-01-01"
|
||||||
sa.base = random.random() * 10000
|
sa.base = random.random() * 10000
|
||||||
|
sa.insert()
|
||||||
|
sa.submit()
|
||||||
|
|
||||||
return ss
|
return ss
|
||||||
|
|
||||||
@ -184,52 +192,63 @@ def setup_user_roles():
|
|||||||
'Nursing User', 'Patient')
|
'Nursing User', 'Patient')
|
||||||
|
|
||||||
if not frappe.db.get_global('demo_hr_user'):
|
if not frappe.db.get_global('demo_hr_user'):
|
||||||
user = frappe.get_doc('User', 'CharmaineGaudreau@example.com')
|
user = frappe.get_doc('User', 'CaitlinSnow@example.com')
|
||||||
user.add_roles('HR User', 'HR Manager', 'Accounts User')
|
user.add_roles('HR User', 'HR Manager', 'Accounts User')
|
||||||
frappe.db.set_global('demo_hr_user', user.name)
|
frappe.db.set_global('demo_hr_user', user.name)
|
||||||
|
update_employee_department(user.name, 'Human Resources')
|
||||||
|
for d in frappe.get_all('User Permission', filters={"user": "CaitlinSnow@example.com"}):
|
||||||
|
frappe.delete_doc('User Permission', d.name)
|
||||||
|
|
||||||
if not frappe.db.get_global('demo_sales_user_1'):
|
if not frappe.db.get_global('demo_sales_user_1'):
|
||||||
user = frappe.get_doc('User', 'VakhitaRyzaev@example.com')
|
user = frappe.get_doc('User', 'VandalSavage@example.com')
|
||||||
user.add_roles('Sales User')
|
user.add_roles('Sales User')
|
||||||
|
update_employee_department(user.name, 'Sales')
|
||||||
frappe.db.set_global('demo_sales_user_1', user.name)
|
frappe.db.set_global('demo_sales_user_1', user.name)
|
||||||
|
|
||||||
if not frappe.db.get_global('demo_sales_user_2'):
|
if not frappe.db.get_global('demo_sales_user_2'):
|
||||||
user = frappe.get_doc('User', 'GabrielleLoftus@example.com')
|
user = frappe.get_doc('User', 'GraceChoi@example.com')
|
||||||
user.add_roles('Sales User', 'Sales Manager', 'Accounts User')
|
user.add_roles('Sales User', 'Sales Manager', 'Accounts User')
|
||||||
|
update_employee_department(user.name, 'Sales')
|
||||||
frappe.db.set_global('demo_sales_user_2', user.name)
|
frappe.db.set_global('demo_sales_user_2', user.name)
|
||||||
|
|
||||||
if not frappe.db.get_global('demo_purchase_user'):
|
if not frappe.db.get_global('demo_purchase_user'):
|
||||||
user = frappe.get_doc('User', 'MichalSobczak@example.com')
|
user = frappe.get_doc('User', 'MaxwellLord@example.com')
|
||||||
user.add_roles('Purchase User', 'Purchase Manager', 'Accounts User', 'Stock User')
|
user.add_roles('Purchase User', 'Purchase Manager', 'Accounts User', 'Stock User')
|
||||||
|
update_employee_department(user.name, 'Purchase')
|
||||||
frappe.db.set_global('demo_purchase_user', user.name)
|
frappe.db.set_global('demo_purchase_user', user.name)
|
||||||
|
|
||||||
if not frappe.db.get_global('demo_manufacturing_user'):
|
if not frappe.db.get_global('demo_manufacturing_user'):
|
||||||
user = frappe.get_doc('User', 'NuranVerkleij@example.com')
|
user = frappe.get_doc('User', 'NeptuniaAquaria@example.com')
|
||||||
user.add_roles('Manufacturing User', 'Stock User', 'Purchase User', 'Accounts User')
|
user.add_roles('Manufacturing User', 'Stock User', 'Purchase User', 'Accounts User')
|
||||||
|
update_employee_department(user.name, 'Production')
|
||||||
frappe.db.set_global('demo_manufacturing_user', user.name)
|
frappe.db.set_global('demo_manufacturing_user', user.name)
|
||||||
|
|
||||||
if not frappe.db.get_global('demo_stock_user'):
|
if not frappe.db.get_global('demo_stock_user'):
|
||||||
user = frappe.get_doc('User', 'HatsueKashiwagi@example.com')
|
user = frappe.get_doc('User', 'HollyGranger@example.com')
|
||||||
user.add_roles('Manufacturing User', 'Stock User', 'Purchase User', 'Accounts User')
|
user.add_roles('Manufacturing User', 'Stock User', 'Purchase User', 'Accounts User')
|
||||||
|
update_employee_department(user.name, 'Production')
|
||||||
frappe.db.set_global('demo_stock_user', user.name)
|
frappe.db.set_global('demo_stock_user', user.name)
|
||||||
|
|
||||||
if not frappe.db.get_global('demo_accounts_user'):
|
if not frappe.db.get_global('demo_accounts_user'):
|
||||||
user = frappe.get_doc('User', 'LeonAbdulov@example.com')
|
user = frappe.get_doc('User', 'BarryAllen@example.com')
|
||||||
user.add_roles('Accounts User', 'Accounts Manager', 'Sales User', 'Purchase User')
|
user.add_roles('Accounts User', 'Accounts Manager', 'Sales User', 'Purchase User')
|
||||||
|
update_employee_department(user.name, 'Accounts')
|
||||||
frappe.db.set_global('demo_accounts_user', user.name)
|
frappe.db.set_global('demo_accounts_user', user.name)
|
||||||
|
|
||||||
if not frappe.db.get_global('demo_projects_user'):
|
if not frappe.db.get_global('demo_projects_user'):
|
||||||
user = frappe.get_doc('User', 'panca@example.com')
|
user = frappe.get_doc('User', 'PeterParker@example.com')
|
||||||
user.add_roles('HR User', 'Projects User')
|
user.add_roles('HR User', 'Projects User')
|
||||||
|
update_employee_department(user.name, 'Management')
|
||||||
frappe.db.set_global('demo_projects_user', user.name)
|
frappe.db.set_global('demo_projects_user', user.name)
|
||||||
|
|
||||||
if not frappe.db.get_global('demo_education_user'):
|
if not frappe.db.get_global('demo_education_user'):
|
||||||
user = frappe.get_doc('User', 'aromn@example.com')
|
user = frappe.get_doc('User', 'ArthurCurry@example.com')
|
||||||
user.add_roles('Academics User')
|
user.add_roles('Academics User')
|
||||||
|
update_employee_department(user.name, 'Management')
|
||||||
frappe.db.set_global('demo_education_user', user.name)
|
frappe.db.set_global('demo_education_user', user.name)
|
||||||
|
|
||||||
#Add Expense Approver
|
#Add Expense Approver
|
||||||
user = frappe.get_doc('User', 'WanMai@example.com')
|
user = frappe.get_doc('User', 'ClarkKent@example.com')
|
||||||
user.add_roles('Expense Approver')
|
user.add_roles('Expense Approver')
|
||||||
|
|
||||||
def setup_leave_allocation():
|
def setup_leave_allocation():
|
||||||
@ -403,3 +422,19 @@ def import_json(doctype, submit=False, values=None):
|
|||||||
frappe.db.commit()
|
frappe.db.commit()
|
||||||
|
|
||||||
frappe.flags.in_import = False
|
frappe.flags.in_import = False
|
||||||
|
|
||||||
|
def update_employee_department(user_id, department):
|
||||||
|
employee = frappe.db.get_value('Employee', {"user_id": user_id}, 'name')
|
||||||
|
department = frappe.db.get_value('Department', {'department_name': department}, 'name')
|
||||||
|
frappe.db.set_value('Employee', employee, 'department', department)
|
||||||
|
|
||||||
|
def setup_custom_field_for_domain():
|
||||||
|
field = {
|
||||||
|
"Item": [
|
||||||
|
dict(fieldname='domain', label='Domain',
|
||||||
|
fieldtype='Select', hidden=1, default="Manufacturing",
|
||||||
|
options="Manufacturing\nService\nDistribution\nRetail"
|
||||||
|
)
|
||||||
|
]
|
||||||
|
}
|
||||||
|
create_custom_fields(field)
|
||||||
|
@ -56,7 +56,7 @@ def work():
|
|||||||
if random.random() < 0.5:
|
if random.random() < 0.5:
|
||||||
make_payment_entries("Purchase Invoice", "Accounts Payable")
|
make_payment_entries("Purchase Invoice", "Accounts Payable")
|
||||||
|
|
||||||
if random.random() < 0.1:
|
if random.random() < 0.4:
|
||||||
#make payment request against sales invoice
|
#make payment request against sales invoice
|
||||||
sales_invoice_name = get_random("Sales Invoice", filters={"docstatus": 1})
|
sales_invoice_name = get_random("Sales Invoice", filters={"docstatus": 1})
|
||||||
if sales_invoice_name:
|
if sales_invoice_name:
|
||||||
|
@ -14,34 +14,31 @@ from erpnext.hr.doctype.leave_application.leave_application import (get_leave_ba
|
|||||||
def work():
|
def work():
|
||||||
frappe.set_user(frappe.db.get_global('demo_hr_user'))
|
frappe.set_user(frappe.db.get_global('demo_hr_user'))
|
||||||
year, month = frappe.flags.current_date.strftime("%Y-%m").split("-")
|
year, month = frappe.flags.current_date.strftime("%Y-%m").split("-")
|
||||||
|
setup_department_approvers()
|
||||||
mark_attendance()
|
mark_attendance()
|
||||||
make_leave_application()
|
make_leave_application()
|
||||||
|
|
||||||
# payroll entry
|
# payroll entry
|
||||||
if not frappe.db.sql('select name from `tabSalary Slip` where month(adddate(start_date, interval 1 month))=month(curdate())'):
|
if not frappe.db.sql('select name from `tabSalary Slip` where month(adddate(start_date, interval 1 month))=month(curdate())'):
|
||||||
# process payroll for previous month
|
|
||||||
payroll_entry = frappe.new_doc("Payroll Entry")
|
|
||||||
payroll_entry.company = frappe.flags.company
|
|
||||||
payroll_entry.payroll_frequency = 'Monthly'
|
|
||||||
|
|
||||||
# select a posting date from the previous month
|
|
||||||
payroll_entry.posting_date = get_last_day(getdate(frappe.flags.current_date) - datetime.timedelta(days=10))
|
|
||||||
payroll_entry.payment_account = frappe.get_value('Account', {'account_type': 'Cash', 'company': erpnext.get_default_company(),'is_group':0}, "name")
|
|
||||||
|
|
||||||
payroll_entry.set_start_end_dates()
|
|
||||||
|
|
||||||
# based on frequency
|
# based on frequency
|
||||||
|
payroll_entry = get_payroll_entry()
|
||||||
payroll_entry.salary_slip_based_on_timesheet = 0
|
payroll_entry.salary_slip_based_on_timesheet = 0
|
||||||
|
payroll_entry.save()
|
||||||
payroll_entry.create_salary_slips()
|
payroll_entry.create_salary_slips()
|
||||||
payroll_entry.submit_salary_slips()
|
payroll_entry.submit_salary_slips()
|
||||||
payroll_entry.make_accrual_jv_entry()
|
payroll_entry.make_accrual_jv_entry()
|
||||||
|
payroll_entry.submit()
|
||||||
# payroll_entry.make_journal_entry(reference_date=frappe.flags.current_date,
|
# payroll_entry.make_journal_entry(reference_date=frappe.flags.current_date,
|
||||||
# reference_number=random_string(10))
|
# reference_number=random_string(10))
|
||||||
|
|
||||||
|
# based on timesheet
|
||||||
|
payroll_entry = get_payroll_entry()
|
||||||
payroll_entry.salary_slip_based_on_timesheet = 1
|
payroll_entry.salary_slip_based_on_timesheet = 1
|
||||||
|
payroll_entry.save()
|
||||||
payroll_entry.create_salary_slips()
|
payroll_entry.create_salary_slips()
|
||||||
payroll_entry.submit_salary_slips()
|
payroll_entry.submit_salary_slips()
|
||||||
payroll_entry.make_accrual_jv_entry()
|
payroll_entry.make_accrual_jv_entry()
|
||||||
|
payroll_entry.submit()
|
||||||
# payroll_entry.make_journal_entry(reference_date=frappe.flags.current_date,
|
# payroll_entry.make_journal_entry(reference_date=frappe.flags.current_date,
|
||||||
# reference_number=random_string(10))
|
# reference_number=random_string(10))
|
||||||
|
|
||||||
@ -55,12 +52,14 @@ def work():
|
|||||||
expense_claim.company = frappe.flags.company
|
expense_claim.company = frappe.flags.company
|
||||||
expense_claim.payable_account = get_payable_account(expense_claim.company)
|
expense_claim.payable_account = get_payable_account(expense_claim.company)
|
||||||
expense_claim.posting_date = frappe.flags.current_date
|
expense_claim.posting_date = frappe.flags.current_date
|
||||||
expense_claim.insert()
|
expense_claim.expense_approver = frappe.db.get_global('demo_hr_user')
|
||||||
|
expense_claim.save()
|
||||||
|
|
||||||
rand = random.random()
|
rand = random.random()
|
||||||
|
|
||||||
if rand < 0.4:
|
if rand < 0.4:
|
||||||
update_sanctioned_amount(expense_claim)
|
update_sanctioned_amount(expense_claim)
|
||||||
|
expense_claim.approval_status = 'Approved'
|
||||||
expense_claim.submit()
|
expense_claim.submit()
|
||||||
|
|
||||||
if random.randint(0, 1):
|
if random.randint(0, 1):
|
||||||
@ -72,6 +71,19 @@ def work():
|
|||||||
je.flags.ignore_permissions = 1
|
je.flags.ignore_permissions = 1
|
||||||
je.submit()
|
je.submit()
|
||||||
|
|
||||||
|
def get_payroll_entry():
|
||||||
|
# process payroll for previous month
|
||||||
|
payroll_entry = frappe.new_doc("Payroll Entry")
|
||||||
|
payroll_entry.company = frappe.flags.company
|
||||||
|
payroll_entry.payroll_frequency = 'Monthly'
|
||||||
|
|
||||||
|
# select a posting date from the previous month
|
||||||
|
payroll_entry.posting_date = get_last_day(getdate(frappe.flags.current_date) - datetime.timedelta(days=10))
|
||||||
|
payroll_entry.payment_account = frappe.get_value('Account', {'account_type': 'Cash', 'company': erpnext.get_default_company(),'is_group':0}, "name")
|
||||||
|
|
||||||
|
payroll_entry.set_start_end_dates()
|
||||||
|
return payroll_entry
|
||||||
|
|
||||||
def get_expenses():
|
def get_expenses():
|
||||||
expenses = []
|
expenses = []
|
||||||
expese_types = frappe.db.sql("""select ect.name, eca.default_account from `tabExpense Claim Type` ect,
|
expese_types = frappe.db.sql("""select ect.name, eca.default_account from `tabExpense Claim Type` ect,
|
||||||
@ -114,7 +126,7 @@ def get_timesheet_based_salary_slip_employee():
|
|||||||
def make_timesheet_records():
|
def make_timesheet_records():
|
||||||
employees = get_timesheet_based_salary_slip_employee()
|
employees = get_timesheet_based_salary_slip_employee()
|
||||||
for e in employees:
|
for e in employees:
|
||||||
ts = make_timesheet(e.employee, simulate = True, billable = 1, activity_type=get_random("Activity Type"))
|
ts = make_timesheet(e.employee, simulate = True, billable = 1, activity_type=get_random("Activity Type"), company=frappe.flags.company)
|
||||||
frappe.db.commit()
|
frappe.db.commit()
|
||||||
|
|
||||||
rand = random.random()
|
rand = random.random()
|
||||||
@ -195,3 +207,11 @@ def mark_attendance():
|
|||||||
attendance.save()
|
attendance.save()
|
||||||
attendance.submit()
|
attendance.submit()
|
||||||
frappe.db.commit()
|
frappe.db.commit()
|
||||||
|
|
||||||
|
def setup_department_approvers():
|
||||||
|
for d in frappe.get_all('Department', filters={'department_name': ['!=', 'All Departments']}):
|
||||||
|
doc = frappe.get_doc('Department', d.name)
|
||||||
|
doc.append("leave_approvers", {'approver': frappe.session.user})
|
||||||
|
doc.append("expense_approvers", {'approver': frappe.session.user})
|
||||||
|
doc.flags.ignore_mandatory = True
|
||||||
|
doc.save()
|
||||||
|
@ -4,25 +4,32 @@
|
|||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
import frappe, random, erpnext
|
import frappe, random, erpnext
|
||||||
|
from datetime import timedelta
|
||||||
from frappe.utils.make_random import how_many
|
from frappe.utils.make_random import how_many
|
||||||
from frappe.desk import query_report
|
from frappe.desk import query_report
|
||||||
from erpnext.manufacturing.doctype.workstation.workstation import WorkstationHolidayError
|
from erpnext.manufacturing.doctype.workstation.workstation import WorkstationHolidayError
|
||||||
from erpnext.manufacturing.doctype.work_order.test_work_order import make_wo_order_test_record
|
from erpnext.manufacturing.doctype.work_order.test_work_order import make_wo_order_test_record
|
||||||
|
|
||||||
def work():
|
def work():
|
||||||
|
if random.random() < 0.3: return
|
||||||
|
|
||||||
frappe.set_user(frappe.db.get_global('demo_manufacturing_user'))
|
frappe.set_user(frappe.db.get_global('demo_manufacturing_user'))
|
||||||
|
if not frappe.get_all('Sales Order'): return
|
||||||
|
|
||||||
from erpnext.projects.doctype.timesheet.timesheet import OverlapError
|
from erpnext.projects.doctype.timesheet.timesheet import OverlapError
|
||||||
|
|
||||||
ppt = frappe.get_doc("Production Planning Tool", "Production Planning Tool")
|
ppt = frappe.new_doc("Production Plan")
|
||||||
ppt.company = erpnext.get_default_company()
|
ppt.company = erpnext.get_default_company()
|
||||||
ppt.use_multi_level_bom = 1
|
# ppt.use_multi_level_bom = 1 #refactored
|
||||||
ppt.get_items_from = "Sales Order"
|
ppt.get_items_from = "Sales Order"
|
||||||
ppt.purchase_request_for_warehouse = "Stores - WPL"
|
# ppt.purchase_request_for_warehouse = "Stores - WPL" # refactored
|
||||||
ppt.run_method("get_open_sales_orders")
|
ppt.run_method("get_open_sales_orders")
|
||||||
|
if not ppt.get("sales_orders"): return
|
||||||
ppt.run_method("get_items")
|
ppt.run_method("get_items")
|
||||||
ppt.run_method("raise_work_orders")
|
|
||||||
ppt.run_method("raise_material_requests")
|
ppt.run_method("raise_material_requests")
|
||||||
|
ppt.save()
|
||||||
|
ppt.submit()
|
||||||
|
ppt.run_method("raise_work_orders")
|
||||||
frappe.db.commit()
|
frappe.db.commit()
|
||||||
|
|
||||||
# submit work orders
|
# submit work orders
|
||||||
@ -39,12 +46,12 @@ def work():
|
|||||||
frappe.db.commit()
|
frappe.db.commit()
|
||||||
|
|
||||||
# stores -> wip
|
# stores -> wip
|
||||||
if random.random() < 0.3:
|
if random.random() < 0.4:
|
||||||
for pro in query_report.run("Open Work Orders")["result"][:how_many("Stock Entry for WIP")]:
|
for pro in query_report.run("Open Work Orders")["result"][:how_many("Stock Entry for WIP")]:
|
||||||
make_stock_entry_from_pro(pro[0], "Material Transfer for Manufacture")
|
make_stock_entry_from_pro(pro[0], "Material Transfer for Manufacture")
|
||||||
|
|
||||||
# wip -> fg
|
# wip -> fg
|
||||||
if random.random() < 0.3:
|
if random.random() < 0.4:
|
||||||
for pro in query_report.run("Work Orders in Progress")["result"][:how_many("Stock Entry for FG")]:
|
for pro in query_report.run("Work Orders in Progress")["result"][:how_many("Stock Entry for FG")]:
|
||||||
make_stock_entry_from_pro(pro[0], "Manufacture")
|
make_stock_entry_from_pro(pro[0], "Manufacture")
|
||||||
|
|
||||||
@ -55,17 +62,9 @@ def work():
|
|||||||
stock_uom = frappe.db.get_value('Item', bom.item, 'stock_uom'),
|
stock_uom = frappe.db.get_value('Item', bom.item, 'stock_uom'),
|
||||||
planned_start_date = frappe.flags.current_date)
|
planned_start_date = frappe.flags.current_date)
|
||||||
|
|
||||||
# submit time logs
|
# submit job card
|
||||||
for timesheet in frappe.get_all("Timesheet", ["name"], {"docstatus": 0,
|
if random.random() < 0.4:
|
||||||
"work_order": ("!=", ""), "to_time": ("<", frappe.flags.current_date)}):
|
submit_job_cards()
|
||||||
timesheet = frappe.get_doc("Timesheet", timesheet.name)
|
|
||||||
try:
|
|
||||||
timesheet.submit()
|
|
||||||
frappe.db.commit()
|
|
||||||
except OverlapError:
|
|
||||||
pass
|
|
||||||
except WorkstationHolidayError:
|
|
||||||
pass
|
|
||||||
|
|
||||||
def make_stock_entry_from_pro(pro_id, purpose):
|
def make_stock_entry_from_pro(pro_id, purpose):
|
||||||
from erpnext.manufacturing.doctype.work_order.work_order import make_stock_entry
|
from erpnext.manufacturing.doctype.work_order.work_order import make_stock_entry
|
||||||
@ -86,3 +85,27 @@ def make_stock_entry_from_pro(pro_id, purpose):
|
|||||||
except (NegativeStockError, IncorrectValuationRateError, DuplicateEntryForWorkOrderError,
|
except (NegativeStockError, IncorrectValuationRateError, DuplicateEntryForWorkOrderError,
|
||||||
OperationsNotCompleteError):
|
OperationsNotCompleteError):
|
||||||
frappe.db.rollback()
|
frappe.db.rollback()
|
||||||
|
|
||||||
|
def submit_job_cards():
|
||||||
|
work_orders = frappe.get_all("Work Order", ["name", "creation"], {"docstatus": 1, "status": "Not Started"})
|
||||||
|
work_order = random.choice(work_orders)
|
||||||
|
# for work_order in work_orders:
|
||||||
|
start_date = work_order.creation
|
||||||
|
work_order = frappe.get_doc("Work Order", work_order.name)
|
||||||
|
job = frappe.get_all("Job Card", ["name", "operation", "work_order"],
|
||||||
|
{"docstatus": 0, "work_order": work_order.name})
|
||||||
|
|
||||||
|
if not job: return
|
||||||
|
job_map = {}
|
||||||
|
for d in job:
|
||||||
|
job_map[d.operation] = frappe.get_doc("Job Card", d.name)
|
||||||
|
|
||||||
|
for operation in work_order.operations:
|
||||||
|
job = job_map[operation.operation]
|
||||||
|
job.actual_start_date = start_date
|
||||||
|
minutes = operation.get("time_in_mins")
|
||||||
|
random_minutes = random.randint(int(minutes/2), minutes)
|
||||||
|
job.actual_end_date = job.actual_start_date + timedelta(minutes=random_minutes)
|
||||||
|
start_date = job.actual_end_date
|
||||||
|
job.save()
|
||||||
|
job.submit()
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
import frappe
|
import frappe, erpnext
|
||||||
from frappe.utils import flt
|
from frappe.utils import flt
|
||||||
from frappe.utils.make_random import get_random
|
from frappe.utils.make_random import get_random
|
||||||
from erpnext.projects.doctype.timesheet.test_timesheet import make_timesheet
|
from erpnext.projects.doctype.timesheet.test_timesheet import make_timesheet
|
||||||
@ -19,7 +19,7 @@ def run_projects(current_date):
|
|||||||
def make_timesheet_for_projects(current_date ):
|
def make_timesheet_for_projects(current_date ):
|
||||||
for data in frappe.get_all("Task", ["name", "project"], {"status": "Open", "exp_end_date": ("<", current_date)}):
|
for data in frappe.get_all("Task", ["name", "project"], {"status": "Open", "exp_end_date": ("<", current_date)}):
|
||||||
employee = get_random("Employee")
|
employee = get_random("Employee")
|
||||||
ts = make_timesheet(employee, simulate = True, billable = 1,
|
ts = make_timesheet(employee, simulate = True, billable = 1, company = erpnext.get_default_company(),
|
||||||
activity_type=get_random("Activity Type"), project=data.project, task =data.name)
|
activity_type=get_random("Activity Type"), project=data.project, task =data.name)
|
||||||
|
|
||||||
if flt(ts.total_billable_amount) > 0.0:
|
if flt(ts.total_billable_amount) > 0.0:
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
import frappe, random
|
import frappe, random, json, erpnext
|
||||||
from frappe.utils.make_random import how_many, get_random
|
from frappe.utils.make_random import how_many, get_random
|
||||||
from frappe.desk import query_report
|
from frappe.desk import query_report
|
||||||
from erpnext.setup.utils import get_exchange_rate
|
from erpnext.setup.utils import get_exchange_rate
|
||||||
@ -16,14 +16,14 @@ from erpnext.buying.doctype.request_for_quotation.request_for_quotation import \
|
|||||||
def work():
|
def work():
|
||||||
frappe.set_user(frappe.db.get_global('demo_purchase_user'))
|
frappe.set_user(frappe.db.get_global('demo_purchase_user'))
|
||||||
|
|
||||||
if random.random() < 0.3:
|
if random.random() < 0.6:
|
||||||
report = "Items To Be Requested"
|
report = "Items To Be Requested"
|
||||||
for row in query_report.run(report)["result"][:random.randint(1, 5)]:
|
for row in query_report.run(report)["result"][:random.randint(1, 5)]:
|
||||||
item_code, qty = row[0], abs(row[-1])
|
item_code, qty = row[0], abs(row[-1])
|
||||||
|
|
||||||
mr = make_material_request(item_code, qty)
|
mr = make_material_request(item_code, qty)
|
||||||
|
|
||||||
if random.random() < 0.3:
|
if random.random() < 0.6:
|
||||||
for mr in frappe.get_all('Material Request',
|
for mr in frappe.get_all('Material Request',
|
||||||
filters={'material_request_type': 'Purchase', 'status': 'Open'},
|
filters={'material_request_type': 'Purchase', 'status': 'Open'},
|
||||||
limit=random.randint(1,6)):
|
limit=random.randint(1,6)):
|
||||||
@ -36,7 +36,7 @@ def work():
|
|||||||
rfq.submit()
|
rfq.submit()
|
||||||
|
|
||||||
# Make suppier quotation from RFQ against each supplier.
|
# Make suppier quotation from RFQ against each supplier.
|
||||||
if random.random() < 0.3:
|
if random.random() < 0.6:
|
||||||
for rfq in frappe.get_all('Request for Quotation',
|
for rfq in frappe.get_all('Request for Quotation',
|
||||||
filters={'status': 'Open'}, limit=random.randint(1, 6)):
|
filters={'status': 'Open'}, limit=random.randint(1, 6)):
|
||||||
if not frappe.get_all('Supplier Quotation',
|
if not frappe.get_all('Supplier Quotation',
|
||||||
@ -51,15 +51,15 @@ def work():
|
|||||||
# get supplier details
|
# get supplier details
|
||||||
supplier = get_random("Supplier")
|
supplier = get_random("Supplier")
|
||||||
|
|
||||||
company_currency = frappe.get_cached_value('Company', "Wind Power LLC", "default_currency")
|
company_currency = frappe.get_cached_value('Company', erpnext.get_default_company(), "default_currency")
|
||||||
party_account_currency = get_party_account_currency("Supplier", supplier, "Wind Power LLC")
|
party_account_currency = get_party_account_currency("Supplier", supplier, erpnext.get_default_company())
|
||||||
if company_currency == party_account_currency:
|
if company_currency == party_account_currency:
|
||||||
exchange_rate = 1
|
exchange_rate = 1
|
||||||
else:
|
else:
|
||||||
exchange_rate = get_exchange_rate(party_account_currency, company_currency, args="for_buying")
|
exchange_rate = get_exchange_rate(party_account_currency, company_currency, args="for_buying")
|
||||||
|
|
||||||
# make supplier quotations
|
# make supplier quotations
|
||||||
if random.random() < 0.2:
|
if random.random() < 0.5:
|
||||||
from erpnext.stock.doctype.material_request.material_request import make_supplier_quotation
|
from erpnext.stock.doctype.material_request.material_request import make_supplier_quotation
|
||||||
|
|
||||||
report = "Material Requests for which Supplier Quotations are not created"
|
report = "Material Requests for which Supplier Quotations are not created"
|
||||||
@ -80,16 +80,20 @@ def work():
|
|||||||
report = "Requested Items To Be Ordered"
|
report = "Requested Items To Be Ordered"
|
||||||
for row in query_report.run(report)["result"][:how_many("Purchase Order")]:
|
for row in query_report.run(report)["result"][:how_many("Purchase Order")]:
|
||||||
if row[0] != "'Total'":
|
if row[0] != "'Total'":
|
||||||
po = frappe.get_doc(make_purchase_order(row[0]))
|
try:
|
||||||
po.supplier = supplier
|
po = frappe.get_doc(make_purchase_order(row[0]))
|
||||||
po.currency = party_account_currency or company_currency
|
po.supplier = supplier
|
||||||
po.conversion_rate = exchange_rate
|
po.currency = party_account_currency or company_currency
|
||||||
po.transaction_date = frappe.flags.current_date
|
po.conversion_rate = exchange_rate
|
||||||
po.insert()
|
po.transaction_date = frappe.flags.current_date
|
||||||
po.submit()
|
po.insert()
|
||||||
frappe.db.commit()
|
po.submit()
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
frappe.db.commit()
|
||||||
|
|
||||||
if random.random() < 0.2:
|
if random.random() < 0.5:
|
||||||
make_subcontract()
|
make_subcontract()
|
||||||
|
|
||||||
def make_material_request(item_code, qty):
|
def make_material_request(item_code, qty):
|
||||||
@ -122,13 +126,14 @@ def add_suppliers(rfq):
|
|||||||
rfq.append("suppliers", { "supplier": supplier })
|
rfq.append("suppliers", { "supplier": supplier })
|
||||||
|
|
||||||
def make_subcontract():
|
def make_subcontract():
|
||||||
from erpnext.buying.doctype.purchase_order.purchase_order import make_stock_entry
|
from erpnext.buying.doctype.purchase_order.purchase_order import make_rm_stock_entry
|
||||||
item_code = get_random("Item", {"is_sub_contracted_item": 1})
|
item_code = get_random("Item", {"is_sub_contracted_item": 1})
|
||||||
if item_code:
|
if item_code:
|
||||||
# make sub-contract PO
|
# make sub-contract PO
|
||||||
po = frappe.new_doc("Purchase Order")
|
po = frappe.new_doc("Purchase Order")
|
||||||
po.is_subcontracted = "Yes"
|
po.is_subcontracted = "Yes"
|
||||||
po.supplier = get_random("Supplier")
|
po.supplier = get_random("Supplier")
|
||||||
|
po.transaction_date = frappe.flags.current_date # added
|
||||||
po.schedule_date = frappe.utils.add_days(frappe.flags.current_date, 7)
|
po.schedule_date = frappe.utils.add_days(frappe.flags.current_date, 7)
|
||||||
|
|
||||||
item_code = get_random("Item", {"is_sub_contracted_item": 1})
|
item_code = get_random("Item", {"is_sub_contracted_item": 1})
|
||||||
@ -150,7 +155,20 @@ def make_subcontract():
|
|||||||
make_material_request(po.items[0].item_code, po.items[0].qty)
|
make_material_request(po.items[0].item_code, po.items[0].qty)
|
||||||
|
|
||||||
# transfer material for sub-contract
|
# transfer material for sub-contract
|
||||||
stock_entry = frappe.get_doc(make_stock_entry(po.name, po.items[0].item_code))
|
rm_items = get_rm_item(po.items[0], po.supplied_items[0])
|
||||||
|
stock_entry = frappe.get_doc(make_rm_stock_entry(po.name, json.dumps([rm_items])))
|
||||||
stock_entry.from_warehouse = "Stores - WPL"
|
stock_entry.from_warehouse = "Stores - WPL"
|
||||||
stock_entry.to_warehouse = "Supplier - WPL"
|
stock_entry.to_warehouse = "Supplier - WPL"
|
||||||
stock_entry.insert()
|
stock_entry.insert()
|
||||||
|
|
||||||
|
def get_rm_item(items, supplied_items):
|
||||||
|
return {
|
||||||
|
"item_code": items.get("item_code"),
|
||||||
|
"rm_item_code": supplied_items.get("rm_item_code"),
|
||||||
|
"item_name": supplied_items.get("rm_item_code"),
|
||||||
|
"qty": supplied_items.get("required_qty") + random.randint(3,10),
|
||||||
|
"amount": supplied_items.get("amount"),
|
||||||
|
"warehouse": supplied_items.get("reserve_warehouse"),
|
||||||
|
"rate": supplied_items.get("rate"),
|
||||||
|
"stock_uom": supplied_items.get("stock_uom")
|
||||||
|
}
|
||||||
|
@ -3,22 +3,23 @@
|
|||||||
|
|
||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
import frappe, random
|
import frappe, random, erpnext
|
||||||
from frappe.utils import flt
|
from frappe.utils import flt
|
||||||
from frappe.utils.make_random import add_random_children, get_random
|
from frappe.utils.make_random import add_random_children, get_random
|
||||||
from erpnext.setup.utils import get_exchange_rate
|
from erpnext.setup.utils import get_exchange_rate
|
||||||
from erpnext.accounts.party import get_party_account_currency
|
from erpnext.accounts.party import get_party_account_currency
|
||||||
from erpnext.accounts.doctype.payment_request.payment_request import make_payment_request, make_payment_entry
|
from erpnext.accounts.doctype.payment_request.payment_request import make_payment_request, make_payment_entry
|
||||||
|
|
||||||
def work():
|
def work(domain="Manufacturing"):
|
||||||
frappe.set_user(frappe.db.get_global('demo_sales_user_2'))
|
frappe.set_user(frappe.db.get_global('demo_sales_user_2'))
|
||||||
if random.random() < 0.5:
|
|
||||||
for i in range(random.randint(1,7)):
|
|
||||||
make_opportunity()
|
|
||||||
|
|
||||||
if random.random() < 0.5:
|
for i in range(random.randint(1,7)):
|
||||||
for i in range(random.randint(1,3)):
|
if random.random() < 0.5:
|
||||||
make_quotation()
|
make_opportunity(domain)
|
||||||
|
|
||||||
|
for i in range(random.randint(1,3)):
|
||||||
|
if random.random() < 0.5:
|
||||||
|
make_quotation(domain)
|
||||||
|
|
||||||
# lost quotations / inquiries
|
# lost quotations / inquiries
|
||||||
if random.random() < 0.3:
|
if random.random() < 0.3:
|
||||||
@ -32,24 +33,27 @@ def work():
|
|||||||
if opportunity and opportunity.status in ('Open', 'Replied'):
|
if opportunity and opportunity.status in ('Open', 'Replied'):
|
||||||
opportunity.declare_enquiry_lost('Did not ask')
|
opportunity.declare_enquiry_lost('Did not ask')
|
||||||
|
|
||||||
if random.random() < 0.3:
|
for i in range(random.randint(1,3)):
|
||||||
for i in range(random.randint(1,3)):
|
if random.random() < 0.6:
|
||||||
make_sales_order()
|
make_sales_order()
|
||||||
|
|
||||||
if random.random() < 0.1:
|
if random.random() < 0.5:
|
||||||
#make payment request against Sales Order
|
#make payment request against Sales Order
|
||||||
sales_order_name = get_random("Sales Order", filters={"docstatus": 1})
|
sales_order_name = get_random("Sales Order", filters={"docstatus": 1})
|
||||||
if sales_order_name:
|
try:
|
||||||
so = frappe.get_doc("Sales Order", sales_order_name)
|
if sales_order_name:
|
||||||
if flt(so.per_billed) != 100:
|
so = frappe.get_doc("Sales Order", sales_order_name)
|
||||||
payment_request = make_payment_request(dt="Sales Order", dn=so.name, recipient_id=so.contact_email,
|
if flt(so.per_billed) != 100:
|
||||||
submit_doc=True, mute_email=True, use_dummy_message=True)
|
payment_request = make_payment_request(dt="Sales Order", dn=so.name, recipient_id=so.contact_email,
|
||||||
|
submit_doc=True, mute_email=True, use_dummy_message=True)
|
||||||
|
|
||||||
payment_entry = frappe.get_doc(make_payment_entry(payment_request.name))
|
payment_entry = frappe.get_doc(make_payment_entry(payment_request.name))
|
||||||
payment_entry.posting_date = frappe.flags.current_date
|
payment_entry.posting_date = frappe.flags.current_date
|
||||||
payment_entry.submit()
|
payment_entry.submit()
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
|
||||||
def make_opportunity():
|
def make_opportunity(domain):
|
||||||
b = frappe.get_doc({
|
b = frappe.get_doc({
|
||||||
"doctype": "Opportunity",
|
"doctype": "Opportunity",
|
||||||
"enquiry_from": "Customer",
|
"enquiry_from": "Customer",
|
||||||
@ -61,13 +65,13 @@ def make_opportunity():
|
|||||||
|
|
||||||
add_random_children(b, "items", rows=4, randomize = {
|
add_random_children(b, "items", rows=4, randomize = {
|
||||||
"qty": (1, 5),
|
"qty": (1, 5),
|
||||||
"item_code": ("Item", {"has_variants": 0, "is_fixed_asset": 0})
|
"item_code": ("Item", {"has_variants": 0, "is_fixed_asset": 0, "domain": domain})
|
||||||
}, unique="item_code")
|
}, unique="item_code")
|
||||||
|
|
||||||
b.insert()
|
b.insert()
|
||||||
frappe.db.commit()
|
frappe.db.commit()
|
||||||
|
|
||||||
def make_quotation():
|
def make_quotation(domain):
|
||||||
# get open opportunites
|
# get open opportunites
|
||||||
opportunity = get_random("Opportunity", {"status": "Open", "with_items": 1})
|
opportunity = get_random("Opportunity", {"status": "Open", "with_items": 1})
|
||||||
|
|
||||||
@ -84,8 +88,8 @@ def make_quotation():
|
|||||||
# get customer, currency and exchange_rate
|
# get customer, currency and exchange_rate
|
||||||
customer = get_random("Customer")
|
customer = get_random("Customer")
|
||||||
|
|
||||||
company_currency = frappe.get_cached_value('Company', "Wind Power LLC", "default_currency")
|
company_currency = frappe.get_cached_value('Company', erpnext.get_default_company(), "default_currency")
|
||||||
party_account_currency = get_party_account_currency("Customer", customer, "Wind Power LLC")
|
party_account_currency = get_party_account_currency("Customer", customer, erpnext.get_default_company())
|
||||||
if company_currency == party_account_currency:
|
if company_currency == party_account_currency:
|
||||||
exchange_rate = 1
|
exchange_rate = 1
|
||||||
else:
|
else:
|
||||||
@ -104,7 +108,7 @@ def make_quotation():
|
|||||||
|
|
||||||
add_random_children(qtn, "items", rows=3, randomize = {
|
add_random_children(qtn, "items", rows=3, randomize = {
|
||||||
"qty": (1, 5),
|
"qty": (1, 5),
|
||||||
"item_code": ("Item", {"has_variants": "0", "is_fixed_asset": 0})
|
"item_code": ("Item", {"has_variants": "0", "is_fixed_asset": 0, "domain": domain})
|
||||||
}, unique="item_code")
|
}, unique="item_code")
|
||||||
|
|
||||||
qtn.insert()
|
qtn.insert()
|
||||||
@ -115,8 +119,8 @@ def make_quotation():
|
|||||||
def make_sales_order():
|
def make_sales_order():
|
||||||
q = get_random("Quotation", {"status": "Submitted"})
|
q = get_random("Quotation", {"status": "Submitted"})
|
||||||
if q:
|
if q:
|
||||||
from erpnext.selling.doctype.quotation.quotation import make_sales_order
|
from erpnext.selling.doctype.quotation.quotation import make_sales_order as mso
|
||||||
so = frappe.get_doc(make_sales_order(q))
|
so = frappe.get_doc(mso(q))
|
||||||
so.transaction_date = frappe.flags.current_date
|
so.transaction_date = frappe.flags.current_date
|
||||||
so.delivery_date = frappe.utils.add_days(frappe.flags.current_date, 10)
|
so.delivery_date = frappe.utils.add_days(frappe.flags.current_date, 10)
|
||||||
so.insert()
|
so.insert()
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
from __future__ import print_function, unicode_literals
|
from __future__ import print_function, unicode_literals
|
||||||
|
|
||||||
import frappe, random
|
import frappe, random, erpnext
|
||||||
from frappe.desk import query_report
|
from frappe.desk import query_report
|
||||||
from erpnext.stock.stock_ledger import NegativeStockError
|
from erpnext.stock.stock_ledger import NegativeStockError
|
||||||
from erpnext.stock.doctype.serial_no.serial_no import SerialNoRequiredError, SerialNoQtyError
|
from erpnext.stock.doctype.serial_no.serial_no import SerialNoRequiredError, SerialNoQtyError
|
||||||
@ -45,7 +45,7 @@ def make_delivery_note():
|
|||||||
# make purchase requests
|
# make purchase requests
|
||||||
|
|
||||||
# make delivery notes (if possible)
|
# make delivery notes (if possible)
|
||||||
if random.random() < 0.3:
|
if random.random() < 0.6:
|
||||||
from erpnext.selling.doctype.sales_order.sales_order import make_delivery_note
|
from erpnext.selling.doctype.sales_order.sales_order import make_delivery_note
|
||||||
report = "Ordered Items To Be Delivered"
|
report = "Ordered Items To Be Delivered"
|
||||||
for so in list(set([r[0] for r in query_report.run(report)["result"]
|
for so in list(set([r[0] for r in query_report.run(report)["result"]
|
||||||
@ -56,8 +56,9 @@ def make_delivery_note():
|
|||||||
if not d.expense_account:
|
if not d.expense_account:
|
||||||
d.expense_account = ("Cost of Goods Sold - {0}".format(
|
d.expense_account = ("Cost of Goods Sold - {0}".format(
|
||||||
frappe.get_cached_value('Company', dn.company, 'abbr')))
|
frappe.get_cached_value('Company', dn.company, 'abbr')))
|
||||||
dn.insert()
|
|
||||||
try:
|
try:
|
||||||
|
dn.insert()
|
||||||
dn.submit()
|
dn.submit()
|
||||||
frappe.db.commit()
|
frappe.db.commit()
|
||||||
except (NegativeStockError, SerialNoRequiredError, SerialNoQtyError, UnableToSelectBatchError):
|
except (NegativeStockError, SerialNoRequiredError, SerialNoQtyError, UnableToSelectBatchError):
|
||||||
@ -68,9 +69,10 @@ def make_stock_reconciliation():
|
|||||||
from erpnext.stock.doctype.stock_reconciliation.stock_reconciliation \
|
from erpnext.stock.doctype.stock_reconciliation.stock_reconciliation \
|
||||||
import OpeningEntryAccountError, EmptyStockReconciliationItemsError
|
import OpeningEntryAccountError, EmptyStockReconciliationItemsError
|
||||||
|
|
||||||
if random.random() < 0.1:
|
if random.random() < 0.4:
|
||||||
stock_reco = frappe.new_doc("Stock Reconciliation")
|
stock_reco = frappe.new_doc("Stock Reconciliation")
|
||||||
stock_reco.posting_date = frappe.flags.current_date
|
stock_reco.posting_date = frappe.flags.current_date
|
||||||
|
stock_reco.company = erpnext.get_default_company()
|
||||||
stock_reco.get_items_for("Stores - WP")
|
stock_reco.get_items_for("Stores - WP")
|
||||||
if stock_reco.items:
|
if stock_reco.items:
|
||||||
for item in stock_reco.items:
|
for item in stock_reco.items:
|
||||||
@ -87,7 +89,7 @@ def make_stock_reconciliation():
|
|||||||
|
|
||||||
def submit_draft_stock_entries():
|
def submit_draft_stock_entries():
|
||||||
from erpnext.stock.doctype.stock_entry.stock_entry import IncorrectValuationRateError, \
|
from erpnext.stock.doctype.stock_entry.stock_entry import IncorrectValuationRateError, \
|
||||||
DuplicateEntryForProductionOrderError, OperationsNotCompleteError
|
DuplicateEntryForWorkOrderError, OperationsNotCompleteError
|
||||||
|
|
||||||
# try posting older drafts (if exists)
|
# try posting older drafts (if exists)
|
||||||
frappe.db.commit()
|
frappe.db.commit()
|
||||||
@ -98,7 +100,7 @@ def submit_draft_stock_entries():
|
|||||||
ste.save()
|
ste.save()
|
||||||
ste.submit()
|
ste.submit()
|
||||||
frappe.db.commit()
|
frappe.db.commit()
|
||||||
except (NegativeStockError, IncorrectValuationRateError, DuplicateEntryForProductionOrderError,
|
except (NegativeStockError, IncorrectValuationRateError, DuplicateEntryForWorkOrderError,
|
||||||
OperationsNotCompleteError):
|
OperationsNotCompleteError):
|
||||||
frappe.db.rollback()
|
frappe.db.rollback()
|
||||||
|
|
||||||
|
@ -12,7 +12,7 @@ app_license = "GNU General Public License (v3)"
|
|||||||
source_link = "https://github.com/frappe/erpnext"
|
source_link = "https://github.com/frappe/erpnext"
|
||||||
|
|
||||||
develop_version = '11.x.x-develop'
|
develop_version = '11.x.x-develop'
|
||||||
staging_version = '11.0.3-beta.11'
|
staging_version = '11.0.3-beta.12'
|
||||||
|
|
||||||
error_report_email = "support@erpnext.com"
|
error_report_email = "support@erpnext.com"
|
||||||
|
|
||||||
|
@ -368,7 +368,8 @@ class BOM(WebsiteGenerator):
|
|||||||
bom_list = self.traverse_tree(bom_list)
|
bom_list = self.traverse_tree(bom_list)
|
||||||
for bom in bom_list:
|
for bom in bom_list:
|
||||||
bom_obj = frappe.get_doc("BOM", bom)
|
bom_obj = frappe.get_doc("BOM", bom)
|
||||||
bom_obj.on_update()
|
bom_obj.check_recursion()
|
||||||
|
bom_obj.update_exploded_items()
|
||||||
|
|
||||||
return bom_list
|
return bom_list
|
||||||
|
|
||||||
|
@ -62,7 +62,7 @@ class BOMUpdateTool(Document):
|
|||||||
bom_list.append(d[0])
|
bom_list.append(d[0])
|
||||||
self.get_parent_boms(d[0], bom_list)
|
self.get_parent_boms(d[0], bom_list)
|
||||||
|
|
||||||
return bom_list
|
return list(set(bom_list))
|
||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
def enqueue_replace_bom(args):
|
def enqueue_replace_bom(args):
|
||||||
|
15
erpnext/patches/v11_0/remove_subscriber_doctype.py
Normal file
15
erpnext/patches/v11_0/remove_subscriber_doctype.py
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
import frappe
|
||||||
|
from frappe.model.utils.rename_field import rename_field
|
||||||
|
|
||||||
|
def execute():
|
||||||
|
""" copy subscribe field to customer """
|
||||||
|
frappe.reload_doc("accounts","doctype","subscription")
|
||||||
|
|
||||||
|
if frappe.db.exists("DocType", "Subscriber"):
|
||||||
|
if frappe.db.has_column('Subscription','subscriber'):
|
||||||
|
frappe.db.sql("""
|
||||||
|
update `tabSubscription` s1
|
||||||
|
set customer=(select customer from tabSubscriber where name=s1.subscriber)
|
||||||
|
""")
|
||||||
|
|
||||||
|
frappe.delete_doc("DocType", "Subscriber")
|
@ -1,5 +1,6 @@
|
|||||||
{
|
{
|
||||||
"allow_copy": 0,
|
"allow_copy": 0,
|
||||||
|
"allow_guest_to_view": 0,
|
||||||
"allow_import": 0,
|
"allow_import": 0,
|
||||||
"allow_rename": 0,
|
"allow_rename": 0,
|
||||||
"beta": 0,
|
"beta": 0,
|
||||||
@ -11,16 +12,21 @@
|
|||||||
"editable_grid": 1,
|
"editable_grid": 1,
|
||||||
"fields": [
|
"fields": [
|
||||||
{
|
{
|
||||||
|
"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,
|
||||||
"fieldname": "user",
|
"fieldname": "user",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"hidden": 0,
|
"hidden": 0,
|
||||||
"ignore_user_permissions": 0,
|
"ignore_user_permissions": 0,
|
||||||
"ignore_xss_filter": 0,
|
"ignore_xss_filter": 0,
|
||||||
"in_filter": 0,
|
"in_filter": 0,
|
||||||
|
"in_global_search": 0,
|
||||||
"in_list_view": 1,
|
"in_list_view": 1,
|
||||||
|
"in_standard_filter": 0,
|
||||||
"label": "User",
|
"label": "User",
|
||||||
"length": 0,
|
"length": 0,
|
||||||
"no_copy": 0,
|
"no_copy": 0,
|
||||||
@ -30,23 +36,30 @@
|
|||||||
"print_hide": 0,
|
"print_hide": 0,
|
||||||
"print_hide_if_no_value": 0,
|
"print_hide_if_no_value": 0,
|
||||||
"read_only": 0,
|
"read_only": 0,
|
||||||
|
"remember_last_selected_value": 0,
|
||||||
"report_hide": 0,
|
"report_hide": 0,
|
||||||
"reqd": 1,
|
"reqd": 1,
|
||||||
"search_index": 1,
|
"search_index": 1,
|
||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
"unique": 0
|
"unique": 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,
|
||||||
"fieldname": "welcome_email_sent",
|
"fieldname": "welcome_email_sent",
|
||||||
"fieldtype": "Check",
|
"fieldtype": "Check",
|
||||||
"hidden": 0,
|
"hidden": 0,
|
||||||
"ignore_user_permissions": 0,
|
"ignore_user_permissions": 0,
|
||||||
"ignore_xss_filter": 0,
|
"ignore_xss_filter": 0,
|
||||||
"in_filter": 0,
|
"in_filter": 0,
|
||||||
|
"in_global_search": 0,
|
||||||
"in_list_view": 0,
|
"in_list_view": 0,
|
||||||
|
"in_standard_filter": 0,
|
||||||
"label": "Welcome email sent",
|
"label": "Welcome email sent",
|
||||||
"length": 0,
|
"length": 0,
|
||||||
"no_copy": 0,
|
"no_copy": 0,
|
||||||
@ -55,24 +68,58 @@
|
|||||||
"print_hide": 0,
|
"print_hide": 0,
|
||||||
"print_hide_if_no_value": 0,
|
"print_hide_if_no_value": 0,
|
||||||
"read_only": 0,
|
"read_only": 0,
|
||||||
|
"remember_last_selected_value": 0,
|
||||||
"report_hide": 0,
|
"report_hide": 0,
|
||||||
"reqd": 0,
|
"reqd": 0,
|
||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
"set_only_once": 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": 1,
|
||||||
|
"fieldname": "view_attachments",
|
||||||
|
"fieldtype": "Check",
|
||||||
|
"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": "View attachments",
|
||||||
|
"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
|
"unique": 0
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
"has_web_view": 0,
|
||||||
"hide_heading": 0,
|
"hide_heading": 0,
|
||||||
"hide_toolbar": 0,
|
"hide_toolbar": 0,
|
||||||
"idx": 0,
|
"idx": 0,
|
||||||
"image_view": 0,
|
"image_view": 0,
|
||||||
"in_create": 0,
|
"in_create": 0,
|
||||||
|
|
||||||
"is_submittable": 0,
|
"is_submittable": 0,
|
||||||
"issingle": 0,
|
"issingle": 0,
|
||||||
"istable": 1,
|
"istable": 1,
|
||||||
"max_attachments": 0,
|
"max_attachments": 0,
|
||||||
"modified": "2016-07-11 03:28:04.756894",
|
"modified": "2018-09-09 12:39:38.376816",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Projects",
|
"module": "Projects",
|
||||||
"name": "Project User",
|
"name": "Project User",
|
||||||
@ -82,7 +129,10 @@
|
|||||||
"quick_entry": 0,
|
"quick_entry": 0,
|
||||||
"read_only": 0,
|
"read_only": 0,
|
||||||
"read_only_onload": 0,
|
"read_only_onload": 0,
|
||||||
|
"show_name_in_global_search": 0,
|
||||||
"sort_field": "modified",
|
"sort_field": "modified",
|
||||||
"sort_order": "DESC",
|
"sort_order": "DESC",
|
||||||
"track_seen": 0
|
"track_changes": 0,
|
||||||
|
"track_seen": 0,
|
||||||
|
"track_views": 0
|
||||||
}
|
}
|
@ -25,6 +25,10 @@ def get_data():
|
|||||||
{
|
{
|
||||||
'label': _('Pricing'),
|
'label': _('Pricing'),
|
||||||
'items': ['Pricing Rule']
|
'items': ['Pricing Rule']
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'label': _('Subscriptions'),
|
||||||
|
'items': ['Subscription']
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
@ -5,6 +5,7 @@ from __future__ import unicode_literals
|
|||||||
import frappe
|
import frappe
|
||||||
from frappe import msgprint, _
|
from frappe import msgprint, _
|
||||||
from frappe.utils import flt
|
from frappe.utils import flt
|
||||||
|
from erpnext import get_company_currency
|
||||||
|
|
||||||
def execute(filters=None):
|
def execute(filters=None):
|
||||||
if not filters: filters = {}
|
if not filters: filters = {}
|
||||||
@ -14,12 +15,14 @@ def execute(filters=None):
|
|||||||
item_details = get_item_details()
|
item_details = get_item_details()
|
||||||
data = []
|
data = []
|
||||||
|
|
||||||
|
company_currency = get_company_currency(filters["company"])
|
||||||
|
|
||||||
for d in entries:
|
for d in entries:
|
||||||
if d.stock_qty > 0 or filters.get('show_return_entries', 0):
|
if d.stock_qty > 0 or filters.get('show_return_entries', 0):
|
||||||
data.append([
|
data.append([
|
||||||
d.name, d.customer, d.territory, item_details.get(d.item_code, {}).get("website_warehouse"), d.posting_date, d.item_code,
|
d.name, d.customer, d.territory, item_details.get(d.item_code, {}).get("website_warehouse"), d.posting_date, d.item_code,
|
||||||
item_details.get(d.item_code, {}).get("item_group"), item_details.get(d.item_code, {}).get("brand"),
|
item_details.get(d.item_code, {}).get("item_group"), item_details.get(d.item_code, {}).get("brand"),
|
||||||
d.stock_qty, d.base_net_amount, d.sales_person, d.allocated_percentage, d.contribution_amt
|
d.stock_qty, d.base_net_amount, d.sales_person, d.allocated_percentage, d.contribution_amt, company_currency
|
||||||
])
|
])
|
||||||
|
|
||||||
if data:
|
if data:
|
||||||
@ -32,13 +35,105 @@ def get_columns(filters):
|
|||||||
if not filters.get("doc_type"):
|
if not filters.get("doc_type"):
|
||||||
msgprint(_("Please select the document type first"), raise_exception=1)
|
msgprint(_("Please select the document type first"), raise_exception=1)
|
||||||
|
|
||||||
return [filters["doc_type"] + ":Link/" + filters["doc_type"] + ":140",
|
columns = [
|
||||||
_("Customer") + ":Link/Customer:140", _("Territory") + ":Link/Territory:100", _("Warehouse") + ":Link/Warehouse:100",
|
{
|
||||||
_("Posting Date") + ":Date:100",
|
"label": _(filters["doc_type"]),
|
||||||
_("Item Code") + ":Link/Item:120", _("Item Group") + ":Link/Item Group:120",
|
"options": filters["doc_type"],
|
||||||
_("Brand") + ":Link/Brand:120", _("Qty") + ":Float:100", _("Amount") + ":Currency:120",
|
"fieldname": frappe.scrub(filters['doc_type']),
|
||||||
_("Sales Person") + ":Link/Sales Person:140", _("Contribution %") + "::110",
|
"fieldtype": "Link",
|
||||||
_("Contribution Amount") + ":Currency:140"]
|
"width": 140
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": _("Customer"),
|
||||||
|
"options": "Customer",
|
||||||
|
"fieldname": "customer",
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"width": 140
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": _("Territory"),
|
||||||
|
"options": "Territory",
|
||||||
|
"fieldname": "territory",
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"width": 140
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": _("Warehouse"),
|
||||||
|
"options": "Warehouse",
|
||||||
|
"fieldname": "warehouse",
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"width": 140
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": _("Posting Date"),
|
||||||
|
"fieldname": "posting_date",
|
||||||
|
"fieldtype": "Date",
|
||||||
|
"width": 140
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": _("Item Code"),
|
||||||
|
"options": "Item",
|
||||||
|
"fieldname": "item_code",
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"width": 140
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": _("Item Group"),
|
||||||
|
"options": "Item Group",
|
||||||
|
"fieldname": "item_group",
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"width": 140
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": _("Brand"),
|
||||||
|
"options": "Brand",
|
||||||
|
"fieldname": "brand",
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"width": 140
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": _("Qty"),
|
||||||
|
"fieldname": "qty",
|
||||||
|
"fieldtype": "Float",
|
||||||
|
"width": 140
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": _("Amount"),
|
||||||
|
"options": "currency",
|
||||||
|
"fieldname": "amount",
|
||||||
|
"fieldtype": "Currency",
|
||||||
|
"width": 140
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": _("Sales Person"),
|
||||||
|
"options": "Sales Person",
|
||||||
|
"fieldname": "sales_person",
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"width": 140
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": _("Contribution %"),
|
||||||
|
"fieldname": "contribution",
|
||||||
|
"fieldtype": "Float",
|
||||||
|
"width": 140
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": _("Contribution Amount"),
|
||||||
|
"options": "currency",
|
||||||
|
"fieldname": "contribution_amt",
|
||||||
|
"fieldtype": "Currency",
|
||||||
|
"width": 140
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label":_("Currency"),
|
||||||
|
"options": "Currency",
|
||||||
|
"fieldname":"currency",
|
||||||
|
"fieldtype":"Link",
|
||||||
|
"hidden" : 1
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
return columns
|
||||||
|
|
||||||
def get_entries(filters):
|
def get_entries(filters):
|
||||||
date_field = filters["doc_type"] == "Sales Order" and "transaction_date" or "posting_date"
|
date_field = filters["doc_type"] == "Sales Order" and "transaction_date" or "posting_date"
|
||||||
|
@ -272,13 +272,13 @@ erpnext.stock.delivery_note.set_print_hide = function(doc, cdt, cdn){
|
|||||||
var dn_item_fields = frappe.meta.docfield_map['Delivery Note Item'];
|
var dn_item_fields = frappe.meta.docfield_map['Delivery Note Item'];
|
||||||
var dn_fields_copy = dn_fields;
|
var dn_fields_copy = dn_fields;
|
||||||
var dn_item_fields_copy = dn_item_fields;
|
var dn_item_fields_copy = dn_item_fields;
|
||||||
|
|
||||||
if (doc.print_without_amount) {
|
if (doc.print_without_amount) {
|
||||||
dn_fields['currency'].print_hide = 1;
|
dn_fields['currency'].print_hide = 1;
|
||||||
dn_item_fields['rate'].print_hide = 1;
|
dn_item_fields['rate'].print_hide = 1;
|
||||||
dn_item_fields['discount_percentage'].print_hide = 1;
|
dn_item_fields['discount_percentage'].print_hide = 1;
|
||||||
dn_item_fields['price_list_rate'].print_hide = 1;
|
dn_item_fields['price_list_rate'].print_hide = 1;
|
||||||
dn_item_fields['amount'].print_hide = 1;
|
dn_item_fields['amount'].print_hide = 1;
|
||||||
|
dn_item_fields['discount_amount'].print_hide = 1;
|
||||||
dn_fields['taxes'].print_hide = 1;
|
dn_fields['taxes'].print_hide = 1;
|
||||||
} else {
|
} else {
|
||||||
if (dn_fields_copy['currency'].print_hide != 1)
|
if (dn_fields_copy['currency'].print_hide != 1)
|
||||||
@ -287,6 +287,8 @@ erpnext.stock.delivery_note.set_print_hide = function(doc, cdt, cdn){
|
|||||||
dn_item_fields['rate'].print_hide = 0;
|
dn_item_fields['rate'].print_hide = 0;
|
||||||
if (dn_item_fields_copy['amount'].print_hide != 1)
|
if (dn_item_fields_copy['amount'].print_hide != 1)
|
||||||
dn_item_fields['amount'].print_hide = 0;
|
dn_item_fields['amount'].print_hide = 0;
|
||||||
|
if (dn_item_fields_copy['discount_amount'].print_hide != 1)
|
||||||
|
dn_item_fields['discount_amount'].print_hide = 0;
|
||||||
if (dn_fields_copy['taxes'].print_hide != 1)
|
if (dn_fields_copy['taxes'].print_hide != 1)
|
||||||
dn_fields['taxes'].print_hide = 0;
|
dn_fields['taxes'].print_hide = 0;
|
||||||
}
|
}
|
||||||
|
@ -74,7 +74,7 @@ class DeliveryNote(SellingController):
|
|||||||
item_meta = frappe.get_meta("Delivery Note Item")
|
item_meta = frappe.get_meta("Delivery Note Item")
|
||||||
print_hide_fields = {
|
print_hide_fields = {
|
||||||
"parent": ["grand_total", "rounded_total", "in_words", "currency", "total", "taxes"],
|
"parent": ["grand_total", "rounded_total", "in_words", "currency", "total", "taxes"],
|
||||||
"items": ["rate", "amount", "price_list_rate", "discount_percentage"]
|
"items": ["rate", "amount", "discount_amount", "price_list_rate", "discount_percentage"]
|
||||||
}
|
}
|
||||||
|
|
||||||
for key, fieldname in print_hide_fields.items():
|
for key, fieldname in print_hide_fields.items():
|
||||||
|
@ -254,7 +254,7 @@ class StockReconciliation(StockController):
|
|||||||
|
|
||||||
def get_items_for(self, warehouse):
|
def get_items_for(self, warehouse):
|
||||||
self.items = []
|
self.items = []
|
||||||
for item in get_items(warehouse, self.posting_date, self.posting_time):
|
for item in get_items(warehouse, self.posting_date, self.posting_time, self.company):
|
||||||
self.append("items", item)
|
self.append("items", item)
|
||||||
|
|
||||||
def submit(self):
|
def submit(self):
|
||||||
|
@ -13,12 +13,18 @@ def execute(filters=None):
|
|||||||
def get_columns():
|
def get_columns():
|
||||||
return [
|
return [
|
||||||
{
|
{
|
||||||
"label": _("Item Name"),
|
"label": _("Item Code"),
|
||||||
"fieldname": "item_name",
|
"fieldname": "item_code",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"options": "Item",
|
"options": "Item",
|
||||||
"width": 120
|
"width": 120
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"label": _("Item Name"),
|
||||||
|
"fieldname": "item_name",
|
||||||
|
"fieldtype": "Data",
|
||||||
|
"width": 120
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"label": _("Brand"),
|
"label": _("Brand"),
|
||||||
"fieldname": "brand",
|
"fieldname": "brand",
|
||||||
@ -76,7 +82,7 @@ def get_item_price_qty_data(filters):
|
|||||||
if filters.get("item_code"):
|
if filters.get("item_code"):
|
||||||
conditions += "where a.item_code=%(item_code)s"
|
conditions += "where a.item_code=%(item_code)s"
|
||||||
|
|
||||||
item_results = frappe.db.sql("""select a.item_code as item_name, a.name as price_list_name,
|
item_results = frappe.db.sql("""select a.item_code, a.item_name, a.name as price_list_name,
|
||||||
a.brand as brand, b.warehouse as warehouse, b.actual_qty as actual_qty
|
a.brand as brand, b.warehouse as warehouse, b.actual_qty as actual_qty
|
||||||
from `tabItem Price` a left join `tabBin` b
|
from `tabItem Price` a left join `tabBin` b
|
||||||
ON a.item_code = b.item_code
|
ON a.item_code = b.item_code
|
||||||
@ -92,6 +98,7 @@ def get_item_price_qty_data(filters):
|
|||||||
if item_results:
|
if item_results:
|
||||||
for item_dict in item_results:
|
for item_dict in item_results:
|
||||||
data = {
|
data = {
|
||||||
|
'item_code': item_dict.item_code,
|
||||||
'item_name': item_dict.item_name,
|
'item_name': item_dict.item_name,
|
||||||
'brand': item_dict.brand,
|
'brand': item_dict.brand,
|
||||||
'warehouse': item_dict.warehouse,
|
'warehouse': item_dict.warehouse,
|
||||||
|
@ -2,16 +2,16 @@
|
|||||||
<div class='timesheet'>
|
<div class='timesheet'>
|
||||||
<a class="no-decoration timesheet-link {{ timesheet.css_seen }}" href="/timesheet/{{ timesheet.info.name}}">
|
<a class="no-decoration timesheet-link {{ timesheet.css_seen }}" href="/timesheet/{{ timesheet.info.name}}">
|
||||||
<div class='row project-item'>
|
<div class='row project-item'>
|
||||||
<div class='col-xs-9'>
|
<div class='col-xs-10'>
|
||||||
<span class="indicator {{ "blue" if timesheet.info.status=="Submitted" else "red" if timesheet.info.status=="Draft" else "darkgrey" }}" title="{{ timesheet.info.status }}" > {{ timesheet.info.name }} </span>
|
<span class="indicator {{ "blue" if timesheet.info.status=="Submitted" else "red" if timesheet.info.status=="Draft" else "darkgrey" }}" title="{{ timesheet.info.status }}" > {{ timesheet.info.name }} </span>
|
||||||
<div class="small text-muted item-timestamp">
|
<div class="small text-muted item-timestamp">
|
||||||
{{ _("From") }} {{ frappe.format_date(timesheet.from_time) }} {{ _("to") }} {{ frappe.format_date(timesheet.to_time) }}
|
{{ _("From") }} {{ frappe.format_date(timesheet.from_time) }} {{ _("to") }} {{ frappe.format_date(timesheet.to_time) }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class='col-xs-1 gravatar-top'>
|
<div class='col-xs-1' style="margin-right:-30px;">
|
||||||
<span class="avatar avatar-small" title="{{ timesheet.info.modified_by }}"> <img src="{{ timesheet.info.user_image }}"></span>
|
<span class="avatar avatar-small" title="{{ timesheet.info.modified_by }}"> <img src="{{ timesheet.info.user_image }}" style="display:flex;"></span>
|
||||||
</div>
|
</div>
|
||||||
<div class='col-xs-2'>
|
<div class='col-xs-1'>
|
||||||
<span class="pull-right list-comment-count small {{ "text-extra-muted" if timesheet.comment_count==0 else "text-muted" }}">
|
<span class="pull-right list-comment-count small {{ "text-extra-muted" if timesheet.comment_count==0 else "text-muted" }}">
|
||||||
<i class="octicon octicon-comment-discussion"></i>
|
<i class="octicon octicon-comment-discussion"></i>
|
||||||
{{ timesheet.info.comment_count }}
|
{{ timesheet.info.comment_count }}
|
||||||
|
@ -10,7 +10,7 @@ $(document).ready(function() {
|
|||||||
"method": "login",
|
"method": "login",
|
||||||
args: {
|
args: {
|
||||||
usr: "demo@erpnext.com",
|
usr: "demo@erpnext.com",
|
||||||
pwd: "demo",
|
pwd: "Demo1234567!!!",
|
||||||
lead_email: $("#lead-email").val(),
|
lead_email: $("#lead-email").val(),
|
||||||
},
|
},
|
||||||
callback: function(r) {
|
callback: function(r) {
|
||||||
|
@ -57,10 +57,34 @@
|
|||||||
{% else %}
|
{% else %}
|
||||||
<p class="text-muted">{{ _("No time sheets") }}</p>
|
<p class="text-muted">{{ _("No time sheets") }}</p>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
|
{% if doc.attachments %}
|
||||||
|
<div class='padding'></div>
|
||||||
|
|
||||||
|
<h4>{{ _("Attachments") }}</h4>
|
||||||
|
<div class="project-attachments">
|
||||||
|
{% for attachment in doc.attachments %}
|
||||||
|
<div class="attachment">
|
||||||
|
<a class="no-decoration attachment-link" href="{{ attachment.file_url }}" target="blank">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-xs-9">
|
||||||
|
<span class="indicator red file-name"> {{ attachment.file_name }}</span>
|
||||||
|
</div>
|
||||||
|
<div class="col-xs-3">
|
||||||
|
<span class="pull-right file-size">{{ attachment.file_size }}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
{% include "erpnext/templates/pages/projects.js" %}
|
{% include "frappe/public/js/frappe/provide.js" %}
|
||||||
|
{% include "frappe/public/js/frappe/form/formatters.js" %}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
@ -36,6 +36,10 @@ frappe.ready(function() {
|
|||||||
more_items('timeline', false);
|
more_items('timeline', false);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
$(".file-size").each(function() {
|
||||||
|
$(this).text(frappe.form.formatters.FileSize($(this).text()));
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
var reload_items = function(item_status, item, $btn) {
|
var reload_items = function(item_status, item, $btn) {
|
||||||
$.ajax({
|
$.ajax({
|
||||||
|
@ -6,7 +6,7 @@ import frappe
|
|||||||
import json
|
import json
|
||||||
|
|
||||||
def get_context(context):
|
def get_context(context):
|
||||||
project_user = frappe.db.get_value("Project User", {"parent": frappe.form_dict.project, "user": frappe.session.user} , "user")
|
project_user = frappe.db.get_value("Project User", {"parent": frappe.form_dict.project, "user": frappe.session.user} , ["user", "view_attachments"], as_dict= True)
|
||||||
if not project_user or frappe.session.user == 'Guest':
|
if not project_user or frappe.session.user == 'Guest':
|
||||||
raise frappe.PermissionError
|
raise frappe.PermissionError
|
||||||
|
|
||||||
@ -22,6 +22,8 @@ def get_context(context):
|
|||||||
project.timesheets = get_timesheets(project.name, start=0,
|
project.timesheets = get_timesheets(project.name, start=0,
|
||||||
search=frappe.form_dict.get("search"))
|
search=frappe.form_dict.get("search"))
|
||||||
|
|
||||||
|
if project_user.view_attachments:
|
||||||
|
project.attachments = get_attachments(project.name)
|
||||||
|
|
||||||
context.doc = project
|
context.doc = project
|
||||||
|
|
||||||
@ -92,3 +94,6 @@ def get_timesheet_html(project, start=0):
|
|||||||
return frappe.render_template("erpnext/templates/includes/projects/project_timesheets.html",
|
return frappe.render_template("erpnext/templates/includes/projects/project_timesheets.html",
|
||||||
{"doc": {"timesheets": get_timesheets(project, start)}}, is_path=True)
|
{"doc": {"timesheets": get_timesheets(project, start)}}, is_path=True)
|
||||||
|
|
||||||
|
def get_attachments(project):
|
||||||
|
return frappe.get_all('File', filters= {"attached_to_name": project, "attached_to_doctype": 'Project', "is_private":0},
|
||||||
|
fields=['file_name','file_url', 'file_size'])
|
||||||
|
Loading…
x
Reference in New Issue
Block a user