소스 검색

Initial Commit

master
mb 1 년 전
커밋
7449337c3a
20개의 변경된 파일582개의 추가작업 그리고 0개의 파일을 삭제
  1. +7
    -0
      .gitignore
  2. +8
    -0
      .idea/.gitignore
  3. +8
    -0
      .idea/invoice_sync.iml
  4. +8
    -0
      .idea/modules.xml
  5. +19
    -0
      .idea/php.xml
  6. +6
    -0
      .idea/vcs.xml
  7. +1
    -0
      README.md
  8. +3
    -0
      invoice_sync/__init__.py
  9. +0
    -0
      invoice_sync/config/__init__.py
  10. +221
    -0
      invoice_sync/hooks.py
  11. +0
    -0
      invoice_sync/invoice_sync/__init__.py
  12. +253
    -0
      invoice_sync/invoice_sync/invoice.py
  13. +1
    -0
      invoice_sync/modules.txt
  14. +6
    -0
      invoice_sync/patches.txt
  15. +0
    -0
      invoice_sync/public/.gitkeep
  16. +0
    -0
      invoice_sync/templates/__init__.py
  17. +0
    -0
      invoice_sync/templates/pages/__init__.py
  18. +0
    -0
      invoice_sync/www/__init__.py
  19. +21
    -0
      license.txt
  20. +20
    -0
      pyproject.toml

+ 7
- 0
.gitignore 파일 보기

@@ -0,0 +1,7 @@
.DS_Store
*.pyc
*.egg-info
*.swp
tags
node_modules
__pycache__

+ 8
- 0
.idea/.gitignore 파일 보기

@@ -0,0 +1,8 @@
# Default ignored files
/shelf/
/workspace.xml
# Editor-based HTTP Client requests
/httpRequests/
# Datasource local storage ignored files
/dataSources/
/dataSources.local.xml

+ 8
- 0
.idea/invoice_sync.iml 파일 보기

@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="WEB_MODULE" version="4">
<component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$" />
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>

+ 8
- 0
.idea/modules.xml 파일 보기

@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/invoice_sync.iml" filepath="$PROJECT_DIR$/.idea/invoice_sync.iml" />
</modules>
</component>
</project>

+ 19
- 0
.idea/php.xml 파일 보기

@@ -0,0 +1,19 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="MessDetectorOptionsConfiguration">
<option name="transferred" value="true" />
</component>
<component name="PHPCSFixerOptionsConfiguration">
<option name="transferred" value="true" />
</component>
<component name="PHPCodeSnifferOptionsConfiguration">
<option name="highlightLevel" value="WARNING" />
<option name="transferred" value="true" />
</component>
<component name="PhpStanOptionsConfiguration">
<option name="transferred" value="true" />
</component>
<component name="PsalmOptionsConfiguration">
<option name="transferred" value="true" />
</component>
</project>

+ 6
- 0
.idea/vcs.xml 파일 보기

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
</component>
</project>

+ 1
- 0
README.md 파일 보기

@@ -0,0 +1 @@
Invoice Sync

+ 3
- 0
invoice_sync/__init__.py 파일 보기

@@ -0,0 +1,3 @@

__version__ = '0.0.1'


+ 0
- 0
invoice_sync/config/__init__.py 파일 보기


+ 221
- 0
invoice_sync/hooks.py 파일 보기

@@ -0,0 +1,221 @@
app_name = "invoice_sync"
app_title = "Invoice Sync"
app_publisher = "SolutionERP"
app_description = "Syncing invoice with mobile app"
app_email = "support@solutionerp.com"
app_license = "mit"
# required_apps = []

# Includes in <head>
# ------------------

# include js, css files in header of desk.html
# app_include_css = "/assets/invoice_sync/css/invoice_sync.css"
# app_include_js = "/assets/invoice_sync/js/invoice_sync.js"

# include js, css files in header of web template
# web_include_css = "/assets/invoice_sync/css/invoice_sync.css"
# web_include_js = "/assets/invoice_sync/js/invoice_sync.js"

# include custom scss in every website theme (without file extension ".scss")
# website_theme_scss = "invoice_sync/public/scss/website"

# include js, css files in header of web form
# webform_include_js = {"doctype": "public/js/doctype.js"}
# webform_include_css = {"doctype": "public/css/doctype.css"}

# include js in page
# page_js = {"page" : "public/js/file.js"}

