Fixes to pricing and customer models. Add req deliv to order. And more..
* Fix NullPriceAllowed and logic in price calculation * Fix CustomerCategory join in Customer model * Add RequestedDeliveryDate to order creation * Start using Jeeves Signatures on order creation
This commit is contained in:
parent
fc7c1e13bc
commit
6339e9d1ce
4 changed files with 63 additions and 24 deletions
|
|
@ -301,7 +301,6 @@ class Customer(RawBaseModel):
|
||||||
'GodsMarke2', 'LevSattKod', 'Language', 'ValKod')
|
'GodsMarke2', 'LevSattKod', 'Language', 'ValKod')
|
||||||
|
|
||||||
FtgNr = Column(String, ForeignKey('fr.FtgNr'), primary_key=True)
|
FtgNr = Column(String, ForeignKey('fr.FtgNr'), primary_key=True)
|
||||||
KundKategoriKod = Column(Integer, ForeignKey('x1k.KundKategoriKod'))
|
|
||||||
SprakKod = Column(Integer, ForeignKey('xw.SprakKod'))
|
SprakKod = Column(Integer, ForeignKey('xw.SprakKod'))
|
||||||
PrisLista = Column(Integer, ForeignKey('prh.PrisLista'))
|
PrisLista = Column(Integer, ForeignKey('prh.PrisLista'))
|
||||||
PrisListaKundSpec = Column(Integer, ForeignKey('prh.PrisLista'))
|
PrisListaKundSpec = Column(Integer, ForeignKey('prh.PrisLista'))
|
||||||
|
|
@ -314,7 +313,9 @@ class Customer(RawBaseModel):
|
||||||
foreign_keys='PriceList.PrisLista',
|
foreign_keys='PriceList.PrisLista',
|
||||||
primaryjoin="Customer.PrisLista==PriceList.PrisLista")
|
primaryjoin="Customer.PrisLista==PriceList.PrisLista")
|
||||||
|
|
||||||
KundKategori = relationship("CustomerCategory")
|
KundKategori = relationship(
|
||||||
|
"CustomerCategory", uselist=False, foreign_keys='CustomerCategory.KundKategoriKod',
|
||||||
|
primaryjoin="Customer.kundkategorikod==CustomerCategory.KundKategoriKod")
|
||||||
LanguageCodes = relationship("LanguageCodes")
|
LanguageCodes = relationship("LanguageCodes")
|
||||||
|
|
||||||
WebUsers = relationship(
|
WebUsers = relationship(
|
||||||
|
|
@ -346,8 +347,8 @@ class PriceList(RawBaseModel):
|
||||||
class PriceListItem(RawBaseModel):
|
class PriceListItem(RawBaseModel):
|
||||||
__tablename__ = 'prl'
|
__tablename__ = 'prl'
|
||||||
__column_map__ = {'ArtNr': 'ArticleNumber', 'vb_pris': 'UnitPrice',
|
__column_map__ = {'ArtNr': 'ArticleNumber', 'vb_pris': 'UnitPrice',
|
||||||
'MarkUpBelopp': 'UnitPriceFactor', 'NollFaktor': 'NullPriceAllowed'}
|
'MarkUpBelopp': 'UnitPriceFactor', 'KodNollPris': 'NullPriceAllowed'}
|
||||||
__to_dict_only__ = ('ArtNr', 'vb_pris', 'MarkUpBelopp', 'NollFaktor', 'Price')
|
__to_dict_only__ = ('ArtNr', 'vb_pris', 'MarkUpBelopp', 'KodNollPris', 'Price')
|
||||||
__to_dict_filter__ = ['PriceList']
|
__to_dict_filter__ = ['PriceList']
|
||||||
|
|
||||||
# Do not serialize price list relationship
|
# Do not serialize price list relationship
|
||||||
|
|
@ -370,8 +371,12 @@ class PriceListItem(RawBaseModel):
|
||||||
@hybrid_property
|
@hybrid_property
|
||||||
def Price(self):
|
def Price(self):
|
||||||
if not self.vb_pris and not self.MarkUpBelopp:
|
if not self.vb_pris and not self.MarkUpBelopp:
|
||||||
|
if self.KodNollPris == "1":
|
||||||
|
return 0
|
||||||
|
|
||||||
|
MarkUpBelop = self.PriceList.MarkUpBelopp if self.PriceList.MarkUpBelopp else 0
|
||||||
return (
|
return (
|
||||||
(self.Article.ArtListPris + self.PriceList.MarkUpBelopp) *
|
(self.Article.ArtListPris + MarkUpBelop) *
|
||||||
self.Article.get_unit_conv())
|
self.Article.get_unit_conv())
|
||||||
if self.vb_pris:
|
if self.vb_pris:
|
||||||
return self.vb_pris * self.Article.get_unit_conv()
|
return self.vb_pris * self.Article.get_unit_conv()
|
||||||
|
|
@ -390,9 +395,10 @@ class Order(RawBaseModel):
|
||||||
'KundBestNr': 'CustomerContact', 'KundRef2': 'CustomerReference',
|
'KundBestNr': 'CustomerContact', 'KundRef2': 'CustomerReference',
|
||||||
'GodsMarke1': 'ShippingInfo', 'GodsMarke2': 'InternalInfo',
|
'GodsMarke1': 'ShippingInfo', 'GodsMarke2': 'InternalInfo',
|
||||||
'TA_MailNotified': 'ShippingEmail', 'TA_PhonNotifiedNo': 'ShippingPhone',
|
'TA_MailNotified': 'ShippingEmail', 'TA_PhonNotifiedNo': 'ShippingPhone',
|
||||||
'TA_SMSNotifiedNo': 'ShippingSMS', 'LevSattKod': 'ShippingTypeCode'}
|
'TA_SMSNotifiedNo': 'ShippingSMS', 'LevSattKod': 'ShippingTypeCode',
|
||||||
|
'OrdBerLevDat': 'RequestedDeliveryDate'}
|
||||||
__to_dict_only__ = ('OrderNr', 'FtgNr', 'OrdDatum', 'OrdStat', 'CompanyName', 'LevSattKod',
|
__to_dict_only__ = ('OrderNr', 'FtgNr', 'OrdDatum', 'OrdStat', 'CompanyName', 'LevSattKod',
|
||||||
'OrdLevAdr1', 'OrdLevAdr2', 'OrdLevAdr3',
|
'OrdLevAdr1', 'OrdLevAdr2', 'OrdLevAdr3', 'OrdBerLevDat',
|
||||||
'OrdLevAdrLandsKod', 'KundBestNr', 'KundRef2', 'GodsMarke1',
|
'OrdLevAdrLandsKod', 'KundBestNr', 'KundRef2', 'GodsMarke1',
|
||||||
'GodsMarke2', 'OrderItems', 'AddrPostalCode', 'AddrCity',
|
'GodsMarke2', 'OrderItems', 'AddrPostalCode', 'AddrCity',
|
||||||
'TA_MailNotified', 'TA_PhonNotifiedNo', 'TA_SMSNotifiedNo')
|
'TA_MailNotified', 'TA_PhonNotifiedNo', 'TA_SMSNotifiedNo')
|
||||||
|
|
@ -401,6 +407,7 @@ class Order(RawBaseModel):
|
||||||
'adapters': {
|
'adapters': {
|
||||||
**{
|
**{
|
||||||
'OrdDatum': lambda ord_date, *_: ord_date.strftime("%Y-%m-%d"),
|
'OrdDatum': lambda ord_date, *_: ord_date.strftime("%Y-%m-%d"),
|
||||||
|
'OrdBerLevDat': lambda ord_date, *_: ord_date.strftime("%Y-%m-%d"),
|
||||||
},
|
},
|
||||||
**RawBaseModel.__dict_args__['adapters']
|
**RawBaseModel.__dict_args__['adapters']
|
||||||
}
|
}
|
||||||
|
|
@ -444,7 +451,8 @@ class Order(RawBaseModel):
|
||||||
|
|
||||||
def create(self, webusername=None):
|
def create(self, webusername=None):
|
||||||
# TODO: Extend with additional functionlity if desired.
|
# TODO: Extend with additional functionlity if desired.
|
||||||
self['OrderNr'], invoicing_possible = OrderHead(self['FtgNr'], webusername).callproc()
|
self['OrderNr'], invoicing_possible = OrderHead(
|
||||||
|
self['FtgNr'], webusername, pers_sign=self['PersSign']).callproc()
|
||||||
return self, invoicing_possible
|
return self, invoicing_possible
|
||||||
|
|
||||||
def save(self, invoiced=False, webusername=None):
|
def save(self, invoiced=False, webusername=None):
|
||||||
|
|
@ -462,15 +470,19 @@ class OrderItem(RawBaseModel):
|
||||||
__tablename__ = 'orp'
|
__tablename__ = 'orp'
|
||||||
__column_map__ = {'OrdRadNr': 'OrderRowNumber', 'vb_pris': 'UnitPrice',
|
__column_map__ = {'OrdRadNr': 'OrderRowNumber', 'vb_pris': 'UnitPrice',
|
||||||
'ArtNr': 'ArticleNumber', 'OrdAntal': 'UnitAmount',
|
'ArtNr': 'ArticleNumber', 'OrdAntal': 'UnitAmount',
|
||||||
'OrdAntalAltEnh': 'AltUnitAmount', 'AltEnhetKod': 'AltUnit'}
|
'OrdAntalAltEnh': 'AltUnitAmount', 'AltEnhetKod': 'AltUnit',
|
||||||
|
'OrdBegLevDat': 'RequestedDeliveryDate'}
|
||||||
__to_dict_only__ = ('OrdRadNr', 'vb_pris', 'ArtNr', 'ArticleName', 'OrdAntal',
|
__to_dict_only__ = ('OrdRadNr', 'vb_pris', 'ArtNr', 'ArticleName', 'OrdAntal',
|
||||||
'OrdAntalAltEnh', 'AltEnhetKod')
|
'OrdAntalAltEnh', 'AltEnhetKod', 'OrdBegLevDat')
|
||||||
|
|
||||||
# Do not serialize order relationship
|
# Do not serialize order relationship
|
||||||
__dict_args__ = {
|
__dict_args__ = {
|
||||||
'adapters': {
|
'adapters': {
|
||||||
**{
|
**{
|
||||||
Order: None,
|
Order: None,
|
||||||
|
'OrdBegLevDat': lambda req_date, *_: (
|
||||||
|
req_date.strftime("%Y-%m-%d")
|
||||||
|
if not isinstance(req_date, str) else req_date),
|
||||||
},
|
},
|
||||||
**RawBaseModel.__dict_args__['adapters']
|
**RawBaseModel.__dict_args__['adapters']
|
||||||
}
|
}
|
||||||
|
|
@ -499,6 +511,7 @@ class OrderItem(RawBaseModel):
|
||||||
row_no = OrderRow(
|
row_no = OrderRow(
|
||||||
company_no=self['FtgNr'], order_no=self['OrderNr'], item_no=self['ArtNr'],
|
company_no=self['FtgNr'], order_no=self['OrderNr'], item_no=self['ArtNr'],
|
||||||
qty=self['OrdAntal'], qty_alt_unit=self['OrdAntalAltEnh'],
|
qty=self['OrdAntal'], qty_alt_unit=self['OrdAntalAltEnh'],
|
||||||
alt_unit=self['AltEnhetKod'], pers_sign='marlin').callproc()
|
alt_unit=self['AltEnhetKod'], requested_date=self['OrdBegLevDat'],
|
||||||
|
pers_sign=self['PersSign']).callproc()
|
||||||
self['OrdRadNr'] = row_no
|
self['OrdRadNr'] = row_no
|
||||||
return self
|
return self
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ import pymssql
|
||||||
from collections import OrderedDict
|
from collections import OrderedDict
|
||||||
from pyjeeves.models import db
|
from pyjeeves.models import db
|
||||||
from pyjeeves import logging
|
from pyjeeves import logging
|
||||||
|
from datetime import date
|
||||||
# from datetime import datetime
|
# from datetime import datetime
|
||||||
# from decimal import Decimal
|
# from decimal import Decimal
|
||||||
|
|
||||||
|
|
@ -102,14 +103,14 @@ class OrderHead(StoredProcedure):
|
||||||
webapp031 and WEBAPP003 determines default order status"""
|
webapp031 and WEBAPP003 determines default order status"""
|
||||||
# TODO: Extend with additional functionlity if desired.
|
# TODO: Extend with additional functionlity if desired.
|
||||||
|
|
||||||
def __init__(self, company_no, web_user_name):
|
def __init__(self, company_no, web_user_name, pers_sign='biz'):
|
||||||
super(OrderHead, self).__init__('Jeeves_Esales_CreateOrder')
|
super(OrderHead, self).__init__('Jeeves_Esales_CreateOrder')
|
||||||
|
|
||||||
self['c_CompanyNo'] = company_no
|
self['c_CompanyNo'] = company_no
|
||||||
|
|
||||||
# Some defaults:
|
# Some defaults:
|
||||||
self['c_ForetagKod'] = 1 # Hardcoded to LK
|
self['c_ForetagKod'] = 1 # Hardcoded to LK
|
||||||
self['c_PersSign'] = 'marlin' # From API profile, or default
|
self['c_PersSign'] = str(pers_sign) # From API profile, or default
|
||||||
# self['c_OrderType'] = None # Default set by WEBAPP008
|
# self['c_OrderType'] = None # Default set by WEBAPP008
|
||||||
# self['c_TemplateRowID'] = None # No template used
|
# self['c_TemplateRowID'] = None # No template used
|
||||||
# self['c_Saljare'] = None # 600 # From API profile, or default
|
# self['c_Saljare'] = None # 600 # From API profile, or default
|
||||||
|
|
@ -140,7 +141,8 @@ class OrderRow(StoredProcedure):
|
||||||
AltEnhetKod logic needs to have been added to the procedure"""
|
AltEnhetKod logic needs to have been added to the procedure"""
|
||||||
|
|
||||||
def __init__(self, company_no, order_no, item_no,
|
def __init__(self, company_no, order_no, item_no,
|
||||||
qty=None, qty_alt_unit=None, alt_unit=None, pers_sign='biz'):
|
qty=None, qty_alt_unit=None, alt_unit=None,
|
||||||
|
requested_date=None, pers_sign='biz'):
|
||||||
super(OrderRow, self).__init__('Jeeves_Esales_AddOrderRow')
|
super(OrderRow, self).__init__('Jeeves_Esales_AddOrderRow')
|
||||||
|
|
||||||
self['c_CompanyNo'] = str(company_no)
|
self['c_CompanyNo'] = str(company_no)
|
||||||
|
|
@ -152,7 +154,9 @@ class OrderRow(StoredProcedure):
|
||||||
self['c_PersSign'] = str(pers_sign)
|
self['c_PersSign'] = str(pers_sign)
|
||||||
|
|
||||||
# Used to set date for delivery (c_OrdBegLevDat) and (c_OrdBerLevDat)
|
# Used to set date for delivery (c_OrdBegLevDat) and (c_OrdBerLevDat)
|
||||||
self['c_RequestedDate'] = None
|
self['c_RequestedDate'] = (
|
||||||
|
requested_date.strftime('%Y%m%d')
|
||||||
|
if isinstance(requested_date, date) else requested_date)
|
||||||
|
|
||||||
# Some defaults:
|
# Some defaults:
|
||||||
self['c_ForetagKod'] = 1 # Hardcoded to LK
|
self['c_ForetagKod'] = 1 # Hardcoded to LK
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@
|
||||||
from pyjeeves.models.raw import Company as CompanyModel, Customer as CustomerModel
|
from pyjeeves.models.raw import Company as CompanyModel, Customer as CustomerModel
|
||||||
from pyjeeves.models import db
|
from pyjeeves.models import db
|
||||||
from sqlalchemy.sql.expression import and_
|
from sqlalchemy.sql.expression import and_
|
||||||
|
from sqlalchemy.orm.strategy_options import Load
|
||||||
|
|
||||||
from pyjeeves import logging
|
from pyjeeves import logging
|
||||||
logger = logging.getLogger("PyJeeves." + __name__)
|
logger = logging.getLogger("PyJeeves." + __name__)
|
||||||
|
|
@ -25,10 +26,24 @@ class Company():
|
||||||
return [c.CompanyModel for c in cust]
|
return [c.CompanyModel for c in cust]
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_list(ftg_nr=[]):
|
def get_customer_numbers(category_list=[10], class_list=[], filter_inactive=True):
|
||||||
return db.raw.query(CompanyModel).filter(
|
category_in = CustomerModel.kundkategorikod.in_(category_list) if category_list else and_()
|
||||||
CompanyModel.FtgNr.in_(ftg_nr)
|
class_in = CustomerModel.kundklass.in_(class_list) if class_list else and_()
|
||||||
).all()
|
inactive = and_(CustomerModel.Makulerad == 0) if filter_inactive else and_()
|
||||||
|
cust = db.raw.query(CustomerModel).options(
|
||||||
|
Load(CustomerModel).noload('*')).filter(
|
||||||
|
and_(category_in, class_in, inactive)).all()
|
||||||
|
return [c.FtgNr for c in cust]
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def get_list(ftg_nr=[], filter_=and_(CustomerModel.Makulerad == 0), offset=0, limit=100):
|
||||||
|
ftg_filter = and_()
|
||||||
|
if ftg_nr:
|
||||||
|
ftg_filter = CompanyModel.FtgNr.in_(ftg_nr)
|
||||||
|
|
||||||
|
return db.raw.query(CompanyModel).join(CustomerModel).filter(
|
||||||
|
and_(ftg_filter, filter_)).order_by(
|
||||||
|
CompanyModel.FtgNr.desc()).offset(offset).limit(limit).all()
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
|
|
|
||||||
|
|
@ -44,8 +44,9 @@ class Order():
|
||||||
).all()
|
).all()
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def create(customer_no, head={}, items=[], web_user_name=None):
|
def create(customer_no, head={}, items=[], web_user_name=None, pers_sign='biz'):
|
||||||
head['CompanyNumber'] = str(customer_no)
|
head['CompanyNumber'] = str(customer_no)
|
||||||
|
head['PersSign'] = str(pers_sign)
|
||||||
|
|
||||||
# Create order from head dict to get an order number
|
# Create order from head dict to get an order number
|
||||||
order, invoice_possible = OrderModel(head).create(web_user_name)
|
order, invoice_possible = OrderModel(head).create(web_user_name)
|
||||||
|
|
@ -53,7 +54,7 @@ class Order():
|
||||||
raise
|
raise
|
||||||
|
|
||||||
# Go through order items, if any, and save them to DB.
|
# Go through order items, if any, and save them to DB.
|
||||||
order['OrderItems'] = Order.create_rows(order['FtgNr'], order['OrderNr'], items)
|
order['OrderItems'] = Order.create_rows(order, items)
|
||||||
|
|
||||||
# Save the information in the order object
|
# Save the information in the order object
|
||||||
# Boolean argument deceides if order has contact person, and should be set 'registered'
|
# Boolean argument deceides if order has contact person, and should be set 'registered'
|
||||||
|
|
@ -62,14 +63,20 @@ class Order():
|
||||||
return order
|
return order
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def create_rows(company_no, order_no, items=[]):
|
def create_rows(order, items=[], pers_sign='biz'):
|
||||||
rv = []
|
rv = []
|
||||||
|
|
||||||
for item in items:
|
for item in items:
|
||||||
if not isinstance(item, OrderItemModel):
|
if not isinstance(item, OrderItemModel):
|
||||||
item = OrderItemModel(item)
|
item = OrderItemModel(item)
|
||||||
item['OrderNr'] = order_no
|
|
||||||
item['FtgNr'] = company_no
|
# Set RequestedDeliveryDate from order head if not specified for items.
|
||||||
|
if order['OrdBerLevDat'] and not item['OrdBegLevDat']:
|
||||||
|
item['OrdBegLevDat'] = order['OrdBerLevDat']
|
||||||
|
|
||||||
|
item['OrderNr'] = order['OrderNr']
|
||||||
|
item['FtgNr'] = order['FtgNr']
|
||||||
|
item['PersSign'] = pers_sign
|
||||||
rv.append(item.save())
|
rv.append(item.save())
|
||||||
|
|
||||||
return rv
|
return rv
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue