Subversion Repositories SmartDukaan

Rev

Rev 7392 | Rev 7399 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
6903 anupam.sin 1
# -*- coding: utf-8 -*-
2
 
104 ashish 3
'''
4
Created on 29-Mar-2010
5
 
2536 chandransh 6
@author: Chandranshu
104 ashish 7
'''
2536 chandransh 8
 
4369 rajveer 9
from datetime import date, timedelta
7151 amit.gupta 10
from decimal import Decimal
11
from elixir import *
6424 rajveer 12
from math import ceil
5944 mandeep.dh 13
from random import randrange
7151 amit.gupta 14
from reportlab.lib.enums import TA_CENTER, TA_JUSTIFY
15
from reportlab.lib.styles import ParagraphStyle, getSampleStyleSheet
3499 mandeep.dh 16
from reportlab.lib.units import inch
2536 chandransh 17
from reportlab.pdfgen.canvas import Canvas
6980 anupam.sin 18
from reportlab.platypus import SimpleDocTemplate, Paragraph, Spacer, Image, \
19
    BaseDocTemplate, Frame, PageTemplate
7151 amit.gupta 20
from reportlab.rl_config import defaultPageSize
5944 mandeep.dh 21
from shop2020.clients.AlertClient import AlertClient
3499 mandeep.dh 22
from shop2020.clients.CatalogClient import CatalogClient
23
from shop2020.clients.HelperClient import HelperClient
5944 mandeep.dh 24
from shop2020.clients.InventoryClient import InventoryClient
3499 mandeep.dh 25
from shop2020.clients.LogisticsClient import LogisticsClient
2747 chandransh 26
from shop2020.clients.PaymentClient import PaymentClient
7151 amit.gupta 27
from shop2020.clients.PromotionClient import PromotionClient
3499 mandeep.dh 28
from shop2020.clients.UserClient import UserClient
29
from shop2020.clients.WarehouseClient import WarehouseClient
7151 amit.gupta 30
from shop2020.config.client.ConfigClient import ConfigClient
3499 mandeep.dh 31
from shop2020.model.v1 import order
6048 rajveer 32
from shop2020.model.v1.order.impl import DataService, RechargeService
7198 amar.kumar 33
from shop2020.model.v1.order.impl.Convertors import to_t_emi_scheme, to_t_order
3499 mandeep.dh 34
from shop2020.model.v1.order.impl.DataService import Transaction, LineItem, \
4435 mandeep.dh 35
    Order, BatchNoGenerator, InvoiceIDGenerator, TransactionRequiringExtraProcessing, \
5348 anupam.sin 36
    OrderInventory, Alert, PaymentSettlement, EBSSettlementSummary, \
7151 amit.gupta 37
    CodVerificationAgent, Attribute, RechargeVoucherTracker, EmiScheme, MiscCharges, \
38
    BlockedIpRange, DeniedIpAddress, InsuranceDetailForOrder, DocumentStore, \
39
    RechargeTransaction, HotspotStore, WalletForCompany, WalletHistoryForCompany, \
7311 kshitij.so 40
    FRC, OperatorSeries, SourceDetail, Company, \
7386 anupam.sin 41
    AmazonOrder, StoreOrderDetail, EdcBank
7151 amit.gupta 42
from shop2020.model.v1.order.impl.model.BaseOrder import BaseOrder
43
from shop2020.model.v1.order.impl.model.DTHRechargeOrder import DTHRechargeOrder
6000 mandeep.dh 44
from shop2020.model.v1.order.impl.model.MobileRechargeOrder import \
45
    MobileRechargeOrder
7151 amit.gupta 46
from shop2020.model.v1.order.impl.model.RechargeDenomination import \
47
    RechargeDenomination
48
from shop2020.model.v1.order.impl.model.RechargeOrder import RechargeOrder
49
from shop2020.model.v1.order.impl.model.RechargePlan import RechargePlan
2687 chandransh 50
from shop2020.model.v1.order.impl.model.ReturnOrder import ReturnOrder
7151 amit.gupta 51
from shop2020.model.v1.order.impl.model.ServiceAvailability import \
52
    ServiceAvailability
53
from shop2020.model.v1.order.impl.model.ServiceProvider import ServiceProvider
54
from shop2020.model.v1.order.impl.model.TelecomCircle import TelecomCircle
55
from shop2020.model.v1.order.impl.model.UserWallet import UserWallet
56
from shop2020.model.v1.order.impl.model.UserWalletHistory import \
57
    UserWalletHistory
5944 mandeep.dh 58
from shop2020.thriftpy.alert.ttypes import MonitoredEntity, EntityType
5527 anupam.sin 59
from shop2020.thriftpy.logistics.ttypes import DeliveryType, PickUpType
6000 mandeep.dh 60
from shop2020.thriftpy.model.v1.catalog.ttypes import ItemType
5944 mandeep.dh 61
from shop2020.thriftpy.model.v1.inventory.ttypes import BillingType, \
62
    InventoryServiceException, WarehouseType, InventoryType
4435 mandeep.dh 63
from shop2020.thriftpy.model.v1.order.ttypes import TransactionServiceException, \
64
    TransactionStatus, OrderStatus, DelayReason, ExtraTransactionProcessingType, \
7151 amit.gupta 65
    HotspotAction, TimeoutSummary, OrderStatusGroups, OrderType, RechargeOrderStatus, \
7393 anupam.sin 66
    RechargeType, RechargeStatistics, DeviceNumberInfo, EmiChargeType, PayMethod, OrderSource,\
67
    StorePaymentStatus
5944 mandeep.dh 68
from shop2020.thriftpy.model.v1.user.ttypes import VoucherType
4421 mandeep.dh 69
from shop2020.thriftpy.payments.ttypes import PaymentException
5110 mandeep.dh 70
from shop2020.thriftpy.warehouse.ttypes import ScanType, \
71
    WarehouseServiceException
6000 mandeep.dh 72
from shop2020.utils.EmailAttachmentSender import mail, get_attachment_part
855 rajveer 73
from shop2020.utils.Utils import to_py_date, to_java_date
4008 mandeep.dh 74
from sqlalchemy.orm.exc import NoResultFound, MultipleResultsFound
3499 mandeep.dh 75
from sqlalchemy.sql import func
7151 amit.gupta 76
from sqlalchemy.sql.expression import and_, or_, desc, not_, distinct, cast, \
77
    between
3499 mandeep.dh 78
from string import Template
79
from textwrap import dedent
80
import datetime
5944 mandeep.dh 81
import httplib
3499 mandeep.dh 82
import logging
83
import os
4421 mandeep.dh 84
import sys
4435 mandeep.dh 85
import time
4421 mandeep.dh 86
import traceback
5806 rajveer 87
import urllib
7308 rajveer 88
import base64
6307 anupam.sin 89
 
5944 mandeep.dh 90
 
3499 mandeep.dh 91
logging.basicConfig(level=logging.DEBUG)
104 ashish 92
 
5966 rajveer 93
sourceId = int(ConfigClient().get_property("sourceid"))
94
mail_user = 'cnc.center@shop2020.in'
95
mail_password = '5h0p2o2o'
96
help_user = 'help@shop2020.in'
97
help_password = '5h0p2o2o'
6029 rajveer 98
source_url = 'www.saholic.com'
99
source_name = 'Saholic'
3499 mandeep.dh 100
 
4763 rajveer 101
PREPAID_SHIPPING_CUTOFF_TIME = 15
4019 chandransh 102
COD_SHIPPING_CUTOFF_TIME = 12
3499 mandeep.dh 103
 
2819 chandransh 104
PAGE_HEIGHT=defaultPageSize[1]
105
PAGE_WIDTH=defaultPageSize[0]
106
 
4763 rajveer 107
billedOrdersColorMap = {}
108
 
3499 mandeep.dh 109
ORDER_STATUS_TO_USER_TRUST_LEVEL_DELTA_DICT = {
4873 mandeep.dh 110
        OrderStatus.RTO_RESHIPPED    :  3,
111
        OrderStatus.RTO_IN_TRANSIT   : -5,
112
        OrderStatus.DELIVERY_SUCCESS :  1,
113
        OrderStatus.DOA_CERT_INVALID : -5
3499 mandeep.dh 114
}
115
 
5783 rajveer 116
delhi_pincodes = ['110001','110002','110003','110004','110005','110006','110007','110008','110009','110010','110011','110012','110013','110014','110015',\
117
                '110016','110017','110018','110019','110020','110021','110022','110023','110024','110025','110026','110027','110028','110029','110030',\
118
                '110031','110032','110033','110034','110035','110037','110038','110041','110042','110044','110045','110046','110047','110048','110049',\
119
                '110051','110052','110053','110054','110055','110056','110057','110058','110059','110060','110061','110062','110063','110064','110065',\
120
                '110066','110067','110068','110070','110071','110074','110075','110076','110078','110081','110082','110083','110084','110085','110086',\
121
                '110087','110088','110089','110091','110092','110093','110094','110095','110096','110101','110103','110104','110105','110106','110107',\
122
                '110108','110109','110110','110112','110113','110114','110115','110116','110117','110118','110119','110120','110122','110124','110125',\
123
                '110301','110302','110501','110502','110503','110504','110505','110510','110511','110512','110601','110602','110603','110604','110605',\
124
                '110606','110607','110608','110609']
125
 
104 ashish 126
def get_new_transaction():
127
    transaction = Transaction()
128
    transaction.createdOn = datetime.datetime.now()
738 chandransh 129
    transaction.status = TransactionStatus.INIT
104 ashish 130
    transaction.status_message = "New transaction"
483 rajveer 131
    return transaction
132
 
133
def create_order(t_order):
134
    order = Order()
135
    if t_order.warehouse_id:
136
        order.warehouse_id = t_order.warehouse_id
509 rajveer 137
    if t_order.logistics_provider_id:    
483 rajveer 138
        order.logistics_provider_id = t_order.logistics_provider_id
139
        order.airwaybill_no = t_order.airwaybill_no
140
        order.tracking_id = t_order.tracking_id
4009 chandransh 141
    if t_order.expected_shipping_time:
4019 chandransh 142
        order.expected_shipping_time = to_py_date(t_order.expected_shipping_time).replace(hour=PREPAID_SHIPPING_CUTOFF_TIME, minute=0, second=0)
4102 chandransh 143
        order.promised_shipping_time = order.expected_shipping_time
4009 chandransh 144
    if t_order.expected_delivery_time:
483 rajveer 145
        order.expected_delivery_time = to_py_date(t_order.expected_delivery_time)
4102 chandransh 146
        order.promised_delivery_time = order.expected_delivery_time
483 rajveer 147
    if t_order.customer_id:    
148
        order.customer_id = t_order.customer_id
149
        order.customer_name = t_order.customer_name
860 rajveer 150
        order.customer_city = t_order.customer_city
151
        order.customer_state = t_order.customer_state
483 rajveer 152
        order.customer_mobilenumber = t_order.customer_mobilenumber
153
        order.customer_pincode = t_order.customer_pincode
738 chandransh 154
        order.customer_address1 = t_order.customer_address1
155
        order.customer_address2 = t_order.customer_address2
483 rajveer 156
        order.customer_email = t_order.customer_email
157
    #new status and status description to be added    
716 rajveer 158
    order.status = t_order.status  
483 rajveer 159
    order.statusDescription = t_order.statusDescription
160
    order.total_amount = t_order.total_amount
6318 rajveer 161
    order.gvAmount = t_order.gvAmount
483 rajveer 162
    order.total_weight = t_order.total_weight
163
    if t_order.created_timestamp:
164
        order.created_timestamp = to_py_date(t_order.created_timestamp)
165
    else:
685 chandransh 166
        order.created_timestamp = datetime.datetime.now()
5555 rajveer 167
    order.pickupStoreId = t_order.pickupStoreId
7033 anupam.sin 168
    if t_order.insurer:
169
        order.insurer = t_order.insurer
170
        order.insuranceAmount = t_order.insuranceAmount
6903 anupam.sin 171
    if order.insurer > 0:
172
        insuranceDetail = InsuranceDetailForOrder()
173
        insuranceDetail.dob = t_order.dob
174
        insuranceDetail.guardianName = t_order.guardianName
175
        insuranceDetail.order = order
7190 amar.kumar 176
    if t_order.freebieItemId:
177
        order.freebieItemId = t_order.freebieItemId
7293 anupam.sin 178
    order.source = t_order.source
179
    order.advanceAmount = t_order.advanceAmount
180
    order.storeId = t_order.storeId
483 rajveer 181
    return order
182
 
183
def create_transaction(t_transaction):
184
    t_orders = t_transaction.orders
185
    if not t_orders:
186
        raise TransactionServiceException(101, "Orders missing from the transaction")
187
    transaction = get_new_transaction()
188
    transaction.customer_id = t_transaction.customer_id 
189
    transaction.shopping_cart_id = t_transaction.shoppingCartid
2219 varun.gupt 190
    transaction.coupon_code = t_transaction.coupon_code
2815 vikas 191
    transaction.session_source = t_transaction.sessionSource
192
    transaction.session_start_time = to_py_date(t_transaction.sessionStartTime)
3858 vikas 193
    transaction.first_source = t_transaction.firstSource
194
    transaction.first_source_start_time = to_py_date(t_transaction.firstSourceTime)
483 rajveer 195
 
6389 rajveer 196
    totalAmount = 0
483 rajveer 197
    for t_order in t_orders:
198
        order = create_order(t_order)
6389 rajveer 199
        totalAmount = totalAmount + order.total_amount
483 rajveer 200
        order.transaction = transaction 
201
        for line_item in t_order.lineitems:
202
            litem = LineItem()
716 rajveer 203
            litem.item_id = line_item.item_id
963 chandransh 204
            litem.productGroup = line_item.productGroup
483 rajveer 205
            litem.brand = line_item.brand
206
            if line_item.model_number:
207
                litem.model_number = line_item.model_number
208
            if line_item.model_name:    
209
                litem.model_name = line_item.model_name
908 chandransh 210
            if line_item.color:
211
                litem.color = line_item.color
483 rajveer 212
            if line_item.extra_info:
213
                litem.extra_info = line_item.extra_info
214
            litem.quantity = line_item.quantity
215
            litem.unit_price = line_item.unit_price
216
            litem.unit_weight = line_item.unit_weight
217
            litem.total_price = line_item.total_price
218
            litem.total_weight = line_item.total_weight
4283 anupam.sin 219
            '''litem.transfer_price = line_item.transfer_price'''
4172 rajveer 220
            litem.dealText = line_item.dealText
4295 varun.gupt 221
            litem.warranty_expiry_timestamp = to_py_date(line_item.warrantry_expiry_timestamp)
1976 varun.gupt 222
 
483 rajveer 223
            """
224
            if line_item.addedOn:
225
                litem.added_on = to_py_date(line_item.addedOn)
226
            else:
227
                litem.added_on = datetime.datetime.now()
228
            """
229
            litem.order = order
230
    session.commit()
6389 rajveer 231
 
232
    generateOtherCharges(transaction, t_transaction.emiSchemeId, totalAmount)
233
 
483 rajveer 234
    return transaction.id
235
 
6389 rajveer 236
def generateOtherCharges(transaction, emiSchemeId, totalAmount):
237
    emiScheme = EmiScheme.get_by(id=emiSchemeId)
238
    if not emiScheme:
239
        return
240
 
241
    if totalAmount < emiScheme.minAmount:
242
        return
243
 
244
    emiCharge = 0
245
    if emiScheme.chargeType == EmiChargeType.FIXED:
6424 rajveer 246
        emiCharge = ceil(emiScheme.chargeValue)
6389 rajveer 247
    if emiScheme.chargeType == EmiChargeType.PERCENTAGE:
6424 rajveer 248
        emiCharge = ceil(totalAmount*(emiScheme.chargeValue)/100)
6736 amit.gupta 249
 
250
    if transaction.coupon_code is not None and transaction.coupon_code != "":    
251
        try:
252
            promotion_client = PromotionClient().get_client()
253
            emis = promotion_client.getEmiDiscount(transaction.shopping_cart_id)
254
            if emis.has_key(emiSchemeId):
255
                discount = emis.get(emiSchemeId)
256
                if emiCharge > discount:
257
                    emiCharge -= discount
258
                else:
259
                    emiCharge = 0
260
        except:
261
            print "Could not get emi discounts from promotion"
262
 
6389 rajveer 263
    miscCharge = MiscCharges()
264
    miscCharge.transaction = transaction
265
    miscCharge.chargeType = 1 ##EMI charges
266
    miscCharge.chargeAmount = emiCharge
267
    session.commit()
268
 
483 rajveer 269
def get_transaction(transaction_id):
270
    transaction = Transaction.get_by(id=transaction_id)
271
    if not transaction:
272
        raise TransactionServiceException(108, "no such transaction")
273
 
274
    return transaction
275
 
276
def get_transactions_for_customer(customer_id, from_date, to_date, status):
277
    if not customer_id:
278
        raise TransactionServiceException(101, "bad customer id")
279
    query = Transaction.query.filter(Transaction.customer_id == customer_id)
1493 vikas 280
    if status is not None:
483 rajveer 281
        query = query.filter(Transaction.status == status)
282
    if from_date:
283
        query = query.filter(Transaction.createdOn >from_date)
284
    if to_date:
285
        query = query.filter(Transaction.createdOn < to_date)
286
    return query.all()
287
 
288
def get_transactions_for_shopping_cart_id(shopping_cart_id):
289
    transactions = Transaction.query.filter_by(shopping_cart_id=shopping_cart_id).all()
290
    return transactions
291
 
292
def get_transaction_status(transaction_id):
293
    if not transaction_id:
294
        raise TransactionServiceException(101, "bad transaction id")
295
 
296
    transaction = get_transaction(transaction_id)
297
 
298
    return transaction.status
299
 
7293 anupam.sin 300
def change_transaction_status(transaction_id, new_status, description, pickUp, orderType, source):
483 rajveer 301
    transaction = get_transaction(transaction_id)
302
    transaction.status = new_status
303
    transaction.status_message = description
5783 rajveer 304
    ## Assign runner in case of delhi pincodes
5784 rajveer 305
    if transaction.orders[0].pickupStoreId:
306
        logistics_client = LogisticsClient().get_client() 
307
        store = logistics_client.getPickupStore(transaction.orders[0].pickupStoreId)
308
        if delhi_pincodes.__contains__(store.pin):
5793 rajveer 309
            pickUp = PickUpType.RUNNER  
5783 rajveer 310
 
690 chandransh 311
    if new_status == TransactionStatus.FAILED:
312
        for order in transaction.orders:
313
            order.status = OrderStatus.PAYMENT_FAILED
2339 chandransh 314
            order.statusDescription = "Payment Failed"
4247 rajveer 315
    elif new_status == TransactionStatus.AUTHORIZED or new_status == TransactionStatus.FLAGGED:
690 chandransh 316
        for order in transaction.orders:
4247 rajveer 317
            if new_status == TransactionStatus.AUTHORIZED:
318
                order.status = OrderStatus.SUBMITTED_FOR_PROCESSING
319
                order.statusDescription = "Submitted to warehouse"
320
            elif new_status == TransactionStatus.FLAGGED:
321
                order.status = OrderStatus.PAYMENT_FLAGGED
322
                order.statusDescription = "Payment flagged by gateway"
3092 chandransh 323
            order.cod = False
5527 anupam.sin 324
            order.orderType = orderType
743 rajveer 325
            #After we got payment success, we will set logistics info also 
326
            logistics_client = LogisticsClient().get_client()
327
            #FIXME line item is only one now. If multiple will come, need to fix.
871 chandransh 328
            item_id = order.lineitems[0].item_id
5767 rajveer 329
            logistics_info = logistics_client.getLogisticsInfo(order.customer_pincode, item_id, DeliveryType.PREPAID, pickUp)
743 rajveer 330
 
1730 ankur.sing 331
            current_time = datetime.datetime.now()
332
            logistics_info.deliveryTime = adjust_delivery_time(current_time, logistics_info.deliveryTime)
4009 chandransh 333
            logistics_info.shippingTime = adjust_delivery_time(current_time, logistics_info.shippingTime)
6726 rajveer 334
            logistics_info.deliveryDelay = adjust_delivery_time(current_time, (logistics_info.shippingTime+logistics_info.deliveryDelay))
5110 mandeep.dh 335
 
6525 rajveer 336
            order.otg = logistics_info.otgAvailable
743 rajveer 337
            order.warehouse_id = logistics_info.warehouseId
5110 mandeep.dh 338
            order.fulfilmentWarehouseId = logistics_info.fulfilmentWarehouseId
743 rajveer 339
            order.logistics_provider_id = logistics_info.providerId
340
            order.airwaybill_no = logistics_info.airway_billno
341
            order.tracking_id = order.airwaybill_no
6726 rajveer 342
            order.courier_delivery_time = (current_time + datetime.timedelta(days=logistics_info.deliveryDelay)).replace(hour=PREPAID_SHIPPING_CUTOFF_TIME, minute=0, second=0)
4019 chandransh 343
            order.expected_shipping_time = (current_time + datetime.timedelta(days=logistics_info.shippingTime)).replace(hour=PREPAID_SHIPPING_CUTOFF_TIME, minute=0, second=0)
4102 chandransh 344
            order.promised_shipping_time = order.expected_shipping_time
5165 rajveer 345
            order.expected_delivery_time = (current_time + datetime.timedelta(days=logistics_info.deliveryTime)).replace(hour=PREPAID_SHIPPING_CUTOFF_TIME, minute=0, second=0)
3986 chandransh 346
            order.promised_delivery_time = order.expected_delivery_time 
871 chandransh 347
 
6718 rajveer 348
            if order.pickupStoreId:
349
                order.otg = False
350
 
5944 mandeep.dh 351
            inventory_client = InventoryClient().get_client()
5966 rajveer 352
            inventory_client.reserveItemInWarehouse(item_id, logistics_info.fulfilmentWarehouseId, sourceId, order.id, to_java_date(order.created_timestamp), to_java_date(order.promised_shipping_time), order.lineitems[0].quantity)
1351 varun.gupt 353
 
4316 anupam.sin 354
            try:
5944 mandeep.dh 355
                item_pricing = inventory_client.getItemPricing(item_id, -1)
4316 anupam.sin 356
                order.lineitems[0].transfer_price = item_pricing.transferPrice
6751 amar.kumar 357
                order.lineitems[0].nlc = item_pricing.nlc
4316 anupam.sin 358
            except:
359
                print "Not able to get transfer price. Skipping"
5944 mandeep.dh 360
 
361
            catalog_client = CatalogClient().get_client() 
5508 rajveer 362
            voucherAmount = catalog_client.getVoucherAmount(item_id, VoucherType.SPICEDECK_MOBILE)
363
            if voucherAmount:
5514 rajveer 364
                __create_recharge_voucher_tracker(order, voucherAmount, VoucherType.SPICEDECK_MOBILE)
5508 rajveer 365
 
3064 chandransh 366
    elif new_status == TransactionStatus.COD_IN_PROCESS:
367
        for order in transaction.orders:
4662 rajveer 368
            order.status = OrderStatus.COD_VERIFICATION_PENDING
3064 chandransh 369
            order.statusDescription = "Verification Pending"
370
            order.cod = True
5527 anupam.sin 371
            order.orderType = orderType
3064 chandransh 372
            #After we got payment success, we will set logistics info also 
373
            logistics_client = LogisticsClient().get_client()
374
            #FIXME line item is only one now. If multiple will come, need to fix.
375
            item_id = order.lineitems[0].item_id
5555 rajveer 376
            if order.pickupStoreId:
5885 mandeep.dh 377
                # Need to send prepaid awb number for store pick up orders
378
                logistics_info = logistics_client.getLogisticsEstimation(item_id, order.customer_pincode, DeliveryType.COD)
379
                prepaid_logistics_info = logistics_client.getLogisticsInfo(order.customer_pincode, item_id, DeliveryType.PREPAID, pickUp)
380
                logistics_info.airway_billno = prepaid_logistics_info.airway_billno
381
                logistics_info.providerId = prepaid_logistics_info.providerId
6525 rajveer 382
                # Will not provide OTG in pickup store
383
                order.otg = False
5555 rajveer 384
            else:
5767 rajveer 385
                logistics_info = logistics_client.getLogisticsInfo(order.customer_pincode, item_id, DeliveryType.COD, pickUp)
6525 rajveer 386
                order.otg = logistics_info.otgAvailable
7293 anupam.sin 387
 
3064 chandransh 388
            current_time = datetime.datetime.now()
389
            logistics_info.deliveryTime = adjust_delivery_time(current_time, logistics_info.deliveryTime)
4009 chandransh 390
            logistics_info.shippingTime = adjust_delivery_time(current_time, logistics_info.shippingTime)
6726 rajveer 391
            logistics_info.deliveryDelay = adjust_delivery_time(current_time, (logistics_info.shippingTime+logistics_info.deliveryDelay))
392
 
3064 chandransh 393
            order.warehouse_id = logistics_info.warehouseId
5110 mandeep.dh 394
            order.fulfilmentWarehouseId = logistics_info.fulfilmentWarehouseId
3064 chandransh 395
            order.logistics_provider_id = logistics_info.providerId
396
            order.airwaybill_no = logistics_info.airway_billno
397
            order.tracking_id = order.airwaybill_no
6726 rajveer 398
            order.courier_delivery_time = (current_time + datetime.timedelta(days=logistics_info.deliveryDelay)).replace(hour=COD_SHIPPING_CUTOFF_TIME, minute=0, second=0)
4019 chandransh 399
            order.expected_shipping_time = (current_time + datetime.timedelta(days=logistics_info.shippingTime)).replace(hour=COD_SHIPPING_CUTOFF_TIME, minute=0, second=0)
4102 chandransh 400
            order.promised_shipping_time = order.expected_shipping_time
5165 rajveer 401
            order.expected_delivery_time = (current_time + datetime.timedelta(days=logistics_info.deliveryTime)).replace(hour=COD_SHIPPING_CUTOFF_TIME, minute=0, second=0)
3986 chandransh 402
            order.promised_delivery_time = order.expected_delivery_time
3064 chandransh 403
 
5944 mandeep.dh 404
            inventory_client = InventoryClient().get_client()
5966 rajveer 405
            inventory_client.reserveItemInWarehouse(item_id, logistics_info.fulfilmentWarehouseId, sourceId, order.id, to_java_date(order.created_timestamp), to_java_date(order.promised_shipping_time), order.lineitems[0].quantity)
3064 chandransh 406
 
4316 anupam.sin 407
            try:
5944 mandeep.dh 408
                item_pricing = inventory_client.getItemPricing(item_id, -1)
6751 amar.kumar 409
                order.lineitems[0].transfer_price = item_pricing.transferPrice
410
                order.lineitems[0].nlc = item_pricing.nlc        
4316 anupam.sin 411
            except:
412
                print "Not able to get transfer price. Skipping"
5508 rajveer 413
 
5944 mandeep.dh 414
            catalog_client = CatalogClient().get_client()
5508 rajveer 415
            voucherAmount = catalog_client.getVoucherAmount(item_id, VoucherType.SPICEDECK_MOBILE)
416
            if voucherAmount:
5514 rajveer 417
                __create_recharge_voucher_tracker(order, voucherAmount, VoucherType.SPICEDECK_MOBILE)
483 rajveer 418
    session.commit()
3499 mandeep.dh 419
 
3530 mandeep.dh 420
    try:
7308 rajveer 421
        if order.source == OrderSource.WEBSITE:    
422
            if new_status == TransactionStatus.COD_IN_PROCESS:
423
                transaction_requiring_extra_processing = TransactionRequiringExtraProcessing()
424
                transaction_requiring_extra_processing.category = 'COD_VERIFICATION'
425
                transaction_requiring_extra_processing.transaction_id = transaction_id
426
                session.commit()
427
            elif new_status == TransactionStatus.FLAGGED:
428
                transaction_requiring_extra_processing = TransactionRequiringExtraProcessing()
429
                transaction_requiring_extra_processing.category = 'PAYMENT_FLAGGED'
430
                transaction_requiring_extra_processing.transaction_id = transaction_id
431
                session.commit()
7313 rajveer 432
        elif order.source == OrderSource.STORE:
7386 anupam.sin 433
 
7313 rajveer 434
                catalog_client = CatalogClient().get_client() 
435
                sourcePricing = catalog_client.getStorePricing(order.lineitems[0].item_id)
436
                if order.total_amount >= sourcePricing.minPrice:
437
                    order.status = OrderStatus.SUBMITTED_FOR_PROCESSING
7386 anupam.sin 438
                    order.statusDescription = "Order Accepted"
7344 rajveer 439
                    session.commit()
7386 anupam.sin 440
                    __push_store_collection_to_hotspot(order, "advance", order.advanceAmount)
7344 rajveer 441
 
7313 rajveer 442
                else: 
443
                    order.status = OrderStatus.COD_VERIFICATION_PENDING
7386 anupam.sin 444
                    order.statusDescription = "Approval Pending"
7313 rajveer 445
                    content = "<html><body>"
7350 rajveer 446
                    content += "<h4>Order Id:  " + str(order.id) + "</h4>"
447
                    content += "<h4>Product:  " + str(order.lineitems[0]) + "</h4>"
448
                    content += "<h4>Min Price: " +  str(sourcePricing.minPrice) + "</h4>"
449
                    content += "<h4>Recommended Price: " +  str(sourcePricing.recommendedPrice) + "</h4>"
7313 rajveer 450
                    content += "<h2>Approval Requested for Price: " +  str(order.total_amount) + "</h2>"
7392 rajveer 451
                    content += "<h2>Note 1: If this discount price is approved then reply 'Approved' otherwise 'Not Approved' without changing anythig in the Mail.</h2>"  
452
                    content += "<h2>Note 2: For Quick approval using browser <a href='http://support.shop2020.in:8080/Support/price-approval?xszbg=" + base64.b64encode(str(order.id))  + "'>Click Here</a></h2>"
7313 rajveer 453
                    content += "<br><br></body></html>"
454
                    store = get_hotspot_store(order.storeId, "")
455
                    helper_client = HelperClient().get_client()
7391 rajveer 456
                    helper_client.saveUserEmailForSending(store.approvalEmail.split(';'), "", "Price approval requested for " + str(order.lineitems[0]) + " order Id " + str(order.id) + " in store " + store.hotspotId , content, str(transaction_id), "PriceApproval", [], [])
7344 rajveer 457
                    session.commit()
3530 mandeep.dh 458
    except Exception as e:
4065 mandeep.dh 459
        print "Error inserting transaction Id: " + str(transaction_id) + " due to " + str(e)
3499 mandeep.dh 460
 
483 rajveer 461
    return True
462
 
5514 rajveer 463
def __create_recharge_voucher_tracker(order, amount, voucherType):
5508 rajveer 464
    rvt = RechargeVoucherTracker()
465
    rvt.order = order
466
    rvt.amount = amount
467
    rvt.voucherIssued = False
5514 rajveer 468
    rvt.voucherType = voucherType
5508 rajveer 469
 
3994 chandransh 470
def __get_holidays(start_time=0L, to_time=-1L):
471
    '''
472
    Get the list of all public holidays since start time including the
473
    day of start time if it's a holiday
474
    '''
475
    midnightTime = start_time.replace(hour=0, minute=0, second=0, microsecond=0)
1730 ankur.sing 476
    fromDate = to_java_date(midnightTime)
477
    logistics_client = LogisticsClient().get_client()
3994 chandransh 478
    #TODO: This list should be cached after the first call.
479
    #Calling logistics server is also unnecessary.
480
    holidays = logistics_client.getHolidays(fromDate, to_time)
481
    holidays = [to_py_date(holiday).date() for holiday in holidays]
482
    return holidays
483
 
484
def adjust_delivery_time(start_time, delivery_days):
485
    '''
486
    Returns the actual no. of days which will pass while 'delivery_days'
487
    no. of business days will pass since 'order_time'. 
488
    '''
489
    start_date = start_time.date()
490
    end_date = start_date + datetime.timedelta(days = delivery_days)
491
    holidays = __get_holidays(start_time)
1730 ankur.sing 492
 
3994 chandransh 493
    while start_date <= end_date:
494
        if start_date.weekday() == 6 or start_date in holidays:
1730 ankur.sing 495
            delivery_days = delivery_days + 1
3994 chandransh 496
            end_date = end_date + datetime.timedelta(days = 1)
4088 chandransh 497
        start_date = start_date + datetime.timedelta(days = 1)
3994 chandransh 498
 
1730 ankur.sing 499
    return delivery_days
500
 
6561 amit.gupta 501
def get_business_days_count(start_time, end_time):
502
    '''
503
    Returns business dates between two dates
504
    '''
505
    start_date = start_time.date()
506
    end_date  = end_time.date()
6669 amit.gupta 507
    diff = (end_date - start_date).days
6665 amit.gupta 508
    sundays = diff/7 + 1 if (start_date.weekday() + (diff%7) > 6) else diff/7 
6561 amit.gupta 509
    '''holidays = __get_holidays(start_time, end_time)'''
510
    logistics_client = LogisticsClient().get_client()
511
    #TODO: This list should be cached after the first call.
512
    #Calling logistics server is also unnecessary.
513
    holidays = logistics_client.getHolidays(to_java_date(start_time), to_java_date(end_time))
514
    non_business_days = len(holidays)
515
    for holiday in holidays:
6675 rajveer 516
        pyholiday = to_py_date(holiday).date()
517
        if pyholiday.weekday() == 6:
6561 amit.gupta 518
            sundays = sundays - 1
519
    return diff - (non_business_days + sundays)
520
 
521
 
1398 varun.gupt 522
def enqueue_transaction_info_email(transaction_id):
1262 varun.gupt 523
    transaction = get_transaction(transaction_id)
6650 amit.gupta 524
    subject = source_name + " - Order Details"
525
    otgLink = ""
6660 amit.gupta 526
    inOrderOtg = "<div>On Time Guarantee<br><span style=color:red>We pay if we delay</span></div>"
6650 amit.gupta 527
    if len(transaction.orders) == 1:
528
        inOrderOtg = ""
529
        if transaction.orders[0].otg :
530
            subject = "Your Order is confirmed with On Time Guarantee We Pay if we Delay"
531
            otgLink = ' Your Order is covered under the <a href="http://www.saholic.com/static/on-time-guarantee">On Time Guarantee, We pay If we Delay.</a>'
532
 
5793 rajveer 533
    customer_name = "" 
1262 varun.gupt 534
    html_header = """
535
<html>
536
<body>
537
<div>
538
    <p>
5793 rajveer 539
        Hello $customer_name,<br /><br />
6650 amit.gupta 540
        Thanks for placing order with us.$otgLink Following are the details of your order:
1262 varun.gupt 541
    </p>
542
    <div>
543
        Order Date: $order_date
1569 varun.gupt 544
    </div>
1262 varun.gupt 545
    <div>
546
        <table>
5879 rajveer 547
        <tr><td colspan="6"><hr /></td></tr>
548
        <tr><td colspan="6" align="left"><b>Order Details</b></td></tr>
549
        <tr><td colspan="6"><hr /></td></tr>
1262 varun.gupt 550
        <tr>
2050 varun.gupt 551
            <th width="100">Order No.</th>
552
            <th>Product</th>
5879 rajveer 553
            <th width="100">Estimated Delivery Date</th>
2050 varun.gupt 554
            <th width="100">Quantity</th>
555
            <th width="100">Unit Price</th>
556
            <th width="100">Amount</th>
1262 varun.gupt 557
        </tr>
558
    """
1398 varun.gupt 559
    user_email = ""
1262 varun.gupt 560
    total_amount = 0.0
561
    html_table = ""
1569 varun.gupt 562
    order_date = datetime.datetime.now()
5676 rajveer 563
 
564
    orders = transaction.orders
565
    html_pickup_text = ""
566
    random_text = ""
5697 rajveer 567
    if orders[0].pickupStoreId:
5793 rajveer 568
        random_text = str(randrange(100000, 999999)) 
6650 amit.gupta 569
 
6654 amit.gupta 570
    first = True    
5676 rajveer 571
    for order in orders:
5793 rajveer 572
        customer_name = order.customer_name
1262 varun.gupt 573
        order_date = order.created_timestamp
1398 varun.gupt 574
        user_email = order.customer_email
6654 amit.gupta 575
        if first:
576
            first = False
577
            html_tr = "" 
578
        else:
6659 amit.gupta 579
            html_tr =  "<tr><td colspan=6>&nbsp;</td></tr>"
6654 amit.gupta 580
        html_tr += "<tr><td align='center'>" + str(order.id) + "</td>"
5676 rajveer 581
 
5879 rajveer 582
        sdt = datetime.datetime.strptime(str(orders[0].expected_delivery_time), "%Y-%m-%d %H:%M:%S")
583
        store_delivery_date = sdt.strftime("%d %B %Y")
584
 
5676 rajveer 585
        if order.pickupStoreId:
586
            attribute = Attribute()
587
            attribute.orderId = order.id
588
            attribute.name = "SECRET_CODE"
589
            attribute.value = random_text
590
            session.commit()
1262 varun.gupt 591
 
592
        for lineitem in order.lineitems:
2050 varun.gupt 593
            lineitem_total_price = round(lineitem.total_price, 2)
594
 
1276 chandransh 595
            html_tr += "<td>" + str(lineitem) + "</td>"
6561 amit.gupta 596
            if order.otg:
6650 amit.gupta 597
                html_tr += "<td align='center'><div>" + store_delivery_date + "</div>" + inOrderOtg + "</td>"
6561 amit.gupta 598
            else:
599
                html_tr += "<td align='center'>" + store_delivery_date + "</td>"
2050 varun.gupt 600
            html_tr += "<td align='center'>" + ("%.0f" % lineitem.quantity) + "</td>"
601
            html_tr += "<td align='center'> Rs. " + ("%.2f" % lineitem.unit_price) + "</td>"
602
            html_tr += "<td align='center'> Rs. " + ("%.2f" % lineitem_total_price) + "</td></tr>"
603
            total_amount += lineitem_total_price
1262 varun.gupt 604
            html_table += html_tr
7190 amar.kumar 605
        if order.freebieItemId:
606
            catalog_client = CatalogClient().get_client()
607
            item = catalog_client.getItem(order.freebieItemId)
7201 amar.kumar 608
            html_table += "<tr><td align='center'></td><td style='font-style:italic;' colspan='5'> Free Item: "+item.brand + " " + item.modelName + " " + item.modelNumber+"</td></tr>"
6906 rajveer 609
        if order.insurer:
610
            html_table += "<tr><td colspan=6>&nbsp;</td></tr>"
6927 rajveer 611
            html_table += "<tr><td align='center'></td><td style='font-style:italic;'>Insured Against Theft for 1 Year. <a href='http://www.saholic.com/static/insurance-terms'>Know More</a></td><td align='center'></td><td align='center'></td><td align='center'></td>"
6911 rajveer 612
            html_table += "<td align='center'>" + str(order.insuranceAmount) + "</td></tr>"
6927 rajveer 613
            total_amount += order.insuranceAmount
6422 rajveer 614
    emi_amount = 0
615
    miscCharges = get_misc_charges(transaction_id)
616
    if miscCharges.get(1):
617
        emi_amount = miscCharges.get(1)
618
 
1262 varun.gupt 619
    html_footer = """
5879 rajveer 620
        <tr><td colspan=6>&nbsp;</td></tr>
621
        <tr><td colspan=6><hr /></td></tr>
6422 rajveer 622
        """
623
    if emi_amount > 0:
6715 amit.gupta 624
        total_amount += emi_amount
6422 rajveer 625
        html_footer = html_footer + "<tr>\
626
                        <td colspan=5>EMI Processing Charges</td>\
627
                        <td> Rs. $emi_amount</td>\
628
                    </tr>"
629
 
630
    html_footer = html_footer + "<tr>\
631
                <td colspan=5>Total Amount</td>\
632
                <td> Rs. $total_amount</td>\
633
                </tr>\
634
            </table>\
635
        </div>"
5793 rajveer 636
 
6422 rajveer 637
 
5793 rajveer 638
    store_address = ""
639
    if orders[0].pickupStoreId:
640
        store = LogisticsClient().get_client().getPickupStore(orders[0].pickupStoreId)
641
        store_address = __get_store_address_html(store)
642
 
643
        html_pickup_text = html_pickup_text + """
644
        <h3>Steps to Pickup In Store</h3>
5879 rajveer 645
        1) You will receive a confirmation email from us when your product(s) reaches the store. Once you receive the same, please visit the following store selected by you.<br>
5793 rajveer 646
        <br><i>$store_address</i><br>
647
        """
648
 
649
        if orders[0].cod:
650
            html_pickup_text = html_pickup_text + """
6318 rajveer 651
            2) Pay Rs. $net_amount, present a valid Photo Identity Proof* and use your Secret Code <b><i>$secret_code</i></b> to claim your Product(s).<br><br>
5793 rajveer 652
            *Valid Photo Identity Proof are Driving License, Passport, PAN Card, Voter ID, Company Issued ID Card, College issued Student ID Card Or any other Government approved Photo Id.<br>
653
            <br>
6029 rajveer 654
            In case you have any questions please visit <a href="$source_url/static/buy-online-and-pickup-in-store">Details on Pickup in Store</a>. If you still have more questions feel free to contact us 24/7 via <a href="$source_url/contact-us">$source_url/contact-us</a>
5793 rajveer 655
            </br><hr />
656
            """
657
        else:
658
            html_pickup_text = html_pickup_text + """
5879 rajveer 659
            2) Present a valid Photo Identity Proof* and use your Secret Code <b><i>$secret_code</i></b> to claim your Product(s).<br><br>
5793 rajveer 660
            *Valid Photo Identity Proof are Driving License, Passport, PAN Card, Voter ID, Company Issued ID Card, College issued Student ID Card Or any other Government approved Photo Id.<br>
661
            <br>
6029 rajveer 662
            In case you have any questions please visit <a href="$source_url/static/buy-online-and-pickup-in-store">Details on Pickup in Store</a>. If you still have more questions feel free to contact us 24/7 via <a href="$source_url/contact-us">$source_url/contact-us</a>
5793 rajveer 663
            </br><hr />
664
            """
665
 
5676 rajveer 666
    html_footer = html_footer + html_pickup_text + """
1262 varun.gupt 667
    <p>
668
        Best Wishes,<br />
6029 rajveer 669
        $source_name Team
1262 varun.gupt 670
    </p>
671
</div>
672
</body>
673
</html>
674
    """
1398 varun.gupt 675
 
1569 varun.gupt 676
    dt = datetime.datetime.strptime(str(order_date), "%Y-%m-%d %H:%M:%S")
1565 varun.gupt 677
    formated_order_date = dt.strftime("%A, %d. %B %Y %I:%M%p")
5793 rajveer 678
 
679
    sdt = datetime.datetime.strptime(str(orders[0].expected_delivery_time), "%Y-%m-%d %H:%M:%S")
680
    store_delivery_date = sdt.strftime("%A, %d %B %Y")
681
 
6650 amit.gupta 682
    email_header = Template(html_header).substitute(dict(order_date = formated_order_date, customer_name = customer_name, source_url = source_url, otgLink = otgLink))
6422 rajveer 683
    email_footer = Template(html_footer).substitute(dict(total_amount = "%.2f" % total_amount, emi_amount = "%.2f" % emi_amount, net_amount = "%.2f" % (total_amount-order.gvAmount), secret_code = random_text, store_address = store_address, store_delivery_date = store_delivery_date, source_url = source_url, source_name = source_name))
1565 varun.gupt 684
 
1351 varun.gupt 685
    try:
686
        helper_client = HelperClient().get_client()
6906 rajveer 687
        helper_client.saveUserEmailForSending([user_email], "", subject, email_header + html_table + email_footer, str(transaction_id), "TransactionInfo", [], [])
5866 rajveer 688
 
1351 varun.gupt 689
        return True
690
    except Exception as e:
691
        print e
692
        return False
1262 varun.gupt 693
 
5802 rajveer 694
def enqueue_received_at_store_email(order):
695
    html_header = """
696
    <html>
697
    <body>
698
    <div>
699
        <p>
700
            Hello $customer_name,<br /><br />
701
            Your Product has reached the Store selected by you and is available for pickup. Please pick up your product on or before $order_expiry_date. Following are the details of your order and steps to pickup the same:
702
        </p>
703
        <div>
704
            Order Date: $order_date
705
        </div>
706
        <div>
707
            <table>
708
            <tr><td colspan="5"><hr /></td></tr>
709
            <tr><td colspan="5" align="left"><b>Order Details</b></td></tr>
710
            <tr><td colspan="5"><hr /></td></tr>
711
            <tr>
712
                <th width="100">Order No.</th>
713
                <th>Product</th>
714
                <th width="100">Quantity</th>
715
                <th width="100">Unit Price</th>
716
                <th width="100">Amount</th>
717
            </tr>
718
    """
719
    total_amount = 0.0
720
    html_table = ""
721
 
722
    html_pickup_text = ""
723
    random_text = __get_secret_code(order.id)
724
 
725
    customer_name = order.customer_name
726
    order_date = order.created_timestamp
727
    user_email = order.customer_email
728
    html_tr = "<tr><td align='center'>" + str(order.id) + "</td>"
729
 
730
    for lineitem in order.lineitems:
731
        lineitem_total_price = round(lineitem.total_price, 2)
732
 
733
        html_tr += "<td>" + str(lineitem) + "</td>"
734
        html_tr += "<td align='center'>" + ("%.0f" % lineitem.quantity) + "</td>"
735
        html_tr += "<td align='center'> Rs. " + ("%.2f" % lineitem.unit_price) + "</td>"
736
        html_tr += "<td align='center'> Rs. " + ("%.2f" % lineitem_total_price) + "</td></tr>"
737
        total_amount += lineitem_total_price
738
        html_table += html_tr
739
 
740
    html_footer = """
741
        <tr><td colspan=5>&nbsp;</td></tr>
742
        <tr><td colspan=5><hr /></td></tr>
743
        <tr>
744
            <td colspan=4>Total Amount</td>
745
            <td> Rs. $total_amount</td>
746
        </tr>
747
        </table>
748
    </div>
749
    """
750
 
751
    store_address = ""
752
    if order.pickupStoreId:
753
        store = LogisticsClient().get_client().getPickupStore(order.pickupStoreId)
754
        store_address = __get_store_address_html(store)
755
 
756
        html_pickup_text = html_pickup_text + """
757
        <h3>Steps to Pickup In Store</h3>
758
        1) Please visit the following store selected by you on or before $order_expiry_date<br>
759
        <br><i>$store_address</i><br>
760
        """
761
 
762
        if order.cod:
763
            html_pickup_text = html_pickup_text + """
6318 rajveer 764
            2) Pay Rs. $net_amount, present a valid Photo Identity Proof* and quote your Secret Code <b><i>$secret_code</i></b> to claim your Product.<br><br>
5802 rajveer 765
            *Valid Photo Identity Proof are Driving License, Passport, PAN Card, Voter ID, Company Issued ID Card, College issued Student ID Card Or any other Government approved Photo Id.<br>
766
            <br>
6029 rajveer 767
            In case you have any questions please visit <a href="$source_url/static/buy-online-and-pickup-in-store">Details on Pickup in Store</a>. If you still have more questions feel free to contact us 24/7 via <a href="$source_url/contact-us">$source_url/contact-us</a>
5802 rajveer 768
            </br><hr />
769
            """
770
        else:
771
            html_pickup_text = html_pickup_text + """
772
            2) Present a valid Photo Identity Proof* and use your Secret Code <b><i>$secret_code</i></b> to claim your Product(s).<br><br>
773
            *Valid Photo Identity Proof are Driving License, Passport, PAN Card, Voter ID, Company Issued ID Card, College issued Student ID Card Or any other Government approved Photo Id.<br>
774
            <br>
6029 rajveer 775
            In case you have any questions please visit <a href="$source_url/static/buy-online-and-pickup-in-store">Details on Pickup in Store</a>. If you still have more questions feel free to contact us 24/7 via <a href="$source_url/contact-us">$source_url/contact-us</a>
5802 rajveer 776
            </br><hr />
777
            """
778
 
779
        html_footer = html_footer + html_pickup_text + """
780
        <p>
781
            Best Wishes,<br />
6029 rajveer 782
            $source_name Team
5802 rajveer 783
        </p>
784
        </div>
785
        </body>
786
        </html>
787
        """
788
 
789
    subject = "Your order for " + str(order.lineitems[0]) + " is ready for Pickup in Store"
790
    dt = datetime.datetime.strptime(str(order_date), "%Y-%m-%d %H:%M:%S")
791
    formated_order_date = dt.strftime("%A, %d. %B %Y %I:%M%p")
792
 
793
    oetd = datetime.datetime.now() + datetime.timedelta(days=4)
794
    formated_order_expiry_date = oetd.strftime("%A, %d %B %Y")
795
 
796
 
6029 rajveer 797
    email_header = Template(html_header).substitute(dict(order_date = formated_order_date, customer_name = customer_name, order_expiry_date = formated_order_expiry_date, source_url = source_url, source_name = source_name))
6318 rajveer 798
    email_footer = Template(html_footer).substitute(dict(total_amount = "%.2f" % total_amount, net_amount = "%.2f" % (total_amount-order.netAmount), secret_code = random_text, store_address = store_address, order_expiry_date = formated_order_expiry_date, source_url = source_url, source_name = source_name))
5802 rajveer 799
 
800
    try:
5812 rajveer 801
        helper_client = HelperClient(host_key = "helper_service_server_host_prod").get_client()
6280 rajveer 802
        helper_client.saveUserEmailForSending([user_email], "", subject, email_header + html_table + email_footer, str(order.id), "ReceivedAtStore", [], [])
5802 rajveer 803
        return True
804
    except Exception as e:
805
        print e
806
        return False
807
 
5966 rajveer 808
def enqueue_delivery_success_mail(order):
5807 rajveer 809
    html_header = """
810
    <html>
811
    <body>
812
    <div>
813
        <p>
814
            Dear $customer_name,<br /><br />
815
    """
6561 amit.gupta 816
 
5807 rajveer 817
    if order.pickupStoreId:
818
        pickup_text = "Pickup Date: " + order.delivery_timestamp.strftime("%A, %d. %B %Y %I:%M%p")
819
        thank_you_html = """
820
        Thank you for shopping with us and picking up your order in Store. Please do join us at our <a href="http://www.facebook.com/mysaholic">Facebook Page</a>, and share your experience with other shoppers.<br><br>
821
 
6029 rajveer 822
        Following are the details of your order for which the pickup has happened. If you have not picked up this product please <a href="$source_url/contact-us" target="_blank">contact us</a> immediately.<br>
5807 rajveer 823
        """
824
    else:
825
        pickup_text = ""
6561 amit.gupta 826
        if order.otg:
827
 
828
            delayed = False
829
            fda = False
830
 
831
            if order.first_dlvyatmp_timestamp.date() < order.delivery_timestamp.date():
832
                fda = True
833
 
834
            fda_datetime = order.first_dlvyatmp_timestamp            
835
            fda_date = fda_datetime.date()
836
 
6711 amit.gupta 837
            if order.promised_delivery_time.date() < fda_date:
6561 amit.gupta 838
                delayed = True
839
 
840
            if not delayed and not fda:
841
                thank_you_html = """As Promised """ + str(order.lineitems[0]) +""" ordered by you has been <b>Delivered On Time.</b>""" 
842
            elif delayed:
843
                max_discount = 500
6711 amit.gupta 844
                delayedDays = get_business_days_count(order.promised_delivery_time, fda_datetime)
6561 amit.gupta 845
                max_discount = min(max_discount, order.lineitems[0].unit_price/10)
6686 anupam.sin 846
                discount = min(round(max_discount),delayedDays*50)  
6561 amit.gupta 847
                promotion_client = PromotionClient().get_client()
848
                endOn =  order.delivery_timestamp + datetime.timedelta(days = 30)
7347 amit.gupta 849
                expiry = endOn.strftime("%A, %d. %B %Y")
6561 amit.gupta 850
                endOn = to_java_date(endOn)
6688 anupam.sin 851
                arguments = "{\"endOn\":" + str(endOn) + ", \"emails\":[\"" + order.customer_email + "\"], \"couponType\":\"both\", \"usage_limit_for_user\":1, \"isCod\":False, \"discount\":" + str(discount) + "}"
6742 anupam.sin 852
                otgCoupon = promotion_client.createCoupon(28, '', arguments, False, "otg")
7347 amit.gupta 853
                thank_you_html = '$prodName ordered by you has been delivered. We apologise for a delay of $delayedDays business days.<br><br> As per our <b>On Time Guarantee</b> Please accept a Gift Voucher worth <b>Rs.$discount</b> as a token of our apology. <br><br>Your unique Gift Voucher Code is <b>$otgCoupon</b>. <br><br>You can use the same to buy any Mobile, Camera, Laptop, Tablet, Accessory or Mobile/DTH Recharge from our website.<br> Note:GV is valid till $expiry<br>'
854
                thank_you_html = Template(thank_you_html).substitute(dict(prodName=order.lineitems[0], delayedDays = delayedDays, discount = discount, otgCoupon = otgCoupon, expiry = expiry))
6561 amit.gupta 855
            elif fda:
856
                fdaFormattedString = order.first_dlvyatmp_timestamp.strftime("%A, %d. %B %Y")
857
                thank_you_html = str(order.lineitems[0]) + """ ordered by you has been delivered.  The First Delivery attempt was made on """+ fdaFormattedString +""" , within our commited estimated time for delivery.""" 
858
 
859
            thank_you_html = thank_you_html + """If you are happy with our services please join us on <a href="http://www.facebook.com/mysaholic">Facebook</a>/<a href="https://twitter.com/saholic">Twitter</a> and help us spread the word."""  
860
 
861
        else :
862
            thank_you_html = str(order.lineitems[0]) + """ ordered by you has been delivered. 
863
            Thank you for shopping with us. Please do join us at our <a href="http://www.facebook.com/mysaholic">Facebook Page</a>, and share your experience with other shoppers. Following are the details of your order.<br>
7198 amar.kumar 864
            """
865
 
866
    freebie_text = "<br/>"
867
    if order.freebieItemId:
868
        catalog_client = CatalogClient().get_client()
869
        item = catalog_client.getItem(order.freebieItemId)
870
        freebie_text = freebie_text = "We have also delivered " + item.brand + " " + item.modelName + "" + item.modelNumber +" as promised"
871
    else:
872
        freebie_orderId = get_order_attribute_value(order.id, "freebieOrderId")
873
        if freebie_orderId != "":
874
            line_items = get_line_items_for_order(int(freebie_orderId))
875
            freebie_order = get_order(int(freebie_orderId))
876
            freebie_text = freebie_text + " We wish to inform you that your freebie item " +line_items[0].brand + " " + line_items[0].model_name + " " + line_items[0].model_number + " will be sent as a separate order with OrderId : " + freebie_orderId + " and is expected to be delivered on " + freebie_order.expected_delivery_time.strftime("%A, %d %B %Y")+ "<br/>You can track the status of this order from My Orders section in saholic.com" 
5807 rajveer 877
 
878
    html_header = html_header + thank_you_html + """        
879
        </p>
880
        <div>
881
            Order Date: $order_date <br>
882
            $pickup_text
883
        </div>
884
        <div>
885
            <table>
886
            <tr><td colspan="5"><hr /></td></tr>
887
            <tr><td colspan="5" align="left"><b>Order Details</b></td></tr>
888
            <tr><td colspan="5"><hr /></td></tr>
889
            <tr>
890
                <th width="100">Order No.</th>
891
                <th>Product</th>
892
                <th width="100">Quantity</th>
893
                <th width="100">Unit Price</th>
894
                <th width="100">Amount</th>
895
            </tr>
896
    """
897
    total_amount = 0.0
898
    html_table = ""
5802 rajveer 899
 
5807 rajveer 900
    customer_name = order.customer_name
901
    order_date = order.created_timestamp
902
    user_email = order.customer_email
903
    html_tr = "<tr><td align='center'>" + str(order.id) + "</td>"
904
 
905
    for lineitem in order.lineitems:
906
        lineitem_total_price = round(lineitem.total_price, 2)
907
 
908
        html_tr += "<td>" + str(lineitem) + "</td>"
909
        html_tr += "<td align='center'>" + ("%.0f" % lineitem.quantity) + "</td>"
910
        html_tr += "<td align='center'> Rs. " + ("%.2f" % lineitem.unit_price) + "</td>"
911
        html_tr += "<td align='center'> Rs. " + ("%.2f" % lineitem_total_price) + "</td></tr>"
912
        total_amount += lineitem_total_price
913
        html_table += html_tr
6906 rajveer 914
    if order.insurer:
6915 anupam.sin 915
        html_table += "<tr><td align='center'></td><td style='font-style:italic;'>Insured Against Theft for 1 Year. <a href='http://www.saholic.com/static/insurance-terms'>Know More</a></td><td align='center'></td><td align='center'></td>"
6911 rajveer 916
        html_table += "<td align='center'>" + str(order.insuranceAmount) + "</td></tr>"
6947 rajveer 917
        html_table += "<tr><td align='center'></td><td style='font-style:italic;'>Please download and read attached policy document.</td><td align='center'></td><td align='center'></td></tr>"
6906 rajveer 918
        total_amount += order.insuranceAmount
919
 
5807 rajveer 920
    html_footer = """
921
        <tr><td colspan=5>&nbsp;</td></tr>
922
        <tr><td colspan=5><hr /></td></tr>
923
        <tr>
924
            <td colspan=4>Total Amount</td>
925
            <td> Rs. $total_amount</td>
926
        </tr>
927
        </table>
7198 amar.kumar 928
        $freebie_text
5807 rajveer 929
    </div>
930
    <p>
931
        Best Wishes,<br />
6029 rajveer 932
        $source_name Team
5807 rajveer 933
    </p>
934
    </div>
935
    </body>
936
    </html>
937
    """
938
 
939
    subject = "Your order for " + str(order.lineitems[0]) + " is now complete"
940
    dt = datetime.datetime.strptime(str(order_date), "%Y-%m-%d %H:%M:%S")
941
    formated_order_date = dt.strftime("%A, %d. %B %Y %I:%M%p")
942
 
943
 
6029 rajveer 944
    email_header = Template(html_header).substitute(dict(order_date = formated_order_date, customer_name = customer_name, pickup_text = pickup_text, source_url = source_url))
7198 amar.kumar 945
    email_footer = Template(html_footer).substitute(dict(total_amount = "%.2f" % total_amount, source_name = source_name, freebie_text = freebie_text))
5807 rajveer 946
 
947
    try:
5812 rajveer 948
        helper_client = HelperClient(host_key = "helper_service_server_host_prod").get_client()
6957 rajveer 949
        if order.insurer:
950
            helper_client.saveUserEmailForSending([user_email], "", subject, email_header + html_table + email_footer, str(order.id), "DeliverySuccess", [], ["pramit.singh@shop2020.in ","anupam.singh@shop2020.in","rajveer.singh@shop2020.in"])
951
        else:
952
            helper_client.saveUserEmailForSending([user_email], "", subject, email_header + html_table + email_footer, str(order.id), "DeliverySuccess", [], [])
5807 rajveer 953
        return True
954
    except Exception as e:
955
        print e
956
        return False
957
 
5802 rajveer 958
def __get_secret_code(order_id):
5855 rajveer 959
    return get_order_attribute_value(order_id, 'SECRET_CODE')
5806 rajveer 960
 
5833 rajveer 961
def get_order_attribute_value(order_id, attribute_name):
5808 rajveer 962
    existingAttribute = Attribute.query.filter(Attribute.orderId == order_id).filter(Attribute.name == attribute_name).first()
963
    if existingAttribute:
964
        return existingAttribute.value
5802 rajveer 965
    return ""
5806 rajveer 966
 
6019 rajveer 967
def change_jacket_number(order_id, jacket_number):
968
    order = get_order(order_id)
969
    if order.status == OrderStatus.BILLED:
970
        order.jacket_number = jacket_number
6047 rajveer 971
        session.commit()
6019 rajveer 972
        return True
973
    return False
974
 
975
def mark_order_as_rto_in_transit(order_id):
976
    order = get_order(order_id)
6032 rajveer 977
    if order == None or order.status not in [OrderStatus.SHIPPED_FROM_WH, OrderStatus.DELIVERED_AT_STORE, OrderStatus.SHIPPED_TO_LOGST, OrderStatus.SHIPPED_TO_DESTINATION_CITY, OrderStatus.REACHED_DESTINATION_CITY, OrderStatus.FIRST_DELIVERY_ATTEMPT_MADE, OrderStatus.DELIVERY_SUCCESS]:
6019 rajveer 978
        return False
979
    order.status = OrderStatus.RTO_IN_TRANSIT
980
    order.delivery_timestamp = datetime.datetime.now()
7151 amit.gupta 981
    order.statusDescription = "Order Returned to Origin"
6019 rajveer 982
    update_trust_level(order)
6032 rajveer 983
    session.commit()
6019 rajveer 984
    return True
985
 
483 rajveer 986
def get_order(order_id):
987
    order = Order.get_by(id=order_id)
988
    if not order:
989
        raise TransactionServiceException(108, "no such order")
990
 
991
    return order
992
 
4999 phani.kuma 993
def get_order_list(order_ids):
994
    orders = Order.query.filter(Order.id.in_(tuple(order_ids)))
995
    return orders
996
 
5386 phani.kuma 997
def get_order_list_for_vendor(order_ids, vendor_id):
998
    if vendor_id == -1:
999
        return get_order_list(order_ids)
1000
    else:
1001
        orders = Order.query.filter_by(vendorId = vendor_id).filter(Order.id.in_(tuple(order_ids)))
1002
        return orders
1003
 
3014 chandransh 1004
def get_orders_for_customer(customer_id, from_date, to_date, statuses):
483 rajveer 1005
    if not customer_id:
1006
        raise TransactionServiceException(101, "bad customer id")
1007
    query = Order.query.filter(Order.customer_id == customer_id)
3014 chandransh 1008
    if statuses:
1009
        query = query.filter(Order.status.in_(tuple(statuses)))
483 rajveer 1010
    if from_date:
1011
        query = query.filter(Order.created_timestamp >from_date)
1012
    if to_date:
1013
        query = query.filter(Order.created_timestamp < to_date)
1014
    return query.all()
1015
 
1528 ankur.sing 1016
def get_order_for_customer(order_id, customer_id):
1017
    if not customer_id:
1018
        raise TransactionServiceException(101, "bad customer id")
1019
    order = get_order(order_id)
1020
    if order.customer_id != customer_id:
1021
        raise TransactionServiceException(108, "order: " + str(order_id) + " does not belong to customer: " + str(customer_id))
1022
    return order
1023
 
4801 anupam.sin 1024
def get_all_orders(statuses, from_date, to_date, warehouse_id):
1025
    if not len(statuses):
1026
        raise TransactionServiceException(101, "Status list is empty")
1027
    query = Order.query.filter(Order.status.in_(statuses))
1028
    if warehouse_id:
1029
        query = query.filter(Order.warehouse_id == warehouse_id)
1030
        #raise TransactionServiceException(101, "bad warehouse id")
483 rajveer 1031
    if from_date:
1032
        query = query.filter(Order.created_timestamp >from_date)
1033
    if to_date:
1034
        query = query.filter(Order.created_timestamp < to_date)
1035
    return query.all()
1036
 
4133 chandransh 1037
def get_orders_in_batch(statuses=[], offset=0, limit=0, warehouse_id=None):
4296 rajveer 1038
    query = Order.query
1039
    if warehouse_id:
1040
        query = query.filter(Order.warehouse_id == warehouse_id)
4133 chandransh 1041
    if statuses:
1042
        query = query.filter(Order.status.in_(statuses))
1043
    query = query.offset(offset)
1044
    if limit:
1045
        query = query.limit(limit)
1046
    return query.all()
1047
 
1048
def get_order_count(statuses=[], warehouse_id=None):
1049
    if not warehouse_id:
1050
        raise TransactionServiceException(101, "bad warehouse id")
1051
    query = session.query(func.count(Order.id)).filter(Order.warehouse_id == warehouse_id)
1052
    if statuses:
1053
        query = query.filter(Order.status.in_(statuses))
1054
    return query.scalar()
1055
 
1382 varun.gupt 1056
def get_returnable_orders_for_customer(customer_id, limit = None):
1057
    if not customer_id:
1058
        raise TransactionServiceException(101, "bad customer id")
1059
 
1060
    query = Order.query.filter(Order.customer_id == customer_id)
1061
    query = query.filter(Order.status != OrderStatus.PAYMENT_FAILED)
1062
    query = query.filter(Order.status != OrderStatus.REJECTED)
1063
    query = query.filter(Order.status > OrderStatus.SHIPPED_FROM_WH)
1064
    query = query.filter(or_(Order.status < OrderStatus.DELIVERY_SUCCESS, Order.delivery_timestamp < datetime.datetime.now() + datetime.timedelta(hours = 48)))
1065
    orders = query.all()
1066
    order_ids = [order.id for order in orders]
1067
    return order_ids
1068
 
1069
def get_cancellable_orders_for_customer(customer_id, limit = None):
1070
    if not customer_id:
1071
        raise TransactionServiceException(101, "bad customer id")
4815 phani.kuma 1072
    cancellableOrderStatuses = OrderStatusGroups().codCancellable
1382 varun.gupt 1073
    query = Order.query.filter(Order.customer_id == customer_id)
4815 phani.kuma 1074
    query = query.filter(Order.status.in_(cancellableOrderStatuses))
1382 varun.gupt 1075
    orders = query.all()
1076
    return [order.id for order in orders]
1077
 
995 varun.gupt 1078
def get_orders_by_billing_date(status, start_billing_date, end_billing_date, warehouse_id):
1079
    if not warehouse_id:
1080
        raise TransactionServiceException(101, "bad warehouse id")
1081
 
1082
    query = Order.query.filter(Order.warehouse_id == warehouse_id)
1083
 
1084
    if status:
1085
        query = query.filter(Order.status == status)
1086
 
1087
    if start_billing_date:
1088
        query = query.filter(Order.billing_timestamp >= start_billing_date)
1089
 
1090
    if end_billing_date:
1091
        query = query.filter(Order.billing_timestamp <= end_billing_date)
1092
 
1093
    return query.all()
1094
 
3451 chandransh 1095
def get_orders_by_shipping_date(from_shipping_date, to_shipping_date, provider_id, warehouse_id, cod):
1096
    query = Order.query.filter(Order.cod == cod)
3427 chandransh 1097
 
1098
    if warehouse_id and warehouse_id != -1:
1099
        query = query.filter(Order.warehouse_id == warehouse_id)
1100
 
1101
    if provider_id and provider_id != -1:
1102
        query = query.filter(Order.logistics_provider_id == provider_id)
1103
 
1104
    if from_shipping_date:
1105
        query = query.filter(Order.shipping_timestamp >= from_shipping_date)
1106
 
1107
    if to_shipping_date:
1108
        query = query.filter(Order.shipping_timestamp <= to_shipping_date)
1109
 
1110
    query = query.order_by(Order.airwaybill_no)
1111
 
1112
    return query.all()
1113
 
1528 ankur.sing 1114
def get_orders_for_transaction(transaction_id, customer_id):
1115
    orders = Order.query.filter_by(transaction_id=transaction_id, customer_id=customer_id).all()
1116
 
1208 chandransh 1117
    if not orders:
1118
        raise TransactionServiceException(101, "No order for the transaction")
1119
    return orders
1120
 
1405 ankur.sing 1121
def get_undelivered_orders(provider_id, warehouse_id):
1122
    query = Order.query
1123
    if provider_id != -1:
1124
        query = query.filter_by(Order.logistics_provider_id == provider_id)
1125
    if warehouse_id != -1:
1126
        query = query.filter(Order.warehouse_id == warehouse_id)
1127
    query = query.filter(and_(Order.status != OrderStatus.DELIVERY_SUCCESS, Order.status != OrderStatus.FAILED, \
1128
                              Order.status > OrderStatus.SHIPPED_FROM_WH))
1479 ankur.sing 1129
    #Get last midnight time instead of current time as courier company would have sent the 
1130
    #delivery records updated at least till midnight and not by the current time.
1131
    time_format = "%Y-%m-%d %H:%M:%S.%f"
1132
    t = time.strptime(str(datetime.datetime.now()), time_format)
1133
    midnightTime = datetime.datetime(*t[:3])
1134
    query = query.filter(Order.expected_delivery_time < midnightTime)
1405 ankur.sing 1135
    orders = query.all()
1136
    return orders
1137
 
1208 chandransh 1138
def get_line_items_for_order(order_id):
1139
    query = LineItem.query.filter(LineItem.order_id == order_id)
1140
    return query.all()
1141
 
483 rajveer 1142
def change_order_status(self, orderId, status, description):
1143
    order = get_order(orderId)
1144
    order.status = status
1145
    order.statusDescription = description
1146
    session.commit()
3578 mandeep.dh 1147
    update_trust_level(order)
1148
    return True
3499 mandeep.dh 1149
 
3578 mandeep.dh 1150
def update_trust_level(order):
3530 mandeep.dh 1151
    try:
3578 mandeep.dh 1152
        trust_level_delta = 0
1153
        if order.cod == True:
1154
            trust_level_delta = ORDER_STATUS_TO_USER_TRUST_LEVEL_DELTA_DICT.get(order.status, 0)
1155
 
3530 mandeep.dh 1156
        if (trust_level_delta != 0):
1157
            user_client = UserClient().get_client()
1158
            user_client.increaseTrustLevel(order.customer_id, trust_level_delta)
1159
    except Exception as e:
1160
        print e
3499 mandeep.dh 1161
 
483 rajveer 1162
    return True
3064 chandransh 1163
 
7391 rajveer 1164
def verify_order(orderId):
3064 chandransh 1165
    logging.info("Verifying order no: " + str(orderId))
1166
    order = get_order(orderId)
4662 rajveer 1167
    if order.status == OrderStatus.COD_VERIFICATION_PENDING:
3064 chandransh 1168
        order.status = OrderStatus.SUBMITTED_FOR_PROCESSING
1169
        order.statusDescription = "Submitted for processing"
1170
        order.verification_timestamp = datetime.datetime.now()
1171
        session.commit()
7344 rajveer 1172
        if order.source == OrderSource.STORE:
7391 rajveer 1173
            __push_store_collection_to_hotspot(order, 'advance', order.advanceAmount)
3064 chandransh 1174
        logging.info("Successfully verified order no: " + str(orderId))
1175
        return True
1176
    else:
1177
        logging.warning("Verify called for order no." + str(orderId) +" which is not in verification pending state");
1178
        return False
1179
 
4285 rajveer 1180
def accept_order(orderId):
3064 chandransh 1181
    logging.info("Accepting order no: " + str(orderId))
921 rajveer 1182
    order = get_order(orderId)
5110 mandeep.dh 1183
    if order.status in [OrderStatus.SUBMITTED_FOR_PROCESSING, OrderStatus.INVENTORY_LOW, OrderStatus.LOW_INV_PO_RAISED, OrderStatus.LOW_INV_REVERSAL_IN_PROCESS, OrderStatus.LOW_INV_NOT_AVAILABLE_AT_HOTSPOT, OrderStatus.CAPTURE_IN_PROCESS]:
3064 chandransh 1184
        if not order.cod:
1185
            if order.transaction.status == TransactionStatus.AUTHORIZED:
4421 mandeep.dh 1186
                __capture_txn(order)
3010 chandransh 1187
        order.status = OrderStatus.ACCEPTED
1188
        order.statusDescription = "Order Accepted"
1189
        order.accepted_timestamp = datetime.datetime.now()
5530 mandeep.dh 1190
        __amend_fulfilment_warehouse(order)
6789 rajveer 1191
        __update_transfer_price(order, order.fulfilmentWarehouseId)
3010 chandransh 1192
        session.commit()
3064 chandransh 1193
        logging.info("Successfully accepted the order no.:" + str(orderId))
3010 chandransh 1194
        return True
1195
    else:
3064 chandransh 1196
        logging.warning("Accept called for the unacceptable order: " + str(orderId))
3010 chandransh 1197
        return False
921 rajveer 1198
 
4421 mandeep.dh 1199
def __capture_txn(order):
1200
    txnId = order.transaction_id
3010 chandransh 1201
    logging.info("Capturing payment for merchant txn:" + str(txnId))
4421 mandeep.dh 1202
    try:
1203
        payment_client = PaymentClient().get_client()
1204
        capture_result = payment_client.capturePayment(txnId)
1205
        if capture_result:
1206
            logging.info("Successfully captured payment for merchant txn:" + str(txnId))
7293 anupam.sin 1207
            change_transaction_status(txnId, TransactionStatus.IN_PROCESS, "Payment received", PickUpType.COURIER, order.orderType, order.source)
4421 mandeep.dh 1208
        else:
1209
            raise TransactionServiceException(115, "Payment capture failed.")
1210
    except PaymentException as e:
1211
        if e.error_code == 106:
1212
            order.status = OrderStatus.CAPTURE_IN_PROCESS
1213
            session.commit()
1214
            raise TransactionServiceException(122, "Unable to capture payment due to connection issue.")
1215
        else:
1216
            raise TransactionServiceException(115, "Payment capture failed.")
3010 chandransh 1217
 
5530 mandeep.dh 1218
def __amend_fulfilment_warehouse(order):
1219
    itemId = order.lineitems[0].item_id
5944 mandeep.dh 1220
    inventoryClient = InventoryClient().get_client()
1221
    inventory = inventoryClient.getItemInventoryByItemId(itemId)
5530 mandeep.dh 1222
    if not (inventory.availability.has_key(order.fulfilmentWarehouseId) and inventory.availability[order.fulfilmentWarehouseId]):
5944 mandeep.dh 1223
        for warehouse in inventoryClient.getWarehouses(WarehouseType.OURS, InventoryType.GOOD, 0, order.warehouse_id, 0):
5558 mandeep.dh 1224
            if inventory.availability.has_key(warehouse.id) and inventory.availability[warehouse.id] >= inventory.reserved[warehouse.id] + order.lineitems[0].quantity:
5966 rajveer 1225
                inventoryClient.reduceReservationCount(itemId, order.fulfilmentWarehouseId, sourceId, order.id, order.lineitems[0].quantity)
1226
                inventoryClient.reserveItemInWarehouse(itemId, warehouse.id, sourceId, order.id, to_java_date(order.created_timestamp), to_java_date(order.promised_shipping_time), order.lineitems[0].quantity)
5637 mandeep.dh 1227
                order.fulfilmentWarehouseId = warehouse.id
5530 mandeep.dh 1228
                break
1229
 
7190 amar.kumar 1230
def add_billing_details(orderId, invoice_number, serialNumbers, itemNumbers, freebieWarehouseId, billedBy, jacketNumber, billingType, fulfilmentWarehouseId, authorize):
4285 rajveer 1231
    if jacketNumber is None or jacketNumber <= 0:
2783 chandransh 1232
        raise TransactionServiceException(110, "Invalid jacket number")
1233
 
4285 rajveer 1234
    if billedBy is None or billedBy.strip() == "":
2783 chandransh 1235
        raise TransactionServiceException(110, "Invalid Biller")
1236
 
1149 chandransh 1237
    order = Order.get_by(id=orderId)
1238
    if not order:
2783 chandransh 1239
        raise TransactionServiceException(101, "No order found for the given order id" + str(orderId))
5110 mandeep.dh 1240
 
7190 amar.kumar 1241
    '''
1242
    First checking whether freebie can be billed or not otherwise wont proceed.
1243
    '''
7198 amar.kumar 1244
    if order.freebieItemId:
1245
        if billingType == BillingType.OURS or billingType == BillingType.OURS_EXTERNAL:
1246
            if freebieWarehouseId:
7190 amar.kumar 1247
                try:
7198 amar.kumar 1248
                    inventory_client = InventoryClient().get_client()
1249
                    warehouse = inventory_client.getWarehouse(freebieWarehouseId)
1250
 
7199 amar.kumar 1251
                    if warehouse.warehouseType!= WarehouseType.OURS or warehouse.inventoryType != InventoryType.GOOD:
7198 amar.kumar 1252
                        raise TransactionServiceException(110,'Billing of Freebie is only allowed from OURS_GOOD warehouses ')
1253
 
7190 amar.kumar 1254
                    warehouse_client = WarehouseClient().get_client()
1255
                    inventoryItem = warehouse_client.scanfreebie(orderId, order.freebieItemId, freebieWarehouseId, ScanType.SALE);
1256
 
1257
                    attr = Attribute()
1258
                    attr.orderId = orderId
1259
                    attr.name = "freebie_tp"
1260
                    attr.value = str(inventoryItem.unitPrice)
1261
 
1262
                    attr1 = Attribute()
1263
                    attr1.orderId = orderId
1264
                    attr1.name = "freebie_vendor"
1265
                    attr1.value = str(inventoryItem.supplierId)
5966 rajveer 1266
 
7190 amar.kumar 1267
                    inventory_client = InventoryClient().get_client()
1268
                    item_pricing = inventory_client.getItemPricing(order.freebieItemId, warehouse.vendor.id)
1269
                    attr2 = Attribute()
1270
                    attr2.orderId = orderId
1271
                    attr2.name = "freebie_nlc"
1272
                    attr2.value = str(item_pricing.nlc)
1273
                except Exception as e:
1274
                    print sys.exc_info()[0]
1275
                    print e.message
7198 amar.kumar 1276
                    raise TransactionServiceException(110,'Error in billing freebie for warehouseId ' + str(freebieWarehouseId))
1277
            else:
1278
                raise TransactionServiceException(110,'No warehouseId provided for billing of freebie ')
1279
        else:
1280
            raise TransactionServiceException(110,'Order with freebies associated with it cant be billed from an external warehouse ')
5110 mandeep.dh 1281
    lineitem = order.lineitems[0]
1282
    item_id = lineitem.item_id
5966 rajveer 1283
 
6007 rajveer 1284
#    inventoryClient = InventoryClient().get_client()
1285
#    if not inventoryClient.isOrderBillable(item_id, order.fulfilmentWarehouseId, sourceId, orderId):
1286
#        raise TransactionServiceException(101, "There are other orders to be billed before this order id " + str(orderId))
5966 rajveer 1287
 
5110 mandeep.dh 1288
    catalog_client = CatalogClient().get_client()
1289
    item = catalog_client.getItem(item_id)
4283 anupam.sin 1290
    if order.status == OrderStatus.ACCEPTED:
4285 rajveer 1291
        order.jacket_number = jacketNumber
6751 amar.kumar 1292
 
1293
        if itemNumbers:
1294
            lineitem.item_number = itemNumbers[0]    
7180 rajveer 1295
        if serialNumbers:
1296
            lineitem.serial_number = serialNumbers[0]                
1297
 
6787 rajveer 1298
        '''
6751 amar.kumar 1299
        if billingType == BillingType.EXTERNAL or billingType == BillingType.OURS_EXTERNAL:
4763 rajveer 1300
            if billedOrdersColorMap.has_key(orderId):
1301
                etpColor = billedOrdersColorMap.get(orderId)
1302
                ourColor = order.lineitems[0].color
4781 rajveer 1303
                if ourColor and etpColor != ourColor and not authorize:
4763 rajveer 1304
                    raise TransactionServiceException(777, "ETP color: " + etpColor + " and Order color: " + ourColor)
1305
                else:
1306
                    billedOrdersColorMap.pop(orderId)
6787 rajveer 1307
        '''
6751 amar.kumar 1308
 
1309
        if billingType == BillingType.EXTERNAL:            
1310
            order.invoice_number = invoice_number
1311
 
1312
        if billingType == BillingType.OURS or billingType == BillingType.OURS_EXTERNAL:
6757 rajveer 1313
            if ItemType.SERIALIZED == item.type and not (serialNumbers and serialNumbers[0]):
1314
                raise TransactionServiceException(110, "No Serial Number supplied")
1315
            if serialNumbers:
1316
                lineitem.serial_number = serialNumbers[0]
6969 amar.kumar 1317
 
4283 anupam.sin 1318
 
2842 chandransh 1319
        order.status = OrderStatus.BILLED
1320
        order.statusDescription = "Order Billed"
1321
        order.billing_timestamp = datetime.datetime.now()
4285 rajveer 1322
        order.billed_by = billedBy
4435 mandeep.dh 1323
 
5436 mandeep.dh 1324
        # Letting the billing process fail in cases where we are unable to 
4435 mandeep.dh 1325
        # fill in transfer price
1326
        try:
5944 mandeep.dh 1327
            inventory_client = InventoryClient().get_client()
1328
            warehouse = inventory_client.getWarehouse(fulfilmentWarehouseId)
1329
            item_pricing = inventory_client.getItemPricing(item_id, warehouse.vendor.id)
5110 mandeep.dh 1330
            lineitem.transfer_price = item_pricing.transferPrice
6751 amar.kumar 1331
            lineitem.nlc = item_pricing.nlc
7330 amit.gupta 1332
            lineitem.vatRate = catalog_client.getVatPercentageForItem(lineitem.item_id, warehouse.stateId, lineitem.unit_price)
5110 mandeep.dh 1333
            order.vendorId = warehouse.vendor.id
4435 mandeep.dh 1334
        except InventoryServiceException as e:
1335
            print sys.exc_info()[0]
1336
            print e.message
5110 mandeep.dh 1337
            raise TransactionServiceException(110, 'Transfer price missing for itemId: ' + str(item_id) + ' and vendor: ' + str(warehouse.vendor.id))
4435 mandeep.dh 1338
 
5110 mandeep.dh 1339
        # For OUR warehouse, we need to scan out items for every billed order
1340
        if billingType == BillingType.OURS:
5530 mandeep.dh 1341
            for index, serialNumber in enumerate(serialNumbers):
5411 rajveer 1342
                try:
1343
                    warehouse_client = WarehouseClient().get_client()
5436 mandeep.dh 1344
                    # Fetching GOOD w/h corresponding to the virtual one here
5835 mandeep.dh 1345
                    if not warehouse.billingWarehouseId:
5950 mandeep.dh 1346
                        warehouse = inventory_client.getWarehouses(None, InventoryType.GOOD, warehouse.vendor.id, order.warehouse_id, 0)[0]
5436 mandeep.dh 1347
 
5411 rajveer 1348
                    if ItemType.SERIALIZED == item.type:
1349
                        inventoryItem = warehouse_client.getInventoryItem(serialNumber)
1350
                    else:
5661 mandeep.dh 1351
                        inventoryItem = warehouse_client.getNonSeralizedInventoryItem(itemNumbers[index], item_id, warehouse.id)
5411 rajveer 1352
 
1353
                    if (inventoryItem.itemId != item_id):
1354
                        catalog_client = CatalogClient().get_client()
1355
                        item = catalog_client.getItem(inventoryItem.itemId)
1356
                        scanItemString = " ".join([str(item.brand), str(item.modelName), str(item.modelNumber), str(item.color)])
1357
                        lineItemString = " ".join([str(lineitem.brand), str(lineitem.model_name), str(lineitem.model_number), str(lineitem.color)])
1358
                        raise TransactionServiceException(110, 'Trying to scan ' + scanItemString + ' instead of ' + lineItemString)
1359
 
1360
                    if ItemType.SERIALIZED == item.type:
5661 mandeep.dh 1361
                        inventoryItem = warehouse_client.scanSerializedItemForOrder(serialNumber, ScanType.SALE, orderId, warehouse.id, 1, order.warehouse_id)
5411 rajveer 1362
                    else:
5661 mandeep.dh 1363
                        inventoryItem = warehouse_client.scanForOrder(inventoryItem, ScanType.SALE, 1, order.id, warehouse.id, order.warehouse_id)
5411 rajveer 1364
 
1365
                    lineitem.transfer_price = inventoryItem.unitPrice
1366
                    order.vendorId = inventoryItem.supplierId
5636 amar.kumar 1367
                    catalog_client = CatalogClient().get_client()
5411 rajveer 1368
                except WarehouseServiceException as e:
1369
                    print sys.exc_info()[0]
1370
                    print 'Could not scan out orders due to: ' + e.message
1371
                    raise TransactionServiceException(110, e.message)
6763 amar.kumar 1372
        elif billingType == BillingType.OURS_EXTERNAL:
1373
            try:
6786 amar.kumar 1374
                if ItemType.SERIALIZED == item.type:
1375
                    serialNumber = serialNumbers[0]
1376
                else:
1377
                    serialNumber = ""
6763 amar.kumar 1378
                warehouse_client = WarehouseClient().get_client()
6768 amar.kumar 1379
                inventoryItem = warehouse_client.scanForOursExternalSale(lineitem.item_id, serialNumber, lineitem.item_number, invoice_number, order.fulfilmentWarehouseId, lineitem.transfer_price, order.id)
6763 amar.kumar 1380
                lineitem.transfer_price = inventoryItem.unitPrice
1381
                order.vendorId = inventoryItem.supplierId
1382
            except WarehouseServiceException as e:
1383
                print sys.exc_info()[0]
1384
                print 'Could not scan out orders due to: ' + e.message
1385
                raise TransactionServiceException(110, e.message)
5123 mandeep.dh 1386
        else:
1387
            if not warehouse.isAvailabilityMonitored:
5944 mandeep.dh 1388
                inventory_client = InventoryClient().get_client()
1389
                inventory_client.addInventory(item.id, warehouse.id, -1 * lineitem.quantity)
4365 mandeep.dh 1390
 
5110 mandeep.dh 1391
        __update_inventory_reservation(order)
5661 mandeep.dh 1392
        order.fulfilmentWarehouseId = warehouse.id
6969 amar.kumar 1393
        if billingType == BillingType.OURS or billingType == BillingType.OURS_EXTERNAL:
1394
            order.invoice_number = get_next_invoice_number(order.orderType)
4541 mandeep.dh 1395
        session.commit()
4283 anupam.sin 1396
        return True
1397
    else:
1398
        return False
1149 chandransh 1399
 
6751 amar.kumar 1400
def add_invoice_number(orderId, invoiceNumber, color, serialNumber, itemNumber):
4579 rajveer 1401
    order = Order.get_by(id=orderId)
1402
    if not order:
1403
        raise TransactionServiceException(101, "No order found for the given order id" + str(orderId))
1404
 
1405
    if order.status == OrderStatus.ACCEPTED:
1406
        order.invoice_number = invoiceNumber
4767 rajveer 1407
        if color:
6764 rajveer 1408
            billedOrdersColorMap[orderId] = color
6751 amar.kumar 1409
        if serialNumber:
6764 rajveer 1410
            order.lineitems[0].serial_number = serialNumber.strip() 
6751 amar.kumar 1411
        if itemNumber:
6764 rajveer 1412
            order.lineitems[0].item_number = itemNumber.strip()
4579 rajveer 1413
    session.commit()
1414
 
1220 chandransh 1415
def batch_orders(warehouseId):
1416
    if not warehouseId:
1417
        raise TransactionServiceException(101, "bad warehouse id")
1225 chandransh 1418
 
1419
    batchno_generator = BatchNoGenerator()
1420
    session.commit()
1220 chandransh 1421
    query = Order.query.filter_by(warehouse_id=warehouseId)
4592 mandeep.dh 1422
    query = query.filter(Order.status == OrderStatus.LOW_INV_PO_RAISED)
1220 chandransh 1423
    query = query.order_by(Order.created_timestamp)
1424
    pending_orders = query.all()
1225 chandransh 1425
 
1220 chandransh 1426
    serial_no = 1
1427
    for order in pending_orders:
1276 chandransh 1428
        order.batchNo = batchno_generator.id
1220 chandransh 1429
        order.serialNo = serial_no
1430
        serial_no += 1
1431
    session.commit() 
1432
    pending_orders = query.all()
1433
    return pending_orders
1434
 
1435
def order_outofstock(orderId):
1911 chandransh 1436
    '''
1437
    Mark order as out of stock
1438
    '''
1220 chandransh 1439
    order = get_order(orderId)
1440
    order.status = OrderStatus.INVENTORY_LOW
1441
    order.statusDescription = "Low Inventory"
1442
    order.outofstock_timestamp = datetime.datetime.now()
1443
    session.commit()
1444
    return True
1445
 
4789 rajveer 1446
def mark_orders_as_shipped_from_warehouse(warehouseId, providerId, cod, orderIds):
4410 rajveer 1447
    try:
1448
        current_timestamp = datetime.datetime.now()
5822 rajveer 1449
        orders = Order.query.filter(Order.id.in_(orderIds)).filter_by(warehouse_id = warehouseId, logistics_provider_id = providerId, status = OrderStatus.BILLED).all()
4410 rajveer 1450
        for order in orders:
5822 rajveer 1451
            order.status = OrderStatus.SHIPPED_FROM_WH
1452
            order.statusDescription = "Order shipped from warehouse"
1453
            order.shipping_timestamp = current_timestamp
1454
            try:
1455
                print "Trying to schedule alert"
1456
                monitoredEntity = MonitoredEntity();
1457
                monitoredEntity.entityType=EntityType.COURIER;
1458
                monitoredEntity.eventType=OrderStatus.SHIPPED_FROM_WH;
1459
                monitoredEntity.entityIdentifier="orderId = " + str(order.id);
1460
                adjustedDeliveryDays = adjust_delivery_time(datetime.datetime.now(), 1);
1461
                sec = datetime.datetime.now()
1462
                #Warn alert time is taken as 16 hrs
1463
                warn_time = (sec + timedelta(days=(adjustedDeliveryDays-1)) + timedelta(hours=16))
1464
                #Critical alert time is taken as 26 hrs                    
1465
                critical_time = (sec + timedelta(days=(adjustedDeliveryDays-1)) + timedelta(hours=26))
1466
                monitoredEntity.warnExpiryTime = int(warn_time.strftime("%s"))*1000
1467
                monitoredEntity.criticalExpiryTime = int(critical_time.strftime("%s"))*1000
1468
                monitoredEntity.description="warehouseId = " + str(warehouseId) + " providerId = " + str(providerId) + " orderId = "  + str(order.id);
1469
                alert_client = AlertClient().get_client()
1470
                alert_client.scheduleAlert(monitoredEntity)
1471
            except Exception as e:
1472
                print "Exception in scheduling alert in ShippedFromWarehouse method"
1473
                print e
759 chandransh 1474
        session.commit()
5832 rajveer 1475
 
4749 varun.gupt 1476
 
1477
        try:
5832 rajveer 1478
            for order in orders:
1479
                if order.pickupStoreId:
1480
                    send_mails_to_bdms(order)
1481
                else:
1482
                    enqueue_shipping_confirmation_email(order)
4749 varun.gupt 1483
        except Exception as e:
1484
            print e
5832 rajveer 1485
 
759 chandransh 1486
        return True
1487
    except:
1488
        return False
4410 rajveer 1489
 
5832 rajveer 1490
def send_mails_to_bdms(order):
5816 rajveer 1491
    logistics_client = LogisticsClient().get_client()
5832 rajveer 1492
    store = logistics_client.getPickupStore(order.pickupStoreId)
1493
    provider = logistics_client.getProvider(order.logistics_provider_id)
6029 rajveer 1494
    subject = source_name + " order " + str(order.id) +" shipped to store" 
5832 rajveer 1495
    raw_message = '''
1496
    Dear Sir,
5816 rajveer 1497
 
5832 rajveer 1498
    Order mentioned below is being shipped to your store. Customer will pick it from your store. 
1499
 
1500
    Store Id: %(store_id)s
1501
    Order Id: %(order_id)s 
1502
    Product: %(product)s
1503
    Delivery By: %(provider)s
5844 mandeep.dh 1504
    Payment Mode: %(payMode)s
1505
 
1506
    %(note)s
1507
 
5832 rajveer 1508
    Thanks and Regards
1509
    Sandeep Sachdeva
1510
    '''
1511
 
5844 mandeep.dh 1512
    payMode = 'Prepaid'
1513
    note = ''
1514
    if order.cod:
1515
        payMode = 'COD'
6318 rajveer 1516
        note = 'Note: Please collect Rs. ' + str(order.total_amount-order.gvAmount) + ' from customer'
5844 mandeep.dh 1517
 
5832 rajveer 1518
    message = dedent(raw_message) % { 'order_id' : str(order.id),
1519
                                     'store_id' : str(store.hotspotId),
1520
                                  'provider' : provider.name,
5844 mandeep.dh 1521
                                  'product' : str(order.lineitems[0]),
1522
                                  'payMode' : payMode,
1523
                                  'note'    : note
5832 rajveer 1524
                                  }
6643 rajveer 1525
    to_addresses = [store.email, store.bdmEmail, 'sandeep.sachdeva@shop2020.in', 'amit.sirohi@shop2020.in', 'manoj.kumar@shop2020.in']
5894 rajveer 1526
    cc = ['khushal.bhatia@spiceretail.co.in']
1527
    bcc = ['rajneesh.arora@spiceretail.co.in']
5966 rajveer 1528
    mail(mail_user, mail_password, to_addresses, subject, message, [], cc, bcc)
5816 rajveer 1529
 
5713 rajveer 1530
def mark_orders_as_returned_from_store(providerId, orderIds, awbs):
5676 rajveer 1531
    try:
1532
        current_timestamp = datetime.datetime.now()
5824 rajveer 1533
        orders = Order.query.filter(Order.id.in_(orderIds)).filter_by(logistics_provider_id = providerId, status = OrderStatus.RET_PICKUP_REQUEST_RAISED).all()
5676 rajveer 1534
        for order in orders:
6943 amar.kumar 1535
            order.status = OrderStatus.RTO_IN_TRANSIT
5824 rajveer 1536
            order.statusDescription = "Order returned from store"
1537
            order.doa_pickup_timestamp = current_timestamp
1538
            #order.airwaybill_no = awbs[orderIds.index(order.id)]
1539
            order.tracking_id = awbs[orderIds.index(order.id)]
5676 rajveer 1540
        session.commit()
1541
 
1542
        return True
1543
    except:
1544
        return False    
1545
 
1546
def set_order_attributes(orderId, attributes):
5871 rajveer 1547
    for attribute in attributes :
1548
        existingAttribute = Attribute.query.filter(Attribute.orderId == orderId).filter(Attribute.name == attribute.name).first()
1549
        if existingAttribute:
1550
            existingAttribute.value = attribute.value
1551
        else :                
1552
            attr = Attribute()
1553
            attr.orderId = orderId
1554
            attr.name = attribute.name
1555
            attr.value = attribute.value
5791 anupam.sin 1556
    session.commit()
5724 rajveer 1557
 
1113 chandransh 1558
def mark_orders_as_picked_up(provider_id, pickup_details):
1559
    for awb, pickup_timestamp in pickup_details.iteritems():
1135 chandransh 1560
        order = Order.query.filter_by(airwaybill_no=awb, logistics_provider_id = provider_id).first()
2684 chandransh 1561
        if order == None or order.status != OrderStatus.SHIPPED_FROM_WH:
2220 chandransh 1562
            #raise TransactionServiceException(102, "No order found for the awb: " + awb)
1563
            continue
1113 chandransh 1564
        order.status = OrderStatus.SHIPPED_TO_LOGST
1565
        order.statusDescription = "Order picked up by Courier Company"
1246 chandransh 1566
        order.pickup_timestamp = pickup_timestamp
5636 amar.kumar 1567
 
1568
        try:
1569
            monitoredEntity = MonitoredEntity();
1570
            monitoredEntity.entityType=EntityType.COURIER;
1571
            monitoredEntity.eventType=OrderStatus.SHIPPED_TO_LOGST
1572
            monitoredEntity.entityIdentifier="orderId = " + str(order.id);
5744 amar.kumar 1573
            adjustedDeliveryDays = adjust_delivery_time(datetime.datetime.now(), 1);
1574
            sec = datetime.datetime.now()
1575
            #Warn alert time is taken as 16 hrs
5821 amit.gupta 1576
            warn_time = (sec + timedelta(days=(adjustedDeliveryDays-1)) + timedelta(hours=15))
5744 amar.kumar 1577
            #Critical alert time is taken as 26 hrs                    
5821 amit.gupta 1578
            critical_time = (sec + timedelta(days=(adjustedDeliveryDays-1)) + timedelta(hours=20))
5744 amar.kumar 1579
            monitoredEntity.warnExpiryTime = int(warn_time.strftime("%s"))*1000
1580
            monitoredEntity.criticalExpiryTime = int(critical_time.strftime("%s"))*1000
5819 amit.gupta 1581
            monitoredEntity.description="providerId = " + str(provider_id)
5636 amar.kumar 1582
            alert_client = AlertClient().get_client()
1583
            alert_client.updateMonitoredObject(monitoredEntity)
1584
        except Exception as e:
5801 amar.kumar 1585
            print "Exception in updating alert in MarkOrdersAsPickedUp method"
5636 amar.kumar 1586
            print e
1113 chandransh 1587
    session.commit()
1217 chandransh 1588
 
4910 phani.kuma 1589
def get_orders_not_picked_up(provider_id):
1132 chandransh 1590
    current_time = datetime.datetime.now()
1591
    to_datetime = datetime.datetime(current_time.year, current_time.month, current_time.day)
4741 phani.kuma 1592
    orders_not_picked_up = Order.query.filter_by(logistics_provider_id = provider_id).filter_by(status=OrderStatus.SHIPPED_FROM_WH).filter(Order.shipping_timestamp <= to_datetime).all()
1113 chandransh 1593
    return orders_not_picked_up
1594
 
1132 chandransh 1595
def mark_orders_as_delivered(provider_id, delivered_orders):
1596
    for awb, detail in delivered_orders.iteritems():
1135 chandransh 1597
        order = Order.query.filter_by(airwaybill_no=awb, logistics_provider_id = provider_id).first()
4910 phani.kuma 1598
        if order == None or order.status not in [OrderStatus.SHIPPED_FROM_WH, OrderStatus.SHIPPED_TO_LOGST, OrderStatus.SHIPPED_TO_DESTINATION_CITY, OrderStatus.REACHED_DESTINATION_CITY, OrderStatus.FIRST_DELIVERY_ATTEMPT_MADE]:
1911 chandransh 1599
            continue
6561 amit.gupta 1600
        timestamp, receiver = detail.split('|')
1601
        order.delivery_timestamp = datetime.datetime.strptime(timestamp, "%Y-%m-%d %H:%M:%S")
1602
        if order.first_dlvyatmp_timestamp is None:
1603
            order.first_dlvyatmp_timestamp = order.delivery_timestamp
1604
        order.receiver = receiver
5555 rajveer 1605
        if order.pickupStoreId:
1606
            order.status = OrderStatus.DELIVERED_AT_STORE
1607
            order.statusDescription = "Order delivered At Store"
5762 amar.kumar 1608
            try:
1609
                monitoredEntity = MonitoredEntity();
1610
                monitoredEntity.entityType=EntityType.COURIER;
1611
                monitoredEntity.eventType=OrderStatus.RECEIVED_AT_STORE;
1612
                monitoredEntity.entityIdentifier="orderId = " + str(order.id);
1613
                #adjustedDeliveryDays = adjust_delivery_time(datetime.datetime.now(), 1);
1614
                sec = datetime.datetime.now()
1615
                #Critical alert time is taken as 26 hrs                    
1616
                critical_time = (sec + timedelta(hours=4))
1617
                monitoredEntity.criticalExpiryTime = int(critical_time.strftime("%s"))*1000
1618
                monitoredEntity.description="deliveryTimeAtStore = " + str(order.delivery_timestamp) + " orderId = "  + str(order.id);
1619
                alert_client = AlertClient().get_client()
1620
                alert_client.updateMonitoredObject(monitoredEntity)
1621
            except Exception as e:
1622
                print e
5555 rajveer 1623
        else:
1624
            order.status = OrderStatus.DELIVERY_SUCCESS
1625
            order.statusDescription = "Order delivered"
5762 amar.kumar 1626
            update_trust_level(order)
6903 anupam.sin 1627
            if order.insuranceDetails:
6906 rajveer 1628
                try:
1629
                    update_insurance_details(order)
1630
                except:
1631
                    print "Error generating insurance file for order " + str(order.id)
1632
                    session.rollback()
1633
                    return
1634
 
6745 anupam.sin 1635
            if enqueue_delivery_success_mail(order) :
1636
                session.commit()
1637
            else :
1638
                session.rollback()
5762 amar.kumar 1639
            try:
1640
                alert_client = AlertClient().get_client()
1641
                alert_client.endMonitoringEntity(EntityType.COURIER, "orderId = " + str(order.id))
1642
            except Exception as e:
5801 amar.kumar 1643
                print "Exception in scheduling alert in ShippedFromWarehouse method"
5762 amar.kumar 1644
                print e
5636 amar.kumar 1645
 
6906 rajveer 1646
def update_insurance_details(order):
1647
    order.insuranceDetails[0].startDate = order.delivery_timestamp
1648
    order.insuranceDetails[0].expiryDate = order.delivery_timestamp + timedelta(days = 365)
6947 rajveer 1649
    filename = "/tmp/" + str(order.id) + "-insurance-policy.pdf"
6906 rajveer 1650
    __generate_policy_doc(order, filename)
1651
    file = open(filename, "rb")
1652
    pdfFile = file.read()
1653
    doc = DocumentStore()
1654
    doc.docType = 1
1655
    doc.docSource = order.id
1656
    doc.document = pdfFile
1132 chandransh 1657
 
4712 rajveer 1658
def mark_order_as_delivered(orderId, deliveryTimestamp, receiver):
1659
    order = Order.get_by(id=orderId)
5555 rajveer 1660
    if order == None or order.status not in [OrderStatus.SHIPPED_FROM_WH, OrderStatus.SHIPPED_TO_LOGST, OrderStatus.SHIPPED_TO_DESTINATION_CITY, OrderStatus.REACHED_DESTINATION_CITY, OrderStatus.FIRST_DELIVERY_ATTEMPT_MADE, OrderStatus.DOA_PICKUP_REQUEST_RAISED, OrderStatus.DOA_PICKUP_CONFIRMED, OrderStatus.RET_REQUEST_RECEIVED, OrderStatus.RET_PICKUP_CONFIRMED, OrderStatus.RET_REQUEST_AUTHORIZED, OrderStatus.RET_PICKUP_REQUEST_RAISED, OrderStatus.RTO_IN_TRANSIT, OrderStatus.BILLED, OrderStatus.RECEIVED_AT_STORE]:
4712 rajveer 1661
        raise TransactionServiceException(101, "Either wrond order id or invalid state " + str(orderId))
5402 rajveer 1662
 
1663
    # Provider is 4 is for self pickup and hardcoded. We should figure out a way to not to hard code.   
1664
    if order.status == OrderStatus.BILLED and order.logistics_provider_id != 4:
5807 rajveer 1665
        raise TransactionServiceException(101, "Order is not marked for self pickup: " + str(orderId))
5402 rajveer 1666
 
5555 rajveer 1667
    if order.status in [OrderStatus.SHIPPED_FROM_WH, OrderStatus.SHIPPED_TO_LOGST, OrderStatus.SHIPPED_TO_DESTINATION_CITY, OrderStatus.REACHED_DESTINATION_CITY, OrderStatus.FIRST_DELIVERY_ATTEMPT_MADE, OrderStatus.RTO_IN_TRANSIT, OrderStatus.BILLED, OrderStatus.RECEIVED_AT_STORE]:
6632 amit.gupta 1668
        order.delivery_timestamp = deliveryTimestamp
6631 amit.gupta 1669
        if order.first_dlvyatmp_timestamp is None:
6632 amit.gupta 1670
            order.first_dlvyatmp_timestamp = deliveryTimestamp
4712 rajveer 1671
        order.receiver = receiver
1672
    order.status = OrderStatus.DELIVERY_SUCCESS
1673
    order.statusDescription = "Order delivered"
1674
    update_trust_level(order)
6903 anupam.sin 1675
    if order.insuranceDetails:
6906 rajveer 1676
        try:
1677
            update_insurance_details(order)
1678
        except:
1679
            print "Error generating insurance file for order " + str(order.id)
1680
            session.rollback()
1681
            return
4712 rajveer 1682
    session.commit()
5713 rajveer 1683
 
5812 rajveer 1684
    if order.pickupStoreId and order.cod:
5806 rajveer 1685
        __push_collection_to_hotspot(order, "SALE")
1686
 
5966 rajveer 1687
    enqueue_delivery_success_mail(order)
5713 rajveer 1688
#    if order.pickupStoreId:
1689
#        payment_client = PaymentClient().get_client()
1690
#        payment_client.createRefund(order.id, order.transaction.id, order.total_amount)
1691
#        payment_client = PaymentClient().get_client()
1692
#        payment_client.partiallyCapturePayment(order.transaction.id, order.total_amount, xferBy, xferTxnId, now())
1693
#        order.cod_reconciliation_timestamp = datetime.datetime.now()
1694
#        session.commit()
1695
 
5636 amar.kumar 1696
    try:
1697
        alert_client = AlertClient().get_client()
5744 amar.kumar 1698
        alert_client.endMonitoringEntity(EntityType.COURIER, "orderId = " + str(order.id))
5636 amar.kumar 1699
    except Exception as e:
5801 amar.kumar 1700
        print "Exception in ending alert in MarkOrderAsDelivered method"
5636 amar.kumar 1701
        print e
1702
 
4712 rajveer 1703
 
5555 rajveer 1704
def mark_order_as_received_at_store(orderId, deliveryTimestamp):
1705
    order = Order.get_by(id=orderId)
1706
    if order != None or order.status in [OrderStatus.SHIPPED_FROM_WH, OrderStatus.SHIPPED_TO_LOGST, OrderStatus.SHIPPED_TO_DESTINATION_CITY, OrderStatus.REACHED_DESTINATION_CITY, OrderStatus.FIRST_DELIVERY_ATTEMPT_MADE, OrderStatus.DELIVERED_AT_STORE]:
1707
        order.status = OrderStatus.RECEIVED_AT_STORE
1708
        order.statusDescription = "Order received at store"
1709
        order.delivery_timestamp = deliveryTimestamp
1710
    session.commit()
5713 rajveer 1711
    try:
5762 amar.kumar 1712
        alert_client = AlertClient().get_client()
1713
        alert_client.endMonitoringEntity(EntityType.COURIER, "orderId = " + str(order.id))
1714
    except Exception as e:
1715
        print e
1716
 
1717
    try:
5713 rajveer 1718
        enqueue_received_at_store_email(order)
1719
    except Exception as e:
1720
        print e
1721
 
1722
 
5555 rajveer 1723
 
4910 phani.kuma 1724
def mark_orders_as_rto(provider_id, returned_orders):
1135 chandransh 1725
    for awb, detail in returned_orders.iteritems():
1726
        order = Order.query.filter_by(airwaybill_no=awb, logistics_provider_id = provider_id).first()
5713 rajveer 1727
        if order == None or order.status not in [OrderStatus.SHIPPED_FROM_WH, OrderStatus.DELIVERED_AT_STORE, OrderStatus.SHIPPED_TO_LOGST, OrderStatus.SHIPPED_TO_DESTINATION_CITY, OrderStatus.REACHED_DESTINATION_CITY, OrderStatus.FIRST_DELIVERY_ATTEMPT_MADE]:
2684 chandransh 1728
            continue
1729
            #raise TransactionServiceException(103, "No order found for the awb:" + awb)
4484 rajveer 1730
        order.status = OrderStatus.RTO_IN_TRANSIT
1135 chandransh 1731
        order.delivery_timestamp, reason = detail.split('|')
1732
        order.statusDescription = "Order Returned to Origin:" + reason
3578 mandeep.dh 1733
        update_trust_level(order)
1911 chandransh 1734
    session.commit()
5636 amar.kumar 1735
    try:
1736
        alert_client = AlertClient().get_client()
5801 amar.kumar 1737
        alert_client.endMonitoringEntity(EntityType.COURIER, "orderId = " + str(order.id))
5636 amar.kumar 1738
    except Exception as e:
5801 amar.kumar 1739
        print "Exception in ending alert in MarkOrderAsRTO method"
5636 amar.kumar 1740
        print e
1135 chandransh 1741
 
4910 phani.kuma 1742
def get_rto_orders(provider_id):
1743
    current_time = datetime.datetime.now()
1744
    to_datetime = datetime.datetime(current_time.year, current_time.month, current_time.day)
1745
    rto_orders = Order.query.filter_by(logistics_provider_id = provider_id).filter_by(status=OrderStatus.RTO_IN_TRANSIT).filter(Order.delivery_timestamp <= to_datetime).all()
1746
    return rto_orders
1747
 
5555 rajveer 1748
def get_receive_pending_orders(storeId):
1749
    return Order.query.filter_by(pickupStoreId = storeId).filter(Order.status.in_((OrderStatus.SHIPPED_FROM_WH, OrderStatus.SHIPPED_TO_LOGST, OrderStatus.SHIPPED_TO_DESTINATION_CITY, OrderStatus.REACHED_DESTINATION_CITY, OrderStatus.FIRST_DELIVERY_ATTEMPT_MADE, OrderStatus.DELIVERED_AT_STORE))).all()
1750
 
1751
def get_received_at_store_orders(storeId):
5676 rajveer 1752
    return Order.query.filter_by(pickupStoreId = storeId).filter(Order.status.in_((OrderStatus.RECEIVED_AT_STORE, OrderStatus.RET_PICKUP_REQUEST_RAISED))).all()
5555 rajveer 1753
 
5713 rajveer 1754
def get_orders_collection_at_store(storeId, fromDate, toDate, onlyCod):
1755
    query = Order.query.filter(Order.status == OrderStatus.DELIVERY_SUCCESS)
1756
    if storeId:
1757
        query = query.filter_by(pickupStoreId = storeId)
5720 rajveer 1758
    else:
1759
        query = query.filter(Order.pickupStoreId != 0)
5713 rajveer 1760
    if onlyCod:
1761
        query = query.filter_by(cod = onlyCod)
1762
    if fromDate:
1763
        query = query.filter(Order.delivery_timestamp >= fromDate)
1764
    if toDate:
1765
        query = query.filter(Order.delivery_timestamp <= toDate)
1766
    return query.all()
1767
 
1246 chandransh 1768
def update_non_delivery_reason(provider_id, undelivered_orders):
1769
    for awb, reason in undelivered_orders.iteritems():
1770
        order = Order.query.filter_by(airwaybill_no=awb, logistics_provider_id = provider_id).first()
4920 phani.kuma 1771
        if order == None or order.status == OrderStatus.FIRST_DELIVERY_ATTEMPT_MADE:
2684 chandransh 1772
            continue
1773
            #raise TransactionServiceException(103, "No order found for the awb:" + awb)
1246 chandransh 1774
        order.statusDescription = reason
1775
    session.commit()
4910 phani.kuma 1776
 
1777
def get_non_delivered_orders_by_courier(provider_id):
4581 phani.kuma 1778
    current_time = datetime.datetime.now()
1779
    today_datetime = datetime.datetime(current_time.year, current_time.month, current_time.day)
1780
    upto_datetime = today_datetime - datetime.timedelta(4)
4910 phani.kuma 1781
    orders_not_delivered = Order.query.filter_by(logistics_provider_id = provider_id).filter(Order.status.in_((OrderStatus.SHIPPED_FROM_WH, OrderStatus.SHIPPED_TO_LOGST, OrderStatus.SHIPPED_TO_DESTINATION_CITY, OrderStatus.REACHED_DESTINATION_CITY, OrderStatus.FIRST_DELIVERY_ATTEMPT_MADE))).filter(or_(Order.shipping_timestamp <= upto_datetime, Order.pickup_timestamp <= upto_datetime)).all()
4581 phani.kuma 1782
    return orders_not_delivered
1246 chandransh 1783
 
4910 phani.kuma 1784
def mark_orders_as_local_connected(provider_id, local_connected_orders):
1785
    for awb, timestamp in local_connected_orders.iteritems():
1786
        order = Order.query.filter_by(airwaybill_no=awb, logistics_provider_id = provider_id).first()
1787
        if order == None or order.status not in [OrderStatus.SHIPPED_FROM_WH, OrderStatus.SHIPPED_TO_LOGST]:
1788
            #raise TransactionServiceException(102, "No order found for the awb: " + awb)
1789
            continue
1790
        order.status = OrderStatus.SHIPPED_TO_DESTINATION_CITY
1791
        order.statusDescription = "Left Out of Origin City"
5636 amar.kumar 1792
        current_time = datetime.datetime.now()
1793
        order.local_connected_timestamp = datetime.datetime(current_time.year, current_time.month, current_time.day)
1794
        try:
1795
            monitoredEntity = MonitoredEntity();
1796
            monitoredEntity.entityType=EntityType.COURIER;
1797
            monitoredEntity.eventType=OrderStatus.SHIPPED_TO_DESTINATION_CITY
1798
            monitoredEntity.entityIdentifier="orderId = " + str(order.id);
5744 amar.kumar 1799
            #Warn alert time is taken as 23 hrs less than promised delivery time
5821 amit.gupta 1800
            warn_time = (order.expected_delivery_time-timedelta(hours = 15))
5744 amar.kumar 1801
            #Critical alert time is taken as 13 hrs less than promised delivery time                    
5821 amit.gupta 1802
            critical_time = (order.expected_delivery_time-timedelta(hours = 10))
5801 amar.kumar 1803
            monitoredEntity.warnExpiryTime = int(warn_time.strftime("%s"))*1000
1804
            monitoredEntity.criticalExpiryTime = int(critical_time.strftime("%s"))*1000
5636 amar.kumar 1805
            monitoredEntity.description="providerId = " + str(provider_id) + " destination city " + order.customer_city 
1806
            alert_client = AlertClient().get_client()
1807
            alert_client.updateMonitoredObject(monitoredEntity)
1808
        except Exception as e:
5801 amar.kumar 1809
            print "Exception in updating alert in MarkOrderAsLocalConnected method"
5636 amar.kumar 1810
            print e
1811
        session.commit()
4910 phani.kuma 1812
 
1813
def get_orders_not_local_connected(provider_id):
1814
    current_time = datetime.datetime.now()
1815
    to_datetime = datetime.datetime(current_time.year, current_time.month, current_time.day)
1816
    orders_pending_local_connection = Order.query.filter_by(logistics_provider_id = provider_id).filter(Order.status.in_((OrderStatus.SHIPPED_FROM_WH, OrderStatus.SHIPPED_TO_LOGST))).filter(or_(Order.shipping_timestamp <= to_datetime, Order.pickup_timestamp <= to_datetime)).all()
1817
    return orders_pending_local_connection
1818
 
1819
def mark_orders_as_destinationCityReached(provider_id, destination_city_reached_orders):
1820
    for awb, timestamp in destination_city_reached_orders.iteritems():
1821
        order = Order.query.filter_by(airwaybill_no=awb, logistics_provider_id = provider_id).first()
1822
        if order == None or order.status not in [OrderStatus.SHIPPED_FROM_WH, OrderStatus.SHIPPED_TO_LOGST, OrderStatus.SHIPPED_TO_DESTINATION_CITY]:
1823
            continue
1824
            #raise TransactionServiceException(103, "No order found for the awb:" + awb)
1825
        order.status = OrderStatus.REACHED_DESTINATION_CITY
1826
        order.statusDescription = "Reached Destination City"
1827
        order.reached_destination_timestamp = timestamp
5636 amar.kumar 1828
        try:
1829
            monitoredEntity = MonitoredEntity();
1830
            monitoredEntity.entityType=EntityType.COURIER;
1831
            monitoredEntity.eventType=OrderStatus.REACHED_DESTINATION_CITY
1832
            monitoredEntity.entityIdentifier="orderId = " + str(order.id);
5764 amar.kumar 1833
            warn_time = (order.expected_delivery_time)
5801 amar.kumar 1834
            critical_time = (order.expected_delivery_time + timedelta(hours=12))
1835
            monitoredEntity.warnExpiryTime = int(warn_time.strftime("%s"))*1000
1836
            monitoredEntity.criticalExpiryTime = int(critical_time.strftime("%s"))*1000
5636 amar.kumar 1837
            monitoredEntity.description="providerId = " + str(provider_id) + " destination city " + order.customer_city 
1838
            alert_client = AlertClient().get_client()
1839
            alert_client.updateMonitoredObject(monitoredEntity)
1840
        except Exception as e:
5801 amar.kumar 1841
            print "Exception in updating alert in MarkOrderAsDestCityReached method"
5636 amar.kumar 1842
            print e
4910 phani.kuma 1843
    session.commit()
1844
 
1845
def mark_orders_as_firstDeliveryAttempted(provider_id, first_atdl_orders):
1846
    for awb, detail in first_atdl_orders.iteritems():
1847
        order = Order.query.filter_by(airwaybill_no=awb, logistics_provider_id = provider_id).first()
1848
        if order == None or order.status not in [OrderStatus.SHIPPED_FROM_WH, OrderStatus.SHIPPED_TO_LOGST, OrderStatus.SHIPPED_TO_DESTINATION_CITY, OrderStatus.REACHED_DESTINATION_CITY]:
1849
            continue
1850
            #raise TransactionServiceException(103, "No order found for the awb:" + awb)
1851
        order.status = OrderStatus.FIRST_DELIVERY_ATTEMPT_MADE
1852
        order.first_dlvyatmp_timestamp, reason = detail.split('|')
1853
        order.statusDescription = reason
5636 amar.kumar 1854
        try:
1855
            monitoredEntity = MonitoredEntity();
1856
            monitoredEntity.entityType=EntityType.COURIER;
1857
            monitoredEntity.eventType=OrderStatus.FIRST_DELIVERY_ATTEMPT_MADE
1858
            monitoredEntity.entityIdentifier="orderId = " + str(order.id);
5744 amar.kumar 1859
            adjustedDeliveryDaysfor1day = adjust_delivery_time(datetime.datetime.now(), 1);
1860
            adjustedDeliveryDaysfor2days = adjust_delivery_time(datetime.datetime.now(), 2);
1861
            sec = datetime.datetime.now()
1862
            #Warn alert time is taken as 16 hrs
1863
            warn_time = (sec + timedelta(days=(adjustedDeliveryDaysfor1day-1)) + timedelta(hours=24))
1864
            #Critical alert time is taken as 26 hrs                    
1865
            critical_time = (sec + timedelta(days=(adjustedDeliveryDaysfor2days-1)) + timedelta(hours=36))
1866
            monitoredEntity.warnExpiryTime = int(warn_time.strftime("%s"))*1000
1867
            monitoredEntity.criticalExpiryTime = int(critical_time.strftime("%s"))*1000
5636 amar.kumar 1868
            monitoredEntity.description="providerId = " + str(provider_id) + " first attempt timestamp" + order.first_dlvyatmp_timestamp
1869
            alert_client = AlertClient().get_client()
1870
            alert_client.updateMonitoredObject(monitoredEntity)
1871
        except Exception as e:
5801 amar.kumar 1872
            print "Exception in updating alert in MarkOrdersAsFirstDeliveryAttempted method"
5636 amar.kumar 1873
            print e
4910 phani.kuma 1874
    session.commit()
1875
 
4783 phani.kuma 1876
def get_orders_not_met_expected_delivery_date():
1877
    current_time = datetime.datetime.now()
1878
    today_datetime = datetime.datetime(current_time.year, current_time.month, current_time.day)
4910 phani.kuma 1879
    orders_not_delivered = Order.query.filter(Order.status.in_((OrderStatus.SHIPPED_FROM_WH, OrderStatus.SHIPPED_TO_LOGST, OrderStatus.SHIPPED_TO_DESTINATION_CITY, OrderStatus.REACHED_DESTINATION_CITY))).filter(Order.expected_delivery_time <= today_datetime).all()
4783 phani.kuma 1880
    return orders_not_delivered
1881
 
4444 rajveer 1882
def get_alerts(type, warehouseId, status, timestamp):
1883
    query = Alert.query.filter(Alert.warehouseId == warehouseId)
1884
    if type != -1 :
1885
        query = query.filter(Alert.type == type)
1886
    if status != -1 :
1887
        query = query.filter(Alert.status == status)
4394 rajveer 1888
    if timestamp:
1889
        query = query.filter(Alert.timestamp >= to_py_date(timestamp))
4412 rajveer 1890
    query = query.order_by(desc(Alert.timestamp))
483 rajveer 1891
    return query.all()
1892
 
4447 rajveer 1893
def add_alert(type, warehouseId, description):
4394 rajveer 1894
    alert = Alert()
1895
    alert.type = type
1896
    alert.status = 1
1897
    alert.description = description
1898
    alert.timestamp = datetime.datetime.now()
4447 rajveer 1899
    alert.warehouseId = warehouseId
4444 rajveer 1900
    session.commit()
766 rajveer 1901
 
4444 rajveer 1902
def mark_alerts_as_seen(warehouseId):
1903
    query = Alert.query.filter(Alert.warehouseId == warehouseId).filter(Alert.status == 1)
1904
    alerts = query.all()
1905
    for alert in alerts:
1906
        alert.status = 0    
1907
    session.commit()
1908
 
1596 ankur.sing 1909
def get_valid_order_count():
2851 chandransh 1910
    '''
1911
    Returns the number of orders which we processed. The reshipped orders are not
1912
    counted since there'll always be a new compensating order present.
1913
    '''
4682 rajveer 1914
    return Order.query.filter(Order.status >= OrderStatus.SUBMITTED_FOR_PROCESSING).filter(not_(Order.status.in_((OrderStatus.RTO_RESHIPPED, OrderStatus.DOA_INVALID_RESHIPPED, OrderStatus.DOA_VALID_RESHIPPED, OrderStatus.COD_VERIFICATION_FAILED)))).count()
1596 ankur.sing 1915
 
1627 ankur.sing 1916
def get_cust_count_with_successful_txn():
2851 chandransh 1917
    '''
1918
    Returns the number of distinct customers who have done successful transactions.
1919
    It uses the sqlalchemy func module to construct an efficient query.
1920
    '''
1921
    return session.query(func.count(distinct(Order.customer_id))).filter(Order.status >= OrderStatus.SUBMITTED_FOR_PROCESSING).scalar()
1627 ankur.sing 1922
 
1730 ankur.sing 1923
def get_valid_orders_amount_range():
2851 chandransh 1924
    '''
1925
    Returns a list containing the minimum and maximum amount across all
1926
    orders placed with us. No need to consider reshippped orders for min/max
1927
    amount of orders.
1928
    '''
1929
    return session.query(func.min(Order.total_amount), func.max(Order.total_amount)).filter(Order.status >= OrderStatus.SUBMITTED_FOR_PROCESSING).one()
1627 ankur.sing 1930
 
5874 rajveer 1931
def get_valid_orders(limit, onlyStore):
2851 chandransh 1932
    '''
1933
    Returns the last limit number of valid orders placed with us. Ignored the
1934
    limit if it's passed as 0. Raises an excpetion if the supplied limit is 
1935
    less than 0. 
1936
    '''
1937
    if limit < 0:
1938
        raise TransactionServiceException(101, "Invalid argument limit " + limit)
4662 rajveer 1939
    query = Order.query.filter(Order.status >= OrderStatus.COD_VERIFICATION_PENDING)
5874 rajveer 1940
    if onlyStore:
1941
        query = query.filter(Order.pickupStoreId != 0)
1886 ankur.sing 1942
    query = query.order_by(desc(Order.created_timestamp))
2851 chandransh 1943
    if limit != 0:
1886 ankur.sing 1944
        query = query.limit(limit)
1945
    return query.all()
1946
 
5527 anupam.sin 1947
def get_next_invoice_number(orderType):
1948
    if OrderType.B2Cbulk == orderType:
1949
        orderType = OrderType.B2C
1950
    entity_id = InvoiceIDGenerator.query.filter(InvoiceIDGenerator.orderType == orderType).with_lockmode("update").one()
2783 chandransh 1951
    invoice_number = entity_id.id + 1
1952
    entity_id.id = invoice_number
1953
    return invoice_number
1954
 
2536 chandransh 1955
def toggle_doa_flag(order_id):
1956
    order = get_order(order_id)
1957
    if(order.doaFlag):
1958
        order.doaFlag = False
1959
    else:
1960
        order.doaFlag = True
1961
    session.commit()
1962
    return order.doaFlag
1963
 
4454 rajveer 1964
def mark_order_doa_request_received(orderId):
1965
    order = get_order(orderId)
1966
    if order.status != OrderStatus.DELIVERY_SUCCESS:
1967
        return False
1968
    order.status = OrderStatus.DOA_REQUEST_RECEIVED
4459 rajveer 1969
    order.statusDescription = "DOA Request Received"
4454 rajveer 1970
    session.commit()
1971
    return True
1972
 
1973
def mark_order_doa_request_authorized(orderId, isAuthorized):
1974
    order = get_order(orderId)
1975
    if order.status != OrderStatus.DOA_REQUEST_RECEIVED:
1976
        return False
1977
    if isAuthorized:
1978
        order.status = OrderStatus.DOA_REQUEST_AUTHORIZED
4459 rajveer 1979
        order.statusDescription = "DOA Request Authorized"
4454 rajveer 1980
    else:
1981
        order.status = OrderStatus.DELIVERY_SUCCESS
4459 rajveer 1982
        order.statusDescription = "Order delivered"
4454 rajveer 1983
    session.commit()
1984
    return True
1985
 
4488 rajveer 1986
def mark_order_return_request_received(orderId):
1987
    order = get_order(orderId)
1988
    if order.status != OrderStatus.DELIVERY_SUCCESS:
1989
        return False
1990
    order.status = OrderStatus.RET_REQUEST_RECEIVED
1991
    order.statusDescription = "Return Request Received"
1992
    session.commit()
1993
    return True
1994
 
1995
def mark_order_return_request_authorized(orderId, isAuthorized):
1996
    order = get_order(orderId)
1997
    if order.status != OrderStatus.RET_REQUEST_RECEIVED:
1998
        return False
1999
    if isAuthorized:
2000
        order.status = OrderStatus.RET_REQUEST_AUTHORIZED
2001
        order.statusDescription = "Return Request Authorized"
2002
    else:
2003
        order.status = OrderStatus.DELIVERY_SUCCESS
2004
        order.statusDescription = "Order delivered"
2005
    session.commit()
2006
    return True
2007
 
4579 rajveer 2008
def request_pickup_number(order_id, providerId):
2536 chandransh 2009
    order = get_order(order_id)
4495 rajveer 2010
    if order.status != OrderStatus.DELIVERY_SUCCESS and order.status != OrderStatus.DOA_REQUEST_AUTHORIZED and order.status != OrderStatus.RET_REQUEST_AUTHORIZED:
2536 chandransh 2011
        return False
2012
 
4227 rajveer 2013
    subject = "Pickup request from " + order.customer_city
2536 chandransh 2014
    try:
5944 mandeep.dh 2015
        inventory_client = InventoryClient().get_client()
2016
        warehouse = inventory_client.getWarehouse(order.warehouse_id)
2536 chandransh 2017
 
2018
        logistics_client = LogisticsClient().get_client()
4579 rajveer 2019
        provider = logistics_client.getProvider(providerId)
3051 chandransh 2020
        to_addr = provider.details[DeliveryType.PREPAID].email
2536 chandransh 2021
        raw_message = '''
2022
        Dear Sir/Madam,
2023
 
2559 chandransh 2024
        Kindly arrange a pickup today from %(customer_city)s. Pickup and delivery addresses are mentioned below.
2536 chandransh 2025
 
6663 rajveer 2026
        Order Id: %(order_id)s
2536 chandransh 2027
        Pickup CODE: %(provider_code)s
2028
        Total Weight: %(order_weight)s kg
2029
 
2559 chandransh 2030
        Pickup Address:
2536 chandransh 2031
 
2032
        %(customer_address)s
2033
 
2034
        Delivery Address:
2035
 
2036
        %(warehouse_executive)s
2037
        %(warehouse_address)s
2038
        PIN %(warehouse_pin)s
2039
 
2040
        Thanks and Regards
4227 rajveer 2041
        Sandeep Sachdeva
2536 chandransh 2042
        '''
4579 rajveer 2043
 
2044
        if warehouse.id == 7:
7181 rajveer 2045
            executive = 'Shiv Kumar'
4579 rajveer 2046
        else:
4966 phani.kuma 2047
            executive = 'Dinesh Kumar'
4579 rajveer 2048
 
2559 chandransh 2049
        message = dedent(raw_message) % { 'customer_city' : order.customer_city,
3051 chandransh 2050
                                          'provider_code' : provider.details[DeliveryType.PREPAID].accountNo,
6663 rajveer 2051
                                          'order_id' : str(order_id),
2536 chandransh 2052
                                          'order_weight' : str(order.total_weight),
2053
                                          'customer_address' : __get_order_address(order),
4579 rajveer 2054
                                          'warehouse_executive' : executive,
2536 chandransh 2055
                                          'warehouse_address' : warehouse.location,
4966 phani.kuma 2056
                                          'warehouse_pin' : warehouse.pincode}
6645 anupam.sin 2057
        to_addresses = [to_addr,'amit.sirohi@shop2020.in', 'shrawan.choudhary@shop2020.in', 'ritesh.chauhan@shop2020.in']
4966 phani.kuma 2058
 
5966 rajveer 2059
        mail(mail_user, mail_password, to_addresses, subject, message)
4495 rajveer 2060
        if order.status == OrderStatus.RET_REQUEST_AUTHORIZED:
2061
            order.status = OrderStatus.RET_PICKUP_REQUEST_RAISED
2062
            order.statusDescription = "Pick up requested for RETURN"
2063
        else:
2064
            order.status = OrderStatus.DOA_PICKUP_REQUEST_RAISED
2065
            order.statusDescription = "Pick up requested for DOA"
4815 phani.kuma 2066
        order.doa_logistics_provider_id = providerId
2536 chandransh 2067
        session.commit()
2068
        return True
2069
    except Exception as e:
2070
        print sys.exc_info()[0]
2071
        return False
2072
 
4602 rajveer 2073
def authorize_pickup(order_id, pickup_number, providerId):
2536 chandransh 2074
    order = get_order(order_id)
4495 rajveer 2075
    if order.status not in [OrderStatus.DOA_PICKUP_REQUEST_RAISED, OrderStatus.RET_PICKUP_REQUEST_RAISED]:
2536 chandransh 2076
        return False
4815 phani.kuma 2077
    if order.doa_logistics_provider_id is not None:
2078
        providerId = order.doa_logistics_provider_id    #previously we are not storing this so data is taken from omdashboarduser
2536 chandransh 2079
    subject = 'Pickup details'
2080
    filename = "/tmp/" +  str(order.id) +".pdf" 
2081
    try:
5944 mandeep.dh 2082
        inventory_client = InventoryClient().get_client()
2083
        warehouse = inventory_client.getWarehouse(order.warehouse_id)
2536 chandransh 2084
 
2085
        logistics_client = LogisticsClient().get_client()
4602 rajveer 2086
        provider = logistics_client.getProvider(providerId)
2536 chandransh 2087
        provider_name = provider.name
2088
 
2089
        to_addr = order.customer_email
2090
        today = date.today().strftime("%d-%B-%Y (%A)")
2091
 
2092
        raw_message = '''
2093
        Dear Mr. %(customer_name)s,
2094
 
4815 phani.kuma 2095
        In reference to the return of order ID %(order_id)d, ''' + __generate_mail_body_for_authorize_pickup(order)
2096
        raw_message = raw_message + '''
2536 chandransh 2097
        Take a printout of the attachment in this mail which contains the delivery address and paste it on the packed parcel.
2098
        We have instructed %(provider_name)s to pick up the material from the below mentioned address on %(date)s. %(provider_name)s pickup request number is %(pickup_request_no)s. Kindly keep the parcel ready.
2099
 
2100
        Pickup will happen from the below mentioned address:-
2101
 
2102
        %(customer_address)s
2103
 
2104
        Do let us know in case of any concerns
2105
 
2106
        Thanks & Regards
6029 rajveer 2107
        %(source_name)s Team
2536 chandransh 2108
        '''
2109
        message = dedent(raw_message) % {'customer_name' : order.customer_name,
2110
                                         'order_id' : order_id,
2111
                                         'provider_name' : provider_name,
2112
                                         'date': today,
2113
                                         'pickup_request_no' : pickup_number,
6029 rajveer 2114
                                         'customer_address' : __get_order_address(order),
2115
                                         'source_name' : source_name}
2536 chandransh 2116
        print message
2117
        __generate_return_advice(order, warehouse, provider, filename)
5966 rajveer 2118
        mail(help_user, help_password, [to_addr], subject, message, [get_attachment_part(filename)])
2536 chandransh 2119
        order.pickupRequestNo = pickup_number
4495 rajveer 2120
        if order.status == OrderStatus.RET_PICKUP_REQUEST_RAISED:
2121
            order.status = OrderStatus.RET_PICKUP_CONFIRMED
2122
            order.statusDescription = "RETURN pick up confirmed"
2123
        else:
2124
            order.status = OrderStatus.DOA_PICKUP_CONFIRMED
2125
            order.statusDescription = "DOA pick up confirmed"
2764 chandransh 2126
        order.doa_auth_timestamp = datetime.datetime.now()
2536 chandransh 2127
        session.commit()
2128
        return True
2129
    except Exception as e:
4234 rajveer 2130
        print sys.exc_info()
4506 phani.kuma 2131
        traceback.print_tb(sys.exc_info()[2])
2536 chandransh 2132
        return False
2133
    finally:
2134
        if os.path.exists(filename):
2135
            os.remove(filename)
2136
 
4815 phani.kuma 2137
def __generate_mail_body_for_authorize_pickup(order):
2138
    brand_msgbody_map = {'Nokia' : 'we request you to kindly pack the box properly with bubble wrap, and send it along with the all original accessories, original handset and the invoice.',
2139
                         'Micromax' : 'we request you to kindly pack the box properly with bubble wrap, and send it along with the all original accessories, original handset and the invoice.',
2140
                         'Karbonn' : 'we request you to kindly pack the box properly with bubble wrap, and send it along with the all original accessories, original handset and the invoice.',
2141
                         'Sony Ericsson' : 'we request you to kindly pack the original DOA certificate and the invoice.',
2142
                         'Others Handsets' : 'we request you to kindly pack the box properly with bubble wrap, and send it along with the original "DOA" certificate and the invoice. Please paste the original DOA on the sealed box. Kindly ensure that the product is properly sealed. If we receive open sealed products, we will not be able to accept.',
2143
                         'Handsets Return' : 'we request you to kindly pack the box properly with bubble wrap, and send it along with the all original accessories, original handset and the invoice.',
2144
                         'Accessories' : 'we request you to kindly pack the box properly with bubble wrap, and send it along with the original product and the invoice.'}
2145
    categories = ["Handsets", "Tablets", "Laptops"]
2146
    lineitem = order.lineitems[0]
2147
    brand = lineitem.brand
2148
    productGroup = lineitem.productGroup
2149
    searchkey = None
2150
    if productGroup not in categories:
2151
        searchkey = 'Accessories'
2152
    elif order.status == OrderStatus.RET_PICKUP_REQUEST_RAISED:
2153
        searchkey = 'Handsets Return'
2154
    elif brand == 'Nokia':
2155
        searchkey = 'Nokia'
2156
    elif brand == 'Micromax':
2157
        searchkey = 'Micromax'
2158
    elif brand == 'Karbonn':
2159
        searchkey = 'Karbonn'
2160
    elif brand == 'Sony Ericsson':
2161
        searchkey = 'Sony Ericsson'
2162
    else:
2163
        searchkey = 'Others Handsets'
2164
    return brand_msgbody_map.get(searchkey)
2165
 
2764 chandransh 2166
def mark_doas_as_picked_up(provider_id, pickup_details):
2167
    for pickupNo, doa_pickup_timestamp in pickup_details.iteritems():
4815 phani.kuma 2168
        order = Order.query.filter_by(pickupRequestNo=pickupNo, doa_logistics_provider_id = provider_id).first()
4452 rajveer 2169
        if order == None or order.status != OrderStatus.DOA_PICKUP_CONFIRMED:
2764 chandransh 2170
            #raise TransactionServiceException(102, "No order found for the awb: " + awb)
2171
            continue
2172
        order.status = OrderStatus.DOA_RETURN_IN_TRANSIT
2173
        order.statusDescription = "DOA picked up by Courier Company"
2174
        order.doa_pickup_timestamp = doa_pickup_timestamp
2175
    session.commit()
2176
 
4910 phani.kuma 2177
def get_doas_not_picked_up(provider_id):
2764 chandransh 2178
    current_time = datetime.datetime.now()
2179
    to_datetime = datetime.datetime(current_time.year, current_time.month, current_time.day)
4815 phani.kuma 2180
    orders_not_picked_up = Order.query.filter_by(doa_logistics_provider_id = provider_id).filter_by(status=OrderStatus.DOA_PICKUP_CONFIRMED).filter(Order.doa_auth_timestamp <= to_datetime).all()
2764 chandransh 2181
    return orders_not_picked_up
2182
 
4741 phani.kuma 2183
def mark_return_orders_as_picked_up(provider_id, pickup_details):
2184
    for pickupNo, return_order_pickup_timestamp in pickup_details.iteritems():
4815 phani.kuma 2185
        order = Order.query.filter_by(pickupRequestNo=pickupNo, doa_logistics_provider_id = provider_id).first()
4741 phani.kuma 2186
        if order == None or order.status != OrderStatus.RET_PICKUP_CONFIRMED:
2187
            #raise TransactionServiceException(102, "No order found for the awb: " + awb)
2188
            continue
2189
        order.status = OrderStatus.RET_RETURN_IN_TRANSIT
2190
        order.statusDescription = "Return order picked up by Courier Company"
2191
        order.doa_pickup_timestamp = return_order_pickup_timestamp
2192
    session.commit()
2193
 
4910 phani.kuma 2194
def get_return_orders_not_picked_up(provider_id):
4741 phani.kuma 2195
    current_time = datetime.datetime.now()
2196
    to_datetime = datetime.datetime(current_time.year, current_time.month, current_time.day)
4815 phani.kuma 2197
    orders_not_picked_up = Order.query.filter_by(doa_logistics_provider_id = provider_id).filter_by(status=OrderStatus.RET_PICKUP_CONFIRMED).filter(Order.doa_auth_timestamp <= to_datetime).all()
4741 phani.kuma 2198
    return orders_not_picked_up
2199
 
4479 rajveer 2200
def receive_return(order_id, receiveCondition):
2591 chandransh 2201
    order = get_order(order_id)
7199 amar.kumar 2202
    scanFreebie = False
4365 mandeep.dh 2203
 
4452 rajveer 2204
    if order.status in [OrderStatus.DOA_PICKUP_CONFIRMED, OrderStatus.DOA_RETURN_IN_TRANSIT]:
4479 rajveer 2205
        if receiveCondition == 0:
2206
            order.status = OrderStatus.DOA_RECEIVED_PRESTINE
2207
            order.statusDescription = "DOA package received"
2208
        elif receiveCondition == 1:
2209
            order.status = OrderStatus.DOA_RECEIVED_DAMAGED
2210
            order.statusDescription = "DOA received damaged"
2211
        elif receiveCondition == 2:
2212
            order.status = OrderStatus.DOA_LOST_IN_TRANSIT
2213
            order.statusDescription = "DOA lost in transit"
2764 chandransh 2214
        order.received_return_timestamp = datetime.datetime.now()
4495 rajveer 2215
    elif order.status in [OrderStatus.RET_PICKUP_CONFIRMED, OrderStatus.RET_RETURN_IN_TRANSIT]:
2216
        if receiveCondition == 0:
2217
            order.status = OrderStatus.RET_RECEIVED_PRESTINE
2218
            order.statusDescription = "RETURN package received"
2219
        elif receiveCondition == 1:
2220
            order.status = OrderStatus.RET_RECEIVED_DAMAGED
2221
            order.statusDescription = "RETURN received damaged"
2222
        elif receiveCondition == 2:
2223
            order.status = OrderStatus.RET_LOST_IN_TRANSIT
2224
            order.statusDescription = "RETURN lost in transit"
2225
        order.received_return_timestamp = datetime.datetime.now()
4484 rajveer 2226
    elif order.status == OrderStatus.RTO_IN_TRANSIT :
4486 rajveer 2227
        if receiveCondition == 0:
2228
            order.status = OrderStatus.RTO_RECEIVED_PRESTINE
4515 mandeep.dh 2229
            order.statusDescription = "Returned to origin"
4486 rajveer 2230
        elif receiveCondition == 1:
2231
            order.status = OrderStatus.RTO_RECEIVED_DAMAGED
2232
            order.statusDescription = "RTO received damaged"
2233
        elif receiveCondition == 2:
2234
            order.status = OrderStatus.RTO_LOST_IN_TRANSIT
2235
            order.statusDescription = "RTO lost in transit"
2764 chandransh 2236
        order.received_return_timestamp = datetime.datetime.now()
7199 amar.kumar 2237
        if order.freebieItemId:
2238
            scanFreebie = True
2616 chandransh 2239
    else:
2591 chandransh 2240
        return False
5110 mandeep.dh 2241
 
2242
    # For OUR warehouses, we need to scan in items for every return
5944 mandeep.dh 2243
    inventoryClient = InventoryClient().get_client()
2244
    warehouse = inventoryClient.getWarehouse(order.warehouse_id)
6763 amar.kumar 2245
    if warehouse.billingType == BillingType.OURS or warehouse.billingType == BillingType.OURS_EXTERNAL:
5361 mandeep.dh 2246
        scanMap = {
2247
            OrderStatus.RTO_RECEIVED_PRESTINE : ScanType.SALE_RET,
2248
            OrderStatus.RTO_RECEIVED_DAMAGED  : ScanType.SALE_RET_UNUSABLE,
2249
            OrderStatus.RTO_LOST_IN_TRANSIT   : ScanType.LOST_IN_TRANSIT,
2250
            OrderStatus.DOA_RECEIVED_PRESTINE : ScanType.DOA_IN,
2251
            OrderStatus.DOA_RECEIVED_DAMAGED  : ScanType.DOA_IN,
2252
            OrderStatus.DOA_LOST_IN_TRANSIT   : ScanType.LOST_IN_TRANSIT
2253
        }
5110 mandeep.dh 2254
 
5419 mandeep.dh 2255
        if scanMap.has_key(order.status):
2256
            scanType = scanMap[order.status]
5361 mandeep.dh 2257
            lineitem = order.lineitems[0]
5944 mandeep.dh 2258
            catalogClient = CatalogClient().get_client()
5361 mandeep.dh 2259
            item = catalogClient.getItem(lineitem.item_id)
2260
            warehouseClient = WarehouseClient().get_client()
6763 amar.kumar 2261
            if warehouse.billingType == BillingType.OURS or scanType != ScanType.SALE_RET:
2262
                if item.type == ItemType.SERIALIZED:
2263
                    warehouseClient.scanSerializedItemForOrder(lineitem.serial_number, scanType, order.id, order.fulfilmentWarehouseId, lineitem.quantity, order.warehouse_id)
2264
                else:
2265
                    warehouseClient.scanForOrder(None, scanType, lineitem.quantity, order.id, order.fulfilmentWarehouseId, order.warehouse_id)
2266
            if warehouse.billingType == BillingType.OURS_EXTERNAL and scanType == ScanType.SALE_RET:
2267
                warehouseClient.scanForOursExternalSaleReturn(order.id, lineitem.transfer_price)
7199 amar.kumar 2268
            if scanFreebie:
7292 amar.kumar 2269
                warehouseClient.scanfreebie(order.id, order.freebieItemId, 0, scanType)
5558 mandeep.dh 2270
    session.commit()
2591 chandransh 2271
    return True
2272
 
2273
def validate_doa(order_id, is_valid):
2274
    order = get_order(order_id)
4452 rajveer 2275
    if order.status != OrderStatus.DOA_RECEIVED_PRESTINE:
2591 chandransh 2276
        return False
2277
    if is_valid:
2609 chandransh 2278
        order.status = OrderStatus.DOA_CERT_VALID
2279
        order.statusDescription = "DOA Certificate Valid"
2591 chandransh 2280
    else:
2281
        order.status = OrderStatus.DOA_CERT_INVALID
2282
        order.statusDescription = "DOA Certificate Invalid"
3578 mandeep.dh 2283
        update_trust_level(order)
2591 chandransh 2284
    session.commit()
2285
    return True
2286
 
4495 rajveer 2287
def validate_return_product(order_id, is_usable):
2288
    order = get_order(order_id)
2289
    if order.status != OrderStatus.RET_RECEIVED_PRESTINE:
2290
        return False
5110 mandeep.dh 2291
 
2292
    scanType = ScanType.SALE_RET_UNUSABLE
4495 rajveer 2293
    if is_usable:
2294
        order.status = OrderStatus.RET_PRODUCT_USABLE
2295
        order.statusDescription = "Return product usable"
5110 mandeep.dh 2296
        scanType = ScanType.SALE_RET
4495 rajveer 2297
    else:
2298
        order.status = OrderStatus.RET_PRODUCT_UNUSABLE
2299
        order.statusDescription = "Return product unusable"
2300
        update_trust_level(order)
2301
    session.commit()
5110 mandeep.dh 2302
 
2303
    # For OUR warehouses, we need to scan in items for every return
5944 mandeep.dh 2304
    inventoryClient = InventoryClient().get_client()
2305
    warehouse = inventoryClient.getWarehouse(order.warehouse_id)
6786 amar.kumar 2306
    if warehouse.billingType == BillingType.OURS or warehouse.billingType == BillingType.OURS_EXTERNAL:
5110 mandeep.dh 2307
        lineitem = order.lineitems[0]
5944 mandeep.dh 2308
        catalogClient = CatalogClient().get_client()
5361 mandeep.dh 2309
        item = catalogClient.getItem(lineitem.item_id)
5110 mandeep.dh 2310
        warehouse_client = WarehouseClient().get_client()
6786 amar.kumar 2311
        if warehouse.billingType == BillingType.OURS or scanType != ScanType.SALE_RET:
2312
            if item.type == ItemType.SERIALIZED:
2313
                warehouse_client.scanSerializedItemForOrder(lineitem.serial_number, scanType, order.id, order.fulfilmentWarehouseId, lineitem.quantity, order.warehouse_id)
2314
            else:
2315
                warehouse_client.scanForOrder(None, scanType, lineitem.quantity, order.id, order.fulfilmentWarehouseId, order.warehouse_id)
2316
        if scanType == ScanType.SALE_RET and warehouse.billingType == BillingType.OURS_EXTERNAL:
2317
            warehouse_client.scanForOursExternalSaleReturn(order.id, lineitem.transfer_price)        
4495 rajveer 2318
    return True
2319
 
2628 chandransh 2320
def reship_order(order_id):
2321
    """
4484 rajveer 2322
    If the order is in RTO_RECEIVED_PRESTINE or DOA_CERT_INVALID state, it does the following:
2628 chandransh 2323
        1. Creates a new order for processing in the BILLED state. All billing information is saved.
4484 rajveer 2324
        2. Marks the current order as one of the final states RTO_RESHIPPED and DOA_INVALID_RESHIPPED depending on what state the order started in.
2628 chandransh 2325
 
2326
    If the order is in DOA_CERT_VALID state, it does the following:
2327
        1. Creates a new order for processing in the SUBMITTED_FOR_PROCESSING state.
2328
        2. Creates a return order for the warehouse executive to return the DOA material.
4452 rajveer 2329
        3. Marks the current order as the final DOA_VALID_RESHIPPED state.
2628 chandransh 2330
 
2331
    Returns the id of the newly created order.
2332
 
2333
    Throws an exception if the order with the given id couldn't be found.
2334
 
2335
    Parameters:
2336
     - orderId
2337
    """
2338
    order = get_order(order_id)
4484 rajveer 2339
    if order.status == OrderStatus.RTO_RECEIVED_PRESTINE:
4220 rajveer 2340
        new_order = __clone_order(order, True, order.cod)
4484 rajveer 2341
        order.status = OrderStatus.RTO_RESHIPPED
2628 chandransh 2342
        order.statusDescription = "Order Reshipped"
2343
        session.commit()
3578 mandeep.dh 2344
        update_trust_level(order)
6735 amar.kumar 2345
        __scan_for_reship_order(order_id, new_order)
4486 rajveer 2346
    elif order.status == OrderStatus.RTO_RECEIVED_DAMAGED:
2347
        new_order = __clone_order(order, False, order.cod)
2348
        ret_order = __create_return_order(order)
2349
        order.status = OrderStatus.RTO_DAMAGED_RESHIPPED
2350
        order.statusDescription = "Order Reshipped Received Damaged"
2351
        session.commit()
2352
    elif order.status == OrderStatus.RTO_LOST_IN_TRANSIT:
2353
        new_order = __clone_order(order, False, order.cod)
2354
        order.status = OrderStatus.RTO_LOST_IN_TRANSIT_RESHIPPED
2355
        order.statusDescription = "Order Reshipped Lost In Transit"
2356
        session.commit()
4662 rajveer 2357
    elif order.status == OrderStatus.LOST_IN_TRANSIT:
2358
        new_order = __clone_order(order, False, order.cod)
2359
        order.status = OrderStatus.LOST_IN_TRANSIT_RESHIPPED
2360
        order.statusDescription = "Order Reshipped Lost In Transit"
2361
        session.commit()
2628 chandransh 2362
    elif order.status == OrderStatus.DOA_CERT_INVALID:
4220 rajveer 2363
        new_order = __clone_order(order, True, False)
2628 chandransh 2364
        order.status = OrderStatus.DOA_INVALID_RESHIPPED
2365
        order.statusDescription = "Order Reshipped"
2366
        session.commit()
6735 amar.kumar 2367
        __scan_for_reship_order(order_id, new_order)
2628 chandransh 2368
    elif order.status == OrderStatus.DOA_CERT_VALID:
4220 rajveer 2369
        new_order = __clone_order(order, False, False)
2628 chandransh 2370
        ret_order = __create_return_order(order)
4452 rajveer 2371
        order.status = OrderStatus.DOA_VALID_RESHIPPED
2628 chandransh 2372
        order.statusDescription = "Order Reshipped"
2373
        session.commit()
4479 rajveer 2374
    elif order.status == OrderStatus.DOA_RECEIVED_DAMAGED:
2375
        new_order = __clone_order(order, False, False)
2376
        ret_order = __create_return_order(order)
2377
        order.status = OrderStatus.DOA_RESHIPPED_RCVD_DAMAGED
2378
        order.statusDescription = "Order Reshipped Received Damaged"
2379
        session.commit()
2380
    elif order.status == OrderStatus.DOA_LOST_IN_TRANSIT:
2381
        new_order = __clone_order(order, False, False)
2382
        order.status = OrderStatus.DOA_RESHIPPED_LOST_IN_TRANSIT
2383
        order.statusDescription = "Order Reshipped Lost In Transit"
2384
        session.commit()
4614 rajveer 2385
    elif order.status == OrderStatus.RET_PRODUCT_USABLE:
5620 mandeep.dh 2386
        new_order = __clone_order(order, False, False)
4614 rajveer 2387
        order.status = OrderStatus.RET_PRODUCT_USABLE_RESHIPPED
4495 rajveer 2388
        order.statusDescription = "Order Reshipped"
2389
        session.commit()
4614 rajveer 2390
    elif order.status == OrderStatus.RET_PRODUCT_UNUSABLE:
4495 rajveer 2391
        new_order = __clone_order(order, False, False)
2392
        ret_order = __create_return_order(order)
4614 rajveer 2393
        order.status = OrderStatus.RET_PRODUCT_UNUSABLE_RESHIPPED
4495 rajveer 2394
        order.statusDescription = "Order Reshipped"
2395
        session.commit()
2396
    elif order.status == OrderStatus.RET_RECEIVED_DAMAGED:
2397
        new_order = __clone_order(order, False, False)
2398
        ret_order = __create_return_order(order)
2399
        order.status = OrderStatus.RET_RESHIPPED_RCVD_DAMAGED
2400
        order.statusDescription = "Order Reshipped Received Damaged"
2401
        session.commit()
2402
    elif order.status == OrderStatus.RET_LOST_IN_TRANSIT:
2403
        new_order = __clone_order(order, False, False)
2404
        order.status = OrderStatus.RET_RESHIPPED_LOST_IN_TRANSIT
2405
        order.statusDescription = "Order Reshipped Lost In Transit"
2406
        session.commit()
2628 chandransh 2407
    else:
2408
        raise TransactionServiceException(112, "This order can't be reshipped")
2409
 
2764 chandransh 2410
    order.reship_timestamp = datetime.datetime.now()
2628 chandransh 2411
    order.new_order_id = new_order.id
2412
    session.commit()
2413
 
2414
    return new_order.id
2415
 
6735 amar.kumar 2416
def __scan_for_reship_order(order_id, new_order):
2417
    inventoryClient = InventoryClient().get_client()
2418
    warehouse = inventoryClient.getWarehouse(new_order.warehouse_id)
2419
    if warehouse.billingType == BillingType.OURS:
2420
        warehouseClient = WarehouseClient().get_client()
2421
        inventoryItem = warehouseClient.getInventoryItemFromOrder(order_id)
2422
        warehouseClient.scanForOrder(inventoryItem, ScanType.SALE, new_order.lineitems[0].quantity, new_order.id, new_order.fulfilmentWarehouseId, new_order.warehouse_id)
7199 amar.kumar 2423
    if order.freebieItemId:
2424
        warehouseClient = WarehouseClient().get_client()
2425
        inventoryItem = warehouseClient.reshipfreebie(order_id, new_order.id, new_order.freebieItemId, ScanType.SALE)
6735 amar.kumar 2426
 
3226 chandransh 2427
def refund_order(order_id, refunded_by, reason):
2628 chandransh 2428
    """
4484 rajveer 2429
    If the order is in RTO_RECEIVED_PRESTINE, DOA_CERT_VALID or DOA_CERT_INVALID state, it does the following:
2628 chandransh 2430
        1. Creates a refund request for batch processing.
2431
        2. Creates a return order for the warehouse executive to return the shipped material.
4484 rajveer 2432
        3. Marks the current order as RTO_REFUNDED, DOA_VALID_REFUNDED or DOA_INVALID_REFUNDED final states.
2628 chandransh 2433
 
2434
    If the order is in SUBMITTED_FOR_PROCESSING or INVENTORY_LOW state, it does the following:
2435
        1. Creates a refund request for batch processing.
3226 chandransh 2436
        2. Cancels the reservation of the item in the warehouse.
2437
        3. Marks the current order as the REFUNDED final state.
2628 chandransh 2438
 
3226 chandransh 2439
    For all COD orders, if the order is in INIT, SUBMITTED_FOR_PROCESSING or INVENTORY_LOW state, it does the following:
2440
        1. Cancels the reservation of the item in the warehouse.
2441
        2. Marks the current order as CANCELED.
2442
 
2443
    In all cases, it updates the reason for cancellation or refund and the person who performed the action.
2444
 
2445
    Returns True if it is successful, False otherwise.
2628 chandransh 2446
 
2447
    Throws an exception if the order with the given id couldn't be found.
2448
 
2449
    Parameters:
3226 chandransh 2450
     - order_id
2451
     - refunded_by
2452
     - reason
2628 chandransh 2453
    """
3414 chandransh 2454
    logging.info("Refunding order id: " + str(order_id))
2628 chandransh 2455
    order = get_order(order_id)
3186 chandransh 2456
 
3226 chandransh 2457
    if order.cod:
3414 chandransh 2458
        logging.info("Refunding COD order with status " + str(order.status))
4662 rajveer 2459
        status_transition = { OrderStatus.LOST_IN_TRANSIT : OrderStatus.LOST_IN_TRANSIT_REFUNDED,
2460
                     OrderStatus.RTO_RECEIVED_PRESTINE : OrderStatus.RTO_REFUNDED,
4486 rajveer 2461
                     OrderStatus.RTO_RECEIVED_DAMAGED : OrderStatus.RTO_DAMAGED_REFUNDED,
2462
                     OrderStatus.RTO_LOST_IN_TRANSIT : OrderStatus.RTO_LOST_IN_TRANSIT_REFUNDED,
3366 chandransh 2463
                     OrderStatus.DOA_CERT_INVALID : OrderStatus.DOA_INVALID_REFUNDED,
2464
                     OrderStatus.DOA_CERT_VALID : OrderStatus.DOA_VALID_REFUNDED,
4479 rajveer 2465
                     OrderStatus.DOA_RECEIVED_DAMAGED : OrderStatus.DOA_REFUNDED_RCVD_DAMAGED,
2466
                     OrderStatus.DOA_LOST_IN_TRANSIT : OrderStatus.DOA_REFUNDED_LOST_IN_TRANSIT,
4495 rajveer 2467
                     OrderStatus.RET_PRODUCT_UNUSABLE : OrderStatus.RET_PRODUCT_UNUSABLE_REFUNDED,
2468
                     OrderStatus.RET_PRODUCT_USABLE : OrderStatus.RET_PRODUCT_USABLE_REFUNDED,
2469
                     OrderStatus.RET_RECEIVED_DAMAGED : OrderStatus.RET_REFUNDED_RCVD_DAMAGED,
2470
                     OrderStatus.RET_LOST_IN_TRANSIT : OrderStatus.RET_REFUNDED_LOST_IN_TRANSIT,
4682 rajveer 2471
                     OrderStatus.COD_VERIFICATION_PENDING : OrderStatus.COD_VERIFICATION_FAILED,
2472
                     OrderStatus.SUBMITTED_FOR_PROCESSING : OrderStatus.CANCELLED_DUE_TO_LOW_INVENTORY,
2473
                     OrderStatus.INVENTORY_LOW : OrderStatus.CANCELLED_DUE_TO_LOW_INVENTORY,
2474
                     OrderStatus.LOW_INV_PO_RAISED : OrderStatus.CANCELLED_DUE_TO_LOW_INVENTORY,
2475
                     OrderStatus.LOW_INV_REVERSAL_IN_PROCESS : OrderStatus.CANCELLED_DUE_TO_LOW_INVENTORY,
2476
                     OrderStatus.LOW_INV_NOT_AVAILABLE_AT_HOTSPOT : OrderStatus.CANCELLED_DUE_TO_LOW_INVENTORY,
2477
                     OrderStatus.ACCEPTED : OrderStatus.CANCELLED_DUE_TO_LOW_INVENTORY,
2478
                     OrderStatus.BILLED : OrderStatus.CANCELLED_DUE_TO_LOW_INVENTORY,
4247 rajveer 2479
                     OrderStatus.CANCEL_REQUEST_CONFIRMED : OrderStatus.CANCELLED_ON_CUSTOMER_REQUEST
3366 chandransh 2480
                     }
2481
        if order.status not in status_transition.keys():
2482
            raise TransactionServiceException(114, "This order can't be refunded")
7386 anupam.sin 2483
 
5199 mandeep.dh 2484
        if order.status in [OrderStatus.COD_VERIFICATION_PENDING, OrderStatus.SUBMITTED_FOR_PROCESSING, OrderStatus.INVENTORY_LOW, OrderStatus.LOW_INV_PO_RAISED, OrderStatus.LOW_INV_REVERSAL_IN_PROCESS, OrderStatus.LOW_INV_NOT_AVAILABLE_AT_HOTSPOT, OrderStatus.ACCEPTED]:
3226 chandransh 2485
            __update_inventory_reservation(order)
2486
            order.statusDescription = "Order Cancelled"
3415 chandransh 2487
        elif order.status == OrderStatus.BILLED:
3413 chandransh 2488
            __create_return_order(order)
2489
            order.statusDescription = "Order Cancelled"
4486 rajveer 2490
        elif order.status in [OrderStatus.RTO_RECEIVED_PRESTINE, OrderStatus.RTO_RECEIVED_DAMAGED, OrderStatus.RTO_LOST_IN_TRANSIT]:
5386 phani.kuma 2491
            if order.status != OrderStatus.RTO_LOST_IN_TRANSIT:
2492
                __create_return_order(order)
4486 rajveer 2493
            order.statusDescription = "RTO Refunded"
4662 rajveer 2494
        elif order.status in [OrderStatus.LOST_IN_TRANSIT]:
5386 phani.kuma 2495
            #__create_return_order(order)
4662 rajveer 2496
            order.statusDescription = "Lost in Transit Refunded"
4479 rajveer 2497
        elif order.status in [OrderStatus.DOA_CERT_INVALID, OrderStatus.DOA_CERT_VALID, OrderStatus.DOA_RECEIVED_DAMAGED, OrderStatus.DOA_LOST_IN_TRANSIT] :
5386 phani.kuma 2498
            if order.status != OrderStatus.DOA_LOST_IN_TRANSIT:
2499
                __create_return_order(order)
3226 chandransh 2500
            __create_refund(order)
4495 rajveer 2501
            order.statusDescription = "DOA Refunded"
2502
        elif order.status in [OrderStatus.RET_PRODUCT_UNUSABLE, OrderStatus.RET_PRODUCT_USABLE, OrderStatus.RET_RECEIVED_DAMAGED, OrderStatus.RET_LOST_IN_TRANSIT] :
5386 phani.kuma 2503
            if order.status != OrderStatus.RET_LOST_IN_TRANSIT:
2504
                __create_return_order(order)
4495 rajveer 2505
            __create_refund(order)
2506
            order.statusDescription = "Return Refunded"
4247 rajveer 2507
        elif order.status == OrderStatus.CANCEL_REQUEST_CONFIRMED:
5199 mandeep.dh 2508
            if order.previousStatus in [OrderStatus.COD_VERIFICATION_PENDING, OrderStatus.SUBMITTED_FOR_PROCESSING, OrderStatus.INVENTORY_LOW, OrderStatus.LOW_INV_PO_RAISED, OrderStatus.LOW_INV_REVERSAL_IN_PROCESS, OrderStatus.LOW_INV_NOT_AVAILABLE_AT_HOTSPOT, OrderStatus.ACCEPTED]:
4247 rajveer 2509
                __update_inventory_reservation(order)
2510
                order.statusDescription = "Order Cancelled on customer request"
2511
            elif order.previousStatus == OrderStatus.BILLED:
2512
                __create_return_order(order)
2513
                order.statusDescription = "Order Cancelled on customer request"
6668 amar.kumar 2514
                order.received_return_timestamp = datetime.datetime.now()
3226 chandransh 2515
    else:
4662 rajveer 2516
        status_transition = {OrderStatus.LOST_IN_TRANSIT : OrderStatus.LOST_IN_TRANSIT_REFUNDED,
2517
                     OrderStatus.RTO_RECEIVED_PRESTINE : OrderStatus.RTO_REFUNDED,
4486 rajveer 2518
                     OrderStatus.RTO_RECEIVED_DAMAGED : OrderStatus.RTO_DAMAGED_REFUNDED,
2519
                     OrderStatus.RTO_LOST_IN_TRANSIT : OrderStatus.RTO_LOST_IN_TRANSIT_REFUNDED,
3366 chandransh 2520
                     OrderStatus.DOA_CERT_INVALID : OrderStatus.DOA_INVALID_REFUNDED,
2521
                     OrderStatus.DOA_CERT_VALID : OrderStatus.DOA_VALID_REFUNDED,
4479 rajveer 2522
                     OrderStatus.DOA_RECEIVED_DAMAGED : OrderStatus.DOA_REFUNDED_RCVD_DAMAGED,
2523
                     OrderStatus.DOA_LOST_IN_TRANSIT : OrderStatus.DOA_REFUNDED_LOST_IN_TRANSIT,
4495 rajveer 2524
                     OrderStatus.RET_PRODUCT_UNUSABLE : OrderStatus.RET_PRODUCT_UNUSABLE_REFUNDED,
2525
                     OrderStatus.RET_PRODUCT_USABLE : OrderStatus.RET_PRODUCT_USABLE_REFUNDED,
2526
                     OrderStatus.RET_RECEIVED_DAMAGED : OrderStatus.RET_REFUNDED_RCVD_DAMAGED,
2527
                     OrderStatus.RET_LOST_IN_TRANSIT : OrderStatus.RET_REFUNDED_LOST_IN_TRANSIT,
4682 rajveer 2528
                     OrderStatus.SUBMITTED_FOR_PROCESSING : OrderStatus.CANCELLED_DUE_TO_LOW_INVENTORY,
2529
                     OrderStatus.INVENTORY_LOW : OrderStatus.CANCELLED_DUE_TO_LOW_INVENTORY,
2530
                     OrderStatus.LOW_INV_PO_RAISED : OrderStatus.CANCELLED_DUE_TO_LOW_INVENTORY,
2531
                     OrderStatus.LOW_INV_REVERSAL_IN_PROCESS : OrderStatus.CANCELLED_DUE_TO_LOW_INVENTORY,
2532
                     OrderStatus.LOW_INV_NOT_AVAILABLE_AT_HOTSPOT : OrderStatus.CANCELLED_DUE_TO_LOW_INVENTORY,
2533
                     OrderStatus.ACCEPTED : OrderStatus.CANCELLED_DUE_TO_LOW_INVENTORY,
2534
                     OrderStatus.BILLED : OrderStatus.CANCELLED_DUE_TO_LOW_INVENTORY,
4247 rajveer 2535
                     OrderStatus.CANCEL_REQUEST_CONFIRMED : OrderStatus.CANCELLED_ON_CUSTOMER_REQUEST,
2536
                     OrderStatus.PAYMENT_FLAGGED : OrderStatus.PAYMENT_FLAGGED_DENIED
3366 chandransh 2537
                     }
2538
        if order.status not in status_transition.keys():
2539
            raise TransactionServiceException(114, "This order can't be refunded")
2540
 
4495 rajveer 2541
        if order.status in [OrderStatus.RTO_RECEIVED_PRESTINE, OrderStatus.RTO_RECEIVED_DAMAGED, OrderStatus.RTO_LOST_IN_TRANSIT] :
5386 phani.kuma 2542
            if order.status != OrderStatus.RTO_LOST_IN_TRANSIT:
2543
                __create_return_order(order)
3226 chandransh 2544
            __create_refund(order)
4495 rajveer 2545
            order.statusDescription = "RTO Refunded"
4662 rajveer 2546
        elif order.status in [OrderStatus.LOST_IN_TRANSIT]:
5386 phani.kuma 2547
            #__create_return_order(order)
4662 rajveer 2548
            __create_refund(order)
2549
            order.statusDescription = "Lost in Transit Refunded"
4495 rajveer 2550
        elif order.status in [OrderStatus.DOA_CERT_INVALID, OrderStatus.DOA_CERT_VALID, OrderStatus.DOA_RECEIVED_DAMAGED, OrderStatus.DOA_LOST_IN_TRANSIT] :
5386 phani.kuma 2551
            if order.status != OrderStatus.DOA_LOST_IN_TRANSIT:
2552
                __create_return_order(order)
4495 rajveer 2553
            __create_refund(order)
2554
            order.statusDescription = "DOA Refunded"
2555
        elif order.status in [OrderStatus.RET_PRODUCT_UNUSABLE, OrderStatus.RET_PRODUCT_USABLE, OrderStatus.RET_RECEIVED_DAMAGED, OrderStatus.RET_LOST_IN_TRANSIT] :
5386 phani.kuma 2556
            if order.status != OrderStatus.RET_LOST_IN_TRANSIT:
2557
                __create_return_order(order)
4495 rajveer 2558
            __create_refund(order)
2559
            order.statusDescription = "Return Refunded"
5199 mandeep.dh 2560
        elif order.status in [OrderStatus.SUBMITTED_FOR_PROCESSING, OrderStatus.INVENTORY_LOW, OrderStatus.LOW_INV_PO_RAISED, OrderStatus.LOW_INV_REVERSAL_IN_PROCESS, OrderStatus.LOW_INV_NOT_AVAILABLE_AT_HOTSPOT, OrderStatus.ACCEPTED]:
3226 chandransh 2561
            __update_inventory_reservation(order)
2562
            order.statusDescription = "Order Refunded"
4247 rajveer 2563
        elif order.status == OrderStatus.CANCEL_REQUEST_CONFIRMED:
5272 mandeep.dh 2564
            if order.previousStatus in [OrderStatus.SUBMITTED_FOR_PROCESSING, OrderStatus.INVENTORY_LOW, OrderStatus.LOW_INV_PO_RAISED, OrderStatus.LOW_INV_REVERSAL_IN_PROCESS, OrderStatus.LOW_INV_NOT_AVAILABLE_AT_HOTSPOT, OrderStatus.PAYMENT_FLAGGED, OrderStatus.ACCEPTED]:
4672 rajveer 2565
                if order.previousStatus == OrderStatus.ACCEPTED:
2566
                    __create_refund(order)
4247 rajveer 2567
                __update_inventory_reservation(order)
2568
                order.statusDescription = "Order Cancelled on customer request"
2569
            elif order.previousStatus == OrderStatus.BILLED:
2570
                __create_return_order(order)
2571
                __create_refund(order)
2572
                order.statusDescription = "Order Cancelled on customer request"
6668 amar.kumar 2573
                order.received_return_timestamp = datetime.datetime.now()
4247 rajveer 2574
        elif order.status == OrderStatus.PAYMENT_FLAGGED:
2575
            __update_inventory_reservation(order)
2576
            order.statusDescription = "Order Cancelled due to payment flagged"
3195 chandransh 2577
 
4873 mandeep.dh 2578
    # For orders that are cancelled after being billed, we need to scan in the scanned out
2579
    # inventory item and change availability accordingly
5944 mandeep.dh 2580
    inventoryClient = InventoryClient().get_client()
2581
    warehouse = inventoryClient.getWarehouse(order.warehouse_id)
6786 amar.kumar 2582
    if warehouse.billingType == BillingType.OURS or warehouse.billingType == BillingType.OURS_EXTERNAL:
4873 mandeep.dh 2583
        if order.status in [OrderStatus.BILLED, OrderStatus.SHIPPED_TO_LOGST, OrderStatus.SHIPPED_FROM_WH] or (order.status == OrderStatus.CANCEL_REQUEST_CONFIRMED and order.previousStatus in [OrderStatus.BILLED, OrderStatus.SHIPPED_TO_LOGST, OrderStatus.SHIPPED_FROM_WH]):
2584
            lineitem = order.lineitems[0]
5944 mandeep.dh 2585
            catalogClient = CatalogClient().get_client()
5177 mandeep.dh 2586
            item = catalogClient.getItem(lineitem.item_id)
5361 mandeep.dh 2587
            warehouseClient = WarehouseClient().get_client()
6786 amar.kumar 2588
            if warehouse.billingType == BillingType.OURS:
2589
                if ItemType.SERIALIZED == item.type:
2590
                    warehouseClient.scanSerializedItemForOrder(lineitem.serial_number, ScanType.SALE_RET, order.id, order.fulfilmentWarehouseId, lineitem.quantity, order.warehouse_id)
2591
                else:
2592
                    warehouseClient.scanForOrder(None, ScanType.SALE_RET, lineitem.quantity, order.id, order.fulfilmentWarehouseId, order.warehouse_id)
2593
            if warehouse.billingType == BillingType.OURS_EXTERNAL:
2594
                warehouseClient.scanForOursExternalSaleReturn(order.id, lineitem.transfer_price)            
4873 mandeep.dh 2595
 
7386 anupam.sin 2596
    if order.source == 2 and order.status in (OrderStatus.SUBMITTED_FOR_PROCESSING, OrderStatus.ACCEPTED, OrderStatus.INVENTORY_LOW):
7393 anupam.sin 2597
        storeOrderDetail = StoreOrderDetail.query.filter(StoreOrderDetail.orderId == order.id).filter(StoreOrderDetail.storeId == order.storeId).first()
2598
        if order.created_timestamp.date() == datetime.datetime.now().date():
2599
            __push_store_collection_to_hotspot(order, "advanceRefund", -(storeOrderDetail.cashRefundAmount + storeOrderDetail.cardRefundAmount))
2600
            storeOrderDetail.payStatus = StorePaymentStatus.ADV_REFUNDED
2601
        else:
2602
            __push_store_collection_to_hotspot(order, "advanceRefund", -(storeOrderDetail.cashRefundAmount))
2603
            if storeOrderDetail.cardRefundAmount > 0:
2604
                storeOrderDetail.payStatus = StorePaymentStatus.REFUND_PENDING
2605
            else:
2606
                storeOrderDetail.payStatus = StorePaymentStatus.ADV_REFUNDED
3195 chandransh 2607
    order.status = status_transition[order.status]
2608
    order.refund_timestamp = datetime.datetime.now()
3226 chandransh 2609
    order.refunded_by = refunded_by
2610
    order.refund_reason = reason
2628 chandransh 2611
    session.commit()
2612
    return True
2613
 
3186 chandransh 2614
def __update_inventory_reservation(order):
3191 chandransh 2615
    '''
2616
    Reduce the reservation count for all line items of the given order.
2617
    '''
3186 chandransh 2618
    try:
5944 mandeep.dh 2619
        inventoryClient = InventoryClient().get_client()
3186 chandransh 2620
        for lineitem in order.lineitems:
5966 rajveer 2621
            inventoryClient.reduceReservationCount(lineitem.item_id, order.fulfilmentWarehouseId, sourceId, order.id, lineitem.quantity)
3186 chandransh 2622
    except:
2623
        print "Unable to reduce reservation count"
2624
 
4220 rajveer 2625
def __clone_order(order, should_copy_billing_info, is_cod):
2628 chandransh 2626
    current_time = datetime.datetime.now()
2627
    new_order = Order()
2628
    new_order.customer_id = order.customer_id
2629
    new_order.customer_name = order.customer_name
2630
    new_order.customer_city = order.customer_city
2631
    new_order.customer_state = order.customer_state
2632
    new_order.customer_mobilenumber = order.customer_mobilenumber
2633
    new_order.customer_pincode = order.customer_pincode
2634
    new_order.customer_address1 = order.customer_address1
2635
    new_order.customer_address2 = order.customer_address2
2636
    new_order.customer_email = order.customer_email
2637
    new_order.total_amount = order.total_amount
6318 rajveer 2638
    new_order.gvAmount = order.gvAmount
2628 chandransh 2639
    new_order.total_weight = order.total_weight
2640
    new_order.status = OrderStatus.SUBMITTED_FOR_PROCESSING
2641
    new_order.statusDescription = 'Submitted for Processing'
2642
    new_order.created_timestamp = current_time
5062 varun.gupt 2643
    new_order.originalOrderId = order.originalOrderId if order.originalOrderId is not None else order.id 
2628 chandransh 2644
 
2645
    new_order.transaction = order.transaction
4220 rajveer 2646
    new_order.cod = is_cod
5527 anupam.sin 2647
    new_order.orderType = order.orderType
7199 amar.kumar 2648
    new_order.freebieItemId = order.freebieItemId
2628 chandransh 2649
    for line_item in order.lineitems:
2650
        litem = LineItem()
2651
        litem.item_id = line_item.item_id
2652
        litem.productGroup = line_item.productGroup
2653
        litem.brand = line_item.brand
2654
        if line_item.model_number:
2655
            litem.model_number = line_item.model_number
2656
        if line_item.model_name:    
2657
            litem.model_name = line_item.model_name
2658
        if line_item.color:
2659
            litem.color = line_item.color
2660
        if line_item.extra_info:
2661
            litem.extra_info = line_item.extra_info
2662
        litem.quantity = line_item.quantity
2663
        litem.unit_price = line_item.unit_price
2664
        litem.unit_weight = line_item.unit_weight
2665
        litem.total_price = line_item.total_price
2666
        litem.total_weight = line_item.total_weight
2667
        litem.transfer_price = line_item.transfer_price
6751 amar.kumar 2668
        litem.nlc = line_item.nlc
4840 mandeep.dh 2669
        litem.dealText = line_item.dealText
6423 amit.gupta 2670
        litem.vatRate = line_item.vatRate
2628 chandransh 2671
        litem.order = new_order
6912 anupam.sin 2672
 
2673
    if order.insurer > 0:
2674
        new_order.insurer = order.insurer
2675
        new_order.insuranceAmount = order.insuranceAmount
2676
        newDetail = InsuranceDetailForOrder()
2677
        oldDetail = InsuranceDetailForOrder.get_by(order_id = order.id)
2678
        newDetail.dob = oldDetail.dob
2679
        newDetail.guardianName = oldDetail.guardianName
2680
        newDetail.order = new_order
2681
 
2628 chandransh 2682
    logistics_client = LogisticsClient().get_client()
2683
    item_id = new_order.lineitems[0].item_id
5785 mandeep.dh 2684
    logistics_info = logistics_client.getLogisticsInfo(new_order.customer_pincode, item_id, is_cod, PickUpType.COURIER) #TODO: We should be able to pass another flag to suggest ignoring the inventory situation.
6726 rajveer 2685
    logistics_info.shippingTime = adjust_delivery_time(current_time, logistics_info.shippingTime)
2628 chandransh 2686
    logistics_info.deliveryTime = adjust_delivery_time(current_time, logistics_info.deliveryTime)
6726 rajveer 2687
    logistics_info.deliveryDelay = adjust_delivery_time(current_time, (logistics_info.shippingTime + logistics_info.deliveryDelay))
2628 chandransh 2688
    new_order.warehouse_id = logistics_info.warehouseId
5110 mandeep.dh 2689
    new_order.fulfilmentWarehouseId = logistics_info.fulfilmentWarehouseId
2628 chandransh 2690
    new_order.logistics_provider_id = logistics_info.providerId
2691
    new_order.airwaybill_no = logistics_info.airway_billno
2692
    new_order.tracking_id = new_order.airwaybill_no
6726 rajveer 2693
 
2694
    order.courier_delivery_time = (current_time + datetime.timedelta(days=logistics_info.deliveryDelay)).replace(hour=PREPAID_SHIPPING_CUTOFF_TIME, minute=0, second=0)
2695
    new_order.expected_delivery_time = (current_time + datetime.timedelta(days=logistics_info.deliveryTime)).replace(hour=PREPAID_SHIPPING_CUTOFF_TIME, minute=0, second=0)
3986 chandransh 2696
    new_order.promised_delivery_time = new_order.expected_delivery_time
6629 anupam.sin 2697
    new_order.expected_shipping_time = (current_time + datetime.timedelta(days=logistics_info.shippingTime)).replace(hour=PREPAID_SHIPPING_CUTOFF_TIME, minute=0, second=0)
2698
    new_order.promised_shipping_time = new_order.expected_shipping_time
2699
 
2628 chandransh 2700
    if should_copy_billing_info:
5388 phani.kuma 2701
        new_order.vendorId = order.vendorId
2628 chandransh 2702
        new_order.invoice_number = order.invoice_number
2703
        new_order.billed_by = order.billed_by
2704
        new_order.warehouse_id = order.warehouse_id
5110 mandeep.dh 2705
        new_order.fulfilmentWarehouseId = order.fulfilmentWarehouseId
5620 mandeep.dh 2706
        new_order.jacket_number = order.jacket_number
2707
        new_order.lineitems[0].serial_number = order.lineitems[0].serial_number
2708
        new_order.lineitems[0].item_number   = order.lineitems[0].item_number
2628 chandransh 2709
        new_order.accepted_timestamp = current_time
2710
        new_order.billing_timestamp = current_time    
2711
        new_order.status = OrderStatus.BILLED
2712
        new_order.statusDescription = 'Order Billed'
5966 rajveer 2713
    else:
2714
        session.commit()       
5944 mandeep.dh 2715
        inventoryClient = InventoryClient().get_client()
5966 rajveer 2716
        inventoryClient.reserveItemInWarehouse(item_id, logistics_info.fulfilmentWarehouseId, sourceId, new_order.id, to_java_date(new_order.created_timestamp), to_java_date(new_order.promised_shipping_time), new_order.lineitems[0].quantity)
2628 chandransh 2717
 
2718
    return new_order
2719
 
2720
def __create_return_order(order):
2687 chandransh 2721
    ret_order = ReturnOrder(order)
2628 chandransh 2722
    return ret_order
2723
 
2724
def __create_refund(order):
4078 chandransh 2725
    payment_client = PaymentClient().get_client()
2726
    payment_client.createRefund(order.id, order.transaction.id, order.total_amount)
2747 chandransh 2727
    return
2628 chandransh 2728
 
2536 chandransh 2729
def __get_order_address(order):
2730
    address = order.customer_name + "\n" + order.customer_address1 + "\n"
2731
    if order.customer_address2:
2732
        address = address + order.customer_address2 + "\n"
2733
    address = address + order.customer_city + "\n"
2734
    address = address + order.customer_state + "\n"
2735
    address = address + "PIN " + order.customer_pincode + "\n"
2736
    address = address + "Phone: " + order.customer_mobilenumber
2737
    return address
2738
 
5767 rajveer 2739
def __get_store_address(store):
2740
    address = store.name + "\n" + store.line1 + "\n"
2741
    if store.line2:
2742
        address = address + store.line2 + "\n"
2743
    address = address + store.city + "\n"
2744
    address = address + store.state + "\n"
5802 rajveer 2745
    address = address + "PIN - " + store.pin + "\n"
5793 rajveer 2746
    if store.phone:
5802 rajveer 2747
        address = address + "Phone - " + store.phone + "\n"
5855 rajveer 2748
    address = address +  "Store timings - 11AM to 8PM (7 days)\n"
5767 rajveer 2749
    return address
2750
 
5793 rajveer 2751
def __get_store_address_html(store):
2752
    address = store.name + "<br>" + store.line1 + "<br>"
2753
    if store.line2:
2754
        address = address + store.line2 + "<br>"
2755
    address = address + store.city + "<br>"
2756
    address = address + store.state + "<br>"
5802 rajveer 2757
    address = address + "PIN - " + store.pin + "<br>"
5793 rajveer 2758
    if store.phone:
5802 rajveer 2759
        address = address + "Phone - " + store.phone + "<br>"
5855 rajveer 2760
    address = address +  "Store timings - 7 days: 11AM to 8PM  (7 days)<br>"
5793 rajveer 2761
    return address
2762
 
4815 phani.kuma 2763
def __generate_return_advice(order, warehouse, provider, filename):
2764
    if warehouse.id == 7:
7181 rajveer 2765
        executive = 'Shiv Kumar'
4815 phani.kuma 2766
    else:
4966 phani.kuma 2767
        executive = 'Dinesh Kumar'
2536 chandransh 2768
    pdf = Canvas(filename)
2769
    pdf.setFont('Times-Bold',16)
2770
    address_text = pdf.beginText(inch, PAGE_HEIGHT - inch)
2771
    address_text.textLine("To")
4815 phani.kuma 2772
    address_text.textLine(executive)
2536 chandransh 2773
    for line in warehouse.location.split("\n"):
2774
        address_text.textLine(line)
2775
    address_text.textLine("PIN " + warehouse.pincode)
2776
    pdf.drawText(address_text)
2777
 
2778
    pdf.setFont('Times-Roman',12)
2779
    order_text = pdf.beginText(inch, PAGE_HEIGHT - 4 * inch)
3051 chandransh 2780
    order_text.textLine("Pickup CODE: " + provider.details[DeliveryType.PREPAID].accountNo)
2536 chandransh 2781
    lineitem = order.lineitems[0] 
4234 rajveer 2782
    order_text.textLine("Content : " + lineitem.brand + " " + str(lineitem.model_number) + " " + str(lineitem.color))
2536 chandransh 2783
    order_text.textLine("Declared Value: Rs. " + str(order.total_amount))
2784
    order_text.textLine("Order ID : " + str(order.id))
2785
    pdf.drawText(order_text)
2786
    pdf.showPage()
2787
    pdf.save()
2788
    return filename
2789
 
7386 anupam.sin 2790
def __push_store_collection_to_hotspot(order, ctype, amount):
7385 rajveer 2791
    try:
2792
        ts = order.created_timestamp
2793
        store =  get_hotspot_store(order.storeId, "")
2794
        storeName = store.hotspotId
2795
        store_string = "<Store>" + storeName + "</Store>"
2796
        order_string = "<OrderID>" + str(order.id) + "</OrderID>"
2797
        product_string = "<Product>" + str(order.lineitems[0]) + "</Product>"
7386 anupam.sin 2798
        collection_type = "<CollectionType>" + ctype + "</CollectionType>"
2799
        amount_string = "<AdvanceAmount>" + amount + "</AdvanceAmount>"
7385 rajveer 2800
        date_string = "<TimeStamp>" + ts.strftime("%Y%m%d%H%M%S") + "</TimeStamp>"
2801
        cash_string = "<CashAmount>" + order.advanceAmount + "</CashAmount>"
2802
        card_string = "<CardAmount>" + "0" + "</CardAmount>"
2803
 
2804
        #advance, saleClosure, advanceRefund, saleRefund
2805
 
2806
        conn = httplib.HTTPConnection("182.71.104.186")
2807
        XML="""
2808
        <soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
2809
          <soap:Body>
2810
            <SaholicAdvanceTransfer xmlns="http://tempuri.org/">
2811
        """
2812
 
2813
        XML = XML + store_string + order_string + product_string + collection_type + amount_string + cash_string + card_string + date_string 
2814
 
2815
        footer = """
2816
            </SaholicAdvanceTransfer>
2817
          </soap:Body>
2818
        </soap:Envelope>
2819
        """
2820
        XML = XML + footer
2821
 
2822
        params = urllib.urlencode({'op': 'SaholicAdvanceTransfer'})
2823
        headers = { "Content-type": "text/xml", "Content-Length": "%d" % len(XML)}
2824
        conn.request("POST", "/loaddetect/Service.asmx?"+params, "", headers)
2825
        conn.send(XML)
2826
        response = conn.getresponse()
2827
        print response.status, response.reason
2828
        resp = response.read()
2829
        conn.close()
2830
        print resp
2831
        if "Saved Successfully" in resp:
2832
            return True
2833
        elif "Error in Saving Data" in resp:
2834
            return False
2835
        else: 
2836
            return False
2837
    except Exception as e:
2838
        print e
2839
        return False
2840
 
7344 rajveer 2841
def __push_collection_to_hotspot(order, type, storeOrder = False):
5806 rajveer 2842
    try:
7344 rajveer 2843
        storeName = '109'
2844
        if storeOrder:
2845
            store =  get_hotspot_store(order.storeId, "")
2846
            storeName = store.hotspotId
2847
            storeName = '109'
2848
        else:
2849
            logistics_client = LogisticsClient().get_client()
2850
            store = logistics_client.getPickupStore(order.pickupStoreId)
2851
            storeName = store.hotspotId
2852
        store_string = "<store>" + storeName + "</store>"
5806 rajveer 2853
        order_string = "<orderno>" + str(order.id) + "</orderno>"
2854
        collection_type = "<Type>" + type + "</Type>"
5833 rajveer 2855
        payment_mode = get_order_attribute_value(order.id, "PAYMENT_MODE")
5806 rajveer 2856
        if type == "SALE":
7344 rajveer 2857
            if storeOrder:
7350 rajveer 2858
                amount = int(order.advanceAmount)
2859
                ts = order.created_timestamp
7344 rajveer 2860
            else:
2861
                amount = int(order.total_amount-order.gvAmount)
7350 rajveer 2862
                ts = order.delivery_timestamp
5806 rajveer 2863
        if type == "SALE RETURN":
7344 rajveer 2864
            if storeOrder:
7350 rajveer 2865
                amount = -int(order.advanceAmount)
7344 rajveer 2866
            else:
2867
                amount = -int(order.total_amount-order.gvAmount)
5806 rajveer 2868
            ts = order.refund_timestamp
2869
        if payment_mode == "Cash":
2870
            cash_string = "<cash>" + str(amount) + "</cash>"
2871
            card_string = "<hdfc>0</hdfc>"
2872
        if payment_mode == "Card":
2873
            cash_string = "<cash>0</cash>"
2874
            card_string = "<hdfc>" + str(amount) + "</hdfc>"
2875
        date_string = "<date>" + ts.strftime("%Y%m%d") + "</date>"
2876
        time_string = "<time>" + ts.strftime("%H%M%S") + "</time>"
2877
 
7254 rajveer 2878
        conn = httplib.HTTPConnection("182.71.104.186")
5806 rajveer 2879
        XML="""
2880
        <soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
2881
          <soap:Body>
2882
            <SaholicDataTransfer xmlns="http://tempuri.org/">
2883
        """
2884
 
2885
        XML = XML + store_string + order_string + collection_type + cash_string + card_string + date_string + time_string 
2886
 
2887
        footer = """
2888
            </SaholicDataTransfer>
2889
          </soap:Body>
2890
        </soap:Envelope>
2891
        """
2892
        XML = XML + footer
2893
 
2894
        params = urllib.urlencode({'op': 'SaholicDataTransfer'})
2895
        headers = { "Content-type": "text/xml", "Content-Length": "%d" % len(XML)}
2896
        conn.request("POST", "/loaddetect/Service.asmx?"+params, "", headers)
2897
        conn.send(XML)
2898
        response = conn.getresponse()
2899
        print response.status, response.reason
2900
        resp = response.read()
2901
        conn.close()
2902
        print resp
2903
        if "Saved Successfully" in resp:
2904
            return True
2905
        elif "Error in Saving Data" in resp:
2906
            return False
2907
        else: 
2908
            return False
2909
    except Exception as e:
2910
        print e
2911
        return False
2912
 
2697 chandransh 2913
def get_return_orders(warehouse_id, from_date, to_date):
2914
    query = ReturnOrder.query.filter_by(processedStatus = False)
2915
    if warehouse_id != -1:
2916
        query = query.filter_by(warehouseId = warehouse_id)
2917
    if from_date:
4118 chandransh 2918
        query = query.filter(ReturnOrder.createdAt >from_date)
2697 chandransh 2919
    if to_date:
4118 chandransh 2920
        query = query.filter(ReturnOrder.createdAt < to_date)
2697 chandransh 2921
    return [return_order.to_thrift_object() for return_order in query.all()]
2922
 
5481 phani.kuma 2923
def get_all_return_orders(onlyNotProcessed, from_date, to_date):
2924
    query = ReturnOrder.query
2925
    if onlyNotProcessed:
2926
        query = query.filter_by(processedStatus = False)
2927
    if from_date:
2928
        query = query.filter(ReturnOrder.createdAt >= from_date)
2929
    if to_date:
2930
        query = query.filter(ReturnOrder.createdAt <= to_date)
2931
    return [return_order.to_thrift_object() for return_order in query.all()]
2932
 
2700 chandransh 2933
def get_return_order(id):
2934
    ret_order = ReturnOrder.get_by(orderId = id)
2935
    if ret_order is None:
2936
        raise TransactionServiceException(116, "No return order found for the given order id")
2937
    return ret_order.to_thrift_object()
2938
 
2697 chandransh 2939
def process_return(ret_order_id):
2940
    ret_order = ReturnOrder.get_by(orderId = ret_order_id)
2941
    if ret_order is None:
2942
        raise TransactionServiceException(116, "No return order found for the given order id")
2943
    ret_order.processedStatus = True
2701 chandransh 2944
    ret_order.processedAt = datetime.datetime.now()
2697 chandransh 2945
    session.commit()
2946
 
4757 mandeep.dh 2947
def update_orders_as_PORaised(itemIdQuantityMap, purchaseOrderId, warehouseId):
2948
    """
2949
    Updates orders as PO raised. Also updates purchase order id in orders. Pass a map of items mapped to
2950
    the quantities for which the PO is raised.
2951
 
2952
    Parameters:
2953
     - itemIdQuantityMap
2954
     - purchaseOrderId
2955
     - warehouseId
2956
    """
3451 chandransh 2957
    query = Order.query.with_lockmode("update").filter_by(warehouse_id=warehouseId)
4757 mandeep.dh 2958
    query = query.filter(or_(Order.status == OrderStatus.SUBMITTED_FOR_PROCESSING, Order.status == OrderStatus.INVENTORY_LOW))
2819 chandransh 2959
    query = query.filter_by(purchase_order_id=None)
2960
    query = query.order_by(Order.created_timestamp)
2961
    pending_orders = query.all()
4586 mandeep.dh 2962
 
2963
    for order in pending_orders:
4757 mandeep.dh 2964
        lineitem = order.lineitems[0]
2965
        if itemIdQuantityMap.has_key(lineitem.item_id):
2966
            if itemIdQuantityMap[lineitem.item_id] >= lineitem.quantity:
2967
                order.status = OrderStatus.LOW_INV_PO_RAISED
2968
                order.statusDescription = 'In Process'
2969
                order.purchase_order_id = purchaseOrderId
2970
                itemIdQuantityMap[lineitem.item_id] -= lineitem.quantity
4434 mandeep.dh 2971
 
2819 chandransh 2972
    session.commit()
2973
 
3451 chandransh 2974
def update_weight(order_id, weight):
3469 chandransh 2975
    '''
2976
    Update the weight of order
2977
    '''
3451 chandransh 2978
    order = get_order(order_id)
2979
    order.total_weight = weight
3469 chandransh 2980
    lineitem = order.lineitems[0]
2981
    lineitem.total_weight = weight
2982
    lineitem.unit_weight = weight
3451 chandransh 2983
 
3469 chandransh 2984
    session.commit()
2985
    return order
2986
 
2987
def change_product(order_id, item_id):
2988
    '''
2989
    Ship a product of a different color to the customer.
2990
    '''
2991
    order = get_order(order_id)
4662 rajveer 2992
    if order.status not in [OrderStatus.COD_VERIFICATION_PENDING, OrderStatus.SUBMITTED_FOR_PROCESSING, OrderStatus.INVENTORY_LOW, OrderStatus.LOW_INV_PO_RAISED, OrderStatus.LOW_INV_REVERSAL_IN_PROCESS, OrderStatus.LOW_INV_NOT_AVAILABLE_AT_HOTSPOT]:
3469 chandransh 2993
        raise TransactionServiceException(120, "This order has already been processed. Please seek help from engineering.")
2994
 
2995
    lineitem = order.lineitems[0]
3451 chandransh 2996
 
3469 chandransh 2997
    catalog_client = CatalogClient().get_client()
2998
 
2999
    old_item = catalog_client.getItem(lineitem.item_id)
3000
    item = catalog_client.getItem(item_id)
3001
    if old_item.catalogItemId != item.catalogItemId:
3002
        raise TransactionServiceException(121, "You can't ship a different item. You can only ship the same item in a different color.")
3003
 
5944 mandeep.dh 3004
    inventoryClient = InventoryClient().get_client()
5966 rajveer 3005
    inventoryClient.reserveItemInWarehouse(item_id, order.fulfilmentWarehouseId, sourceId, order.id, to_java_date(order.created_timestamp), to_java_date(order.promised_shipping_time), order.lineitems[0].quantity)
5110 mandeep.dh 3006
    __update_inventory_reservation(order)
3469 chandransh 3007
    #TODO: Check that this new item has the same price
3008
 
3009
    lineitem.item_id = item_id
3010
    lineitem.color = item.color
3011
 
3451 chandransh 3012
    session.commit()
3469 chandransh 3013
 
3014
    order = get_order(order_id)
3451 chandransh 3015
    return order
3469 chandransh 3016
 
3017
def change_warehouse(order_id, warehouse_id):
3018
    '''
3019
    Update the warehouse which will be used to fulfil this order.
3020
    '''
3021
    order = get_order(order_id)
6019 rajveer 3022
    if order.status not in [OrderStatus.COD_VERIFICATION_PENDING, OrderStatus.SUBMITTED_FOR_PROCESSING, OrderStatus.INVENTORY_LOW, OrderStatus.LOW_INV_PO_RAISED, OrderStatus.LOW_INV_REVERSAL_IN_PROCESS, OrderStatus.LOW_INV_NOT_AVAILABLE_AT_HOTSPOT, OrderStatus.ACCEPTED]:
3469 chandransh 3023
        raise TransactionServiceException(117, "This order has already been processed. Please seek help from engineering.")
3024
 
3025
    if warehouse_id == order.warehouse_id:
3026
        raise TransactionServiceException(118, "You have selected the current warehouse again. Nothing to do")
3027
 
3028
    lineitem = order.lineitems[0]
3029
    catalog_client = CatalogClient().get_client()
5944 mandeep.dh 3030
    inventoryClient = InventoryClient().get_client()
3469 chandransh 3031
    try:
5944 mandeep.dh 3032
        warehouse = inventoryClient.getWarehouse(warehouse_id)
3469 chandransh 3033
    except:
3034
        raise TransactionServiceException(119, "No warehouse with id" + str(warehouse_id))
5110 mandeep.dh 3035
 
6870 rajveer 3036
    if not warehouse.billingWarehouseId:
5147 mandeep.dh 3037
        raise TransactionServiceException(119, "Shifting of warehouse allowed to warehouse with billing support only")
5110 mandeep.dh 3038
 
5620 mandeep.dh 3039
    # If One gives a billing warehouse for warehouse shift, we should assign order to the GOOD warehouse
3040
    # present within it with maximum availability
3041
    if warehouse.id == warehouse.billingWarehouseId:
5944 mandeep.dh 3042
        warehouses = inventoryClient.getWarehouses(None, InventoryType.GOOD, 0, 0, warehouse.id)
5147 mandeep.dh 3043
        if warehouses:
5944 mandeep.dh 3044
            itemInventory = inventoryClient.getItemInventoryByItemId(lineitem.item_id)
5147 mandeep.dh 3045
            warehouse = warehouses[0]
3046
            maxAvailability = 0
3047
            for goodWarehouse in warehouses:
3048
                if itemInventory.availability.has_key(goodWarehouse.id) and maxAvailability < itemInventory.availability[goodWarehouse.id]:
3049
                    warehouse = goodWarehouse
3050
                    maxAvailability = itemInventory.availability[goodWarehouse.id]
3051
 
3052
            # Use preferred vendor's warehouse if not available anywhere
3053
            if not maxAvailability:
3054
                item = catalog_client.getItem(lineitem.item_id)
3055
                if item.preferredVendor:
3056
                    for goodWarehouse in warehouses:
3057
                        if goodWarehouse.vendor.id == item.preferredVendor:
3058
                            warehouse = goodWarehouse
3059
        else:
3060
            raise TransactionServiceException(119, "Shifting of warehouse allowed to GOOD inventory type warehouse with billing support")
3061
 
6007 rajveer 3062
    inventoryClient.reserveItemInWarehouse(lineitem.item_id, warehouse.id, sourceId, order.id, to_java_date(order.created_timestamp), to_java_date(order.promised_shipping_time), lineitem.quantity)
5110 mandeep.dh 3063
    __update_inventory_reservation(order)
6789 rajveer 3064
    if order.status == OrderStatus.ACCEPTED:
3065
        __update_transfer_price(order, warehouse.id)
5110 mandeep.dh 3066
    order.warehouse_id = warehouse.billingWarehouseId
5147 mandeep.dh 3067
    order.fulfilmentWarehouseId = warehouse.id
3469 chandransh 3068
    session.commit()
3069
    return order
3553 chandransh 3070
 
6789 rajveer 3071
def __update_transfer_price(order, warehouse_id):
3072
    lineitem = order.lineitems[0]
3073
    inventory_client = InventoryClient().get_client()
3074
    warehouse = inventory_client.getWarehouse(warehouse_id)
3075
    item_pricing = inventory_client.getItemPricing(lineitem.item_id, warehouse.vendor.id)
3076
    lineitem.transfer_price = item_pricing.transferPrice
3077
    lineitem.nlc = item_pricing.nlc
3078
 
4647 rajveer 3079
def add_delay_reason(order_id, reason, further_delay, delayReasonText):
3553 chandransh 3080
    '''
3994 chandransh 3081
    Adds a delay reason to the order and updates the expected delivery time.
3553 chandransh 3082
    '''
3083
    order = get_order(order_id)
3084
    try:
3581 chandransh 3085
        order.delay_reason = DelayReason._VALUES_TO_NAMES[reason]
4647 rajveer 3086
        order.delayReasonText = delayReasonText
4009 chandransh 3087
        actual_delivery_delay = adjust_delivery_time(order.expected_delivery_time, further_delay)
3088
        order.expected_delivery_time = order.expected_delivery_time + datetime.timedelta(days=actual_delivery_delay)
4102 chandransh 3089
 
4842 rajveer 3090
        actual_shipping_delay = adjust_delivery_time(order.expected_shipping_time, further_delay)
3091
        order.expected_shipping_time = order.expected_shipping_time + datetime.timedelta(days=actual_shipping_delay)
4102 chandransh 3092
 
6726 rajveer 3093
        order.courier_delivery_time = order.courier_delivery_time + datetime.timedelta(days=adjust_delivery_time(order.courier_delivery_time, further_delay))
3094
 
3553 chandransh 3095
        session.commit()
4008 mandeep.dh 3096
 
3097
        try:
3098
            transaction_requiring_extra_processing = TransactionRequiringExtraProcessing()
3099
            transaction_requiring_extra_processing.category = 'DELAYED_DELIVERY'
3100
            transaction_requiring_extra_processing.transaction_id = order.transaction_id
3101
            session.commit()
3102
        except Exception as e:
4065 mandeep.dh 3103
            print 'Could not persist transaction id: ' + str(order.transaction_id) + ' for further processing due to: ' + str(e)
4008 mandeep.dh 3104
 
3553 chandransh 3105
        return True
3106
    except:
3994 chandransh 3107
        print sys.exc_info()[0]
3553 chandransh 3108
        return False
3956 chandransh 3109
 
3110
def reconcile_cod_collection(collected_amount_map, xferBy, xferTxnId, xferDate):
3111
    unprocessed_awbs = {}
3112
    for awb, amount in collected_amount_map.iteritems():
3113
        try:
3114
            order = Order.query.filter_by(airwaybill_no=awb).one()
3115
        except NoResultFound:
3116
            unprocessed_awbs[awb] = "No order was found for the given AWB: " + awb
3117
            continue
3118
        except MultipleResultsFound:
3119
            unprocessed_awbs[awb] = "Multiple orders were found for the given AWB:" + awb
3120
            continue
3121
 
3122
        if order.cod_reconciliation_timestamp:
3123
            #This order has been processed already! This may be a re-run. Let's allow other orders to be processed.
3124
            continue
3125
 
3126
        if order.status < OrderStatus.DELIVERY_SUCCESS:
3127
            #Order has not been delivered yet. No way we can receive the payment.
3128
            unprocessed_awbs[awb] = "Payment has been received for order: " + str(order.id) + " before delivery reconciliation"
3129
            continue
3130
 
4252 rajveer 3131
        ##As per ticket #743 if amount difference less than 0.5 we should reconcile
6318 rajveer 3132
        if abs(amount - (order.total_amount - order.gvAmount)) > 0.5:
3956 chandransh 3133
            #Received amount is less than or more than the order amount. Mustn't let the user proceed.
6318 rajveer 3134
            unprocessed_awbs[awb] = "Payment of Rs. " + str(amount) + " has been received against the total value of Rs. " + str(order.total_amount-order.gvAmount) + " for order: " + str(order.id)
3956 chandransh 3135
            continue
3136
 
3137
        try:
3138
            payment_client = PaymentClient().get_client()
3139
            payment_client.partiallyCapturePayment(order.transaction.id, amount, xferBy, xferTxnId, xferDate)
3140
        except Exception:
3141
            unprocessed_awbs[awb] = "We were unable to partially capture payment for order id " + str(order.id) + ", AWB: " + awb
3142
            continue
3143
 
3144
        #Payment has been recorded now. We can update the order peacefully.
3145
        order.cod_reconciliation_timestamp = datetime.datetime.now()
3146
        session.commit()
3469 chandransh 3147
 
3956 chandransh 3148
    return unprocessed_awbs
4008 mandeep.dh 3149
 
3150
def get_transactions_requiring_extra_processing(category):
4065 mandeep.dh 3151
    """
3152
    Returns the list of transaction ids that require some extra processing and
3153
    which belong to a particular category. This is currently used by CRM
3154
    application. If no such transaction ids are present, it returns an empty list.
3155
    """
3156
    query = TransactionRequiringExtraProcessing.query
4008 mandeep.dh 3157
 
4065 mandeep.dh 3158
    if category is not None:
3159
        query = query.filter_by(category = ExtraTransactionProcessingType._VALUES_TO_NAMES.get(category))
4008 mandeep.dh 3160
 
4065 mandeep.dh 3161
    return [a.transaction_id for a in query.all()]
4008 mandeep.dh 3162
 
3163
def mark_transaction_as_processed(transactionId, category):
4065 mandeep.dh 3164
    """
3165
    Marks a particular transaction as processed for a particular cateogory.
3166
    It essentially deletes the transaction id record for a particular
3167
    processing type category (if present) from DB.
3168
    This is currently used by CRM application.
3169
    """
4008 mandeep.dh 3170
    TransactionRequiringExtraProcessing.query.filter_by(transaction_id = transactionId).filter_by(category = ExtraTransactionProcessingType._VALUES_TO_NAMES.get(category)).delete()
3171
    session.commit()
3172
 
4018 chandransh 3173
def get_item_wise_risky_orders_count():
3174
    """
3175
    Returns a map containing the number of risky orders keyed by item id. A risky order
3176
    is defined as one whose shipping date is about to expire.
3177
    """
3178
    item_wise_risky_orders_count = {}
4019 chandransh 3179
    shipping_cutoff_time = (datetime.datetime.now() + datetime.timedelta(days = 1)).replace(hour=PREPAID_SHIPPING_CUTOFF_TIME, minute=0, second=0)
4018 chandransh 3180
    orders = Order.query.filter(Order.status.in_(tuple([OrderStatus.SUBMITTED_FOR_PROCESSING, OrderStatus.INVENTORY_LOW, OrderStatus.ACCEPTED]))).filter(Order.expected_shipping_time <= shipping_cutoff_time).all()
3181
    for order in orders:
3182
        for lineitem in order.lineitems:
3183
            quantity = lineitem.quantity
3184
            if item_wise_risky_orders_count.has_key(lineitem.item_id):
3185
                quantity = quantity + item_wise_risky_orders_count[lineitem.item_id]
3186
 
3187
            item_wise_risky_orders_count[lineitem.item_id] = quantity
3188
    return item_wise_risky_orders_count
3189
 
4324 mandeep.dh 3190
def update_shipment_address(order_id, address_id):
3191
    """
3192
    Updates shipment address of an order. Delivery and shipping date estimates
3193
    etc. are also updated here.
3194
 
3195
    Throws TransactionServiceException in case address change is not
3196
    possible due to certain reasons such as new pincode in address is
3197
    not serviceable etc.
3198
 
3199
    Parameters:
3200
     - orderId
3201
     - addressId
3202
    """
3203
    user_client = UserClient().get_client()
3204
    address     = user_client.getAddressById(address_id)
3205
    order       = get_order(order_id)
3206
 
4630 mandeep.dh 3207
    type = DeliveryType.PREPAID
3208
    if order.cod:
3209
        type = DeliveryType.COD
3210
 
4324 mandeep.dh 3211
    logistics_client = LogisticsClient().get_client()
5886 mandeep.dh 3212
    logistics_info = logistics_client.getLogisticsEstimation(order.lineitems[0].item_id, address.pin, type)
4324 mandeep.dh 3213
 
3214
    # Check for new estimate. Raise exception if new address is not serviceable
3215
    if logistics_info.deliveryTime == -1:
3216
        raise TransactionServiceException(1, 'Location not serviceable')
3217
 
3218
    # COD services are not available everywhere
3219
    if order.cod:
4868 rajveer 3220
        if not logistics_info.codAllowed:
4324 mandeep.dh 3221
            raise TransactionServiceException(2, 'COD service not available')
3222
 
5593 mandeep.dh 3223
    if logistics_info.providerId != order.logistics_provider_id:
5887 mandeep.dh 3224
        logistics_info = logistics_client.getLogisticsInfo(address.pin, order.lineitems[0].item_id, type, PickUpType.COURIER)
5593 mandeep.dh 3225
        order.tracking_id = logistics_info.airway_billno
3226
        order.airwaybill_no = logistics_info.airway_billno
3227
        order.logistics_provider_id = logistics_info.providerId
3228
 
6525 rajveer 3229
    order.otg = logistics_info.otgAvailable
4324 mandeep.dh 3230
    current_time = datetime.datetime.now()
3231
    logistics_info.deliveryTime = adjust_delivery_time(current_time, logistics_info.deliveryTime)
3232
    logistics_info.shippingTime = adjust_delivery_time(current_time, logistics_info.shippingTime)
6726 rajveer 3233
    logistics_info.deliveryDelay = adjust_delivery_time(current_time, (logistics_info.shippingTime+logistics_info.deliveryDelay))
4324 mandeep.dh 3234
 
3235
    order.customer_name         = address.name
3236
    order.customer_pincode      = address.pin
3237
    order.customer_address1     = address.line1
3238
    order.customer_address2     = address.line2
3239
    order.customer_city         = address.city
3240
    order.customer_state        = address.state
3241
    order.customer_mobilenumber = address.phone
3242
 
3243
    if order.cod:
3244
        order.expected_shipping_time = (current_time + datetime.timedelta(days=logistics_info.shippingTime)).replace(hour=COD_SHIPPING_CUTOFF_TIME, minute=0, second=0)
6726 rajveer 3245
        order.expected_delivery_time = (current_time + datetime.timedelta(days=logistics_info.deliveryTime)).replace(hour=COD_SHIPPING_CUTOFF_TIME, minute=0, second=0)
3246
        order.courier_delivery_time = (current_time + datetime.timedelta(days=logistics_info.deliveryDelay)).replace(hour=COD_SHIPPING_CUTOFF_TIME, minute=0, second=0)
4324 mandeep.dh 3247
    else:
3248
        order.expected_shipping_time = (current_time + datetime.timedelta(days=logistics_info.shippingTime)).replace(hour=PREPAID_SHIPPING_CUTOFF_TIME, minute=0, second=0)
6726 rajveer 3249
        order.expected_delivery_time = (current_time + datetime.timedelta(days=logistics_info.deliveryTime)).replace(hour=PREPAID_SHIPPING_CUTOFF_TIME, minute=0, second=0)
3250
        order.courier_delivery_time = (current_time + datetime.timedelta(days=logistics_info.deliveryDelay)).replace(hour=PREPAID_SHIPPING_CUTOFF_TIME, minute=0, second=0)
4324 mandeep.dh 3251
 
3252
    order.promised_shipping_time = order.expected_shipping_time
3253
    order.promised_delivery_time = order.expected_delivery_time 
3254
 
3255
    session.commit()
3256
 
4247 rajveer 3257
def mark_order_cancellation_request_received(orderId):
3258
    """
3259
    Mark order as cancellation request received. If customer sends request of cancellation of
3260
    a particular order, this method will be called. It will just change status of the order
3261
    depending on its current status. It also records the previous status, so that we can move
3262
    back to that status if cancellation request is denied.
3263
 
3264
    Parameters:
3265
     - orderId
3266
    """
4662 rajveer 3267
    status_transition = {OrderStatus.COD_VERIFICATION_PENDING : OrderStatus.CANCEL_REQUEST_RECEIVED,
4247 rajveer 3268
             OrderStatus.SUBMITTED_FOR_PROCESSING : OrderStatus.CANCEL_REQUEST_RECEIVED,
3269
             OrderStatus.INVENTORY_LOW : OrderStatus.CANCEL_REQUEST_RECEIVED,
4306 rajveer 3270
             OrderStatus.LOW_INV_PO_RAISED : OrderStatus.CANCEL_REQUEST_RECEIVED,
3271
             OrderStatus.LOW_INV_REVERSAL_IN_PROCESS : OrderStatus.CANCEL_REQUEST_RECEIVED,
3272
             OrderStatus.LOW_INV_NOT_AVAILABLE_AT_HOTSPOT : OrderStatus.CANCEL_REQUEST_RECEIVED,
4247 rajveer 3273
             OrderStatus.ACCEPTED : OrderStatus.CANCEL_REQUEST_RECEIVED,
3274
             OrderStatus.BILLED : OrderStatus.CANCEL_REQUEST_RECEIVED,
3275
             OrderStatus.PAYMENT_FLAGGED : OrderStatus.CANCEL_REQUEST_RECEIVED
3276
             }
4662 rajveer 3277
 
3278
    order = get_order(orderId)
4247 rajveer 3279
    if order.status not in status_transition.keys():
3280
        raise TransactionServiceException(114, "This order can't be considered for cancellation")
3281
 
4662 rajveer 3282
 
4247 rajveer 3283
    order.previousStatus = order.status
3284
    order.status = OrderStatus.CANCEL_REQUEST_RECEIVED
3285
    order.statusDescription = "Cancellation request received from user"
3286
    session.commit()
3287
 
4662 rajveer 3288
def mark_order_as_lost_in_transit(orderId):
3289
    """
3290
    Parameters:
3291
     - orderId
3292
    """
3293
    order = get_order(orderId)
4910 phani.kuma 3294
    if order.status not in [OrderStatus.SHIPPED_FROM_WH, OrderStatus.SHIPPED_TO_LOGST, OrderStatus.SHIPPED_TO_DESTINATION_CITY, OrderStatus.REACHED_DESTINATION_CITY, OrderStatus.FIRST_DELIVERY_ATTEMPT_MADE]:
4662 rajveer 3295
        raise TransactionServiceException(115, "This order can't be marked as lost in transit")
3296
    order.status = OrderStatus.LOST_IN_TRANSIT
3297
    order.statusDescription = "Lost in Transit"
3298
    session.commit()
3299
 
4258 rajveer 3300
def mark_transaction_as_payment_flag_removed(transactionId):
4247 rajveer 3301
    """
4258 rajveer 3302
    If we and/or payment gateway has decided to accept the payment, this method needs to be called.
3303
    Changed transaction and all orders status to payment accepted.
4247 rajveer 3304
 
3305
    Parameters:
4258 rajveer 3306
     - transactionId
4247 rajveer 3307
    """
4258 rajveer 3308
    transaction = get_transaction(transactionId)
3309
    transaction.status = TransactionStatus.AUTHORIZED
3310
    for order in transaction.orders:
3311
        order.status = OrderStatus.SUBMITTED_FOR_PROCESSING
3312
        order.statusDescription = "Submitted to warehouse"
4247 rajveer 3313
    session.commit()
3314
 
4259 anupam.sin 3315
def refund_transaction(transactionId, refundedBy, reason):
3316
    """
3317
    This method is called when a flagged payment is deemed unserviceable and the corresponding orders
3318
    need to be cancelled
3319
 
3320
    Parameters:
3321
     - transactionId
3322
    """
3323
    transaction = get_transaction(transactionId)
3324
    transaction.status = TransactionStatus.FAILED
3325
    for order in transaction.orders:
3326
        refund_order(order.id, refundedBy, reason)
3327
    session.commit()
3328
 
4247 rajveer 3329
def mark_order_cancellation_request_denied(orderId):
3330
    """
4283 anupam.sin 3331
    If we decide to not to cancel order, we will move the order to previous status.
4247 rajveer 3332
 
3333
    Parameters:
3334
     - orderId
3335
    """
3336
    order = get_order(orderId)
3337
    order.status = order.previousStatus
3338
    order.previousStatus = None
3339
    order.statusDescription = "Cancellation request denied"
3340
    session.commit()
3341
 
3342
def mark_order_cancellation_request_confirmed(orderId):
3343
    """
3344
    If we decide to to cancel order, CRM will call this method to move the status of order to
3345
    cancellation request confirmed. After this OM will be able to cancel the order.
3346
 
3347
    Parameters:
3348
     - orderId
3349
    """
3350
    order = get_order(orderId)
3351
    order.status = OrderStatus.CANCEL_REQUEST_CONFIRMED
3352
    order.statusDescription = "Cancellation request confirmed"
3353
    session.commit()
3354
 
4285 rajveer 3355
def accept_orders_for_item_id(itemId, inventory):
3356
    """
3357
    Marks the orders as ACCEPTED for the given itemId and inventory. It also updates the accepted timestamp. If the
3358
    given order is not a COD order, it also captures the payment if the same has not been captured.
3359
 
3360
    Parameters:
3361
     - itemId
3362
     - inventory
3363
    """
6782 rajveer 3364
    orders = Order.query.filter(Order.warehouse_id == 9).filter(Order.status.in_(tuple([OrderStatus.SUBMITTED_FOR_PROCESSING, OrderStatus.INVENTORY_LOW, OrderStatus.LOW_INV_PO_RAISED, OrderStatus.LOW_INV_REVERSAL_IN_PROCESS]))).order_by(Order.expected_shipping_time).all()
4285 rajveer 3365
    for order in orders:
4301 rajveer 3366
        if inventory > 0:
3367
            lineitem = order.lineitems[0]
3368
            if itemId == lineitem.item_id:
3369
                try:
3370
                    accept_order(order.id)
3371
                    inventory = inventory - lineitem.quantity
3372
                except:
3373
                    logging.info("Unable to accept the order")
3374
        else:
3375
            order_outofstock(order.id)
4285 rajveer 3376
    return
3377
 
6864 rajveer 3378
def move_orders_to_correct_warehouse():
3379
    orders = Order.query.filter(Order.status.in_(tuple([OrderStatus.SUBMITTED_FOR_PROCESSING, OrderStatus.INVENTORY_LOW, OrderStatus.LOW_INV_PO_RAISED, OrderStatus.LOW_INV_REVERSAL_IN_PROCESS]))).order_by(Order.promised_shipping_time).all()
3380
    logistics_client = LogisticsClient().get_client()
3381
    for order in orders:
3382
        lineitem = order.lineitems[0]
6870 rajveer 3383
        logistics_info = logistics_client.getLogisticsInfo(order.customer_pincode, lineitem.item_id, order.cod, PickUpType.COURIER)
6864 rajveer 3384
        if order.fulfilmentWarehouseId != logistics_info.fulfilmentWarehouseId:
6870 rajveer 3385
            try:
3386
                print "++++" + str(order.id) + "=" + str(order.fulfilmentWarehouseId) + "->"+ str(logistics_info.fulfilmentWarehouseId)
3387
                change_warehouse(order.id, logistics_info.fulfilmentWarehouseId)
3388
            except:
3389
                print "++++" + str(order.id)
6864 rajveer 3390
 
4607 rajveer 3391
def get_slipped_sipping_date_orders():
4662 rajveer 3392
    return Order.query.filter(Order.status.in_(tuple([OrderStatus.COD_VERIFICATION_PENDING, OrderStatus.SUBMITTED_FOR_PROCESSING, OrderStatus.INVENTORY_LOW, OrderStatus.LOW_INV_PO_RAISED, OrderStatus.LOW_INV_REVERSAL_IN_PROCESS, OrderStatus.ACCEPTED, OrderStatus.BILLED]))).filter(Order.promised_shipping_time <= datetime.datetime.now()).order_by(Order.promised_shipping_time).all()
4709 rajveer 3393
 
3394
def get_cancelled_orders(cancelDateFrom, cancelDateTo):
3395
    return Order.query.filter(Order.status == OrderStatus.CANCELLED_DUE_TO_LOW_INVENTORY).filter(Order.refund_timestamp >= cancelDateFrom).filter(Order.refund_timestamp <= cancelDateTo).all()
4607 rajveer 3396
 
4369 rajveer 3397
def mark_orders_as_po_raised(vendorId, itemId, quantity, estimate, isReminder):
3398
    if isReminder:
3399
        statuses = tuple([OrderStatus.LOW_INV_PO_RAISED_TIMEOUT, OrderStatus.LOW_INV_REVERSAL_TIMEOUT])
3400
    else:
3401
        statuses = tuple([OrderStatus.SUBMITTED_FOR_PROCESSING, OrderStatus.INVENTORY_LOW])
3402
 
3403
    orders = Order.query.filter(Order.status.in_(statuses)).order_by(Order.expected_shipping_time).all()
4303 rajveer 3404
    for order in orders:
3405
        lineitem = order.lineitems[0]
3406
        if quantity >= lineitem.quantity and itemId == lineitem.item_id:
3407
            if estimate > 0:
3408
                add_delay_reason(order.id, DelayReason.OTHERS, estimate)
3409
            order.status = OrderStatus.LOW_INV_PO_RAISED
4362 rajveer 3410
            order.statusDescription = "PO Raised"
4303 rajveer 3411
            quantity = quantity - lineitem.quantity
3412
            store_inventory_action(order, itemId, HotspotAction.PO_RAISED, estimate, lineitem.quantity)
3413
            session.commit()
3414
 
4369 rajveer 3415
def mark_orders_as_reversal_initiated(vendorId, itemId, quantity, estimate, isReminder):
3416
    if isReminder:
3417
        statuses = tuple([OrderStatus.LOW_INV_PO_RAISED_TIMEOUT, OrderStatus.LOW_INV_REVERSAL_TIMEOUT])
3418
    else:
3419
        statuses = tuple([OrderStatus.SUBMITTED_FOR_PROCESSING, OrderStatus.INVENTORY_LOW])
3420
    orders = Order.query.filter(Order.status.in_(statuses)).order_by(Order.expected_shipping_time).all()
4303 rajveer 3421
    for order in orders:
3422
        lineitem = order.lineitems[0]
3423
        if quantity >= lineitem.quantity and itemId == lineitem.item_id:
3424
            if estimate > 0:
3425
                add_delay_reason(order.id, DelayReason.OTHERS, estimate)
3426
            order.status = OrderStatus.LOW_INV_REVERSAL_IN_PROCESS
4362 rajveer 3427
            order.statusDescription = "Reversal Initiated"
4303 rajveer 3428
            quantity = quantity - lineitem.quantity
3429
            store_inventory_action(order, itemId, HotspotAction.REVERSAL_INITIATED, estimate, lineitem.quantity)
3430
            session.commit()
3431
 
4369 rajveer 3432
def mark_orders_as_not_available(vendorId, itemId, quantity, estimate, isReminder):
3433
    if isReminder:
3434
        statuses = tuple([OrderStatus.LOW_INV_PO_RAISED_TIMEOUT, OrderStatus.LOW_INV_REVERSAL_TIMEOUT])
3435
    else:
3436
        statuses = tuple([OrderStatus.SUBMITTED_FOR_PROCESSING, OrderStatus.INVENTORY_LOW])
3437
 
3438
    orders = Order.query.filter(Order.status.in_(statuses)).order_by(Order.expected_shipping_time).all()
4303 rajveer 3439
    for order in orders:
3440
        lineitem = order.lineitems[0]
3441
        if quantity >= lineitem.quantity and itemId == lineitem.item_id:
3442
            order.status = OrderStatus.LOW_INV_NOT_AVAILABLE_AT_HOTSPOT
4362 rajveer 3443
            order.statusDescription = "Not Available"
4303 rajveer 3444
            quantity = quantity - lineitem.quantity
3445
            store_inventory_action(order, itemId, HotspotAction.NOT_AVAILABLE, estimate, lineitem.quantity)
3446
            session.commit()
3447
 
3448
def store_inventory_action(order, itemId, hotspotAction, estimate, quantity):
4369 rajveer 3449
    orderInv = OrderInventory.get_by(order_id=order.id)
3450
    if not orderInv:
3451
        orderInv = OrderInventory()
3452
        orderInv.order = order
4303 rajveer 3453
    orderInv.hotspotAction = hotspotAction  
3454
    orderInv.estimate = estimate
3455
    orderInv.itemId = itemId
3456
    orderInv.timestamp = datetime.datetime.now()
3457
    orderInv.quantity = quantity
3458
 
4556 mandeep.dh 3459
'''    
4369 rajveer 3460
def mark_orders_as_timeout(vendorId):
3461
    ret_timeouts = {}
3462
    orderInvs = OrderInventory.query.all()
3463
    for orderInv in orderInvs:
3464
        if orderInv.timestamp +  timedelta(days=orderInv.estimate) < datetime.datetime.now():
3465
            if not ret_timeouts.has_key(orderInv.itemId):
3466
                timeout = TimeoutSummary()
3467
                ret_timeouts[orderInv.itemId] = timeout
3468
            else:
3469
                timeout = ret_timeouts.get(orderInv.itemId)
3470
            if orderInv.hotspotAction == HotspotAction.PO_RAISED and orderInv.order.status == OrderStatus.LOW_INV_PO_RAISED:
3471
                if timeout.poRaised:
3472
                    timeout.poRaised += 1
3473
                else:
3474
                    timeout.poRaised = 1
3475
 
3476
                if timeout.poEstimate:
3477
                    timeout.poEstimate += orderInv.estimate
3478
                else:
3479
                    timeout.poEstimate = orderInv.estimate
3480
                orderInv.order.status = OrderStatus.LOW_INV_PO_RAISED_TIMEOUT
3481
                orderInv.order.statusDescription = "PO Raised Timeout"
3482
            elif orderInv.hotspotAction == HotspotAction.REVERSAL_INITIATED and orderInv.order.status == OrderStatus.LOW_INV_REVERSAL_IN_PROCESS:
3483
                if timeout.reversalInitiated:
3484
                    timeout.reversalInitiated += 1
3485
                else:
3486
                    timeout.reversalInitiated = 1
3487
 
3488
                if timeout.reversalEstimate:
3489
                    timeout.reversalEstimate += orderInv.estimate
3490
                else:
3491
                    timeout.reversalEstimate = orderInv.estimate
3492
                orderInv.order.status = OrderStatus.LOW_INV_REVERSAL_TIMEOUT
3493
                orderInv.order.statusDescription = "Reversal Initiated Timeout"
3494
            else:
3495
                orderInv.delete()
3496
    session.commit()
3497
    return ret_timeouts
4556 mandeep.dh 3498
'''
3499
 
3500
 
3501
def mark_orders_as_timeout(vendorId):
3502
    ret_timeouts = {}
3503
    orderInvs = OrderInventory.query.all()
3504
    for orderInv in orderInvs:
3505
        if not ret_timeouts.has_key(orderInv.itemId):
3506
            timeout = TimeoutSummary()
3507
            ret_timeouts[orderInv.itemId] = timeout
3508
        else:
3509
            timeout = ret_timeouts.get(orderInv.itemId)
3510
        if orderInv.hotspotAction == HotspotAction.PO_RAISED and orderInv.order.status == OrderStatus.LOW_INV_PO_RAISED:
3511
            if timeout.poRaised:
3512
                timeout.poRaised += 1
3513
            else:
3514
                timeout.poRaised = 1
3515
 
3516
            if timeout.poEstimate:
3517
                timeout.poEstimate = max(orderInv.estimate, timeout.poEstimate)
3518
            else:
3519
                timeout.poEstimate = orderInv.estimate
3520
        elif orderInv.hotspotAction == HotspotAction.REVERSAL_INITIATED and orderInv.order.status == OrderStatus.LOW_INV_REVERSAL_IN_PROCESS:
3521
            if timeout.reversalInitiated:
3522
                timeout.reversalInitiated += 1
3523
            else:
3524
                timeout.reversalInitiated = 1
3525
 
3526
            if timeout.reversalEstimate:
3527
                timeout.reversalEstimate = max(orderInv.estimate, timeout.reversalEstimate)
3528
            else:
3529
                timeout.reversalEstimate = orderInv.estimate
3530
        orderInv.order.status = OrderStatus.INVENTORY_LOW
3531
        orderInv.order.statusDescription = "Low Inventory"
3532
        orderInv.delete()
3533
    session.commit()
3534
    return ret_timeouts
3535
 
4386 anupam.sin 3536
def get_order_for_awb(awb):
3537
    order = Order.get_by(airwaybill_no=awb)
3538
    if not order:
3539
        raise TransactionServiceException(108, "no such order")
3540
 
3541
    return order
4369 rajveer 3542
 
4910 phani.kuma 3543
def get_orders_for_provider_for_status(provider_id, order_status_list):
3544
    if not provider_id or not order_status_list:
4506 phani.kuma 3545
        raise TransactionServiceException(101, "bad provider id or order status")
4910 phani.kuma 3546
    doa_provider = False
3547
    for order_status in order_status_list:
3548
        if order_status in [OrderStatus.DOA_PICKUP_CONFIRMED, OrderStatus.RET_PICKUP_CONFIRMED]:
3549
            doa_provider = True
3550
    if doa_provider:
3551
        query = Order.query.filter_by(doa_logistics_provider_id = provider_id).filter(Order.status.in_(order_status_list))
4815 phani.kuma 3552
    else:
4910 phani.kuma 3553
        query = Order.query.filter_by(logistics_provider_id = provider_id).filter(Order.status.in_(order_status_list))
4506 phani.kuma 3554
    return query.all()
4386 anupam.sin 3555
 
4600 varun.gupt 3556
def get_billed_orders_for_vendor(vendor_id, billing_date_from, billing_date_to):
5368 mandeep.dh 3557
    query = Order.query.filter(Order.status != OrderStatus.PAYMENT_PENDING)
3558
 
3559
    if vendor_id:
3560
        query = query.filter_by(vendorId = vendor_id)
3561
 
4600 varun.gupt 3562
    if billing_date_from:
3563
        query = query.filter(Order.billing_timestamp >= billing_date_from)
5368 mandeep.dh 3564
 
4600 varun.gupt 3565
    if billing_date_to:
3566
        query = query.filter(Order.billing_timestamp <= billing_date_to)
5368 mandeep.dh 3567
 
4600 varun.gupt 3568
    return query.all()
3569
 
5481 phani.kuma 3570
def get_billed_orders(vendor_id, onlyVendorNotPaid, billing_date_from, billing_date_to):
5386 phani.kuma 3571
    query = Order.query.filter(Order.billing_timestamp != None)
5481 phani.kuma 3572
 
3573
    if onlyVendorNotPaid:
5488 phani.kuma 3574
        query = query.filter_by(vendor_paid = False)
5481 phani.kuma 3575
 
5386 phani.kuma 3576
    if vendor_id != -1:
3577
        query = query.filter_by(vendorId = vendor_id)
3578
 
5481 phani.kuma 3579
    if billing_date_from:
3580
        query = query.filter(Order.billing_timestamp >= billing_date_from)
3581
 
3582
    if billing_date_to:
3583
        query = query.filter(Order.billing_timestamp <= billing_date_to)
3584
 
4885 varun.gupt 3585
    return query.all()
4875 varun.gupt 3586
 
4600 varun.gupt 3587
def save_bluedart_settlements(map_awb_and_amount):
3588
    payment_client = PaymentClient().get_client()
3589
 
3590
    for awb, amount in map_awb_and_amount.iteritems():
3591
        order = Order.get_by(airwaybill_no = awb)
3592
 
3593
        payment = payment_client.getSuccessfulPaymentForTxnId(order.transaction_id)
3594
        settlement = PaymentSettlement()
3595
        settlement.paymentId = payment.paymentId
3596
        settlement.paymentGatewayId = payment.gatewayId
3597
        settlement.netCollection = amount
3598
        session.commit()
3599
 
4905 varun.gupt 3600
def save_payment_settlements(settlementDate, paymentGatewayId, referenceId, serviceTax, otherCharges, netCollection):
5386 phani.kuma 3601
    originalOrderId = None
3602
    if paymentGatewayId == 4:
3603
        cod_order = Order.get_by(id = referenceId)
3604
        if cod_order.originalOrderId:
3605
            originalOrderId = cod_order.originalOrderId
3606
        else:
3607
            originalOrderId = referenceId
4600 varun.gupt 3608
    settlement = PaymentSettlement()
3609
    settlement.settlementDate = settlementDate
3610
    settlement.paymentGatewayId = paymentGatewayId
5386 phani.kuma 3611
    if originalOrderId is not None:
3612
        settlement.originalOrderId = originalOrderId
4905 varun.gupt 3613
    settlement.referenceId = referenceId
4600 varun.gupt 3614
    settlement.serviceTax = serviceTax
3615
    settlement.otherCharges = otherCharges
3616
    settlement.netCollection = netCollection
3617
    session.commit()
3618
 
5386 phani.kuma 3619
def get_settlement_for_Prepaid(reference_id, is_refund = False):
3620
    query = PaymentSettlement.query.filter_by(referenceId = reference_id).filter(PaymentSettlement.paymentGatewayId != 4)
4600 varun.gupt 3621
 
5189 varun.gupt 3622
    if is_refund:
3623
        query = query.filter(PaymentSettlement.netCollection < 0)
3624
    else:
3625
        query = query.filter(PaymentSettlement.netCollection > 0)
3626
 
5386 phani.kuma 3627
    return query.first()
3628
 
3629
def get_settlement_for_Cod(orderId, is_refund = False):
3630
    query = PaymentSettlement.query.filter_by(originalOrderId = orderId)
5382 varun.gupt 3631
 
5386 phani.kuma 3632
    if is_refund:
3633
        query = query.filter(PaymentSettlement.netCollection < 0)
3634
    else:
3635
        query = query.filter(PaymentSettlement.netCollection > 0)
3636
 
5189 varun.gupt 3637
    return query.first()
4600 varun.gupt 3638
 
3639
def save_ebs_settlement_summary(settlement_id, settlement_date, transaction_date_from, transaction_date_to, amount):
5551 phani.kuma 3640
    summary = EBSSettlementSummary.query.filter_by(settlementId = settlement_id).first()
5481 phani.kuma 3641
    if summary is None:
3642
        summary = EBSSettlementSummary()
3643
        summary.settlementId = settlement_id
3644
        summary.settlementDate = settlement_date
3645
        summary.transactionDateFrom = transaction_date_from
3646
        summary.transactionDateTo = transaction_date_to
3647
        summary.amount = amount
3648
        summary.detailsUploaded = False
3649
        session.commit()
4600 varun.gupt 3650
 
3651
def get_ebs_settlement_summaries():
3652
    summaries = EBSSettlementSummary.query.filter_by(detailsUploaded = False).order_by(EBSSettlementSummary.transactionDateFrom).all()
3653
    summary_map = {}
3654
 
3655
    for summary in summaries:
3656
        transactionDateFrom = str(summary.transactionDateFrom.year) + '-' + str(summary.transactionDateFrom.month) + '-' + str(summary.transactionDateFrom.day)
3657
        transactionDateTo = str(summary.transactionDateTo.year) + '-' + str(summary.transactionDateTo.month) + '-' + str(summary.transactionDateTo.day)
3658
 
3659
        summary_map[summary.settlementId] = "%s to %s" %(transactionDateFrom, transactionDateTo)
3660
 
3661
    return summary_map
3662
 
3663
def get_ebs_settlement_date(settlement_id):
3664
    summary = EBSSettlementSummary.get_by(settlementId = settlement_id)
3665
 
3666
    if summary:
3667
        return summary.settlementDate
3668
 
3669
def mark_ebs_settlement_uploaded(settlement_id):
3670
    summary = EBSSettlementSummary.get_by(settlementId = settlement_id)
3671
 
3672
    if summary:
3673
        summary.detailsUploaded = True
3674
        session.commit()
4715 varun.gupt 3675
 
3676
def get_settlements_by_date(settlement_date_from, settlement_date_to, is_refund):
3677
    query = PaymentSettlement.query
4600 varun.gupt 3678
 
4715 varun.gupt 3679
    if settlement_date_from:
3680
        query = query.filter(PaymentSettlement.settlementDate >= settlement_date_from)
3681
 
3682
    if settlement_date_to:
3683
        query = query.filter(PaymentSettlement.settlementDate <= settlement_date_to)
3684
 
4749 varun.gupt 3685
    if is_refund is True:
3686
        query = query.filter(PaymentSettlement.netCollection < 0.0)
3687
    else:
3688
        query = query.filter(PaymentSettlement.netCollection > 0.0)
4715 varun.gupt 3689
 
4749 varun.gupt 3690
    return query.all()
4715 varun.gupt 3691
 
3692
def get_reshipped_order_ids(order_ids):
3693
    reshipped_order_ids = []
3694
    return [order.new_order_id for order in Order.query.filter(Order.new_order_id.in_(order_ids)).all()]
3695
 
4749 varun.gupt 3696
def get_shipping_confirmation_email_body(order):
3697
 
3698
    html = """
3699
<html>
3700
<body>
3701
<div>
3702
    <p>Dear Customer,</p>
3703
    <p>
4885 varun.gupt 3704
        We are pleased to inform that we have shipped the order: $order_id for your product $product_name on $shipping_datetime. 
5139 varun.gupt 3705
        The shipment will be delivered to you via $courier_name Courier Service vide AWB# $awb.
7198 amar.kumar 3706
 
4749 varun.gupt 3707
    </p>
3708
    <p>
6655 rajveer 3709
        Expected delivery date for your order is $expected_delivery_date.
6675 rajveer 3710
        <br/>
3711
        $otg_text
7198 amar.kumar 3712
        $freebie_text
6675 rajveer 3713
        <br/> 
6716 rajveer 3714
        The product can be delivered to you between business hours of 10am to 6pm.
3715
        You can Check the current shipment updates for your product online at <a href="www.saholic.com/myaccount">Open Orders</a>.
4749 varun.gupt 3716
    </p>
3717
    <p>
5573 amit.gupta 3718
        For scheduling the delivery of your product at some specific timings, we recommend you to contact the helpline for $courier_name with your complete AWB#.
4749 varun.gupt 3719
    </p>
5139 varun.gupt 3720
    <p>$courier_name: $courier_phone</p>
4749 varun.gupt 3721
    <p>
3722
        Warm Regards,<br />
6029 rajveer 3723
        $source_name Team
4749 varun.gupt 3724
    </p>
4750 varun.gupt 3725
</div>
4749 varun.gupt 3726
</body>
3727
</html>
3728
    """
5573 amit.gupta 3729
    logistics_providers = {1: {'name': 'BlueDart', 'phone': '011-66111234'}, 2: {'name': 'Aramex', 'phone': '0124- 39419900'}, 3: {'name': 'Delhivery', 'phone' : '0124- 4212200'}}
5139 varun.gupt 3730
    provider_name = logistics_providers[order.logistics_provider_id]['name']
3731
    provider_phone = logistics_providers[order.logistics_provider_id]['phone']
3732
 
5868 rajveer 3733
    lclient = LogisticsClient().get_client()
3734
    logistics_info = lclient.getLogisticsEstimation(order.lineitems[0].item_id, order.customer_pincode, DeliveryType.PREPAID)
4749 varun.gupt 3735
    dt = datetime.datetime.strptime(str(order.shipping_timestamp), "%Y-%m-%d %H:%M:%S")
4885 varun.gupt 3736
    shipping_date = dt.strftime("%A, %d %B %Y %I:%M%p")
6712 rajveer 3737
    product = str(order.lineitems[0])
5868 rajveer 3738
    new_expected_delivery_timestamp = datetime.datetime.now() + timedelta(adjust_delivery_time(datetime.datetime.now(), (logistics_info.deliveryTime - logistics_info.shippingTime)))
6728 rajveer 3739
    new_courier_delivery_time = datetime.datetime.now() + timedelta(adjust_delivery_time(datetime.datetime.now(), (logistics_info.deliveryTime - logistics_info.shippingTime - logistics_info.deliveryDelay)))
6666 rajveer 3740
    #update new expected timestamp
3741
    if order.cod:
6705 amar.kumar 3742
        new_expected_delivery_timestamp = new_expected_delivery_timestamp.replace(hour=COD_SHIPPING_CUTOFF_TIME, minute=0, second=0, microsecond=0)
6728 rajveer 3743
        order.courier_delivery_time = new_courier_delivery_time.replace(hour=COD_SHIPPING_CUTOFF_TIME, minute=0, second=0, microsecond=0)
6666 rajveer 3744
    else:
6705 amar.kumar 3745
        new_expected_delivery_timestamp = new_expected_delivery_timestamp.replace(hour=PREPAID_SHIPPING_CUTOFF_TIME, minute=0, second=0, microsecond=0)
6728 rajveer 3746
        order.courier_delivery_time = new_courier_delivery_time.replace(hour=PREPAID_SHIPPING_CUTOFF_TIME, minute=0, second=0, microsecond=0)
6666 rajveer 3747
    order.expected_delivery_time = new_expected_delivery_timestamp
3748
    session.commit()
3749
 
4885 varun.gupt 3750
    new_expected_delivery_date = new_expected_delivery_timestamp.strftime("%A, %d %B %Y")
6655 rajveer 3751
    otg_text = ""
3752
    if order.otg:
6662 rajveer 3753
        promised_delivery_date = order.promised_delivery_time.strftime("%A, %d %B %Y")
6655 rajveer 3754
        if new_expected_delivery_timestamp > order.promised_delivery_time:
6712 rajveer 3755
            otg_text = 'Your order is covered under our <a href="http://www.saholic.com/static/on-time-guarantee">On Time Guarantee; We Pay if we Delay.</a> We apologize in advance for the expected delay from our initial promised delivery date of ' + promised_delivery_date + '. Your will receive a Gift Voucher Code at time of delivery based on the actual delay. You can use the same to buy any Mobile, Camera, Laptop, Tablet, Accessory or Mobile/DTH Recharge from our website.'
6655 rajveer 3756
        elif new_expected_delivery_timestamp < order.promised_delivery_time:
6662 rajveer 3757
            otg_text = 'We are happy to inform you that we expect to deliver your order before time. Your order is covered under our <a href="http://www.saholic.com/static/on-time-guarantee">On Time Guarantee; We Pay if we Delay.</a> Please note, compensation for delay (If Any) will be computed from the initial promised delivery date of ' + promised_delivery_date + '.'
6655 rajveer 3758
        else:            
6662 rajveer 3759
            otg_text = 'Your order is covered under our <a href="http://www.saholic.com/static/on-time-guarantee">On Time Guarantee; We Pay if we Delay.</a> We are committed to deliver your order by our initial promised delivery date of ' + promised_delivery_date + '.'
7190 amar.kumar 3760
 
3761
    freebie_text = "<br/>"
3762
    if order.freebieItemId:
3763
        catalog_client = CatalogClient().get_client()
3764
        item = catalog_client.getItem(order.freebieItemId)
7198 amar.kumar 3765
        freebie_text = freebie_text = "We have also shipped you " + item.brand + " " + item.modelName + "" + item.modelNumber +" as promised<br/>"
7190 amar.kumar 3766
    else:
3767
        freebie_orderId = get_order_attribute_value(order.id, "freebieOrderId")
3768
        if freebie_orderId != "":
3769
            line_items = get_line_items_for_order(int(freebie_orderId))
7198 amar.kumar 3770
            freebie_order = get_order(int(freebie_orderId))
3771
            freebie_text = freebie_text + "We wish to inform you that your freebie item " +line_items[0].brand + " " + line_items[0].model_name + " " + line_items[0].model_number + " will be sent as a separate order with OrderId : " + freebie_orderId + " and is expected to be delivered on " + freebie_order.expected_delivery_time.strftime("%A, %d %B %Y")+ "<br/>"
3772
        else:
3773
            freebie_text = ""
6655 rajveer 3774
 
7190 amar.kumar 3775
    info = dict(order_id = order.id, product_name = product, shipping_datetime = shipping_date, awb = order.airwaybill_no, expected_delivery_date = new_expected_delivery_date, courier_name = provider_name, courier_phone = provider_phone, source_name = source_name, otg_text = otg_text, freebie_text = freebie_text)
4885 varun.gupt 3776
    return Template(html).substitute(info)
4749 varun.gupt 3777
 
5832 rajveer 3778
def enqueue_shipping_confirmation_email(order):
4915 varun.gupt 3779
    # Calling helper service on production
3780
    helperClient = HelperClient(host_key = "helper_service_server_host_prod").get_client()
5832 rajveer 3781
    try:
3782
        emailSubject = 'Shipping Details for Order ID: ' + str(order.id)
3783
        emailBody = get_shipping_confirmation_email_body(order)
6906 rajveer 3784
        helperClient.saveUserEmailForSending([order.customer_email], None, emailSubject, emailBody, str(order.id), 'ShippingConfirmation', [], [])
6687 rajveer 3785
 
5832 rajveer 3786
    except Exception as e:
3787
        print e
5139 varun.gupt 3788
 
4915 varun.gupt 3789
def get_order_distribution_by_status(start_date, end_date):
5067 varun.gupt 3790
    query = session.query(Order.status, func.count(Order.id)).group_by(Order.status)
3791
    query = query.filter(Order.created_timestamp >= start_date)
3792
    query = query.filter(Order.created_timestamp <= end_date)
3793
    return query.all()
4915 varun.gupt 3794
 
5067 varun.gupt 3795
def get_order_ids_for_status(status, start_datetime, end_datetime):
3796
    query = Order.query.filter(Order.status == status)
3797
    query = query.filter(Order.created_timestamp >= start_datetime)
3798
    query = query.filter(Order.created_timestamp <= end_datetime)
3799
    return query.all()
3800
 
5099 varun.gupt 3801
def update_orders_as_paid_to_vendor(order_id):
5139 varun.gupt 3802
    paid_order = Order.get_by(id = order_id)
5099 varun.gupt 3803
 
5139 varun.gupt 3804
    if paid_order.originalOrderId is None:
3805
        paid_order.vendor_paid = True
5099 varun.gupt 3806
        session.commit()
5139 varun.gupt 3807
 
3808
        for order in Order.query.filter(Order.originalOrderId == order_id).all():
3809
            order.vendor_paid = True
3810
            session.commit()
3811
    else:
5208 varun.gupt 3812
        original_order_id = paid_order.originalOrderId
5139 varun.gupt 3813
 
5208 varun.gupt 3814
        for order in Order.query.filter(Order.originalOrderId == original_order_id).all():
5139 varun.gupt 3815
            order.vendor_paid = True
3816
            session.commit()
3817
 
3818
        original_order = Order.get_by(id = original_order_id)
3819
        if original_order:  original_order.vendor_paid = True
3820
        session.commit()
5348 anupam.sin 3821
 
3822
def update_COD_agent(agentEmailId, orderId):
3823
    order = Order.get_by(id=orderId)
3824
    if not order:
3825
        raise TransactionServiceException(101, "No order found for the given order id" + str(orderId))
3826
    agent = CodVerificationAgent()
3827
    agent.orderId = orderId
3828
    agent.verificationAgent = agentEmailId
3829
    session.commit()
3830
 
5099 varun.gupt 3831
 
5386 phani.kuma 3832
def update_order_only_as_paid_to_vendor(order_id):
3833
    paid_order = Order.get_by(id = order_id)
3834
    if paid_order is None:
3835
        raise TransactionServiceException(116, "No order found for the given order id")
3836
    paid_order.vendor_paid = True
3837
    session.commit()
3838
 
5208 varun.gupt 3839
def get_refunded_orders_marked_paid():
3840
    orderStatusGroup = OrderStatusGroups()
3841
    return Order.query.filter(Order.vendor_paid == 1).filter(Order.status.in_(orderStatusGroup.refundedOrders)).all()
3842
 
5447 anupam.sin 3843
def get_all_verification_agents(minOrderId, maxOrderId):
3844
    return CodVerificationAgent.query.filter(CodVerificationAgent.orderId >= minOrderId).filter(CodVerificationAgent.orderId <= maxOrderId).all()
3845
 
5527 anupam.sin 3846
def get_all_attributes_for_order_id(orderId):
3847
    return Attribute.query.filter(Attribute.orderId == orderId).all()
3848
 
3849
def set_order_attribute_for_transaction(transactionId, t_attribute):
3850
    for order in Order.query.filter_by(transaction_id = transactionId).all():
3851
        attribute = Attribute()
3852
        attribute.orderId = order.id
3853
        attribute.name = t_attribute.name
3854
        attribute.value = t_attribute.value
3855
        session.commit()
5593 mandeep.dh 3856
 
5558 mandeep.dh 3857
def accept_order_for_item(itemId, quantity, fulfilmentWarehouseId, billingWarehouseId):
5944 mandeep.dh 3858
    inventoryClient = InventoryClient().get_client()
3859
    inventory = inventoryClient.getItemInventoryByItemId(itemId)
5684 mandeep.dh 3860
    orders = Order.query.filter(Order.fulfilmentWarehouseId != fulfilmentWarehouseId).filter(Order.warehouse_id == billingWarehouseId).filter(Order.status.in_(tuple([OrderStatus.SUBMITTED_FOR_PROCESSING, OrderStatus.COD_VERIFICATION_PENDING, OrderStatus.ACCEPTED, OrderStatus.INVENTORY_LOW, OrderStatus.LOW_INV_PO_RAISED, OrderStatus.LOW_INV_REVERSAL_IN_PROCESS]))).order_by(Order.expected_shipping_time).all()
5558 mandeep.dh 3861
    for order in orders:
5593 mandeep.dh 3862
        lineitem = order.lineitems[0]
5558 mandeep.dh 3863
        if lineitem.item_id == itemId and lineitem.quantity <= quantity:
5944 mandeep.dh 3864
            warehouse = inventoryClient.getWarehouse(order.fulfilmentWarehouseId)
5684 mandeep.dh 3865
            if not warehouse.billingWarehouseId and warehouse.warehouseType == WarehouseType.THIRD_PARTY:
3866
                if (inventory.availability[fulfilmentWarehouseId] >= inventory.reserved[fulfilmentWarehouseId] + lineitem.quantity) and inventory.availability[order.fulfilmentWarehouseId] < inventory.reserved[order.fulfilmentWarehouseId]:
5966 rajveer 3867
                    inventoryClient.reduceReservationCount(itemId, order.fulfilmentWarehouseId, sourceId, order.id, lineitem.quantity)
3868
                    inventoryClient.reserveItemInWarehouse(itemId, fulfilmentWarehouseId, sourceId, order.id, to_java_date(order.created_timestamp), to_java_date(order.promised_shipping_time), lineitem.quantity)
5684 mandeep.dh 3869
                    order.fulfilmentWarehouseId = fulfilmentWarehouseId
5558 mandeep.dh 3870
                    quantity -= lineitem.quantity
5684 mandeep.dh 3871
                    session.commit()
5593 mandeep.dh 3872
                    if not quantity:
3873
                        break
5558 mandeep.dh 3874
 
6031 rajveer 3875
def get_recharge_order(rechargeOrderId):
6048 rajveer 3876
    return RechargeOrder.get_by(id = rechargeOrderId)
6031 rajveer 3877
 
3878
def get_recharge_orders(userId):
3879
    return RechargeOrder.query.filter_by(userId = userId).all()
3880
 
6279 rajveer 3881
def update_recharge_order_status(rechargeOrderId, rechargeOrderStatus, refundDate=None):
6031 rajveer 3882
    recharge_order = get_recharge_order(rechargeOrderId)
3883
    if rechargeOrderStatus == RechargeOrderStatus.PAYMENT_FAILED:
3884
        recharge_order.status = RechargeOrderStatus.PAYMENT_FAILED
3885
        session.commit()
3886
        return True
6214 rajveer 3887
 
3888
    if rechargeOrderStatus == RechargeOrderStatus.RECHARGE_FAILED:
3889
        recharge_order.status = RechargeOrderStatus.RECHARGE_FAILED
3890
        session.commit()
3891
        update_amount_in_wallet(recharge_order.userId, recharge_order.walletAmount, recharge_order.id)
6441 rajveer 3892
        update_amount_in_wallet(recharge_order.userId, recharge_order.totalAmount - recharge_order.walletAmount - recharge_order.couponAmount, recharge_order.id)
6214 rajveer 3893
        enqueue_recharge_info_email(recharge_order)
3894
        return True
3895
 
3896
    if rechargeOrderStatus == RechargeOrderStatus.RECHARGE_SUCCESSFUL:
3897
        recharge_order.status = RechargeOrderStatus.RECHARGE_SUCCESSFUL
6553 rajveer 3898
        recharge_order.invoiceNumber = get_next_invoice_number(OrderType.RECHARGE)
6214 rajveer 3899
        session.commit()
6285 rajveer 3900
        gvs = allocate_gift_voucher(recharge_order)
3901
        enqueue_recharge_info_email(recharge_order, gvs)
6214 rajveer 3902
        return True
3903
 
6279 rajveer 3904
    if rechargeOrderStatus == RechargeOrderStatus.RECHARGE_FAILED_REFUNDED:
3905
        recharge_order.status = RechargeOrderStatus.RECHARGE_FAILED_REFUNDED
3906
        order.responseTimestamp = refundDate
3907
        session.commit()
3908
        update_amount_in_wallet(recharge_order.userId, recharge_order.walletAmount, recharge_order.id)
6441 rajveer 3909
        update_amount_in_wallet(recharge_order.userId, recharge_order.totalAmount - recharge_order.walletAmount - recharge_order.couponAmount, recharge_order.id)
6279 rajveer 3910
        enqueue_recharge_info_email(recharge_order)
3911
        return True
3912
 
6031 rajveer 3913
    if rechargeOrderStatus == RechargeOrderStatus.PAYMENT_SUCCESSFUL:
6285 rajveer 3914
        gvs = {}
6206 rajveer 3915
        recharge_order.status = RechargeOrderStatus.PAYMENT_SUCCESSFUL
3916
        session.commit()
6031 rajveer 3917
        if recharge_order.walletAmount > 0:
3918
            wallet = get_user_wallet(recharge_order.userId)
3919
            if wallet and wallet.amount >= recharge_order.walletAmount:
3920
                update_amount_in_wallet(recharge_order.userId, -recharge_order.walletAmount, recharge_order.id)
3921
            else:
6441 rajveer 3922
                update_amount_in_wallet(recharge_order.userId, recharge_order.totalAmount - recharge_order.walletAmount - recharge_order.couponAmount, recharge_order.id)
6031 rajveer 3923
                raise TransactionServiceException(103, 'Wallet amount has already been used')
3924
 
6092 rajveer 3925
        try:
3926
            if activate_recharge_txn(recharge_order):
3927
                recharge_order.invoiceNumber = get_next_invoice_number(OrderType.RECHARGE)
3928
                session.commit()
6285 rajveer 3929
                gvs = allocate_gift_voucher(recharge_order)
6092 rajveer 3930
                return True
3931
            else:
3932
                update_amount_in_wallet(recharge_order.userId, recharge_order.walletAmount, recharge_order.id)
6441 rajveer 3933
                update_amount_in_wallet(recharge_order.userId, recharge_order.totalAmount - recharge_order.walletAmount - recharge_order.couponAmount, recharge_order.id)
6092 rajveer 3934
                session.commit()
3935
                return False
3936
        except:
3937
            transaction_requiring_extra_processing = TransactionRequiringExtraProcessing()
3938
            transaction_requiring_extra_processing.category = 'RECHARGE_UNKNOWN'
3939
            transaction_requiring_extra_processing.transaction_id = recharge_order.transaction_id
6031 rajveer 3940
            session.commit()
3941
            return False
6102 rajveer 3942
        finally:
6285 rajveer 3943
            enqueue_recharge_info_email(recharge_order, gvs)
6102 rajveer 3944
 
6031 rajveer 3945
 
6285 rajveer 3946
def allocate_gift_voucher(recharge_order):            
3947
    totalAmount = recharge_order.totalAmount
3948
    gvs = {}
6438 rajveer 3949
    return gvs
6330 rajveer 3950
    if totalAmount >= 100:
3951
        totalAmount=500 if totalAmount >= 500 else totalAmount
6285 rajveer 3952
        try:
3953
            pc = PromotionClient().get_client()
6330 rajveer 3954
            enddate = datetime.datetime.now() + datetime.timedelta(days=45)
6285 rajveer 3955
            while totalAmount > 0:
6330 rajveer 3956
                gvAmount = totalAmount if totalAmount <= 250 else 250
6285 rajveer 3957
                totalAmount = totalAmount - gvAmount
6561 amit.gupta 3958
                gv = pc.createCoupon(26, to_java_date(enddate), recharge_order.userEmailId, gvAmount, False, 1, None)
6285 rajveer 3959
                gvs[gv] = gvAmount  
3960
        except:
3961
            print "Not able to create gift voucher for user " + recharge_order.userEmailId
3962
    return gvs     
3963
 
6048 rajveer 3964
def activate_recharge_txn(recharge_order):
3965
    if isinstance(recharge_order, MobileRechargeOrder):
3966
        rechargeType = 'MTP'
3967
        deviceNumber = recharge_order.mobileNumber
3968
        strProviderCode = get_provider_code(recharge_order.mobileOperatorId)
6161 rajveer 3969
        plan = recharge_order.rechargePlan
6048 rajveer 3970
    if isinstance(recharge_order, DTHRechargeOrder):
3971
        rechargeType = 'RCH'
3972
        deviceNumber = recharge_order.dthAccountNumber
3973
        strProviderCode = get_provider_code(recharge_order.dthOperatorId)
6161 rajveer 3974
        plan = ''
7369 rajveer 3975
    retStatus, retCode, spiceTID, description, aggTID, providerTID = RechargeService.rechargeDevice(recharge_order.id, rechargeType, strProviderCode, deviceNumber, recharge_order.totalAmount, plan)
6231 rajveer 3976
    recharge_order.spiceTID = spiceTID
3977
    recharge_order.responseTimestamp = datetime.datetime.now()
3978
    recharge_order.description = description
3979
    session.commit()
6092 rajveer 3980
    if retCode == '00' and retStatus == 'S':
3981
        recharge_order.status = RechargeOrderStatus.RECHARGE_SUCCESSFUL
3982
        session.commit()
3983
        return True
6259 rajveer 3984
    elif retCode in ('STO', 'US', 'UP') and retStatus == 'S':
6231 rajveer 3985
        raise TransactionServiceException(111, "No response from operator within specified time")
6092 rajveer 3986
    else:
3987
        recharge_order.status = RechargeOrderStatus.RECHARGE_FAILED
6265 rajveer 3988
        if retCode in ('SVAI', 'SVIA', 'AI', 'IA', 'EAI', 'SVEAI'):
3989
            recharge_order.description = "Invalid Amount"
3990
        elif retCode in ('ECL', 'SVECL', 'SCL'):
3991
            recharge_order.description = "Customer Exceeded Daily Limit"
3992
        elif retCode in ('CI', 'ECI', 'ESP', 'SVCI', 'SVECI', 'SVESP', 'SV_ECI', 'SV ECI'):
6399 rajveer 3993
            recharge_order.description = "Invalid Device Number"
6092 rajveer 3994
        session.commit()
6048 rajveer 3995
        return False
6031 rajveer 3996
 
6092 rajveer 3997
 
6031 rajveer 3998
def get_user_wallet(userId):
3999
    wallet = UserWallet.get_by(userId = userId)
4000
    if not wallet:
4001
        wallet = UserWallet()
4002
        wallet.amount = 0
4003
        wallet.userId = userId
4004
    return wallet
4005
 
4006
def get_user_wallet_history(userId):
4007
    wallet = get_user_wallet(userId)
4008
    if wallet.id:
4009
        return UserWalletHistory.query.filter_by(wallet = wallet).all()
4010
    else:
4011
        return []
4012
 
6125 rajveer 4013
def get_provider(providerId):
4014
    return ServiceProvider.query.filter_by(id = providerId).one()
4015
 
6048 rajveer 4016
def get_provider_code(providerId):
4017
    return ServiceProvider.query.filter_by(id = providerId).one().code
6031 rajveer 4018
 
6310 anupam.sin 4019
def get_provider_by_code(providerCode):
4020
    return ServiceProvider.query.filter_by(code = providerCode).one()
6049 rajveer 4021
 
6206 rajveer 4022
def get_service_providers(recharge_type, only_active):
4023
    query = ServiceProvider.query.filter_by(type = recharge_type)
4024
    if only_active:
4025
        query = query.filter_by(status = only_active)
4026
    providers = query.all()
6048 rajveer 4027
    serviceProviders = {}
4028
    for provider in providers:
4029
        serviceProviders[provider.id] = provider.name
4030
    return serviceProviders
4031
 
6049 rajveer 4032
def get_service_provider_for_device(rechargeType, deviceNumber):
4033
    if rechargeType == RechargeType.MOBILE:
4034
        serviceType = 'MTP'
4035
    if rechargeType == RechargeType.DTH:
4036
        serviceType = 'RCH'
6048 rajveer 4037
 
6313 anupam.sin 4038
    provider = None
7120 rajveer 4039
    try:
4040
        series = OperatorSeries.get_by(series = int(deviceNumber))
4041
        if series:
7122 rajveer 4042
            providerId = series.operatorId
7120 rajveer 4043
            tc = TelecomCircle.get_by(id = series.circleId)
4044
            operatorCircle = tc.code
6092 rajveer 4045
        else:
7120 rajveer 4046
            l = len(deviceNumber)
4047
            if l < 10:
4048
                deviceNumber = deviceNumber + "0" * (10-l) 
4049
            providerCode, operatorCircle = RechargeService.checkServiceProviderApi(serviceType, deviceNumber)
4050
            if providerCode == 'SNS' or providerCode == '':
4051
                providerId = 0
4052
            else:
4053
                provider = get_provider_by_code(providerCode)
4054
                providerId = provider.id
6049 rajveer 4055
    except:
6092 rajveer 4056
        providerId = -1
6643 rajveer 4057
        operatorCircle = ""
6092 rajveer 4058
 
6289 anupam.sin 4059
    deviceNumberInfo = DeviceNumberInfo()
6336 anupam.sin 4060
    deviceNumberInfo.circleCode = operatorCircle
6289 anupam.sin 4061
    deviceNumberInfo.operatorId = providerId
6313 anupam.sin 4062
    if provider:
4063
        deviceNumberInfo.operatorName = provider.name
6289 anupam.sin 4064
    return deviceNumberInfo
6269 rajveer 4065
 
6591 anupam.sin 4066
def validate_recharge(rechargeType, deviceNumber, userSelectedProviderId, clientAddress):
4067
 
4068
    addressComponents = clientAddress.split('.')
4069
    n = 3
4070
    addressNumber = 0
4071
    for addressComponent in addressComponents :
4072
        addressNumber = addressNumber + (int(addressComponent) * pow(256, n))
4073
        n = n-1
4074
    matchingRow = BlockedIpRange.query.filter(BlockedIpRange.start <= addressNumber).filter(BlockedIpRange.end >= addressNumber).first()
4075
    #if a match is found then check if date has expired.
4076
    if matchingRow :
4077
        #if expiredOn is None that means this range is permanently blocked.
4078
        if matchingRow.expiredOn is None:
4079
            deniedIpAddress = DeniedIpAddress()
4080
            deniedIpAddress.ip = clientAddress
4081
            deniedIpAddress.deniedOn = datetime.datetime.now()
4082
            deniedIpAddress.deviceNumber = deviceNumber
4083
            deniedIpAddress.rechargeType = rechargeType
4084
            session.commit()
4085
            return "Oops! There seems to be a problem. Please try after some time."
4086
        else :
4087
            #if expired is not None and the blockage is still not expired then block the ip.
4088
            if matchingRow.expiredOn > datetime.datetime.now():
4089
                deniedIpAddress = DeniedIpAddress()
4090
                deniedIpAddress.ip = clientAddress
4091
                deniedIpAddress.deniedOn = datetime.datetime.now()
4092
                deniedIpAddress.deviceNumber = deviceNumber
4093
                deniedIpAddress.rechargeType = rechargeType
4094
                session.commit()
4095
                return "Oops! There seems to be a problem. Please try after some time."
4096
 
4097
 
6307 anupam.sin 4098
    deviceNumberInfo = get_service_provider_for_device(rechargeType, deviceNumber)
4099
    if deviceNumberInfo.operatorId == -1:
4100
        return "Oops! There seems to be a problem. Please try after some time."
6336 anupam.sin 4101
    circle = TelecomCircle.query.filter_by(code = deviceNumberInfo.circleCode).first()
6313 anupam.sin 4102
    if circle:
6734 anupam.sin 4103
        serviceAvailability = ServiceAvailability.query.filter_by(circleId = circle.id).filter_by(operatorId = userSelectedProviderId).first()
4104
        if serviceAvailability.permIsServiceAvailable == False or serviceAvailability.tempIsServiceAvailable == False :
4105
 
6313 anupam.sin 4106
            if deviceNumberInfo.operatorName :
6734 anupam.sin 4107
                if serviceAvailability.permIsServiceAvailable == False:
4108
                    return "We currently do not provide service for " + deviceNumberInfo.operatorName + " in " + circle.name + ". We regret the inconvenience."
6314 anupam.sin 4109
                else :
4110
                    return "We are facing technical issues with " + deviceNumberInfo.operatorName + " in " + circle.name + " currently. Please try later." 
6316 anupam.sin 4111
            else :
6734 anupam.sin 4112
                if serviceAvailability.permIsServiceAvailable == False:
4113
                    return "We currently do not provide service for this operator in " + circle.name + ". We regret the inconvenience."
4114
                else:
4115
                    return "We are facing technical issues with this operator in " + circle.name + " currently. Please try later." 
6719 anupam.sin 4116
    totalSuccessfulRechargeAmount = get_previous_transactions(clientAddress)
4117
    if totalSuccessfulRechargeAmount >= 3000 :
4118
        return "You have exceeded your daily recharge limit. Please try after 24 hours."
6269 rajveer 4119
    return "SUCCESS"
6049 rajveer 4120
 
6719 anupam.sin 4121
def get_previous_transactions(clientAddress):
6271 rajveer 4122
    limittime = datetime.datetime.now() - datetime.timedelta(hours=24)
6719 anupam.sin 4123
    totalSuccessfulRechargeAmount = session.query(func.sum(RechargeOrder.totalAmount)).filter(RechargeOrder.status == 5).filter(RechargeOrder.ipAddress == clientAddress).filter(RechargeOrder.creationTimestamp  > limittime).scalar()
4124
    return totalSuccessfulRechargeAmount    
6269 rajveer 4125
 
6031 rajveer 4126
def update_amount_in_wallet(userId, amount, orderId):
4127
    if amount == 0:
4128
        return
4129
    wallet = get_user_wallet(userId)
4130
    wallet.amount = wallet.amount + amount
4131
 
4132
    history = UserWalletHistory()
4133
    history.amount = amount
4134
    history.orderId = orderId
4135
    history.wallet = wallet
4136
    history.timestamp = datetime.datetime.now()
4137
    session.commit()
6056 amit.gupta 4138
 
6094 rajveer 4139
def get_recharge_orders_for_device(deviceNumber):
4140
    orders = MobileRechargeOrder.query.filter_by(mobileNumber = deviceNumber).all()
4141
    if orders is None:
4142
        orders = DTHRechargeOrder.query.filter_by(dthAccountNumber = deviceNumber).all()
4143
    return orders
4144
 
6154 rajveer 4145
def get_recharge_orders_for_status(status):
4146
    if status == -1:
6161 rajveer 4147
        orders = RechargeOrder.query.order_by(desc(RechargeOrder.id)).all()
6154 rajveer 4148
    else:
6161 rajveer 4149
        orders = RechargeOrder.query.order_by(desc(RechargeOrder.id)).filter_by(status = status).all()
6154 rajveer 4150
    return orders
4151
 
6188 rajveer 4152
def get_recharge_statistics():
4153
    rs = RechargeStatistics()
4154
    statusCounts = {}
4155
    operatorCounts = {}
4156
    currentOrders = {}
4157
    amounts = {}
4158
 
4159
    sorders = session.query(RechargeOrder.status, func.count(RechargeOrder.status)).group_by(RechargeOrder.status).all()
4160
    for sorder in sorders:
6190 rajveer 4161
        statusCounts[sorder[0]] = sorder[1]
6188 rajveer 4162
 
4163
    oorders = session.query(MobileRechargeOrder.mobileOperatorId, func.count(MobileRechargeOrder.mobileOperatorId)).group_by(MobileRechargeOrder.mobileOperatorId).all()
4164
    for oorder in oorders:
6190 rajveer 4165
        operatorCounts[oorder[0]] = oorder[1]
6188 rajveer 4166
 
4167
    oorders = session.query(DTHRechargeOrder.dthOperatorId, func.count(DTHRechargeOrder.dthOperatorId)).group_by(DTHRechargeOrder.dthOperatorId).all()
4168
    for oorder in oorders:
6190 rajveer 4169
        operatorCounts[oorder[0]] = oorder[1]
6188 rajveer 4170
 
6219 rajveer 4171
    forders = RechargeOrder.query.order_by(desc(RechargeOrder.id)).filter_by(status = RechargeOrderStatus.RECHARGE_FAILED).limit(20).all()
6188 rajveer 4172
    currentOrders[RechargeOrderStatus._VALUES_TO_NAMES.get(RechargeOrderStatus.RECHARGE_FAILED)] = [order.to_thrift_object() for order in forders]
4173
    sorders = RechargeOrder.query.order_by(desc(RechargeOrder.id)).filter_by(status = RechargeOrderStatus.RECHARGE_SUCCESSFUL).limit(20).all()
6197 rajveer 4174
    currentOrders[RechargeOrderStatus._VALUES_TO_NAMES.get(RechargeOrderStatus.RECHARGE_SUCCESSFUL)] = [order.to_thrift_object() for order in sorders]
6216 rajveer 4175
    porders = RechargeOrder.query.order_by(desc(RechargeOrder.id)).filter_by(status = RechargeOrderStatus.PAYMENT_SUCCESSFUL).limit(20).all()
4176
    currentOrders[RechargeOrderStatus._VALUES_TO_NAMES.get(RechargeOrderStatus.PAYMENT_SUCCESSFUL)] = [order.to_thrift_object() for order in porders]
6238 rajveer 4177
    rorders = RechargeOrder.query.order_by(desc(RechargeOrder.id)).filter_by(status = RechargeOrderStatus.RECHARGE_FAILED_REFUNDED).limit(20).all()
4178
    currentOrders[RechargeOrderStatus._VALUES_TO_NAMES.get(RechargeOrderStatus.RECHARGE_FAILED_REFUNDED)] = [order.to_thrift_object() for order in rorders]
6188 rajveer 4179
 
6190 rajveer 4180
    twa = session.query(func.sum(UserWallet.amount)).one()
4181
    tra = session.query(func.sum(RechargeOrder.totalAmount)).filter(RechargeOrder.status == RechargeOrderStatus.RECHARGE_SUCCESSFUL).one()
4182
    gwa = session.query(func.sum(UserWalletHistory.amount)).filter(UserWalletHistory.orderId > 100000).one()
6278 rajveer 4183
    #tpa = session.query(func.sum(UserWalletHistory.amount)).filter(UserWalletHistory.orderId < 100000).one()
6482 rajveer 4184
    tpa = session.query(func.sum(RechargeOrder.totalAmount-RechargeOrder.walletAmount-RechargeOrder.couponAmount)).filter(RechargeOrder.status.in_((RechargeOrderStatus.RECHARGE_SUCCESSFUL, RechargeOrderStatus.RECHARGE_FAILED, RechargeOrderStatus.PAYMENT_SUCCESSFUL, RechargeOrderStatus.RECHARGE_FAILED_REFUNDED))).one()
4185
    tda = session.query(func.sum(RechargeOrder.couponAmount)).filter(RechargeOrder.status == RechargeOrderStatus.RECHARGE_SUCCESSFUL).one()
4186
 
6346 rajveer 4187
    balance = RechargeService.getBalance()
6305 rajveer 4188
    amounts['(a) Total Payment Amount'] = tpa[0]
4189
    amounts['(b) Gift Wallet Amount'] = gwa[0]
4190
    amounts['(c) Total Wallet Amount'] = twa[0]
4191
    amounts['(d) Total Recharge Amount'] = tra[0]
4192
    amounts['(e) Account Balance'] = balance
6482 rajveer 4193
    amounts['(f) Discount Balance'] = tda[0]
6278 rajveer 4194
    #amounts['Total Payment Amount'] = tra[0] + twa[0] - gwa[0]
6524 rajveer 4195
    amounts['Saholic Mismatch = (a+b+f-c-d)'] = tpa[0] + gwa[0] + tda[0] - tra[0] - (twa[0] + 63774)
4196
    amounts['SpiceDeck Mismatch = (d-e)'] = tra[0] + balance - 750000 
6278 rajveer 4197
 
6337 rajveer 4198
    '''
6318 rajveer 4199
    if amounts['SpiceDeck Mismatch = (d-e)'] != -739:
4200
        mail(mail_user, mail_password, ['rajneesh.arora@shop2020.in', 'rajveer.singh@shop2020.in', 'anupam.singh@shop2020.in'], "SpiceDeck Account mismatch of amount " + str(amounts['SpiceDeck Mismatch = (d-e)']), "", [], [], [])
4201
    if amounts['Saholic Mismatch = (a+b-c-d)'] != -1919:
4202
        mail(mail_user, mail_password, ['rajneesh.arora@shop2020.in', 'rajveer.singh@shop2020.in', 'anupam.singh@shop2020.in'], "Saholic Recharge Account mismatch of amount " + str(amounts['Saholic Mismatch = (a+b-c-d)']), "", [], [], [])
6337 rajveer 4203
    '''
6318 rajveer 4204
 
6188 rajveer 4205
    rs.statusCounts = statusCounts
4206
    rs.operatorCounts = operatorCounts    
4207
    rs.currentOrders = currentOrders
4208
    rs.amounts = amounts
4209
 
4210
    return rs
4211
 
4212
 
6159 rajveer 4213
def get_plans_for_operator(operator_id):
4214
    return RechargePlan.query.filter_by(operatorId = operator_id).all()
4215
 
6056 amit.gupta 4216
def get_recharge_orders_for_transaction(txId):
4217
    return RechargeOrder.query.filter_by(transaction_id = txId).first()
6102 rajveer 4218
 
6285 rajveer 4219
def enqueue_recharge_info_email(recharge_order, gvs={}):
6102 rajveer 4220
    status = ""
4221
    message = ""
4222
    html_header = """
4223
 
4224
    <html>
4225
    <body>
4226
    <div>
4227
        <p>
4228
            Hello $email,<br /><br />
6127 rajveer 4229
            Thanks for placing recharge order with us. Following are the details of your recharge order:
6102 rajveer 4230
        </p>
4231
        <div>
6136 rajveer 4232
            Order Id : $order_id <br/>
4233
            Order Date : $order_date <br/>
4234
            Order Amount : Rs. $order_amount <br/>
4235
            Order Status : $order_status <br/>
4236
            Device Number : $device_number <br/>
4237
            Service Provider : $service_provider <br/>
6102 rajveer 4238
        </div>
6348 rajveer 4239
    <br />
6102 rajveer 4240
    """
6288 rajveer 4241
 
4242
    FailureReasonMap = {}
4243
    FailureReasonMap["Invalid Amount"] = "the amount you tried seems to be invalid. Please try another amount."
4244
    FailureReasonMap["Customer Exceeded Daily Limit"] = "you have exceeded daily recharge limit for this number. Please try after 12 hours."
6399 rajveer 4245
    FailureReasonMap["Invalid Device Number"] = "it seems that your device number is not being recognized by selected operator. Please make sure the number you tried is correct."
6288 rajveer 4246
 
4247
    failureReason = FailureReasonMap.get(recharge_order.description)
4248
    if failureReason is None:
4249
        failureReason = "of network failure."
6102 rajveer 4250
    if recharge_order.status == RechargeOrderStatus.RECHARGE_SUCCESSFUL:
4251
        status = "Recharge Successful"
4252
        message = ""
6444 rajveer 4253
        if recharge_order.couponAmount > 0:
4254
            message = message + "<b>You have used coupon " + recharge_order.couponCode + " and got discount of Rs. " + str(recharge_order.couponAmount) + ".</b>" 
4255
 
6102 rajveer 4256
    elif recharge_order.status == RechargeOrderStatus.RECHARGE_FAILED:
4257
        status = "Recharge Failed"
6127 rajveer 4258
        message = """
6288 rajveer 4259
                We could not process your recharge because $failureReason We have credited the amount to your recharge wallet. You can use wallet amount to recharge again. <a href="$source_url/static/recharge-faq">Learn More</a>
6127 rajveer 4260
                """
6206 rajveer 4261
    elif recharge_order.status == RechargeOrderStatus.PAYMENT_SUCCESSFUL:
6102 rajveer 4262
        status = "Recharge Under Process"
6127 rajveer 4263
        message = """
6288 rajveer 4264
                Your Payment was successful but due to some internal error with the operator's system we are not sure if the recharge was successful. In case your recharge is not processed, we will credit amount to your recharge wallet. You can use wallet amount to recharge again. <a href="$source_url/static/recharge-faq">Learn More</a>
6127 rajveer 4265
                """
6279 rajveer 4266
    elif recharge_order.status == RechargeOrderStatus.RECHARGE_FAILED_REFUNDED:
4267
        status = "Recharge Failed, Amount Refunded"
4268
        message = """
4269
                It seems operator could not process your recharge request. We are crediting the refund amount to your recharge wallet. You can use wallet amount to recharge again. <a href="$source_url/static/recharge-faq">Learn More</a>
4270
                """
6285 rajveer 4271
    if len(gvs) > 0:
6340 rajveer 4272
        message = message  + '<br />  You have been awarded with following Gift Voucher(s). You can redeem Gift Voucher(s) to purchase any product for Rs. 5000 and above using credit/debit card and net banking. <a href="$source_url/static/giftvoucher-offer">More details</a>'
6330 rajveer 4273
        message = message + " <br />  <b>Voucher Code &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Amount</b>"
6285 rajveer 4274
        for gv in gvs.keys():
4275
            gvAmount = gvs.get(gv)
6330 rajveer 4276
            message = message + " <br />  <b>" + gv + "&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Rs. "  + str(gvAmount) + "</b>"
6285 rajveer 4277
 
6114 rajveer 4278
    message = message  + '<br />  In case of any problem, please  <a href="$source_url/contact-us">contact us</a>'
6102 rajveer 4279
 
6136 rajveer 4280
    html_header = html_header + message
6102 rajveer 4281
    html_footer = """
4282
    <p>
4283
        Best Wishes,<br />
4284
        $source_name Team
4285
    </p>
4286
    </div>
4287
    </body>
4288
    </html>
4289
    """
4290
 
6125 rajveer 4291
    if isinstance(recharge_order, MobileRechargeOrder):
4292
        deviceNumber = recharge_order.mobileNumber
4293
        providerName = get_provider(recharge_order.mobileOperatorId).name
4294
    if isinstance(recharge_order, DTHRechargeOrder):
4295
        deviceNumber = recharge_order.dthAccountNumber
4296
        providerName = get_provider(recharge_order.dthOperatorId).name
4297
 
6127 rajveer 4298
    display_order_id = recharge_order.idPrefix + str(recharge_order.id)
6102 rajveer 4299
    email = recharge_order.userEmailId
4300
    dt = datetime.datetime.strptime(str(recharge_order.creationTimestamp), "%Y-%m-%d %H:%M:%S")
4301
    formated_order_date = dt.strftime("%A, %d. %B %Y %I:%M%p")
4302
 
6288 rajveer 4303
    email_header = Template(html_header).substitute(dict(order_id = display_order_id, order_date = formated_order_date, email = email, source_url = source_url, order_amount = recharge_order.totalAmount, order_status = status, device_number = deviceNumber, service_provider = providerName, failureReason = failureReason))
6102 rajveer 4304
    email_footer = Template(html_footer).substitute(dict(source_url = source_url, source_name = source_name))
4305
 
4306
    try:
4307
        helper_client = HelperClient().get_client()
6906 rajveer 4308
        helper_client.saveUserEmailForSending([email], "", source_name + " - Recharge Order Details", email_header + email_footer, str(recharge_order.id), "RechargeInfo", [], [])
6102 rajveer 4309
        return True
4310
    except Exception as e:
4311
        print e
4312
        return False
4313
 
6307 anupam.sin 4314
def get_recharge_denominations(operator_id, circleCode, denomination_type):
4315
    circle_id = TelecomCircle.query.filter_by(code = circleCode).first().id
6289 anupam.sin 4316
    return RechargeDenomination.query.filter_by(operatorId = operator_id).filter_by(circleId = circle_id).filter_by(denominationType = denomination_type).all()
6371 rajveer 4317
 
4318
def update_availability_status(operatorId, circleId, isAvailable):
4319
    serviceAvailability = ServiceAvailability.query.filter_by(circleId = circleId).filter_by(operatorId = operatorId).first()
6734 anupam.sin 4320
    serviceAvailability.tempIsServiceAvailable = isAvailable
6371 rajveer 4321
    session.commit()
4322
 
6389 rajveer 4323
def get_misc_charges(transactionId):
4324
    retCharges = {}
4325
    miscCharges = MiscCharges.get_by(transaction_id = transactionId)
4326
    if miscCharges:
6426 rajveer 4327
        retCharges[1] = miscCharges.chargeAmount 
6389 rajveer 4328
    return retCharges
6396 amit.gupta 4329
 
4330
def get_available_emi_schemes():
4331
    t_emi_schemes = []
4332
    emi_schemes = EmiScheme.query.all()
4333
    if emi_schemes:
4334
        t_emi_schemes = [to_t_emi_scheme(emi_scheme) for emi_scheme in emi_schemes]
4335
    return t_emi_schemes
6389 rajveer 4336
 
6507 anupam.sin 4337
def refund_recharge_order(rechargeOrderId):
4338
    try :
4339
        rechargeOrder = RechargeOrder.query.filter_by(id = rechargeOrderId).first()
4340
        wallet = UserWallet.query.filter_by(userId = rechargeOrder.userId).first()
4341
    except:
4342
        return False
4343
 
4344
    paidAmount = rechargeOrder.totalAmount - rechargeOrder.walletAmount - rechargeOrder.couponAmount
4345
    amountToRefund = 0
4346
    status = None
4347
    if (paidAmount <= wallet.amount) :
4348
        amountToRefund = paidAmount
4349
        status = RechargeOrderStatus.REFUNDED
4350
    else :
4351
        amountToRefund = wallet.amount
4352
        status = RechargeOrderStatus.PARTIALLY_REFUNDED
4353
 
4354
    update_amount_in_wallet(rechargeOrder.userId, -amountToRefund, rechargeOrderId)
4355
 
4356
    try:    
4357
        pc = PaymentClient().get_client()
4358
        if pc.refundPayment(rechargeOrder.transaction_id, amountToRefund, True) :
4359
            rechargeOrder.status = status
6515 anupam.sin 4360
            rechargeOrder.refundTimestamp = datetime.datetime.now()
6507 anupam.sin 4361
            session.commit()
4362
            return True
4363
        else :
4364
            update_amount_in_wallet(rechargeOrder.userId, amountToRefund, rechargeOrderId)
4365
 
4366
    except:
4367
        update_amount_in_wallet(rechargeOrder.userId, amountToRefund, rechargeOrderId)
4368
 
4369
    return False 
4370
 
6821 amar.kumar 4371
def get_physical_orders(from_date, to_date):
4372
    query = Order.query.filter(Order.created_timestamp >from_date).filter(Order.created_timestamp < to_date).filter(Order.status>=2)
4373
    return query.all()
4374
 
6507 anupam.sin 4375
 
766 rajveer 4376
def close_session():
4377
    if session.is_active:
4378
        print "session is active. closing it."
2783 chandransh 4379
        session.close()
3376 rajveer 4380
 
4381
def is_alive():
4382
    try:
4383
        session.query(Transaction.id).limit(1).one()
4384
        return True
4385
    except:
6000 mandeep.dh 4386
        return False
4387
 
6906 rajveer 4388
def get_document(docType, docSource):
4389
    document = DocumentStore.get_by(docType = docType, docSource = docSource)
4390
    if document:
4391
        return document.document
4392
    else:
7040 amar.kumar 4393
        return bin(0)
6906 rajveer 4394
 
7075 rajveer 4395
def retrieve_invoice(orderId, userId):
4396
    order = get_order(orderId)
4397
    if order.customer_id != userId:
4398
        return bin(0)
6988 rajveer 4399
    strOrderId = '0'*(10-len(str(orderId)))+str(orderId)
7072 rajveer 4400
    filename = "/SaholicInvoices/" + strOrderId[0:2] + "/" + strOrderId[2:4] + "/" + strOrderId[4:6] + "/" + str(orderId) + ".pdf"  
6988 rajveer 4401
    file = open(filename, "rb")
4402
    pdfFile = file.read()
4403
    return pdfFile
4404
 
6906 rajveer 4405
def myFirstPage(canvas, doc):
4406
    canvas.saveState()
6916 anupam.sin 4407
    canvas.setTitle("Theft-Insurance-Policy")
6906 rajveer 4408
    canvas.restoreState()
4409
 
4410
 
4411
def __generate_policy_doc(order, filename):
6903 anupam.sin 4412
    PAGE_HEIGHT=defaultPageSize[1]; PAGE_WIDTH=defaultPageSize[0]
4413
    styles = getSampleStyleSheet()
4414
    styles.add(ParagraphStyle(name='left', leftIndent=12,fontSize=11), alias='li')
4415
    styles.add(ParagraphStyle(name='bullet', bulletIndent=24, leftIndent=24), alias='bull')
6916 anupam.sin 4416
    styles.add(ParagraphStyle(name='insurerName', alignment=TA_CENTER, fontName="Times-Bold", fontSize=16), alias='iN')
4417
    styles.add(ParagraphStyle(name='insurerAdd', alignment=TA_CENTER, fontName="Helvetica",leading=15, fontSize=12), alias='iA')
4418
    styles.add(ParagraphStyle(name='subHeading', alignment=TA_CENTER, fontName="Helvetica", fontSize=13), alias='sH')
6903 anupam.sin 4419
 
6914 rajveer 4420
    invoiceNumber = str(order.invoice_number)
6906 rajveer 4421
    billing_timestamp = str(order.billing_timestamp.date()) 
6903 anupam.sin 4422
 
6906 rajveer 4423
    doc = SimpleDocTemplate(filename)
6916 anupam.sin 4424
    Story = [Spacer(0, 0)]
6903 anupam.sin 4425
    style = styles["Normal"]
6916 anupam.sin 4426
 
4427
 
4428
    file_name = os.path.dirname(os.path.realpath(__file__)) + '/../resources/nia-logo.jpg'
4429
    image = Image(file_name, width=100, height=100)
4430
    Story.append(image)
4431
    Story.append(Spacer(1,0.2*inch))
4432
 
4433
    text = ("""<u>The New India Assurance Company Limited</u>""") 
4434
    p = Paragraph(text, styles['insurerName'])
4435
    Story.append(p)
4436
    Story.append(Spacer(1,0.2*inch))
4437
 
4438
    text = ("""DO-IX, 35/1, Fortune Park, 1st Floor, Park Road, Tasker Town, Shivajinagar, Bangalore  560051""") 
4439
    p = Paragraph(text, styles['insurerAdd'])
4440
    Story.append(p)
4441
    Story.append(Spacer(1,0.3*inch))
4442
 
4443
    text = ("""MOBILE HAND SET INSURANCE – THEFT & BURGLARY RISKS ONLY""")
4444
    p = Paragraph(text, styles['subHeading'])
4445
    Story.append(p)
4446
    Story.append(Spacer(1,1*inch))
4447
 
6903 anupam.sin 4448
    text = ("""<u><b>Subject Matter Of Insurance</b></u> : <i>New Mobile Handsets</i> alone and <i>Tablets with 'Voice Calls'</i> only. 
4449
    Sold 'online' by <b>Spice Online Retail Private Limited, New Delhi</b>, to its customers.""") 
4450
    p = Paragraph(text, style)
4451
    Story.append(p)
4452
    Story.append(Spacer(1,0.2*inch))
4453
    text = ("""Insurer will indemnify the Insured in the event of Theft/Burglary of <i>Mobile Handsets</i> 
6914 rajveer 4454
    alone and <i>Tablets with 'Voice Calls'</i> only sold as per Invoice No. %s
6903 anupam.sin 4455
    dated %s and insured with THE NEW INDIA ASSURANCE COMPANY LIMITED, BANGALORE, as per Policy No. 671700/46/12/2400000008,  
4456
    for a period of 12 months from the date and time of delivery of Mobile Handset to the customer.""" % (invoiceNumber, billing_timestamp)) 
4457
    p = Paragraph(text, style)
4458
    Story.append(p)
4459
    Story.append(Spacer(1,0.2*inch))
4460
    text = ("""<b>WARRANTY</b> -  Warranted that the Mobile Handset sold during the Policy Period of 25/02/2013 to 24/02/2014
4461
             are only covered irrespective of date of delivery to the customer""")
4462
    p = Paragraph(text, style)
4463
    Story.append(p)
4464
    Story.append(Spacer(1,0.2*inch))
6915 anupam.sin 4465
    text = ("<b>INSURER</b> -The New India Assurance company limited.")
6903 anupam.sin 4466
    p = Paragraph(text, style)
4467
    Story.append(p)
4468
    Story.append(Spacer(1,0.2*inch))
4469
    text = ("<b>INSURED</b> - Purchaser of the Mobile Handset OR his/her spouse or children. If the Purchaser is a ‘Company’, user is the duly authorised person.") 
4470
    p = Paragraph(text, style)
4471
    Story.append(p)
4472
    Story.append(Spacer(1,0.2*inch))
4473
    text = ("<b>GEOGRAPHICAL LIMIT</b> – World-wide") 
4474
    p = Paragraph(text, style)
4475
    Story.append(p)
4476
    Story.append(Spacer(1,0.2*inch))
4477
    text = ("<b>RISK COVERAGE</b> – Theft and/or burglary only") 
4478
    p = Paragraph(text, style)
4479
    Story.append(p)
6916 anupam.sin 4480
    Story.append(Spacer(1,0.4*inch))
6915 anupam.sin 4481
    text = ("Terms and Conditions of Insurance:") 
4482
    p = Paragraph(text, styles["h2"])
4483
    Story.append(p)
4484
    Story.append(Spacer(1,0.1*inch))
4485
    text = ("""Insurance Premium paid will not be refunded.""")
4486
    p = Paragraph(text, styles["bullet"], bulletText='\xe2\x80\xa2')
4487
    Story.append(p)
4488
    Story.append(Spacer(1,0.1*inch))
6921 anupam.sin 4489
    text = ("""Claims will be settled by UIB on behalf of The New India Assurance Co. Ltd.<br></br>
4490
            Saholic.com will not be responsible for claim approval and disbursement.""")
4491
    p = Paragraph(text, styles["bullet"], bulletText='\xe2\x80\xa2')
4492
    Story.append(p)
4493
    Story.append(Spacer(1,0.1*inch))
6915 anupam.sin 4494
    text = ("""Insurance will be invalidated for returned products.""")
4495
    p = Paragraph(text, styles["bullet"], bulletText='\xe2\x80\xa2')
4496
    Story.append(p)
6921 anupam.sin 4497
    Story.append(Spacer(1,0.3*inch))
6903 anupam.sin 4498
    text = ("Exclusions:") 
4499
    p = Paragraph(text, styles["h2"])
4500
    Story.append(p)
4501
    Story.append(Spacer(1,0.1*inch))
4502
    text = ("Insurer is not liable") 
4503
    p = Paragraph(text, styles["left"])
4504
    Story.append(p)
4505
    Story.append(Spacer(1,0.1*inch))
4506
    text = ("If the handset is not connected to Mobile Service Provider Network")
4507
    p = Paragraph(text, styles["bullet"], bulletText='\xe2\x80\xa2')
4508
    Story.append(p)
4509
    Story.append(Spacer(1,0.1*inch))
4510
    text = ("Caused by incorrect storage, poor care and maintenance, careless use, negligence.")
4511
    p = Paragraph(text, styles["bullet"], bulletText='\xe2\x80\xa2')
4512
    Story.append(p)
4513
    Story.append(Spacer(1,0.1*inch))
4514
    text = ("Due to mysterious disappearance, forgotten or misplaced or Lost or if handset is left unattended at any point of time.")
4515
    p = Paragraph(text, styles["bullet"], bulletText='\xe2\x80\xa2')
4516
    Story.append(p)
4517
    Story.append(Spacer(1,0.1*inch))
4518
    text = ("Caused by war, war like operation, act of foreign enemy, civil war, rebellion, civil commotion, military usurped power, seizure, capture, confiscation, arrests, restrains and detainment by order of any Government or any other Authority.")
4519
    p = Paragraph(text, styles["bullet"], bulletText='\xe2\x80\xa2')
4520
    Story.append(p)
4521
    Story.append(Spacer(1,0.1*inch))
4522
    text = ("Caused whilst engaging in criminal acts.")
4523
    p = Paragraph(text, styles["bullet"], bulletText='\xe2\x80\xa2')
4524
    Story.append(p)
4525
    Story.append(Spacer(1,0.1*inch))
4526
    text = ("Caused by consequential loss or damage of whatsoever nature or any costs incurred in connection with claim under this policy, including postage, transit costs and reconnection cost.")
4527
    p = Paragraph(text, styles["bullet"], bulletText='\xe2\x80\xa2')
4528
    Story.append(p)
4529
    Story.append(Spacer(1,0.1*inch))
4530
    text = ("Loss of mobile handset due to theft from an unattended vehicle unless the vehicle is of  fully enclosed saloon type having at time all the doors/windows and other opening securely locked and properly fastened.")
4531
    p = Paragraph(text, styles["bullet"], bulletText='\xe2\x80\xa2')
4532
    Story.append(p)
4533
    Story.append(Spacer(1,0.1*inch))
4534
    text = ("Loss of mobile handset due to theft from the building unless there is visible forcible entry/exit into/from the building.")
4535
    p = Paragraph(text, styles["bullet"], bulletText='\xe2\x80\xa2')
4536
    Story.append(p)
4537
    Story.append(Spacer(1,0.1*inch))
4538
    text = ("If the documents are found to be tampered; non-disclosure of material fact, fraud/misrepresentation.")
4539
    p = Paragraph(text, styles["bullet"], bulletText='\xe2\x80\xa2')
4540
    Story.append(p)
4541
    Story.append(Spacer(1,0.1*inch))
4542
    text = ("The policy is not transferable.")
4543
    p = Paragraph(text, styles["bullet"], bulletText='\xe2\x80\xa2')
4544
    Story.append(p)
4545
    Story.append(Spacer(1,0.2*inch))
4546
 
4547
    text = ("Claim Procedure:") 
4548
    p = Paragraph(text, styles["h2"])
4549
    Story.append(p)
4550
    Story.append(Spacer(1,0.1*inch))
4551
    text = ("""For Theft or Burglary of the handset immediate intimation to be given
4552
     to the police within 48 hours of occurrence of incident and proper documents to be obtained 
4553
     and inform the service provider within 48 hours about theft of handset in order to block the SIM services.""")
4554
    p = Paragraph(text, styles["bullet"], bulletText='\xe2\x80\xa2')
4555
    Story.append(p)
4556
    Story.append(Spacer(1,0.1*inch))
4557
    text = ("""To intimate Insurance Company about the loss of Mobile Handset within 48 hours 
6915 anupam.sin 4558
     through Call Centre No.022-49107910 OR through e-mail <u>saholic.claims@universalinsurance.co.in</u> OR through 
6903 anupam.sin 4559
     written communication to <i>Universal Insurance brokers (UIB) No.304, Commerce House, 9/1,Cunningham Road, Bangalore – 560052</i>.""")
4560
    p = Paragraph(text, styles["bullet"], bulletText='\xe2\x80\xa2')
4561
    Story.append(p)
4562
    Story.append(Spacer(1,0.1*inch))
6915 anupam.sin 4563
    text = ("""Claim documents can be downloaded through UIB Website <u>http://www.universalinsurance.co.in/mobileinsurance/claiminfo.html</u>
4564
    <br></br>To know or track your claim please contact Call Centre No. 022-49107910 of Universal Insurance brokers (UIB). """)
6903 anupam.sin 4565
    p = Paragraph(text, styles["bullet"], bulletText='\xe2\x80\xa2')
4566
    Story.append(p)
4567
    Story.append(Spacer(1,0.1*inch))
4568
    text = ("""All the completed claim documents to reach ‘Universal Insurance Brokers (UIB)’ office 
4569
    at <i>No.304, Commerce House, 9/1, Cunningham Road, Bangalore – 560052</i> <b>within 21 days</b>.""")
4570
    p = Paragraph(text, styles["bullet"], bulletText='\xe2\x80\xa2')
4571
    Story.append(p)
4572
    Story.append(Spacer(1,0.2*inch))
4573
 
4574
 
4575
    text = ("Excess(Minimum Deduction):") 
4576
    p = Paragraph(text, styles["h2"])
4577
    Story.append(p)
4578
    Story.append(Spacer(1,0.1*inch))
4579
    text = ("""The excess will be 5% of the value of each claim subject to a minimum of Rs.500/-""")
4580
    p = Paragraph(text, styles["left"])
4581
    Story.append(p)
4582
    Story.append(Spacer(1,0.2*inch))
4583
 
4584
    text = ("Depreciation:") 
4585
    p = Paragraph(text, styles["h2"])
4586
    Story.append(p)
4587
    Story.append(Spacer(1,0.1*inch))
4588
 
4589
    text = ("For 0 – 60 days, 15%")
4590
    p = Paragraph(text, styles["bullet"], bulletText='\xe2\x80\xa2')
4591
    Story.append(p)
4592
    Story.append(Spacer(1,0.1*inch))
4593
 
4594
    text = ("61-150 days, 30%")
4595
    p = Paragraph(text, styles["bullet"], bulletText='\xe2\x80\xa2')
4596
    Story.append(p)
4597
    Story.append(Spacer(1,0.1*inch))
4598
 
4599
    text = ("151 – 365 days, 45%")
4600
    p = Paragraph(text, styles["bullet"], bulletText='\xe2\x80\xa2')
4601
    Story.append(p)
4602
    Story.append(Spacer(1,0.4*inch))
4603
 
4604
    text = ("<i>Insurance is a subject matter of solicitation.</i>")
4605
    p = Paragraph(text, style)
4606
    Story.append(p)
4607
    Story.append(Spacer(1,0.2*inch))
4608
 
6906 rajveer 4609
    doc.build(Story, onFirstPage=myFirstPage)
6980 anupam.sin 4610
 
4611
def drawLine(Story, style):
4612
    Story.append(Paragraph('-'*40, style))
6915 anupam.sin 4613
 
6980 anupam.sin 4614
def generateHotSpotInvoice():
4615
 
4616
    ##########TO BE PASSED TO THIS METHOD####################################
4617
    #########################################################################
4618
    filename = "/home/anupam/test.pdf"                             ##########
4619
    itemCode = "SPICEMI450WHT"                                     ##########
4620
    lotNumber = "12345678901234"                                   ##########
4621
    itemName = "Spice Stellar Craze Mi-450 White"                  ##########
4622
    qty = 1                                                        ##########
4623
    unitPrice = 3099.50                                            ##########
4624
    vat = 310.23                                                   ##########
4625
    billingTime = datetime.datetime.now()                          ##########
4626
    invNum = "885182994"                                           ##########
4627
    counter = 1                                                    ##########
4628
    ourInvoiceNum = "209809"                                       ##########
4629
    customerId = "12345678909"                                     ##########
4630
    customerName = "ANUPAM PRATAP SINGH"                           ##########
4631
    telNum = ""                                                    ##########
4632
    #########################################################################
4633
 
4634
    PAGE_HEIGHT=defaultPageSize[1];
4635
    styles = getSampleStyleSheet()
4636
    styles.add(ParagraphStyle(name='prologue', alignment=TA_CENTER, fontName="Courier", rightIndent = 5, fontSize=10), alias='sH')
4637
    styles.add(ParagraphStyle(name='text', alignment=TA_JUSTIFY, fontName="Courier", fontSize=10), alias='text')
4638
    styles.add(ParagraphStyle(name='line', alignment=TA_CENTER, fontName="Courier", fontSize=10), alias='line')
4639
    styles.add(ParagraphStyle(name='epilogue', alignment=TA_CENTER, fontName="Courier", leftIndent = 30, rightIndent=36, fontSize=10), alias='ep')
4640
 
4641
    Story = []
4642
    prologueStyle = styles["prologue"]
4643
    lineStyle = styles["line"]
4644
    textStyle = styles["text"]
4645
    epilogueStyle = styles["epilogue"]
4646
 
4647
    doc = BaseDocTemplate(filename,showBoundary=0)
4648
 
4649
    #Two Columns
4650
    frame1 = Frame(58, doc.bottomMargin, doc.width/2 + 25, doc.height + 7, id='col1')
4651
 
4652
 
4653
 
4654
    Story.append(Paragraph("""Spice Retail Limited<br></br>
4655
        C/O,PIBCO LIMITED,Basement,Punjsons<br></br>
4656
        2,Kalkaji Industrial Area,New Delhi<br></br>
4657
          .<br></br>
4658
        TIN NO. 07430284979<br></br>
4659
        Service Tax No:AAACM0294PST001<br></br>
4660
        D U P L I C A T E<br></br>
4661
        I N V O I C E<br></br>""", prologueStyle))
4662
    drawLine(Story, lineStyle)
4663
 
4664
    Story.append(Paragraph('{0:7s}{1:>11s}{2:  %d/%m/%Y  %H:%M:%S}'.format("INV NO:", invNum, billingTime).replace(" ", "&nbsp;"), textStyle))
4665
    Story.append(Paragraph("{0:8s}{1:>5d}{2:>11s}{3:>11s}".format('COUNTER:', counter, "CASHIER:", "SUPERADMIN").replace(" ", "&nbsp;"), textStyle))
4666
    Story.append(Paragraph("MN INV NO&amp;DT: {0:<13s}{1:%d/%m/%Y}   ".format(ourInvoiceNum, billingTime).replace(" ", "&nbsp;"), textStyle))
4667
    drawLine(Story, lineStyle)
4668
 
4669
    Story.append(Paragraph("{0:<13s}{1:<27s}".format("CUSTOMER ID:", customerId).replace(" ", "&nbsp;"), textStyle))
4670
    Story.append(Paragraph("{0:<6s}{1:<34s}".format("NAME:", customerName + " " + ourInvoiceNum).replace(" ", "&nbsp;"), textStyle))
4671
    Story.append(Paragraph("{0:<9s}{1:<31s}".format("TEL NO.:", telNum).replace(" ", "&nbsp;"), textStyle))
4672
    drawLine(Story, lineStyle)
4673
 
4674
    Story.append(Paragraph("ITEM" + "&nbsp;"*12 + "LOT NUMBER<br></br>" + \
4675
                            "&nbsp;ITEM NAME<br></br>" + \
4676
                            "&nbsp;"*5 + "QTY" + "&nbsp;"*21 + "AMOUNT(INR)", textStyle))
4677
    drawLine(Story, lineStyle)
4678
 
4679
    Story.append(Paragraph(('{0:<16s}{1:24s}').format(itemCode, lotNumber).replace(' ', '&nbsp;'),textStyle))
4680
    Story.append(Paragraph((' {0:<39s}').format(itemName).replace(' ', '&nbsp;'),textStyle))
4681
    Story.append(Paragraph(('{0:<3d}{1:>10s}{2:13.2f}{3:14.2f}').format(qty, 'PCS', unitPrice, qty*unitPrice).replace(' ', '&nbsp;'),textStyle))
4682
    Story.append(Paragraph(('{0:<3s}{1:37.2f}').format("VAT", vat).replace(' ', '&nbsp;'),textStyle))
4683
    Story.append(Paragraph(('{0:<10s}{1:30.2f}').format("ITEM TOTAL", vat + unitPrice*qty).replace(' ', '&nbsp;'),textStyle))
4684
 
4685
    drawLine(Story, lineStyle)
4686
    Story.append(Paragraph(('{0:13s}{1:>12s}{2:15.2f}').format("GROSS TOTAL:","INR", vat + unitPrice*qty).replace(' ', '&nbsp;'),textStyle))
4687
    drawLine(Story, lineStyle)
4688
 
4689
    Story.append(Paragraph(('{0:13s}{1:>12s}{2:15.2f}').format("NET TOTAL:","INR", vat + unitPrice*qty).replace(' ', '&nbsp;'),textStyle))
4690
    Story.append(Paragraph(('{0:13s}{1:>12s}{2:15.2f}').format("NET VAT:","INR", vat).replace(' ', '&nbsp;'),textStyle))
4691
    drawLine(Story, lineStyle)
4692
 
4693
    Story.append(Paragraph(('{0:13s}{1:>12s}{2:15.2f}').format("SPICE ONLINE:","INR", vat + unitPrice*qty).replace(' ', '&nbsp;'),textStyle))
4694
    drawLine(Story, lineStyle)
4695
 
4696
    Story.append(Paragraph(('{0:16s}{1:>4d}').format("NUMBER OF ITEMS:",qty,).replace(' ', '&nbsp;'),textStyle))
4697
    Story.append(Paragraph(('{0:16s}{1:>9.6f}').format("TOTAL ITEMS    :",qty,).replace(' ', '&nbsp;'),textStyle))
4698
 
4699
    Story.append(Paragraph("Goods once Sold Will not be taken back.<br></br>All Disputes subject to Delhi Jurisdiction",epilogueStyle))
4700
 
4701
 
4702
    doc.addPageTemplates([PageTemplate(id='TwoCol',frames=[frame1]), ])
4703
 
4704
    #start the construction of the pdf
4705
    doc.build(Story)
4706
 
6985 anupam.sin 4707
def change_shipping_address(orderId, line1, line2, city, state, pin):
4708
    order = Order.get_by(id = orderId)
4709
    if order:
4710
        order.customer_address1 = line1
4711
        order.customer_address2 = line2
4712
        order.customer_city = city
4713
        order.customer_state = state
7364 manish.sha 4714
 
4715
        # Start:- Added/Modified by Manish Sharma on 13 May 2013 for Change Shipping Address functionality
4716
        if order.customer_pincode != pin :
4717
            type = DeliveryType.PREPAID
4718
            if order.cod:
4719
                type = DeliveryType.COD
4720
            logistics_client = LogisticsClient().get_client()
4721
            logistics_info = logistics_client.getLogisticsEstimation(order.lineitems[0].item_id, pin, type)
4722
 
4723
            # Check for new estimate. Raise exception if new address is not serviceable
4724
            if logistics_info.deliveryTime == -1:
4725
                raise TransactionServiceException(1, 'Location not serviceable')
4726
 
4727
            # COD services are not available everywhere
4728
            if order.cod:
4729
                if not logistics_info.codAllowed:
4730
                    raise TransactionServiceException(2, 'COD service not available')
4731
 
4732
            logistics_info_new = logistics_client.getLogisticsInfo(pin, order.lineitems[0].item_id, type, PickUpType.COURIER)
4733
            order.tracking_id = logistics_info_new.airway_billno
4734
            order.airwaybill_no = logistics_info_new.airway_billno
4735
            order.logistics_provider_id = logistics_info_new.providerId
4736
            current_time = datetime.datetime.now()
4737
 
4738
            logistics_info.deliveryTime = adjust_delivery_time(current_time, logistics_info.deliveryTime)
4739
            logistics_info.shippingTime = adjust_delivery_time(current_time, logistics_info.shippingTime)
4740
            logistics_info.deliveryDelay = adjust_delivery_time(current_time, (logistics_info.shippingTime+logistics_info.deliveryDelay))
4741
            new_expected_shipping_time_cod = (current_time + datetime.timedelta(days=logistics_info.shippingTime)).replace(hour=COD_SHIPPING_CUTOFF_TIME, minute=0, second=0)
4742
            new_expected_shipping_time_prepaid = (current_time + datetime.timedelta(days=logistics_info.shippingTime)).replace(hour=PREPAID_SHIPPING_CUTOFF_TIME, minute=0, second=0)
4743
 
4744
            if order.cod:
4745
                if order.expected_shipping_time.date() == new_expected_shipping_time_cod.date() :
4746
                    if order.otg :
4747
                        order.otg = logistics_info.otgAvailable 
4748
                else:
4749
                    if order.otg:
4750
                        order.otg = False
4751
                order.expected_shipping_time = new_expected_shipping_time_cod
4752
                order.expected_delivery_time = (current_time + datetime.timedelta(days=logistics_info.deliveryTime)).replace(hour=COD_SHIPPING_CUTOFF_TIME, minute=0, second=0)
4753
                order.courier_delivery_time = (current_time + datetime.timedelta(days=logistics_info.deliveryDelay)).replace(hour=COD_SHIPPING_CUTOFF_TIME, minute=0, second=0)
4754
            else:
4755
                if order.expected_shipping_time.date() == new_expected_shipping_time_prepaid.date() :
4756
                    if order.otg :
4757
                        order.otg = logistics_info.otgAvailable 
4758
                else:
4759
                    if order.otg:
4760
                        order.otg = False
4761
                order.expected_shipping_time = new_expected_shipping_time_prepaid
4762
                order.expected_delivery_time = (current_time + datetime.timedelta(days=logistics_info.deliveryTime)).replace(hour=PREPAID_SHIPPING_CUTOFF_TIME, minute=0, second=0)
4763
                order.courier_delivery_time = (current_time + datetime.timedelta(days=logistics_info.deliveryDelay)).replace(hour=PREPAID_SHIPPING_CUTOFF_TIME, minute=0, second=0)
4764
 
4765
        order.customer_pincode = pin
4766
        # End:- Added/Modified by Manish Sharma on 13 May 2013 for Change Shipping Address functionality
6985 anupam.sin 4767
        session.commit()
4768
        return True
4769
    return False
4770
 
7084 rajveer 4771
def get_recharge_transactions(storeId):
4772
    query = RechargeTransaction.query.filter(RechargeTransaction.storeId == storeId)
4773
    return query.all()
4774
 
7151 amit.gupta 4775
def get_recharge_trans(storeId, startdate,enddate, status):
4776
    if startdate == -1:
4777
        startdate = None
4778
    if enddate == -1:
4779
        enddate = None
4780
    if storeId== 0:
4781
        storeId = None
4782
    if status == 0:
4783
        status = None    
4784
 
4785
    query = RechargeTransaction.query
4786
    if storeId is not None:
4787
        query = query.filter(RechargeTransaction.storeId == storeId)
4788
    if status is not None:
4789
        query = query.filter(RechargeTransaction.status == status)
7169 anupam.sin 4790
 
4791
    if status == RechargeOrderStatus.RECHARGE_FAILED_REFUNDED :
4792
        query.filter(cast(RechargeTransaction.responseTime, DATE) == enddate)
7151 amit.gupta 4793
 
7169 anupam.sin 4794
    else :
4795
        if startdate is not None and enddate is not None:
4796
            startdate = to_py_date(startdate).date()
4797
            enddate = to_py_date(enddate).date()
4798
            if startdate == enddate:
4799
                query = query.filter(cast(RechargeTransaction.transactionTime, DATE) == enddate)
4800
            elif enddate < startdate:
4801
                query = query.filter(between(cast(RechargeTransaction.transactionTime, DATE), enddate, startdate))
4802
            else:
4803
                query = query.filter(between(cast(RechargeTransaction.transactionTime, DATE), startdate, enddate))
4804
        elif startdate is not None:
4805
            startdate = to_py_date(startdate).date()
4806
            query = query.filter(cast(RechargeTransaction.transactionTime, DATE) >= startdate)
4807
        elif enddate is not None:
4808
            enddate = to_py_date(enddate).date()
4809
            query = query.filter(cast(RechargeTransaction.transactionTime, DATE) <= enddate)
4810
 
7151 amit.gupta 4811
    return query.all()    
4812
 
7243 rajveer 4813
def update_recharge_transaction_status(id, status):
7127 rajveer 4814
    rechargeTransaction = RechargeTransaction.get_by(id=id)
7163 rajveer 4815
    if status in (RechargeOrderStatus.RECHARGE_FAILED_REFUNDED, RechargeOrderStatus.RECHARGE_FAILED):
4816
        rechargeTransaction.status = status
7243 rajveer 4817
        rechargeTransaction.responseTime = datetime.datetime.now() 
7127 rajveer 4818
 
4819
        store = HotspotStore.get_by(id=rechargeTransaction.storeId)
4820
        wallet = WalletForCompany.get_by(companyId=store.companyId)
4821
        wh = WalletHistoryForCompany()
4822
        wh.walletId = wallet.id
4823
        wh.amount = rechargeTransaction.amount
4824
        wh.transactionTime = rechargeTransaction.responseTime
4825
        wh.openingBal = wallet.amount
4826
        wh.closingBal = wallet.amount + wh.amount
4827
        wh.referenceNumber = rechargeTransaction.id 
4828
        wh.description = "Credited amount"
4829
 
4830
        wallet.amount = wallet.amount + rechargeTransaction.amount
4831
        store.availableLimit = store.availableLimit + rechargeTransaction.amount
4832
        store.collectedAmount = store.collectedAmount - rechargeTransaction.amount + rechargeTransaction.discount
4833
        session.commit()
7163 rajveer 4834
 
4835
    if status == RechargeOrderStatus.RECHARGE_SUCCESSFUL:
4836
        rechargeTransaction.status = RechargeOrderStatus.RECHARGE_SUCCESSFUL
4837
        rechargeTransaction.invoiceNumber = get_next_invoice_number(OrderType.RCH4HOTSPOT)
4838
        session.commit()
4839
 
4840
 
7073 anupam.sin 4841
def create_recharge_transaction(t_recharge):
7163 rajveer 4842
    dt = datetime.datetime.now() - datetime.timedelta(minutes=10)
4843
    txns = RechargeTransaction.query.filter(RechargeTransaction.deviceNum == t_recharge.deviceNum).filter(RechargeTransaction.transactionTime > dt).all()
4844
    if txns:
4845
        raise TransactionServiceException(898, "In last 10 minutes you had already recharged this mobile number. Please try after sometime.")
7073 anupam.sin 4846
    rechargeTransaction = RechargeTransaction()
4847
    rechargeTransaction.amount = t_recharge.amount
7096 anupam.sin 4848
    rechargeTransaction.circleId = t_recharge.circleId
7073 anupam.sin 4849
    rechargeTransaction.deviceNum = t_recharge.deviceNum
4850
    rechargeTransaction.deviceType = t_recharge.deviceType
4851
    rechargeTransaction.discount = t_recharge.discount
4852
    rechargeTransaction.email = t_recharge.email
4853
    rechargeTransaction.name = t_recharge.name
4854
    rechargeTransaction.cafNum = t_recharge.cafNum
4855
    rechargeTransaction.simNum = t_recharge.simNum
4856
    rechargeTransaction.isFrc = t_recharge.isFrc
4857
    rechargeTransaction.status = RechargeOrderStatus.INIT
4858
    rechargeTransaction.storeId = t_recharge.storeId
4859
    rechargeTransaction.transactionTime = datetime.datetime.now()
7075 rajveer 4860
    rechargeTransaction.operatorId = t_recharge.operatorId
4861
    rechargeTransaction.plan = t_recharge.plan
7080 anupam.sin 4862
    rechargeTransaction.ipAddress = t_recharge.ipAddress
7096 anupam.sin 4863
    rechargeTransaction.paymentAmount = t_recharge.paymentAmount
7139 amit.gupta 4864
    rechargeTransaction.payMethod = t_recharge.payMethod
7075 rajveer 4865
 
4866
    store = HotspotStore.get_by(id=rechargeTransaction.storeId)
7304 rajveer 4867
    if not rechargeTransaction.circleId:
4868
        rechargeTransaction.circleId = store.circleId
4869
 
7075 rajveer 4870
    wallet = WalletForCompany.get_by(companyId=store.companyId)
4871
    if store.availableLimit < rechargeTransaction.amount or wallet.amount < rechargeTransaction.amount:
4872
        raise TransactionServiceException(898, "Either wallet amount for company or available limit for store is less than recharge amount.")
7249 rajveer 4873
 
7075 rajveer 4874
    wh = WalletHistoryForCompany()
4875
    wh.walletId = wallet.id
4876
    wh.amount = -rechargeTransaction.amount
4877
    wh.transactionTime = rechargeTransaction.transactionTime
4878
    wh.openingBal = wallet.amount
4879
    wh.closingBal = wallet.amount + wh.amount
4880
    wh.description = "Debited amount"
4881
 
4882
    wallet.amount = wallet.amount - rechargeTransaction.amount
4883
    store.availableLimit = store.availableLimit - rechargeTransaction.amount
7076 rajveer 4884
    store.collectedAmount = store.collectedAmount + rechargeTransaction.amount - rechargeTransaction.discount 
7075 rajveer 4885
    session.commit()
4886
 
7249 rajveer 4887
    wh.referenceNumber = rechargeTransaction.id
4888
    session.commit()
4889
 
4890
 
7101 rajveer 4891
    strProviderCode = get_provider_code(rechargeTransaction.operatorId)
4892
    if rechargeTransaction.deviceType == 1:
4893
        rtype = 'MTP'
4894
    else:
4895
        rtype = 'RCH'
7369 rajveer 4896
    retStatus, retCode, spiceTID, description, aggTID, providerTID = RechargeService.rechargeDevice(rechargeTransaction.id, rtype, strProviderCode, rechargeTransaction.deviceNum, rechargeTransaction.amount, rechargeTransaction.plan)
7075 rajveer 4897
    rechargeTransaction.spiceTID = spiceTID
7369 rajveer 4898
    rechargeTransaction.aggTID = aggTID
4899
    rechargeTransaction.providerTID = providerTID
7075 rajveer 4900
    rechargeTransaction.responseTime = datetime.datetime.now()
4901
    rechargeTransaction.description = description
4902
    if retCode == '00' and retStatus == 'S':
4903
        rechargeTransaction.status = RechargeOrderStatus.RECHARGE_SUCCESSFUL
7096 anupam.sin 4904
        rechargeTransaction.invoiceNumber = get_next_invoice_number(OrderType.RCH4HOTSPOT)
7075 rajveer 4905
 
4906
    elif retCode in ('STO', 'US', 'UP') and retStatus == 'S':
4907
        rechargeTransaction.status = RechargeOrderStatus.RECHARGE_UNKNOWN
4908
    else:
4909
        rechargeTransaction.status = RechargeOrderStatus.RECHARGE_FAILED
4910
        if retCode in ('SVAI', 'SVIA', 'AI', 'IA', 'EAI', 'SVEAI'):
4911
            rechargeTransaction.description = "Invalid Amount"
4912
        elif retCode in ('ECL', 'SVECL', 'SCL'):
4913
            rechargeTransaction.description = "Customer Exceeded Daily Limit"
4914
        elif retCode in ('CI', 'ECI', 'ESP', 'SVCI', 'SVECI', 'SVESP', 'SV_ECI', 'SV ECI'):
4915
            rechargeTransaction.description = "Invalid Device Number"
4916
 
4917
        store = HotspotStore.get_by(id=rechargeTransaction.storeId)
4918
        wallet = WalletForCompany.get_by(companyId=store.companyId)
4919
        wh = WalletHistoryForCompany()
4920
        wh.walletId = wallet.id
4921
        wh.amount = rechargeTransaction.amount
4922
        wh.transactionTime = rechargeTransaction.responseTime
4923
        wh.openingBal = wallet.amount
4924
        wh.closingBal = wallet.amount + wh.amount
4925
        wh.referenceNumber = rechargeTransaction.id 
4926
        wh.description = "Credited amount"
4927
 
4928
        wallet.amount = wallet.amount + rechargeTransaction.amount
4929
        store.availableLimit = store.availableLimit + rechargeTransaction.amount
7076 rajveer 4930
        store.collectedAmount = store.collectedAmount - rechargeTransaction.amount + rechargeTransaction.discount
7075 rajveer 4931
 
4932
    session.commit()
4933
 
7073 anupam.sin 4934
    return rechargeTransaction
4935
 
7080 anupam.sin 4936
def get_frcs(circleId, operatorId):
7267 anupam.sin 4937
    query = FRC.query.filter(FRC.circleId == circleId)
4938
    if(operatorId > 0):
4939
        query = query.filter(FRC.operatorId == operatorId)
4940
 
4941
    frcs = query.all()
4942
 
7096 anupam.sin 4943
    if frcs is None:
4944
        return []
4945
    return frcs
7080 anupam.sin 4946
 
4947
def get_recharge_transaction(rechargeId):
4948
    recharge = RechargeTransaction.get_by(id = rechargeId)
4949
    if not recharge:
4950
        raise TransactionServiceException(108, "no such transaction")
4951
    return recharge
4952
 
7096 anupam.sin 4953
def get_hotspot_store(id, hotspotid):
4954
    store = None
4955
    if id > 0:
4956
        store = HotspotStore.query.filter(HotspotStore.id == id).first()
4957
    elif len(hotspotid) > 0:
4958
        store = HotspotStore.query.filter(HotspotStore.hotspotId == hotspotid).first()
4959
    else:
4960
        raise TransactionServiceException(119, 'No such store')
4961
    if store:
4962
        return store
4963
    else:
4964
        raise TransactionServiceException(119, 'No such store')
4965
 
4966
def get_circle(id, code):
4967
    circle = None
4968
    if id > 0:
4969
        circle = TelecomCircle.get_by(id = id)
4970
    elif len(code) > 0:
4971
        circle = TelecomCircle.get_by(code = code)
4972
    else:
4973
        raise TransactionServiceException(119, 'No such circle')
4974
    if circle:
4975
        return circle
4976
    else:
4977
        raise TransactionServiceException(119, 'No such circle')
4978
 
7109 anupam.sin 4979
def retrieve_hotspot_recharge_invoice(id):
4980
    recharge = RechargeTransaction.get_by(id = id)
7139 amit.gupta 4981
    filename = "/tmp/recharge" + str(recharge.invoiceNumber) + ".pdf"
7109 anupam.sin 4982
    operator = ServiceProvider.get_by(id = recharge.operatorId).name
4983
    amount = recharge.amount
4984
    telNum = "+91 " + str(recharge.deviceNum)
4985
    customerName = recharge.name
4986
    invNum = str(recharge.invoiceNumber)
4987
    billingTime = recharge.responseTime
7151 amit.gupta 4988
    payMethod = recharge.payMethod
4989
    return __printRechargeInvoice(filename, operator, amount, telNum, customerName, invNum, billingTime, payMethod)
7109 anupam.sin 4990
 
7190 amar.kumar 4991
def split_freebie_order(order_id, splitReason, shippingDate):
4992
    order = get_order(order_id)
4993
    freebie_order = Order()
4994
 
4995
    freebie_order.transaction = order.transaction
4996
 
4997
    freebie_order.customer_id = order.customer_id
4998
    freebie_order.customer_email = order.customer_email
4999
    freebie_order.customer_name = order.customer_name
5000
    freebie_order.customer_pincode = order.customer_pincode
5001
    freebie_order.customer_address1 = order.customer_address1
5002
    freebie_order.customer_address2 = order.customer_address2
5003
    freebie_order.customer_city = order.customer_city
5004
    freebie_order.customer_state = order.customer_state
5005
    freebie_order.customer_mobilenumber = order.customer_mobilenumber
5006
    freebie_order.total_weight = order.total_weight
5007
    freebie_order.total_amount = 0.01
5008
    freebie_order.status = OrderStatus.SUBMITTED_FOR_PROCESSING
5009
    freebie_order.statusDescription = "In Process";
5010
    freebie_order.created_timestamp = datetime.datetime.now()
5011
    freebie_order.cod = 0
5012
    freebie_order.orderType = OrderType.B2C
5013
    freebie_order.pickupStoreId = 0
5014
    freebie_order.otg = 0
5015
    freebie_order.insurer = 0
5016
    freebie_order.insuranceAmount = 0
5017
 
5018
    logistics_client = LogisticsClient().get_client()
5019
    logistics_info = logistics_client.getLogisticsInfo(order.customer_pincode, 1, DeliveryType.PREPAID, PickUpType.COURIER)
5020
    freebie_order.logistics_provider_id = logistics_info.providerId;
5021
    freebie_order.tracking_id = logistics_info.airway_billno
5022
    freebie_order.airwaybill_no = logistics_info.airway_billno
5023
    freebie_order.expected_delivery_time = (to_py_date(shippingDate)+datetime.timedelta(days=logistics_info.deliveryTime)).replace(hour=PREPAID_SHIPPING_CUTOFF_TIME, minute=0, second=0)  
5024
    freebie_order.promised_delivery_time = order.promised_delivery_time
5025
    freebie_order.expected_shipping_time = to_py_date(shippingDate)
5026
    freebie_order.promised_shipping_time = order.promised_shipping_time
5027
 
5028
    inventory_client = InventoryClient().get_client()
7198 amar.kumar 5029
    item_availability = inventory_client.getItemAvailabilityAtLocation(order.freebieItemId,1)
7190 amar.kumar 5030
    freebie_order.warehouse_id = item_availability[2]
7303 amar.kumar 5031
    freebie_order.fulfilmentWarehouseId = item_availability[0]
7190 amar.kumar 5032
 
5033
    catalog_client = CatalogClient().get_client()
5034
    item = catalog_client.getItem(order.freebieItemId)
5035
    freebie_order.total_weight = item.weight
5036
 
5037
    litem = LineItem()
5038
    litem.item_id = item.id
5039
    litem.productGroup = item.productGroup
5040
    litem.brand = item.brand
5041
    litem.model_number = item.modelNumber
5042
    litem.model_name = item.modelName
5043
    litem.color = item.color
5044
    litem.extra_info = "Freebie Order for Order ID " + str(order.id)
5045
    litem.quantity = 1
5046
    litem.unit_price = 0.01
5047
    litem.unit_weight = item.weight
5048
    litem.total_price = 0.01
5049
    litem.total_weight = item.weight
5050
    litem.vatRate = 5.0
5051
 
5052
    freebie_order.lineitems.append(litem)
7198 amar.kumar 5053
    order.freebieItemId = 0
7190 amar.kumar 5054
    session.commit()
7198 amar.kumar 5055
    order.lineitems[0].extra_info = "Parent Order for Order ID " + str(freebie_order.id)
7190 amar.kumar 5056
 
7198 amar.kumar 5057
    inventory_client = InventoryClient().get_client()   
5058
    inventory_client.reserveItemInWarehouse(freebie_order.lineitems[0].item_id, item_availability[0], sourceId, freebie_order.id, to_java_date(freebie_order.created_timestamp), to_java_date(freebie_order.promised_shipping_time), 1)
7190 amar.kumar 5059
    parentOrderAttribute = Attribute()
5060
    parentOrderAttribute.orderId = freebie_order.id
5061
    parentOrderAttribute.name = "parentOrderIdForFreebie"
5062
    parentOrderAttribute.value = str(order.id)
5063
 
5064
    freebieOrderAttribute = Attribute()
5065
    freebieOrderAttribute.orderId = order.id
5066
    freebieOrderAttribute.name = "freebieOrderId"
5067
    freebieOrderAttribute.value = str(freebie_order.id)
5068
    session.commit()
5069
 
7198 amar.kumar 5070
    return to_t_order(freebie_order)
7190 amar.kumar 5071
 
7151 amit.gupta 5072
def __printRechargeInvoice(filename, operator, amount, telNum, customerName, invNum, billingTime, payMethod): 
7109 anupam.sin 5073
    PAGE_HEIGHT=defaultPageSize[1];
5074
    styles = getSampleStyleSheet()
5075
    styles.add(ParagraphStyle(name='prologue', alignment=TA_CENTER, fontName="Courier", rightIndent = 5, fontSize=10), alias='sH')
5076
    styles.add(ParagraphStyle(name='text', alignment=TA_JUSTIFY, fontName="Courier", fontSize=10), alias='text')
5077
    styles.add(ParagraphStyle(name='line', alignment=TA_CENTER, fontName="Courier", fontSize=10), alias='line')
5078
    styles.add(ParagraphStyle(name='epilogue', alignment=TA_CENTER, fontName="Courier", leftIndent = 30, rightIndent=36, fontSize=10), alias='ep')
7096 anupam.sin 5079
 
7109 anupam.sin 5080
    Story = []
5081
    prologueStyle = styles["prologue"]
5082
    lineStyle = styles["line"]
5083
    textStyle = styles["text"]
5084
    epilogueStyle = styles["epilogue"]
7096 anupam.sin 5085
 
7109 anupam.sin 5086
    doc = BaseDocTemplate(filename,showBoundary=0)
5087
 
5088
    #Two Columns
5089
    frame1 = Frame(58, doc.bottomMargin, doc.width/2 + 25, doc.height + 7, id='col1')
5090
 
5091
 
5092
 
5093
    Story.append(Paragraph("""Spice Retail Limited<br></br>
5094
        C/O,PIBCO LIMITED,Basement,Punjsons<br></br>
5095
        2,Kalkaji Industrial Area,New Delhi<br></br>
5096
          .<br></br>
5097
        TIN NO. 07430284979<br></br>
5098
        Service Tax No:AAACM0294PST001<br></br><br></br><br></br>""", prologueStyle))
5099
    drawLine(Story, lineStyle)
5100
 
5101
    Story.append(Paragraph('{0:7s}{1:>11s}{2:  %d/%m/%Y  %H:%M:%S}'.format("INV NO:", invNum, billingTime).replace(" ", "&nbsp;"), textStyle))
5102
    drawLine(Story, lineStyle)
5103
 
5104
    Story.append(Paragraph("{0:<6s}{1:<34s}".format("NAME:", customerName).replace(" ", "&nbsp;"), textStyle))
5105
    Story.append(Paragraph("{0:<9s}{1:<31s}".format("TEL NO.:", telNum).replace(" ", "&nbsp;"), textStyle))
7151 amit.gupta 5106
    Story.append(Paragraph("{0:<9s}{1:<31s}".format("PAYMENT MODE:", PayMethod._VALUES_TO_NAMES[payMethod]).replace(" ", "&nbsp;"), textStyle))
7109 anupam.sin 5107
    drawLine(Story, lineStyle)
5108
 
5109
    Story.append(Paragraph(('{0:<16s}{1:>13s}{2:11.2f}').format(operator, "RECHARGE", amount).replace(' ', '&nbsp;'),textStyle))
5110
    drawLine(Story, lineStyle)
5111
    doc.addPageTemplates([PageTemplate(id='TwoCol',frames=[frame1]), ])
5112
 
5113
    #start the construction of the pdf
5114
    doc.build(Story)
5115
 
5116
    try:
5117
        fileToSend = open(filename, "rb")
5118
        pdfFile = fileToSend.read()
5119
    except:
5120
        return bin(0)
5121
 
5122
    return pdfFile
5123
 
7172 anupam.sin 5124
def get_recharge_transactions_by_number(number, storeId):
7169 anupam.sin 5125
    query = RechargeTransaction.query.filter(RechargeTransaction.deviceNum == number)
7172 anupam.sin 5126
    query = query.filter(RechargeTransaction.storeId == storeId)
7169 anupam.sin 5127
    return query.all()
5128
 
5129
def update_hotspot_store_password(storeId, password):
5130
    store = None
5131
    if password is None:
5132
        return False
5133
    if storeId:
5134
        store = HotspotStore.query.filter(HotspotStore.id == storeId).first()
5135
    if store:
5136
        store.password = password
5137
        session.commit()
5138
        return True
5139
    return False
5140
 
7263 anupam.sin 5141
def get_source_detail(source):
5142
    detail = SourceDetail.get_by(id=source)
5143
    if not detail:
5144
        raise TransactionServiceException(108, "no such source")
5145
    return detail
5146
 
7267 anupam.sin 5147
def get_all_circles():
5148
    circles = TelecomCircle.query.all();
5149
    if not circles:
5150
        circles = []
5151
    return circles 
5152
 
5153
def delete_frcs(frcIdsToDelete):
5154
    toReturn = False
5155
    if frcIdsToDelete:
5156
        for frcId in frcIdsToDelete:
5157
            frc = FRC.get_by(id = frcId)
5158
            if frc:
5159
                frc.delete()
5160
                toReturn = True
5161
        session.commit()
5162
        return toReturn
5163
    else:
5164
        return toReturn
5165
 
7285 rajveer 5166
def topup_company_wallet(companyId, amount):
5167
    wallet = WalletForCompany.query.filter(WalletForCompany.id == companyId).with_lockmode("update").one()
5168
    company = Company.get_by(id = companyId)
5169
    wh = WalletHistoryForCompany()
5170
    wh.walletId = wallet.id
5171
    wh.openingBal = wallet.amount
5172
    wh.closingBal = wallet.amount +  amount
5173
    wh.amount = amount
5174
    wh.transactionTime = datetime.datetime.now()
5175
    wh.referenceNumber =  get_next_invoice_number(OrderType.WALLETCREDIT)
5176
    wh.description = "Wallet Credited"
5177
 
5178
    wallet.amount += amount
5179
    session.commit()
5180
    mail("cnc.center@shop2020.in", "5h0p2o2o", ["rajveer.singh@shop2020.in", "anupam.singh@shop2020.in", "Ashwani.Kumar@spiceretail.co.in","parveen.mittal@spiceretail.co.in","pardeep.panwar@spiceretail.co.in","gagan.sharma@spiceretail.co.in","j.p.gupta@shop2020.in", "rajneesh.arora@shop2020.in", "amit.tyagi@spiceretail.co.in"] , company.name + " wallet topped up by " +  str(amount) + " rupees.", "", [], [], [])
5181
    return wallet.amount
7267 anupam.sin 5182
 
7285 rajveer 5183
def get_wallet_balance_for_company(companyId):
5184
    return WalletForCompany.get_by(companyId = companyId).amount
5185
 
7311 kshitij.so 5186
def add_amazon_order(amazonOrder):
5187
    amazon_order = AmazonOrder()
5188
    amazon_order.orderId = amazonOrder.orderId
5189
    amazon_order.amazonOrderCode = amazonOrder.amazonOrderCode
5190
    amazon_order.amazonOrderItemCode = amazonOrder.amazonOrderItemCode
5191
    amazon_order.transactionId = amazonOrder.transactionId
5192
    amazon_order.item_id= amazonOrder.item_id
5193
    amazon_order.status= amazonOrder.status
5194
    session.commit()
5195
 
7322 vikram.rag 5196
def update_amazon_order_status(order_id,status):
7311 kshitij.so 5197
    try:
5198
        row = AmazonOrder.get_by(orderId=order_id)
5199
        row.status=status
5200
        result=True
5201
    except:
5202
        result=False
5203
    finally:
5204
        session.commit()
5205
        return result
5206
 
5207
def get_amazon_orders_marked_sent():
7322 vikram.rag 5208
    return AmazonOrder.query.filter(AmazonOrder.status=='Acknowledgement-Sent').all()
7311 kshitij.so 5209
 
5210
def get_amazon_orders_shipped(interval):
5211
    amazonShippedOrders = []
5212
    toDate = datetime.datetime.now()
5213
    fromDate = toDate-timedelta(days = interval-1, hours=toDate.hour, minutes=toDate.minute, seconds=toDate.second)
5214
    orders = get_amazon_orders_marked_sent()
5215
    for order in orders:
5216
        row = Order.query.filter(Order.shipping_timestamp.between (fromDate,toDate)).filter(Order.id==order.orderId).first()
7314 kshitij.so 5217
        if row is None:
5218
            continue
7311 kshitij.so 5219
        amazonShippedOrders.append(to_t_order(row))
5220
    return amazonShippedOrders
5221
 
5222
def get_amazon_orders_cancelled(interval):
5223
    amazonCancelledOrders = []
5224
    toDate = datetime.datetime.now()
5225
    fromDate = toDate-timedelta(days = interval-1, hours=toDate.hour, minutes=toDate.minute, seconds=toDate.second)
5226
    orders = get_amazon_orders_marked_sent()
5227
    for order in orders:
5228
        row = Order.query.filter(Order.refund_timestamp.between (fromDate,toDate)).filter(Order.id==order.orderId).first()
7314 kshitij.so 5229
        if row is None:
5230
            continue
7311 kshitij.so 5231
        if ( row.status == 15 or row.status == 18 or row.status == 34 ):
5232
            amazonCancelledOrders.append(to_t_order(row))
5233
    return amazonCancelledOrders        
7322 vikram.rag 5234
 
5235
def get_amazon_order(order_id):
5236
    return AmazonOrder.get_by(orderId=order_id)
5237
 
7311 kshitij.so 5238
 
7343 anupam.sin 5239
def get_orders_for_store(orderId, storeId, startDate, endDate, statuses):
5240
    orders = []
5241
    query = Order.query
5242
    if storeId < 1:
5243
        return orders
5244
    elif orderId > 0:
5245
        query = query.filter(Order.id == orderId)
5246
    else :
5247
        if startDate:
5248
            query = query.filter(cast(Order.created_timestamp, DATE) >= startDate.date())
5249
 
5250
        if endDate:
5251
            query = query.filter(cast(Order.created_timestamp, DATE) <= endDate.date())
5252
 
5253
        if len(statuses) > 0:
5254
            query = query.filter(Order.status.in_(statuses))
5255
 
5256
    orders = query.filter(Order.storeId == storeId).all()
5257
    return orders
5258
 
7386 anupam.sin 5259
def get_store_order_advance_invoice(orderId, storeId):
7343 anupam.sin 5260
    order = Order.get_by(id = orderId)
7386 anupam.sin 5261
    storeOrderDetail = StoreOrderDetail.query.filter(StoreOrderDetail.orderId == orderId).filter(StoreOrderDetail.storeId == storeId).first()
7343 anupam.sin 5262
    filename = "/tmp/recharge" + str(order.id) + ".pdf"
7346 anupam.sin 5263
    modelName = "&nbsp;"
5264
    modelNumber = "&nbsp;"
5265
    color = "&nbsp;"
5266
    if order.lineitems[0].model_name:
5267
        modelName = modelName + order.lineitems[0].model_name
5268
    if order.lineitems[0].model_number:
5269
        modelNumber = modelNumber + order.lineitems[0].model_number
5270
    if order.lineitems[0].color:
5271
        color = color + order.lineitems[0].color
5272
 
5273
    product = order.lineitems[0].brand +  modelName + modelNumber + color
7386 anupam.sin 5274
    advanceAmount = order.advanceAmount
7343 anupam.sin 5275
    totalAmount = order.total_amount
7346 anupam.sin 5276
    delivery = order.expected_delivery_time
7386 anupam.sin 5277
 
7343 anupam.sin 5278
    customerName = order.customer_name
7386 anupam.sin 5279
    customerAdd1 = order.customer_address1
5280
    customerAdd2 = order.customer_address2
5281
    customerCity = order.customer_city
5282
    customerState = order.customer_state
5283
    customerMobile = order.customer_mobilenumber
5284
    customerPin = order.customer_pincode
7393 anupam.sin 5285
    inCash = storeOrderDetail.cashAmount
5286
    byCard = storeOrderDetail.cardAmount
7343 anupam.sin 5287
    #payMethod = recharge.payMethod
7386 anupam.sin 5288
#    if order.status == 15 or order.status == 34:
5289
#        return __printStoreOrderAdvanceInvoice(filename, product, advanceAmount, totalAmount, customerName, delivery, mode, customerAdd1, customerAdd2, customerCity, customerState, customerMobile, customerPin)
7393 anupam.sin 5290
    return __printStoreOrderAdvanceInvoice(filename, product, advanceAmount, totalAmount, customerName, delivery, inCash, byCard, customerAdd1, customerAdd2, customerCity, customerState, customerMobile, customerPin)
7343 anupam.sin 5291
 
5292
 
7393 anupam.sin 5293
def __printStoreOrderAdvanceInvoice(filename, product, advanceAmount, totalAmount, customerName, delivery, inCash, byCard, customerAdd1, customerAdd2, customerCity, customerState, customerMobile, customerPin): 
7343 anupam.sin 5294
    PAGE_HEIGHT=defaultPageSize[1];
5295
    styles = getSampleStyleSheet()
5296
    styles.add(ParagraphStyle(name='prologue', alignment=TA_CENTER, fontName="Courier", rightIndent = 5, fontSize=10), alias='sH')
5297
    styles.add(ParagraphStyle(name='text', alignment=TA_JUSTIFY, fontName="Courier", fontSize=10), alias='text')
5298
    styles.add(ParagraphStyle(name='line', alignment=TA_CENTER, fontName="Courier", fontSize=10), alias='line')
5299
    styles.add(ParagraphStyle(name='epilogue', alignment=TA_CENTER, fontName="Courier", leftIndent = 30, rightIndent=36, fontSize=10), alias='ep')
5300
 
5301
    Story = []
5302
    prologueStyle = styles["prologue"]
5303
    lineStyle = styles["line"]
5304
    textStyle = styles["text"]
5305
    epilogueStyle = styles["epilogue"]
5306
 
5307
    doc = BaseDocTemplate(filename,showBoundary=0)
5308
 
5309
    #Two Columns
5310
    frame1 = Frame(58, doc.bottomMargin, doc.width/2 + 25, doc.height + 7, id='col1')
5311
 
5312
 
7386 anupam.sin 5313
    ############### TODO ###############################################################
7343 anupam.sin 5314
    Story.append(Paragraph("""Spice Retail Limited<br></br>
5315
        C/O,PIBCO LIMITED,Basement,Punjsons<br></br>
5316
        2,Kalkaji Industrial Area,New Delhi<br></br>
7393 anupam.sin 5317
          .<br></br>""", prologueStyle))
7386 anupam.sin 5318
    ############### ADDRESS TO BE DYNAMIC ##############################################
5319
 
7343 anupam.sin 5320
    drawLine(Story, lineStyle)
7393 anupam.sin 5321
    Story.append(Paragraph("{0:^39s}".format("*** ADVANCE RECEIPT ***").replace(" ", "&nbsp;"), textStyle))
5322
    drawLine(Story, lineStyle)
7343 anupam.sin 5323
 
7386 anupam.sin 5324
    Story.append(Paragraph("{0:^39s}".format("DELIVERY ADDRESS").replace(" ", "&nbsp;"), textStyle))
5325
    drawLine(Story, lineStyle)
5326
    Story.append(Paragraph(customerAdd1, textStyle))
5327
    if len(customerAdd2) > 0:
5328
        Story.append(Paragraph(customerAdd2, textStyle))
5329
 
5330
    Story.append(Paragraph(customerCity, textStyle))
5331
    Story.append(Paragraph(customerState + " - " + customerPin, textStyle))
5332
    drawLine(Story, lineStyle)
7343 anupam.sin 5333
 
5334
    Story.append(Paragraph("{0:<6s}{1:<34s}".format("NAME:", customerName).replace(" ", "&nbsp;"), textStyle))
7386 anupam.sin 5335
    Story.append(Paragraph("{0:<10s}{1:<29s}".format("MOBILE:", customerMobile).replace(" ", "&nbsp;"), textStyle))
7393 anupam.sin 5336
    Story.append(Paragraph("{0:<20s}{1:  %d/%m/%Y}".format("EXPECTED DELIVERY:", delivery).replace(" ", "&nbsp;"), textStyle))
7343 anupam.sin 5337
 
5338
    drawLine(Story, lineStyle)
7346 anupam.sin 5339
    Story.append(Paragraph("{0:^39s}".format("PRODUCT NAME").replace(" ", "&nbsp;"), textStyle))
7343 anupam.sin 5340
    drawLine(Story, lineStyle)
5341
    Story.append(Paragraph("{0:<39s}".format(product).replace(" ", "&nbsp;"), textStyle))
5342
    drawLine(Story, lineStyle)
5343
 
5344
    Story.append(Paragraph(('{0:<20s}{1:>19.2f}').format("TOTAL PRICE: ", totalAmount).replace(' ', '&nbsp;'),textStyle))
7386 anupam.sin 5345
    Story.append(Paragraph(('{0:<20s}{1:>19.2f}').format("ADVANCE AMOUNT: ", advanceAmount).replace(' ', '&nbsp;'),textStyle))
7393 anupam.sin 5346
    Story.append(Paragraph(('{0:<20s}{1:>19.2f}').format("IN CASH: ", inCash).replace(' ', '&nbsp;'),textStyle))
5347
    Story.append(Paragraph(('{0:<20s}{1:>19.2f}').format("BY CARD: ", byCard).replace(' ', '&nbsp;'),textStyle))
7386 anupam.sin 5348
    Story.append(Paragraph(('{0:<20s}{1:>19.2f}').format("BALANCE TO BE PAID: ", (totalAmount - advanceAmount)).replace(' ', '&nbsp;'),textStyle))
7343 anupam.sin 5349
 
5350
    drawLine(Story, lineStyle)
7386 anupam.sin 5351
    Story.append(Paragraph("Note:", textStyle))                                        
5352
    Story.append(Paragraph("* In case of cancellation of order on customer request, 10% of product amount subject to minimum Rs 500/- shall be deducted by Spice Retail Limited as cancellation charges. Customer shall provide original copy of 'Advance Receipt' to get the balance amount as refund",textStyle))                                        
5353
    Story.append(Paragraph("* In case of cancellation of order other than customer request, original copy of 'Advance Receipt' shall be provided by customer to get the refund",textStyle))                                        
5354
    Story.append(Paragraph("* Balance amount as mentioned above to be paid at the time of delivery of product to courier agency. Refusal to accept the product delivered through courier shall be deemed as cancellation of order and cancellation charges shall become applicable.",textStyle))                                         
5355
    Story.append(Paragraph("* The product as mentioned above shall be made available to the customer, subject to its availability from the manufacturer",textStyle))                                        
7393 anupam.sin 5356
    drawLine(Story, lineStyle)
5357
    Story.append(Paragraph(('{0:<20s}{1:>19s}').format("Customer care : ", "0120-6744700").replace(' ', '&nbsp;'),textStyle))
5358
    drawLine(Story, lineStyle)
7386 anupam.sin 5359
 
7343 anupam.sin 5360
    doc.addPageTemplates([PageTemplate(id='TwoCol',frames=[frame1]), ])
5361
 
5362
    #start the construction of the pdf
5363
    doc.build(Story)
5364
 
5365
    try:
5366
        fileToSend = open(filename, "rb")
5367
        pdfFile = fileToSend.read()
5368
    except:
5369
        return bin(0)
5370
 
5371
    return pdfFile
5372
 
7370 anupam.sin 5373
def add_frc(circle, operatorId, denomination, maxDiscount):
7371 anupam.sin 5374
    frc = FRC.query.filter(FRC.circleId == circle).filter(FRC.operatorId == operatorId).filter(FRC.denomination == denomination).first()
7370 anupam.sin 5375
    if frc:
5376
        frc.maxDiscount = maxDiscount
5377
    else:
5378
        frc = FRC()
5379
        frc.circleId = circle
5380
        frc.denomination = denomination
5381
        frc.maxDiscount = maxDiscount
5382
        frc.operatorId = operatorId
5383
    session.commit()
5384
    return True 
5385
 
7371 anupam.sin 5386
def add_series(circle, operatorId, series):
5387
    operatorSeriesObject = OperatorSeries.query.filter(OperatorSeries.series == series).first()
5388
    if operatorSeriesObject:
5389
        circleName = TelecomCircle.get_by(id = operatorSeriesObject.circleId).name
5390
        operatorName = ServiceProvider.get_by(id = operatorSeriesObject.operatorId).name
5391
        return "Series already exists for : " + operatorName + " in circle : " + circleName
5392
    else :
5393
        operatorSeriesObject = OperatorSeries()
5394
        operatorSeriesObject.series = series
5395
        operatorSeriesObject.circleId = circle
5396
        operatorSeriesObject.operatorId = operatorId
5397
        session.commit()
5398
        return "Successfully saved"
7386 anupam.sin 5399
 
5400
 
5401
def save_store_order_detail(thrift_storeOrderDetail):
5402
    txnId = thrift_storeOrderDetail.orderId
5403
    txn = Transaction.get_by(id=txnId)
5404
    oid = txn.orders[0].id
5405
    ds_storeOrderDetail = StoreOrderDetail()
5406
    ds_storeOrderDetail.orderId = oid
5407
    ds_storeOrderDetail.advanceAmount = thrift_storeOrderDetail.advanceAmount
5408
    ds_storeOrderDetail.cardAmount = thrift_storeOrderDetail.cardAmount
5409
    ds_storeOrderDetail.cashAmount = thrift_storeOrderDetail.cashAmount
5410
    ds_storeOrderDetail.storeId = thrift_storeOrderDetail.storeId
5411
    ds_storeOrderDetail.payStatus = thrift_storeOrderDetail.payStatus
5412
    session.commit()
5413
    return True
5414
 
5415
def get_store_order_detail(orderId, storeId):
5416
    storeOrderDetail = StoreOrderDetail.query.filter(StoreOrderDetail.orderId == orderId).filter(StoreOrderDetail.storeId == storeId).first()
5417
    if storeOrderDetail:
5418
        return storeOrderDetail
5419
    else:
5420
        return StoreOrderDetail()
5421
 
5422
def get_all_edc_banks():
5423
    allBankNames = []
5424
    edcBanks = EdcBank.query.all();
5425
    for bank in edcBanks:
5426
        allBankNames.append(bank.name)
5427
    return allBankNames
7393 anupam.sin 5428
 
5429
def save_refund_amounts_for_store_order(orderId, storeId, cashRefundAmount, cardRefundAmount):
5430
    storeOrderDetail = StoreOrderDetail.query.filter(StoreOrderDetail.orderId == orderId).filter(StoreOrderDetail.storeId == storeId).first()
5431
    if storeOrderDetail:
5432
        storeOrderDetail.cashRefundAmount = cashRefundAmount
5433
        storeOrderDetail.cardRefundAmount = cardRefundAmount
5434
        session.commit()
5435
        return True
5436
    else:
5437
        return False
7386 anupam.sin 5438
 
7393 anupam.sin 5439
 
6915 anupam.sin 5440
if __name__ == '__main__':
7393 anupam.sin 5441
    print datetime.datetime.now()
5442
    print datetime.datetime.now().date()
5443
    DataService.initialize('transaction', 'localhost')
5444
    order = Order.get_by(id = 308405)
5445
    print order.created_timestamp.date()
5446
    if order.created_timestamp.date() == datetime.datetime.now().date():
5447
        print "BOOO-YEAH"