
from collections import namedtuple

# an Order is a pair containing an id and a list of Item
# the id type is not relevant
Order = namedtuple('Order', 'id, items')

# an Item is a quadruplet with a type, a description, an amount and a quantity
# the type of the description is not relevant
# the types of the other fields are constrained by function "validorder" bellow
Item = namedtuple('Item', 'type, description, amount, quantity')

# check if an order is valid and return the corresponding balance 
def validorder(order: Order):
    net = 0  # user balance

    for item in order.items:
        if item.amount < 0:
            return "Item amount should be a positive value!"
        if item.type == 'payment':
            net += item.amount * item.quantity
        elif item.type == 'refund':
            net -= item.amount * item.quantity
        elif item.type == 'product':
                # check that a quantity is a positive integer
            if (not isinstance(item.quantity, int)) or item.quantity < 0: 
                return "Item quantity should be a positive integer value!"
            net -= item.amount * item.quantity
        else:  # only 'payment', 'refund' and 'product' order types are accepted
            return "Invalid item type: %s" % item.type

    if net != 0:
        return "Order ID: %s - Payment imbalance: $%e" % (order.id, net)
    else:
        return "Order ID: %s - Full payment received" % order.id
