示例#1
0
class Product(ProductBase):
    name = base.String('description1')
    code = base.String('number')
    ean13 = base.String('ean')
    list_price = base.Decimal('recommendedretailprice')
    cost_price = base.Decimal('unitprice')
    manufacturer = base.String('supplier')
    picture = base.URL('pictureurl')

    @property
    def valid(self):
        return True

    @property
    def description(self):
        descr = base.String('description2').parse(self)
        if descr is None:
            return self.name
        return descr

    @classmethod
    def search(cls, keywords, offset=0, limit=20, count=False):
        if limit is None:
            limit = 20

        sp = SearchProducts(cls._ctx)
        products = sp.execute(keywords, offset, limit)
        if count:
            if len(products) < limit:
                return len(products)
            else:
                # HACK
                return 100 * limit

        return [p.code for p in products]

    @classmethod
    def read(cls, codes):
        if len(codes) == 0:
            return []

        # If products dont exist, create invalid products.
        # All for all codes coming in, products have to be returned.
        itd = ItemDetails(cls._ctx)
        products = {}
        for product in itd.execute(codes):
            products[product.code] = product

        res = []
        for code in codes:
            if code in products:
                res.append(products[code])
            else:
                res.append(InvalidProduct(code))

        return res
示例#2
0
class Order(VeloModelMixin, TransactionMixin, OrderBase):
    lines = base.One2Many('/vco:OrderResponse/vco:OrderResponseLine',
                          model=Line)
    orderid = base.String('vco:OrderHeader/vco:OrderID')

    def _load(self, tan):
        vo = ViewOrder(self._ctx)
        self._data = vo.execute(tan)

    @staticmethod
    def _build_lines(lines):
        rlines = []
        for product, qty in lines:
            line = OrderRequestLine(
                product.sellers_item_identification,
                Quantity(str(qty), quantityUnitCode=product.unit_code))
            rlines.append(line)
        return rlines

    def add_lines(self, lines):
        uo = UpdateOrder(self._ctx)
        self._data = uo.execute(self.tan, self._build_lines(lines))

    def finish(self):
        fo = FinishOrder(self._ctx)
        self._data = fo.execute(self.tan)
        return self

    @classmethod
    def create(cls, lines):
        co = CreateOrder(cls._ctx)
        return co.execute(cls._build_lines(lines))
示例#3
0
class TransactionMixin(object):
    tan = base.String('vct:TransactionID')

    def rollback(self):
        try:
            rbk = Rollback(self._ctx)
            rbk.execute(self.tan)
        except VeloConnectException, e:
            if e.code != ERR_NOT_SUPPORTED:
                raise
示例#4
0
class Line(VeloModelMixin, Model):
    quantity = base.Decimal('cbc:Quantity')
    unit_price = base.Decimal('cac:UnitPrice')
    product = base.Many2One('cac:Item', model=Product)
    availability = base.String('vco:Availability/vco:Code')
    available_quantity = base.Decimal('vco:Availability/vco:AvailableQuantity')
示例#5
0
class Product(VeloModelMixin, ProductBase):
    _name_exp = re.compile(r'[\n\r]|&nbsp;')
    _prefixes = ['cac:Item/']  # 'Works with ItemDetail and Item nodes.'

    valid = ~base.Bool('vco:ItemUnknown/cac:SellersItemIdentification/cac:ID',
                       default=True)
    code = base.String(
        'cac:SellersItemIdentification/cac:ID',
        'vco:RequestReplacement/cac:SellersItemIdentification/cac:ID',
        'vco:ItemUnknown/cac:SellersItemIdentification/cac:ID')
    replacement = base.String(
        'vco:RequestReplacement/cac:ItemReplacement/cac:ID')
    description = base.String('cbc:Description', subst=(r'&nbsp;', ' '))
    list_price = base.Decimal('cac:RecommendedRetailPrice/cbc:PriceAmount')
    cost_price = base.Decimal('cac:BasePrice/cbc:PriceAmount')
    unit_code = base.Attribute('cac:BasePrice/cbc:BaseQuantity',
                               attr='quantityUnitCode')
    manufacturer = base.String('cac:ManufacturersItemIdentification'
                               '/cac:IssuerParty/cac:PartyName/cbc:Name')
    availability = base.String('vco:Availability/vco:Code')
    available_quantity = base.Decimal('vco:Availability/vco:AvailableQuantity')

    @property
    def name(self):
        if self.description is None:
            return None
        return self._name_exp.sub(' ', self.description[:100] + '...')

    @property
    def ean13(self):
        ean13 = self._data.xpath(
            'cac:Item/cac:StandardItemIdentification'
            '/cac:ID[@identificationSchemeID="EAN/UCC-13"]',
            namespaces=NAMESPACES)
        return len(ean13) and ean13[0].text or None

    @property
    def sellers_item_identification(self):
        return SellersItemIdentification(ID(self.code))

    @property
    def picture(self):
        urls = self._data.xpath(
            'cac:Item/vcc:ItemInformation/vcc:InformationURL'
            '/vcc:Disposition[text()="picture"]/../vcc:URI',
            namespaces=NAMESPACES)
        url = len(urls) and urls[0].text or None
        if url is None:
            return None
        return buffer(urllib2.urlopen(url).read())

    @classmethod
    def search(cls, keywords, offset=0, limit=20, count=False):
        cts = CreateTextSearch(cls._ctx)
        ctsresp = cts.execute(keywords)

        if count:
            return ctsresp.count

        if ctsresp.count == 0:
            return []

        sr = SearchResult(cls._ctx)
        return sr.execute(ctsresp.tan, offset, limit)

    @classmethod
    def read(cls, codes):
        gidl = GetItemDetailsList(cls._ctx)
        return gidl.execute(codes)
示例#6
0
 def description(self):
     descr = base.String('description2').parse(self)
     if descr is None:
         return self.name
     return descr