Skip to content

Commit

Permalink
feat: (Uni-commerce) generate Delivery Note and sync item fields (fra…
Browse files Browse the repository at this point in the history
…ppe#239)

Squashed commit of the following:

commit b3bf98d
Merge: 13928e9 fa461c8
Author: Ankush Menat <[email protected]>
Date:   Mon Jun 5 13:09:31 2023 +0530

    Merge branch 'develop' into dev-fix

commit 13928e9
Author: Vikas8600 <[email protected]>
Date:   Sat May 13 06:15:59 2023 +0530

    fix: pre-commit

commit 1eba131
Author: Ankush Menat <[email protected]>
Date:   Fri May 12 14:28:49 2023 +0530

    chore: format and trigger tests

    Commiting this myself to allow workflows to run (first contribution
    restriction)

commit c284ac7
Author: Vikas8600 <[email protected]>
Date:   Fri May 12 14:05:48 2023 +0530

    fix: reformatted

commit 5fd6611
Author: Vikas8600 <[email protected]>
Date:   Fri May 12 14:04:24 2023 +0530

    fix: pre-commit

commit 708bbf2
Author: Vikas8600 <[email protected]>
Date:   Fri May 12 14:03:40 2023 +0530

    fix: pre-commit

commit 511fdc6
Author: Vikas8600 <[email protected]>
Date:   Thu May 11 23:31:18 2023 +0530

    fixed

commit a80582d
Author: Vikas8600 <[email protected]>
Date:   Thu May 11 23:24:48 2023 +0530

    fix: test cases added

commit 31cfa60
Author: Vikas8600 <[email protected]>
Date:   Thu May 4 21:30:08 2023 +0530

    fix: log statement

commit 28568c5
Author: Vikas8600 <[email protected]>
Date:   Tue May 2 17:38:23 2023 +0530

    fix: item changes

commit 770e3a4
Author: Vikas8600 <[email protected]>
Date:   Tue May 2 17:28:02 2023 +0530

    Delete ci2.yml

commit 70dcc4a
Author: Vikas8600 <[email protected]>
Date:   Tue May 2 17:23:29 2023 +0530

    Update and rename dev_fix.yml to ci2.yml

commit 9ae78a6
Author: Vikas8600 <[email protected]>
Date:   Tue May 2 17:21:17 2023 +0530

    Update dev_fix.yml

commit 3dafd10
Author: Vikas8600 <[email protected]>
Date:   Tue May 2 17:19:54 2023 +0530

    Create dev_fix.yml

commit bae33f3
Author: Vikas8600 <[email protected]>
Date:   Tue May 2 17:00:40 2023 +0530

    Update ci.yml

commit be20d74
Author: Vikas8600 <[email protected]>
Date:   Tue May 2 16:04:47 2023 +0530

    fix: code changes

commit 4b24fa6
Author: Vikas8600 <[email protected]>
Date:   Tue May 2 15:32:30 2023 +0530

    Update ci.yml

commit a277f33
Author: Vikas8600 <[email protected]>
Date:   Tue May 2 15:17:20 2023 +0530

    Update ci.yml

commit 82e688c
Author: Vikas8600 <[email protected]>
Date:   Tue May 2 13:14:35 2023 +0530

    fix: code changes

commit e9a46d4
Author: Vikas8600 <[email protected]>
Date:   Tue May 2 10:49:58 2023 +0530

    feat: delivery note feature

commit 0b4d68c
Author: Vikas8600 <[email protected]>
Date:   Tue May 2 10:32:14 2023 +0530

    fix: code changes

commit a2be0f8
Author: Vikas8600 <[email protected]>
Date:   Mon May 1 22:38:16 2023 +0530

    fix: test product

commit db7982d
Author: Vikas8600 <[email protected]>
Date:   Mon May 1 20:29:42 2023 +0530

    Update product-MC-100.json

commit eb5c82e
Author: Vikas8600 <[email protected]>
Date:   Mon May 1 20:27:54 2023 +0530

    Update product-MC-100.json

commit 1e2071c
Author: Vikas8600 <[email protected]>
Date:   Mon May 1 19:39:59 2023 +0530

    Update delivery_note.py

commit 087f02a
Author: Vikas8600 <[email protected]>
Date:   Mon May 1 19:38:45 2023 +0530

    Update ci.yml

commit 40adea6
Author: Vikas8600 <[email protected]>
Date:   Mon May 1 15:10:30 2023 +0530

    fix: sales invoice getting skip

commit d56d55e
Author: Vikas8600 <[email protected]>
Date:   Fri Apr 28 15:39:31 2023 +0530

    fix: code related changes

commit ec99301
Author: Vikas8600 <[email protected]>
Date:   Fri Apr 28 15:37:11 2023 +0530

    fix: code related changes

commit f7ecd88
Author: Ankush Menat <[email protected]>
Date:   Wed Apr 26 11:34:30 2023 +0530

    chore: format

commit ea407d9
Author: Vikas8600 <[email protected]>
Date:   Fri Apr 21 17:53:38 2023 +0530

    fix: debit to account

commit 901fe14
Author: Vikas8600 <[email protected]>
Date:   Fri Apr 21 14:17:56 2023 +0530

    fix: remove html tag from Description

commit d3155d3
Author: Vikas8600 <[email protected]>
Date:   Thu Apr 20 19:32:01 2023 +0530

    fix: address gst category

commit 79be001
Author: Vikas8600 <[email protected]>
Date:   Wed Apr 19 15:36:36 2023 +0530

    fix: remove unuse code

commit ef11120
Author: Vikas8600 <[email protected]>
Date:   Wed Apr 19 15:05:44 2023 +0530

    feat: Delivery Note button

commit 22b7b6e
Author: Vikas8600 <[email protected]>
Date:   Wed Apr 19 13:03:15 2023 +0530

    fix: logger

commit 67ce869
Author: Vikas8600 <[email protected]>
Date:   Wed Apr 19 12:55:05 2023 +0530

    logger added

commit 533928e
Author: Vikas8600 <[email protected]>
Date:   Tue Apr 18 15:35:58 2023 +0530

    feat: item resync

commit deb9fdb
Author: Vikas8600 <[email protected]>
Date:   Mon Apr 17 11:45:06 2023 +0530

    feat: added valuation rate

commit 7f3fe72
Author: Vikas8600 <[email protected]>
Date:   Sun Apr 16 10:38:31 2023 +0530

    fix: item stock

commit 7b5e733
Author: Vikas8600 <[email protected]>
Date:   Fri Apr 14 22:12:09 2023 +0530

    fixed

commit c71c886
Author: Vikas8600 <[email protected]>
Date:   Fri Apr 14 21:33:14 2023 +0530

    fixed

commit 5813d32
Author: Vikas8600 <[email protected]>
Date:   Fri Apr 14 19:17:05 2023 +0530

    fixed

commit 8c39727
Author: Vikas8600 <[email protected]>
Date:   Fri Apr 14 16:50:18 2023 +0530

    fix: hcn_code

commit 5a1d22d
Author: Vikas8600 <[email protected]>
Date:   Fri Apr 14 16:33:01 2023 +0530

    feat: taxTempType

commit e7d42f5
Author: Vikas8600 <[email protected]>
Date:   Fri Apr 14 14:23:44 2023 +0530

    fix: item warehouse

commit 07b8c19
Author: Vikas8600 <[email protected]>
Date:   Wed Apr 12 14:00:14 2023 +0530

    fix:  delivery note

commit a9a73f9
Author: Vikas8600 <[email protected]>
Date:   Wed Apr 12 12:48:37 2023 +0530

    fix: param

commit 0d288e7
Author: Vikas8600 <[email protected]>
Date:   Wed Apr 12 12:42:45 2023 +0530

    fix: param added

commit 0e18d3c
Author: Vikas8600 <[email protected]>
Date:   Wed Apr 12 12:01:20 2023 +0530

    feat: custome fields

commit bd24b34
Author: Vikas8600 <[email protected]>
Date:   Wed Apr 12 11:21:30 2023 +0530

    feat: delivery note

commit 8f9e140
Author: Vikas8600 <[email protected]>
Date:   Thu Apr 6 22:21:19 2023 +0530

    fix: sales invoice

commit f705164
Author: Vikas8600 <[email protected]>
Date:   Thu Apr 6 17:41:42 2023 +0530

    fix: sales invoice

commit a5c0693
Author: Vikas860086 <[email protected]>
Date:   Thu Apr 6 14:38:14 2023 +0530

    fix: sales invoice and item fields

Co-authored-by: Ankush Menat <[email protected]>
  • Loading branch information
Vikas8600 and ankush authored Jun 5, 2023
1 parent b59324f commit f474301
Show file tree
Hide file tree
Showing 9 changed files with 230 additions and 13 deletions.
1 change: 1 addition & 0 deletions ecommerce_integrations/hooks.py
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,7 @@
"*/5 * * * *": [
"ecommerce_integrations.unicommerce.order.sync_new_orders",
"ecommerce_integrations.unicommerce.inventory.update_inventory_on_unicommerce",
"ecommerce_integrations.unicommerce.delivery_note.prepare_delivery_note",
],
},
}
Expand Down
1 change: 1 addition & 0 deletions ecommerce_integrations/unicommerce/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
SHIPPING_PACKAGE_STATUS_FIELD = "unicommerce_shipping_package_status"
IS_COD_CHECKBOX = "unicommerce_is_cod"
SHIPPING_METHOD_FIELD = "unicommerce_shipping_method"
UNICOMMERCE_SHIPPING_ID = "unicommerce_shipment_id"
PICKLIST_ORDER_DETAILS_FIELD = "order_details"