# include js in doctype views
# doctype_js = {"doctype" : "public/js/doctype.js"}
# doctype_list_js = {"doctype" : "public/js/doctype_list.js"}
# doctype_tree_js = {"doctype" : "public/js/doctype_tree.js"}
# doctype_calendar_js = {"doctype" : "public/js/doctype_calendar.js"}

# Svg Icons
# ------------------
# include app icons in desk
# app_include_icons = "invoice_sync/public/icons.svg"

# Home Pages
# ----------

# application home page (will override Website Settings)
# home_page = "login"

# website user home page (by Role)
# role_home_page = {
# "Role": "home_page"
# }

# Generators
# ----------

# automatically create page for each record of this doctype
# website_generators = ["Web Page"]

# Jinja
# ----------

# add methods and filters to jinja environment
# jinja = {
# "methods": "invoice_sync.utils.jinja_methods",
# "filters": "invoice_sync.utils.jinja_filters"
# }

# Installation
# ------------

# before_install = "invoice_sync.install.before_install"
# after_install = "invoice_sync.install.after_install"

# Uninstallation
# ------------

# before_uninstall = "invoice_sync.uninstall.before_uninstall"
# after_uninstall = "invoice_sync.uninstall.after_uninstall"

# Integration Setup
# ------------------
# To set up dependencies/integrations with other apps
# Name of the app being installed is passed as an argument

# before_app_install = "invoice_sync.utils.before_app_install"
# after_app_install = "invoice_sync.utils.after_app_install"

# Integration Cleanup
# -------------------
# To clean up dependencies/integrations with other apps
# Name of the app being uninstalled is passed as an argument

# before_app_uninstall = "invoice_sync.utils.before_app_uninstall"
# after_app_uninstall = "invoice_sync.utils.after_app_uninstall"

# Desk Notifications
# ------------------
# See xhiveframework.core.notifications.get_notification_config

# notification_config = "invoice_sync.notifications.get_notification_config"

# Permissions
# -----------
# Permissions evaluated in scripted ways

# permission_query_conditions = {
# "Event": "xhiveframework.desk.doctype.event.event.get_permission_query_conditions",
# }
#
# has_permission = {
# "Event": "xhiveframework.desk.doctype.event.event.has_permission",
# }

# DocType Class
# ---------------
# Override standard doctype classes

# override_doctype_class = {
# "ToDo": "custom_app.overrides.CustomToDo"
# }

# Document Events
# ---------------
# Hook on document methods and events

# doc_events = {
# "*": {
# "on_update": "method",
# "on_cancel": "method",
# "on_trash": "method"
# }
# }

# Scheduled Tasks
# ---------------

# scheduler_events = {
# "all": [
# "invoice_sync.tasks.all"
# ],
# "daily": [
# "invoice_sync.tasks.daily"
# ],
# "hourly": [
# "invoice_sync.tasks.hourly"
# ],
# "weekly": [
# "invoice_sync.tasks.weekly"
# ],
# "monthly": [
# "invoice_sync.tasks.monthly"
# ],
# }

# Testing
# -------

# before_tests = "invoice_sync.install.before_tests"

# Overriding Methods
# ------------------------------
#
# override_whitelisted_methods = {
# "xhiveframework.desk.doctype.event.event.get_events": "invoice_sync.event.get_events"
# }
#
# each overriding function accepts a `data` argument;
# generated from the base implementation of the doctype dashboard,
# along with any modifications made in other Xhive apps
# override_doctype_dashboards = {
# "Task": "invoice_sync.task.get_dashboard_data"
# }

# exempt linked doctypes from being automatically cancelled
#
# auto_cancel_exempted_doctypes = ["Auto Repeat"]

# Ignore links to specified DocTypes when deleting documents
# -----------------------------------------------------------

# ignore_links_on_delete = ["Communication", "ToDo"]

# Request Events
# ----------------
# before_request = ["invoice_sync.utils.before_request"]
# after_request = ["invoice_sync.utils.after_request"]

# Job Events
# ----------
# before_job = ["invoice_sync.utils.before_job"]
# after_job = ["invoice_sync.utils.after_job"]

# User Data Protection
# --------------------

# user_data_fields = [
# {
# "doctype": "{doctype_1}",
# "filter_by": "{filter_by}",
# "redact_fields": ["{field_1}", "{field_2}"],
# "partial": 1,
# },
# {
# "doctype": "{doctype_2}",
# "filter_by": "{filter_by}",
# "partial": 1,
# },
# {
# "doctype": "{doctype_3}",
# "strict": False,
# },
# {
# "doctype": "{doctype_4}"
# }
# ]

# Authentication and authorization
# --------------------------------

