diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.js b/erpnext/accounts/doctype/sales_invoice/sales_invoice.js index d89a39eb6b..8c5097466e 100644 --- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.js +++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.js @@ -51,9 +51,9 @@ erpnext.accounts.SalesInvoiceController = erpnext.selling.SellingController.exte if(doc.docstatus==1 && !doc.is_return) { - var flag_delivery_note = false; + var is_drop_ship = false; - flag_delivery_note = cur_frm.doc.items.some(function(item){ + is_drop_ship = cur_frm.doc.items.some(function(item){ return item.is_drop_ship ? true : false; }) @@ -68,7 +68,7 @@ erpnext.accounts.SalesInvoiceController = erpnext.selling.SellingController.exte return item.delivery_note ? true : false; }); - if(!from_delivery_note && flag_delivery_note) { + if(!from_delivery_note && !is_drop_ship) { cur_frm.add_custom_button(__('Delivery'), cur_frm.cscript['Make Delivery Note']).addClass("btn-primary"); } } diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py index 11cd5d8073..60fdc1a710 100644 --- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py +++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py @@ -668,7 +668,7 @@ def make_delivery_note(source_name, target_doc=None): "so_detail": "so_detail" }, "postprocess": update_item, - "condition": lambda doc: (doc.is_drop_ship!=1 and not doc.supplier) + "condition": lambda doc: doc.is_drop_ship!=1 }, "Sales Taxes and Charges": { "doctype": "Sales Taxes and Charges", diff --git a/erpnext/accounts/doctype/sales_invoice_item/sales_invoice_item.json b/erpnext/accounts/doctype/sales_invoice_item/sales_invoice_item.json index 44f69cb923..37b60d1bf6 100644 --- a/erpnext/accounts/doctype/sales_invoice_item/sales_invoice_item.json +++ b/erpnext/accounts/doctype/sales_invoice_item/sales_invoice_item.json @@ -725,50 +725,6 @@ "set_only_once": 0, "unique": 0 }, - { - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "fieldname": "column_break_33", - "fieldtype": "Column Break", - "hidden": 0, - "ignore_user_permissions": 0, - "in_filter": 0, - "in_list_view": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "read_only": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "unique": 0 - }, - { - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "fieldname": "supplier", - "fieldtype": "Link", - "hidden": 0, - "ignore_user_permissions": 0, - "in_filter": 0, - "in_list_view": 0, - "label": "Supplier", - "no_copy": 0, - "options": "Supplier", - "permlevel": 0, - "precision": "", - "print_hide": 0, - "read_only": 1, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "unique": 0 - }, { "allow_on_submit": 0, "bold": 0, @@ -1371,8 +1327,8 @@ "is_submittable": 0, "issingle": 0, "istable": 1, - "modified": "2015-10-20 15:54:03.318846", - "modified_by": "saurabh6790@gmail.com", + "modified": "2015-10-21 19:06:40.313900", + "modified_by": "Administrator", "module": "Accounts", "name": "Sales Invoice Item", "owner": "Administrator", diff --git a/erpnext/buying/doctype/purchase_common/purchase_common.py b/erpnext/buying/doctype/purchase_common/purchase_common.py index 3cdb5a064b..a86b330630 100644 --- a/erpnext/buying/doctype/purchase_common/purchase_common.py +++ b/erpnext/buying/doctype/purchase_common/purchase_common.py @@ -83,11 +83,9 @@ class PurchaseCommon(BuyingController): def check_for_stopped_or_closed_status(self, doctype, docname): status = frappe.db.get_value(doctype, docname, "status") - if status == "Stopped": - frappe.throw(_("{0} {1} status is Stopped").format(doctype, docname), frappe.InvalidStatusError) - if status == "Closed": - frappe.throw(_("{0} {1} status is Closed").format(doctype, docname), frappe.InvalidStatusError) - + if status in ("Stopped", "Closed"): + frappe.throw(_("{0} {1} status is {2}").format(doctype, docname, status), frappe.InvalidStatusError) + def check_docstatus(self, check, doctype, docname, detail_doctype = ''): if check == 'Next': submitted = frappe.db.sql("""select t1.name from `tab%s` t1,`tab%s` t2 diff --git a/erpnext/buying/doctype/purchase_order/purchase_order.js b/erpnext/buying/doctype/purchase_order/purchase_order.js index 9a701595c5..94ec770b5d 100644 --- a/erpnext/buying/doctype/purchase_order/purchase_order.js +++ b/erpnext/buying/doctype/purchase_order/purchase_order.js @@ -22,9 +22,9 @@ erpnext.buying.PurchaseOrderController = erpnext.buying.BuyingController.extend( if(doc.docstatus == 1 && doc.status != 'Stopped' && doc.status != 'Closed') { if(flt(doc.per_billed, 2) < 100 || doc.per_received < 100) - cur_frm.add_custom_button(__('Stop'), cur_frm.cscript['Stop Purchase Order']); + cur_frm.add_custom_button(__('Stop'), this.stop_purchase_order); - cur_frm.add_custom_button(__('Close'), cur_frm.cscript['Close Purchase Order']); + cur_frm.add_custom_button(__('Close'), this.close_purchase_order); if(flt(doc.per_billed)==0) { cur_frm.add_custom_button(__('Payment'), cur_frm.cscript.make_bank_entry); @@ -48,7 +48,7 @@ erpnext.buying.PurchaseOrderController = erpnext.buying.BuyingController.extend( } if(doc.docstatus == 1 && doc.status == 'Stopped') - cur_frm.add_custom_button(__('Unstop'), cur_frm.cscript['Unstop Purchase Order']); + cur_frm.add_custom_button(__('Unstop'), this.unstop_purchase_order); }, make_stock_entry: function() { @@ -157,6 +157,15 @@ erpnext.buying.PurchaseOrderController = erpnext.buying.BuyingController.extend( frappe.set_route("Form", doclist[0].doctype, doclist[0].name); } }); + }, + stop_purchase_order: function(){ + cur_frm.cscript.update_status('Stop', 'Stopped') + }, + unstop_purchase_order: function(){ + cur_frm.cscript.update_status('UNSTOP', 'Submitted') + }, + close_purchase_order: function(){ + cur_frm.cscript.update_status('Close', 'Closed') } }); @@ -164,6 +173,21 @@ erpnext.buying.PurchaseOrderController = erpnext.buying.BuyingController.extend( // for backward compatibility: combine new and previous states $.extend(cur_frm.cscript, new erpnext.buying.PurchaseOrderController({frm: cur_frm})); +cur_frm.cscript.update_status= function(label, status){ + var doc = cur_frm.doc; + var check = confirm(__("Do you really want to {0} {1}",[label, doc.name])); + + if (check) { + frappe.call({ + method: "erpnext.buying.doctype.purchase_order.purchase_order.update_status", + args:{status: status, name: doc.name}, + callback:function(r){ + cur_frm.refresh(); + } + }) + } +} + cur_frm.fields_dict['supplier_address'].get_query = function(doc, cdt, cdn) { return { filters: {'supplier': doc.supplier} @@ -203,40 +227,6 @@ cur_frm.cscript.get_last_purchase_rate = function(doc, cdt, cdn){ }); } -cur_frm.cscript['Stop Purchase Order'] = function() { - var doc = cur_frm.doc; - var check = confirm(__("Do you really want to STOP ") + doc.name); - - if (check) { - return $c('runserverobj', args={'method':'update_status', 'arg': 'Stopped', 'docs':doc}, function(r,rt) { - cur_frm.refresh(); - }); - } -} - -cur_frm.cscript['Unstop Purchase Order'] = function() { - var doc = cur_frm.doc; - var check = confirm(__("Do you really want to UNSTOP ") + doc.name); - - if (check) { - return $c('runserverobj', args={'method':'update_status', 'arg': 'Submitted', 'docs':doc}, function(r,rt) { - cur_frm.refresh(); - }); - } -} - -cur_frm.cscript['Close Purchase Order'] = function() { - var doc = cur_frm.doc; - var check = confirm(__("Do you really want to Close ") + doc.name); - - if (check) { - return $c('runserverobj', args={'method':'update_status', 'arg': 'Closed', 'docs':doc}, function(r,rt) { - cur_frm.refresh(); - }); - } -} - - cur_frm.pformat.indent_no = function(doc, cdt, cdn){ //function to make row of table diff --git a/erpnext/buying/doctype/purchase_order/purchase_order.py b/erpnext/buying/doctype/purchase_order/purchase_order.py index 9e0649ba34..d73f793c42 100644 --- a/erpnext/buying/doctype/purchase_order/purchase_order.py +++ b/erpnext/buying/doctype/purchase_order/purchase_order.py @@ -163,12 +163,7 @@ class PurchaseOrder(BuyingController): def on_submit(self): if self.is_drop_ship == 1: - self.status_updater[0].update({ - "target_parent_dt": "Sales Order", - "target_parent_field": "per_ordered", - "target_dt": "Sales Order Item", - 'target_field': 'ordered_qty' - }) + self.update_status_updater() super(PurchaseOrder, self).on_submit() @@ -185,12 +180,7 @@ class PurchaseOrder(BuyingController): def on_cancel(self): if self.is_drop_ship == 1: - self.status_updater[0].update({ - "target_parent_dt": "Sales Order", - "target_parent_field": "per_ordered", - "target_dt": "Sales Order Item", - 'target_field': 'ordered_qty' - }) + self.update_status_updater() pc_obj = frappe.get_doc('Purchase Common') self.check_for_stopped_or_closed_status(pc_obj) @@ -229,6 +219,14 @@ class PurchaseOrder(BuyingController): for field in ("received_qty", "billed_amt", "prevdoc_doctype", "prevdoc_docname", "prevdoc_detail_docname", "supplier_quotation", "supplier_quotation_item"): d.set(field, None) + + def update_status_updater(self): + self.status_updater[0].update({ + "target_parent_dt": "Sales Order", + "target_parent_field": "per_ordered", + "target_dt": "Sales Order Item", + 'target_field': 'ordered_qty' + }) @frappe.whitelist() def stop_or_unstop_purchase_orders(names, status): @@ -341,3 +339,9 @@ def make_stock_entry(purchase_order, item_code): stock_entry.bom_no = po_item.bom stock_entry.get_items() return stock_entry.as_dict() + +@frappe.whitelist() +def update_status(status, name): + po = frappe.get_doc("Purchase Order", name) + po.update_status(status) + return \ No newline at end of file diff --git a/erpnext/controllers/selling_controller.py b/erpnext/controllers/selling_controller.py index 7135baf02a..1ed8b8abe1 100644 --- a/erpnext/controllers/selling_controller.py +++ b/erpnext/controllers/selling_controller.py @@ -223,10 +223,8 @@ class SellingController(StockController): for d in self.get("items"): if d.get(ref_fieldname): status = frappe.db.get_value("Sales Order", d.get(ref_fieldname), "status") - if status == "Stopped": - frappe.throw(_("Sales Order {0} is stopped").format(d.get(ref_fieldname))) - if status == "Closed": - frappe.throw(_("Sales Order {0} is closed").format(d.get(ref_fieldname))) + if status in ("Stopped", "Closed"): + frappe.throw(_("Sales Order {0} is {1}").format(d.get(ref_fieldname), status)) def check_active_sales_items(obj): for d in obj.get("items"): diff --git a/erpnext/public/js/controllers/transaction.js b/erpnext/public/js/controllers/transaction.js index f518e9c53d..87cc2f6591 100644 --- a/erpnext/public/js/controllers/transaction.js +++ b/erpnext/public/js/controllers/transaction.js @@ -735,7 +735,7 @@ erpnext.TransactionController = erpnext.taxes_and_totals.extend({ var valid = true; $.each(["company", "customer"], function(i, fieldname) { - if(frappe.meta.has_field(me.frm.doc.doctype, fieldname)) { + if(frappe.meta.has_field(me.frm.doc.doctype, fieldname && me.frm.doc.doctype != "Purchase Order")) { if (!me.frm.doc[fieldname]) { msgprint(__("Please specify") + ": " + frappe.meta.get_label(me.frm.doc.doctype, fieldname, me.frm.doc.name) + diff --git a/erpnext/selling/doctype/sales_order/sales_order.js b/erpnext/selling/doctype/sales_order/sales_order.js index 71e52150fb..c354242353 100644 --- a/erpnext/selling/doctype/sales_order/sales_order.js +++ b/erpnext/selling/doctype/sales_order/sales_order.js @@ -15,18 +15,18 @@ erpnext.selling.SalesOrderController = erpnext.selling.SellingController.extend( refresh: function(doc, dt, dn) { this._super(); this.frm.dashboard.reset(); - var flag_drop_ship = false; - var flag_delivery_note = false; + var is_drop_ship = false; + var is_delivery_note = false; if(doc.docstatus==1) { if(doc.status != 'Stopped' && doc.status != 'Closed') { $.each(cur_frm.doc.items, function(i, item){ if(item.is_drop_ship == 1 || item.supplier){ - flag_drop_ship = true; + is_drop_ship = true; } else{ - flag_delivery_note = true; + is_delivery_note = true; } }) @@ -44,13 +44,13 @@ erpnext.selling.SalesOrderController = erpnext.selling.SellingController.extend( } // stop - if((flt(doc.per_delivered, 2) < 100 && flag_delivery_note) || doc.per_billed < 100 - || (flt(doc.per_ordered,2) < 100 && flag_drop_ship)){ - cur_frm.add_custom_button(__('Stop'), cur_frm.cscript['Stop Sales Order']) + if((flt(doc.per_delivered, 2) < 100 && is_delivery_note) || doc.per_billed < 100 + || (flt(doc.per_ordered,2) < 100 && is_drop_ship)){ + cur_frm.add_custom_button(__('Stop'), this.stop_sales_order) } - cur_frm.add_custom_button(__('Close'), cur_frm.cscript['Close Sales Order']) + cur_frm.add_custom_button(__('Close'), this.close_sales_order) // maintenance if(flt(doc.per_delivered, 2) < 100 && ["Sales", "Shopping Cart"].indexOf(doc.order_type)===-1) { @@ -59,7 +59,7 @@ erpnext.selling.SalesOrderController = erpnext.selling.SellingController.extend( } // delivery note - if(flt(doc.per_delivered, 2) < 100 && ["Sales", "Shopping Cart"].indexOf(doc.order_type)!==-1 && flag_delivery_note) + if(flt(doc.per_delivered, 2) < 100 && ["Sales", "Shopping Cart"].indexOf(doc.order_type)!==-1 && is_delivery_note) cur_frm.add_custom_button(__('Delivery'), this.make_delivery_note).addClass("btn-primary"); // sales invoice @@ -67,7 +67,7 @@ erpnext.selling.SalesOrderController = erpnext.selling.SellingController.extend( cur_frm.add_custom_button(__('Invoice'), this.make_sales_invoice).addClass("btn-primary"); } - if(flt(doc.per_ordered, 2) < 100 && flag_drop_ship) + if(flt(doc.per_ordered, 2) < 100 && is_drop_ship) cur_frm.add_custom_button(__('Make Purchase Order'), cur_frm.cscript.make_purchase_order).addClass("btn-primary"); } else { @@ -187,7 +187,7 @@ erpnext.selling.SalesOrderController = erpnext.selling.SellingController.extend( dialog.hide(); return frappe.call({ type: "GET", - method: "erpnext.selling.doctype.sales_order.sales_order.make_drop_shipment", + method: "erpnext.selling.doctype.sales_order.sales_order.make_purchase_order_for_drop_shipment", args: { "source_name": cur_frm.doc.name, "for_supplier": args.supplier @@ -202,6 +202,12 @@ erpnext.selling.SalesOrderController = erpnext.selling.SellingController.extend( }) }); dialog.show(); + }, + stop_sales_order: function(){ + cur_frm.cscript.update_status("Stop", "Stopped") + }, + close_sales_order: function(){ + cur_frm.cscript.update_status("Close", "Closed") } }); @@ -225,19 +231,18 @@ cur_frm.fields_dict['project_name'].get_query = function(doc, cdt, cdn) { } } -cur_frm.cscript['Stop Sales Order'] = function() { +cur_frm.cscript.update_status = function(label, status){ var doc = cur_frm.doc; - - var check = confirm(__("Are you sure you want to STOP ") + doc.name); - + var check = confirm(__("Do you really want to {0} {1}",[label, doc.name])); + if (check) { - return $c('runserverobj', { - 'method':'stop_sales_order', - 'docs': doc, - 'arg': "Stopped" - }, function(r,rt) { - cur_frm.refresh(); - }); + frappe.call({ + method: "erpnext.selling.doctype.sales_order.sales_order.update_status", + args:{status: status, name: doc.name}, + callback:function(r){ + cur_frm.refresh(); + } + }) } } @@ -256,22 +261,6 @@ cur_frm.cscript['Unstop Sales Order'] = function() { } } -cur_frm.cscript['Close Sales Order'] = function(){ - var doc = cur_frm.doc; - - var check = confirm(__("Are you sure you want to CLOSE ") + doc.name); - - if (check) { - return $c('runserverobj', { - 'method':'stop_sales_order', - 'docs': doc, - 'arg': "Closed" - }, function(r,rt) { - cur_frm.refresh(); - }); - } -} - cur_frm.cscript.on_submit = function(doc, cdt, cdn) { if(cint(frappe.boot.notification_settings.sales_order)) { cur_frm.email_doc(frappe.boot.notification_settings.sales_order_message); diff --git a/erpnext/selling/doctype/sales_order/sales_order.json b/erpnext/selling/doctype/sales_order/sales_order.json index b8680b8428..63f60f933c 100644 --- a/erpnext/selling/doctype/sales_order/sales_order.json +++ b/erpnext/selling/doctype/sales_order/sales_order.json @@ -2048,7 +2048,7 @@ "ignore_user_permissions": 0, "in_filter": 1, "in_list_view": 1, - "label": "% Ordered", + "label": "% Ordered", "no_copy": 1, "permlevel": 0, "precision": "", @@ -2578,7 +2578,7 @@ "is_submittable": 1, "issingle": 0, "istable": 0, - "modified": "2015-10-19 11:34:16.668148", + "modified": "2015-10-21 19:02:58.591057", "modified_by": "Administrator", "module": "Selling", "name": "Sales Order", diff --git a/erpnext/selling/doctype/sales_order/sales_order.py b/erpnext/selling/doctype/sales_order/sales_order.py index 630494a6cf..8c5cf59829 100644 --- a/erpnext/selling/doctype/sales_order/sales_order.py +++ b/erpnext/selling/doctype/sales_order/sales_order.py @@ -151,7 +151,7 @@ class SalesOrder(SellingController): def validate_drop_ship(self): for d in self.get('items'): if d.is_drop_ship and not d.supplier: - frappe.throw(_("#{0} Set Supplier for item {1}").format(d.idx, d.item_code)) + frappe.throw(_("Row #{0}: Set Supplier for item {1}").format(d.idx, d.item_code)) def on_submit(self): super(SalesOrder, self).on_submit() @@ -359,7 +359,7 @@ def make_delivery_note(source_name, target_doc=None): "parent": "against_sales_order", }, "postprocess": update_item, - "condition": lambda doc: doc.delivered_qty < doc.qty and (doc.is_drop_ship!=1 and not doc.supplier) + "condition": lambda doc: doc.delivered_qty < doc.qty and doc.is_drop_ship!=1 }, "Sales Taxes and Charges": { "doctype": "Sales Taxes and Charges", @@ -387,7 +387,6 @@ def make_sales_invoice(source_name, target_doc=None): target.run_method("calculate_taxes_and_totals") def update_item(source, target, source_parent): - target.supplier = source.supplier target.amount = flt(source.amount) - flt(source.billed_amt) target.base_amount = target.amount * flt(source_parent.conversion_rate) target.qty = target.amount / flt(source.rate) if (source.rate and source.billed_amt) else source.qty @@ -500,28 +499,20 @@ def get_events(start, end, filters=None): return data @frappe.whitelist() -def make_drop_shipment(source_name, for_supplier, target_doc=None): - def postprocess(source, target): - set_missing_values(source, target) - +def make_purchase_order_for_drop_shipment(source_name, for_supplier, target_doc=None): def set_missing_values(source, target): target.supplier = for_supplier - target.buying_price_list = frappe.get_value("Supplier", for_supplier, "default_price_list") or 'Standard Buying' - target.address_display = "" - target.contact_display = "" - target.contact_mobile = "" - target.contact_email = "" - target.contact_person = "" + + default_price_list = frappe.get_value("Supplier", for_supplier, "default_price_list") + if default_price_list: + target.buying_price_list = default_price_list + target.is_drop_ship = 1 target.run_method("set_missing_values") target.run_method("calculate_taxes_and_totals") def update_item(source, target, source_parent): target.schedule_date = source_parent.delivery_date - target.rate = '' - target.price_list_rate = '' - target.base_amount = (flt(source.qty) - flt(source.ordered_qty)) * flt(source.base_rate) - target.amount = (flt(source.qty) - flt(source.ordered_qty)) * flt(source.rate) target.qty = flt(source.qty) - flt(source.ordered_qty) doclist = get_mapped_doc("Sales Order", source_name, { @@ -534,6 +525,13 @@ def make_drop_shipment(source_name, for_supplier, target_doc=None): "contact_email": "customer_contact_email", "contact_person": "customer_contact_person" }, + "field_no_map": [ + "address_display", + "contact_display", + "contact_mobile", + "contact_email", + "contact_person" + ], "validation": { "docstatus": ["=", 1] } @@ -547,14 +545,18 @@ def make_drop_shipment(source_name, for_supplier, target_doc=None): ["uom", "stock_uom"], ["delivery_date", "schedule_date"] ], + "field_no_map": [ + "rate", + "price_list_rate" + ], "postprocess": update_item, - "condition": lambda doc: doc.ordered_qty < doc.qty and doc.supplier == for_supplier or (doc.is_drop_ship==1 and doc.supplier == for_supplier) + "condition": lambda doc: doc.ordered_qty < doc.qty and doc.supplier == for_supplier }, "Sales Taxes and Charges": { "doctype": "Purchase Taxes and Charges", "add_if_empty": True } - }, target_doc, postprocess) + }, target_doc, set_missing_values) @@ -587,4 +589,10 @@ def get_supplier(doctype, txt, searchfield, start, page_len, filters): 'start': start, 'page_len': page_len, 'parent': filters.get('parent') - }) \ No newline at end of file + }) + +@frappe.whitelist() +def update_status(status, name): + so = frappe.get_doc("Sales Order", name) + so.stop_sales_order(status) + return \ No newline at end of file diff --git a/erpnext/selling/doctype/sales_order_item/sales_order_item.json b/erpnext/selling/doctype/sales_order_item/sales_order_item.json index 8acb16ae8e..cd56cc5f87 100644 --- a/erpnext/selling/doctype/sales_order_item/sales_order_item.json +++ b/erpnext/selling/doctype/sales_order_item/sales_order_item.json @@ -720,7 +720,7 @@ "no_copy": 0, "permlevel": 0, "precision": "", - "print_hide": 0, + "print_hide": 1, "read_only": 0, "report_hide": 0, "reqd": 0, @@ -764,7 +764,7 @@ "options": "Supplier", "permlevel": 0, "precision": "", - "print_hide": 0, + "print_hide": 1, "read_only": 0, "report_hide": 0, "reqd": 0, @@ -1206,7 +1206,7 @@ "is_submittable": 0, "issingle": 0, "istable": 1, - "modified": "2015-10-19 03:04:51.257808", + "modified": "2015-10-21 19:25:21.712515", "modified_by": "Administrator", "module": "Selling", "name": "Sales Order Item", diff --git a/erpnext/stock/get_item_details.py b/erpnext/stock/get_item_details.py index 8f47ebc68b..0c5f7c7eae 100644 --- a/erpnext/stock/get_item_details.py +++ b/erpnext/stock/get_item_details.py @@ -30,8 +30,7 @@ def get_item_details(args): "is_subcontracted": "Yes" / "No", "transaction_type": "selling", "ignore_pricing_rule": 0/1 - "project_name": "", - "default_supplier":"" + "project_name": "" } """ args = process_args(args)