GRN_STOCK_ENTRY_TYPE = "GRN on Unicommerce"
Expand Down
99 changes: 99 additions & 0 deletions ecommerce_integrations/unicommerce/delivery_note.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
import frappe

from ecommerce_integrations.unicommerce.api_client import UnicommerceAPIClient
from ecommerce_integrations.unicommerce.constants import ORDER_CODE_FIELD, SETTINGS_DOCTYPE
from ecommerce_integrations.unicommerce.utils import create_unicommerce_log


@frappe.whitelist()
def prepare_delivery_note():
try:
settings = frappe.get_cached_doc(SETTINGS_DOCTYPE)
if not settings.delivery_note:
return

client = UnicommerceAPIClient()

days_to_sync = min(settings.get("order_status_days") or 2, 14)
minutes = days_to_sync * 24 * 60

# find all Facilities
enabled_facilities = list(settings.get_integration_to_erpnext_wh_mapping().keys())
enabled_channels = frappe.db.get_list(
"Unicommerce Channel", filters={"enabled": 1}, pluck="channel_id"
)

for facility in enabled_facilities:
updated_packages = client.search_shipping_packages(
updated_since=minutes, facility_code=facility
)
valid_packages = [p for p in updated_packages if p.get("channel") in enabled_channels]
if not valid_packages:
continue
shipped_packages = [p for p in valid_packages if p["status"] in ["DISPATCHED"]]
for order in shipped_packages:
if not frappe.db.exists(
"Delivery Note", {"unicommerce_shipment_id": order["code"]}, "name"
) and frappe.db.exists("Sales Order", {ORDER_CODE_FIELD: order["saleOrderCode"]}):
sales_order = frappe.get_doc("Sales Order", {ORDER_CODE_FIELD: order["saleOrderCode"]})
if frappe.db.exists(
"Sales Invoice", {"unicommerce_order_code": sales_order.unicommerce_order_code}
):
sales_invoice = frappe.get_doc(
"Sales Invoice", {"unicommerce_order_code": sales_order.unicommerce_order_code}
)
create_delivery_note(sales_order, sales_invoice)
except Exception as e:
create_unicommerce_log(status="Error", exception=e, rollback=True)


