Compare commits

...

8 Commits

Author SHA1 Message Date
ae81d17ed5 feat: Delete Order, Delete Order Line 2025-03-22 15:48:20 -05:00
09cabd6798 feat: Implemented get associate party to contact_mechanism 2025-03-15 15:00:58 -05:00
becf5f929a Fix: Create POST Order Line 2025-02-15 12:17:37 -05:00
2c64f80f9c Feat: Confirm order 2025-02-11 21:30:19 -05:00
58a600c17d Fix: Tests 2025-02-11 21:01:23 -05:00
0ce8f2e3fb Fix: Improve response post_order 2025-02-11 20:55:14 -05:00
b78ec4549b Feat: Add enpoints SaleOrder 2025-02-11 20:34:32 -05:00
13618e7dda Fix: Tests SaleApiOrder 2025-02-11 18:13:51 -05:00
6 changed files with 496 additions and 39 deletions

View File

@@ -1,7 +1,8 @@
from trytond.pool import Pool
from . import sale_order, user
from . import sale_order, user, routes
__all__ = ['register']
__all__ = [
'register', 'routes']
def register():

164
routes.py
View File

@@ -1,25 +1,165 @@
from trytond.wsgi import app
from trytond.transaction import Transaction
from trytond.protocols.wrappers import (
with_pool,
with_transaction,
user_application,
allow_null_origin)
allow_null_origin,
)
import json
sale_order = user_application('sale_order')
sale_order_application = user_application("sale_order")
@app.route('/<database_name>/sale_order/order', methods=['POST'])
@app.route(
"/<database_name>/sale_order/associate_party/<contact_method>", methods=[
"GET"])
@allow_null_origin
@with_pool
@with_transaction()
@sale_order
def order(request, pool):
raise Exception(request)
Order = pool.get('sale.order')
if request.method == 'POST':
data = json.loads(
request.get_data().decode()
)
@sale_order_application
def get_associate_party(request, pool, contact_method: str):
ContactMechanism = pool.get("party.contact_mechanism")
associate_contact_method = ContactMechanism.search(
[("value", "ilike", contact_method)]
)
if associate_contact_method:
response_data = {
"id": associate_contact_method[0].id,
"associate_party": associate_contact_method[0].party.id,
"status": "success",
"type": associate_contact_method[0].type,
"message": "Associate Party found",
}
Order.create([dict(data)])
return json.dumps(response_data), 200
response_data = {
"id": None,
"associate_party": None,
"status": "success",
"type": None,
"message": "Associate Party not found",
}
return json.dumps(response_data), 404
@app.route("/<database_name>/sale_order/order/<order>", methods=["GET"])
@allow_null_origin
@with_pool
@with_transaction()
@sale_order_application
def get_order(request, pool, order: int):
Order = pool.get("sale.order")
with Transaction().set_context({"company": 1, "locations": [3]}):
if request.method == "GET":
orders = Order.search_read(
[("id", "=", order)],
order=[("id", "ASC")],
fields_names=["id", "party", "lines"],
)
return orders
@app.route("/<database_name>/sale_order/order", methods=["POST"])
@allow_null_origin
@with_pool
@with_transaction()
@sale_order_application
def post_order(request, pool):
Order = pool.get("sale.order")
with Transaction().set_context({"company": 1, "locations": [3]}):
if request.method == "POST":
data = json.loads(request.get_data().decode())
(order,) = Order.create([dict(data)])
response_data = {
"id": order.id,
"status": "success",
"message": "Order created successfully",
}
return json.dumps(response_data), 201
@app.route("/<database_name>/sale_order/<order>/order_line", methods=["POST"])
@allow_null_origin
@with_pool
@with_transaction()
@sale_order_application
def order_line(request, pool, order: int):
OrderLine = pool.get("order.line")
with Transaction().set_context({"company": 1, "locations": [3]}):
if request.method == "POST":
data = json.loads(request.get_data().decode())
order_lines = OrderLine.create([dict(data)])
response_data = {
"order_lines": [line.id for line in order_lines],
"status": "success",
"message": "Order lines created successfully",
}
return json.dumps(response_data), 201
@app.route("/<database_name>/sale_order/confirm_order/<order>", methods=[
"POST"])
@allow_null_origin
@with_pool
@with_transaction()
@sale_order_application
def confirm_order(request, pool, order: int):
Order = pool.get("sale.order")
if request.method == "POST":
(order,) = Order.search([("id", "=", order)])
Order.confirm([order])
response_data = {
"id": order.id,
"status": "success",
"state": order.state,
"message": "Order confirm successfully",
}
return json.dumps(response_data), 201
@app.route("/<database_name>/sale_order/<order>", methods=["DELETE"])
@allow_null_origin
@with_pool
@with_transaction()
@sale_order_application
def delete_order(request, pool, order: int):
Order = pool.get("sale.order")
if request.method == "DELETE":
(order,) = Order.search([("id", "=", order)])
order.delete([order])
response_data = {
"id": order.id,
"status": "success",
"message": "Order deleted successfully",
}
return json.dumps(response_data), 200
@app.route(
"/<database_name>/sale_order/<order>/order_line/<order_line>", methods=[
"DELETE"])
@allow_null_origin
@with_pool
@with_transaction()
@sale_order_application
def delete_order_line(request, pool, order: int, order_line: int):
OrderLine = pool.get("order.line")
if request.method == "DELETE":
(order_line,) = OrderLine.search([("id", "=", order_line)])
order_line.delete([order_line])
response_data = {
"id": order_line.id,
"status": "success",
"message": "Order line deleted successfully",
}
return json.dumps(response_data), 200

