Subversion Repositories SmartDukaan

Rev

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