def create_delivery_note(so, sales_invoice):
try:
# Create the delivery note
from frappe.model.mapper import make_mapped_doc

res = make_mapped_doc(
method="erpnext.selling.doctype.sales_order.sales_order.make_delivery_note", source_name=so.name
)
res.update({"items": []})
for item in sales_invoice.items:
res.append(
"items",
{
"item_code": item.item_code,
"item_name": item.item_name,
"description": item.description,
"qty": item.qty,
"uom": item.uom,
"rate": item.rate,
"amount": item.amount,
"warehouse": item.warehouse,
"against_sales_order": item.sales_order,
"batch_no": item.batch_no,
"so_detail": item.so_detail,
},
)
for item in sales_invoice.taxes:
res.append(
"taxes",
{
"charge_type": item.charge_type,
"account_head": item.account_head,
"tax_amount": item.tax_amount,
"description": item.description,
"item_wise_tax_detail": item.item_wise_tax_detail,
"dont_recompute_tax": item.dont_recompute_tax,
},
)
res.unicommerce_order_code = sales_invoice.unicommerce_order_code
res.unicommerce_shipment_id = sales_invoice.unicommerce_shipping_package_code
res.save()
res.submit()
log = create_unicommerce_log(method="create_delevery_note", make_new=True)
frappe.flags.request_id = log.name
except Exception as e:
create_unicommerce_log(status="Error", exception=e, rollback=True)
else:
create_unicommerce_log(status="Success")
frappe.flags.request_id = None
return res
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@
"sales_order_series",
"sales_invoice_series",
"order_status_days",
"delivery_note_settings_section",
"delivery_note",
"inventory_sync_settings_section",
"enable_inventory_sync",
"inventory_sync_frequency",
Expand Down Expand Up @@ -249,12 +251,23 @@
"fieldname": "vendor_code",
"fieldtype": "Data",
"label": "Vendor Code"
},
{
"fieldname": "delivery_note_settings_section",
"fieldtype": "Section Break",
"label": "Delivery Note Settings"
},
{
"default": "0",
"fieldname": "delivery_note",
"fieldtype": "Check",
"label": "Import Delivery Notes from Unicommerce on Shipment"
}
],
"index_web_pages_for_search": 1,
"issingle": 1,
"links": [],
"modified": "2022-02-07 14:11:34.599710",
"modified": "2023-05-02 14:04:26.684256",
"modified_by": "Administrator",
"module": "unicommerce",
"name": "Unicommerce Settings",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
SHIPPING_PACKAGE_STATUS_FIELD,
SHIPPING_PROVIDER_CODE,
TRACKING_CODE_FIELD,
UNICOMMERCE_SHIPPING_ID,
)
from ecommerce_integrations.unicommerce.utils import create_unicommerce_log

