Merge branch 'develop' into fix-margin-for-filter
This commit is contained in:
commit
ccdaf3da66
@ -0,0 +1,89 @@
|
||||
<h1 class="text-center" style="page-break-before:always">{{ filters.party[0] }}</h1>
|
||||
<h3 class="text-center">{{ _("Statement of Accounts") }}</h3>
|
||||
|
||||
<h5 class="text-center">
|
||||
{{ frappe.format(filters.from_date, 'Date')}}
|
||||
{{ _("to") }}
|
||||
{{ frappe.format(filters.to_date, 'Date')}}
|
||||
</h5>
|
||||
|
||||
<table class="table table-bordered">
|
||||
<thead>
|
||||
<tr>
|
||||
<th style="width: 12%">{{ _("Date") }}</th>
|
||||
<th style="width: 15%">{{ _("Ref") }}</th>
|
||||
<th style="width: 25%">{{ _("Party") }}</th>
|
||||
<th style="width: 15%">{{ _("Debit") }}</th>
|
||||
<th style="width: 15%">{{ _("Credit") }}</th>
|
||||
<th style="width: 18%">{{ _("Balance (Dr - Cr)") }}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for row in data %}
|
||||
<tr>
|
||||
{% if(row.posting_date) %}
|
||||
<td>{{ frappe.format(row.posting_date, 'Date') }}</td>
|
||||
<td>{{ row.voucher_type }}
|
||||
<br>{{ row.voucher_no }}</td>
|
||||
<td>
|
||||
{% if not (filters.party or filters.account) %}
|
||||
{{ row.party or row.account }}
|
||||
<br>
|
||||
{% endif %}
|
||||
|
||||
{{ _("Against") }}: {{ row.against }}
|
||||
<br>{{ _("Remarks") }}: {{ row.remarks }}
|
||||
{% if row.bill_no %}
|
||||
<br>{{ _("Supplier Invoice No") }}: {{ row.bill_no }}
|
||||
{% endif %}
|
||||
</td>
|
||||
<td style="text-align: right">
|
||||
{{ frappe.utils.fmt_money(row.debit, filters.presentation_currency) }}</td>
|
||||
<td style="text-align: right">
|
||||
{{ frappe.utils.fmt_money(row.credit, filters.presentation_currency) }}</td>
|
||||
{% else %}
|
||||
<td></td>
|
||||
<td></td>
|
||||
<td><b>{{ frappe.format(row.account, {fieldtype: "Link"}) or " " }}</b></td>
|
||||
<td style="text-align: right">
|
||||
{{ row.account and frappe.utils.fmt_money(row.debit, filters.presentation_currency) }}
|
||||
</td>
|
||||
<td style="text-align: right">
|
||||
{{ row.account and frappe.utils.fmt_money(row.credit, filters.presentation_currency) }}
|
||||
</td>
|
||||
{% endif %}
|
||||
<td style="text-align: right">
|
||||
{{ frappe.utils.fmt_money(row.balance, filters.presentation_currency) }}
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
<br><br>
|
||||
{% if aging %}
|
||||
<h3 class="text-center">{{ _("Ageing Report Based On ") }} {{ aging.ageing_based_on }}</h3>
|
||||
<h5 class="text-center">
|
||||
{{ _("Up to " ) }} {{ frappe.format(filters.to_date, 'Date')}}
|
||||
</h5>
|
||||
<br>
|
||||
|
||||
<table class="table table-bordered">
|
||||
<thead>
|
||||
<tr>
|
||||
<th style="width: 12%">30 Days</th>
|
||||
<th style="width: 15%">60 Days</th>
|
||||
<th style="width: 25%">90 Days</th>
|
||||
<th style="width: 15%">120 Days</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>{{ aging.range1 }}</td>
|
||||
<td>{{ aging.range2 }}</td>
|
||||
<td>{{ aging.range3 }}</td>
|
||||
<td>{{ aging.range4 }}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
{% endif %}
|
||||
<p class="text-right text-muted">Printed On {{ frappe.format(frappe.utils.get_datetime(), 'Datetime') }}</p>
|
@ -0,0 +1,132 @@
|
||||
// Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and contributors
|
||||
// For license information, please see license.txt
|
||||
|
||||
frappe.ui.form.on('Process Statement Of Accounts', {
|
||||
view_properties: function(frm) {
|
||||
frappe.route_options = {doc_type: 'Customer'};
|
||||
frappe.set_route("Form", "Customize Form");
|
||||
},
|
||||
refresh: function(frm){
|
||||
if(!frm.doc.__islocal) {
|
||||
frm.add_custom_button('Send Emails',function(){
|
||||
frappe.call({
|
||||
method: "erpnext.accounts.doctype.process_statement_of_accounts.process_statement_of_accounts.send_emails",
|
||||
args: {
|
||||
"document_name": frm.doc.name,
|
||||
},
|
||||
callback: function(r) {
|
||||
if(r && r.message) {
|
||||
frappe.show_alert({message: __('Emails Queued'), indicator: 'blue'});
|
||||
}
|
||||
else{
|
||||
frappe.msgprint('No Records for these settings.')
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
frm.add_custom_button('Download',function(){
|
||||
var url = frappe.urllib.get_full_url(
|
||||
'/api/method/erpnext.accounts.doctype.process_statement_of_accounts.process_statement_of_accounts.download_statements?'
|
||||
+ 'document_name='+encodeURIComponent(frm.doc.name))
|
||||
$.ajax({
|
||||
url: url,
|
||||
type: 'GET',
|
||||
success: function(result) {
|
||||
if(jQuery.isEmptyObject(result)){
|
||||
frappe.msgprint('No Records for these settings.');
|
||||
}
|
||||
else{
|
||||
window.location = url;
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
},
|
||||
onload: function(frm) {
|
||||
frm.set_query('currency', function(){
|
||||
return {
|
||||
filters: {
|
||||
'enabled': 1
|
||||
}
|
||||
}
|
||||
});
|
||||
if(frm.doc.__islocal){
|
||||
frm.set_value('from_date', frappe.datetime.add_months(frappe.datetime.get_today(), -1));
|
||||
frm.set_value('to_date', frappe.datetime.get_today());
|
||||
}
|
||||
},
|
||||
customer_collection: function(frm){
|
||||
frm.set_value('collection_name', '');
|
||||
if(frm.doc.customer_collection){
|
||||
frm.get_field('collection_name').set_label(frm.doc.customer_collection);
|
||||
}
|
||||
},
|
||||
frequency: function(frm){
|
||||
if(frm.doc.frequency != ''){
|
||||
frm.set_value('start_date', frappe.datetime.get_today());
|
||||
}
|
||||
else{
|
||||
frm.set_value('start_date', '');
|
||||
}
|
||||
},
|
||||
fetch_customers: function(frm){
|
||||
if(frm.doc.collection_name){
|
||||
frappe.call({
|
||||
method: "erpnext.accounts.doctype.process_statement_of_accounts.process_statement_of_accounts.fetch_customers",
|
||||
args: {
|
||||
'customer_collection': frm.doc.customer_collection,
|
||||
'collection_name': frm.doc.collection_name,
|
||||
'primary_mandatory': frm.doc.primary_mandatory
|
||||
},
|
||||
callback: function(r) {
|
||||
if(!r.exc) {
|
||||
if(r.message.length){
|
||||
frm.clear_table('customers');
|
||||
for (const customer of r.message){
|
||||
var row = frm.add_child('customers');
|
||||
row.customer = customer.name;
|
||||
row.primary_email = customer.primary_email;
|
||||
row.billing_email = customer.billing_email;
|
||||
}
|
||||
frm.refresh_field('customers');
|
||||
}
|
||||
else{
|
||||
frappe.msgprint('No Customers found with selected options.');
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
else {
|
||||
frappe.throw('Enter ' + frm.doc.customer_collection + ' name.');
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
frappe.ui.form.on('Process Statement Of Accounts Customer', {
|
||||
customer: function(frm, cdt, cdn){
|
||||
var row = locals[cdt][cdn];
|
||||
if (!row.customer){
|
||||
return;
|
||||
}
|
||||
frappe.call({
|
||||
method: 'erpnext.accounts.doctype.process_statement_of_accounts.process_statement_of_accounts.get_customer_emails',
|
||||
args: {
|
||||
'customer_name': row.customer,
|
||||
'primary_mandatory': frm.doc.primary_mandatory
|
||||
},
|
||||
callback: function(r){
|
||||
if(!r.exe){
|
||||
if(r.message.length){
|
||||
frappe.model.set_value(cdt, cdn, "primary_email", r.message[0])
|
||||
frappe.model.set_value(cdt, cdn, "billing_email", r.message[1])
|
||||
}
|
||||
else {
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
});
|
@ -0,0 +1,310 @@
|
||||
{
|
||||
"actions": [],
|
||||
"allow_workflow": 1,
|
||||
"autoname": "Prompt",
|
||||
"creation": "2020-05-22 16:46:18.712954",
|
||||
"doctype": "DocType",
|
||||
"editable_grid": 1,
|
||||
"engine": "InnoDB",
|
||||
"field_order": [
|
||||
"section_break_11",
|
||||
"from_date",
|
||||
"company",
|
||||
"account",
|
||||
"group_by",
|
||||
"cost_center",
|
||||
"column_break_14",
|
||||
"to_date",
|
||||
"finance_book",
|
||||
"currency",
|
||||
"project",
|
||||
"section_break_3",
|
||||
"customer_collection",
|
||||
"collection_name",
|
||||
"fetch_customers",
|
||||
"column_break_6",
|
||||
"primary_mandatory",
|
||||
"column_break_17",
|
||||
"customers",
|
||||
"preferences",
|
||||
"orientation",
|
||||
"section_break_14",
|
||||
"include_ageing",
|
||||
"ageing_based_on",
|
||||
"section_break_1",
|
||||
"enable_auto_email",
|
||||
"section_break_18",
|
||||
"frequency",
|
||||
"filter_duration",
|
||||
"column_break_21",
|
||||
"start_date",
|
||||
"section_break_33",
|
||||
"subject",
|
||||
"column_break_28",
|
||||
"cc_to",
|
||||
"section_break_30",
|
||||
"body",
|
||||
"help_text"
|
||||
],
|
||||
"fields": [
|
||||
{
|
||||
"fieldname": "frequency",
|
||||
"fieldtype": "Select",
|
||||
"label": "Frequency",
|
||||
"options": "Weekly\nMonthly\nQuarterly"
|
||||
},
|
||||
{
|
||||
"fieldname": "company",
|
||||
"fieldtype": "Link",
|
||||
"in_list_view": 1,
|
||||
"label": "Company",
|
||||
"options": "Company",
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
"depends_on": "eval:doc.enable_auto_email == 0;",
|
||||
"fieldname": "from_date",
|
||||
"fieldtype": "Date",
|
||||
"label": "From Date",
|
||||
"mandatory_depends_on": "eval:doc.frequency == '';"
|
||||
},
|
||||
{
|
||||
"depends_on": "eval:doc.enable_auto_email == 0;",
|
||||
"fieldname": "to_date",
|
||||
"fieldtype": "Date",
|
||||
"label": "To Date",
|
||||
"mandatory_depends_on": "eval:doc.frequency == '';"
|
||||
},
|
||||
{
|
||||
"fieldname": "cost_center",
|
||||
"fieldtype": "Table MultiSelect",
|
||||
"label": "Cost Center",
|
||||
"options": "PSOA Cost Center"
|
||||
},
|
||||
{
|
||||
"fieldname": "project",
|
||||
"fieldtype": "Table MultiSelect",
|
||||
"label": "Project",
|
||||
"options": "PSOA Project"
|
||||
},
|
||||
{
|
||||
"fieldname": "section_break_3",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "Customers"
|
||||
},
|
||||
{
|
||||
"fieldname": "column_break_6",
|
||||
"fieldtype": "Column Break"
|
||||
},
|
||||
{
|
||||
"fieldname": "section_break_11",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "General Ledger Filters"
|
||||
},
|
||||
{
|
||||
"fieldname": "column_break_14",
|
||||
"fieldtype": "Column Break"
|
||||
},
|
||||
{
|
||||
"fieldname": "column_break_17",
|
||||
"fieldtype": "Section Break",
|
||||
"hide_border": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "customer_collection",
|
||||
"fieldtype": "Select",
|
||||
"label": "Select Customers By",
|
||||
"options": "\nCustomer Group\nTerritory\nSales Partner\nSales Person"
|
||||
},
|
||||
{
|
||||
"depends_on": "eval: doc.customer_collection !== ''",
|
||||
"fieldname": "collection_name",
|
||||
"fieldtype": "Dynamic Link",
|
||||
"label": "Recipient",
|
||||
"options": "customer_collection"
|
||||
},
|
||||
{
|
||||
"fieldname": "section_break_1",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "Email Settings"
|
||||
},
|
||||
{
|
||||
"fieldname": "account",
|
||||
"fieldtype": "Link",
|
||||
"label": "Account",
|
||||
"options": "Account"
|
||||
},
|
||||
{
|
||||
"fieldname": "finance_book",
|
||||
"fieldtype": "Link",
|
||||
"label": "Finance Book",
|
||||
"options": "Finance Book"
|
||||
},
|
||||
{
|
||||
"fieldname": "preferences",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "Print Preferences"
|
||||
},
|
||||
{
|
||||
"fieldname": "orientation",
|
||||
"fieldtype": "Select",
|
||||
"label": "Orientation",
|
||||
"options": "Landscape\nPortrait"
|
||||
},
|
||||
{
|
||||
"default": "Today",
|
||||
"fieldname": "start_date",
|
||||
"fieldtype": "Date",
|
||||
"label": "Start Date"
|
||||
},
|
||||
{
|
||||
"default": "Group by Voucher (Consolidated)",
|
||||
"fieldname": "group_by",
|
||||
"fieldtype": "Select",
|
||||
"label": "Group By",
|
||||
"options": "\nGroup by Voucher\nGroup by Voucher (Consolidated)"
|
||||
},
|
||||
{
|
||||
"fieldname": "currency",
|
||||
"fieldtype": "Link",
|
||||
"label": "Currency",
|
||||
"options": "Currency"
|
||||
},
|
||||
{
|
||||
"default": "0",
|
||||
"fieldname": "include_ageing",
|
||||
"fieldtype": "Check",
|
||||
"in_list_view": 1,
|
||||
"label": "Include Ageing Summary"
|
||||
},
|
||||
{
|
||||
"default": "Due Date",
|
||||
"depends_on": "eval:doc.include_ageing === 1",
|
||||
"fieldname": "ageing_based_on",
|
||||
"fieldtype": "Select",
|
||||
"label": "Ageing Based On",
|
||||
"options": "Due Date\nPosting Date"
|
||||
},
|
||||
{
|
||||
"default": "0",
|
||||
"fieldname": "enable_auto_email",
|
||||
"fieldtype": "Check",
|
||||
"in_list_view": 1,
|
||||
"label": "Enable Auto Email"
|
||||
},
|
||||
{
|
||||
"fieldname": "section_break_14",
|
||||
"fieldtype": "Column Break",
|
||||
"hide_border": 1
|
||||
},
|
||||
{
|
||||
"depends_on": "eval: doc.enable_auto_email ==1",
|
||||
"fieldname": "section_break_18",
|
||||
"fieldtype": "Section Break",
|
||||
"hide_border": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "column_break_21",
|
||||
"fieldtype": "Column Break"
|
||||
},
|
||||
{
|
||||
"depends_on": "eval: doc.customer_collection !== ''",
|
||||
"fieldname": "fetch_customers",
|
||||
"fieldtype": "Button",
|
||||
"label": "Fetch Customers",
|
||||
"options": "fetch_customers",
|
||||
"print_hide": 1,
|
||||
"report_hide": 1
|
||||
},
|
||||
{
|
||||
"default": "1",
|
||||
"fieldname": "primary_mandatory",
|
||||
"fieldtype": "Check",
|
||||
"label": "Send To Primary Contact"
|
||||
},
|
||||
{
|
||||
"fieldname": "cc_to",
|
||||
"fieldtype": "Link",
|
||||
"label": "CC To",
|
||||
"options": "User"
|
||||
},
|
||||
{
|
||||
"default": "1",
|
||||
"fieldname": "filter_duration",
|
||||
"fieldtype": "Int",
|
||||
"label": "Filter Duration (Months)"
|
||||
},
|
||||
{
|
||||
"fieldname": "customers",
|
||||
"fieldtype": "Table",
|
||||
"label": "Customers",
|
||||
"options": "Process Statement Of Accounts Customer",
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "column_break_28",
|
||||
"fieldtype": "Column Break"
|
||||
},
|
||||
{
|
||||
"fieldname": "section_break_30",
|
||||
"fieldtype": "Section Break",
|
||||
"hide_border": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "section_break_33",
|
||||
"fieldtype": "Section Break",
|
||||
"hide_border": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "help_text",
|
||||
"fieldtype": "HTML",
|
||||
"label": "Help Text",
|
||||
"options": "<br>\n<h4>Note</h4>\n<ul>\n<li>\nYou can use <a href=\"https://jinja.palletsprojects.com/en/2.11.x/\" target=\"_blank\">Jinja tags</a> in <b>Subject</b> and <b>Body</b> fields for dynamic values.\n</li><li>\n All fields in this doctype are available under the <b>doc</b> object and all fields for the customer to whom the mail will go to is available under the <b>customer</b> object.\n</li></ul>\n<h4> Examples</h4>\n<!-- {% raw %} -->\n<ul>\n <li><b>Subject</b>:<br><br><pre><code>Statement Of Accounts for {{ customer.name }}</code></pre><br></li>\n <li><b>Body</b>: <br><br>\n<pre><code>Hello {{ customer.name }},<br>PFA your Statement Of Accounts from {{ doc.from_date }} to {{ doc.to_date }}.</code> </pre></li>\n</ul>\n<!-- {% endraw %} -->"
|
||||
},
|
||||
{
|
||||
"fieldname": "subject",
|
||||
"fieldtype": "Data",
|
||||
"label": "Subject"
|
||||
},
|
||||
{
|
||||
"fieldname": "body",
|
||||
"fieldtype": "Text Editor",
|
||||
"label": "Body"
|
||||
}
|
||||
],
|
||||
"links": [],
|
||||
"modified": "2020-08-08 08:47:09.185728",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "Process Statement Of Accounts",
|
||||
"owner": "Administrator",
|
||||
"permissions": [
|
||||
{
|
||||
"create": 1,
|
||||
"delete": 1,
|
||||
"email": 1,
|
||||
"export": 1,
|
||||
"print": 1,
|
||||
"read": 1,
|
||||
"report": 1,
|
||||
"role": "Accounts User",
|
||||
"share": 1,
|
||||
"write": 1
|
||||
},
|
||||
{
|
||||
"create": 1,
|
||||
"delete": 1,
|
||||
"email": 1,
|
||||
"export": 1,
|
||||
"print": 1,
|
||||
"read": 1,
|
||||
"report": 1,
|
||||
"role": "Accounts Manager",
|
||||
"share": 1,
|
||||
"write": 1
|
||||
}
|
||||
],
|
||||
"sort_field": "modified",
|
||||
"sort_order": "DESC",
|
||||
"track_changes": 1
|
||||
}
|
@ -0,0 +1,271 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and contributors
|
||||
# For license information, please see license.txt
|
||||
|
||||
from __future__ import unicode_literals
|
||||
import frappe
|
||||
from frappe.model.document import Document
|
||||
from erpnext.accounts.report.general_ledger.general_ledger import execute as get_soa
|
||||
from erpnext.accounts.report.accounts_receivable_summary.accounts_receivable_summary import execute as get_ageing
|
||||
from frappe.core.doctype.communication.email import make
|
||||
|
||||
from frappe.utils.print_format import report_to_pdf
|
||||
from frappe.utils.pdf import get_pdf
|
||||
from frappe.utils import today, add_days, add_months, getdate, format_date
|
||||
from frappe.utils.jinja import validate_template
|
||||
|
||||
import copy
|
||||
from datetime import timedelta
|
||||
from frappe.www.printview import get_print_style
|
||||
|
||||
class ProcessStatementOfAccounts(Document):
|
||||
def validate(self):
|
||||
if not self.subject:
|
||||
self.subject = 'Statement Of Accounts for {{ customer.name }}'
|
||||
if not self.body:
|
||||
self.body = 'Hello {{ customer.name }},<br>PFA your Statement Of Accounts from {{ doc.from_date }} to {{ doc.to_date }}.'
|
||||
|
||||
validate_template(self.subject)
|
||||
validate_template(self.body)
|
||||
|
||||
if not self.customers:
|
||||
frappe.throw(frappe._('Customers not selected.'))
|
||||
|
||||
if self.enable_auto_email:
|
||||
self.to_date = self.start_date
|
||||
self.from_date = add_months(self.to_date, -1 * self.filter_duration)
|
||||
|
||||
|
||||
def get_report_pdf(doc, consolidated=True):
|
||||
statement_dict = {}
|
||||
aging = ''
|
||||
base_template_path = "frappe/www/printview.html"
|
||||
template_path = "erpnext/accounts/doctype/process_statement_of_accounts/process_statement_of_accounts.html"
|
||||
|
||||
for entry in doc.customers:
|
||||
if doc.include_ageing:
|
||||
ageing_filters = frappe._dict({
|
||||
'company': doc.company,
|
||||
'report_date': doc.to_date,
|
||||
'ageing_based_on': doc.ageing_based_on,
|
||||
'range1': 30,
|
||||
'range2': 60,
|
||||
'range3': 90,
|
||||
'range4': 120,
|
||||
'customer': entry.customer
|
||||
})
|
||||
col1, aging = get_ageing(ageing_filters)
|
||||
aging[0]['ageing_based_on'] = doc.ageing_based_on
|
||||
|
||||
tax_id = frappe.get_doc('Customer', entry.customer).tax_id
|
||||
|
||||
filters= frappe._dict({
|
||||
'from_date': doc.from_date,
|
||||
'to_date': doc.to_date,
|
||||
'company': doc.company,
|
||||
'finance_book': doc.finance_book if doc.finance_book else None,
|
||||
"account": doc.account if doc.account else None,
|
||||
'party_type': 'Customer',
|
||||
'party': [entry.customer],
|
||||
'group_by': doc.group_by,
|
||||
'currency': doc.currency,
|
||||
'cost_center': [cc.cost_center_name for cc in doc.cost_center],
|
||||
'project': [p.project_name for p in doc.project],
|
||||
'show_opening_entries': 0,
|
||||
'include_default_book_entries': 0,
|
||||
'show_cancelled_entries': 1,
|
||||
'tax_id': tax_id if tax_id else None
|
||||
})
|
||||
col, res = get_soa(filters)
|
||||
|
||||
for x in [0, -2, -1]:
|
||||
res[x]['account'] = res[x]['account'].replace("'","")
|
||||
|
||||
if len(res) == 3:
|
||||
continue
|
||||
html = frappe.render_template(template_path, \
|
||||
{"filters": filters, "data": res, "aging": aging[0] if doc.include_ageing else None})
|
||||
html = frappe.render_template(base_template_path, {"body": html, \
|
||||
"css": get_print_style(), "title": "Statement For " + entry.customer})
|
||||
statement_dict[entry.customer] = html
|
||||
if not bool(statement_dict):
|
||||
return False
|
||||
elif consolidated:
|
||||
result = ''.join(list(statement_dict.values()))
|
||||
return get_pdf(result, {'orientation': doc.orientation})
|
||||
else:
|
||||
for customer, statement_html in statement_dict.items():
|
||||
statement_dict[customer]=get_pdf(statement_html, {'orientation': doc.orientation})
|
||||
return statement_dict
|
||||
|
||||
def get_customers_based_on_territory_or_customer_group(customer_collection, collection_name):
|
||||
fields_dict = {
|
||||
'Customer Group': 'customer_group',
|
||||
'Territory': 'territory',
|
||||
}
|
||||
collection = frappe.get_doc(customer_collection, collection_name)
|
||||
selected = [customer.name for customer in frappe.get_list(customer_collection, filters=[
|
||||
['lft', '>=', collection.lft],
|
||||
['rgt', '<=', collection.rgt]
|
||||
],
|
||||
fields=['name'],
|
||||
order_by='lft asc, rgt desc'
|
||||
)]
|
||||
return frappe.get_list('Customer', fields=['name', 'email_id'], \
|
||||
filters=[[fields_dict[customer_collection], 'IN', selected]])
|
||||
|
||||
def get_customers_based_on_sales_person(sales_person):
|
||||
lft, rgt = frappe.db.get_value("Sales Person",
|
||||
sales_person, ["lft", "rgt"])
|
||||
records = frappe.db.sql("""
|
||||
select distinct parent, parenttype
|
||||
from `tabSales Team` steam
|
||||
where parenttype = 'Customer'
|
||||
and exists(select name from `tabSales Person` where lft >= %s and rgt <= %s and name = steam.sales_person)
|
||||
""", (lft, rgt), as_dict=1)
|
||||
sales_person_records = frappe._dict()
|
||||
for d in records:
|
||||
sales_person_records.setdefault(d.parenttype, set()).add(d.parent)
|
||||
customers = frappe.get_list('Customer', fields=['name', 'email_id'], \
|
||||
filters=[['name', 'in', list(sales_person_records['Customer'])]])
|
||||
return customers
|
||||
|
||||
def get_recipients_and_cc(customer, doc):
|
||||
recipients = []
|
||||
for clist in doc.customers:
|
||||
if clist.customer == customer:
|
||||
recipients.append(clist.billing_email)
|
||||
if doc.primary_mandatory and clist.primary_email:
|
||||
recipients.append(clist.primary_email)
|
||||
cc = []
|
||||
if doc.cc_to != '':
|
||||
try:
|
||||
cc=[frappe.get_value('User', doc.cc_to, 'email')]
|
||||
except:
|
||||
pass
|
||||
|
||||
return recipients, cc
|
||||
|
||||
def get_context(customer, doc):
|
||||
template_doc = copy.deepcopy(doc)
|
||||
del template_doc.customers
|
||||
template_doc.from_date = format_date(template_doc.from_date)
|
||||
template_doc.to_date = format_date(template_doc.to_date)
|
||||
return {
|
||||
'doc': template_doc,
|
||||
'customer': frappe.get_doc('Customer', customer),
|
||||
'frappe': frappe.utils
|
||||
}
|
||||
|
||||
@frappe.whitelist()
|
||||
def fetch_customers(customer_collection, collection_name, primary_mandatory):
|
||||
customer_list = []
|
||||
customers = []
|
||||
|
||||
if customer_collection == 'Sales Person':
|
||||
customers = get_customers_based_on_sales_person(collection_name)
|
||||
if not bool(customers):
|
||||
frappe.throw('No Customers found with selected options.')
|
||||
else:
|
||||
if customer_collection == 'Sales Partner':
|
||||
customers = frappe.get_list('Customer', fields=['name', 'email_id'], \
|
||||
filters=[['default_sales_partner', '=', collection_name]])
|
||||
else:
|
||||
customers = get_customers_based_on_territory_or_customer_group(customer_collection, collection_name)
|
||||
|
||||
for customer in customers:
|
||||
primary_email = customer.get('email_id') or ''
|
||||
billing_email = get_customer_emails(customer.name, 1, billing_and_primary=False)
|
||||
|
||||
if billing_email == '' or (primary_email == '' and int(primary_mandatory)):
|
||||
continue
|
||||
|
||||
customer_list.append({
|
||||
'name': customer.name,
|
||||
'primary_email': primary_email,
|
||||
'billing_email': billing_email
|
||||
})
|
||||
return customer_list
|
||||
|
||||
@frappe.whitelist()
|
||||
def get_customer_emails(customer_name, primary_mandatory, billing_and_primary=True):
|
||||
billing_email = frappe.db.sql("""
|
||||
SELECT c.email_id FROM `tabContact` AS c JOIN `tabDynamic Link` AS l ON c.name=l.parent \
|
||||
WHERE l.link_doctype='Customer' and l.link_name='""" + customer_name + """' and \
|
||||
c.is_billing_contact=1 \
|
||||
order by c.creation desc""")
|
||||
|
||||
if len(billing_email) == 0 or (billing_email[0][0] is None):
|
||||
if billing_and_primary:
|
||||
frappe.throw('No billing email found for customer: '+ customer_name)
|
||||
else:
|
||||
return ''
|
||||
|
||||
if billing_and_primary:
|
||||
primary_email = frappe.get_value('Customer', customer_name, 'email_id')
|
||||
if primary_email is None and int(primary_mandatory):
|
||||
frappe.throw('No primary email found for customer: '+ customer_name)
|
||||
return [primary_email or '', billing_email[0][0]]
|
||||
else:
|
||||
return billing_email[0][0] or ''
|
||||
|
||||
@frappe.whitelist()
|
||||
def download_statements(document_name):
|
||||
doc = frappe.get_doc('Process Statement Of Accounts', document_name)
|
||||
report = get_report_pdf(doc)
|
||||
if report:
|
||||
frappe.local.response.filename = doc.name + '.pdf'
|
||||
frappe.local.response.filecontent = report
|
||||
frappe.local.response.type = "download"
|
||||
|
||||
@frappe.whitelist()
|
||||
def send_emails(document_name, from_scheduler=False):
|
||||
doc = frappe.get_doc('Process Statement Of Accounts', document_name)
|
||||
report = get_report_pdf(doc, consolidated=False)
|
||||
|
||||
if report:
|
||||
for customer, report_pdf in report.items():
|
||||
attachments = [{
|
||||
'fname': customer + '.pdf',
|
||||
'fcontent': report_pdf
|
||||
}]
|
||||
|
||||
recipients, cc = get_recipients_and_cc(customer, doc)
|
||||
context = get_context(customer, doc)
|
||||
subject = frappe.render_template(doc.subject, context)
|
||||
message = frappe.render_template(doc.body, context)
|
||||
|
||||
frappe.enqueue(
|
||||
queue='short',
|
||||
method=frappe.sendmail,
|
||||
recipients=recipients,
|
||||
sender=frappe.session.user,
|
||||
cc=cc,
|
||||
subject=subject,
|
||||
message=message,
|
||||
now=True,
|
||||
reference_doctype='Process Statement Of Accounts',
|
||||
reference_name=document_name,
|
||||
attachments=attachments
|
||||
)
|
||||
|
||||
if doc.enable_auto_email and from_scheduler:
|
||||
new_to_date = getdate(today())
|
||||
if doc.frequency == 'Weekly':
|
||||
new_to_date = add_days(new_to_date, 7)
|
||||
else:
|
||||
new_to_date = add_months(new_to_date, 1 if doc.frequency == 'Monthly' else 3)
|
||||
new_from_date = add_months(new_to_date, -1 * doc.filter_duration)
|
||||
doc.add_comment('Comment', 'Emails sent on: ' + frappe.utils.format_datetime(frappe.utils.now()))
|
||||
doc.db_set('to_date', new_to_date, commit=True)
|
||||
doc.db_set('from_date', new_from_date, commit=True)
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
@frappe.whitelist()
|
||||
def send_auto_email():
|
||||
selected = frappe.get_list('Process Statement Of Accounts', filters={'to_date': format_date(today()), 'enable_auto_email': 1})
|
||||
for entry in selected:
|
||||
send_emails(entry.name, from_scheduler=True)
|
||||
return True
|
@ -0,0 +1,10 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and Contributors
|
||||
# See license.txt
|
||||
from __future__ import unicode_literals
|
||||
|
||||
# import frappe
|
||||
import unittest
|
||||
|
||||
class TestProcessStatementOfAccounts(unittest.TestCase):
|
||||
pass
|
@ -0,0 +1,47 @@
|
||||
{
|
||||
"actions": [],
|
||||
"allow_workflow": 1,
|
||||
"creation": "2020-08-03 16:35:21.852178",
|
||||
"doctype": "DocType",
|
||||
"editable_grid": 1,
|
||||
"engine": "InnoDB",
|
||||
"field_order": [
|
||||
"customer",
|
||||
"billing_email",
|
||||
"primary_email"
|
||||
],
|
||||
"fields": [
|
||||
{
|
||||
"fieldname": "customer",
|
||||
"fieldtype": "Link",
|
||||
"in_list_view": 1,
|
||||
"label": "Customer",
|
||||
"options": "Customer",
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "primary_email",
|
||||
"fieldtype": "Read Only",
|
||||
"in_list_view": 1,
|
||||
"label": "Primary Contact Email"
|
||||
},
|
||||
{
|
||||
"fieldname": "billing_email",
|
||||
"fieldtype": "Read Only",
|
||||
"in_list_view": 1,
|
||||
"label": "Billing Email"
|
||||
}
|
||||
],
|
||||
"istable": 1,
|
||||
"links": [],
|
||||
"modified": "2020-08-03 22:55:38.875601",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "Process Statement Of Accounts Customer",
|
||||
"owner": "Administrator",
|
||||
"permissions": [],
|
||||
"quick_entry": 1,
|
||||
"sort_field": "modified",
|
||||
"sort_order": "DESC",
|
||||
"track_changes": 1
|
||||
}
|
@ -0,0 +1,10 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and contributors
|
||||
# For license information, please see license.txt
|
||||
|
||||
from __future__ import unicode_literals
|
||||
# import frappe
|
||||
from frappe.model.document import Document
|
||||
|
||||
class ProcessStatementOfAccountsCustomer(Document):
|
||||
pass
|
@ -0,0 +1,30 @@
|
||||
{
|
||||
"actions": [],
|
||||
"creation": "2020-08-03 16:56:45.744905",
|
||||
"doctype": "DocType",
|
||||
"editable_grid": 1,
|
||||
"engine": "InnoDB",
|
||||
"field_order": [
|
||||
"cost_center_name"
|
||||
],
|
||||
"fields": [
|
||||
{
|
||||
"fieldname": "cost_center_name",
|
||||
"fieldtype": "Link",
|
||||
"label": "Cost Center",
|
||||
"options": "Cost Center"
|
||||
}
|
||||
],
|
||||
"istable": 1,
|
||||
"links": [],
|
||||
"modified": "2020-08-03 16:56:45.744905",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "PSOA Cost Center",
|
||||
"owner": "Administrator",
|
||||
"permissions": [],
|
||||
"quick_entry": 1,
|
||||
"sort_field": "modified",
|
||||
"sort_order": "DESC",
|
||||
"track_changes": 1
|
||||
}
|
@ -0,0 +1,10 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and contributors
|
||||
# For license information, please see license.txt
|
||||
|
||||
from __future__ import unicode_literals
|
||||
# import frappe
|
||||
from frappe.model.document import Document
|
||||
|
||||
class PSOACostCenter(Document):
|
||||
pass
|
0
erpnext/accounts/doctype/psoa_project/__init__.py
Normal file
0
erpnext/accounts/doctype/psoa_project/__init__.py
Normal file
30
erpnext/accounts/doctype/psoa_project/psoa_project.json
Normal file
30
erpnext/accounts/doctype/psoa_project/psoa_project.json
Normal file
@ -0,0 +1,30 @@
|
||||
{
|
||||
"actions": [],
|
||||
"creation": "2020-08-03 16:52:14.731978",
|
||||
"doctype": "DocType",
|
||||
"editable_grid": 1,
|
||||
"engine": "InnoDB",
|
||||
"field_order": [
|
||||
"project_name"
|
||||
],
|
||||
"fields": [
|
||||
{
|
||||
"fieldname": "project_name",
|
||||
"fieldtype": "Link",
|
||||
"label": "Project",
|
||||
"options": "Project"
|
||||
}
|
||||
],
|
||||
"istable": 1,
|
||||
"links": [],
|
||||
"modified": "2020-08-03 16:53:39.219736",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "PSOA Project",
|
||||
"owner": "Administrator",
|
||||
"permissions": [],
|
||||
"quick_entry": 1,
|
||||
"sort_field": "modified",
|
||||
"sort_order": "DESC",
|
||||
"track_changes": 1
|
||||
}
|
10
erpnext/accounts/doctype/psoa_project/psoa_project.py
Normal file
10
erpnext/accounts/doctype/psoa_project/psoa_project.py
Normal file
@ -0,0 +1,10 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and contributors
|
||||
# For license information, please see license.txt
|
||||
|
||||
from __future__ import unicode_literals
|
||||
# import frappe
|
||||
from frappe.model.document import Document
|
||||
|
||||
class PSOAProject(Document):
|
||||
pass
|
@ -180,7 +180,7 @@
|
||||
"no_copy": 1,
|
||||
"oldfieldname": "naming_series",
|
||||
"oldfieldtype": "Select",
|
||||
"options": "ACC-PINV-.YYYY.-",
|
||||
"options": "ACC-PINV-.YYYY.-\nACC-PINV-RET-.YYYY.-",
|
||||
"print_hide": 1,
|
||||
"reqd": 1,
|
||||
"set_only_once": 1
|
||||
@ -1334,7 +1334,7 @@
|
||||
"idx": 204,
|
||||
"is_submittable": 1,
|
||||
"links": [],
|
||||
"modified": "2020-08-03 12:46:01.411074",
|
||||
"modified": "2020-08-03 23:20:04.466153",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "Purchase Invoice",
|
||||
@ -1396,4 +1396,4 @@
|
||||
"timeline_field": "supplier",
|
||||
"title_field": "title",
|
||||
"track_changes": 1
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,6 @@
|
||||
{
|
||||
"actions": [],
|
||||
"allow_import": 1,
|
||||
"allow_workflow": 1,
|
||||
"autoname": "naming_series:",
|
||||
"creation": "2013-05-24 19:29:05",
|
||||
"doctype": "DocType",
|
||||
@ -217,7 +216,7 @@
|
||||
"no_copy": 1,
|
||||
"oldfieldname": "naming_series",
|
||||
"oldfieldtype": "Select",
|
||||
"options": "ACC-SINV-.YYYY.-",
|
||||
"options": "ACC-SINV-.YYYY.-\nACC-SINV-RET-.YYYY.-",
|
||||
"print_hide": 1,
|
||||
"reqd": 1,
|
||||
"set_only_once": 1
|
||||
@ -1947,7 +1946,7 @@
|
||||
"idx": 181,
|
||||
"is_submittable": 1,
|
||||
"links": [],
|
||||
"modified": "2020-07-18 05:07:16.725974",
|
||||
"modified": "2020-08-03 23:31:12.675040",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "Sales Invoice",
|
||||
|
@ -479,7 +479,11 @@ class AccountsController(TransactionBase):
|
||||
if d.against_order:
|
||||
allocated_amount = flt(d.amount)
|
||||
else:
|
||||
amount = self.rounded_total or self.grand_total
|
||||
if self.get('party_account_currency') == self.company_currency:
|
||||
amount = self.get('base_rounded_total') or self.base_grand_total
|
||||
else:
|
||||
amount = self.get('rounded_total') or self.grand_total
|
||||
|
||||
allocated_amount = min(amount - advance_allocated, d.amount)
|
||||
advance_allocated += flt(allocated_amount)
|
||||
|
||||
@ -802,10 +806,22 @@ class AccountsController(TransactionBase):
|
||||
self.payment_terms_template = ''
|
||||
return
|
||||
|
||||
party_account_currency = self.get('party_account_currency')
|
||||
if not party_account_currency:
|
||||
party_type, party = self.get_party()
|
||||
|
||||
if party_type and party:
|
||||
party_account_currency = get_party_account_currency(party_type, party, self.company)
|
||||
|
||||
posting_date = self.get("bill_date") or self.get("posting_date") or self.get("transaction_date")
|
||||
date = self.get("due_date")
|
||||
due_date = date or posting_date
|
||||
grand_total = self.get("rounded_total") or self.grand_total
|
||||
|
||||
if party_account_currency == self.company_currency:
|
||||
grand_total = self.get("base_rounded_total") or self.base_grand_total
|
||||
else:
|
||||
grand_total = self.get("rounded_total") or self.grand_total
|
||||
|
||||
if self.doctype in ("Sales Invoice", "Purchase Invoice"):
|
||||
grand_total = grand_total - flt(self.write_off_amount)
|
||||
|
||||
@ -850,13 +866,25 @@ class AccountsController(TransactionBase):
|
||||
def validate_payment_schedule_amount(self):
|
||||
if self.doctype == 'Sales Invoice' and self.is_pos: return
|
||||
|
||||
party_account_currency = self.get('party_account_currency')
|
||||
if not party_account_currency:
|
||||
party_type, party = self.get_party()
|
||||
|
||||
if party_type and party:
|
||||
party_account_currency = get_party_account_currency(party_type, party, self.company)
|
||||
|
||||
if self.get("payment_schedule"):
|
||||
total = 0
|
||||
for d in self.get("payment_schedule"):
|
||||
total += flt(d.payment_amount)
|
||||
total = flt(total, self.precision("grand_total"))
|
||||
|
||||
grand_total = flt(self.get("rounded_total") or self.grand_total, self.precision('grand_total'))
|
||||
if party_account_currency == self.company_currency:
|
||||
total = flt(total, self.precision("base_grand_total"))
|
||||
grand_total = flt(self.get("base_rounded_total") or self.base_grand_total, self.precision('base_grand_total'))
|
||||
else:
|
||||
total = flt(total, self.precision("grand_total"))
|
||||
grand_total = flt(self.get("rounded_total") or self.grand_total, self.precision('grand_total'))
|
||||
|
||||
if self.get("total_advance"):
|
||||
grand_total -= self.get("total_advance")
|
||||
|
||||
|
@ -16,6 +16,7 @@
|
||||
"opportunity_from",
|
||||
"party_name",
|
||||
"customer_name",
|
||||
"source",
|
||||
"column_break0",
|
||||
"title",
|
||||
"opportunity_type",
|
||||
@ -49,10 +50,9 @@
|
||||
"contact_email",
|
||||
"contact_mobile",
|
||||
"more_info",
|
||||
"source",
|
||||
"company",
|
||||
"campaign",
|
||||
"column_break1",
|
||||
"company",
|
||||
"transaction_date",
|
||||
"amended_from",
|
||||
"lost_reasons"
|
||||
@ -344,7 +344,7 @@
|
||||
"collapsible": 1,
|
||||
"fieldname": "more_info",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "Source",
|
||||
"label": "More Information",
|
||||
"oldfieldtype": "Section Break",
|
||||
"options": "fa fa-file-text"
|
||||
},
|
||||
@ -424,7 +424,7 @@
|
||||
"icon": "fa fa-info-sign",
|
||||
"idx": 195,
|
||||
"links": [],
|
||||
"modified": "2020-07-14 16:49:15.888503",
|
||||
"modified": "2020-08-11 17:34:35.066961",
|
||||
"modified_by": "Administrator",
|
||||
"module": "CRM",
|
||||
"name": "Opportunity",
|
||||
|
@ -119,11 +119,19 @@ class Opportunity(TransactionBase):
|
||||
and q.status not in ('Lost', 'Closed')""", self.name)
|
||||
|
||||
def has_ordered_quotation(self):
|
||||
return frappe.db.sql("""
|
||||
select q.name
|
||||
from `tabQuotation` q, `tabQuotation Item` qi
|
||||
where q.name = qi.parent and q.docstatus=1 and qi.prevdoc_docname =%s
|
||||
and q.status = 'Ordered'""", self.name)
|
||||
if not self.with_items:
|
||||
return frappe.get_all('Quotation',
|
||||
{
|
||||
'opportunity': self.name,
|
||||
'status': 'Ordered',
|
||||
'docstatus': 1
|
||||
}, 'name')
|
||||
else:
|
||||
return frappe.db.sql("""
|
||||
select q.name
|
||||
from `tabQuotation` q, `tabQuotation Item` qi
|
||||
where q.name = qi.parent and q.docstatus=1 and qi.prevdoc_docname =%s
|
||||
and q.status = 'Ordered'""", self.name)
|
||||
|
||||
def has_lost_quotation(self):
|
||||
lost_quotation = frappe.db.sql("""
|
||||
|
@ -322,7 +322,8 @@ scheduler_events = {
|
||||
"erpnext.crm.doctype.email_campaign.email_campaign.set_email_campaign_status",
|
||||
"erpnext.selling.doctype.quotation.quotation.set_expired_status",
|
||||
"erpnext.healthcare.doctype.patient_appointment.patient_appointment.update_appointment_status",
|
||||
"erpnext.buying.doctype.supplier_quotation.supplier_quotation.set_expired_status"
|
||||
"erpnext.buying.doctype.supplier_quotation.supplier_quotation.set_expired_status",
|
||||
"erpnext.accounts.doctype.process_statement_of_accounts.process_statement_of_accounts.send_auto_email"
|
||||
],
|
||||
"daily_long": [
|
||||
"erpnext.setup.doctype.email_digest.email_digest.send",
|
||||
|
@ -78,7 +78,7 @@
|
||||
"idx": 0,
|
||||
"is_standard": 1,
|
||||
"label": "HR",
|
||||
"modified": "2020-06-16 19:20:50.976045",
|
||||
"modified": "2020-08-11 17:04:38.655417",
|
||||
"modified_by": "Administrator",
|
||||
"module": "HR",
|
||||
"name": "HR",
|
||||
@ -88,7 +88,7 @@
|
||||
"pin_to_top": 0,
|
||||
"shortcuts": [
|
||||
{
|
||||
"color": "#9deca2",
|
||||
"color": "#cef6d1",
|
||||
"format": "{} Active",
|
||||
"label": "Employee",
|
||||
"link_to": "Employee",
|
||||
@ -96,18 +96,19 @@
|
||||
"type": "DocType"
|
||||
},
|
||||
{
|
||||
"label": "Attendance",
|
||||
"link_to": "Attendance",
|
||||
"stats_filter": "",
|
||||
"type": "DocType"
|
||||
},
|
||||
{
|
||||
"color": "#ffe8cd",
|
||||
"format": "{} Open",
|
||||
"label": "Leave Application",
|
||||
"link_to": "Leave Application",
|
||||
"stats_filter": "{\"status\":\"Open\"}",
|
||||
"type": "DocType"
|
||||
},
|
||||
{
|
||||
"label": "Attendance",
|
||||
"link_to": "Attendance",
|
||||
"stats_filter": "",
|
||||
"type": "DocType"
|
||||
},
|
||||
{
|
||||
"label": "Job Applicant",
|
||||
"link_to": "Job Applicant",
|
||||
|
@ -8,7 +8,7 @@
|
||||
{
|
||||
"hidden": 0,
|
||||
"label": "Taxation",
|
||||
"links": "[\n {\n \"label\": \"Payroll Period\",\n \"name\": \"Payroll Period\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n \n },\n {\n \"label\": \"Income Tax Slab\",\n \"name\": \"Income Tax Slab\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n \n },\n {\n \"label\": \"Employee Tax Exemption Declaration\",\n \"name\": \"Employee Tax Exemption Declaration\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n \n },\n {\n \"label\": \"Employee Tax Exemption Proof Submission\",\n \"name\": \"Employee Tax Exemption Proof Submission\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n \n },\n {\n \"label\": \"Employee Tax Exemption Category\",\n \"name\": \"Employee Tax Exemption Category\",\n \"type\": \"doctype\"\n \n },\n {\n \"label\": \"Employee Tax Exemption Sub Category\",\n \"name\": \"Employee Tax Exemption Sub Category\",\n \"type\": \"doctype\"\n \n }\n]"
|
||||
"links": "[\n {\n \"label\": \"Payroll Period\",\n \"name\": \"Payroll Period\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n \n },\n {\n \"label\": \"Income Tax Slab\",\n \"name\": \"Income Tax Slab\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n \n },\n {\n \"label\": \"Employee Other Income\",\n \"name\": \"Employee Other Income\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n \n },\n {\n \"label\": \"Employee Tax Exemption Declaration\",\n \"name\": \"Employee Tax Exemption Declaration\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n \n },\n {\n \"label\": \"Employee Tax Exemption Proof Submission\",\n \"name\": \"Employee Tax Exemption Proof Submission\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n \n },\n {\n \"label\": \"Employee Tax Exemption Category\",\n \"name\": \"Employee Tax Exemption Category\",\n \"type\": \"doctype\"\n \n },\n {\n \"label\": \"Employee Tax Exemption Sub Category\",\n \"name\": \"Employee Tax Exemption Sub Category\",\n \"type\": \"doctype\"\n \n }\n]"
|
||||
},
|
||||
{
|
||||
"hidden": 0,
|
||||
@ -38,7 +38,7 @@
|
||||
"idx": 0,
|
||||
"is_standard": 1,
|
||||
"label": "Payroll",
|
||||
"modified": "2020-06-19 12:23:06.034046",
|
||||
"modified": "2020-08-10 19:38:45.976209",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Payroll",
|
||||
"name": "Payroll",
|
||||
|
@ -297,6 +297,10 @@
|
||||
margin-top: 30px;
|
||||
}
|
||||
|
||||
.item-group-slideshow {
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
.product-image-img {
|
||||
border: 1px solid @light-border-color;
|
||||
border-radius: 3px;
|
||||
|
@ -242,7 +242,7 @@
|
||||
{
|
||||
"fieldname": "default_warehouse_for_sales_return",
|
||||
"fieldtype": "Link",
|
||||
"label": "Default warehouse for Sales Return",
|
||||
"label": "Default Warehouse for Sales Return",
|
||||
"options": "Warehouse"
|
||||
},
|
||||
{
|
||||
@ -801,4 +801,4 @@
|
||||
"sort_field": "modified",
|
||||
"sort_order": "ASC",
|
||||
"track_changes": 1
|
||||
}
|
||||
}
|
||||
|
@ -175,7 +175,7 @@
|
||||
"no_copy": 1,
|
||||
"oldfieldname": "naming_series",
|
||||
"oldfieldtype": "Select",
|
||||
"options": "MAT-DN-.YYYY.-",
|
||||
"options": "MAT-DN-.YYYY.-\nMAT-DN-RET-.YYYY.-",
|
||||
"print_hide": 1,
|
||||
"reqd": 1,
|
||||
"set_only_once": 1
|
||||
@ -1255,7 +1255,7 @@
|
||||
"idx": 146,
|
||||
"is_submittable": 1,
|
||||
"links": [],
|
||||
"modified": "2020-07-18 05:13:55.580420",
|
||||
"modified": "2020-08-03 23:18:47.739997",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Stock",
|
||||
"name": "Delivery Note",
|
||||
|
@ -1,7 +1,6 @@
|
||||
{
|
||||
"actions": [],
|
||||
"allow_import": 1,
|
||||
"allow_workflow": 1,
|
||||
"autoname": "naming_series:",
|
||||
"creation": "2013-05-21 16:16:39",
|
||||
"doctype": "DocType",
|
||||
@ -160,7 +159,7 @@
|
||||
"no_copy": 1,
|
||||
"oldfieldname": "naming_series",
|
||||
"oldfieldtype": "Select",
|
||||
"options": "MAT-PRE-.YYYY.-",
|
||||
"options": "MAT-PRE-.YYYY.-\nMAT-PR-RET-.YYYY.-",
|
||||
"print_hide": 1,
|
||||
"reqd": 1,
|
||||
"set_only_once": 1
|
||||
@ -1110,7 +1109,7 @@
|
||||
"idx": 261,
|
||||
"is_submittable": 1,
|
||||
"links": [],
|
||||
"modified": "2020-07-18 05:19:12.148115",
|
||||
"modified": "2020-08-03 23:20:26.381024",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Stock",
|
||||
"name": "Purchase Receipt",
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
{% block page_content %}
|
||||
<div class="item-group-content" itemscope itemtype="http://schema.org/Product">
|
||||
<div>
|
||||
<div class="item-group-slideshow">
|
||||
{% if slideshow %}<!-- slideshow -->
|
||||
{% include "templates/includes/slideshow.html" %}
|
||||
{% endif %}
|
||||
|
Loading…
x
Reference in New Issue
Block a user