Merge branch 'develop' into gst-category
This commit is contained in:
commit
f9e7dc3f62
@ -81,7 +81,7 @@ def add_suffix_if_duplicate(account_name, account_number, accounts):
|
|||||||
def identify_is_group(child):
|
def identify_is_group(child):
|
||||||
if child.get("is_group"):
|
if child.get("is_group"):
|
||||||
is_group = child.get("is_group")
|
is_group = child.get("is_group")
|
||||||
elif len(set(child.keys()) - set(["account_type", "root_type", "is_group", "tax_rate", "account_number"])):
|
elif len(set(child.keys()) - set(["account_name", "account_type", "root_type", "is_group", "tax_rate", "account_number"])):
|
||||||
is_group = 1
|
is_group = 1
|
||||||
else:
|
else:
|
||||||
is_group = 0
|
is_group = 0
|
||||||
|
@ -4,9 +4,14 @@
|
|||||||
frappe.provide("erpnext.accounts");
|
frappe.provide("erpnext.accounts");
|
||||||
erpnext.accounts.PaymentReconciliationController = class PaymentReconciliationController extends frappe.ui.form.Controller {
|
erpnext.accounts.PaymentReconciliationController = class PaymentReconciliationController extends frappe.ui.form.Controller {
|
||||||
onload() {
|
onload() {
|
||||||
var me = this;
|
const default_company = frappe.defaults.get_default('company');
|
||||||
|
this.frm.set_value('company', default_company);
|
||||||
|
|
||||||
this.frm.set_query("party_type", function() {
|
this.frm.set_value('party_type', '');
|
||||||
|
this.frm.set_value('party', '');
|
||||||
|
this.frm.set_value('receivable_payable_account', '');
|
||||||
|
|
||||||
|
this.frm.set_query("party_type", () => {
|
||||||
return {
|
return {
|
||||||
"filters": {
|
"filters": {
|
||||||
"name": ["in", Object.keys(frappe.boot.party_account_types)],
|
"name": ["in", Object.keys(frappe.boot.party_account_types)],
|
||||||
@ -14,44 +19,30 @@ erpnext.accounts.PaymentReconciliationController = class PaymentReconciliationCo
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
this.frm.set_query('receivable_payable_account', function() {
|
this.frm.set_query('receivable_payable_account', () => {
|
||||||
check_mandatory(me.frm);
|
|
||||||
return {
|
return {
|
||||||
filters: {
|
filters: {
|
||||||
"company": me.frm.doc.company,
|
"company": this.frm.doc.company,
|
||||||
"is_group": 0,
|
"is_group": 0,
|
||||||
"account_type": frappe.boot.party_account_types[me.frm.doc.party_type]
|
"account_type": frappe.boot.party_account_types[this.frm.doc.party_type]
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
this.frm.set_query('bank_cash_account', function() {
|
this.frm.set_query('bank_cash_account', () => {
|
||||||
check_mandatory(me.frm, true);
|
|
||||||
return {
|
return {
|
||||||
filters:[
|
filters:[
|
||||||
['Account', 'company', '=', me.frm.doc.company],
|
['Account', 'company', '=', this.frm.doc.company],
|
||||||
['Account', 'is_group', '=', 0],
|
['Account', 'is_group', '=', 0],
|
||||||
['Account', 'account_type', 'in', ['Bank', 'Cash']]
|
['Account', 'account_type', 'in', ['Bank', 'Cash']]
|
||||||
]
|
]
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
this.frm.set_value('party_type', '');
|
|
||||||
this.frm.set_value('party', '');
|
|
||||||
this.frm.set_value('receivable_payable_account', '');
|
|
||||||
|
|
||||||
var check_mandatory = (frm, only_company=false) => {
|
|
||||||
var title = __("Mandatory");
|
|
||||||
if (only_company && !frm.doc.company) {
|
|
||||||
frappe.throw({message: __("Please Select a Company First"), title: title});
|
|
||||||
} else if (!frm.doc.company || !frm.doc.party_type) {
|
|
||||||
frappe.throw({message: __("Please Select Both Company and Party Type First"), title: title});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
refresh() {
|
refresh() {
|
||||||
this.frm.disable_save();
|
this.frm.disable_save();
|
||||||
|
|
||||||
this.frm.set_df_property('invoices', 'cannot_delete_rows', true);
|
this.frm.set_df_property('invoices', 'cannot_delete_rows', true);
|
||||||
this.frm.set_df_property('payments', 'cannot_delete_rows', true);
|
this.frm.set_df_property('payments', 'cannot_delete_rows', true);
|
||||||
this.frm.set_df_property('allocation', 'cannot_delete_rows', true);
|
this.frm.set_df_property('allocation', 'cannot_delete_rows', true);
|
||||||
@ -85,76 +76,92 @@ erpnext.accounts.PaymentReconciliationController = class PaymentReconciliationCo
|
|||||||
}
|
}
|
||||||
|
|
||||||
company() {
|
company() {
|
||||||
var me = this;
|
this.frm.set_value('party', '');
|
||||||
this.frm.set_value('receivable_payable_account', '');
|
this.frm.set_value('receivable_payable_account', '');
|
||||||
me.frm.clear_table("allocation");
|
}
|
||||||
me.frm.clear_table("invoices");
|
|
||||||
me.frm.clear_table("payments");
|
party_type() {
|
||||||
me.frm.refresh_fields();
|
this.frm.set_value('party', '');
|
||||||
me.frm.trigger('party');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
party() {
|
party() {
|
||||||
var me = this;
|
this.frm.set_value('receivable_payable_account', '');
|
||||||
if (!me.frm.doc.receivable_payable_account && me.frm.doc.party_type && me.frm.doc.party) {
|
this.frm.trigger("clear_child_tables");
|
||||||
|
|
||||||
|
if (!this.frm.doc.receivable_payable_account && this.frm.doc.party_type && this.frm.doc.party) {
|
||||||
return frappe.call({
|
return frappe.call({
|
||||||
method: "erpnext.accounts.party.get_party_account",
|
method: "erpnext.accounts.party.get_party_account",
|
||||||
args: {
|
args: {
|
||||||
company: me.frm.doc.company,
|
company: this.frm.doc.company,
|
||||||
party_type: me.frm.doc.party_type,
|
party_type: this.frm.doc.party_type,
|
||||||
party: me.frm.doc.party
|
party: this.frm.doc.party
|
||||||
},
|
},
|
||||||
callback: function(r) {
|
callback: (r) => {
|
||||||
if (!r.exc && r.message) {
|
if (!r.exc && r.message) {
|
||||||
me.frm.set_value("receivable_payable_account", r.message);
|
this.frm.set_value("receivable_payable_account", r.message);
|
||||||
}
|
}
|
||||||
me.frm.refresh();
|
this.frm.refresh();
|
||||||
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
get_unreconciled_entries() {
|
receivable_payable_account() {
|
||||||
var me = this;
|
this.frm.trigger("clear_child_tables");
|
||||||
return this.frm.call({
|
this.frm.refresh();
|
||||||
doc: me.frm.doc,
|
|
||||||
method: 'get_unreconciled_entries',
|
|
||||||
callback: function(r, rt) {
|
|
||||||
if (!(me.frm.doc.payments.length || me.frm.doc.invoices.length)) {
|
|
||||||
frappe.throw({message: __("No invoice and payment records found for this party")});
|
|
||||||
}
|
}
|
||||||
me.frm.refresh();
|
|
||||||
|
clear_child_tables() {
|
||||||
|
this.frm.clear_table("invoices");
|
||||||
|
this.frm.clear_table("payments");
|
||||||
|
this.frm.clear_table("allocation");
|
||||||
|
this.frm.refresh_fields();
|
||||||
|
}
|
||||||
|
|
||||||
|
get_unreconciled_entries() {
|
||||||
|
this.frm.clear_table("allocation");
|
||||||
|
return this.frm.call({
|
||||||
|
doc: this.frm.doc,
|
||||||
|
method: 'get_unreconciled_entries',
|
||||||
|
callback: () => {
|
||||||
|
if (!(this.frm.doc.payments.length || this.frm.doc.invoices.length)) {
|
||||||
|
frappe.throw({message: __("No Unreconciled Invoices and Payments found for this party and account")});
|
||||||
|
} else if (!(this.frm.doc.invoices.length)) {
|
||||||
|
frappe.throw({message: __("No Outstanding Invoices found for this party")});
|
||||||
|
} else if (!(this.frm.doc.payments.length)) {
|
||||||
|
frappe.throw({message: __("No Unreconciled Payments found for this party")});
|
||||||
|
}
|
||||||
|
this.frm.refresh();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
allocate() {
|
allocate() {
|
||||||
var me = this;
|
let payments = this.frm.fields_dict.payments.grid.get_selected_children();
|
||||||
let payments = me.frm.fields_dict.payments.grid.get_selected_children();
|
|
||||||
if (!(payments.length)) {
|
if (!(payments.length)) {
|
||||||
payments = me.frm.doc.payments;
|
payments = this.frm.doc.payments;
|
||||||
}
|
}
|
||||||
let invoices = me.frm.fields_dict.invoices.grid.get_selected_children();
|
let invoices = this.frm.fields_dict.invoices.grid.get_selected_children();
|
||||||
if (!(invoices.length)) {
|
if (!(invoices.length)) {
|
||||||
invoices = me.frm.doc.invoices;
|
invoices = this.frm.doc.invoices;
|
||||||
}
|
}
|
||||||
return me.frm.call({
|
return this.frm.call({
|
||||||
doc: me.frm.doc,
|
doc: this.frm.doc,
|
||||||
method: 'allocate_entries',
|
method: 'allocate_entries',
|
||||||
args: {
|
args: {
|
||||||
payments: payments,
|
payments: payments,
|
||||||
invoices: invoices
|
invoices: invoices
|
||||||
},
|
},
|
||||||
callback: function() {
|
callback: () => {
|
||||||
me.frm.refresh();
|
this.frm.refresh();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
reconcile() {
|
reconcile() {
|
||||||
var me = this;
|
var show_dialog = this.frm.doc.allocation.filter(d => d.difference_amount && !d.difference_account);
|
||||||
var show_dialog = me.frm.doc.allocation.filter(d => d.difference_amount && !d.difference_account);
|
|
||||||
|
|
||||||
if (show_dialog && show_dialog.length) {
|
if (show_dialog && show_dialog.length) {
|
||||||
|
|
||||||
@ -186,10 +193,10 @@ erpnext.accounts.PaymentReconciliationController = class PaymentReconciliationCo
|
|||||||
label: __("Difference Account"),
|
label: __("Difference Account"),
|
||||||
fieldname: 'difference_account',
|
fieldname: 'difference_account',
|
||||||
reqd: 1,
|
reqd: 1,
|
||||||
get_query: function() {
|
get_query: () => {
|
||||||
return {
|
return {
|
||||||
filters: {
|
filters: {
|
||||||
company: me.frm.doc.company,
|
company: this.frm.doc.company,
|
||||||
is_group: 0
|
is_group: 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -203,7 +210,7 @@ erpnext.accounts.PaymentReconciliationController = class PaymentReconciliationCo
|
|||||||
}]
|
}]
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
primary_action: function() {
|
primary_action: () => {
|
||||||
const args = dialog.get_values()["allocation"];
|
const args = dialog.get_values()["allocation"];
|
||||||
|
|
||||||
args.forEach(d => {
|
args.forEach(d => {
|
||||||
@ -211,7 +218,7 @@ erpnext.accounts.PaymentReconciliationController = class PaymentReconciliationCo
|
|||||||
"difference_account", d.difference_account);
|
"difference_account", d.difference_account);
|
||||||
});
|
});
|
||||||
|
|
||||||
me.reconcile_payment_entries();
|
this.reconcile_payment_entries();
|
||||||
dialog.hide();
|
dialog.hide();
|
||||||
},
|
},
|
||||||
primary_action_label: __('Reconcile Entries')
|
primary_action_label: __('Reconcile Entries')
|
||||||
@ -237,15 +244,12 @@ erpnext.accounts.PaymentReconciliationController = class PaymentReconciliationCo
|
|||||||
}
|
}
|
||||||
|
|
||||||
reconcile_payment_entries() {
|
reconcile_payment_entries() {
|
||||||
var me = this;
|
|
||||||
|
|
||||||
return this.frm.call({
|
return this.frm.call({
|
||||||
doc: me.frm.doc,
|
doc: this.frm.doc,
|
||||||
method: 'reconcile',
|
method: 'reconcile',
|
||||||
callback: function(r, rt) {
|
callback: () => {
|
||||||
me.frm.clear_table("allocation");
|
this.frm.clear_table("allocation");
|
||||||
me.frm.refresh_fields();
|
this.frm.refresh();
|
||||||
me.frm.refresh();
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -114,6 +114,8 @@ class POSInvoiceMergeLog(Document):
|
|||||||
def merge_pos_invoice_into(self, invoice, data):
|
def merge_pos_invoice_into(self, invoice, data):
|
||||||
items, payments, taxes = [], [], []
|
items, payments, taxes = [], [], []
|
||||||
loyalty_amount_sum, loyalty_points_sum = 0, 0
|
loyalty_amount_sum, loyalty_points_sum = 0, 0
|
||||||
|
rounding_adjustment, base_rounding_adjustment = 0, 0
|
||||||
|
rounded_total, base_rounded_total = 0, 0
|
||||||
for doc in data:
|
for doc in data:
|
||||||
map_doc(doc, invoice, table_map={ "doctype": invoice.doctype })
|
map_doc(doc, invoice, table_map={ "doctype": invoice.doctype })
|
||||||
|
|
||||||
@ -162,6 +164,11 @@ class POSInvoiceMergeLog(Document):
|
|||||||
found = True
|
found = True
|
||||||
if not found:
|
if not found:
|
||||||
payments.append(payment)
|
payments.append(payment)
|
||||||
|
rounding_adjustment += doc.rounding_adjustment
|
||||||
|
rounded_total += doc.rounded_total
|
||||||
|
base_rounding_adjustment += doc.rounding_adjustment
|
||||||
|
base_rounded_total += doc.rounded_total
|
||||||
|
|
||||||
|
|
||||||
if loyalty_points_sum:
|
if loyalty_points_sum:
|
||||||
invoice.redeem_loyalty_points = 1
|
invoice.redeem_loyalty_points = 1
|
||||||
@ -171,6 +178,10 @@ class POSInvoiceMergeLog(Document):
|
|||||||
invoice.set('items', items)
|
invoice.set('items', items)
|
||||||
invoice.set('payments', payments)
|
invoice.set('payments', payments)
|
||||||
invoice.set('taxes', taxes)
|
invoice.set('taxes', taxes)
|
||||||
|
invoice.set('rounding_adjustment',rounding_adjustment)
|
||||||
|
invoice.set('rounding_adjustment',base_rounding_adjustment)
|
||||||
|
invoice.set('base_rounded_total',base_rounded_total)
|
||||||
|
invoice.set('rounded_total',rounded_total)
|
||||||
invoice.additional_discount_percentage = 0
|
invoice.additional_discount_percentage = 0
|
||||||
invoice.discount_amount = 0.0
|
invoice.discount_amount = 0.0
|
||||||
invoice.taxes_and_charges = None
|
invoice.taxes_and_charges = None
|
||||||
|
@ -450,7 +450,8 @@ def update_reference_in_journal_entry(d, journal_entry, do_not_save=False):
|
|||||||
|
|
||||||
# new row with references
|
# new row with references
|
||||||
new_row = journal_entry.append("accounts")
|
new_row = journal_entry.append("accounts")
|
||||||
new_row.update(jv_detail.as_dict().copy())
|
|
||||||
|
new_row.update((frappe.copy_doc(jv_detail)).as_dict())
|
||||||
|
|
||||||
new_row.set(d["dr_or_cr"], d["allocated_amount"])
|
new_row.set(d["dr_or_cr"], d["allocated_amount"])
|
||||||
new_row.set('debit' if d['dr_or_cr'] == 'debit_in_account_currency' else 'credit',
|
new_row.set('debit' if d['dr_or_cr'] == 'debit_in_account_currency' else 'credit',
|
||||||
|
@ -16,9 +16,8 @@ frappe.query_reports["Fixed Asset Register"] = {
|
|||||||
fieldname:"status",
|
fieldname:"status",
|
||||||
label: __("Status"),
|
label: __("Status"),
|
||||||
fieldtype: "Select",
|
fieldtype: "Select",
|
||||||
options: "In Location\nDisposed",
|
options: "\nIn Location\nDisposed",
|
||||||
default: 'In Location',
|
default: 'In Location'
|
||||||
reqd: 1
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname":"filter_based_on",
|
"fieldname":"filter_based_on",
|
||||||
|
@ -45,6 +45,7 @@ def get_conditions(filters):
|
|||||||
if filters.get('cost_center'):
|
if filters.get('cost_center'):
|
||||||
conditions["cost_center"] = filters.get('cost_center')
|
conditions["cost_center"] = filters.get('cost_center')
|
||||||
|
|
||||||
|
if status:
|
||||||
# In Store assets are those that are not sold or scrapped
|
# In Store assets are those that are not sold or scrapped
|
||||||
operand = 'not in'
|
operand = 'not in'
|
||||||
if status not in 'In Location':
|
if status not in 'In Location':
|
||||||
|
@ -566,7 +566,7 @@ def get_filtered_dimensions(doctype, txt, searchfield, start, page_len, filters)
|
|||||||
|
|
||||||
query_filters.append(['name', query_selector, dimensions])
|
query_filters.append(['name', query_selector, dimensions])
|
||||||
|
|
||||||
output = frappe.get_all(doctype, filters=query_filters)
|
output = frappe.get_list(doctype, filters=query_filters)
|
||||||
result = [d.name for d in output]
|
result = [d.name for d in output]
|
||||||
|
|
||||||
return [(d,) for d in set(result)]
|
return [(d,) for d in set(result)]
|
||||||
|
@ -260,7 +260,9 @@ class calculate_taxes_and_totals(object):
|
|||||||
self.doc.round_floats_in(self.doc, ["total", "base_total", "net_total", "base_net_total"])
|
self.doc.round_floats_in(self.doc, ["total", "base_total", "net_total", "base_net_total"])
|
||||||
|
|
||||||
def calculate_taxes(self):
|
def calculate_taxes(self):
|
||||||
|
if not self.doc.get('is_consolidated'):
|
||||||
self.doc.rounding_adjustment = 0
|
self.doc.rounding_adjustment = 0
|
||||||
|
|
||||||
# maintain actual tax rate based on idx
|
# maintain actual tax rate based on idx
|
||||||
actual_tax_dict = dict([[tax.idx, flt(tax.tax_amount, tax.precision("tax_amount"))]
|
actual_tax_dict = dict([[tax.idx, flt(tax.tax_amount, tax.precision("tax_amount"))]
|
||||||
for tax in self.doc.get("taxes") if tax.charge_type == "Actual"])
|
for tax in self.doc.get("taxes") if tax.charge_type == "Actual"])
|
||||||
@ -312,7 +314,9 @@ class calculate_taxes_and_totals(object):
|
|||||||
|
|
||||||
# adjust Discount Amount loss in last tax iteration
|
# adjust Discount Amount loss in last tax iteration
|
||||||
if i == (len(self.doc.get("taxes")) - 1) and self.discount_amount_applied \
|
if i == (len(self.doc.get("taxes")) - 1) and self.discount_amount_applied \
|
||||||
and self.doc.discount_amount and self.doc.apply_discount_on == "Grand Total":
|
and self.doc.discount_amount \
|
||||||
|
and self.doc.apply_discount_on == "Grand Total" \
|
||||||
|
and not self.doc.get('is_consolidated'):
|
||||||
self.doc.rounding_adjustment = flt(self.doc.grand_total
|
self.doc.rounding_adjustment = flt(self.doc.grand_total
|
||||||
- flt(self.doc.discount_amount) - tax.total,
|
- flt(self.doc.discount_amount) - tax.total,
|
||||||
self.doc.precision("rounding_adjustment"))
|
self.doc.precision("rounding_adjustment"))
|
||||||
@ -405,11 +409,16 @@ class calculate_taxes_and_totals(object):
|
|||||||
self.doc.rounding_adjustment = diff
|
self.doc.rounding_adjustment = diff
|
||||||
|
|
||||||
def calculate_totals(self):
|
def calculate_totals(self):
|
||||||
self.doc.grand_total = flt(self.doc.get("taxes")[-1].total) + flt(self.doc.rounding_adjustment) \
|
if self.doc.get("taxes"):
|
||||||
if self.doc.get("taxes") else flt(self.doc.net_total)
|
self.doc.grand_total = flt(self.doc.get("taxes")[-1].total) + flt(self.doc.rounding_adjustment)
|
||||||
|
else:
|
||||||
|
self.doc.grand_total = flt(self.doc.net_total)
|
||||||
|
|
||||||
|
if self.doc.get("taxes"):
|
||||||
self.doc.total_taxes_and_charges = flt(self.doc.grand_total - self.doc.net_total
|
self.doc.total_taxes_and_charges = flt(self.doc.grand_total - self.doc.net_total
|
||||||
- flt(self.doc.rounding_adjustment), self.doc.precision("total_taxes_and_charges"))
|
- flt(self.doc.rounding_adjustment), self.doc.precision("total_taxes_and_charges"))
|
||||||
|
else:
|
||||||
|
self.doc.total_taxes_and_charges = 0.0
|
||||||
|
|
||||||
self._set_in_company_currency(self.doc, ["total_taxes_and_charges", "rounding_adjustment"])
|
self._set_in_company_currency(self.doc, ["total_taxes_and_charges", "rounding_adjustment"])
|
||||||
|
|
||||||
@ -446,6 +455,7 @@ class calculate_taxes_and_totals(object):
|
|||||||
self.doc.total_net_weight += d.total_weight
|
self.doc.total_net_weight += d.total_weight
|
||||||
|
|
||||||
def set_rounded_total(self):
|
def set_rounded_total(self):
|
||||||
|
if not self.doc.get('is_consolidated'):
|
||||||
if self.doc.meta.get_field("rounded_total"):
|
if self.doc.meta.get_field("rounded_total"):
|
||||||
if self.doc.is_rounded_total_disabled():
|
if self.doc.is_rounded_total_disabled():
|
||||||
self.doc.rounded_total = self.doc.base_rounded_total = 0
|
self.doc.rounded_total = self.doc.base_rounded_total = 0
|
||||||
|
@ -307,6 +307,9 @@ class BOM(WebsiteGenerator):
|
|||||||
existing_bom_cost = self.total_cost
|
existing_bom_cost = self.total_cost
|
||||||
|
|
||||||
for d in self.get("items"):
|
for d in self.get("items"):
|
||||||
|
if not d.item_code:
|
||||||
|
continue
|
||||||
|
|
||||||
rate = self.get_rm_rate({
|
rate = self.get_rm_rate({
|
||||||
"company": self.company,
|
"company": self.company,
|
||||||
"item_code": d.item_code,
|
"item_code": d.item_code,
|
||||||
@ -599,7 +602,7 @@ class BOM(WebsiteGenerator):
|
|||||||
for d in self.get('items'):
|
for d in self.get('items'):
|
||||||
if d.bom_no:
|
if d.bom_no:
|
||||||
self.get_child_exploded_items(d.bom_no, d.stock_qty)
|
self.get_child_exploded_items(d.bom_no, d.stock_qty)
|
||||||
else:
|
elif d.item_code:
|
||||||
self.add_to_cur_exploded_items(frappe._dict({
|
self.add_to_cur_exploded_items(frappe._dict({
|
||||||
'item_code' : d.item_code,
|
'item_code' : d.item_code,
|
||||||
'item_name' : d.item_name,
|
'item_name' : d.item_name,
|
||||||
|
@ -122,7 +122,7 @@ def get_total_emiratewise(filters):
|
|||||||
try:
|
try:
|
||||||
return frappe.db.sql("""
|
return frappe.db.sql("""
|
||||||
select
|
select
|
||||||
s.vat_emirate as emirate, sum(i.base_amount) as total, sum(s.total_taxes_and_charges)
|
s.vat_emirate as emirate, sum(i.base_amount) as total, sum(i.tax_amount)
|
||||||
from
|
from
|
||||||
`tabSales Invoice Item` i inner join `tabSales Invoice` s
|
`tabSales Invoice Item` i inner join `tabSales Invoice` s
|
||||||
on
|
on
|
||||||
|
@ -101,10 +101,6 @@ def get_stock_balance(item_code, warehouse, posting_date=None, posting_time=None
|
|||||||
|
|
||||||
if with_valuation_rate:
|
if with_valuation_rate:
|
||||||
if with_serial_no:
|
if with_serial_no:
|
||||||
serial_nos = last_entry.get("serial_no")
|
|
||||||
|
|
||||||
if (serial_nos and
|
|
||||||
len(get_serial_nos_data(serial_nos)) < last_entry.qty_after_transaction):
|
|
||||||
serial_nos = get_serial_nos_data_after_transactions(args)
|
serial_nos = get_serial_nos_data_after_transactions(args)
|
||||||
|
|
||||||
return ((last_entry.qty_after_transaction, last_entry.valuation_rate, serial_nos)
|
return ((last_entry.qty_after_transaction, last_entry.valuation_rate, serial_nos)
|
||||||
@ -115,19 +111,32 @@ def get_stock_balance(item_code, warehouse, posting_date=None, posting_time=None
|
|||||||
return last_entry.qty_after_transaction if last_entry else 0.0
|
return last_entry.qty_after_transaction if last_entry else 0.0
|
||||||
|
|
||||||
def get_serial_nos_data_after_transactions(args):
|
def get_serial_nos_data_after_transactions(args):
|
||||||
serial_nos = []
|
from pypika import CustomFunction
|
||||||
data = frappe.db.sql(""" SELECT serial_no, actual_qty
|
|
||||||
FROM `tabStock Ledger Entry`
|
|
||||||
WHERE
|
|
||||||
item_code = %(item_code)s and warehouse = %(warehouse)s
|
|
||||||
and timestamp(posting_date, posting_time) < timestamp(%(posting_date)s, %(posting_time)s)
|
|
||||||
order by posting_date, posting_time asc """, args, as_dict=1)
|
|
||||||
|
|
||||||
for d in data:
|
serial_nos = set()
|
||||||
if d.actual_qty > 0:
|
args = frappe._dict(args)
|
||||||
serial_nos.extend(get_serial_nos_data(d.serial_no))
|
sle = frappe.qb.DocType('Stock Ledger Entry')
|
||||||
|
Timestamp = CustomFunction('timestamp', ['date', 'time'])
|
||||||
|
|
||||||
|
stock_ledger_entries = frappe.qb.from_(
|
||||||
|
sle
|
||||||
|
).select(
|
||||||
|
'serial_no','actual_qty'
|
||||||
|
).where(
|
||||||
|
(sle.item_code == args.item_code)
|
||||||
|
& (sle.warehouse == args.warehouse)
|
||||||
|
& (Timestamp(sle.posting_date, sle.posting_time) < Timestamp(args.posting_date, args.posting_time))
|
||||||
|
& (sle.is_cancelled == 0)
|
||||||
|
).orderby(
|
||||||
|
sle.posting_date, sle.posting_time, sle.creation
|
||||||
|
).run(as_dict=1)
|
||||||
|
|
||||||
|
for stock_ledger_entry in stock_ledger_entries:
|
||||||
|
changed_serial_no = get_serial_nos_data(stock_ledger_entry.serial_no)
|
||||||
|
if stock_ledger_entry.actual_qty > 0:
|
||||||
|
serial_nos.update(changed_serial_no)
|
||||||
else:
|
else:
|
||||||
serial_nos = list(set(serial_nos) - set(get_serial_nos_data(d.serial_no)))
|
serial_nos.difference_update(changed_serial_no)
|
||||||
|
|
||||||
return '\n'.join(serial_nos)
|
return '\n'.join(serial_nos)
|
||||||
|
|
||||||
|
@ -12,12 +12,6 @@ from erpnext.erpnext_integrations.connectors.woocommerce_connection import order
|
|||||||
|
|
||||||
class TestWoocommerce(unittest.TestCase):
|
class TestWoocommerce(unittest.TestCase):
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
if not frappe.db.exists('Company', 'Woocommerce'):
|
|
||||||
company = frappe.new_doc("Company")
|
|
||||||
company.company_name = "Woocommerce"
|
|
||||||
company.abbr = "W"
|
|
||||||
company.default_currency = "INR"
|
|
||||||
company.save()
|
|
||||||
|
|
||||||
woo_settings = frappe.get_doc("Woocommerce Settings")
|
woo_settings = frappe.get_doc("Woocommerce Settings")
|
||||||
if not woo_settings.secret:
|
if not woo_settings.secret:
|
||||||
@ -26,14 +20,14 @@ class TestWoocommerce(unittest.TestCase):
|
|||||||
woo_settings.api_consumer_key = "ck_fd43ff5756a6abafd95fadb6677100ce95a758a1"
|
woo_settings.api_consumer_key = "ck_fd43ff5756a6abafd95fadb6677100ce95a758a1"
|
||||||
woo_settings.api_consumer_secret = "cs_94360a1ad7bef7fa420a40cf284f7b3e0788454e"
|
woo_settings.api_consumer_secret = "cs_94360a1ad7bef7fa420a40cf284f7b3e0788454e"
|
||||||
woo_settings.enable_sync = 1
|
woo_settings.enable_sync = 1
|
||||||
woo_settings.company = "Woocommerce"
|
woo_settings.company = "_Test Company"
|
||||||
woo_settings.tax_account = "Sales Expenses - W"
|
woo_settings.tax_account = "Sales Expenses - _TC"
|
||||||
woo_settings.f_n_f_account = "Expenses - W"
|
woo_settings.f_n_f_account = "Expenses - _TC"
|
||||||
woo_settings.creation_user = "Administrator"
|
woo_settings.creation_user = "Administrator"
|
||||||
woo_settings.save(ignore_permissions=True)
|
woo_settings.save(ignore_permissions=True)
|
||||||
|
|
||||||
def test_sales_order_for_woocommerce(self):
|
def test_sales_order_for_woocommerce(self):
|
||||||
frappe.flags.woocomm_test_order_data = {"id":75,"parent_id":0,"number":"74","order_key":"wc_order_5aa1281c2dacb","created_via":"checkout","version":"3.3.3","status":"processing","currency":"INR","date_created":"2018-03-08T12:10:04","date_created_gmt":"2018-03-08T12:10:04","date_modified":"2018-03-08T12:10:04","date_modified_gmt":"2018-03-08T12:10:04","discount_total":"0.00","discount_tax":"0.00","shipping_total":"150.00","shipping_tax":"0.00","cart_tax":"0.00","total":"649.00","total_tax":"0.00","prices_include_tax":False,"customer_id":12,"customer_ip_address":"103.54.99.5","customer_user_agent":"mozilla\\/5.0 (x11; linux x86_64) applewebkit\\/537.36 (khtml, like gecko) chrome\\/64.0.3282.186 safari\\/537.36","customer_note":"","billing":{"first_name":"Tony","last_name":"Stark","company":"Woocommerce","address_1":"Mumbai","address_2":"","city":"Dadar","state":"MH","postcode":"123","country":"IN","email":"tony@gmail.com","phone":"123457890"},"shipping":{"first_name":"Tony","last_name":"Stark","company":"","address_1":"Mumbai","address_2":"","city":"Dadar","state":"MH","postcode":"123","country":"IN"},"payment_method":"cod","payment_method_title":"Cash on delivery","transaction_id":"","date_paid":"","date_paid_gmt":"","date_completed":"","date_completed_gmt":"","cart_hash":"8e76b020d5790066496f244860c4703f","meta_data":[],"line_items":[{"id":80,"name":"Marvel","product_id":56,"variation_id":0,"quantity":1,"tax_class":"","subtotal":"499.00","subtotal_tax":"0.00","total":"499.00","total_tax":"0.00","taxes":[],"meta_data":[],"sku":"","price":499}],"tax_lines":[],"shipping_lines":[{"id":81,"method_title":"Flat rate","method_id":"flat_rate:1","total":"150.00","total_tax":"0.00","taxes":[],"meta_data":[{"id":623,"key":"Items","value":"Marvel × 1"}]}],"fee_lines":[],"coupon_lines":[],"refunds":[]}
|
frappe.flags.woocomm_test_order_data = {"id":75,"parent_id":0,"number":"74","order_key":"wc_order_5aa1281c2dacb","created_via":"checkout","version":"3.3.3","status":"processing","currency":"INR","date_created":"2018-03-08T12:10:04","date_created_gmt":"2018-03-08T12:10:04","date_modified":"2018-03-08T12:10:04","date_modified_gmt":"2018-03-08T12:10:04","discount_total":"0.00","discount_tax":"0.00","shipping_total":"150.00","shipping_tax":"0.00","cart_tax":"0.00","total":"649.00","total_tax":"0.00","prices_include_tax":False,"customer_id":12,"customer_ip_address":"103.54.99.5","customer_user_agent":"mozilla\\/5.0 (x11; linux x86_64) applewebkit\\/537.36 (khtml, like gecko) chrome\\/64.0.3282.186 safari\\/537.36","customer_note":"","billing":{"first_name":"Tony","last_name":"Stark","company":"_Test Company","address_1":"Mumbai","address_2":"","city":"Dadar","state":"MH","postcode":"123","country":"IN","email":"tony@gmail.com","phone":"123457890"},"shipping":{"first_name":"Tony","last_name":"Stark","company":"","address_1":"Mumbai","address_2":"","city":"Dadar","state":"MH","postcode":"123","country":"IN"},"payment_method":"cod","payment_method_title":"Cash on delivery","transaction_id":"","date_paid":"","date_paid_gmt":"","date_completed":"","date_completed_gmt":"","cart_hash":"8e76b020d5790066496f244860c4703f","meta_data":[],"line_items":[{"id":80,"name":"Marvel","product_id":56,"variation_id":0,"quantity":1,"tax_class":"","subtotal":"499.00","subtotal_tax":"0.00","total":"499.00","total_tax":"0.00","taxes":[],"meta_data":[],"sku":"","price":499}],"tax_lines":[],"shipping_lines":[{"id":81,"method_title":"Flat rate","method_id":"flat_rate:1","total":"150.00","total_tax":"0.00","taxes":[],"meta_data":[{"id":623,"key":"Items","value":"Marvel × 1"}]}],"fee_lines":[],"coupon_lines":[],"refunds":[]}
|
||||||
order()
|
order()
|
||||||
|
|
||||||
self.assertTrue(frappe.get_value("Customer",{"woocommerce_email":"tony@gmail.com"}))
|
self.assertTrue(frappe.get_value("Customer",{"woocommerce_email":"tony@gmail.com"}))
|
||||||
|
Loading…
x
Reference in New Issue
Block a user