123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237 |
- #!/usr/bin/env python3
- from typing import List, Tuple, ClassVar, Type, Any
- from dataclasses import dataclass
- from marshmallow import Schema
- import xmlrpc.client
- import marshmallow_dataclass
- import pprint
- try:
- from types import SimpleNamespace as Namespace
- except ImportError:
- # Python 2.x fallback
- from argparse import Namespace
- @dataclass
- class Address:
- """All of the Dataclasses us Marshmallow for Serialisation
- This is the adress. It contains coordinates but also the adress"""
- id: int
- name: str
- phone: str
- street: str
- street2: str
- city: str
- zip: str
- longitude: float
- latitude: float
- # state: str
- @dataclass
- class Sale:
- """Unlike pythons dynamic Typing we use statically Typed Classes
- This allows us to catch TypeErrors and thus allows us to validate the
- Answer from the Server"""
- id: int
- name: str
- invoice_status: str
- amount_total: float
- amount_tax: float
- create_date: str
- order_line: List[int]
- # price_subtotal: float
- @dataclass
- class Sale_Line:
- """This class is one line of a sail.
- The relation Ship is many sale_lines to one sale"""
- id: int
- name: str
- price_total: float
- product_uom_qty: int
- @dataclass
- class Picking(object):
- """Pickings are drone flights which are created by Sales
- A Sale has three steps in a picking. It is picked, packed and then shiped
- currently a user in the Backend advances the picking in the web app.
- picking validation threw GPS or QR Codes is a feature automation
- """
- id: int
- name: str
- group_id: Tuple[int, str]
- location_id: Tuple[int, str]
- location_dest_id: Tuple[int, str]
- move_lines: List[int]
- partner_id: Tuple[int, str]
- sale_id: Tuple[int, str]
- state: str
- create_date: str
- printed: bool
- product_id: Tuple[int, str]
- # wk_picking_notes: Any
- Schema: ClassVar[Type[Schema]] = Schema
- PickingSchema = marshmallow_dataclass.class_schema(Picking)
- AddressSchema = marshmallow_dataclass.class_schema(Address)
- SaleLineSchema = marshmallow_dataclass.class_schema(Sale_Line)
- SaleSchema = marshmallow_dataclass.class_schema(Sale)
- class API:
- """This interacts with the external odoo 13 API with XMLrpc
- The API Class is intended to be used a black box implentation
- which is imported by another Class or Python Scipt
- """
- url = "http://localhost:8069"
- db = "anemoi_test"
- username = "test" # FIXME Read Val from system env or file
- password = "1234" # FIXME Read Val from system env or file
- common = xmlrpc.client.ServerProxy("{}/xmlrpc/2/common".format(url))
- models = xmlrpc.client.ServerProxy("{}/xmlrpc/2/object".format(url))
- uid = common.authenticate(db, username, password, {})
- def __init__(
- self, id, name, number, addres, description, menge, preis, sum_order, comment,
- ):
- """Reads the values from its parameters and uses them to build the API"""
- self.printed = True
- self.id = id
- self.name = name
- self.number = number
- self.addres = addres
- self.description = description
- self.menge = menge
- self.preis = preis
- self.sum_order = sum_order
- self.comment = comment
- def login():
- """Login into the Server return the reading rights of stock.picking"""
- # To verify if the connection information is correct before trying to authenticate,
- # the simplest call is to ask for the server’s version.
- print(API.common.version())
- # The second endpoint is xmlrpc/2/object, is used to call
- # methods of odoo models via the execute_kw RPC function.
- return API.models.execute_kw(
- API.db,
- API.uid,
- API.password,
- "stock.picking",
- "check_access_rights",
- ["read"],
- {"raise_exception": False},
- )
- def get_fields(field_name):
- """What Fields does the our Odoo Model have of of this data Field"""
- return API.models.execute_kw(
- API.db,
- API.uid,
- API.password,
- field_name,
- "fields_get",
- [],
- {"attributes": ["string", "help", "type"]},
- )
- def get_partner_address(ids):
- """Returns the adress and geolocation of all ids as a AdressSchema"""
- ps = API.models.execute_kw(
- API.db,
- API.uid,
- API.password,
- "res.partner",
- "read",
- [ids],
- {
- "fields": [
- "name",
- "street",
- "street2",
- "zip",
- "phone",
- "city",
- "partner_latitude",
- "partner_longitude",
- ]
- },
- )
- p_objects = [AddressSchema().load(p) for p in ps]
- return p_objects
- def get_not_printed_pickings():
- """Returns all Pickings which have not been not been printed or processed
- The xml Response of the Server is parsed to a python Data Picking Class """
- ps = API.models.execute_kw(
- API.db,
- API.uid,
- API.password,
- "stock.picking",
- "search_read",
- [
- ["&", ("printed", "!=", True), ("state", "!=", "cancel")]
- ], # TODO add check if adress is null.
- {
- "fields": [
- "name",
- "partner_id",
- "sale_id",
- "state",
- "create_date",
- "printed",
- "product_id",
- "move_lines",
- "location_id",
- "location_dest_id",
- "group_id",
- ],
- "limit": 50,
- },
- )
- pprint.pprint(ps)
- p_objects = [PickingSchema().load(p) for p in ps]
- return p_objects
- def __load_picking(p_picking):
- """Loads the Picking Schema from a String. Usefull for testing"""
- picking_schema = marshmallow_dataclass.class_schema(Picking)
- return picking_schema.load(p_picking)
- def get_product(ids):
- """Returns all orders Lines of a Product"""
- return API.models.execute_kw(
- API.db,
- API.uid,
- API.password,
- "product.product",
- "read",
- [ids],
- {"fields": ["order_line",]},
- )
- def post_printed_picking(printed: bool, picking_id: int):
- """Post the new value of printed for picking_id"""
- API.models.execute_kw(
- API.db,
- API.uid,
- API.password,
- "stock.picking",
- "write",
- [[picking_id], {"printed": printed}],
- )
|