Expand Down Expand Up @@ -202,6 +203,15 @@ def setup_custom_fields(update=True):
collapsible=1,
),
],
"Delivery Note": [
dict(
fieldname="unicommerce_section",
label="Unicommerce Details",
fieldtype="Section Break",
insert_after="instructions",
collapsible=1,
),
],
}

custom_fields = {
Expand Down Expand Up @@ -429,6 +439,22 @@ def setup_custom_fields(update=True):
read_only=1,
),
],
"Delivery Note": [
dict(
fieldname=ORDER_CODE_FIELD,
label="Unicommerce Order No",
fieldtype="Data",
insert_after="unicommerce_section",
read_only=1,
),
dict(
fieldname=UNICOMMERCE_SHIPPING_ID,
label="Unicommerce Shipment Id",
fieldtype="Data",
insert_after=ORDER_CODE_FIELD,
read_only=1,
),
],
"Pick List": [
dict(
fieldname=PICKLIST_ORDER_DETAILS_FIELD,
Expand Down
2 changes: 1 addition & 1 deletion ecommerce_integrations/unicommerce/invoice.py
Original file line number Diff line number Diff line change
Expand Up @@ -381,7 +381,7 @@ def create_sales_invoice(
si.naming_series = channel_config.sales_invoice_series or settings.sales_invoice_series
si.delivery_date = so.delivery_date
si.ignore_pricing_rule = 1
si.update_stock = update_stock
si.update_stock = False if settings.delivery_note else update_stock
si.flags.raw_data = si_data
si.insert()

Expand Down
29 changes: 18 additions & 11 deletions ecommerce_integrations/unicommerce/order.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
CHANNEL_ID_FIELD,
CHANNEL_TAX_ACCOUNT_FIELD_MAP,
FACILITY_CODE_FIELD,
INVOICE_CODE_FIELD,
IS_COD_CHECKBOX,
MODULE_NAME,
ORDER_CODE_FIELD,
Expand Down Expand Up @@ -78,9 +79,8 @@ def _get_new_orders(
for order in uni_orders:
if order["channel"] not in configured_channels:
continue
if frappe.db.exists("Sales Order", {ORDER_CODE_FIELD: order["code"]}):
continue

# In case a sales invoice is not generated for some reason and is skipped, we need to create it manually. Therefore, I have commented out this line of code.
order = client.get_sales_order(order_code=order["code"])
if order:
yield order
Expand All @@ -95,12 +95,19 @@ def _create_sales_invoices(unicommerce_order, sales_order, client: UnicommerceAP
shipping_packages = unicommerce_order["shippingPackages"]
for package in shipping_packages:
try:
log = create_unicommerce_log(method="create_sales_invoice", make_new=True)
frappe.flags.request_id = log.name

# This code was added because the log statement below was being executed every time.
invoice_data = client.get_sales_invoice(
shipping_package_code=package["code"], facility_code=facility_code
)
existing_si = frappe.db.get_value(
"Sales Invoice", {INVOICE_CODE_FIELD: invoice_data["invoice"]["code"]}
)
if existing_si:
continue

log = create_unicommerce_log(method="create_sales_invoice", make_new=True)
frappe.flags.request_id = log.name

warehouse_allocations = _get_warehouse_allocations(sales_order)
create_sales_invoice(
invoice_data["invoice"],
Expand All @@ -121,18 +128,18 @@ def create_order(payload: UnicommerceOrder, request_id: Optional[str] = None, cl

order = payload

existing_so = frappe.db.get_value("Sales Order", {ORDER_CODE_FIELD: order["code"]})
if existing_so:
so = frappe.get_doc("Sales Order", existing_so)
return so

# If a sales order already exists, then every time it's executed
if request_id is None:
log = create_unicommerce_log(
method="ecommerce_integrations.unicommerce.order.create_order", request_data=payload
)
request_id = log.name

existing_so = frappe.db.get_value("Sales Order", {ORDER_CODE_FIELD: order["code"]})
if existing_so:
so = frappe.get_doc("Sales Order", existing_so)
create_unicommerce_log(status="Invalid", message="Sales Order already exists, skipped")
return so

if client is None:
client = UnicommerceAPIClient()

Expand Down
5 changes: 5 additions & 0 deletions ecommerce_integrations/unicommerce/product.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@
"width": ITEM_WIDTH_FIELD,
"height": ITEM_HEIGHT_FIELD,
"batchGroupCode": ITEM_BATCH_GROUP_FIELD,
"maxRetailPrice": "standard_rate",
"costPrice": "valuation_rate",
}

ERPNEXT_TO_UNI_ITEM_MAPPING = {v: k for k, v in UNI_TO_ERPNEXT_ITEM_MAPPING.items()}
Expand Down Expand Up @@ -287,6 +289,9 @@ def _build_unicommerce_item(item_code: ItemCode) -> JsonDict:
)
# append site prefix to image url
item_json["imageUrl"] = get_url(item.image)
item_json["maxRetailPrice"] = item.standard_rate
item_json["description"] = frappe.utils.strip_html_tags(item.description)
item_json["costPrice"] = item.valuation_rate

return item_json

Expand Down
65 changes: 65 additions & 0 deletions ecommerce_integrations/unicommerce/tests/test_delivery_note.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
import base64
import unittest

import frappe
import responses
from erpnext.stock.doctype.stock_entry.stock_entry_utils import make_stock_entry

from ecommerce_integrations.unicommerce.constants import (
FACILITY_CODE_FIELD,
INVOICE_CODE_FIELD,
ORDER_CODE_FIELD,
SHIPPING_PACKAGE_CODE_FIELD,
)
from ecommerce_integrations.unicommerce.delivery_note import create_delivery_note
from ecommerce_integrations.unicommerce.invoice import bulk_generate_invoices, create_sales_invoice
from ecommerce_integrations.unicommerce.order import create_order
from ecommerce_integrations.unicommerce.tests.test_client import TestCaseApiClient


class TestDeliveryNote(TestCaseApiClient):
@classmethod
def setUpClass(cls):
super().setUpClass()

def test_create_invoice_and_delivery_note(self):
"""Use mocked invoice json to create and assert synced fields"""
from ecommerce_integrations.unicommerce import invoice

# HACK to allow invoicing test
invoice.INVOICED_STATE.append("CREATED")
self.responses.add(
responses.POST,
"https://demostaging.unicommerce.com/services/rest/v1/oms/shippingPackage/createInvoiceAndAllocateShippingProvider",
status=200,
json=self.load_fixture("create_invoice_and_assign_shipper"),
match=[responses.json_params_matcher({"shippingPackageCode": "TEST00949"})],
)
self.responses.add(
responses.POST,
"https://demostaging.unicommerce.com/services/rest/v1/invoice/details/get",
status=200,
json=self.load_fixture("invoice-SDU0026"),
match=[responses.json_params_matcher({"shippingPackageCode": "TEST00949", "return": False})],
)
self.responses.add(
responses.GET,
"https://example.com",
status=200,
body=base64.b64decode(self.load_fixture("invoice_label_response")["label"]),
)

order = self.load_fixture("order-SO5906")["saleOrderDTO"]
so = create_order(order, client=self.client)
make_stock_entry(item_code="MC-100", qty=15, to_warehouse="Stores - WP", rate=42)

bulk_generate_invoices(sales_orders=[so.name], client=self.client)

sales_invoice_code = frappe.db.get_value("Sales Invoice", {INVOICE_CODE_FIELD: "SDU0026"})

if not sales_invoice_code:
self.fail("Sales invoice not generated")

si = frappe.get_doc("Sales Invoice", sales_invoice_code)
dn = create_delivery_note(so, si)
self.assertEqual(dn.unicommerce_order_code, so.unicommerce_order_code)

0 comments on commit f474301

Please sign in to comment.