View File

@@ -33,12 +33,15 @@ class SaleOrder (Workflow, ModelView, ModelSQL):
party = fields.Many2One(
'party.party', "Party", required=True, states=_states)
order_address = fields.Many2One(
'party.address', 'Address', required=True, states=_states)
'party.address', 'Address', states=_states)
pickup_location = fields.Selection([
("on_site", "On Site"),
("at_home", "At Home")], 'Pickup Location', states=_states)
order_mobile = fields.Char('Mobile', states=_states)
date = fields.Date("Date", required=True, states=_states)
date = fields.Date("Date", required=True, states={
'readonly': Eval('state').in_(['confirmed', 'done']),
'required': Eval('pickup_location') == 'at_home'
})
lines = fields.One2Many(
'order.line', 'order', 'Lines', states=_states)
total_order = fields.Function(

View File

@@ -107,7 +107,7 @@ setup(name=name,
],
license='GPL-3',
python_requires='>=3.8',
install_requires=requires,
# install_requires=requires,
extras_require={
'test': tests_require,
},

75
tests/SaleOrderApiTest.py Normal file
View File

@@ -0,0 +1,75 @@
import pudb
import requests
import json
url = "http://localhost:8000"
key = (
"f46f14d77db646b0ac0802e7bdab9cbb"
+ ("1d53ad96387242e1918c45854dce5238707fed31daa64cab88569d119512153")
+ ("64db6ced393b44f198ab9a3967b6f4ddf")
)
db = "tryton"
application_name = "sale_order"
base_url = "{}/{}/{}".format(url, db, application_name)
get_associate_party = requests.get(
base_url + "/associate_party/alejandro.ayala@gmail.com",
headers={
"Authorization": f"bearer {key}",
},
)
post_sale_order = requests.post(
base_url + "/order",
headers={
"Authorization": f"bearer {key}",
},
data=json.dumps(
{
"party": 2573,
"pickup_location": "on_site",
"lines": [
[
"create",
[
{
"product": "1",
"unit": "1",
"quantity": "5",
"unitprice": "10"
}],
]
],
}
),
)
order = json.loads(json.loads(post_sale_order.text)[0]).get("id")
get_sale_order = requests.get(
base_url + "/order/1",
headers={
"Authorization": f"bearer {key}",
},
)
post_line_order = requests.post(
base_url.replace(
"sale_don_confiao", "sale_order") + f"/{order}/order_line",
headers={
"Authorization": f"bearer {key}",
},
data=json.dumps(
{
"order": order,
"product": "1",
"unit": "1",
"quantity": "5",
"unitprice": "10",
}
),
)
pudb.set_trace()

View File

@@ -12,42 +12,280 @@ from trytond.tests.tools import activate_modules
class SaleOrderApiRouteTestCase(RouteTestCase):
"""Sale Order API Routes"""
module = 'sale_order'
module = "sale_order"
key = uuid.uuid4().hex
@classmethod
def setUpClass(cls):
activate_modules('sale_order', create_company)
activate_modules("sale_order", create_company)
def setUp(self):
pool = Pool(DB_NAME)
transaction = Transaction().start(DB_NAME, 0, _lock_tables=[
'product_product'])
transaction = Transaction().start(
DB_NAME, 0, _lock_tables=["product_product"])
with transaction:
Party = pool.get('party.party')
ProductTemplate = pool.get('product.template')
Product = pool.get('product.product')
Uom = pool.get('product.uom')
self.productTemplate, = ProductTemplate.create([{
'name': 'Product',
'default_uom': Uom.search([('name', '=', 'Unit')])[0].id,
}])
self.product, = Product.create([
{'template': self.productTemplate.id}
Party = pool.get("party.party")
ProductTemplate = pool.get("product.template")
Product = pool.get("product.product")
Uom = pool.get("product.uom")
Application = pool.get("res.user.application")
Application(
key=self.key,
user=1,
application="sale_order",
state="validated"
).save()
self.unit = Uom.search([("name", "=", "Unit")])[0].id
(self.productTemplate,) = ProductTemplate.create(
[
{
"name": "Product",
"default_uom": self.unit,
}
]
)
(self.product,) = Product.create([
{"template": self.productTemplate.id}
])
self.party, = Party.create([{
'name': "Dunkan"
}])
(self.party,) = Party.create(
[
{
"name": "Dunkan",
"contact_mechanisms": [[
"create", [{
"type": "mobile",
"value": "3102223334"}]]
],
}
]
)
def test_post_sale_order(self):
client = self.client()
response = client.post(
f'/{self.db_name}/sale_order/order',
f"/{self.db_name}/sale_order/order",
headers={
'Authorization': f'bearer {self.key}',
}, data=json.dumps({
"party": self.party.id,
}))
"Authorization": f"bearer {self.key}",
},
data=json.dumps(
{
"party": self.party.id,
"pickup_location": "on_site",
"lines": [
[
"create",
[
{
"product": self.product.id,
"unit": self.unit,
"quantity": "5",
"unitprice": "10",
}
],
]
],
}
),
)
self.assertEqual(response.status_code, HTTPStatus.OK)
def test_get_sale_orders(self):
client = self.client()
order = json.loads(
client.post(
f"/{self.db_name}/sale_order/order",
headers={
"Authorization": f"bearer {self.key}",
},
data=json.dumps(
{
"party": self.party.id,
"pickup_location": "on_site",
"lines": [
[
"create",
[
{
"product": self.product.id,
"unit": self.unit,
"quantity": "5",
"unitprice": "10",
}
],
]
],
}
),
)
.get_data()
.decode()
)
response = client.get(
f"/{self.db_name}/sale_order/order/{json.loads(order[0])['id']}",
headers={
"Authorization": f"bearer {self.key}",
},
)
self.assertEqual(response.status_code, HTTPStatus.OK)
self.assertEqual(len(json.loads(response.text)), 1)
def test_confirm_sale_order(self):
client = self.client()
order = json.loads(
client.post(
f"/{self.db_name}/sale_order/order",
headers={
"Authorization": f"bearer {self.key}",
},
data=json.dumps(
{
"party": self.party.id,
"pickup_location": "on_site",
"lines": [
[
"create",
[
{
"product": self.product.id,
"unit": self.unit,
"quantity": "5",
"unitprice": "10",
}
],
]
],
}
),
)
.get_data()
.decode()
)
confirm_url = f"/{self.db_name}/sale_order/confirm_order/"
order_id = json.loads(order[0])["id"]
response = client.post(
f"{confirm_url}{order_id}",
headers={
"Authorization": f"bearer {self.key}",
},
)
response_data = json.loads(json.loads(response.text)[0])
self.assertEqual(response.status_code, HTTPStatus.OK)
self.assertEqual(response_data["state"], "confirmed")
def test_post_line_order(self):
client = self.client()
response = client.post(
f"/{self.db_name}/sale_order/order",
headers={"Authorization": f"bearer {self.key}"},
data=json.dumps({
"party": self.party.id,
"pickup_location": "on_site"}),
)
order = json.loads(json.loads(response.text)[0]).get("id")
response = client.post(
f"/{self.db_name}/sale_order/{order}/order_line",
headers={
"Authorization": f"bearer {self.key}",
},
data=json.dumps(
{
"order": order,
"product": self.product.id,
"unit": self.unit,
"quantity": "5",
"unitprice": "10",
}
),
)
self.assertEqual(response.status_code, HTTPStatus.OK)
def test_get_party_asociate_contact_method(self):
"""
Recibe un numbero de telofono y retorna el tercero asociado
a este numero de telofono.
Args:
phone: string
Return:
party: int
"""
client = self.client()
response = client.get(
f"/{self.db_name}/sale_order/associate_party/3102223334",
headers={
"Authorization": f"bearer {self.key}",
},
)
self.assertEqual(response.status_code, HTTPStatus.OK)
self.assertEqual(json.loads(response.text)[1], 200)
self.assertEqual(json.loads(
json.loads(
response.text
)[0])["associate_party"], 2)
def test_create_contact_method(self):
"""
Crea un tercero asociandolo a un metodo de contacto
Args:
email, phone : string
Return:
party: int
"""
def test_delete_sale(self):
client = self.client()
order = json.loads(
client.post(
f"/{self.db_name}/sale_order/order",
headers={
"Authorization": f"bearer {self.key}",
},
data=json.dumps(
{
"party": self.party.id,
"pickup_location": "on_site",
"lines": [
[
"create",
[
{
"product": self.product.id,
"unit": self.unit,
"quantity": "5",
"unitprice": "10",
}
],
]
],
}
),
)
.get_data()
.decode()
)
order_id = json.loads(order[0])["id"] # Get the id of the order
delete_order = client.delete(
f"/{self.db_name}/sale_order/{order_id}",
headers={"Authorization": f"bearer {self.key}"},
)
self.assertEqual(delete_order.status_code, HTTPStatus.OK)
self.assertEqual(json.loads(delete_order.text)[1], 200)