def get_doc(start_idx): if doctypes: doc = {} for idx in xrange(start_idx, len(rows)): if (not doc) or main_doc_empty(rows[idx]): for dt in doctypes: d = {} for column_idx in column_idx_to_fieldname[dt]: try: fieldname = column_idx_to_fieldname[dt][ column_idx] fieldtype = column_idx_to_fieldtype[dt][ column_idx] d[fieldname] = rows[idx][column_idx] if fieldtype in ("Int", "Check"): d[fieldname] = cint(d[fieldname]) elif fieldtype in ("Float", "Currency", "Percent"): d[fieldname] = flt(d[fieldname]) elif fieldtype == "Date": d[fieldname] = getdate( parse_date(d[fieldname]) ) if d[fieldname] else None elif fieldtype == "Datetime": if d[fieldname]: _date, _time = d[fieldname].split() _date = parse_date(d[fieldname]) d[fieldname] = get_datetime(_date + " " + _time) else: d[fieldname] = None except IndexError: pass # scrub quotes from name and modified if d.get("name") and d["name"].startswith('"'): d["name"] = d["name"][1:-1] if sum([0 if not val else 1 for val in d.values()]): d['doctype'] = dt if dt == doctype: doc.update(d) else: if not overwrite: d['parent'] = doc["name"] d['parenttype'] = doctype d['parentfield'] = doctype_parentfield[dt] doc.setdefault(d['parentfield'], []).append(d) else: break return doc else: doc = frappe._dict(zip(columns, rows[start_idx][1:])) doc['doctype'] = doctype return doc
def addrecords(name, datarows, limit=65000): meta = frappe.get_meta(name) columns = 0 x = 0 j = 0 for row in datarows: if j >= limit: break if columns == 0: fields = row columns = len(fields) continue datadoc = {"doctype": name} i = 0 for cell in row: if i >= columns: break df = meta.get_field(fields[i]) fieldtype = df.fieldtype if df else "Data" if fieldtype in ("Int", "Check"): cell = cint(cell) elif fieldtype in ("Float", "Currency", "Percent"): cell = flt(cell) elif fieldtype == "Date": if cell and isinstance(cell, datetime): cell = str(cell) if cell and isinstance(cell, string_types): cell = getdate(parse_date(cell)) elif fieldtype == "Datetime": if cell: if " " in cell: _date, _time = cell.split() else: _date, _time = cell, '00:00:00' _date = parse_date(cell) cell = get_datetime(_date + " " + _time) else: cell = None elif fieldtype in ("Link", "Dynamic Link", "Data") and cell: cell = cstr(cell) datadoc.setdefault(fields[i], cell) i += 1 row_original = str(datadoc) xduplicates = frappe.get_list(name, filters={'row_original': row_original}, fields=['name']) j += 1 if len(xduplicates) > 0: x += 1 continue datadoc = conversionrules(datadoc) datadoc.setdefault("row_original", row_original) doc = frappe.get_doc(datadoc) doc.insert(ignore_permissions=True) return j - x
def get_doc(start_idx): if doctypes: doc = {} for idx in xrange(start_idx, len(rows)): if (not doc) or main_doc_empty(rows[idx]): for dt, parentfield in doctypes: d = {} for column_idx in column_idx_to_fieldname[(dt, parentfield)]: try: fieldname = column_idx_to_fieldname[(dt, parentfield)][column_idx] fieldtype = column_idx_to_fieldtype[(dt, parentfield)][column_idx] d[fieldname] = rows[idx][column_idx] if fieldtype in ("Int", "Check"): d[fieldname] = cint(d[fieldname]) elif fieldtype in ("Float", "Currency", "Percent"): d[fieldname] = flt(d[fieldname]) elif fieldtype == "Date": d[fieldname] = getdate(parse_date(d[fieldname])) if d[fieldname] else None elif fieldtype == "Datetime": if d[fieldname]: if " " in d[fieldname]: _date, _time = d[fieldname].split() else: _date, _time = d[fieldname], '00:00:00' _date = parse_date(d[fieldname]) d[fieldname] = get_datetime(_date + " " + _time) else: d[fieldname] = None except IndexError: pass # scrub quotes from name and modified if d.get("name") and d["name"].startswith('"'): d["name"] = d["name"][1:-1] if sum([0 if not val else 1 for val in d.values()]): d['doctype'] = dt if dt == doctype: doc.update(d) else: if not overwrite: d['parent'] = doc["name"] d['parenttype'] = doctype d['parentfield'] = parentfield doc.setdefault(d['parentfield'], []).append(d) else: break return doc else: doc = frappe._dict(zip(columns, rows[start_idx][1:])) doc['doctype'] = doctype return doc
def update_or_create_item_discount(site_name, doc_item, oc_discount, save=False, is_updating=False): disc_template = '{customer_group_id}-{quantity}-{priority}-{date_start}-{date_end}' oc_discount_copy = dict(oc_discount) oc_discount_copy.update({ 'date_start': parse_date(str(oc_discount.get('date_start'))) if oc_discount.get('date_start') else '', 'date_end': parse_date(str(oc_discount.get('date_end'))) if oc_discount.get('date_end') else '' }) oc_discount_hash = disc_template.format(**oc_discount_copy) # frappe.msgprint('items::update_or_create_item_discount') for doc_oc_discount in doc_item.get('oc_discounts'): if site_name != doc_oc_discount.get('oc_site'): continue doc_customer_group = frappe.get_doc('Customer Group', doc_oc_discount.get('customer_group')) if site_name != doc_customer_group.get('oc_site'): continue customer_group_id = doc_customer_group.get('oc_customer_group_id') if not customer_group_id: frappe.throw('customer_group_id is not set in Customer Group "%s"' % doc_oc_discount.get('customer_group')) doc_discount_hash = disc_template.format(**{ 'customer_group_id': customer_group_id, # 'price': doc_oc_discount.get('price'), 'priority': int(doc_oc_discount.get('priority', 0)), 'quantity': int(doc_oc_discount.get('quantity', 0)), 'date_start': parse_date(str(doc_oc_discount.get('date_start'))) if doc_oc_discount.get('date_start') else '', 'date_end': parse_date(str(doc_oc_discount.get('date_end'))) if doc_oc_discount.get('date_end') else '', }) if oc_discount_hash == doc_discount_hash: doc_oc_discount.update({'price': oc_discount.get('price')}) update_discount_prices(doc_oc_discount, oc_discount) doc_oc_discount.save() break else: doc_customer_group = customer_groups.get(site_name, oc_discount.get('customer_group_id')) if not doc_customer_group: frappe.throw('Cannot not found Customer Group with customer_group_id "%s" for Item "%s"' % (customer_group_id, doc_item.get('name'))) doc_oc_discount = frappe.get_doc({ 'doctype': 'Opencart Discount', 'oc_site': site_name, 'item_name': doc_item.get('name'), 'customer_group': doc_customer_group.get('name'), 'quantity': oc_discount.get('quantity'), 'priority': oc_discount.get('priority'), 'price': oc_discount.get('price'), 'date_start': oc_discount.get('date_start'), 'date_end': oc_discount.get('date_end'), }) update_discount_prices(doc_oc_discount, oc_discount) doc_item.append('oc_discounts', doc_oc_discount) if is_updating: doc_item.update({'oc_is_updating': 1}) if save: doc_item.save()
def reconcile_multiple_transactions_with_one_document(self): reconciled_amount = 0 for bank_transaction in self.bank_transactions: if abs(self.documents[0] ["unreconciled_amount"]) > reconciled_amount: bank_transaction = frappe.get_doc("Bank Transaction", bank_transaction.get("name")) allocated_amount = min( max(bank_transaction.unallocated_amount, 0), abs(self.documents[0]["unreconciled_amount"])) date_value = self.documents[0].get("reference_date") if isinstance(date_value, str): date_value = parse_date(date_value) if allocated_amount > 0: bank_transaction.append( 'payment_entries', { 'payment_document': self.reconciliation_doctype, 'payment_entry': self.documents[0]["name"], 'allocated_amount': allocated_amount, 'party': self.documents[0][PARTY_FIELD.get( self.reconciliation_doctype)], 'date': getdate(date_value) }) reconciled_amount += allocated_amount bank_transaction.save()
def check_record(d, parenttype=None, doctype_dl=None): """check for mandatory, select options, dates. these should ideally be in doclist""" from frappe.utils.dateutils import parse_date if parenttype and not d.get('parent'): frappe.msgprint(_("Parent is required."), raise_exception=1) if not doctype_dl: doctype_dl = frappe.model.doctype.get(d.doctype) for key in d: docfield = doctype_dl.get_field(key) val = d[key] if docfield: if docfield.reqd and (val=='' or val==None): frappe.msgprint("%s is mandatory." % docfield.label, raise_exception=1) if docfield.fieldtype=='Select' and val and docfield.options: if docfield.options.startswith('link:'): link_doctype = docfield.options.split(':')[1] if not frappe.db.exists(link_doctype, val): frappe.msgprint("%s: %s must be a valid %s" % (docfield.label, val, link_doctype), raise_exception=1) elif docfield.options == "attach_files:": pass elif val not in docfield.options.split('\n'): frappe.msgprint("%s must be one of: %s" % (docfield.label, ", ".join(filter(None, docfield.options.split("\n")))), raise_exception=1) if val and docfield.fieldtype=='Date': d[key] = parse_date(val) elif val and docfield.fieldtype in ["Int", "Check"]: d[key] = cint(val) elif val and docfield.fieldtype in ["Currency", "Float"]: d[key] = flt(val)
def create_bank_entries(columns, data, bank_account): header_map = get_header_mapping(columns, bank_account) success = 0 errors = 0 for d in json.loads(data): if all(item is None for item in d) is True: continue fields = {} for key, value in iteritems(header_map): fields.update({key: d[int(value) - 1]}) try: bank_transaction = frappe.get_doc({"doctype": "Bank Transaction"}) bank_transaction.update(fields) bank_transaction.date = getdate(parse_date(bank_transaction.date)) bank_transaction.bank_account = bank_account bank_transaction.insert() bank_transaction.submit() success += 1 except Exception: frappe.log_error(frappe.get_traceback()) errors += 1 return {"success": success, "errors": errors}
def create_bank_entries(columns, data, bank_account): bank_name = frappe.db.get_value("Bank Account", bank_account, "bank") bank = frappe.get_doc("Bank", bank_name) header_map = get_header_mapping(columns, bank) success = 0 errors = 0 total = len(json.loads(data)) for idx, d in enumerate(json.loads(data)): if all(item is None for item in d) is True: continue fields = {} for key, value in iteritems(header_map): fields.update({ key: get_value(d, key, bank, int(value)-1) }) frappe.publish_progress(((idx+1)*100)/total, title=_("Importing Transactions"),description=_("Transaction {0} of {1}.").format(idx, total)) try: bank_transaction = frappe.get_doc({ "doctype": "Bank Transaction" }) bank_transaction.update(fields) bank_transaction.date = getdate(parse_date(bank_transaction.date)) bank_transaction.bank_account = bank_account bank_transaction.insert() bank_transaction.submit() success += 1 except Exception: frappe.log_error(frappe.get_traceback()) errors += 1 return {"success": success, "errors": errors}
def create_bank_entries(columns, data, bank_account): header_map = get_header_mapping(columns, bank_account) success = 0 errors = 0 for d in json.loads(data): if all(item is None for item in d) is True: continue fields = {} for key, value in iteritems(header_map): fields.update({key: d[int(value)-1]}) try: bank_transaction = frappe.get_doc({ "doctype": "Bank Transaction" }) bank_transaction.update(fields) bank_transaction.date = getdate(parse_date(bank_transaction.date)) bank_transaction.bank_account = bank_account bank_transaction.insert() bank_transaction.submit() success += 1 except Exception: frappe.log_error(frappe.get_traceback()) errors += 1 return {"success": success, "errors": errors}
def check_record(d): """check for mandatory, select options, dates. these should ideally be in doclist""" from frappe.utils.dateutils import parse_date doc = frappe.get_doc(d) frappe.errprint(type(d)) for key in d: docfield = doc.meta.get_field(key) val = d[key] if docfield: if docfield.reqd and (val == '' or val == None): frappe.msgprint(_("{0} is required").format(docfield.label), raise_exception=1) if docfield.fieldtype == 'Select' and val and docfield.options: if docfield.options.startswith('link:'): link_doctype = docfield.options.split(':')[1] if not frappe.db.exists(link_doctype, val): frappe.throw( _("{0} {1} must be a valid {2}").format( _(docfield.lable), val, _(link_doctype))) elif docfield.options == "attach_files:": pass elif val not in docfield.options.split('\n'): frappe.throw( _("{0} must be one of {1}").format( _(docfield.label), comma_or(docfield.options.split("\n")))) if val and docfield.fieldtype == 'Date': d[key] = parse_date(val) elif val and docfield.fieldtype in ["Int", "Check"]: d[key] = cint(val) elif val and docfield.fieldtype in ["Currency", "Float"]: d[key] = flt(val)
def reconcile_created_payments(self): for transaction, payment in zip(self.bank_transactions, self.payment_entries): bank_transaction = frappe.get_doc("Bank Transaction", transaction.get("name")) date_value = payment.get("reference_date") if isinstance(date_value, str): date_value = parse_date(date_value) bank_transaction.append( 'payment_entries', { 'payment_document': payment.get("doctype"), 'payment_entry': payment.get("name"), 'allocated_amount': min(abs(payment.get("unreconciled_amount")), abs(bank_transaction.unallocated_amount)), 'party': payment.get(PARTY_FIELD.get(payment.get("doctype"))), 'date': getdate(date_value) }) bank_transaction.save()
def check_record(d): """check for mandatory, select options, dates. these should ideally be in doclist""" from frappe.utils.dateutils import parse_date doc = frappe.get_doc(d) for key in d: docfield = doc.meta.get_field(key) val = d[key] if docfield: if docfield.reqd and (val == '' or val == None): frappe.msgprint(_("{0} is required").format(docfield.label), raise_exception=1) if docfield.fieldtype == 'Select' and val and docfield.options: if val not in docfield.options.split('\n'): frappe.throw( _("{0} must be one of {1}").format( _(docfield.label), comma_or(docfield.options.split("\n")))) if val and docfield.fieldtype == 'Date': d[key] = parse_date(val) elif val and docfield.fieldtype in ["Int", "Check"]: d[key] = cint(val) elif val and docfield.fieldtype in [ "Currency", "Float", "Percent" ]: d[key] = flt(val)
def check_record(d): """check for mandatory, select options, dates. these should ideally be in doclist""" from frappe.utils.dateutils import parse_date doc = frappe.get_doc(d) for key in d: docfield = doc.meta.get_field(key) val = d[key] if docfield: if docfield.reqd and (val=='' or val==None): frappe.msgprint(_("{0} is required").format(docfield.label), raise_exception=1) if docfield.fieldtype=='Select' and val and docfield.options: if docfield.options == "attach_files:": pass elif val not in docfield.options.split('\n'): frappe.throw(_("{0} must be one of {1}").format(_(docfield.label), comma_or(docfield.options.split("\n")))) if val and docfield.fieldtype=='Date': d[key] = parse_date(val) elif val and docfield.fieldtype in ["Int", "Check"]: d[key] = cint(val) elif val and docfield.fieldtype in ["Currency", "Float", "Percent"]: d[key] = flt(val)
def create_oauth_user(data, provider): if data.get("birthday"): from frappe.utils.dateutils import parse_date data["birthday"] = parse_date(data["birthday"]) if isinstance(data.get("location"), dict): data["location"] = data.get("location").get("name") user = frappe.get_doc({ "doctype": "User", "first_name": data.get("first_name") or data.get("given_name") or data.get("name"), "last_name": data.get("last_name") or data.get("family_name"), "email": data["email"], "gender": data.get("gender"), "enabled": 1, "new_password": frappe.generate_hash(data["email"]), "location": data.get("location"), "birth_date": data.get("birthday"), "user_type": "Website User", "user_image": data.get("picture") or data.get("avatar_url") }) if provider == "facebook": user.update({ "fb_username": data["username"], "fb_userid": data["id"], "user_image": "https://graph.facebook.com/{username}/picture".format( username=data["username"]) }) elif provider == "google": user.google_userid = data["id"] elif provider == "github": user.github_userid = data["id"] user.github_username = data["login"] user.ignore_permissions = True user.no_welcome_mail = True user.insert()
def create_bank_entries(columns, data, bank_account, upload_type=None): if not upload_type: frappe.throw(_("Please upload a file first")) header_map = get_header_mapping(columns, bank_account, upload_type) if not header_map: return {"status": "Missing header map"} success = 0 errors = 0 duplicates = 0 for d in json.loads(data): if all(item is None for item in d) is True: continue fields = {} for key, dummy in iteritems(header_map): fields.update({header_map.get(key): d.get(key)}) try: bank_transaction = frappe.new_doc("Bank Transaction") bank_transaction.update(fields) bank_transaction.date = getdate(parse_date(bank_transaction.date)) bank_transaction.bank_account = bank_account bank_transaction.flags.import_statement = True bank_transaction.insert() bank_transaction.submit() success += 1 frappe.db.commit() except frappe.UniqueValidationError: duplicates += 1 frappe.clear_messages() except frappe.DuplicateEntryError: duplicates += 1 frappe.clear_messages() except Exception: errors += 1 frappe.log_error(frappe.get_traceback(), _("Bank transaction creation error")) return { "success": success, "errors": errors, "duplicates": duplicates, "status": "Complete" }
def create_bank_entries(columns, data, bank_account): header_map = get_header_mapping(columns, bank_account) count = 0 for d in json.loads(data): if all(item is None for item in d) is True: continue fields = {} for key, value in iteritems(header_map): fields.update({key: d[int(value) - 1]}) bank_transaction = frappe.get_doc({"doctype": "Bank Transaction"}) bank_transaction.update(fields) bank_transaction.date = getdate(parse_date(bank_transaction.date)) bank_transaction.bank_account = bank_account bank_transaction.insert() bank_transaction.submit() count = count + 1 return count
def validate(self): if not self.lot: frappe.throw(_("Lot number is not generated. Please contact your admin.")) veh_ref_cp = [] for veh_ref in self.vehicle_reference: if veh_ref.date > nowdate(): frappe.throw(_("Date entered cannot be greater than today's date")) diff = frappe.utils.date_diff(nowdate(), veh_ref.date) if diff > 30 and not self.confirm_days_old: frappe.throw(_("Days Old {0} is greater than 30 days. Check Confirm Days Old to confirm.").format(diff)) date_str = dateutils.parse_date(veh_ref.date) year = date_str[2:4] month = date_str[5:7] day = date_str[8:11] veh_ref.vehicle_reference = year + month + day + "." + veh_ref.truck_sequence + veh_ref.species_sequence veh_ref_cp.append({ 'vehicle_reference': veh_ref.vehicle_reference, 'date': veh_ref.date, 'truck_sequence': veh_ref.truck_sequence, 'species_sequence': veh_ref.species_sequence }) duplicates = [ref for n, ref in enumerate(veh_ref_cp) if ref in veh_ref_cp[:n]] if duplicates: frappe.throw(_("Duplicates exist for Date, TT and SS combination")) if self.sort_order == "Ascending": sort_order = False else: sort_order = True veh_ref_cp = sorted(veh_ref_cp,key=itemgetter('vehicle_reference'),reverse=sort_order) self.vehicle_reference = [] for ref in veh_ref_cp: self.append('vehicle_reference', {'date': ref["date"], 'truck_sequence': ref["truck_sequence"], 'species_sequence': ref["species_sequence"], 'vehicle_reference': ref["vehicle_reference"]})
def create_oauth_user(data, provider): if data.get("birthday"): from frappe.utils.dateutils import parse_date data["birthday"] = parse_date(data["birthday"]) if isinstance(data.get("location"), dict): data["location"] = data.get("location").get("name") user = frappe.get_doc({ "doctype":"User", "first_name": data.get("first_name") or data.get("given_name") or data.get("name"), "last_name": data.get("last_name") or data.get("family_name"), "email": data["email"], "gender": data.get("gender"), "enabled": 1, "new_password": frappe.generate_hash(data["email"]), "location": data.get("location"), "birth_date": data.get("birthday"), "user_type": "Website User", "user_image": data.get("picture") or data.get("avatar_url") }) if provider=="facebook": user.update({ "fb_username": data["username"], "fb_userid": data["id"], "user_image": "https://graph.facebook.com/{username}/picture".format(username=data["username"]) }) elif provider=="google": user.google_userid = data["id"] elif provider=="github": user.github_userid = data["id"] user.github_username = data["login"] user.ignore_permissions = True user.no_welcome_mail = True user.insert()
def check_matching_dates(self, output): if not output: return [] comparison_date = self.bank_transactions[0].get("date") description = self.bank_transactions[0].get("description") output = sorted(output, key=lambda doc: difflib.SequenceMatcher( lambda doc: doc == " ", str(doc.get("party")), description).ratio(), reverse=True) date_field = self.get_reference_date_field() closest = min(output[:10], key=lambda x: abs( getdate(x.get(date_field)) - getdate( parse_date(comparison_date)))) return [ dict(x, **{"vgtSelected": True}) if x.get("name") == closest.get("name") else x for x in output ]
def create_bank_entries(columns, data, bank_account): header_map = get_header_mapping(columns, bank_account) count = 0 for d in json.loads(data): if all(item is None for item in d) is True: continue fields = {} for key, value in header_map.iteritems(): fields.update({key: d[int(value)-1]}) bank_transaction = frappe.get_doc({ "doctype": "Bank Transaction" }) bank_transaction.update(fields) bank_transaction.date = getdate(parse_date(bank_transaction.date)) bank_transaction.bank_account = bank_account bank_transaction.insert() bank_transaction.submit() count = count + 1 return count
def reconcile_one_transaction_with_multiple_documents(self): for document in self.documents: bank_transaction = frappe.get_doc( "Bank Transaction", self.bank_transactions[0]["name"]) date_value = document.get("reference_date") if isinstance(date_value, str): date_value = parse_date(date_value) if flt(bank_transaction.unallocated_amount) != 0: bank_transaction.append( 'payment_entries', { 'payment_document': document.get("doctype"), 'payment_entry': document.get("name"), 'allocated_amount': abs(document.get("unreconciled_amount")), 'party': document.get(PARTY_FIELD.get(document.get("doctype"))), 'date': getdate(date_value) }) bank_transaction.save()
def get_doc(start_idx): if doctypes: doc = {} attachments = [] last_error_row_idx = None for idx in range(start_idx, len(rows)): last_error_row_idx = idx # pylint: disable=W0612 if (not doc) or main_doc_empty(rows[idx]): for dt, parentfield in doctypes: d = {} for column_idx in column_idx_to_fieldname[( dt, parentfield)]: try: fieldname = column_idx_to_fieldname[( dt, parentfield)][column_idx] fieldtype = column_idx_to_fieldtype[( dt, parentfield)][column_idx] if not fieldname or not rows[idx][column_idx]: continue d[fieldname] = rows[idx][column_idx] if fieldtype in ("Int", "Check"): d[fieldname] = cint(d[fieldname]) elif fieldtype in ("Float", "Currency", "Percent"): d[fieldname] = flt(d[fieldname]) elif fieldtype == "Date": if d[fieldname] and isinstance( d[fieldname], string_types): d[fieldname] = getdate( parse_date(d[fieldname])) elif fieldtype == "Datetime": if d[fieldname]: if " " in d[fieldname]: _date, _time = d[fieldname].split() else: _date, _time = d[ fieldname], '00:00:00' _date = parse_date(d[fieldname]) d[fieldname] = get_datetime(_date + " " + _time) else: d[fieldname] = None elif fieldtype in ("Image", "Attach Image", "Attach"): # added file to attachments list attachments.append(d[fieldname]) elif fieldtype in ("Link", "Dynamic Link", "Data") and d[fieldname]: # as fields can be saved in the number format(long type) in data import template d[fieldname] = cstr(d[fieldname]) except IndexError: pass # scrub quotes from name and modified if d.get("name") and d["name"].startswith('"'): d["name"] = d["name"][1:-1] if sum([0 if not val else 1 for val in d.values()]): d['doctype'] = dt if dt == doctype: doc.update(d) else: if not overwrite and doc.get("name"): d['parent'] = doc["name"] d['parenttype'] = doctype d['parentfield'] = parentfield doc.setdefault(d['parentfield'], []).append(d) else: break #frappe.msgprint(doc) return doc, attachments, last_error_row_idx else: doc = frappe._dict(zip(columns, rows[start_idx][1:])) doc['doctype'] = doctype return doc, [], None
def get_doc(start_idx): if doctypes: doc = {} attachments = [] last_error_row_idx = None for idx in range(start_idx, len(rows)): last_error_row_idx = idx # pylint: disable=W0612 if (not doc) or main_doc_empty(rows[idx]): for dt, parentfield in doctypes: d = {} for column_idx in column_idx_to_fieldname[(dt, parentfield)]: try: fieldname = column_idx_to_fieldname[(dt, parentfield)][column_idx] fieldtype = column_idx_to_fieldtype[(dt, parentfield)][column_idx] if not fieldname or not rows[idx][column_idx]: continue d[fieldname] = rows[idx][column_idx] if fieldtype in ("Int", "Check"): d[fieldname] = cint(d[fieldname]) elif fieldtype in ("Float", "Currency", "Percent"): d[fieldname] = flt(d[fieldname]) elif fieldtype == "Date": if d[fieldname] and isinstance(d[fieldname], string_types): d[fieldname] = getdate(parse_date(d[fieldname])) elif fieldtype == "Datetime": if d[fieldname]: if " " in d[fieldname]: _date, _time = d[fieldname].split() else: _date, _time = d[fieldname], '00:00:00' _date = parse_date(d[fieldname]) d[fieldname] = get_datetime(_date + " " + _time) else: d[fieldname] = None elif fieldtype in ("Image", "Attach Image", "Attach"): # added file to attachments list attachments.append(d[fieldname]) elif fieldtype in ("Link", "Dynamic Link", "Data") and d[fieldname]: # as fields can be saved in the number format(long type) in data import template d[fieldname] = cstr(d[fieldname]) except IndexError: pass # scrub quotes from name and modified if d.get("name") and d["name"].startswith('"'): d["name"] = d["name"][1:-1] if sum([0 if not val else 1 for val in d.values()]): d['doctype'] = dt if dt == doctype: doc.update(d) else: if not overwrite and doc.get("name"): d['parent'] = doc["name"] d['parenttype'] = doctype d['parentfield'] = parentfield doc.setdefault(d['parentfield'], []).append(d) else: break return doc, attachments, last_error_row_idx else: doc = frappe._dict(zip(columns, rows[start_idx][1:])) doc['doctype'] = doctype return doc, [], None
def upload(import_settings=None): if not frappe.has_permission("Attendance", "create"): raise frappe.PermissionError from frappe.utils.csvutils import read_csv_content_from_uploaded_file from frappe.modules import scrub rows = read_csv_content_from_uploaded_file() rows = list(filter(lambda x: x and any(x), rows)) if not rows: msg = [_("Please select a csv file")] return {"messages": msg, "error": msg} #fixme error when importing certain header #columns = [scrub(f) for f in rows[0]] columns = ["employee", "attendance_date", "arrival_time", "departure_time"] ret = [] error = False started = False import json params = json.loads(frappe.form_dict.get("params") or '{}') if not params.get("import_settings"): import_settings = "default" else: import_settings = params.get("import_settings") from frappe.utils.csvutils import check_record, import_doc for i, row in enumerate(rows[1:]): if not row: continue started = True row_idx = i + 1 d = frappe._dict(zip(columns, row)) d["doctype"] = "Attendance" date_error = False try: parse_date(d.attendance_date) except Exception as e: date_error = True ret.append('Error for row (#%d) %s : %s' % (row_idx + 1, len(row) > 1 and row[1] or "", cstr(e))) except ValueError as e: date_error = True ret.append('Error for row (#%d) %s : %s' % (row_idx + 1, len(row) > 1 and row[1] or "", cstr(e))) except: date_error = True ret.append('Error for row (#%d) %s' % (row_idx + 1, len(row) > 1 and row[1] or "")) if date_error == True: if import_settings != "ignore": error = True continue formatted_attendance_date = getdate(parse_date(d.attendance_date)) if import_settings == "ignore": attendance = frappe.db.sql( """select name,docstatus,attendance_date from `tabAttendance` where employee = %s and attendance_date = %s""", (d.employee, formatted_attendance_date), as_dict=True) if attendance: link = [ '<a href="#Form/Attendance/{0}">{0}</a>'.format( str(attendance[0].name)) ] # ret.append('Ignored row (#%d) %s : %s - %s' % (row_idx+1, # len(row)>1 and row[1] or "", cstr(d.employee),link)) else: try: check_record(d) ret.append( import_doc(d, "Attendance", 1, row_idx, submit=False)) except Exception, e: # error = True ret.append( 'Error for row (#%d) %s : %s' % (row_idx + 1, len(row) > 1 and row[1] or "", cstr(e))) # frappe.errprint(frappe.get_traceback()) elif import_settings == "update": attendance = frappe.db.sql( """select name,docstatus,attendance_date from `tabAttendance` where employee = %s and attendance_date = %s""", (d.employee, formatted_attendance_date), as_dict=True) if attendance: d["docstatus"] = attendance[0].docstatus d["name"] = attendance[0].name try: check_record(d) ret.append( import_doc(d, "Attendance", 1, row_idx, submit=False)) except Exception, e: error = True ret.append( 'Error for row (#%d) %s : %s' % (row_idx + 1, len(row) > 1 and row[1] or "", cstr(e)))
def get_payment_entry(self, transaction): company_currency = frappe.db.get_value("Company", self.company, "default_currency") party_account_currency = get_account_currency(self.party_account) # payment type if (self.reconciliation_doctype == "Sales Invoice" and transaction.get("amount") > 0) \ or (self.reconciliation_doctype == "Purchase Invoice" and transaction.get("amount") > 0): payment_type = "Receive" else: payment_type = "Pay" # total outstanding total_outstanding_amount = 0 if self.reconciliation_doctype in ("Sales Invoice", "Purchase Invoice"): total_outstanding_amount = sum( [x.get("outstanding_amount") for x in self.documents]) elif self.reconciliation_doctype in ("Expense Claim"): total_outstanding_amount = sum([ (flt(x.get("grand_total")) - flt(x.get("total_amount_reimbursed"))) for x in self.documents ]) elif self.reconciliation_doctype == "Employee Advance": total_outstanding_amount = sum([ (flt(x.get("advance_amount")) - flt(x.get("paid_amount"))) for x in self.documents ]) bank_account = frappe.get_doc("Bank Account", transaction.get("bank_account")) account_currency = frappe.db.get_value("Account", bank_account.account, "account_currency") paid_amount = received_amount = 0 outstanding_amount = sum( [x.get("outstanding_amount") for x in self.documents]) amount_to_pay_or_receive = abs(transaction.get("unallocated_amount")) \ if abs(transaction.get("unallocated_amount")) <= outstanding_amount else outstanding_amount if party_account_currency == account_currency: paid_amount = received_amount = amount_to_pay_or_receive elif payment_type == "Receive": paid_amount = amount_to_pay_or_receive target_exchange_rate = total_outstanding_amount / paid_amount received_amount = total_outstanding_amount else: received_amount = amount_to_pay_or_receive source_exchange_rate = received_amount / total_outstanding_amount paid_amount = total_outstanding_amount pe = frappe.new_doc("Payment Entry") pe.payment_type = payment_type pe.company = bank_account.company pe.cost_center = self.cost_center pe.posting_date = getdate(parse_date(transaction.get("date"))) pe.mode_of_payment = self.mode_of_payment pe.party_type = self.party_type pe.party = self.party contacts = [x.get("contact_person") for x in self.documents] pe.contact_person = contacts[0] if contacts else None pe.contact_email = " ,".join([ x.get("contact_email") for x in self.documents if x.get("contact_email") ]) pe.ensure_supplier_is_not_blocked() pe.paid_from = self.party_account if payment_type == "Receive" else bank_account.account pe.paid_to = self.party_account if payment_type == "Pay" else bank_account.account pe.paid_from_account_currency = party_account_currency \ if payment_type == "Receive" else account_currency pe.paid_to_account_currency = party_account_currency if payment_type == "Pay" else account_currency pe.paid_amount = paid_amount pe.received_amount = received_amount letter_heads = [x.get("letter_head") for x in self.documents] pe.letter_head = letter_heads[0] if letter_heads else None pe.reference_no = transaction.get( "reference_number") or transaction.get("name") pe.reference_date = getdate(parse_date(transaction.get("date"))) pe.bank_account = bank_account.name if pe.party_type in ["Customer", "Supplier"]: bank_account = get_party_bank_account(pe.party_type, pe.party) pe.set("party_bank_account", bank_account) pe.set_bank_account_data() total_allocated_amount = 0 for doc in self.documents: # only Purchase Invoice can be blocked individually if doc.get("doctype") == "Purchase Invoice": pi = frappe.get_doc("Purchase Invoice", doc.get("name")) if pi.invoice_is_blocked(): frappe.throw( _('{0} is on hold till {1}'.format( pi.name, pi.release_date))) # amounts grand_total = outstanding_amount = 0 if self.reconciliation_doctype in ("Sales Invoice", "Purchase Invoice"): if party_account_currency == doc.get("company_currency"): grand_total = doc.get("base_rounded_total") or doc.get( "base_grand_total") else: grand_total = doc.get("rounded_total") or doc.get( "grand_total") outstanding_amount = doc.get("outstanding_amount") elif self.reconciliation_doctype in ("Expense Claim"): grand_total = doc.get("total_sanctioned_amount") + doc.get( "total_taxes_and_charges") outstanding_amount = doc.get("grand_total") - doc.get( "total_amount_reimbursed") elif self.reconciliation_doctype == "Employee Advance": grand_total = doc.get("advance_amount") outstanding_amount = flt(doc.get("advance_amount")) - flt( doc.get("paid_amount")) else: if party_account_currency == doc.get("company_currency"): grand_total = flt( doc.get("base_rounded_total") or doc.get("base_grand_total")) else: grand_total = flt( doc.get("rounded_total") or doc.get("grand_total")) outstanding_amount = grand_total - flt(doc.get("advance_paid")) allocated_amount = min( outstanding_amount, flt(abs(transaction.get("unallocated_amount"))) - flt(total_allocated_amount)) pe.append( "references", { 'reference_doctype': doc.get("doctype"), 'reference_name': doc.get("name"), "bill_no": doc.get("bill_no"), "due_date": doc.get("due_date"), 'total_amount': grand_total, 'outstanding_amount': outstanding_amount, 'allocated_amount': allocated_amount }) total_allocated_amount += allocated_amount pe.setup_party_account_field() pe.set_missing_values() if self.party_account and bank_account: pe.set_exchange_rate() pe.set_amounts() return pe