Compare commits

...

4 Commits

Author SHA1 Message Date
wilsongomez 3e4843ff88 minor fix 2022-03-11 17:06:47 -05:00
wilsongomez 964596aaa9 minor fix 2022-03-11 16:59:47 -05:00
wilsongomez 5fb2d539a1 minor fix 2022-03-11 12:31:31 -05:00
wilsongomez 573dc364bb minor fix 2022-03-11 11:52:27 -05:00
2 changed files with 790 additions and 5 deletions

View File

@ -438,7 +438,7 @@ def create_app(dbname):
if shop.get('freight_product'):
product_freight_id = shop['freight_product.']['id']
product_freight_price = shop['freight_product.']['temaplate.']['sale_price_w_tax']
product_freight_price = shop['freight_product.']['template.']['sale_price_w_tax']
new_shop = {
'id': shop['id'],
'name': shop['name'],
@ -591,7 +591,8 @@ def create_app(dbname):
@require_appkey
def add_sale():
data = json.loads(request.data.decode("utf-8"))
for k, v in data.items():
print(k, '---', v)
@tryton.transaction()
def _get_user():
User = _pool.get('res.user')
@ -615,15 +616,17 @@ def create_app(dbname):
Product = _pool.get('product.product')
for l in data['lines']:
product = Product(l['product'])
if not l.get('product') or l.get('product') == '':
continue
product = Product(int(l['product']))
template = product.template
taxes = [tax.id for tax in template.account_category.customer_taxes_used]
lines.append({
'product': l['product'],
'product': int(l['product']),
'description': template.name,
'unit_price': Decimal(l['list_price']),
'unit': template.default_uom.id,
'quantity': l['quantity'],
'quantity': int(l['quantity']),
'taxes': [('add', taxes)]
})
return lines

782
factory_org.py Normal file
View File

@ -0,0 +1,782 @@
import logging
import os
from decimal import Decimal
import simplejson as json
from datetime import datetime, date
from functools import wraps
import configparser
from pytz import timezone
from flask import Flask, request, abort, jsonify
from flask_tryton import Tryton
from flask.globals import current_app
from flask_cors import CORS
from tools import (
send, get_config, InvalidAPIUsage, CustomJSONEncoder
)
HOME_DIR = os.getenv('HOME')
default_dir = os.path.join(HOME_DIR, '.flask')
config_file = os.path.join(default_dir, 'escool.ini')
config = configparser.ConfigParser()
config.read(config_file)
trytond_config = get_config('trytond_config')
host_ = config.get('General', 'host')
API_KEY = config.get('Auth', 'api_key')
# The actual decorator function
def require_appkey(view_function):
@wraps(view_function)
# the new, post-decoration function. Note *args and **kwargs here.
def decorated_function(*args, **kwargs):
if request.headers.get('Authorization') and request.headers.get('Authorization') == API_KEY:
return view_function(*args, **kwargs)
else:
abort(401)
return decorated_function
def exec_(method):
try:
return method()
except Exception as e:
print('=' * 100)
print(f"Error in API transaction >> {e}")
print('=' * 100)
abort(500, description=f"Error in API transaction >> {e}")
def create_app(dbname):
app = Flask(dbname, instance_relative_config=False)
CORS(app)
app.app_context().push()
try:
with app.app_context():
current_app.json_encoder = CustomJSONEncoder
current_app.config['TRYTON_DATABASE'] = dbname
current_app.config['TRYTON_CONFIG'] = trytond_config
current_app.config['CORS_HEADERS'] = 'Content-Type'
tryton = Tryton(current_app)
_pool = tryton.pool
except:
logging.warning('Error database disabled or unknown error: %s' % dbname)
return None
@app.errorhandler(InvalidAPIUsage)
def invalid_api_usage(e):
return jsonify(e.to_dict())
@app.route('/')
@tryton.transaction()
def home():
Company = _pool.get('company.company')
company, = Company.search_read([
('id', '=', 1)
], fields_names=['party.name'])
msg = 'Hello welcome to %s' % company['party.name']
return send(msg)
@app.route("/countries/", methods=['GET'])
def countries():
@tryton.transaction()
def _method():
Country = _pool.get('party.country_code')
return Country.search_read([], fields_names=['name'])
return send(exec_(_method))
@app.route("/departments/", methods=['GET'])
@require_appkey
def departments():
@tryton.transaction()
def _method():
Department = _pool.get('party.department_code')
return Department.search_read([], fields_names=['name'])
return send(exec_(_method))
@app.route("/cities/<departmentId>", methods=['GET'])
def get_cities(departmentId):
@tryton.transaction()
def _method():
City = _pool.get('party.city_code')
return City.search_read([
('department', '=', int(departmentId))
], fields_names=['name', 'department'])
return send(exec_(_method))
@app.route("/parties", methods=['GET'])
@require_appkey
def get_parties():
@tryton.transaction()
def _method():
Party = _pool.get('party.party')
return Party.search_read(
[], fields_names=['name', 'id_number', 'email']
)
return send(exec_(_method))
@app.route("/party/<idNumber>", methods=['GET'])
@require_appkey
def get_party(idNumber):
@tryton.transaction()
def _method():
Party = _pool.get('party.party')
party, = Party.search_read([
('id_number', '=', idNumber),
], fields_names=['id', 'name', 'id_number', 'email']
)
return party
return send(exec_(_method))
@app.route("/payment_term", methods=['GET'])
@require_appkey
def get_payment_term():
@tryton.transaction()
def _method():
Payment = _pool.get('account.invoice.payment_term')
return Payment.search_read([], fields_names=['name'])
return send(exec_(_method))
@app.route("/search_party", methods=['POST'])
@require_appkey
def search_party():
data = json.loads(request.data.decode("utf-8"))
id_number = data['id_number']
@tryton.transaction()
def _method():
Party = _pool.get('party.party')
parties = Party.search_read([
('id_number', '=', id_number),
], fields_names=['name', 'id_number', 'email']
)
return parties[0] if parties else {}
return send(exec_(_method))
@app.route("/product_freight", methods=['GET'])
@require_appkey
def get_product_freight():
# ENDPOINT DEPRECATION WARNING
res = {
'msg': 'This enpoint is in deprecation, please use shops endpoint for get freight!',
'status': 'warning',
}
return send(res)
@app.route("/products_by_shop/<shopId>", methods=['GET'])
@require_appkey
def get_products_by_shop(shopId):
@tryton.transaction()
def _method():
Product = _pool.get('product.product')
Shop = _pool.get('sale.shop')
Category = _pool.get('product.category')
shop, = Shop.search_read([
('id', '=', shopId)
], fields_names=['product_categories'])
products = []
add_products = products.append
values = Product.search_read([
('account_category', 'in', shop['product_categories']),
('categories', '!=', None),
('active', '=', True),
], fields_names=[
'template', 'template.name', 'code', 'template.categories',
'template.sale_price_w_tax', 'template.list_price'
], order=[('code', 'ASC')]
)
for val in values:
template = val.get('template.', None)
if template and not template.get('sale_price_w_tax'):
continue
categories = Category.search_read([
('id', 'in', val['template.']['categories']),
], fields_names=['name', 'parent'])
add_products({
'id': val['id'],
'name': val['template.']['name'],
'code': val['code'],
'category': categories,
'sale_price': float(val['template.']['sale_price_w_tax']),
# 'sale_price': float(val['template.']['list_price']) if val['template.'].get('list_price') else 0,
'images': '',
})
return products
return send(exec_(_method))
@app.route("/categorized_products/<shopId>")
@require_appkey
def get_categorized_products(shopId):
@tryton.transaction()
def _set_ctx():
Shop = _pool.get('sale.shop')
shop = Shop(shopId)
locations_ids = [shop.warehouse.storage_location.id]
context = {
'locations': locations_ids,
'stock_date_end': date.today(),
}
return context
context = _set_ctx()
@tryton.transaction(context=context)
def _method():
Product = _pool.get('product.product')
Shop = _pool.get('sale.shop')
ListPrice = _pool.get('product.list_price')
Category = _pool.get('product.category')
shop, = Shop.search_read([('id', '=', shopId)],
fields_names=['product_categories'])
target_categories = {}
values = Product.search([
('account_category', 'in', shop['product_categories']),
('categories', '!=', None),
('active', '=', True),
], order=[('code', 'ASC')]
)
# fields_names=[
# 'id', 'template.name', 'code', 'template.categories',
# 'template.sale_price_w_tax', 'template', 'attributes'
# ],
prices = ListPrice.search_read([
('template', 'in', [v.template.id for v in values])
], fields_names=['template', 'list_price']
)
prices2product = {p['template']: p['list_price'] for p in prices}
for val in values:
template = val.template
product = {
'id': val.id,
'name': template.name,
'code': val.code,
'quantity': val.quantity,
'sale_price': float(round(prices2product[template.id], 2)),
# 'sale_price_w_tax': float(round(prices2product[template.id], 2)),
'sale_price_w_tax': float(round(template.sale_price_w_tax, 2)),
'attributes': val.attributes,
}
cat = val.template.categories[0]
try:
target_categories[cat]['products'].append(product)
except:
c = Category(cat)
target_categories[cat] = {
'id': c.id,
'images': [i.image for i in c.images],
'name': c.name,
'parent': c.parent.id if c.parent else None,
'products': [product]
}
return list(target_categories.values())
return send(exec_(_method))
@app.route("/products_shop_category/<shopId>/<categoryId>")
@require_appkey
def get_products_shop_category(shopId, categoryId):
@tryton.transaction()
def _set_ctx():
Shop = _pool.get('sale.shop')
shop = Shop(shopId)
locations_ids = [shop.warehouse.storage_location.id]
context = {
'locations': locations_ids,
'stock_date_end': date.today(),
}
return context
context = _set_ctx()
@tryton.transaction(context=context)
def _method():
Product = _pool.get('product.product')
ProductCategory = _pool.get('product.template-product.category')
ListPrice = _pool.get('product.list_price')
Shop = _pool.get('sale.shop')
shop, = Shop.search_read([('id', '=', shopId)],
fields_names=['product_categories'])
templates_cat = ProductCategory.search_read([
('category', '=', int(categoryId))
], fields_names=['template'])
templates_cat = [t['template'] for t in templates_cat]
products = []
add_products = products.append
values = Product.search([
('account_category', 'in', shop['product_categories']),
('active', '=', True),
('template', 'in', templates_cat),
],
order=[('code', 'ASC')]
)
prices = ListPrice.search_read([
('template', 'in', [v.template.id for v in values])
], fields_names=['template', 'list_price']
)
prices2product = {p['template']: p['list_price'] for p in prices}
for val in values:
add_products({
'id': val.id,
'name': val.template.name,
'code': val.code,
'quantity': val.quantity,
'sale_price': float(prices2product[val.template.id]),
'sale_price_w_tax': float(val.template.sale_price_w_tax),
'categories': [c.id for c in val.template.categories],
})
return products
return send(exec_(_method))
@app.route("/products_elastic/<shopId>/<query>", methods=['GET'])
@require_appkey
def get_products_elastic(shopId, query):
@tryton.transaction()
def _method():
Product = _pool.get('product.product')
Shop = _pool.get('sale.shop')
ListPrice = _pool.get('product.list_price')
shop, = Shop.search_read([('id', '=', shopId)],
fields_names=['product_categories'])
products = []
values = Product.search_read([
('account_category', 'in', shop['product_categories']),
('active', '=', True),
('categories', '!=', None),
('template.name', 'ilike', '%' + query + '%'),
('template.salable', '=', True),
], fields_names=[
'template.name', 'code', 'template.categories',
'template.sale_price_w_tax', 'template'
],
order=[('code', 'ASC')]
)
prices = ListPrice.search_read([
('template', 'in', [v['template.']['id'] for v in values])
], fields_names=['id', 'template', 'list_price']
)
prices2product = {p['template']: p['list_price'] for p in prices}
for val in values:
products.append({
'id': val['id'],
'name': val['template.']['name'],
'code': val['code'],
'sale_price': float(prices2product[val['template.']['id']]),
'sale_price_w_tax': float(val['template.']['sale_price_w_tax']),
'categories': val['template.']['categories'],
})
return products
return send(exec_(_method))
@app.route("/categories", methods=['GET'])
@require_appkey
def get_categories():
@tryton.transaction()
def _method():
Category = _pool.get('product.category')
categories = Category.search([
('accounting', '=', False),
('parent', '=', )
])
values = []
for cat in categories:
values.append({
'id': cat.id,
'name': cat.name,
'parent': cat.parent.id if cat.parent else None,
'images': [img.image for img in cat.images]
})
return values
return send(exec_(_method))
@app.route("/shops", methods=['GET'])
@require_appkey
def get_shops():
@tryton.transaction()
def _method():
Shop = _pool.get('sale.shop')
shops = Shop.search_read(
[],
fields_names=[
'id', 'name',
'freight_product',
'freight_product.template.name',
'freight_product.template.sale_price_w_tax',
])
shops_ = []
for shop in shops:
if shop.get('freight_product'):
product_freight_id = shop['freight_product.']['id']
product_freight_price = shop['freight_product.']['template.']['sale_price_w_tax']
new_shop = {
'id': shop['id'],
'name': shop['name'],
'product_freight_id': product_freight_id,
'product_freight_name': 'FLETE',
'product_freight_price': product_freight_price,
}
shops_.append(new_shop)
return shops_
return send(exec_(_method))
@app.route("/add_party", methods=['POST', 'PUT'])
@require_appkey
def add_party():
data = json.loads(request.data.decode("utf-8"))
regime_tax = ''
if data['type_document'] == '31':
regime_tax = 'regimen_comun'
res = {
'msg': 'Error party no created!',
'status': 'error',
'id': None
}
values = {
'name': data['name'].upper(),
'id_number': data['id_number'],
'type_document': data['type_document'],
'regime_tax': regime_tax,
'addresses': [('create', [{
'street': data['address'],
'country_code': data['country'],
'department_code': data['department'],
'city_code': data['city'],
}])],
'contact_mechanisms': [('create', [{
'type': 'mobile',
'value': data['phone'],
}, {
'type': 'email',
'value': data['email'],
}]
)],
}
@tryton.transaction()
def _add_party():
Party = _pool.get('party.party')
PartyAccount = _pool.get('party.party.account')
Configuration = _pool.get('account.configuration.default_account')
config = Configuration(1)
parties = Party.search([
('id_number', '=', data['id_number'])
])
if parties:
res['msg'] = 'Party already exists!'
res['status'] = 'warning'
return
party, = Party.create([values])
if config.default_account_receivable:
PartyAccount.create([{
'company': 1,
'party': party.id,
'account_payable': None,
'account_receivable': config.default_account_receivable.id,
}])
return party
try:
new_party = _add_party()
if new_party and new_party.id:
res['msg'] = 'Party created succesfully'
res['status'] = 'success'
res['id'] = new_party.id
except Exception as e:
print(e)
res['msg'] = e
return send(res)
@app.route("/update_party", methods=['POST', 'PUT'])
@require_appkey
def update_party():
data = json.loads(request.data.decode("utf-8"))
regime_tax = ''
if data['type_document'] == '31':
regime_tax = 'regimen_comun'
values = {
'name': data['name'],
'id_number': data['id_number'],
'type_document': data['type_document'],
'regime_tax': regime_tax,
}
addresses = {
'street': data['address'],
'country_code': data['country'],
'department_code': data['department'],
'city_code': data['city']
}
@tryton.transaction()
def _update_party():
Party = _pool.get('party.party')
party = Party(data['id'])
Party.write([party], values)
return party
@tryton.transaction()
def _update_address():
Party = _pool.get('party.party')
party = Party(data['id'])
Address = _pool.get('party.address')
Address.write(list(party.addresses), addresses)
@tryton.transaction()
def _update_contact(type_, val):
Party = _pool.get('party.party')
party = Party(data['id'])
Contact = _pool.get('party.contact_mechanism')
contacts = Contact.search([
('party', '=', party.id,),
('type', '=', type_,),
])
Contact.write(contacts, {
'type': type_,
'value': val,
})
try:
_update_party()
if data['address']:
_update_address()
if data['phone']:
_update_contact('mobile', data['phone'])
if data['email']:
_update_contact('email', data['email'])
msg = 'User updated succesfully!'
except:
msg = 'Error in user update!'
return send(msg)
@app.route("/add_sale/", methods=['POST'])
@require_appkey
def add_sale():
data = json.loads(request.data.decode("utf-8"))
for k, v in data.items():
print(k, '---', v)
@tryton.transaction()
def _get_user():
User = _pool.get('res.user')
user, = User.search([
('login', '=', 'ecommerce')
])
return user.id
user_id = _get_user()
ctx = {'company': 1}
res = {
'msg': 'Error in sale creation!',
'status': 'error',
'order': ''
}
@tryton.transaction(context=ctx, user=user_id)
def _get_lines():
lines = []
Product = _pool.get('product.product')
for l in data['lines']:
if not l.get('product') or l.get('product') == '':
continue
product = Product(int(l['product']))
template = product.template
taxes = [tax.id for tax in template.account_category.customer_taxes_used]
lines.append({
'product': int(l['product']),
'description': template.name,
'unit_price': Decimal(l['list_price']),
'unit': template.default_uom.id,
'quantity': int(l['quantity']),
'taxes': [('add', taxes)]
})
return lines
@tryton.transaction(user=user_id)
def _create(lines):
Party = _pool.get('party.party')
Sale = _pool.get('sale.sale')
Shop = _pool.get('sale.shop')
PartyAccount = _pool.get('party.party.account')
Statement = _pool.get('account.statement')
StatementLine = _pool.get('account.statement.line')
shipment_party = data['party']
party = Party(data['party'])
shipment_address_id = party.addresses[0].id
shop = Shop(data['shop'])
sale_date = datetime.now(timezone(shop.company.timezone)).date()
for var in ('party', 'payment_term', 'shop', 'paid_amount', 'voucher'):
if not data.get(var):
res['msg'] = f'Missing {var} in request'
return
vals = {
'company': shop.company.id,
'state': 'draft',
'party': data['party'],
'sale_date': sale_date,
'currency': shop.company.currency.id,
'shop': data['shop'],
'payment_term': data['payment_term'],
'shipment_party': shipment_party,
'shipment_address': shipment_address_id,
'invoice_address': shipment_address_id,
'warehouse': shop.warehouse.id,
'shipment_method': 'order',
'invoice_method': 'order',
'shipment_state': 'none',
'invoice_state': 'none',
'invoice_type': 'P',
'lines': [('create', lines)],
'description': 'WEB SALE',
'reference': shop.name,
'self_pick_up': False
}
sale, = Sale.create([vals])
Sale.quote([sale])
statements = Statement.search([
('journal.name', '=', 'pagos_web'),
('sale_device.shop', '=', int(data['shop'])),
('state', '=', 'draft'),
])
statement = None
if statements:
statement = statements[0]
party_accs = PartyAccount.search([
('party', '=', party.id),
('account_receivable', '!=', None),
])
party_acc = party_accs[0]
if statement and data.get('paid_amount') and data.get('voucher'):
StatementLine.create([{
'sale': sale.id,
'date': sale_date,
'statement': statement.id,
'amount': data['paid_amount'],
'party': sale.party.id,
'account': party_acc.account_receivable.id,
'description': data.get('voucher'),
}])
sale.save()
sale, = Sale.browse([sale.id])
print('sale num ....', sale.number)
return sale
try:
lines = _get_lines()
sale = _create(lines)
if sale and sale.number:
res['msg'] = 'Sale created succesfully'
res['status'] = 'success'
res['order'] = sale.number
except Exception as e:
print(e)
res['msg'] = e
return send(res)
@app.route("/categories_tree/<shopId>", methods=['GET'])
@require_appkey
def get_categories_tree(shopId):
@tryton.transaction()
def _method():
Shop = _pool.get('sale.shop')
def _get_childs(cat):
value = {
'id': cat.id,
'name': cat.name,
'parent': cat.parent.id if cat.parent else None,
'images': [img.image for img in cat.images]
}
if cat.childs:
value['childs'] = [_get_childs(c) for c in cat.childs]
return value
shop = Shop(shopId)
categories = [
c for c in shop.product_categories if c.accounting == False
]
categoryTree = []
if categories:
categoryTree = _get_childs(categories[0])
return categoryTree
return send(exec_(_method))
@app.route("/product/", methods=['POST'])
@require_appkey
def get_product():
data = json.loads(request.data.decode("utf-8"))
id_product = None
if data.get('id'):
id_product = data['id']
@tryton.transaction()
def _method():
Product = _pool.get('product.product')
fields_names = [
'id', 'code', 'name', 'template.categories',
'template.sale_price_w_tax', 'template.name']
products = Product.search_read(
['id', '=', id_product],
fields_names=fields_names
)
if products:
product = products[0]
value = {
'id': product['id'],
'name': product['template.']['name'],
'code': product['code'],
'sale_price': float(product['template.']['sale_price_w_tax']),
'categories': product['template.']['categories.'],
'images': ''
}
return value
return send(exec_(_method))
return app