# auth_hooks = [
# "invoice_sync.auth.validate"
# ]

+ 0
- 0
invoice_sync/invoice_sync/__init__.py 파일 보기


+ 253
- 0
invoice_sync/invoice_sync/invoice.py 파일 보기

@@ -0,0 +1,253 @@
import requests
import json
import xhiveframework
import json
import urllib.parse;
import base64
from werkzeug.wrappers import Response


@xhiveframework.whitelist(allow_guest=True)
def generate_token_secure( api_key, api_secret, app_key):


try:
try:
app_key = base64.b64decode(app_key).decode("utf-8")
except Exception as e:
return Response(json.dumps({"message": "Security Parameters are not valid" , "user_count": 0}), status=401, mimetype='application/json')
clientID, clientSecret, clientUser = xhiveframework.db.get_value('OAuth Client', {'app_name': app_key}, ['client_id', 'client_secret','user'])

if clientID is None:
# return app_key
return Response(json.dumps({"message": "Security Parameters are not valid" , "user_count": 0}), status=401, mimetype='application/json')

client_id = clientID # Replace with your OAuth client ID
client_secret = clientSecret # Replace with your OAuth client secret
url = xhiveframework.local.conf.host_name + "/api/method/xhiveframework.integrations.oauth2.get_token"
payload = {
"username": api_key,
"password": api_secret,
"grant_type": "password",
"client_id": client_id,
"client_secret": client_secret,

}
files = []
headers = {"Content-Type": "application/json"}
response = requests.request("POST", url, data=payload, files=files)
if response.status_code == 200:
result_data = json.loads(response.text)
return Response(json.dumps({"data":result_data}), status=200, mimetype='application/json')


else:

xhiveframework.local.response.http_status_code = 401
return json.loads(response.text)


except Exception as e:


return Response(json.dumps({"message": e , "user_count": 0}), status=500, mimetype='application/json')






@xhiveframework.whitelist(allow_guest=True)
def create_refresh_token(refresh_token):
url = xhiveframework.local.conf.host_name + "/api/method/xhiveframework.integrations.oauth2.get_token"
payload = f'grant_type=refresh_token&refresh_token={refresh_token}'
headers = {
'Content-Type': 'application/x-www-form-urlencoded'
}
files = []

response = requests.post(url, headers=headers, data=payload, files=files)


if response.status_code == 200:
try:

message_json = json.loads(response.text)


new_message = {
"access_token": message_json["access_token"],
"expires_in": message_json["expires_in"],
"token_type": message_json["token_type"],
"scope": message_json["scope"],
"refresh_token": message_json["refresh_token"]
}


return Response(json.dumps({"data": new_message}), status=200, mimetype='application/json')
except json.JSONDecodeError as e:
return Response(json.dumps({"data": f"Error decoding JSON: {e}"}), status=401, mimetype='application/json')
else:

return Response(json.dumps({"data": response.text}), status=401, mimetype='application/json')





@xhiveframework.whitelist()
def customer(customer, customer_type, phone, email,is_supplier=False):
response_content =xhiveframework.session.user
is_supplier = is_supplier.lower() in ['true', '1', 'yes'] if isinstance(is_supplier, str) else bool(is_supplier)

if not is_supplier:

email_result = []


if email is not None:
email_result = xhiveframework.get_all("Customer", fields=["name as id", "customer_name", "customer_type", "mobile_no", "custom_email as email"],
filters={'custom_email': ['like', email]})

if not email_result:
customer_doc = xhiveframework.get_doc({
"doctype": "Customer",
"customer_name": customer,
"customer_type": customer_type,
"mobile_no": phone,
"custom_email": email,

})

customer_doc.insert(ignore_permissions=True)
customer_doc.save()

details = xhiveframework.get_all("Customer", fields=["name as id", "customer_name", "customer_type", "mobile_no", "custom_email as email",],
filters={'name': ['like', customer_doc.name]})

data = {
"message": "Customer created successfully.",
"Details": details,
}


return Response(json.dumps({"data":data}), status=200, mimetype='application/json')


else:
data = {
"message": "Customer already exists",
"Details": email_result
}


return Response(json.dumps({"data":data}), status=200, mimetype='application/json')

else:
suplr_already_exist=xhiveframework.get_all("Supplier", fields=["name as id", "supplier_name", "custom_email as email", "custom_mobileno as phone"],
filters={'name': ['like',customer]})
details={
"message":"Already exists",
"Details":suplr_already_exist
}
if suplr_already_exist:
return Response(json.dumps({"data":details }), status=409, mimetype='application/json')
supplier_doc = xhiveframework.get_doc({
"doctype": "Supplier",
"supplier_name": customer,
"custom_mobileno": phone,
"custom_email": email,
})
supplier_doc.insert(ignore_permissions=True)

