Subversion Repositories SmartDukaan

Rev

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