supplier_details = xhiveframework.get_all("Supplier", fields=["name as id", "supplier_name", "custom_email as email", "custom_mobileno as phone"],
filters={'name': ['like', supplier_doc.name]})
suplr={
"Details":supplier_details
}
return Response(json.dumps({"data":suplr}), status=200, mimetype='application/json')






@xhiveframework.whitelist()
def create_invoice(customer_id, supplier_id, payment_method, items):
invoice_items = []

for item in items:
item_code = item["item_name"]

item_exists = xhiveframework.get_value("Item", {"name": item_code}, "name")

if not item_exists:
invoice_item = {
"item_name": item_code,
"qty": item.get("quantity", 0),
"rate": item.get("rate", 0),
"uom": item.get("uom", "Nos"),
"income_account": item.get("income_account", "Sales - erp")
}
else:
invoice_item = {
"item_code": item_code,
"qty": item.get("quantity", 0),
"rate": item.get("rate", 0),

}

invoice_items.append(invoice_item)

new_invoice = xhiveframework.get_doc({
"doctype": "Sales Invoice",
"customer": customer_id,
"custom_supplier_id": supplier_id,
"custom_payment_method": payment_method,
"items": invoice_items
})

new_invoice.insert(ignore_permissions=True)
new_invoice.save()
iitem = xhiveframework.get_doc("Sales Invoice", new_invoice.name)

attribute_dict = []
for attribute in iitem.items:
attribute_data = {
"item_name": attribute.item_name,
"item_code": attribute.item_code,
"quantity": attribute.qty,
"rate": attribute.rate,
"uom": attribute.uom,
"income_account": attribute.income_account
}
attribute_dict.append(attribute_data)

customer_info = {
"id": new_invoice.name,
"customer_id": new_invoice.customer,
"customer_name": new_invoice.customer_name,
"supplier_id": new_invoice.custom_supplier_id,
"payment_method": new_invoice.custom_payment_method,
"total_quantity": new_invoice.total_qty,
"total": new_invoice.total,
"grand_total": new_invoice.grand_total,
"items": attribute_dict
}

return Response(json.dumps({"data":customer_info}), status=200, mimetype='application/json')





@xhiveframework.whitelist()
def customer1(customer, phone, email, is_supplier=False, user_id=None):
try:
return "hello"

except xhiveframework.exceptions.PermissionError as e:
return Response(json.dumps({"message": "Permission error"}), status=401, mimetype='application/json')
except Exception as e:
# Handle other exceptions if needed
return Response(json.dumps({"message": str(e)}), status=500, mimetype='application/json')

+ 1
- 0
invoice_sync/modules.txt 파일 보기

@@ -0,0 +1 @@
Invoice Sync

+ 6
- 0
invoice_sync/patches.txt 파일 보기

@@ -0,0 +1,6 @@
[pre_model_sync]
# Patches added in this section will be executed before doctypes are migrated
# Read docs to understand patches: https://xhiveframework.com/docs/v14/user/en/database-migrations

[post_model_sync]
# Patches added in this section will be executed after doctypes are migrated

+ 0
- 0
invoice_sync/public/.gitkeep 파일 보기


+ 0
- 0
invoice_sync/templates/__init__.py 파일 보기


+ 0
- 0
invoice_sync/templates/pages/__init__.py 파일 보기


+ 0
- 0
invoice_sync/www/__init__.py 파일 보기


+ 21
- 0
license.txt 파일 보기

@@ -0,0 +1,21 @@
MIT License

Copyright (c) [year] [fullname]

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

+ 20
- 0
pyproject.toml 파일 보기

@@ -0,0 +1,20 @@
[project]
name = "invoice_sync"
authors = [
{ name = "SolutionERP", email = "support@solutionerp.com"}
]
description = "Syncing invoice with mobile app"
requires-python = ">=3.10"
readme = "README.md"
dynamic = ["version"]
dependencies = [
# "xhiveframework~=15.0.0" # Installed and managed by bench.
]

[build-system]
requires = ["flit_core >=3.4,<4"]
build-backend = "flit_core.buildapi"

# These dependencies are only installed when developer mode is enabled
[tool.bench.dev-dependencies]
# package_name = "~=1.1.0"

불러오는 중...
취소
저장